Kernel: Add support for multiple serial ports per device

This commit adds support for initializing multiple serial ports per
PCI board, as well as initializing multiple different pci serial boards

Currently we just choose the first PCI serial port seen as the debug
port, but this should probably be made configurable some how in the
future.
This commit is contained in:
Idan Horowitz 2021-05-18 13:57:54 +03:00 committed by Andreas Kling
parent 093818de62
commit 208cfcb0a5
Notes: sideshowbarker 2024-07-18 17:51:45 +09:00

View File

@ -12,23 +12,27 @@ static SerialDevice* s_the = nullptr;
void PCISerialDevice::detect()
{
size_t current_device_minor = 68;
PCI::enumerate([&](const PCI::Address& address, PCI::ID id) {
if (address.is_null())
return;
// HACK: There's currently no way to break out of PCI::enumerate, so we just early return if we already initialized the pci serial device
if (is_available())
return;
for (auto& board_definition : board_definitions) {
if (board_definition.device_id != id)
continue;
auto bar_base = PCI::get_BAR(address, board_definition.pci_bar) & ~1;
// FIXME: We should support more than 1 PCI serial port (per card/multiple devices)
s_the = new SerialDevice(IOAddress(bar_base + board_definition.first_offset), 68);
if (board_definition.baud_rate != SerialDevice::Baud::Baud38400) // non-default baud
s_the->set_baud(board_definition.baud_rate);
auto port_base = IOAddress(bar_base + board_definition.first_offset);
for (size_t i = 0; i < board_definition.port_count; i++) {
auto serial_device = new SerialDevice(port_base.offset(board_definition.port_size * i), current_device_minor++);
if (board_definition.baud_rate != SerialDevice::Baud::Baud38400) // non-default baud
serial_device->set_baud(board_definition.baud_rate);
// If this is the first port of the first pci serial device, store it as the debug PCI serial port (TODO: Make this configurable somehow?)
if (!is_available())
s_the = serial_device;
// NOTE: We intentionally leak the reference to serial_device here, as it is eternal
}
dmesgln("PCISerialDevice: Found {} @ {}", board_definition.name, address);
return;