]> 4ch.mooo.com Git - 16.git/blob - src/lib/doslib/hw/pcie/test.c
added a bunch of things~ and midi stuff~
[16.git] / src / lib / doslib / hw / pcie / test.c
1
2 #include <stdio.h>
3 #include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
4 #include <stdlib.h>
5 #include <string.h>
6 #include <unistd.h>
7 #include <assert.h>
8 #include <fcntl.h>
9 #include <dos.h>
10
11 #include <hw/flatreal/flatreal.h>
12 #include <hw/llmem/llmem.h>
13 #include <hw/pcie/pcie.h>
14 #include <hw/cpu/cpu.h>
15
16 static void help() {
17         printf("test [options]\n");
18         printf("Test PCI-Express access library\n");
19         printf("   /?                this help\n");
20 }
21
22 int main(int argc,char **argv) {
23         int pref = -1,i;
24
25         for (i=1;i < argc;) {
26                 char *a = argv[i++];
27
28                 if (*a == '-' || *a == '/') {
29                         do { a++; } while (*a == '-' || *a == '/');
30
31                         if (!strcmp(a,"h") || !strcmp(a,"help") || !strcmp(a,"?")) {
32                                 help();
33                                 return 1;
34                         }
35                         else {
36                                 printf("Unknown switch '%s'\n",a);
37                                 help();
38                                 return 1;
39                         }
40                 }
41                 else {
42                         printf("Unknown arg '%s'\n",a);
43                         return 1;
44                 }
45         }
46
47         printf("PCI-Express bus test code\n");
48
49         cpu_probe();
50         if (cpu_basic_level < 5) {
51                 printf("PCI-Express programming requires a Pentium or higher\n");
52                 return 1;
53         }
54
55 #if TARGET_MSDOS == 32
56         probe_dpmi();
57         dos_ltp_probe();
58 #endif
59
60         if (!llmem_init()) {
61                 printf("Your system is not suitable to use with the Long-Long memory access library\n");
62                 printf("Reason: %s\n",llmem_reason);
63         }
64
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");
69                 return 1;
70         }
71 #endif
72
73         if (pcie_probe(pref) == PCIE_CFG_NONE) {
74                 printf("PCI-Express bus not found\n");
75                 return 1;
76         }
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);
80
81         { /* prove readability by dumping 0,0,0 config space */
82                 unsigned int reg;
83                 uint32_t val;
84                 uint64_t q;
85
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);
90                 }
91                 printf("\n");
92
93                 for (reg=0;reg < (8*4);reg += 4) {
94                         val = pcie_read_cfgl(0,0,0,reg);
95                         printf("%08lX ",(unsigned long)val);
96                 }
97                 printf("\n");
98
99                 for (reg=0;reg < (15*2);reg += 2) {
100                         val = pcie_read_cfgw(0,0,0,reg);
101                         printf("%04X ",(unsigned int)val);
102                 }
103                 printf("\n");
104
105                 for (reg=0;reg < 25;reg++) {
106                         val = pcie_read_cfgb(0,0,0,reg);
107                         printf("%02X ",(unsigned int)val);
108                 }
109                 printf("\n");
110                 while (getch() != 13);
111         }
112
113         /* then enumerate the bus */
114         {
115                 int line=0;
116                 uint16_t bus;
117                 uint8_t dev,func;
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]);
122                                 line++;
123                         }
124
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;
130                                         uint32_t class_code;
131                                         uint8_t revision_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);
136
137                                         class_code = pcie_read_cfgl(bus,dev,func,0x08);
138                                         revision_id = class_code & 0xFF;
139                                         class_code >>= 8UL;
140
141                                         /* show it Linux sysfs style */
142                                         line++;
143                                         printf(" %04x:%02x:%02x.%x: Vendor %04x Device %04x Sub %04x Vnd %04x Class %06lx rev %02x\n",
144                                                 0,bus,dev,func,
145                                                 vendor,device,subsystem,subvendor_id,
146                                                 class_code,revision_id);
147
148                                         /* any interrupt? */
149                                         {
150                                                 uint8_t l = pcie_read_cfgb(bus,dev,func,0x3C);
151                                                 uint8_t p = pcie_read_cfgb(bus,dev,func,0x3D);
152                                                 if (p != 0)
153                                                         printf("   IRQ: %u (pin %c (%02Xh))\n",l,p-1+'A',p);
154                                         }
155
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 */
160                                         {
161                                                 uint8_t bar;
162
163                                                 for (bar=0;bar < 6;bar++) {
164                                                         uint8_t io=0;
165                                                         uint32_t lower=0,higher=0;
166                                                         uint8_t reg = 0x10+(bar*4);
167
168                                                         _cli();
169                                                         t32a = pcie_read_cfgl(bus,dev,func,reg);
170                                                         if (t32a == 0xFFFFFFFFUL) continue;
171                                                         io = t32a & 1;
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? */
181                                                         }
182                                                         else {
183                                                                 uint32_t size = ~(t32c & ~(io ? 3UL : 15UL));
184                                                                 if (io) size &= 0xFFFFUL;
185                                                                 if ((size+1UL) == 0UL) continue;
186                                                                 higher = lower + size;
187                                                         }
188
189                                                         if (higher == lower) continue;
190
191                                                         _sti();
192                                                         line++;
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");
196                                                 }
197                                                 _sti();
198                                         }
199
200                                         if (line >= 20) {
201                                                 while (getch() != 13);
202                                                 line -= 20;
203                                         }
204                                 }
205                         }
206
207                         if (line >= 20) {
208                                 while (getch() != 13);
209                                 line -= 20;
210                         }
211                 }
212         }
213
214         return 0;
215 }
216