1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
#include <stdio.h>
#include <stdlib.h>
#include <dpmi.h>
typedef unsigned long UDWORD;
typedef short int WORD;
typedef unsigned short int UWORD;
typedef unsigned char UBYTE;
typedef union {
struct {
UDWORD edi;
UDWORD esi;
UDWORD ebp;
UDWORD res;
UDWORD ebx;
UDWORD edx;
UDWORD ecx;
UDWORD eax;
} d;
struct {
UWORD di, di_hi;
UWORD si, si_hi;
UWORD bp, bp_hi;
UWORD res, res_hi;
UWORD bx, bx_hi;
UWORD dx, dx_hi;
UWORD cx, cx_hi;
UWORD ax, ax_hi;
UWORD flags;
UWORD es;
UWORD ds;
UWORD fs;
UWORD gs;
UWORD ip;
UWORD cs;
UWORD sp;
UWORD ss;
} x;
struct {
UBYTE edi[4];
UBYTE esi[4];
UBYTE ebp[4];
UBYTE res[4];
UBYTE bl, bh, ebx_b2, ebx_b3;
UBYTE dl, dh, edx_b2, edx_b3;
UBYTE cl, ch, ecx_b2, ecx_b3;
UBYTE al, ah, eax_b2, eax_b3;
} h;
} X86_REGS;
/*************************************************************
* Excute soft interrupt in real mode
*************************************************************/
int x86_int(int int_num, X86_REGS *x86_reg) {
__dpmi_regs d_regs;
int return_value;
d_regs.d.edi = x86_reg->d.edi;
d_regs.d.esi = x86_reg->d.esi;
d_regs.d.ebp = x86_reg->d.ebp;
d_regs.d.res = x86_reg->d.res;
d_regs.d.ebx = x86_reg->d.ebx;
d_regs.d.ecx = x86_reg->d.ecx;
d_regs.d.edx = x86_reg->d.edx;
d_regs.d.eax = x86_reg->d.eax;
d_regs.x.flags = x86_reg->x.flags;
d_regs.x.es = x86_reg->x.es;
d_regs.x.ds = x86_reg->x.ds;
d_regs.x.fs = x86_reg->x.fs;
d_regs.x.gs = x86_reg->x.gs;
d_regs.x.ip = x86_reg->x.ip;
d_regs.x.cs = x86_reg->x.cs;
d_regs.x.sp = x86_reg->x.sp;
d_regs.x.ss = x86_reg->x.ss;
return_value = __dpmi_int(int_num, &d_regs);
x86_reg->d.edi = d_regs.d.edi;
x86_reg->d.esi = d_regs.d.esi;
x86_reg->d.ebp = d_regs.d.ebp;
x86_reg->d.res = d_regs.d.res;
x86_reg->d.ebx = d_regs.d.ebx;
x86_reg->d.ecx = d_regs.d.ecx;
x86_reg->d.edx = d_regs.d.edx;
x86_reg->d.eax = d_regs.d.eax;
x86_reg->x.flags = d_regs.x.flags;
x86_reg->x.es = d_regs.x.es;
x86_reg->x.ds = d_regs.x.ds;
x86_reg->x.fs = d_regs.x.fs;
x86_reg->x.gs = d_regs.x.gs;
x86_reg->x.ip = d_regs.x.ip;
x86_reg->x.cs = d_regs.x.cs;
x86_reg->x.sp = d_regs.x.sp;
x86_reg->x.ss = d_regs.x.ss;
return return_value;
}
/**********************************
* Read Configuration WORD if PCI
**********************************/
UWORD ReadConfigWORD(WORD pciAddr, int reg) {
X86_REGS inregs;
inregs.x.ax = 0xB109; // Read Configuration word
inregs.x.bx = pciAddr;
inregs.x.di = reg; // Register number
x86_int(0x1A, &inregs);
return inregs.d.ecx; // the value
}
// main program
int main(void) {
UWORD pciAddr;
UWORD subClass;
int ehciCount = 0, ohciCount = 0, uhciCount = 0;
for (pciAddr = 0; pciAddr < 0xffff; pciAddr++) {
if (ReadConfigWORD(pciAddr, 0) != 0xFFFF) {
// Read Class Code
if (ReadConfigWORD(pciAddr, 0x000a ) == 0x0c03) { // Usb Host Controller
// Read SubClass Code
subClass = ReadConfigWORD(pciAddr, 0x0008);
if ((subClass & 0xff00) == 0x2000) { // uhci
ehciCount++;
} else if ((subClass & 0xff00) == 0x1000) { // ohci
ohciCount++;
} else if ((subClass & 0xff00) == 0x00) { // uhci
uhciCount++;
}
}
}
}
printf("There are %d ohci device(s).\n", ohciCount);
printf("There are %d ehci device(s).\n", ehciCount);
printf("There are %d uhci device(s).\n", uhciCount);
return 0;
}
|