AHCIController.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /*
  2. * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/Atomic.h>
  7. #include <AK/OwnPtr.h>
  8. #include <AK/RefPtr.h>
  9. #include <AK/Types.h>
  10. #include <Kernel/Bus/PCI/API.h>
  11. #include <Kernel/Memory/MemoryManager.h>
  12. #include <Kernel/Storage/AHCIController.h>
  13. #include <Kernel/Storage/SATADiskDevice.h>
  14. namespace Kernel {
  15. NonnullRefPtr<AHCIController> AHCIController::initialize(PCI::DeviceIdentifier const& pci_device_identifier)
  16. {
  17. return adopt_ref(*new AHCIController(pci_device_identifier));
  18. }
  19. bool AHCIController::reset()
  20. {
  21. hba().control_regs.ghc = 1;
  22. dbgln_if(AHCI_DEBUG, "{}: AHCI Controller reset", pci_address());
  23. full_memory_barrier();
  24. size_t retry = 0;
  25. while (true) {
  26. if (retry > 1000)
  27. return false;
  28. if (!(hba().control_regs.ghc & 1))
  29. break;
  30. IO::delay(1000);
  31. retry++;
  32. }
  33. // The HBA is locked or hung if we waited more than 1 second!
  34. return true;
  35. }
  36. bool AHCIController::shutdown()
  37. {
  38. TODO();
  39. }
  40. size_t AHCIController::devices_count() const
  41. {
  42. size_t count = 0;
  43. for (auto& port_handler : m_handlers) {
  44. port_handler.enumerate_ports([&](const AHCIPort& port) {
  45. if (port.connected_device())
  46. count++;
  47. });
  48. }
  49. return count;
  50. }
  51. void AHCIController::start_request(const StorageDevice&, AsyncBlockDeviceRequest&)
  52. {
  53. VERIFY_NOT_REACHED();
  54. }
  55. void AHCIController::complete_current_request(AsyncDeviceRequest::RequestResult)
  56. {
  57. VERIFY_NOT_REACHED();
  58. }
  59. volatile AHCI::PortRegisters& AHCIController::port(size_t port_number) const
  60. {
  61. VERIFY(port_number < (size_t)AHCI::Limits::MaxPorts);
  62. return static_cast<volatile AHCI::PortRegisters&>(hba().port_regs[port_number]);
  63. }
  64. volatile AHCI::HBA& AHCIController::hba() const
  65. {
  66. return static_cast<volatile AHCI::HBA&>(*(volatile AHCI::HBA*)(m_hba_region->vaddr().as_ptr()));
  67. }
  68. AHCIController::AHCIController(PCI::DeviceIdentifier const& pci_device_identifier)
  69. : StorageController()
  70. , PCI::Device(pci_device_identifier.address())
  71. , m_hba_region(default_hba_region())
  72. , m_capabilities(capabilities())
  73. {
  74. initialize_hba(pci_device_identifier);
  75. }
  76. AHCI::HBADefinedCapabilities AHCIController::capabilities() const
  77. {
  78. u32 capabilities = hba().control_regs.cap;
  79. u32 extended_capabilities = hba().control_regs.cap2;
  80. dbgln_if(AHCI_DEBUG, "{}: AHCI Controller Capabilities = {:#08x}, Extended Capabilities = {:#08x}", pci_address(), capabilities, extended_capabilities);
  81. return (AHCI::HBADefinedCapabilities) {
  82. (capabilities & 0b11111) + 1,
  83. ((capabilities >> 8) & 0b11111) + 1,
  84. (u8)((capabilities >> 20) & 0b1111),
  85. (capabilities & (u32)(AHCI::HBACapabilities::SXS)) != 0,
  86. (capabilities & (u32)(AHCI::HBACapabilities::EMS)) != 0,
  87. (capabilities & (u32)(AHCI::HBACapabilities::CCCS)) != 0,
  88. (capabilities & (u32)(AHCI::HBACapabilities::PSC)) != 0,
  89. (capabilities & (u32)(AHCI::HBACapabilities::SSC)) != 0,
  90. (capabilities & (u32)(AHCI::HBACapabilities::PMD)) != 0,
  91. (capabilities & (u32)(AHCI::HBACapabilities::FBSS)) != 0,
  92. (capabilities & (u32)(AHCI::HBACapabilities::SPM)) != 0,
  93. (capabilities & (u32)(AHCI::HBACapabilities::SAM)) != 0,
  94. (capabilities & (u32)(AHCI::HBACapabilities::SCLO)) != 0,
  95. (capabilities & (u32)(AHCI::HBACapabilities::SAL)) != 0,
  96. (capabilities & (u32)(AHCI::HBACapabilities::SALP)) != 0,
  97. (capabilities & (u32)(AHCI::HBACapabilities::SSS)) != 0,
  98. (capabilities & (u32)(AHCI::HBACapabilities::SMPS)) != 0,
  99. (capabilities & (u32)(AHCI::HBACapabilities::SSNTF)) != 0,
  100. (capabilities & (u32)(AHCI::HBACapabilities::SNCQ)) != 0,
  101. (capabilities & (u32)(AHCI::HBACapabilities::S64A)) != 0,
  102. (extended_capabilities & (u32)(AHCI::HBACapabilitiesExtended::BOH)) != 0,
  103. (extended_capabilities & (u32)(AHCI::HBACapabilitiesExtended::NVMP)) != 0,
  104. (extended_capabilities & (u32)(AHCI::HBACapabilitiesExtended::APST)) != 0,
  105. (extended_capabilities & (u32)(AHCI::HBACapabilitiesExtended::SDS)) != 0,
  106. (extended_capabilities & (u32)(AHCI::HBACapabilitiesExtended::SADM)) != 0,
  107. (extended_capabilities & (u32)(AHCI::HBACapabilitiesExtended::DESO)) != 0
  108. };
  109. }
  110. NonnullOwnPtr<Memory::Region> AHCIController::default_hba_region() const
  111. {
  112. return MM.allocate_kernel_region(PhysicalAddress(PCI::get_BAR5(pci_address())).page_base(), Memory::page_round_up(sizeof(AHCI::HBA)), "AHCI HBA", Memory::Region::Access::ReadWrite).release_value();
  113. }
  114. AHCIController::~AHCIController()
  115. {
  116. }
  117. void AHCIController::initialize_hba(PCI::DeviceIdentifier const& pci_device_identifier)
  118. {
  119. if (!reset()) {
  120. dmesgln("{}: AHCI controller reset failed", pci_address());
  121. return;
  122. }
  123. dmesgln("{}: AHCI controller reset", pci_address());
  124. dbgln("{}: AHCI command list entries count - {}", pci_address(), hba_capabilities().max_command_list_entries_count);
  125. u32 version = hba().control_regs.version;
  126. dbgln_if(AHCI_DEBUG, "{}: AHCI Controller Version = {:#08x}", pci_address(), version);
  127. hba().control_regs.ghc = 0x80000000; // Ensure that HBA knows we are AHCI aware.
  128. PCI::enable_interrupt_line(pci_address());
  129. PCI::enable_bus_mastering(pci_address());
  130. enable_global_interrupts();
  131. m_handlers.append(AHCIPortHandler::create(*this, pci_device_identifier.interrupt_line().value(),
  132. AHCI::MaskedBitField((volatile u32&)(hba().control_regs.pi))));
  133. }
  134. void AHCIController::disable_global_interrupts() const
  135. {
  136. hba().control_regs.ghc = hba().control_regs.ghc & 0xfffffffd;
  137. }
  138. void AHCIController::enable_global_interrupts() const
  139. {
  140. hba().control_regs.ghc = hba().control_regs.ghc | (1 << 1);
  141. }
  142. RefPtr<StorageDevice> AHCIController::device_by_port(u32 port_index) const
  143. {
  144. for (auto& port_handler : m_handlers) {
  145. if (!port_handler.is_responsible_for_port_index(port_index))
  146. continue;
  147. auto port = port_handler.port_at_index(port_index);
  148. if (!port)
  149. return nullptr;
  150. return port->connected_device();
  151. }
  152. return nullptr;
  153. }
  154. RefPtr<StorageDevice> AHCIController::device(u32 index) const
  155. {
  156. NonnullRefPtrVector<StorageDevice> connected_devices;
  157. u32 pi = hba().control_regs.pi;
  158. u32 bit = __builtin_ffsl(pi);
  159. while (bit) {
  160. dbgln_if(AHCI_DEBUG, "Checking implemented port {}, pi {:b}", bit - 1, pi);
  161. pi &= ~(1u << (bit - 1));
  162. auto checked_device = device_by_port(bit - 1);
  163. bit = __builtin_ffsl(pi);
  164. if (checked_device.is_null())
  165. continue;
  166. connected_devices.append(checked_device.release_nonnull());
  167. }
  168. dbgln_if(AHCI_DEBUG, "Connected device count: {}, Index: {}", connected_devices.size(), index);
  169. if (index >= connected_devices.size())
  170. return nullptr;
  171. return connected_devices[index];
  172. }
  173. }