From 7a6b222e07a52347602843596dfac4a6d7de8006 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Sat, 4 Jan 2014 02:34:16 +0100 Subject: [PATCH] Update kernel/uart.{cpp,h} to current coding conventions. --- kernel/uart.cpp | 293 +++++++++++++++++++++++------------------------- kernel/uart.h | 22 ++-- 2 files changed, 152 insertions(+), 163 deletions(-) diff --git a/kernel/uart.cpp b/kernel/uart.cpp index f2183564..8745dfb8 100644 --- a/kernel/uart.cpp +++ b/kernel/uart.cpp @@ -22,164 +22,153 @@ *******************************************************************************/ +#include +#include +#include + #include #include -#include #include "vga.h" #include "uart.h" -namespace Sortix +namespace Sortix { +namespace UART { + +const unsigned TXR = 0; // Transmit register +const unsigned RXR = 0; // Receive register +const unsigned IER = 1; // Interrupt Enable +const unsigned IIR = 2; // Interrupt ID +const unsigned FCR = 2; // FIFO control +const unsigned LCR = 3; // Line control +const unsigned MCR = 4; // Modem control +const unsigned LSR = 5; // Line Status +const unsigned MSR = 6; // Modem Status +const unsigned DLL = 0; // divisor Latch Low +const unsigned DLM = 1; // divisor latch High + +const unsigned LCR_DLAB = 0x80; // divisor latch access bit +const unsigned LCR_SBC = 0x40; // Set break control +const unsigned LCR_SPAR = 0x20; // Stick parity (?) +const unsigned LCR_EPAR = 0x10; // Even parity select +const unsigned LCR_PARITY = 0x08; // Parity Enable +const unsigned LCR_STOP = 0x04; // Stop bits: 0=1 bit, 1=2 bits +const unsigned LCR_WLEN5 = 0x00; // Wordlength: 5 bits +const unsigned LCR_WLEN6 = 0x01; // Wordlength: 6 bits +const unsigned LCR_WLEN7 = 0x02; // Wordlength: 7 bits +const unsigned LCR_WLEN8 = 0x03; // Wordlength: 8 bits + +const unsigned LSR_TEMT = 0x40; // Transmitter empty +const unsigned LSR_THRE = 0x20; // Transmit-hold-register empty +const unsigned LSR_READY = 0x1; + +const unsigned BASE_BAUD = 1843200 / 16; +const unsigned BOTH_EMPTY = LSR_TEMT | LSR_THRE; + +unsigned ProbeBaud(unsigned port) { - namespace UART - { - const unsigned TXR = 0; // Transmit register - const unsigned RXR = 0; // Receive register - const unsigned IER = 1; // Interrupt Enable - const unsigned IIR = 2; // Interrupt ID - const unsigned FCR = 2; // FIFO control - const unsigned LCR = 3; // Line control - const unsigned MCR = 4; // Modem control - const unsigned LSR = 5; // Line Status - const unsigned MSR = 6; // Modem Status - const unsigned DLL = 0; // Divisor Latch Low - const unsigned DLM = 1; // Divisor latch High + uint8_t lcr = CPU::InPortB(port + LCR); + CPU::OutPortB(port + LCR, lcr | LCR_DLAB); + uint8_t dll = CPU::InPortB(port + DLL); + uint8_t dlm = CPU::InPortB(port + DLM); + CPU::OutPortB(port + LCR, lcr); + unsigned quot = dlm << 8 | dll; - const unsigned LCR_DLAB = 0x80; // Divisor latch access bit - const unsigned LCR_SBC = 0x40; // Set break control - const unsigned LCR_SPAR = 0x20; // Stick parity (?) - const unsigned LCR_EPAR = 0x10; // Even parity select - const unsigned LCR_PARITY = 0x08; // Parity Enable - const unsigned LCR_STOP = 0x04; // Stop bits: 0=1 bit, 1=2 bits - const unsigned LCR_WLEN5 = 0x00; // Wordlength: 5 bits - const unsigned LCR_WLEN6 = 0x01; // Wordlength: 6 bits - const unsigned LCR_WLEN7 = 0x02; // Wordlength: 7 bits - const unsigned LCR_WLEN8 = 0x03; // Wordlength: 8 bits - - const unsigned LSR_TEMT = 0x40; // Transmitter empty - const unsigned LSR_THRE = 0x20; // Transmit-hold-register empty - const unsigned LSR_READY = 0x1; - - const unsigned Port = 0x3f8; - - const unsigned BASE_BAUD = 1843200/16; - const unsigned BOTH_EMPTY = LSR_TEMT | LSR_THRE; - - unsigned ProbeBaud(unsigned Port) - { - uint8_t lcr = CPU::InPortB(Port + LCR); - CPU::OutPortB(Port + LCR, lcr | LCR_DLAB); - uint8_t dll = CPU::InPortB(Port + DLL); - uint8_t dlm = CPU::InPortB(Port + DLM); - CPU::OutPortB(Port + LCR, lcr); - unsigned quot = (dlm << 8) | dll; - - return BASE_BAUD / quot; - } - - void WaitForEmptyBuffers(unsigned Port) - { - while ( true ) - { - unsigned Status = CPU::InPortB(Port + LSR); - - if ( (Status & BOTH_EMPTY) == BOTH_EMPTY ) - { - return; - } - } - } - - unsigned Baud; - - void Init() - { - Baud = ProbeBaud(Port); - - CPU::OutPortB(Port + LCR, 0x3); // 8n1 - CPU::OutPortB(Port + IER, 0); // No interrupt - CPU::OutPortB(Port + FCR, 0); // No FIFO - CPU::OutPortB(Port + MCR, 0x3); // DTR + RTS - - unsigned Divisor = 115200 / Baud; - uint8_t C = CPU::InPortB(Port + LCR); - CPU::OutPortB(Port + LCR, C | LCR_DLAB); - CPU::OutPortB(Port + DLL, Divisor & 0xFF); - CPU::OutPortB(Port + DLM, (Divisor >> 8) & 0xFF); - CPU::OutPortB(Port + LCR, C & ~LCR_DLAB); - } - - void Read(uint8_t* Buffer, size_t Size) - { - // Save the IER and disable interrupts. - unsigned ier = CPU::InPortB(Port + IER); - CPU::OutPortB(Port + IER, 0); - - for ( size_t I = 0; I < Size; I++ ) - { - while ( ! ( CPU::InPortB(Port + LSR) & LSR_READY ) ) { } - - Buffer[I] = CPU::InPortB(Port); - } - - // Wait for transmitter to become empty and restore the IER. - WaitForEmptyBuffers(Port); - CPU::OutPortB(Port + IER, ier); - } - - void Write(const void* B, size_t Size) - { - const uint8_t* Buffer = (const uint8_t*) B; - - // Save the IER and disable interrupts. - unsigned ier = CPU::InPortB(Port + IER); - CPU::OutPortB(Port + IER, 0); - - for ( size_t I = 0; I < Size; I++ ) - { - WaitForEmptyBuffers(Port); - - CPU::OutPortB(Port, Buffer[I]); - } - - // Wait for transmitter to become empty and restore the IER. - WaitForEmptyBuffers(Port); - CPU::OutPortB(Port + IER, ier); - } - - void WriteChar(char C) - { - // Save the IER and disable interrupts. - unsigned ier = CPU::InPortB(Port + IER); - CPU::OutPortB(Port + IER, 0); - - WaitForEmptyBuffers(Port); - - CPU::OutPortB(Port, C); - - // Wait for transmitter to become empty and restore the IER. - WaitForEmptyBuffers(Port); - CPU::OutPortB(Port + IER, ier); - } - - int TryPopChar() - { - // Save the IER and disable interrupts. - unsigned ier = CPU::InPortB(Port + IER); - CPU::OutPortB(Port + IER, 0); - - int Result = -1; - - if ( CPU::InPortB(Port + LSR) & LSR_READY ) - { - Result = CPU::InPortB(Port); - } - - // Wait for transmitter to become empty and restore the IER. - WaitForEmptyBuffers(Port); - CPU::OutPortB(Port + IER, ier); - - return Result; - } - } + return BASE_BAUD / quot; } + +void WaitForEmptyBuffers(unsigned port) +{ + while ( (CPU::InPortB(port + LSR) & BOTH_EMPTY) != BOTH_EMPTY ); +} + +const unsigned PORT = 0x3F8; + +void Init() +{ + unsigned baud = ProbeBaud(PORT); + + CPU::OutPortB(PORT + LCR, 0x3); // 8n1 + CPU::OutPortB(PORT + IER, 0); // No interrupt + CPU::OutPortB(PORT + FCR, 0); // No FIFO + CPU::OutPortB(PORT + MCR, 0x3); // DTR + RTS + + unsigned divisor = 115200 / baud; + uint8_t c = CPU::InPortB(PORT + LCR); + CPU::OutPortB(PORT + LCR, c | LCR_DLAB); + CPU::OutPortB(PORT + DLL, divisor >> 0 & 0xFF); + CPU::OutPortB(PORT + DLM, divisor >> 8 & 0xFF); + CPU::OutPortB(PORT + LCR, c & ~LCR_DLAB); +} + +void Read(uint8_t* buffer, size_t size) +{ + // Save the IER and disable interrupts. + unsigned ier = CPU::InPortB(PORT + IER); + CPU::OutPortB(PORT + IER, 0); + + for ( size_t i = 0; i < size; i++ ) + { + while ( !(CPU::InPortB(PORT + LSR) & LSR_READY) ); + buffer[i] = CPU::InPortB(PORT); + } + + // Wait for transmitter to become empty and restore the IER. + WaitForEmptyBuffers(PORT); + CPU::OutPortB(PORT + IER, ier); +} + +void Write(const void* b, size_t size) +{ + const uint8_t* buffer = (const uint8_t*) b; + + // Save the IER and disable interrupts. + unsigned ier = CPU::InPortB(PORT + IER); + CPU::OutPortB(PORT + IER, 0); + + for ( size_t i = 0; i < size; i++ ) + { + WaitForEmptyBuffers(PORT); + CPU::OutPortB(PORT, buffer[i]); + } + + // Wait for transmitter to become empty and restore the IER. + WaitForEmptyBuffers(PORT); + CPU::OutPortB(PORT + IER, ier); +} + +void WriteChar(char c) +{ + // Save the IER and disable interrupts. + unsigned ier = CPU::InPortB(PORT + IER); + CPU::OutPortB(PORT + IER, 0); + + WaitForEmptyBuffers(PORT); + + CPU::OutPortB(PORT, c); + + // Wait for transmitter to become empty and restore the IER. + WaitForEmptyBuffers(PORT); + CPU::OutPortB(PORT + IER, ier); +} + +int TryPopChar() +{ + // Save the IER and disable interrupts. + unsigned ier = CPU::InPortB(PORT + IER); + CPU::OutPortB(PORT + IER, 0); + + int result = -1; + + if ( CPU::InPortB(PORT + LSR) & LSR_READY ) + result = CPU::InPortB(PORT); + + // Wait for transmitter to become empty and restore the IER. + WaitForEmptyBuffers(PORT); + CPU::OutPortB(PORT + IER, ier); + + return result; +} + +} // namespace UART +} // namespace Sortix diff --git a/kernel/uart.h b/kernel/uart.h index db8b2cae..4c6bd0bc 100644 --- a/kernel/uart.h +++ b/kernel/uart.h @@ -25,16 +25,16 @@ #ifndef SORTIX_UART_H #define SORTIX_UART_H -namespace Sortix -{ - namespace UART - { - void Init(); - void Read(uint8_t* Buffer, size_t Size); - void Write(const void* Buffer, size_t Size); - void WriteChar(char C); - int TryPopChar(); - } -} +namespace Sortix { +namespace UART { + +void Init(); +void Read(uint8_t* buffer, size_t size); +void Write(const void* buffer, size_t size); +void WriteChar(char c); +int TryPopChar(); + +} // namespace UART +} // namespace Sortix #endif