Kernel: Don't enter infinite loop on unexpected serial behaviour

This commit is contained in:
Bananymous 2025-02-06 20:59:17 +02:00
parent faa5252191
commit f9b70d1b5b
2 changed files with 30 additions and 31 deletions

View File

@ -2,6 +2,7 @@
#include <BAN/CircularQueue.h> #include <BAN/CircularQueue.h>
#include <BAN/Errors.h> #include <BAN/Errors.h>
#include <BAN/Optional.h>
#include <kernel/Interruptable.h> #include <kernel/Interruptable.h>
#include <kernel/Terminal/TTY.h> #include <kernel/Terminal/TTY.h>
@ -13,12 +14,12 @@ namespace Kernel
public: public:
static void initialize(); static void initialize();
static bool has_devices(); static bool has_devices();
static void putchar_any(char); static void putchar_any(uint8_t);
static void initialize_devices(); static void initialize_devices();
void putchar(char); void putchar(uint8_t);
char getchar(); BAN::Optional<uint8_t> getchar();
bool is_valid() const { return m_port != 0; } bool is_valid() const { return m_port != 0; }

View File

@ -107,41 +107,38 @@ namespace Kernel
while (*ptr) while (*ptr)
putchar(*ptr++); putchar(*ptr++);
if (getchar() != '\033') if (auto ch = getchar(); !ch.has_value() || ch.value() != '\033')
return false; return false;
if (getchar() != '[') if (auto ch = getchar(); !ch.has_value() || ch.value() != '[')
return false; return false;
auto read_number = auto read_number =
[&](char end) [&](uint8_t end) -> BAN::Optional<uint32_t>
{ {
uint32_t number = 0; uint32_t number = 0;
while (true) while (true)
{ {
char c = getchar(); const auto ch = getchar();
if (c == end) if (!ch.has_value())
break; return {};
if (!isdigit(c)) if (ch.value() == end)
return UINT32_MAX; return number;
number = (number * 10) + (c - '0'); if (!isdigit(ch.value()))
return {};
number = (number * 10) + (ch.value() - '0');
} }
return number;
}; };
m_height = read_number(';'); const auto height = read_number(';');
if (m_height == UINT32_MAX) if (!height.has_value())
{
m_port = 0;
return false; return false;
}
m_width = read_number('R'); const auto width = read_number('R');
if (m_width == UINT32_MAX) if (!width.has_value())
{
m_port = 0;
return false; return false;
}
m_height = height.value();
m_width = width.value();
return true; return true;
} }
@ -150,25 +147,26 @@ namespace Kernel
return s_has_devices; return s_has_devices;
} }
void Serial::putchar(char c) void Serial::putchar(uint8_t ch)
{ {
while (!(IO::inb(m_port + 5) & 0x20)) while (!(IO::inb(m_port + 5) & 0x20))
continue; continue;
IO::outb(m_port, c); IO::outb(m_port, ch);
} }
char Serial::getchar() BAN::Optional<uint8_t> Serial::getchar()
{ {
while (!(IO::inb(m_port + 5) & 0x01)) for (size_t i = 0; i < 10'000'000; i++)
continue; if (IO::inb(m_port + 5) & 0x01)
return IO::inb(m_port); return IO::inb(m_port);
return {};
} }
void Serial::putchar_any(char c) void Serial::putchar_any(uint8_t ch)
{ {
for (auto& device : s_serial_drivers) for (auto& device : s_serial_drivers)
if (device.is_valid()) if (device.is_valid())
device.putchar(c); return device.putchar(ch);
} }
SerialTTY::SerialTTY(Serial serial) SerialTTY::SerialTTY(Serial serial)