HostBridge.cpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /*
  2. * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <Kernel/Arch/x86/IO.h>
  7. #include <Kernel/Arch/x86/PCI/Controller/HostBridge.h>
  8. #include <Kernel/Bus/PCI/Access.h>
  9. #include <Kernel/Sections.h>
  10. namespace Kernel::PCI {
  11. NonnullOwnPtr<HostBridge> HostBridge::must_create_with_io_access()
  12. {
  13. PCI::Domain domain { 0, 0, 0xff };
  14. return adopt_own_if_nonnull(new (nothrow) HostBridge(domain)).release_nonnull();
  15. }
  16. HostBridge::HostBridge(PCI::Domain const& domain)
  17. : HostController(domain)
  18. {
  19. }
  20. static u32 io_address_for_pci_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u8 field)
  21. {
  22. return 0x80000000u | (bus.value() << 16u) | (device.value() << 11u) | (function.value() << 8u) | (field & 0xfc);
  23. }
  24. void HostBridge::write8_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field, u8 value)
  25. {
  26. IO::out32(PCI::address_port, io_address_for_pci_field(bus, device, function, field));
  27. IO::out8(PCI::value_port + (field & 3), value);
  28. }
  29. void HostBridge::write16_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field, u16 value)
  30. {
  31. IO::out32(PCI::address_port, io_address_for_pci_field(bus, device, function, field));
  32. IO::out16(PCI::value_port + (field & 2), value);
  33. }
  34. void HostBridge::write32_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field, u32 value)
  35. {
  36. IO::out32(PCI::address_port, io_address_for_pci_field(bus, device, function, field));
  37. IO::out32(PCI::value_port, value);
  38. }
  39. u8 HostBridge::read8_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field)
  40. {
  41. IO::out32(PCI::address_port, io_address_for_pci_field(bus, device, function, field));
  42. return IO::in8(PCI::value_port + (field & 3));
  43. }
  44. u16 HostBridge::read16_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field)
  45. {
  46. IO::out32(PCI::address_port, io_address_for_pci_field(bus, device, function, field));
  47. return IO::in16(PCI::value_port + (field & 2));
  48. }
  49. u32 HostBridge::read32_field(BusNumber bus, DeviceNumber device, FunctionNumber function, u32 field)
  50. {
  51. IO::out32(PCI::address_port, io_address_for_pci_field(bus, device, function, field));
  52. return IO::in32(PCI::value_port);
  53. }
  54. }