From 90a6065691beee52bf5309916fba98f7580d27be Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Sat, 3 Feb 2024 00:50:07 -0500 Subject: refactor, new arch dirs, (wip) page alloc on write, hsv screen (convert to userspace later), other fixes --- src/arch/amd64/drivers/serial.c | 48 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/arch/amd64/drivers/serial.c (limited to 'src/arch/amd64/drivers/serial.c') diff --git a/src/arch/amd64/drivers/serial.c b/src/arch/amd64/drivers/serial.c new file mode 100644 index 0000000..b9e351e --- /dev/null +++ b/src/arch/amd64/drivers/serial.c @@ -0,0 +1,48 @@ +#include + +#include "../bindings.h" + +#define PORT 0x3F8 + +// initialize the specified COM port for serial +// see https://wiki.osdev.org/Serial_Ports +// and https://en.wikibooks.org/wiki/Serial_Programming/8250_UART_Programming +int serial_init(void) { + outb(PORT + 1, 0x00); // disable interrupts + outb(PORT + 3, 0x80); // enable DLAB (divisor latch access bit) + outb(PORT + 0, 0x03); // (lo) Set baud divisor to 3 38400 baud + outb(PORT + 1, 0x00); // (hi) + outb(PORT + 3, 0x03); // disable DLAB, set 8 bits per word, one stop bit, no parity + outb(PORT + 2, 0xC7); // enable and clear FIFOs, set to maximum threshold + // outb(port + 4, 0x0B); // TODO copied this from osdev wiki but i don't think you need it here + outb(PORT + 4, 0x1E); // set in loopback mode for test + outb(PORT + 0, 0xAE); // test by sending 0xAE + + uint8_t response = inb(PORT + 0); + if (response != 0xAE) { + // TODO panic here? + return -1; + } + + // disable loopback, enable IRQs + outb(PORT + 4, 0x0F); + return 0; +} + +uint8_t serial_in(void) { + // wait for data to be available + while ((inb(PORT + 5) & 0x01) == 0); + return inb(PORT); +} + +void serial_out(uint8_t ch) { + // wait for output to be free + while ((inb(PORT + 5) & 0x20) == 0); + outb(PORT, ch); +} + +void serial_out_str(const char *str) { + for (; *str != '\0'; str++) { + serial_out(*str); + } +} -- cgit v1.2.3-freya