PatchworkOS
Loading...
Searching...
No Matches
pci_config.c
Go to the documentation of this file.
2
4#include <kernel/log/log.h>
5#include <kernel/mem/vmm.h>
6
8static mcfg_t* mcfg;
9
11{
12 mcfg = (mcfg_t*)table;
13
14 uint64_t entriesLength = mcfg->header.length - sizeof(mcfg_t);
15 if (entriesLength % sizeof(pci_config_bar_t) != 0)
16 {
17 LOG_ERR("MCFG table does not contain a whole number of entries\n");
18 return ERR;
19 }
20
21 entryCount = entriesLength / sizeof(pci_config_bar_t);
22
23 for (uint64_t i = 0; i < entryCount; i++)
24 {
25 pci_config_bar_t* entry = &mcfg->entries[i];
26
27 uint64_t busCount = entry->endBus - entry->startBus + 1;
28 uint64_t length = busCount * 256 * 4096;
29
30 void* virtAddr = (void*)PML_LOWER_TO_HIGHER(entry->base);
31 if (vmm_map(NULL, virtAddr, (void*)entry->base, length, PML_WRITE | PML_GLOBAL | PML_PRESENT, NULL, NULL) ==
32 NULL)
33 {
34 LOG_ERR("failed to map PCI-e configuration space at 0x%016lx\n", entry->base);
35 return ERR;
36 }
37
38 LOG_INFO("mapped PCI-e config space 0x%016lx (segment=%u bus=%u-%u)\n", entry->base, entry->segmentGroup,
39 entry->startBus, entry->endBus);
40 }
41
42 errno = EOK;
43 return 0;
44}
45
47
49{
50 for (uint64_t i = 0; i < entryCount; ++i)
51 {
52 if (mcfg->entries[i].segmentGroup == segmentGroup && bus >= mcfg->entries[i].startBus &&
53 bus <= mcfg->entries[i].endBus)
54 {
55 return &mcfg->entries[i];
56 }
57 }
58 return NULL;
59}
60
61static volatile void* pci_config_get_address(pci_segment_group_t segmentGroup, pci_bus_t bus, pci_slot_t slot,
62 uint8_t function, uint16_t offset)
63{
64 pci_config_bar_t* region = pci_config_bar_get(segmentGroup, bus);
65 if (region == NULL)
66 {
67 return NULL;
68 }
69
70 // This formula calculates the final address based on the OSDev Wiki page.
72 address += (uint64_t)(bus - region->startBus) << 20;
73 address += (uint64_t)slot << 15;
74 address += (uint64_t)function << 12;
75 address += offset;
76
77 return (void*)address;
78}
79
81 uint16_t offset)
82{
83 volatile uint8_t* addr = (volatile uint8_t*)pci_config_get_address(segmentGroup, bus, slot, function, offset);
84 if (addr == NULL)
85 {
86 return 0xFF;
87 }
88 return *addr;
89}
90
92 uint16_t offset)
93{
94 volatile uint16_t* addr = (volatile uint16_t*)pci_config_get_address(segmentGroup, bus, slot, function, offset);
95 if (addr == NULL)
96 {
97 return 0xFFFF;
98 }
99 return *addr;
100}
101
103 uint16_t offset)
104{
105 volatile uint32_t* addr = (volatile uint32_t*)pci_config_get_address(segmentGroup, bus, slot, function, offset);
106 if (addr == NULL)
107 {
108 return 0xFFFFFFFF;
109 }
110 return *addr;
111}
112
114 uint16_t offset, uint8_t value)
115{
116 volatile uint8_t* addr = (volatile uint8_t*)pci_config_get_address(segmentGroup, bus, slot, function, offset);
117 if (addr != NULL)
118 {
119 *addr = value;
120 }
121}
122
124 uint16_t offset, uint16_t value)
125{
126 volatile uint16_t* addr = (volatile uint16_t*)pci_config_get_address(segmentGroup, bus, slot, function, offset);
127 if (addr != NULL)
128 {
129 *addr = value;
130 }
131}
132
134 uint16_t offset, uint32_t value)
135{
136 volatile uint32_t* addr = (volatile uint32_t*)pci_config_get_address(segmentGroup, bus, slot, function, offset);
137 if (addr != NULL)
138 {
139 *addr = value;
140 }
141}
#define ACPI_SDT_HANDLER_REGISTER(sig, initHandler)
Macro to register an ACPI SDT handler.
Definition tables.h:274
void pci_config_write8(pci_segment_group_t segmentGroup, pci_bus_t bus, pci_slot_t slot, pci_function_t function, uint16_t offset, uint8_t value)
Write a byte to PCI configuration space.
Definition pci_config.c:113
uint8_t pci_function_t
PCI Function Type.
Definition pci_config.h:39
void pci_config_write16(pci_segment_group_t segmentGroup, pci_bus_t bus, pci_slot_t slot, pci_function_t function, uint16_t offset, uint16_t value)
Write a word to PCI configuration space.
Definition pci_config.c:123
uint8_t pci_config_read8(pci_segment_group_t segmentGroup, pci_bus_t bus, pci_slot_t slot, pci_function_t function, uint16_t offset)
Read a byte from PCI configuration space.
Definition pci_config.c:80
uint8_t pci_slot_t
PCI Slot Type.
Definition pci_config.h:34
uint32_t pci_config_read32(pci_segment_group_t segmentGroup, pci_bus_t bus, pci_slot_t slot, pci_function_t function, uint16_t offset)
Read a dword from PCI configuration space.
Definition pci_config.c:102
void pci_config_write32(pci_segment_group_t segmentGroup, pci_bus_t bus, pci_slot_t slot, pci_function_t function, uint16_t offset, uint32_t value)
Write a dword to PCI configuration space.
Definition pci_config.c:133
uint8_t pci_bus_t
PCI Bus Type.
Definition pci_config.h:29
uint16_t pci_segment_group_t
PCI Segment Group Type.
Definition pci_config.h:24
uint16_t pci_config_read16(pci_segment_group_t segmentGroup, pci_bus_t bus, pci_slot_t slot, pci_function_t function, uint16_t offset)
Read a word from PCI configuration space.
Definition pci_config.c:91
#define LOG_ERR(format,...)
Definition log.h:89
#define LOG_INFO(format,...)
Definition log.h:87
#define PML_LOWER_TO_HIGHER(addr)
Converts an address from the lower half to the higher half.
@ PML_PRESENT
@ PML_WRITE
@ PML_GLOBAL
void * vmm_map(space_t *space, void *virtAddr, void *physAddr, uint64_t length, pml_flags_t flags, space_callback_func_t func, void *private)
Maps physical memory to virtual memory in a given address space.
Definition vmm.c:231
#define errno
Error number variable.
Definition errno.h:27
#define EOK
No error.
Definition errno.h:32
#define NULL
Pointer error value.
Definition NULL.h:23
#define ERR
Integer error value.
Definition ERR.h:17
static uintptr_t address
Definition hpet.c:12
static volatile void * pci_config_get_address(pci_segment_group_t segmentGroup, pci_bus_t bus, pci_slot_t slot, uint8_t function, uint16_t offset)
Definition pci_config.c:61
uint64_t pci_config_init(sdt_header_t *table)
Definition pci_config.c:10
static pci_config_bar_t * pci_config_bar_get(pci_segment_group_t segmentGroup, pci_bus_t bus)
Definition pci_config.c:48
static mcfg_t * mcfg
Definition pci_config.c:8
static uint64_t entryCount
Definition pci_config.c:7
static start_entry_t entries[START_ENTRY_MAX]
Definition start_menu.c:21
__UINT32_TYPE__ uint32_t
Definition stdint.h:15
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINT8_TYPE__ uint8_t
Definition stdint.h:11
__UINTPTR_TYPE__ uintptr_t
Definition stdint.h:43
__UINT16_TYPE__ uint16_t
Definition stdint.h:13
PCI Express Memory-mapped Configuration.
Definition pci_config.h:59
sdt_header_t header
Definition pci_config.h:60
pci_config_bar_t entries[]
Definition pci_config.h:62
PCI-e Configuration Space Base Address Allocation Structure.
Definition pci_config.h:46
pci_segment_group_t segmentGroup
Definition pci_config.h:48
pci_bus_t endBus
Definition pci_config.h:50
pci_bus_t startBus
Definition pci_config.h:49
System Description Table Header.
Definition acpi.h:90
uint32_t length
Definition acpi.h:92