From a5699a141dcfaa3c1c605d70316ce5b08dfcf0c2 Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Fri, 23 Apr 2021 17:25:40 +0300 Subject: [PATCH] Kernel: Add a put_char(char) method to SerialDevice This can be used to print a single char to the serial port the SerialDevice instance handles. --- Kernel/Devices/SerialDevice.cpp | 15 ++++++++++++++- Kernel/Devices/SerialDevice.h | 3 +++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Kernel/Devices/SerialDevice.cpp b/Kernel/Devices/SerialDevice.cpp index 3198cc9e88..7daec69cd7 100644 --- a/Kernel/Devices/SerialDevice.cpp +++ b/Kernel/Devices/SerialDevice.cpp @@ -56,11 +56,24 @@ KResultOr SerialDevice::write(FileDescription&, u64, const UserOrKernelB return buffer.read_buffered<128>(size, [&](u8 const* data, size_t data_size) { for (size_t i = 0; i < data_size; i++) - IO::out8(m_base_addr, data[i]); + put_char(data[i]); return data_size; }); } +void SerialDevice::put_char(char ch) +{ + while ((get_line_status() & EmptyTransmitterHoldingRegister) == 0) + ; + + if (ch == '\n' && !m_last_put_char_was_carriage_return) + IO::out8(m_base_addr, '\r'); + + IO::out8(m_base_addr, ch); + + m_last_put_char_was_carriage_return = (ch == '\r'); +} + String SerialDevice::device_name() const { return String::formatted("ttyS{}", minor() - 64); diff --git a/Kernel/Devices/SerialDevice.h b/Kernel/Devices/SerialDevice.h index 7a0205429a..1bd05c944b 100644 --- a/Kernel/Devices/SerialDevice.h +++ b/Kernel/Devices/SerialDevice.h @@ -27,6 +27,8 @@ public: virtual bool can_write(const FileDescription&, size_t) const override; virtual KResultOr write(FileDescription&, u64, const UserOrKernelBuffer&, size_t) override; + void put_char(char); + enum InterruptEnable { LowPowerMode = 0x01 << 5, SleepMode = 0x01 << 4, @@ -129,6 +131,7 @@ private: WordLength m_word_length { EightBits }; bool m_break_enable { false }; u8 m_modem_control { 0 }; + bool m_last_put_char_was_carriage_return { false }; }; }