/* Functions related to both serial console output/intput device driver */ static int init(void* device, void* data) { if(serial_enabled) return 0; // Already enabled if((port_in8(SERIAL_IO_ADDR + 0x05) == 0xFF) && (port_in8(SERIAL_IO_ADDR + 0x06) == 0xFF)) { serial_enabled = false; return -1; } /* Disable interrupts. */ port_out8(SERIAL_IO_ADDR + 0x01, 0); /* Assert RTS and DTR. */ port_out8(SERIAL_IO_ADDR + 0x04, 3); /* Set the Line control register to user divisor latch. */ uint8_t reg = port_in8(SERIAL_IO_ADDR + 0x03); port_out8(SERIAL_IO_ADDR + 0x03, reg | 0x80); /* Set the divisor latch for speed. */ int speed = SERIAL_SPEED; // Full speed uint16_t divisor = 115200 / speed; port_out8(SERIAL_IO_ADDR + 0x00, divisor & 0xFF); port_out8(SERIAL_IO_ADDR + 0x01, divisor >> 8); /* Restore the previous value of the divisor. * * And set 8 bits per character */ port_out8(SERIAL_IO_ADDR + 0x03, (reg & ~0x80)); serial_enabled = true; return 0; }
/* Functions related to serial console output device driver */ static void serial_putchar(uint8_t ch) { while((port_in8(SERIAL_IO_ADDR + 0x05) & 0x20) == 0); // Wait till empty port_out8(SERIAL_IO_ADDR, ch); if(ch == '\n') serial_putchar('\r'); }
void apic_activate() { // Disable PIT #define PIT_FREQUENCY 1193180 #define PIT_COUNTER0 0x40 #define PIT_COUNTER1 0x41 #define PIT_COUNTER2 0x42 #define PIT_COMMAND 0x43 #define PIT_CHANNEL0 0x00 #define PIT_CHANNEL1 0x40 #define PIT_CHANNEL2 0x60 #define PIT_LATCH 0x00 #define PIT_LOW 0x10 #define PIT_HIGH 0x20 #define PIT_LOWHIGH 0x30 #define PIT_MODE0 0x00 #define PIT_MODE1 0x02 #define PIT_MODE2 0x04 #define PIT_MODE3 0x06 #define PIT_MODE4 0x08 #define PIT_MODE5 0x0a #define PIT_MODE6 0x0c #define PIT_MODE7 0x0e #define PIT_BIN 0x00 #define PIT_BCD 0x01 port_out8(PIT_COMMAND, PIT_CHANNEL0 | PIT_LOWHIGH | PIT_MODE0 | PIT_BIN); uint16_t interval = 0; port_out8(PIT_COUNTER0, (interval >> 0) & 0xff); port_out8(PIT_COUNTER0, (interval >> 8) & 0xff); // Disable PIC(mask all) #define PIC_MASTER_PORT2 0x21 #define PIC_SLAVE_PORT2 0xa1 port_out8(PIC_MASTER_PORT2, 0xff); port_out8(PIC_SLAVE_PORT2, 0xff); printf("\tActivate local APICs...\n"); void _apic_activate(); _apic_activate(); }
static void vga_move_cursor(uint_t row, uint_t column) { uint_t position; /* assert(row >= 0); */ assert(row < VGA_ROWS); /* assert(column >= 0); */ assert(column < VGA_COLUMNS); position = (row * VGA_COLUMNS + column); port_out8(VGA_COMMAND_PORT, VGA_SET_CURSOR_HIGH); port_out8(VGA_DATA_PORT, (position >> 8)); port_out8(VGA_COMMAND_PORT, VGA_SET_CURSOR_LOW); port_out8(VGA_DATA_PORT, (position & 0xFF)); }
// 0xff0000: hour, 0xff00: minute, 0xff: second static uint32_t rtc_time() { uint32_t result = 0; uint32_t tmp; port_out8(RTC_ADDRESS, RTC_ADDR_HOUR); tmp = port_in8(RTC_DATA); result |= BCD(tmp) << 16; port_out8(RTC_ADDRESS, RTC_ADDR_MINUTE); tmp = port_in8(RTC_DATA); result |= BCD(tmp) << 8; port_out8(RTC_ADDRESS, RTC_ADDR_SECOND); tmp = port_in8(RTC_DATA); result |= BCD(tmp) << 0; return result; }
// 0xff000000: year, 0xff0000: month, 0xff00: day of month, 0xff: day of week static uint32_t rtc_date() { uint32_t result = 0; uint32_t tmp; port_out8(RTC_ADDRESS, RTC_ADDR_YEAR); tmp = port_in8(RTC_DATA); result |= BCD(tmp) << 24; port_out8(RTC_ADDRESS, RTC_ADDR_MONTH); tmp = port_in8(RTC_DATA); result |= BCD(tmp) << 16; port_out8(RTC_ADDRESS, RTC_ADDR_DATE); tmp = port_in8(RTC_DATA); result |= BCD(tmp) << 8; port_out8(RTC_ADDRESS, RTC_ADDR_WEEK); tmp = port_in8(RTC_DATA); result |= BCD(tmp) << 0; return result; }
int vga_init(void) { assert(!initialized); vga.base = (uint8_t *) VGA_BASE; vga.row = 0; vga.column = 0; /* * NOTE: * Set the first scan line for the cursor, and the blinking * mode. First scan line is 11, so that we have a visible * cursor. */ port_out8(VGA_COMMAND_PORT, VGA_SET_CURSOR_START); port_out8(VGA_DATA_PORT, ((0x2 << 5) | 11)); vga_clear(); initialized = 1; return 1; }