MemoryBackedHostBridge.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*
  2. * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/ByteReader.h>
  7. #include <Kernel/Bus/PCI/Access.h>
  8. #include <Kernel/Bus/PCI/Controller/MemoryBackedHostBridge.h>
  9. namespace Kernel::PCI {
  10. NonnullOwnPtr<MemoryBackedHostBridge> MemoryBackedHostBridge::must_create(Domain const& domain, PhysicalAddress start_address)
  11. {
  12. return adopt_own_if_nonnull(new (nothrow) MemoryBackedHostBridge(domain, start_address)).release_nonnull();
  13. }
  14. MemoryBackedHostBridge::MemoryBackedHostBridge(PCI::Domain const& domain, PhysicalAddress start_address)
  15. : HostController(domain)
  16. , m_start_address(start_address)
  17. {
  18. }
  19. u8 MemoryBackedHostBridge::read8_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field)
  20. {
  21. VERIFY(Access::the().access_lock().is_locked());
  22. VERIFY(field <= 0xfff);
  23. return *((u8 volatile*)(get_device_configuration_memory_mapped_space(bus, device, function).get() + (field & 0xfff)));
  24. }
  25. u16 MemoryBackedHostBridge::read16_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field)
  26. {
  27. VERIFY(Access::the().access_lock().is_locked());
  28. VERIFY(field < 0xfff);
  29. u16 data = 0;
  30. ByteReader::load<u16>(get_device_configuration_memory_mapped_space(bus, device, function).offset(field & 0xfff).as_ptr(), data);
  31. return data;
  32. }
  33. u32 MemoryBackedHostBridge::read32_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field)
  34. {
  35. VERIFY(Access::the().access_lock().is_locked());
  36. VERIFY(field <= 0xffc);
  37. u32 data = 0;
  38. ByteReader::load<u32>(get_device_configuration_memory_mapped_space(bus, device, function).offset(field & 0xfff).as_ptr(), data);
  39. return data;
  40. }
  41. void MemoryBackedHostBridge::write8_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field, u8 value)
  42. {
  43. VERIFY(Access::the().access_lock().is_locked());
  44. VERIFY(field <= 0xfff);
  45. *((u8 volatile*)(get_device_configuration_memory_mapped_space(bus, device, function).get() + (field & 0xfff))) = value;
  46. }
  47. void MemoryBackedHostBridge::write16_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field, u16 value)
  48. {
  49. VERIFY(Access::the().access_lock().is_locked());
  50. VERIFY(field < 0xfff);
  51. ByteReader::store<u16>(get_device_configuration_memory_mapped_space(bus, device, function).offset(field & 0xfff).as_ptr(), value);
  52. }
  53. void MemoryBackedHostBridge::write32_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field, u32 value)
  54. {
  55. VERIFY(Access::the().access_lock().is_locked());
  56. VERIFY(field <= 0xffc);
  57. ByteReader::store<u32>(get_device_configuration_memory_mapped_space(bus, device, function).offset(field & 0xfff).as_ptr(), value);
  58. }
  59. void MemoryBackedHostBridge::map_bus_region(BusNumber bus)
  60. {
  61. VERIFY(Access::the().access_lock().is_locked());
  62. if (m_mapped_bus == bus && m_mapped_bus_region)
  63. return;
  64. auto bus_base_address = determine_memory_mapped_bus_base_address(bus);
  65. auto region_or_error = MM.allocate_kernel_region(bus_base_address, memory_range_per_bus, "PCI ECAM"sv, Memory::Region::Access::ReadWrite);
  66. // FIXME: Find a way to propagate error from here.
  67. if (region_or_error.is_error())
  68. VERIFY_NOT_REACHED();
  69. m_mapped_bus_region = region_or_error.release_value();
  70. m_mapped_bus = bus;
  71. dbgln_if(PCI_DEBUG, "PCI: New PCI ECAM Mapped region for bus {} @ {} {}", bus, m_mapped_bus_region->vaddr(), m_mapped_bus_region->physical_page(0)->paddr());
  72. }
  73. VirtualAddress MemoryBackedHostBridge::get_device_configuration_memory_mapped_space(BusNumber bus, DeviceNumber device, FunctionNumber function)
  74. {
  75. VERIFY(Access::the().access_lock().is_locked());
  76. map_bus_region(bus);
  77. return m_mapped_bus_region->vaddr().offset(mmio_device_space_size * function.value() + (mmio_device_space_size * to_underlying(Limits::MaxFunctionsPerDevice)) * device.value());
  78. }
  79. PhysicalAddress MemoryBackedHostBridge::determine_memory_mapped_bus_base_address(BusNumber bus) const
  80. {
  81. auto start_bus = min(bus.value(), m_domain.start_bus());
  82. return m_start_address.offset(memory_range_per_bus * (bus.value() - start_bus));
  83. }
  84. }