#include "uart_16550.h" #include int uart_thre(unsigned short port) { return inb(port + LineStatus) & THRE; } void uart_putc(const FILE *self, char a) { const unsigned short port = (unsigned short)self->id; while (uart_thre(port) == 0) {} outb((unsigned char)a, port); if (a == '\n') { while (uart_thre(port) == 0) {} outb('\r', port); } } int uart_puts(const FILE *self, const char *string, int length) { int i; int written = 0; if (length == -1) while (*string != '\0') { uart_putc(self, *string); ++string; ++written; } else for (i = 0; i < length; ++i) { uart_putc(self, string[i]); ++written; } return written; } void uart_flush(__attribute__((unused)) const FILE *self) { } FILE uart_stream; FILE * uart_init(unsigned short port) { outb(0x00, port + 1); /* Disable all interrupts */ outb(0x80, port + 3); /* Enable DLAB (set baud rate divisor) */ outb(0x03, port + 0); /* Set divisor to 3 (lo byte) 38400 baud */ outb(0x00, port + 1); /* (hi byte) */ outb(0x03, port + 3); /* 8 bits, no parity, one stop bit */ outb(0xc7, port + 2); /* Enable FIFO, clear them, with 14-byte threshold */ outb(0x0b, port + 4); /* IRQs enabled, RTS/DSR set */ outb(0x1e, port + 4); /* Set in loopback mode, test the serial chip */ outb(0xae, port + 0); /* Test serial chip (send byte 0xAE and check if serial */ /* returns same byte) */ /* Check if serial is faulty (i.e: not same byte as sent) */ if (inb(port + 0) != 0xae) { return NULL; } /* If serial is not faulty set it in normal operation mode */ /* (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled) */ outb(0x0f, port + 4); uart_stream.id = port; uart_stream.putc = &uart_putc; uart_stream.puts = &uart_puts; uart_stream.flush = &uart_flush; return &uart_stream; }