|
|
1.1 ! root 1: /* ! 2: * Copyright (C) 2003, 2004 Stefan Reinauer ! 3: * ! 4: * See the file "COPYING" for further information about ! 5: * the copyright and warranty status of this work. ! 6: */ ! 7: ! 8: #include "config.h" ! 9: #include "libopenbios/bindings.h" ! 10: #include "kernel/kernel.h" ! 11: #include "drivers/drivers.h" ! 12: #include "libc/vsprintf.h" ! 13: ! 14: /* ****************************************************************** ! 15: * serial console functions ! 16: * ****************************************************************** */ ! 17: ! 18: #define SER_SIZE 8 ! 19: ! 20: #define RBR(x) x==2?0x2f8:0x3f8 ! 21: #define THR(x) x==2?0x2f8:0x3f8 ! 22: #define IER(x) x==2?0x2f9:0x3f9 ! 23: #define IIR(x) x==2?0x2fa:0x3fa ! 24: #define LCR(x) x==2?0x2fb:0x3fb ! 25: #define MCR(x) x==2?0x2fc:0x3fc ! 26: #define LSR(x) x==2?0x2fd:0x3fd ! 27: #define MSR(x) x==2?0x2fe:0x3fe ! 28: #define SCR(x) x==2?0x2ff:0x3ff ! 29: #define DLL(x) x==2?0x2f8:0x3f8 ! 30: #define DLM(x) x==2?0x2f9:0x3f9 ! 31: ! 32: int uart_charav(int port) ! 33: { ! 34: return ((inb(LSR(port)) & 1) != 0); ! 35: } ! 36: ! 37: char uart_getchar(int port) ! 38: { ! 39: while (!uart_charav(port)); ! 40: return ((char) inb(RBR(port)) & 0177); ! 41: } ! 42: ! 43: static void uart_putchar(int port, unsigned char c) ! 44: { ! 45: if (c == '\n') ! 46: uart_putchar(port, '\r'); ! 47: while (!(inb(LSR(port)) & 0x20)); ! 48: outb(c, THR(port)); ! 49: } ! 50: ! 51: static void uart_init_line(int port, unsigned long baud) ! 52: { ! 53: int i, baudconst; ! 54: ! 55: switch (baud) { ! 56: case 115200: ! 57: baudconst = 1; ! 58: break; ! 59: case 57600: ! 60: baudconst = 2; ! 61: break; ! 62: case 38400: ! 63: baudconst = 3; ! 64: break; ! 65: case 19200: ! 66: baudconst = 6; ! 67: break; ! 68: case 9600: ! 69: default: ! 70: baudconst = 12; ! 71: break; ! 72: } ! 73: ! 74: outb(0x87, LCR(port)); ! 75: outb(0x00, DLM(port)); ! 76: outb(baudconst, DLL(port)); ! 77: outb(0x07, LCR(port)); ! 78: outb(0x0f, MCR(port)); ! 79: ! 80: for (i = 10; i > 0; i--) { ! 81: if (inb(LSR(port)) == (unsigned int) 0) ! 82: break; ! 83: inb(RBR(port)); ! 84: } ! 85: } ! 86: ! 87: #ifdef CONFIG_DEBUG_CONSOLE_SERIAL ! 88: int uart_init(int port, unsigned long speed) ! 89: { ! 90: uart_init_line(port, speed); ! 91: return -1; ! 92: } ! 93: ! 94: void serial_putchar(int c) ! 95: { ! 96: uart_putchar(CONFIG_SERIAL_PORT, (unsigned char) (c & 0xff)); ! 97: } ! 98: #endif ! 99: ! 100: /* ( addr len -- actual ) */ ! 101: static void ! 102: pc_serial_read(unsigned long *address) ! 103: { ! 104: char *addr; ! 105: int len; ! 106: ! 107: len = POP(); ! 108: addr = (char *)POP(); ! 109: ! 110: if (len != 1) ! 111: printk("pc_serial_read: bad len, addr %lx len %x\n", (unsigned long)addr, len); ! 112: ! 113: if (uart_charav(*address)) { ! 114: *addr = (char)uart_getchar(*address); ! 115: PUSH(1); ! 116: } else { ! 117: PUSH(0); ! 118: } ! 119: } ! 120: ! 121: /* ( addr len -- actual ) */ ! 122: static void ! 123: pc_serial_write(unsigned long *address) ! 124: { ! 125: unsigned char *addr; ! 126: int i, len; ! 127: ! 128: len = POP(); ! 129: addr = (unsigned char *)POP(); ! 130: ! 131: for (i = 0; i < len; i++) { ! 132: uart_putchar(*address, addr[i]); ! 133: } ! 134: PUSH(len); ! 135: } ! 136: ! 137: static void ! 138: pc_serial_close(void) ! 139: { ! 140: } ! 141: ! 142: static void ! 143: pc_serial_open(unsigned long *address) ! 144: { ! 145: int len; ! 146: phandle_t ph; ! 147: unsigned long *prop; ! 148: ! 149: fword("my-self"); ! 150: fword("ihandle>phandle"); ! 151: ph = (phandle_t)POP(); ! 152: prop = (unsigned long *)get_property(ph, "address", &len); ! 153: *address = *prop; ! 154: ! 155: RET ( -1 ); ! 156: } ! 157: ! 158: DECLARE_UNNAMED_NODE(pc_serial, INSTALL_OPEN, sizeof(unsigned long)); ! 159: ! 160: NODE_METHODS(pc_serial) = { ! 161: { "open", pc_serial_open }, ! 162: { "close", pc_serial_close }, ! 163: { "read", pc_serial_read }, ! 164: { "write", pc_serial_write }, ! 165: }; ! 166: ! 167: void ! 168: ob_pc_serial_init(const char *path, const char *dev_name, uint64_t base, ! 169: uint64_t offset, int intr) ! 170: { ! 171: phandle_t aliases; ! 172: char nodebuff[128]; ! 173: ! 174: snprintf(nodebuff, sizeof(nodebuff), "%s/%s", path, dev_name); ! 175: REGISTER_NAMED_NODE(pc_serial, nodebuff); ! 176: ! 177: push_str(nodebuff); ! 178: fword("find-device"); ! 179: ! 180: push_str("serial"); ! 181: fword("device-type"); ! 182: ! 183: PUSH((base + offset) >> 32); ! 184: fword("encode-int"); ! 185: PUSH((base + offset) & 0xffffffff); ! 186: fword("encode-int"); ! 187: fword("encode+"); ! 188: PUSH(SER_SIZE); ! 189: fword("encode-int"); ! 190: fword("encode+"); ! 191: push_str("reg"); ! 192: fword("property"); ! 193: ! 194: aliases = find_dev("/aliases"); ! 195: set_property(aliases, "ttya", nodebuff, strlen(nodebuff) + 1); ! 196: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.