From 9a1b5d0ff2177f3ef4f15c66d6aaf04b2c76df4e Mon Sep 17 00:00:00 2001 From: Dor Laor <dor@cloudius-systems.com> Date: Sun, 7 Apr 2013 11:42:31 +0300 Subject: [PATCH] Adding read line support to the console Now our Isa serial device can read characters. Using it by calling readln(char *msg, size_t len); Note that the calls block until the len input chars or a newline. --- core/debug.cc | 5 +++++ drivers/console.cc | 10 ++++++++++ drivers/console.hh | 2 ++ drivers/debug-console.cc | 5 +++++ drivers/debug-console.hh | 1 + drivers/isa-serial.cc | 15 +++++++++++++++ drivers/isa-serial.hh | 8 ++++++++ include/debug.hh | 3 +++ 8 files changed, 49 insertions(+) diff --git a/core/debug.cc b/core/debug.cc index e01c5cf19..136345b4d 100644 --- a/core/debug.cc +++ b/core/debug.cc @@ -153,6 +153,11 @@ extern "C" { console::write(msg, strlen(msg), true); } + void readln(char *msg, size_t size) + { + console::read(msg, size); + } + void debug_write(const char *msg, size_t len) { console::write(msg, len, false); diff --git a/drivers/console.cc b/drivers/console.cc index e4bc08526..69934611b 100755 --- a/drivers/console.cc +++ b/drivers/console.cc @@ -18,6 +18,16 @@ void write(const char *msg, size_t len, bool lf) console.newline(); } +void read(char *msg, size_t len) +{ + for (size_t i = 0; i < len; i++) { + msg[i] = console.readch(); + write(&msg[i],1,false); + if (msg[i] == '\r') + break; + } +} + } static int diff --git a/drivers/console.hh b/drivers/console.hh index 6c338a4ae..bb8f9d698 100644 --- a/drivers/console.hh +++ b/drivers/console.hh @@ -7,12 +7,14 @@ class Console { public: virtual ~Console() {} virtual void write(const char *str, size_t len) = 0; + virtual char readch() = 0; virtual void newline() = 0; }; namespace console { void write(const char *msg, size_t len, bool lf); +void read(char *msg, size_t len); } diff --git a/drivers/debug-console.cc b/drivers/debug-console.cc index 523fc6b82..e1647f54d 100644 --- a/drivers/debug-console.cc +++ b/drivers/debug-console.cc @@ -14,3 +14,8 @@ void debug_console::newline() { with_lock(_lock, [=] { _impl.newline(); }); } + +char debug_console::readch() +{ + return with_lock(_lock, [=] { return _impl.readch(); }); + } diff --git a/drivers/debug-console.hh b/drivers/debug-console.hh index be87481de..97be35a2a 100644 --- a/drivers/debug-console.hh +++ b/drivers/debug-console.hh @@ -12,6 +12,7 @@ public: explicit debug_console(Console& impl); virtual void write(const char *str, size_t len); virtual void newline(); + virtual char readch(); private: Console& _impl; spinlock _lock; diff --git a/drivers/isa-serial.cc b/drivers/isa-serial.cc index 7777f47ad..fcec8a124 100644 --- a/drivers/isa-serial.cc +++ b/drivers/isa-serial.cc @@ -1,4 +1,5 @@ #include "isa-serial.hh" +#include <string.h> IsaSerialConsole::IsaSerialConsole() { reset(); @@ -12,6 +13,20 @@ void IsaSerialConsole::write(const char *str, size_t len) } } +char IsaSerialConsole::readch() +{ + u8 lsr; + char letter; + + do { + lsr = pci::inb(ioport + LSR_ADDRESS); + } while (!(lsr & (LSR_RECEIVE_DATA_READY | LSR_OVERRUN | LSR_PARITY_ERROR | LSR_FRAME_ERROR))); + + letter = pci::inb(ioport); + + return letter; +} + void IsaSerialConsole::writeByte(const char letter) { u8 lsr; diff --git a/drivers/isa-serial.hh b/drivers/isa-serial.hh index c9e8b0021..5160aea99 100644 --- a/drivers/isa-serial.hh +++ b/drivers/isa-serial.hh @@ -10,6 +10,7 @@ public: IsaSerialConsole(); virtual void write(const char *str, size_t len); virtual void newline(); + virtual char readch(); private: static const u16 ioport = 0x3f8; u8 lcr; @@ -21,7 +22,14 @@ private: BAUD_GEN0_ADDRESS = 0x0, BAUD_GEN1_ADDRESS = 0x1, LSR_ADDRESS = 0x5, + LSR_RECEIVE_DATA_READY = 0x1, + LSR_OVERRUN = 0x2, + LSR_PARITY_ERROR = 0x4, + LSR_FRAME_ERROR = 0x8, + LSR_BREAK_INTERRUPT = 0x10, LSR_TRANSMIT_HOLD_EMPTY = 0x20, + LSR_TRANSMIT_EMPTY = 0x40, + LSR_FIFO_ERROR = 0x80, }; void reset(); diff --git a/include/debug.hh b/include/debug.hh index 14bed4715..ac0a78088 100644 --- a/include/debug.hh +++ b/include/debug.hh @@ -55,4 +55,7 @@ extern "C" {void debug(const char *msg); } void debug(const boost::format& fmt, bool lf=true); void debug(std::string str, bool lf=true); +extern "C" {void readln(char *msg, size_t size); } + + #endif // DEBUG_H -- GitLab