summaryrefslogtreecommitdiff
path: root/src/lib/uart8250.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/uart8250.c')
-rw-r--r--src/lib/uart8250.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/lib/uart8250.c b/src/lib/uart8250.c
new file mode 100644
index 0000000000..778919b7ff
--- /dev/null
+++ b/src/lib/uart8250.c
@@ -0,0 +1,64 @@
+#ifndef lint
+static char rcsid[] = "$Id$";
+#endif
+
+/* Should support 8250, 16450, 16550, 16550A type uarts */
+#include <arch/io.h>
+#include <uart8250.h>
+
+/* Data */
+#define UART_RBR 0x00
+#define UART_TBR 0x00
+
+/* Control */
+#define UART_IER 0x01
+#define UART_IIR 0x02
+#define UART_FCR 0x02
+#define UART_LCR 0x03
+#define UART_MCR 0x04
+#define UART_DLL 0x00
+#define UART_DLM 0x01
+
+/* Status */
+#define UART_LSR 0x05
+#define UART_MSR 0x06
+#define UART_SCR 0x07
+
+static inline int uart8250_can_tx_byte(unsigned base_port)
+{
+ return inb(base_port + UART_LSR) & 0x20;
+}
+
+static inline void uart8250_wait_to_tx_byte(unsigned base_port)
+{
+ while(!uart8250_can_tx_byte(base_port))
+ ;
+}
+
+static inline void uart8250_wait_until_sent(unsigned base_port)
+{
+ while(!(inb(base_port + UART_LSR) & 0x40))
+ ;
+}
+
+void uart8250_tx_byte(unsigned base_port, unsigned char data)
+{
+ uart8250_wait_to_tx_byte(base_port);
+ outb(data, base_port + UART_TBR);
+ /* Make certain the data clears the fifos */
+ uart8250_wait_until_sent(base_port);
+}
+
+void uart8250_init(unsigned base_port, unsigned divisor, unsigned lcs)
+{
+ lcs &= 0x7f;
+ /* disable interrupts */
+ outb(0x0, base_port + UART_IER);
+ /* enable fifo's */
+ outb(0x01, base_port + UART_FCR);
+ /* Set Baud Rate Divisor to 12 ==> 115200 Baud */
+ outb(0x80 | lcs, base_port + UART_LCR);
+ outb(divisor & 0xFF, base_port + UART_DLL);
+ outb((divisor >> 8) & 0xFF, base_port + UART_DLM);
+ outb(lcs, base_port + UART_LCR);
+}