pci.hpp 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #pragma once
  2. #include <functional>
  3. #include <memory>
  4. #include <stdint.h>
  5. #include <types/types.h>
  6. #include <kernel/mem/phys.hpp>
  7. namespace kernel::hw::pci {
  8. struct PACKED device_header_base {
  9. uint16_t vendor;
  10. uint16_t device;
  11. uint16_t volatile command;
  12. uint16_t volatile status;
  13. uint8_t revision_id;
  14. uint8_t prog_if;
  15. uint8_t subclass;
  16. uint8_t class_code;
  17. uint8_t cache_line_size;
  18. uint8_t latency_timer;
  19. uint8_t header_type;
  20. uint8_t volatile bist;
  21. };
  22. struct PACKED device_header_type0 {
  23. device_header_base base;
  24. uint32_t bars[6];
  25. uint32_t cardbus_cis_pointer;
  26. uint16_t subsystem_vendor_id;
  27. uint16_t subsystem_id;
  28. uint32_t expansion_rom_base_address;
  29. uint8_t capabilities_pointer;
  30. uint8_t __reserved[7];
  31. uint8_t volatile interrupt_line;
  32. uint8_t volatile interrupt_pin;
  33. uint8_t min_grant;
  34. uint8_t max_latency;
  35. };
  36. struct SegmentGroup {
  37. mem::physaddr<void, false> base;
  38. int number;
  39. };
  40. class pci_device {
  41. private:
  42. std::shared_ptr<SegmentGroup> segment_group;
  43. int bus;
  44. int device;
  45. int function;
  46. void* config_space;
  47. explicit pci_device(std::shared_ptr<SegmentGroup> segment_group, int bus,
  48. int device, int function, void* config_space);
  49. public:
  50. static pci_device* probe(std::shared_ptr<SegmentGroup> segment_group,
  51. int bus, int device, int function);
  52. device_header_base& header() const;
  53. device_header_type0& header_type0() const;
  54. void enableBusMastering();
  55. template <typename T>
  56. inline T& at(size_t offset) const {
  57. return *reinterpret_cast<T*>(reinterpret_cast<uint8_t*>(config_space) +
  58. offset);
  59. }
  60. };
  61. using driver_t = std::function<int(pci_device&)>;
  62. int register_driver(uint16_t vendor, uint16_t device, driver_t drv);
  63. int register_driver_r(uint16_t vendor, uint16_t device, int (*drv)(pci_device*));
  64. } // namespace kernel::hw::pci