1
2 #include <stdint.h>
3
4 #include <sys/kassert.h>
5 #include <sys/pci.h>
6
7 #include <machine/amd64.h>
8 #include <machine/amd64op.h>
9
10 #define PCI_PORT_ADDR 0xCF8
11 #define PCI_PORT_DATABASE 0xCFC
12
13 static inline uint32_t
PCIGetAddr(uint32_t bus,uint32_t slot,uint32_t func,uint32_t reg)14 PCIGetAddr(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg)
15 {
16 ASSERT(bus < 256 && slot < 64 && func < 8 && reg < 256);
17 return (1 << 31) | (bus << 16) | (slot << 11) | (func << 8) | (reg & 0x00fc);
18 }
19
20 uint8_t
PCICfgRead8(uint32_t bus,uint32_t slot,uint32_t func,uint32_t reg)21 PCICfgRead8(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg)
22 {
23 uint32_t addr = PCIGetAddr(bus, slot, func, reg);
24 uint16_t port = PCI_PORT_DATABASE + (reg & 0x3);
25
26 outl(PCI_PORT_ADDR, addr);
27 return inb(port);
28 }
29
30 uint16_t
PCICfgRead16(uint32_t bus,uint32_t slot,uint32_t func,uint32_t reg)31 PCICfgRead16(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg)
32 {
33 uint32_t addr = PCIGetAddr(bus, slot, func, reg);
34 uint16_t port = PCI_PORT_DATABASE + (reg & 0x2);
35
36 ASSERT((reg & 0x1) == 0);
37
38 outl(PCI_PORT_ADDR, addr);
39 return inw(port);
40 }
41
42 uint32_t
PCICfgRead32(uint32_t bus,uint32_t slot,uint32_t func,uint32_t reg)43 PCICfgRead32(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg)
44 {
45 uint32_t addr = PCIGetAddr(bus, slot, func, reg);
46 uint16_t port = PCI_PORT_DATABASE;
47
48 ASSERT((reg & 0x3) == 0);
49
50 outl(PCI_PORT_ADDR, addr);
51 return inl(port);
52 }
53
54 void
PCICfgWrite8(uint32_t bus,uint32_t slot,uint32_t func,uint32_t reg,uint8_t data)55 PCICfgWrite8(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg,
56 uint8_t data)
57 {
58 uint32_t addr = PCIGetAddr(bus, slot, func, reg);
59 uint16_t port = PCI_PORT_DATABASE + (reg & 0x3);
60
61 outl(PCI_PORT_ADDR, addr);
62 outb(port, data);
63 }
64
65 void
PCICfgWrite16(uint32_t bus,uint32_t slot,uint32_t func,uint32_t reg,uint16_t data)66 PCICfgWrite16(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg,
67 uint16_t data)
68 {
69 uint32_t addr = PCIGetAddr(bus, slot, func, reg);
70 uint16_t port = PCI_PORT_DATABASE + (reg & 0x3);
71
72 outl(PCI_PORT_ADDR, addr);
73 outw(port, data);
74 }
75
76 void
PCICfgWrite32(uint32_t bus,uint32_t slot,uint32_t func,uint32_t reg,uint32_t data)77 PCICfgWrite32(uint32_t bus, uint32_t slot, uint32_t func, uint32_t reg,
78 uint32_t data)
79 {
80 uint32_t addr = PCIGetAddr(bus, slot, func, reg);
81 uint16_t port = PCI_PORT_DATABASE + (reg & 0x3);
82
83 outl(PCI_PORT_ADDR, addr);
84 outl(port, data);
85 }
86
87