20 #include "pedigree/kernel/machine/Pci.h" 21 #include "modules/Module.h" 23 #include "pedigree/kernel/Log.h" 24 #include "pedigree/kernel/machine/Bus.h" 25 #include "pedigree/kernel/machine/Device.h" 26 #include "pedigree/kernel/processor/IoPort.h" 27 #include "pedigree/kernel/processor/types.h" 28 #include "pedigree/kernel/utilities/String.h" 29 #include "pedigree/kernel/utilities/Vector.h" 30 #include "pedigree/kernel/utilities/utility.h" 32 #define CONFIG_ADDRESS 0 37 static IoPort configSpace(
"PCI config space");
45 uint32_t
function : 3;
48 uint32_t reserved : 7;
56 uint32_t *pCs32 =
reinterpret_cast<uint32_t *
>(pCs);
63 static const char *getVendor(uint16_t vendor)
65 for (
unsigned int i = 0; i < PCI_VENTABLE_LEN; i++)
67 if (PciVenTable[i].VenId == vendor)
68 return PciVenTable[i].VenShort;
73 static const char *getDevice(uint16_t vendor, uint16_t device)
75 for (
unsigned int i = 0; i < PCI_DEVTABLE_LEN; i++)
77 if (PciDevTable[i].VenId == vendor && PciDevTable[i].DevId == device)
78 return PciDevTable[i].ChipDesc;
85 for (
int iBus = 0; iBus < MAX_BUS; iBus++)
88 char *str =
new char[256];
89 StringFormat(str,
"PCI #%d", iBus);
93 for (
int iDevice = 0; iDevice < 32; iDevice++)
95 bool bIsMultifunc =
false;
96 for (
int iFunc = 0; iFunc < 8; iFunc++)
98 if (iFunc > 0 && !bIsMultifunc)
104 uint32_t vendorAndDeviceId =
106 if ((vendorAndDeviceId & 0xFFFF) == 0xFFFF ||
107 (vendorAndDeviceId & 0xFFFF) == 0)
118 readConfigSpace(pDevice, &cs);
120 if (cs.header_type & 0x80)
124 "PCI: " <<
Dec << iBus <<
":" << iDevice <<
":" << iFunc
125 <<
"\t Vendor:" <<
Hex << cs.vendor
126 <<
" Device:" << cs.device);
130 c,
"%s - %s", getDevice(cs.vendor, cs.device),
131 getVendor(cs.vendor));
135 cs.class_code, cs.subclass, cs.vendor, cs.device,
138 "PCI: Class: " << cs.class_code
139 <<
" Subclass: " << cs.subclass
140 <<
" ProgIF: " << cs.progif);
142 for (
int l = 0; l < 6; l++)
146 if ((cs.header_type & 0x7F) == 0x1 && l >= 2)
156 uint8_t offset = (0x10 + l * 4) >> 2;
158 pDevice, offset, 0xFFFFFFFF);
162 pDevice, offset, cs.bar[l]);
166 uint32_t size = ~(mask & 0xFFFFFFF0) +
170 bool io = (cs.bar[l] & 0x1);
175 StringFormat(c,
"bar%d", l);
176 uintptr_t s = (cs.bar[l] & 0xFFFFFFF0);
179 "PCI: BAR" <<
Dec << l <<
Hex <<
": " << s <<
".." 180 << (s + size) <<
" (" << io <<
")");
182 String(c), cs.bar[l] & 0xFFFFFFF0, size,
183 (cs.bar[l] & 0x1) == 0x1);
188 "PCI: IRQ: L" << cs.interrupt_line <<
" P" 189 << cs.interrupt_pin);
216 MODULE_INFO(
"pci", &entry, &exit);
virtual void setInterruptNumber(uintptr_t n)
virtual Vector< Address * > & addresses()
static void addToRoot(Device *device)
virtual void setSpecificType(String str)
uint32_t readConfigSpace(Device *pDev, uint8_t offset)
void addChild(Device *pDevice)
void setPciPosition(uint32_t bus, uint32_t device, uint32_t func)
void setParent(Device *p)
void setPciIdentifiers(uint8_t classCode, uint8_t subclassCode, uint16_t vendorId, uint16_t deviceId, uint8_t progIf)
void setPciConfigHeader(const PciBus::ConfigSpace &space)
void writeConfigSpace(Device *pDev, uint8_t offset, uint32_t data)