pci.hpp 1.9 KB

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