pci.hpp 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #pragma once
  2. #include <functional>
  3. #include <stdint.h>
  4. namespace kernel::kinit {
  5. void init_pci();
  6. } // namespace kernel::kinit
  7. namespace kernel::hw::pci {
  8. struct bar_mmio {
  9. uint32_t always_zero : 1;
  10. uint32_t type : 2;
  11. uint32_t prefetchable : 1;
  12. uint32_t base_address : 28;
  13. };
  14. struct bar_io {
  15. uint32_t always_one : 1;
  16. uint32_t reserved : 1;
  17. uint32_t base_address : 30;
  18. };
  19. union bar {
  20. bar_mmio mmio;
  21. bar_io io;
  22. };
  23. struct config_reg {
  24. uint32_t addr_base;
  25. explicit constexpr config_reg(
  26. uint32_t bus, uint32_t dev, uint32_t func)
  27. : addr_base(0x80000000U | (bus << 16) | (dev << 11) | (func << 8))
  28. { }
  29. // offset is in range from 0x00 to 0xff
  30. uint32_t read32(uint32_t offset) const;
  31. uint16_t read16(uint16_t offset) const;
  32. // read n-th 32-bit register
  33. uint32_t operator[](uint32_t n) const;
  34. };
  35. struct device_header_base {
  36. uint16_t vendor;
  37. uint16_t device;
  38. uint16_t command;
  39. uint16_t status;
  40. uint8_t revision_id;
  41. uint8_t prog_if;
  42. uint8_t subclass;
  43. uint8_t class_code;
  44. uint8_t cache_line_size;
  45. uint8_t latency_timer;
  46. uint8_t header_type;
  47. uint8_t bist;
  48. };
  49. struct device_header_type0 {
  50. bar bars[6];
  51. uint32_t cardbus_cis_pointer;
  52. uint16_t subsystem_vendor_id;
  53. uint16_t subsystem_id;
  54. uint32_t expansion_rom_base_address;
  55. uint8_t capabilities_pointer;
  56. uint8_t reserved[7];
  57. uint8_t interrupt_line;
  58. uint8_t interrupt_pin;
  59. uint8_t min_grant;
  60. uint8_t max_latency;
  61. };
  62. class pci_device {
  63. public:
  64. config_reg reg;
  65. uint16_t vendor;
  66. uint16_t device;
  67. uint8_t revision_id;
  68. uint8_t subclass;
  69. uint8_t class_code;
  70. uint8_t header_type;
  71. explicit pci_device(config_reg reg);
  72. };
  73. using driver_t = std::function<int(pci_device*)>;
  74. pci_device* probe_device(uint8_t bus, uint8_t device, uint8_t function);
  75. int register_driver(uint16_t vendor, uint16_t device, driver_t drv);
  76. } // namespace kernel::hw::pci