3 #include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
11 #include <hw/flatreal/flatreal.h>
12 #include <hw/llmem/llmem.h>
13 #include <hw/pcie/pcie.h>
14 #include <hw/cpu/cpu.h>
17 printf("test [options]\n");
18 printf("Test PCI-Express access library\n");
19 printf(" /? this help\n");
22 int main(int argc,char **argv) {
28 if (*a == '-' || *a == '/') {
29 do { a++; } while (*a == '-' || *a == '/');
31 if (!strcmp(a,"h") || !strcmp(a,"help") || !strcmp(a,"?")) {
36 printf("Unknown switch '%s'\n",a);
42 printf("Unknown arg '%s'\n",a);
47 printf("PCI-Express bus test code\n");
50 if (cpu_basic_level < 5) {
51 printf("PCI-Express programming requires a Pentium or higher\n");
55 #if TARGET_MSDOS == 32
61 printf("Your system is not suitable to use with the Long-Long memory access library\n");
62 printf("Reason: %s\n",llmem_reason);
65 #if TARGET_MSDOS == 16
66 if (!flatrealmode_setup(FLATREALMODE_4GB)) {
67 printf("Unable to set up flat real mode (needed for 16-bit builds)\n");
68 printf("Most ACPI functions require access to the full 4GB range.\n");
73 if (pcie_probe(pref) == PCIE_CFG_NONE) {
74 printf("PCI-Express bus not found\n");
77 printf("Found PCI-Express BUS, code %d\n",pcie_cfg);
78 printf(" Last bus: %d\n",pcie_bios_last_bus);
79 printf(" Bus decode bits: %d\n",pcie_bus_decode_bits);
81 { /* prove readability by dumping 0,0,0 config space */
86 printf("PCI BUS/DEV/FUNC 0/0/0 config space: [DWORD]\n");
87 for (reg=0;reg < (4*8);reg += 8) {
88 q = pcie_read_cfgq(0,0,0,reg);
89 printf("%016llX ",(unsigned long long)q);
93 for (reg=0;reg < (8*4);reg += 4) {
94 val = pcie_read_cfgl(0,0,0,reg);
95 printf("%08lX ",(unsigned long)val);
99 for (reg=0;reg < (15*2);reg += 2) {
100 val = pcie_read_cfgw(0,0,0,reg);
101 printf("%04X ",(unsigned int)val);
105 for (reg=0;reg < 25;reg++) {
106 val = pcie_read_cfgb(0,0,0,reg);
107 printf("%02X ",(unsigned int)val);
110 while (getch() != 13);
113 /* then enumerate the bus */
118 uint32_t t32a,t32b,t32c;
119 for (bus=0;bus <= pcie_bios_last_bus;bus++) {
120 if (pcie_bus_mmio_base[bus] != 0ULL) {
121 fprintf(stderr,"BUS %u at %08llX\n",bus,(unsigned long long)pcie_bus_mmio_base[bus]);
125 for (dev=0;dev < 32;dev++) {
126 uint8_t functions = pcie_probe_device_functions(bus,dev);
127 for (func=0;func < functions;func++) {
128 /* make sure something is there before announcing it */
129 uint16_t vendor,device,subsystem,subvendor_id;
132 vendor = pcie_read_cfgw(bus,dev,func,0x00); if (vendor == 0xFFFF) continue;
133 device = pcie_read_cfgw(bus,dev,func,0x02); if (device == 0xFFFF) continue;
134 subvendor_id = pcie_read_cfgw(bus,dev,func,0x2C);
135 subsystem = pcie_read_cfgw(bus,dev,func,0x2E);
137 class_code = pcie_read_cfgl(bus,dev,func,0x08);
138 revision_id = class_code & 0xFF;
141 /* show it Linux sysfs style */
143 printf(" %04x:%02x:%02x.%x: Vendor %04x Device %04x Sub %04x Vnd %04x Class %06lx rev %02x\n",
145 vendor,device,subsystem,subvendor_id,
146 class_code,revision_id);
150 uint8_t l = pcie_read_cfgb(bus,dev,func,0x3C);
151 uint8_t p = pcie_read_cfgb(bus,dev,func,0x3D);
153 printf(" IRQ: %u (pin %c (%02Xh))\n",l,p-1+'A',p);
156 /* show resources too. note that to figure out how large the BARs are we have to
157 * write to them and see which bits toggle. finally, remember that changing BARs
158 * affects any resources that TSRs or other functions might be trying to use at
159 * the same time, so we must disable interrupts while doing this */
163 for (bar=0;bar < 6;bar++) {
165 uint32_t lower=0,higher=0;
166 uint8_t reg = 0x10+(bar*4);
169 t32a = pcie_read_cfgl(bus,dev,func,reg);
170 if (t32a == 0xFFFFFFFFUL) continue;
172 if (io) lower = t32a & 0xFFFFFFFCUL;
173 else lower = t32a & 0xFFFFFFF0UL;
174 pcie_write_cfgl(bus,dev,func,reg,0);
175 t32b = pcie_read_cfgl(bus,dev,func,reg);
176 pcie_write_cfgl(bus,dev,func,reg,~0UL);
177 t32c = pcie_read_cfgl(bus,dev,func,reg);
178 pcie_write_cfgl(bus,dev,func,reg,t32a); /* restore prior contents */
179 if (t32a == t32b && t32b == t32c) {
180 /* hm, can't change it? */
183 uint32_t size = ~(t32c & ~(io ? 3UL : 15UL));
184 if (io) size &= 0xFFFFUL;
185 if ((size+1UL) == 0UL) continue;
186 higher = lower + size;
189 if (higher == lower) continue;
193 if (io) printf(" IO: 0x%04lx-0x%04lx\n",lower,higher);
194 else printf(" MEM: 0x%08lx-0x%08lx %s\n",lower,higher,
195 t32a & 8 ? "Prefetch" : "Non-prefetch");
201 while (getch() != 13);
208 while (getch() != 13);