PCISerialDevice.cpp 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. /*
  2. * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <Kernel/Bus/PCI/API.h>
  7. #include <Kernel/Devices/PCISerialDevice.h>
  8. #include <Kernel/Sections.h>
  9. namespace Kernel {
  10. static SerialDevice* s_the = nullptr;
  11. UNMAP_AFTER_INIT void PCISerialDevice::detect()
  12. {
  13. size_t current_device_minor = 68;
  14. PCI::enumerate([&](const PCI::Address& address, PCI::ID id) {
  15. if (address.is_null())
  16. return;
  17. for (auto& board_definition : board_definitions) {
  18. if (board_definition.device_id != id)
  19. continue;
  20. auto bar_base = PCI::get_BAR(address, board_definition.pci_bar) & ~1;
  21. auto port_base = IOAddress(bar_base + board_definition.first_offset);
  22. for (size_t i = 0; i < board_definition.port_count; i++) {
  23. auto serial_device = new SerialDevice(port_base.offset(board_definition.port_size * i), current_device_minor++);
  24. if (board_definition.baud_rate != SerialDevice::Baud::Baud38400) // non-default baud
  25. serial_device->set_baud(board_definition.baud_rate);
  26. // 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?)
  27. if (!is_available())
  28. s_the = serial_device;
  29. // NOTE: We intentionally leak the reference to serial_device here, as it is eternal
  30. }
  31. dmesgln("PCISerialDevice: Found {} @ {}", board_definition.name, address);
  32. return;
  33. }
  34. });
  35. }
  36. SerialDevice& PCISerialDevice::the()
  37. {
  38. VERIFY(s_the);
  39. return *s_the;
  40. }
  41. bool PCISerialDevice::is_available()
  42. {
  43. return s_the;
  44. }
  45. }