Files
my-kern/include/myke/drivers/pci.h

244 lines
6.5 KiB
C

//
// Created by rick on 02-02-21.
//
#ifndef NEW_KERNEL_PCI_H
#define NEW_KERNEL_PCI_H
#include <sys/types.h>
#include <myke/driver.h>
#include <stdbool.h>
#include <myke/attributes.h>
#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