diff options
Diffstat (limited to 'mubios/drivers')
| -rw-r--r-- | mubios/drivers/ata.c | 3 | ||||
| -rw-r--r-- | mubios/drivers/ioapic.c | 2 | ||||
| -rw-r--r-- | mubios/drivers/kbd.c | 12 | ||||
| -rw-r--r-- | mubios/drivers/serial.c | 113 | ||||
| -rw-r--r-- | mubios/drivers/vga.c | 27 |
5 files changed, 134 insertions, 23 deletions
diff --git a/mubios/drivers/ata.c b/mubios/drivers/ata.c index 86bab21..7d23a9c 100644 --- a/mubios/drivers/ata.c +++ b/mubios/drivers/ata.c @@ -96,8 +96,7 @@ ata_read_transfer28 (u32 lba, u16 *buffer, u16 count) for (sector = 0; sector < count; ++sector) { status = ata_wait_not_busy (); - if ((status & ATA_STATUS_ERR) != 0 - || (status & ATA_STATUS_DRQ) == 0) + if ((status & ATA_STATUS_ERR) != 0 || (status & ATA_STATUS_DRQ) == 0) return 1; for (index = 0; index < 256; ++index) diff --git a/mubios/drivers/ioapic.c b/mubios/drivers/ioapic.c index 7a0b6cb..552f497 100644 --- a/mubios/drivers/ioapic.c +++ b/mubios/drivers/ioapic.c @@ -84,7 +84,7 @@ ioapic_mask_all (void) for (pin = 0; pin <= maximum_pin; ++pin) { ioapic_write ((u8)(IOAPIC_REDIRECTION_BASE + 2u * pin), - IOAPIC_REDIRECTION_MASK); + IOAPIC_REDIRECTION_MASK); ioapic_write ((u8)(IOAPIC_REDIRECTION_BASE + 2u * pin + 1u), 0); } } diff --git a/mubios/drivers/kbd.c b/mubios/drivers/kbd.c index 4de0a96..eb99e70 100644 --- a/mubios/drivers/kbd.c +++ b/mubios/drivers/kbd.c @@ -33,9 +33,9 @@ /* * 8042 command byte bits. - * Bit 0 enables the keyboard IRQ, bit 1 the auxiliary port IRQ, bit 4 and bit 5 - * hold the keyboard and auxiliary clock, and bit 6 selects set 1 scan codes on - * the keyboard interface. + * Bit 0 enables the keyboard IRQ, bit 1 the auxiliary port IRQ, bit 4 and bit + * 5 hold the keyboard and auxiliary clock, and bit 6 selects set 1 scan codes + * on the keyboard interface. */ #define KBD_CONFIG_IRQ1 0x01u #define KBD_CONFIG_IRQ12 0x02u @@ -103,7 +103,8 @@ kbd_init (void) /* Disable both ports before the controller is reconfigured. */ kbd_write_command (KBD_CMD_DISABLE_KBD); - /* Drain the self-test and any pending scan code left in the output buffer. */ + /* Drain the self-test and any pending scan code left in the output buffer. + */ while ((io_in8 (KBD_STATUS_PORT) & KBD_STATUS_OBF) != 0u) (void)io_in8 (KBD_DATA_PORT); @@ -115,7 +116,8 @@ kbd_init (void) config = io_in8 (KBD_DATA_PORT); - config &= (u8)~(KBD_CONFIG_DISABLE_KBD_CLOCK | KBD_CONFIG_DISABLE_AUX_CLOCK); + config + &= (u8) ~(KBD_CONFIG_DISABLE_KBD_CLOCK | KBD_CONFIG_DISABLE_AUX_CLOCK); config |= KBD_CONFIG_IRQ1 | KBD_CONFIG_IRQ12 | KBD_CONFIG_TRANSLATE; if (kbd_write_command (KBD_CMD_WRITE_CONFIG) != 0) diff --git a/mubios/drivers/serial.c b/mubios/drivers/serial.c index 3da2093..c8b9adf 100644 --- a/mubios/drivers/serial.c +++ b/mubios/drivers/serial.c @@ -30,6 +30,7 @@ #define COM_LCR_OFFSET 0x03u #define COM_MCR_OFFSET 0x04u #define COM_LSR_OFFSET 0x05u +#define COM_MSR_OFFSET 0x06u #define COM_LCR_DLAB 0x80u #define COM_LCR_8N1 0x03u @@ -44,6 +45,12 @@ #define COM_MCR_OUT2 0x08u #define COM_LSR_THRE 0x20u +#define COM_LSR_IDLE 0x40u +#define COM_LSR_DATA_READY 0x01u +#define BIOS_SERIAL_TIMEOUT 0x80u + +#define PIT_COUNTER0 0x0040u +#define PIT_COMMAND 0x0043u static u16 com1_port (u16 offset) @@ -51,6 +58,112 @@ com1_port (u16 offset) return (u16)(COM1_BASE + offset); } +/* Latching channel 0 works while the protected-mode service has IRQs off. */ +u16 +serial_timer_counter (void) +{ + u16 counter; + + io_out8 (PIT_COMMAND, 0x00u); + counter = io_in8 (PIT_COUNTER0); + counter |= (u16)((u16)io_in8 (PIT_COUNTER0) << 8); + return counter; +} + +static int +serial_wait (u16 base, u8 mask, u8 timeout, u8 *status) +{ + u16 previous; + u16 current; + u32 elapsed; + u32 duration; + + previous = serial_timer_counter (); + elapsed = 0; + /* One BDA timeout unit is one 65536-clock BIOS timer tick. */ + duration = (u32)timeout << 16; + + for (;;) + { + *status = io_in8 ((u16)(base + COM_LSR_OFFSET)); + if ((*status & mask) == mask) + return 1; + + if (elapsed >= duration) + { + *status |= BIOS_SERIAL_TIMEOUT; + return 0; + } + + current = serial_timer_counter (); + elapsed += (u16)(previous - current); + previous = current; + } +} + +u16 +serial_status (u16 base) +{ + u8 line; + u8 modem; + + line = io_in8 ((u16)(base + COM_LSR_OFFSET)); + modem = io_in8 ((u16)(base + COM_MSR_OFFSET)); + return (u16)(((u16)line << 8) | modem); +} + +u16 +serial_configure (u16 base, u8 parameters) +{ + static const u16 divisors[] + = { 1047u, 768u, 384u, 192u, 96u, 48u, 24u, 12u }; + u16 divisor; + + /* INT 14h AL: bits 7:5 select baud; bits 4:0 are the UART format. */ + divisor = divisors[parameters >> 5]; + io_out8 ((u16)(base + COM_LCR_OFFSET), COM_LCR_DLAB); + io_out8 ((u16)(base + COM_DATA_OFFSET), (u8)divisor); + io_out8 ((u16)(base + COM_IER_OFFSET), (u8)(divisor >> 8)); + io_out8 ((u16)(base + COM_LCR_OFFSET), parameters & 0x1Fu); + /* Do not reset the FIFO here: pending terminal input must survive. */ + return serial_status (base); +} + +u8 +serial_transmit (u16 base, u8 value, u8 timeout) +{ + u8 status; + + if (serial_wait (base, COM_LSR_THRE | COM_LSR_IDLE, timeout, &status)) + io_out8 ((u16)(base + COM_DATA_OFFSET), value); + + return status; +} + +u8 +serial_receive (u16 base, u8 *value, u8 timeout) +{ + u8 status; + + if (serial_wait (base, COM_LSR_DATA_READY, timeout, &status)) + *value = io_in8 ((u16)(base + COM_DATA_OFFSET)); + + return status; +} + +int +serial_try_receive (u16 base, u8 *value) +{ + u8 status; + + status = io_in8 ((u16)(base + COM_LSR_OFFSET)); + if ((status & COM_LSR_DATA_READY) == 0u) + return 0; + + *value = io_in8 ((u16)(base + COM_DATA_OFFSET)); + return 1; +} + void serial_init (void) { diff --git a/mubios/drivers/vga.c b/mubios/drivers/vga.c index 57e1f8f..16f88e5 100644 --- a/mubios/drivers/vga.c +++ b/mubios/drivers/vga.c @@ -35,8 +35,7 @@ #define VGA_ATTR_INDEX_DATA 0x03C0u static void -vga_write_registers (u16 index_port, u16 data_port, const u8 *values, - u8 count) +vga_write_registers (u16 index_port, u16 data_port, const u8 *values, u8 count) { u8 index; @@ -50,19 +49,17 @@ vga_write_registers (u16 index_port, u16 data_port, const u8 *values, void vga_text_mode_init (void) { - static const u8 sequencer[] = {0x00u, 0x00u, 0x03u, 0x00u, 0x02u}; - static const u8 crtc[] = {0x5Fu, 0x4Fu, 0x50u, 0x82u, 0x55u, 0x81u, - 0xBFu, 0x1Fu, 0x00u, 0x4Fu, 0x0Du, 0x0Eu, - 0x00u, 0x00u, 0x00u, 0x00u, 0x9Cu, 0x8Eu, - 0x8Fu, 0x28u, 0x1Fu, 0x96u, 0xB9u, 0xA3u, - 0xFFu}; - static const u8 graphics[] = {0x00u, 0x00u, 0x00u, 0x00u, 0x00u, - 0x10u, 0x0Fu, 0x00u, 0xFFu}; - static const u8 attributes[] = {0x00u, 0x01u, 0x02u, 0x03u, 0x04u, - 0x05u, 0x06u, 0x07u, 0x08u, 0x09u, - 0x0Au, 0x0Bu, 0x0Cu, 0x0Du, 0x0Eu, - 0x0Fu, 0x0Cu, 0x00u, 0x0Fu, 0x08u, - 0x00u}; + static const u8 sequencer[] = { 0x00u, 0x00u, 0x03u, 0x00u, 0x02u }; + static const u8 crtc[] + = { 0x5Fu, 0x4Fu, 0x50u, 0x82u, 0x55u, 0x81u, 0xBFu, 0x1Fu, 0x00u, + 0x4Fu, 0x0Du, 0x0Eu, 0x00u, 0x00u, 0x00u, 0x00u, 0x9Cu, 0x8Eu, + 0x8Fu, 0x28u, 0x1Fu, 0x96u, 0xB9u, 0xA3u, 0xFFu }; + static const u8 graphics[] + = { 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x0Fu, 0x00u, 0xFFu }; + static const u8 attributes[] + = { 0x00u, 0x01u, 0x02u, 0x03u, 0x04u, 0x05u, 0x06u, + 0x07u, 0x08u, 0x09u, 0x0Au, 0x0Bu, 0x0Cu, 0x0Du, + 0x0Eu, 0x0Fu, 0x0Cu, 0x00u, 0x0Fu, 0x08u, 0x00u }; volatile u16 *video; volatile u8 *bda; u16 cell; |
