Definitions.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /*
  2. * Copyright (c) 2020, Liav A. <liavalb@hotmail.co.il>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Function.h>
  8. #include <AK/String.h>
  9. #include <AK/Types.h>
  10. #include <AK/Vector.h>
  11. #include <Kernel/Debug.h>
  12. namespace Kernel {
  13. #define PCI_VENDOR_ID 0x00 // word
  14. #define PCI_DEVICE_ID 0x02 // word
  15. #define PCI_COMMAND 0x04 // word
  16. #define PCI_STATUS 0x06 // word
  17. #define PCI_REVISION_ID 0x08 // byte
  18. #define PCI_PROG_IF 0x09 // byte
  19. #define PCI_SUBCLASS 0x0a // byte
  20. #define PCI_CLASS 0x0b // byte
  21. #define PCI_CACHE_LINE_SIZE 0x0c // byte
  22. #define PCI_LATENCY_TIMER 0x0d // byte
  23. #define PCI_HEADER_TYPE 0x0e // byte
  24. #define PCI_BIST 0x0f // byte
  25. #define PCI_BAR0 0x10 // u32
  26. #define PCI_BAR1 0x14 // u32
  27. #define PCI_BAR2 0x18 // u32
  28. #define PCI_BAR3 0x1C // u32
  29. #define PCI_BAR4 0x20 // u32
  30. #define PCI_BAR5 0x24 // u32
  31. #define PCI_SUBSYSTEM_VENDOR_ID 0x2C // u16
  32. #define PCI_SUBSYSTEM_ID 0x2E // u16
  33. #define PCI_CAPABILITIES_POINTER 0x34 // u8
  34. #define PCI_INTERRUPT_LINE 0x3C // byte
  35. #define PCI_SECONDARY_BUS 0x19 // byte
  36. #define PCI_HEADER_TYPE_DEVICE 0
  37. #define PCI_HEADER_TYPE_BRIDGE 1
  38. #define PCI_TYPE_BRIDGE 0x0604
  39. #define PCI_ADDRESS_PORT 0xCF8
  40. #define PCI_VALUE_PORT 0xCFC
  41. #define PCI_NONE 0xFFFF
  42. #define PCI_MAX_DEVICES_PER_BUS 32
  43. #define PCI_MAX_BUSES 256
  44. #define PCI_MAX_FUNCTIONS_PER_DEVICE 8
  45. #define PCI_CAPABILITY_NULL 0x0
  46. #define PCI_CAPABILITY_MSI 0x5
  47. #define PCI_CAPABILITY_VENDOR_SPECIFIC 0x9
  48. #define PCI_CAPABILITY_MSIX 0x11
  49. // Taken from https://pcisig.com/sites/default/files/files/PCI_Code-ID_r_1_11__v24_Jan_2019.pdf
  50. #define PCI_MASS_STORAGE_CLASS_ID 0x1
  51. #define PCI_IDE_CTRL_SUBCLASS_ID 0x1
  52. #define PCI_SATA_CTRL_SUBCLASS_ID 0x6
  53. #define PCI_AHCI_IF_PROGIF 0x1
  54. namespace PCI {
  55. struct ID {
  56. u16 vendor_id { 0 };
  57. u16 device_id { 0 };
  58. bool is_null() const { return !vendor_id && !device_id; }
  59. bool operator==(const ID& other) const
  60. {
  61. return vendor_id == other.vendor_id && device_id == other.device_id;
  62. }
  63. bool operator!=(const ID& other) const
  64. {
  65. return vendor_id != other.vendor_id || device_id != other.device_id;
  66. }
  67. };
  68. struct Address {
  69. public:
  70. Address() = default;
  71. Address(u16 seg)
  72. : m_seg(seg)
  73. , m_bus(0)
  74. , m_device(0)
  75. , m_function(0)
  76. {
  77. }
  78. Address(u16 seg, u8 bus, u8 device, u8 function)
  79. : m_seg(seg)
  80. , m_bus(bus)
  81. , m_device(device)
  82. , m_function(function)
  83. {
  84. }
  85. Address(const Address& address)
  86. : m_seg(address.seg())
  87. , m_bus(address.bus())
  88. , m_device(address.device())
  89. , m_function(address.function())
  90. {
  91. }
  92. bool is_null() const { return !m_bus && !m_device && !m_function; }
  93. operator bool() const { return !is_null(); }
  94. // Disable default implementations that would use surprising integer promotion.
  95. bool operator<=(const Address&) const = delete;
  96. bool operator>=(const Address&) const = delete;
  97. bool operator<(const Address&) const = delete;
  98. bool operator>(const Address&) const = delete;
  99. bool operator==(const Address& other) const
  100. {
  101. if (this == &other)
  102. return true;
  103. return m_seg == other.m_seg && m_bus == other.m_bus && m_device == other.m_device && m_function == other.m_function;
  104. }
  105. bool operator!=(const Address& other) const
  106. {
  107. return !(*this == other);
  108. }
  109. u16 seg() const { return m_seg; }
  110. u8 bus() const { return m_bus; }
  111. u8 device() const { return m_device; }
  112. u8 function() const { return m_function; }
  113. u32 io_address_for_field(u8 field) const
  114. {
  115. return 0x80000000u | (m_bus << 16u) | (m_device << 11u) | (m_function << 8u) | (field & 0xfc);
  116. }
  117. protected:
  118. u32 m_seg { 0 };
  119. u8 m_bus { 0 };
  120. u8 m_device { 0 };
  121. u8 m_function { 0 };
  122. };
  123. struct ChangeableAddress : public Address {
  124. ChangeableAddress()
  125. : Address(0)
  126. {
  127. }
  128. explicit ChangeableAddress(u16 seg)
  129. : Address(seg)
  130. {
  131. }
  132. ChangeableAddress(u16 seg, u8 bus, u8 device, u8 function)
  133. : Address(seg, bus, device, function)
  134. {
  135. }
  136. void set_seg(u16 seg) { m_seg = seg; }
  137. void set_bus(u8 bus) { m_bus = bus; }
  138. void set_device(u8 device) { m_device = device; }
  139. void set_function(u8 function) { m_function = function; }
  140. bool operator==(const Address& address)
  141. {
  142. if (m_seg == address.seg() && m_bus == address.bus() && m_device == address.device() && m_function == address.function())
  143. return true;
  144. else
  145. return false;
  146. }
  147. const ChangeableAddress& operator=(const Address& address)
  148. {
  149. set_seg(address.seg());
  150. set_bus(address.bus());
  151. set_device(address.device());
  152. set_function(address.function());
  153. return *this;
  154. }
  155. };
  156. class Capability {
  157. public:
  158. Capability(const Address& address, u8 id, u8 ptr)
  159. : m_address(address)
  160. , m_id(id)
  161. , m_ptr(ptr)
  162. {
  163. }
  164. u8 id() const { return m_id; }
  165. u8 read8(u32) const;
  166. u16 read16(u32) const;
  167. u32 read32(u32) const;
  168. void write8(u32, u8);
  169. void write16(u32, u16);
  170. void write32(u32, u32);
  171. private:
  172. Address m_address;
  173. const u8 m_id;
  174. const u8 m_ptr;
  175. };
  176. class PhysicalID {
  177. public:
  178. PhysicalID(Address address, ID id, Vector<Capability> capabilities)
  179. : m_address(address)
  180. , m_id(id)
  181. , m_capabilities(capabilities)
  182. {
  183. if constexpr (PCI_DEBUG) {
  184. for (const auto& capability : capabilities)
  185. dbgln("{} has capability {}", address, capability.id());
  186. }
  187. }
  188. Vector<Capability> capabilities() const { return m_capabilities; }
  189. const ID& id() const { return m_id; }
  190. const Address& address() const { return m_address; }
  191. private:
  192. Address m_address;
  193. ID m_id;
  194. Vector<Capability> m_capabilities;
  195. };
  196. ID get_id(PCI::Address);
  197. bool is_io_space_enabled(Address);
  198. void enumerate(Function<void(Address, ID)> callback);
  199. void enable_interrupt_line(Address);
  200. void disable_interrupt_line(Address);
  201. u8 get_interrupt_line(Address);
  202. void raw_access(Address, u32, size_t, u32);
  203. u32 get_BAR0(Address);
  204. u32 get_BAR1(Address);
  205. u32 get_BAR2(Address);
  206. u32 get_BAR3(Address);
  207. u32 get_BAR4(Address);
  208. u32 get_BAR5(Address);
  209. u32 get_BAR(Address address, u8 bar);
  210. u8 get_revision_id(Address);
  211. u8 get_programming_interface(Address);
  212. u8 get_subclass(Address);
  213. u8 get_class(Address);
  214. u16 get_subsystem_id(Address);
  215. u16 get_subsystem_vendor_id(Address);
  216. size_t get_BAR_space_size(Address, u8);
  217. Optional<u8> get_capabilities_pointer(Address);
  218. Vector<Capability> get_capabilities(Address);
  219. void enable_bus_mastering(Address);
  220. void disable_bus_mastering(Address);
  221. void enable_io_space(Address);
  222. void disable_io_space(Address);
  223. void enable_memory_space(Address);
  224. void disable_memory_space(Address);
  225. PhysicalID get_physical_id(Address address);
  226. class Access;
  227. class MMIOAccess;
  228. class WindowedMMIOAccess;
  229. class IOAccess;
  230. class MMIOSegment;
  231. class Device;
  232. }
  233. }
  234. template<>
  235. struct AK::Formatter<Kernel::PCI::Address> : Formatter<FormatString> {
  236. void format(FormatBuilder& builder, Kernel::PCI::Address value)
  237. {
  238. return Formatter<FormatString>::format(
  239. builder,
  240. "PCI [{:04x}:{:02x}:{:02x}:{:02x}]", value.seg(), value.bus(), value.device(), value.function());
  241. }
  242. };
  243. template<>
  244. struct AK::Formatter<Kernel::PCI::ID> : Formatter<FormatString> {
  245. void format(FormatBuilder& builder, Kernel::PCI::ID value)
  246. {
  247. return Formatter<FormatString>::format(
  248. builder,
  249. "PCI::ID [{:04x}:{:04x}]", value.vendor_id, value.device_id);
  250. }
  251. };