Serenity Operating System
at master 56 lines 2.2 kB view raw
1/* 2 * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <Kernel/Bus/PCI/API.h> 8#include <Kernel/Devices/PCISerialDevice.h> 9#include <Kernel/IOWindow.h> 10#include <Kernel/Sections.h> 11 12namespace Kernel { 13 14static SerialDevice* s_the = nullptr; 15 16UNMAP_AFTER_INIT void PCISerialDevice::detect() 17{ 18 size_t current_device_minor = 68; 19 MUST(PCI::enumerate([&](PCI::DeviceIdentifier const& device_identifier) { 20 for (auto& board_definition : board_definitions) { 21 if (board_definition.device_id != device_identifier.hardware_id()) 22 continue; 23 24 auto registers_io_window = IOWindow::create_for_pci_device_bar(device_identifier, static_cast<PCI::HeaderType0BaseRegister>(board_definition.pci_bar)).release_value_but_fixme_should_propagate_errors(); 25 auto first_offset_registers_io_window = registers_io_window->create_from_io_window_with_offset(board_definition.first_offset).release_value_but_fixme_should_propagate_errors(); 26 27 for (size_t i = 0; i < board_definition.port_count; i++) { 28 auto port_registers_io_window = first_offset_registers_io_window->create_from_io_window_with_offset(board_definition.port_size * i).release_value_but_fixme_should_propagate_errors(); 29 auto serial_device = new SerialDevice(move(port_registers_io_window), current_device_minor++); 30 if (board_definition.baud_rate != SerialDevice::Baud::Baud38400) // non-default baud 31 serial_device->set_baud(board_definition.baud_rate); 32 33 // 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?) 34 if (!is_available()) 35 s_the = serial_device; 36 // NOTE: We intentionally leak the reference to serial_device here. 37 } 38 39 dmesgln("PCISerialDevice: Found {} @ {}", board_definition.name, device_identifier.address()); 40 return; 41 } 42 })); 43} 44 45SerialDevice& PCISerialDevice::the() 46{ 47 VERIFY(s_the); 48 return *s_the; 49} 50 51bool PCISerialDevice::is_available() 52{ 53 return s_the; 54} 55 56}