From d1ff7bcc91886626dc9060ec5fb67ee102ab7c1d Mon Sep 17 00:00:00 2001 From: Jon Santmyer Date: Mon, 11 Mar 2024 21:30:31 -0400 Subject: usermode capable kernel with logging syscall --- arch/x86_64/serial.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 arch/x86_64/serial.c (limited to 'arch/x86_64/serial.c') diff --git a/arch/x86_64/serial.c b/arch/x86_64/serial.c new file mode 100644 index 0000000..1b49e3f --- /dev/null +++ b/arch/x86_64/serial.c @@ -0,0 +1,62 @@ +#include "serial.h" +#include "uart.h" +#include "io/log.h" + +static struct LogDevice s_serial_logdev = + { .out = serial_out, .chain = NULL }; + +bool serial_supported = true; + +void +serial_setup(void) +{ + /* Disable interrupts. */ + poutb(SERIAL_UART_COM_IER(SERIAL_UART_COM1), 0x0); + /* Enable DLAB. */ + poutb(SERIAL_UART_COM_LCR(SERIAL_UART_COM1), 0x80); + /* Set divisor to 3 (38400 baud)*/ + poutb(SERIAL_UART_COM_DLAB_DLL(SERIAL_UART_COM1), 3); + poutb(SERIAL_UART_COM_DLAB_DLH(SERIAL_UART_COM1), 0); + /* Set flags for LCR (8 bits, no parity, one stop)*/ + poutb(SERIAL_UART_COM_LCR(SERIAL_UART_COM1), 1 | 2); + /* Enable & clear FIFO, 14-byte threshold */ + poutb(SERIAL_UART_COM_FCR(SERIAL_UART_COM1), 1 | 2 | 4 | 0xC0); + /* Enable interrupts, set RTS/DSR. */ + poutb(SERIAL_UART_COM_MCR(SERIAL_UART_COM1), 1 | 2 | 8); + /* Set loopback mode for testing. */ + poutb(SERIAL_UART_COM_MCR(SERIAL_UART_COM1), 2 | 4 | 8 | 0x10); + /* Test serial output. */ + poutb(SERIAL_UART_COM1, 0xAE); + if(pinb(SERIAL_UART_COM1) != 0xAE) { + serial_supported = false; + return; + } + + /* Serial is not faulty. + * No loopback, enable output 1 & 2.*/ + poutb(SERIAL_UART_COM_MCR(SERIAL_UART_COM1), 1 | 2 | 4 | 8); + + klog_newdev(&s_serial_logdev); +} + +static ALWAYS_INLINE bool +serial_transmit_empty(uint16_t com) +{ + return pinb(SERIAL_UART_COM_LSR(com) & 0x20); +} + +static inline void +serial_outb(uint16_t com, uint8_t b) +{ + if(b == '\n') serial_outb(com, '\r'); + while(!serial_transmit_empty(SERIAL_UART_COM1)); + poutb(com, b); +} + +void +serial_out(const char *s, size_t len) +{ + if(!serial_supported) return; + for(; len > 0; len--) + serial_outb(SERIAL_UART_COM1, *(s++)); +} -- cgit v1.2.1