Annotation of qemu/roms/openbios/drivers/pc_serial.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.