/* * pci.h * * Copyright (C) 2016 Aleksandar Andrejevic * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #ifndef _PCI_H_ #define _PCI_H_ #include #include #define PCI_FIELD_REG(h, p) (OFFSET_OF(h, p) >> 2) #define PCI_FIELD_BIT_OFFSET(h, p) ((OFFSET_OF(h, p) & 3) << 3) #define PCI_FIELD_SIZE_MASK(h, p) ((sizeof(((h*)NULL)->p) == 1) ? 0xFF : ((sizeof(((h*)NULL)->p) == 2) ? 0xFFFF : 0xFFFFFFFF)) #define PCI_FIELD_MASK(h, p) (PCI_FIELD_SIZE_MASK(h, p) << PCI_FIELD_BIT_OFFSET(h, p)) #define PCI_READ_VALUE(d, h, p) ((pci_read((d), PCI_FIELD_REG(h, p)) >> PCI_FIELD_BIT_OFFSET(h, p)) & PCI_FIELD_SIZE_MASK(h, p)) #define PCI_WRITE_VALUE(d, h, p, v) pci_write((d), \ PCI_FIELD_REG(h, p), \ (((v) << PCI_FIELD_BIT_OFFSET(h, p)) & PCI_FIELD_MASK(h, p)) \ | (pci_read((d), PCI_FIELD_REG(h, p)) & ~PCI_FIELD_MASK(h, p))) #pragma pack(push, 1) typedef struct { word_t vendor_id; word_t device_id; word_t command; word_t status; byte_t revision_id; byte_t prog_if; byte_t subclass; byte_t class; byte_t cache_line_size; byte_t latency_timer; byte_t header_type; byte_t bist; } pci_header_t; typedef struct { pci_header_t header; dword_t bar[6]; dword_t cardbus_ptr; word_t subsys_vendor_id; word_t subsys_id; dword_t expansion_rom_addr; byte_t capabilities; byte_t reserved[7]; byte_t interrupt_line; byte_t interrupt_pin; byte_t min_grant; byte_t max_latency; } pci_standard_header_t; typedef struct { pci_header_t header; dword_t bar[2]; byte_t primary_bus_num; byte_t secondary_bus_num; byte_t subordinate_bus_num; byte_t secondary_latency_timer; byte_t io_base; byte_t io_limit; word_t secondary_status; word_t prefetchable_mem_base; word_t prefetchable_mem_limit; dword_t prefetchable_base_high; dword_t prefetchable_limit_high; word_t io_base_high; word_t io_limit_high; byte_t capabilities; byte_t reserved[3]; dword_t expansion_rom_addr; byte_t interrupt_line; byte_t interrupt_pin; word_t bridge_control; } pci_bridge_header_t; #pragma pack(pop) typedef struct _pci_device_t { list_entry_t list; dword_t bus, slot, function; dword_t class, subclass, prog_if; bool_t in_use; } pci_device_t; enum { PCI_LEGACY_DEVICE, PCI_MASS_STORAGE_DEVICE, PCI_NETWORK_DEVICE, PCI_DISPLAY_DEVICE, PCI_MULTIMEDIA_DEVICE, PCI_MEMORY_DEVICE, PCI_BRIDGE_DEVICE, PCI_COMMUNICATION_DEVICE, PCI_PERIPHERAL_DEVICE, PCI_INPUT_DEVICE, PCI_DOCKING_STATION, PCI_PROCESSOR, PCI_WIRELESS_DEVICE }; extern const char *pci_device_classes[]; void pci_init(void); list_entry_t *get_pci_device_list_head(void); dword_t pci_read(pci_device_t *device, dword_t reg); void pci_write(pci_device_t *device, dword_t reg, dword_t data); #endif