Kernel: Don't enter infinite loop on unexpected serial behaviour
This commit is contained in:
parent
faa5252191
commit
f9b70d1b5b
|
@ -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; }
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
||||||
number = (number * 10) + (c - '0');
|
|
||||||
}
|
|
||||||
return number;
|
return number;
|
||||||
|
if (!isdigit(ch.value()))
|
||||||
|
return {};
|
||||||
|
number = (number * 10) + (ch.value() - '0');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
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)
|
||||||
|
|
Loading…
Reference in New Issue