From 71182acb6682b32fd254f40e463bb0b344169b13 Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Fri, 12 Feb 2021 20:23:57 +0200 Subject: Add SerialPort self-test to constructor --- .clang-format | 3 ++- drivers/serial.cc | 34 ++++++++++++++++++++-------------- drivers/serial.h | 8 +++++--- src/kernel.cc | 2 +- 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/.clang-format b/.clang-format index ec6cc2c..e490b56 100644 --- a/.clang-format +++ b/.clang-format @@ -2,6 +2,7 @@ BasedOnStyle: Chromium ColumnLimit: '120' AccessModifierOffset: '-2' -AllowShortBlocksOnASingleLine: true +AllowShortIfStatementsOnASingleLine: true +AllowShortLoopsOnASingleLine: true ... diff --git a/drivers/serial.cc b/drivers/serial.cc index 84dd4b0..22b8051 100644 --- a/drivers/serial.cc +++ b/drivers/serial.cc @@ -5,22 +5,18 @@ * |dla| | parity | s | data | */ enum LineControlRegister : uint8_t { - // data bits - d5bit = 0b00000000, + d5bit = 0b00000000, // data bits d6bit = 0b00000001, d7bit = 0b00000010, d8bit = 0b00000011, - // parity bits - none = 0b00000000, + none = 0b00000000, // parity bits odd = 0b00001000, even = 0b00011000, mark = 0b00101000, space = 0b00111000, - // stop bits - s1bit = 0b00000000, + s1bit = 0b00000000, // stop bits s2bit = 0b00000100, // 1.5 for 5bit data; 2 otherwise - // divisor latch access bit - dlab = 0b10000000, + dlab = 0b10000000, // divisor latch access bit }; /* Line Status Register */ @@ -35,6 +31,10 @@ enum LineStatusRegister : uint8_t { ERRO = 0b10000000, // impending error: see if there is an error with a word in the input buffer }; +// TODO InterruptControlRegister +// TODO FifoControlRegister +// TODO ModemControlRegister + SerialPort::SerialPort() { /* * The serial controller (UART) has a baud rate of 115200 ticks per second; to limit the speed of the port set the @@ -54,6 +54,16 @@ SerialPort::SerialPort() { port.write(0xc7, FifoControl); // enable FIFO, clear, with 14-byte threshold port.write(0x0b, ModemControl); // IRQ enabled, RTS/DSR set + + // test serial port + port.write(0x1e, ModemControl); // set in loopback mode + port.write(0xae); // write 0xae to port + self_check_okay = (port.read() == 0xae); + + // if not faulty, set in normal operation mode + if (self_check_okay) { + port.write(0x0f, ModemControl); + } } bool SerialPort::ready_read() { @@ -61,9 +71,7 @@ bool SerialPort::ready_read() { } uint8_t SerialPort::read() { - while (!ready_read()) { - asm volatile("nop"); - } + while (!ready_read()) asm volatile("nop"); return port.read(); } @@ -72,9 +80,7 @@ bool SerialPort::ready_write() { } void SerialPort::write(char c) { - while (!ready_write()) { - asm volatile("nop"); - } + while (!ready_write()) asm volatile("nop"); switch (c) { case '\n': diff --git a/drivers/serial.h b/drivers/serial.h index 0579dd4..896d831 100644 --- a/drivers/serial.h +++ b/drivers/serial.h @@ -16,20 +16,22 @@ public: SerialPort(); ~SerialPort() = default; + bool self_check() const { return self_check_okay; } + bool ready_read(); uint8_t read(); bool ready_write(); void write(char c) override; void write(ViewIterator& iter) override { - while (iter) { - write(iter.next()); - } + while (iter) write(iter.next()); } void update_cursor() override {} private: + bool self_check_okay; + enum PortOffset : uint16_t { BaudDiv_l = 0, // if dlab is set BaudDiv_h = 1, // if dlab is set diff --git a/src/kernel.cc b/src/kernel.cc index 624f472..1139e3b 100644 --- a/src/kernel.cc +++ b/src/kernel.cc @@ -20,7 +20,7 @@ void dump_gdt(); void kernel_main([[maybe_unused]] uint32_t mb_magic, [[maybe_unused]] uint32_t mb_addr) { SerialPort s0; - Console::set(&s0); + if (s0.self_check()) Console::set(&s0); CGA terminal; Console::set(&terminal); -- cgit v1.2.1