pci.hpp 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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(uint32_t bus, uint32_t dev, uint32_t func)
  26. : addr_base(0x80000000U | (bus << 16) | (dev << 11) | (func << 8)) {}
  27. // offset is in range from 0x00 to 0xff
  28. uint32_t read32(uint32_t offset) const;
  29. uint16_t read16(uint16_t offset) const;
  30. // read n-th 32-bit register
  31. uint32_t operator[](uint32_t n) const;
  32. };
  33. struct device_header_base {
  34. uint16_t vendor;
  35. uint16_t device;
  36. uint16_t command;
  37. uint16_t status;
  38. uint8_t revision_id;
  39. uint8_t prog_if;
  40. uint8_t subclass;
  41. uint8_t class_code;
  42. uint8_t cache_line_size;
  43. uint8_t latency_timer;
  44. uint8_t header_type;
  45. uint8_t bist;
  46. };
  47. struct device_header_type0 {
  48. bar bars[6];
  49. uint32_t cardbus_cis_pointer;
  50. uint16_t subsystem_vendor_id;
  51. uint16_t subsystem_id;
  52. uint32_t expansion_rom_base_address;
  53. uint8_t capabilities_pointer;
  54. uint8_t reserved[7];
  55. uint8_t interrupt_line;
  56. uint8_t interrupt_pin;
  57. uint8_t min_grant;
  58. uint8_t max_latency;
  59. };
  60. class pci_device {
  61. public:
  62. config_reg reg;
  63. uint16_t vendor;
  64. uint16_t device;
  65. uint8_t revision_id;
  66. uint8_t subclass;
  67. uint8_t class_code;
  68. uint8_t header_type;
  69. explicit pci_device(config_reg reg);
  70. };
  71. using driver_t = std::function<int(pci_device*)>;
  72. pci_device* probe_device(uint8_t bus, uint8_t device, uint8_t function);
  73. int register_driver(uint16_t vendor, uint16_t device, driver_t drv);
  74. } // namespace kernel::hw::pci