2 * Copyright (C) 2003, 2004 Stefan Reinauer
4 * See the file "COPYING" for further information about
5 * the copyright and warranty status of this work.
9 #include "libopenbios/bindings.h"
10 #include "kernel/kernel.h"
11 #include "drivers/drivers.h"
12 #include "libc/vsprintf.h"
14 /* ******************************************************************
15 * serial console functions
16 * ****************************************************************** */
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
32 int uart_charav(int port
)
34 return ((inb(LSR(port
)) & 1) != 0);
37 char uart_getchar(int port
)
39 while (!uart_charav(port
));
40 return ((char) inb(RBR(port
)) & 0177);
43 static void uart_putchar(int port
, unsigned char c
)
46 uart_putchar(port
, '\r');
47 while (!(inb(LSR(port
)) & 0x20));
51 static void uart_init_line(int port
, unsigned long baud
)
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
));
80 for (i
= 10; i
> 0; i
--) {
81 if (inb(LSR(port
)) == (unsigned int) 0)
87 #ifdef CONFIG_DEBUG_CONSOLE_SERIAL
88 int uart_init(int port
, unsigned long speed
)
90 uart_init_line(port
, speed
);
94 void serial_putchar(int c
)
96 uart_putchar(CONFIG_SERIAL_PORT
, (unsigned char) (c
& 0xff));
100 /* ( addr len -- actual ) */
102 pc_serial_read(unsigned long *address
)
108 addr
= (char *)POP();
111 printk("pc_serial_read: bad len, addr %lx len %x\n", (unsigned long)addr
, len
);
113 if (uart_charav(*address
)) {
114 *addr
= (char)uart_getchar(*address
);
121 /* ( addr len -- actual ) */
123 pc_serial_write(unsigned long *address
)
129 addr
= (unsigned char *)POP();
131 for (i
= 0; i
< len
; i
++) {
132 uart_putchar(*address
, addr
[i
]);
138 pc_serial_close(void)
143 pc_serial_open(unsigned long *address
)
150 fword("ihandle>phandle");
151 ph
= (phandle_t
)POP();
152 prop
= (unsigned long *)get_property(ph
, "address", &len
);
158 DECLARE_UNNAMED_NODE(pc_serial
, INSTALL_OPEN
, sizeof(unsigned long));
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
},
168 ob_pc_serial_init(const char *path
, const char *dev_name
, uint64_t base
,
169 uint64_t offset
, int intr
)
174 snprintf(nodebuff
, sizeof(nodebuff
), "%s/%s", path
, dev_name
);
175 REGISTER_NAMED_NODE(pc_serial
, nodebuff
);
178 fword("find-device");
181 fword("device-type");
183 PUSH((base
+ offset
) >> 32);
185 PUSH((base
+ offset
) & 0xffffffff);
194 aliases
= find_dev("/aliases");
195 set_property(aliases
, "ttya", nodebuff
, strlen(nodebuff
) + 1);