// // Created by rick on 02-02-21. // #ifndef NEW_KERNEL_PCI_H #define NEW_KERNEL_PCI_H #include #include #include #include #define PCI_CLASS_MASS_STORAGE 0x01 #define PCI_CLASS_BRIDGE 0x06 // class MASS STORAGE 0x01 #define PCI_SUB_CLASS_IDE 0x01 // class BRIDGE 0x06 #define PCI_SUB_CLASS_PCI_PCI_BRIDGE_4 0x04 #define PCI_SUB_CLASS_PCI_PCI_BRIDGE_9 0x09 #define PCI_REGISTER_OK 0 #define PCI_REGISTER_ERR_FULL (-1) #define PCI_VALIDATE_OK 0 #define PCI_VALIDATE_FAIL 1 #define PCI_INIT_OK 0 #define PCI_INIT_FAIL 1 #define PCI_USE_OK 0 #define PCI_USE_FAIL 1 #define PCI_HEADER_TYPE_MULTI_FUNC 0x80 #define PCI_HEADER_TYPE_ENDPOINT 0x00 #define PCI_HEADER_TYPE_PCI_PCI_BRIDGE 0x01 #define PCI_HEADER_TYPE_PCI_CARDBUS_BRIDGE 0x02 #define PCI_CONFIG_VENDOR_ID 0x00 #define PCI_CONFIG_DEVICE_ID 0x02 #define PCI_CONFIG_COMMAND 0x04 #define PCI_CONFIG_STATUS 0x06 #define PCI_CONFIG_REVISION_ID 0x08 #define PCI_CONFIG_PROG_IF 0x09 #define PCI_CONFIG_SUBCLASS 0x0A #define PCI_CONFIG_CLASS_CODE 0x0B #define PCI_CONFIG_CACHE_LINE_SIZE 0x0C #define PCI_CONFIG_LATENCY_TIMER 0x0D #define PCI_CONFIG_HEADER_TYPE 0x0E #define PCI_CONFIG_BIST 0x0F #define PCI_CONFIG_BAR0 0x10 #define PCI_CONFIG_BAR1 0x14 #define PCI_CONFIG_BAR2 0x18 #define PCI_CONFIG_BAR3 0x1C #define PCI_CONFIG_BAR4 0x20 #define PCI_CONFIG_BAR5 0x24 #define PCI_CONFIG_CARDBUS_CIS_P 0x28 #define PCI_CONFIG_SUBSYSTEM_VENDOR_ID 0x2C #define PCI_CONFIG_SUBSYSTEM_ID 0x2E #define PCI_CONFIG_EXPANSION_ROM_ADDR 0x30 #define PCI_CONFIG_CAP_POINTER 0x34 #define PCI_CONFIG_INTERRUPT_LINE 0x3C #define PCI_CONFIG_INTERRUPT_PIN 0x3D #define PCI_CONFIG_MAX_GRANT 0x3E #define PCI_CONFIG_MAX_LATENCY 0x3F // header type 1 #define PCI_CONFIG_PRIMARY_BUS_NUMBER 0x18 #define PCI_CONFIG_SECONDARY_BUS_NUMBER 0x19 #define PCI_CONFIG_SUBORDINATE_BUS_NUMBER 0x1A #define PCI_CONFIG_SECONDARY_LATENCY_TIMER 0x1B #define PCI_CONFIG_IO_BASE 0x1C #define PCI_CONFIG_IO_LIMIT 0x1D #define PCI_CONFIG_SECONDARY_STATUS 0x1E #define PCI_CONFIG_MEMORY_BASE 0x20 #define PCI_CONFIG_MEMORY_LIMIT 0x22 #define PCI_CONFIG_MEMORY_BASE_UPPER 0x28 #define PCI_CONFIG_MEMORY_LIMIT_UPPER 0x2C #define PCI_CONFIG_IO_BASE_UPPER 0x30 #define PCI_CONFIG_IO_LIMIT_UPPER 0x32 #define PCI_CONFIG_EXPANSION_ROM 0x38 #define PCI_CONFIG_BRIDGE_CONTROL 0x3E #define PCI_INTERRUPT_LINE_DISABLED 0xff typedef struct pci_device pci_device; typedef uint8_t (*pci_driver_use)(const pci_device *); typedef uint8_t (*pci_driver_validate)(const pci_device *); typedef uint8_t (*pci_driver_initialize)(pci_device *); struct pci_driver { const char *name; const char *description; struct { uint8_t class; uint8_t subclass; uint8_t interface; uint16_t vendor; uint16_t device; } match; struct { bool class: 1; bool subclass: 1; bool interface: 1; bool vendor: 1; bool device: 1; } mask; struct { bool direct_use: 1; bool validatable: 1; bool initialisable: 1; }; pci_driver_use use; pci_driver_validate validate; pci_driver_initialize initialize; } __attribute__((__aligned__(STRUCT_ALIGNMENT))); #define PCI_DRIVER(order) GENERIC_DRIVER(pci_driver, order) typedef struct { uint32_t address; uint32_t size; uint8_t present: 1; uint8_t is_io_space: 1; uint8_t type: 2; uint8_t prefetchable: 1; } bar_info; typedef struct pci_device { uint8_t bus; uint8_t slot; uint8_t func; union { struct { uint16_t vendorId; uint16_t deviceId; }; uint32_t config_line_0; }; union { struct { uint8_t revisionId; uint8_t programInterface; uint8_t subclass; uint8_t class; }; uint32_t config_line_2; }; union { struct { uint8_t cacheLineSize; uint8_t latencyTimer; uint8_t headerType; uint8_t bist; }; uint32_t config_line_3; }; bar_info bar0; bar_info bar1; bar_info bar2; bar_info bar3; bar_info bar4; bar_info bar5; const struct pci_driver *pci_driver; struct { uint8_t present: 1; } device_state; struct { uint8_t initialized: 1; } driver_state; } pci_device; typedef union { uint16_t value; struct { bool io_space: 1; bool mem_space: 1; bool bus_master: 1; bool special_cycles: 1; bool mem_write_invalidate_enable: 1; bool vga_palette_snoop: 1; bool parity_error_response: 1; uint8_t reserved: 1; bool serr_enable: 1; bool fast_b2b_enable: 1; bool interrupt_disable: 1; uint8_t reserved2: 5; } packed command; } pci_command_register_t; typedef union { uint16_t value; struct { uint8_t reserved: 3; bool interrupt_status: 1; bool capabilities_list: 1; bool speed_66mhz_capable: 1; uint8_t reserved2: 1; bool fast_b2b_capable: 1; bool master_data_parity_error: 1; uint8_t devsel_timing: 2; bool signaled_target_abort: 1; bool received_target_abort: 1; bool received_master_abort: 1; bool signaled_system_error: 1; bool detected_parity_error: 1; } packed status; } pci_status_register_t; void pci_print_info(); void pci_dump_caps(); #ifdef ENABLE_PCIPP void pci_pretty_print(); #endif void pci_init_drivers(); void pci_scan(); uint32_t pci_config_read_double_word(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset); uint16_t pci_config_read_word(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset); uint8_t pci_config_read_byte(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset); void pci_config_write_double_word(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset, uint32_t value); void pci_config_write_word(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset, uint16_t value); void pci_config_write_byte(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset, uint8_t value); void pci_init_bar(pci_device *device, uint8_t bar_index); #endif //NEW_KERNEL_PCI_H