#include "debug/debug.h" #include "common/port.h" #include "scheduler/scheduler.h" #define COM1 0x3f8 #define BOCHS_DBG 1 namespace { bool is_transmit_empty() { return (inb(COM1 + 5) & 0x20) != 0; } void dbgputchar(char c) { while (!is_transmit_empty()); outb(COM1, c); #if BOCHS_DBG outb(0xe9, c); #endif } void dbg(const glcr::StringView& str) { for (uint64_t i = 0; i < str.size(); i++) { dbgputchar(str[i]); } } void AddProcPrefix() { if (gScheduler != nullptr) { auto t = gScheduler->CurrentThread(); char buffer[16]; glcr::FixedStringBuilder builder(buffer, 16); glcr::StrFormatIntoBuffer(builder, "[{}.{}] ", t->pid(), t->tid()); dbg(builder); } } } // namespace void dbgln(const glcr::StringView& str) { AddProcPrefix(); dbg(str); dbg("\n"); } namespace { // Helper function to write a byte to a specified COM1 register offset void write_serial_port(uint16_t offset, uint8_t value) { outb(COM1 + offset, value); } // Helper function to read a byte from a specified COM1 register offset uint8_t read_serial_port(uint16_t offset) { return inb(COM1 + offset); } } // namespace namespace serial { // Function to initialize the serial port with a given baud rate void initialize(uint32_t baud_rate) { // Disable interrupts write_serial_port(1, 0x00); // Enable DLAB (Divisor Latch Access Bit) in Line Control Register (LCR) write_serial_port(3, read_serial_port(3) | 0x80); // Calculate the divisor // Baud rate = 115200 / divisor (approximately) uint16_t divisor = 115200 / baud_rate; // Set the low byte of the divisor write_serial_port(0, divisor & 0xFF); // Set the high byte of the divisor write_serial_port(1, (divisor >> 8) & 0xFF); // Clear DLAB and set data bits, stop bits, and parity // 8 data bits, 1 stop bit, no parity write_serial_port(3, 0x03); // 00000011b // Enable FIFO, clear buffers, set trigger level (e.g., 1 byte) write_serial_port(2, 0xC7); // 11000111b // Enable IRQs (optional, for interrupt-driven communication) // write_serial_port(1, 0x01); // Set Modem Control Register (MCR) // Enable RTS, DTR, OUT1, OUT2, loopback off, IRQs enabled write_serial_port(4, 0x0B); // 00001011b } } // namespace serial