Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2 | pj | 1 | #include <ll/i386/hw-instr.h> |
2 | #include <ll/i386/hw-data.h> |
||
3 | #include <ll/i386/hw-arch.h> |
||
4 | #include <ll/i386/hw-io.h> |
||
5 | |||
6 | #include <drivers/llpci.h> |
||
7 | |||
8 | int (*pcibios_read_config_byte)(BYTE bus, BYTE dev, BYTE where, BYTE *val); |
||
9 | int (*pcibios_read_config_word)(BYTE bus, BYTE dev, BYTE where, WORD *val); |
||
10 | int (*pcibios_read_config_dword)(BYTE bus, BYTE dev, BYTE where, DWORD *val); |
||
11 | int (*pcibios_write_config_byte)(BYTE bus, BYTE dev, BYTE where, BYTE val); |
||
12 | int (*pcibios_write_config_word)(BYTE bus, BYTE dev, BYTE where, WORD val); |
||
13 | int (*pcibios_write_config_dword)(BYTE bus, BYTE dev, BYTE where, DWORD val); |
||
14 | |||
15 | static int PCItype = 0; |
||
16 | |||
17 | /* LowLevel Functions */ |
||
18 | int pci_conf1_read_config_dword(BYTE bus, BYTE dev, BYTE where, DWORD *val) |
||
19 | { |
||
20 | if (where & 3) |
||
21 | return -1; |
||
22 | outpd(0x0CF8, 0x80000000 | (bus <<16) | (dev << 8) | (where & ~3)); |
||
23 | *val = inpd(0x0CFC); |
||
24 | return 1; |
||
25 | } |
||
26 | |||
27 | int pci_conf2_read_config_dword(BYTE bus, BYTE dev, BYTE where, DWORD *val) |
||
28 | { |
||
29 | if (dev & 0x80) |
||
30 | return -1; |
||
31 | outpw(0xCF8, (((dev & 7) << 1) | 0xf0)); |
||
32 | outpw(0xCFA, bus); |
||
33 | *val = inpd((0xC000 | ((dev & 0x78) << 5)) + where); |
||
34 | outpw(0xCF8,0); |
||
35 | return 1; |
||
36 | } |
||
37 | |||
38 | int pci_conf1_read_config_byte(BYTE bus, BYTE dev, BYTE where, BYTE *val) |
||
39 | { |
||
40 | outpd(0x0CF8, 0x80000000 | (bus <<16) | (dev << 8) | (where & ~3)); |
||
41 | *val = inp(0x0CFC + (where & 3)); |
||
42 | return 1; |
||
43 | } |
||
44 | |||
45 | int pci_conf2_read_config_byte(BYTE bus, BYTE dev, BYTE where, BYTE *val) |
||
46 | { |
||
47 | if (dev & 0x80) |
||
48 | return -1; |
||
49 | outpw(0xCF8, (((dev & 7) << 1) | 0xf0)); |
||
50 | outpw(0xCFA, bus); |
||
51 | *val = inp((0xC000 | ((dev & 0x78) << 5)) + where); |
||
52 | outpw(0xCF8,0); |
||
53 | return 1; |
||
54 | } |
||
55 | int pci_conf1_read_config_word(BYTE bus, BYTE dev, BYTE where, WORD *val) |
||
56 | { |
||
57 | if (where & 1) |
||
58 | return -1; |
||
59 | outpd(0x0CF8, 0x80000000 | (bus <<16) | (dev << 8) | (where & ~3)); |
||
60 | *val = inpw(0x0CFC + (where & 2)); |
||
61 | return 1; |
||
62 | } |
||
63 | |||
64 | int pci_conf2_read_config_word(BYTE bus, BYTE dev, BYTE where, WORD *val) |
||
65 | { |
||
66 | if (dev & 0x80) |
||
67 | return -1; |
||
68 | outpw(0xCF8, (((dev & 7) << 1) | 0xf0)); |
||
69 | outpw(0xCFA, bus); |
||
70 | *val = inpw((0xC000 | ((dev & 0x78) << 5)) + where); |
||
71 | /* *val = inpw(0xC000 | ((dev & 0x78) << 5) + where); */ |
||
72 | outpw(0xCF8,0); |
||
73 | return 1; |
||
74 | } |
||
75 | |||
76 | |||
77 | int pci_conf1_write_config_dword(BYTE bus, BYTE dev, BYTE where, DWORD val) |
||
78 | { |
||
79 | if (where & 3) |
||
80 | return -1; |
||
81 | outpd(0x0CF8, 0x80000000 | (bus <<16) | (dev << 8) | (where & ~3)); |
||
82 | outpd(0x0CFC, val); |
||
83 | return 1; |
||
84 | } |
||
85 | |||
86 | int pci_conf2_write_config_dword(BYTE bus, BYTE dev, BYTE where, DWORD val) |
||
87 | { |
||
88 | if (dev & 0x80) |
||
89 | return -1; |
||
90 | outpw(0xCF8, (((dev & 7) << 1) | 0xf0)); |
||
91 | outpw(0xCFA, bus); |
||
92 | outpd((0xC000 | ((dev & 0x78) << 5)) + where, val); |
||
93 | outpw(0xCF8,0); |
||
94 | return 1; |
||
95 | } |
||
96 | |||
97 | int pci_conf1_write_config_byte(BYTE bus, BYTE dev, BYTE where, BYTE val) |
||
98 | { |
||
99 | outpd(0x0CF8, 0x80000000 | (bus <<16) | (dev << 8) | (where & ~3)); |
||
100 | outp(0x0CFC + (where & 3), val); |
||
101 | return 1; |
||
102 | } |
||
103 | |||
104 | int pci_conf2_write_config_byte(BYTE bus, BYTE dev, BYTE where, BYTE val) |
||
105 | { |
||
106 | if (dev & 0x80) |
||
107 | return -1; |
||
108 | outpw(0xCF8, (((dev & 7) << 1) | 0xf0)); |
||
109 | outpw(0xCFA, bus); |
||
110 | outp((0xC000 | ((dev & 0x78) << 5)) + where, val); |
||
111 | outpw(0xCF8,0); |
||
112 | return 1; |
||
113 | } |
||
114 | int pci_conf1_write_config_word(BYTE bus, BYTE dev, BYTE where, WORD val) |
||
115 | { |
||
116 | if (where & 1) |
||
117 | return -1; |
||
118 | outpd(0x0CF8, 0x80000000 | (bus <<16) | (dev << 8) | (where & ~3)); |
||
119 | outpw(0x0CFC + (where & 2), val); |
||
120 | return 1; |
||
121 | } |
||
122 | |||
123 | int pci_conf2_write_config_word(BYTE bus, BYTE dev, BYTE where, WORD val) |
||
124 | { |
||
125 | if (dev & 0x80) |
||
126 | return -1; |
||
127 | outpw(0xCF8, (((dev & 7) << 1) | 0xf0)); |
||
128 | outpw(0xCFA, bus); |
||
129 | outpw((0xC000 | ((dev & 0x78) << 5)) + where, val); |
||
130 | outpw(0xCF8,0); |
||
131 | return 1; |
||
132 | } |
||
133 | |||
134 | |||
135 | |||
136 | int pci_check_direct() |
||
137 | { |
||
138 | int PCItype; |
||
139 | DWORD tmp; |
||
140 | |||
141 | PCItype = 0; |
||
142 | outp(0xCFB, 0x01); |
||
143 | tmp = inpd(0xCF8); |
||
144 | outpd(0xCF8, 0x80000000); |
||
145 | if (inpd(0xCF8) == 0x80000000) { |
||
146 | outpd(0xCF8, tmp); |
||
147 | pcibios_read_config_dword = pci_conf1_read_config_dword; |
||
148 | pcibios_read_config_word = pci_conf1_read_config_word; |
||
149 | pcibios_read_config_byte = pci_conf1_read_config_byte; |
||
150 | |||
151 | pcibios_write_config_dword = pci_conf1_write_config_dword; |
||
152 | pcibios_write_config_word = pci_conf1_write_config_word; |
||
153 | pcibios_write_config_byte = pci_conf1_write_config_byte; |
||
154 | PCItype = 1; |
||
155 | } |
||
156 | outpw(0x0CF8,tmp); |
||
157 | |||
158 | outp(0xCFB, 0); |
||
159 | outp(0xCF8, 0); |
||
160 | outp(0x0CFA,0); |
||
161 | if ((inp(0x0CF8) == 0) && (inp(0x0CFA) == 0)) { |
||
162 | pcibios_read_config_dword = pci_conf2_read_config_dword; |
||
163 | pcibios_read_config_word = pci_conf2_read_config_word; |
||
164 | pcibios_read_config_byte = pci_conf2_read_config_byte; |
||
165 | |||
166 | pcibios_write_config_dword = pci_conf2_write_config_dword; |
||
167 | pcibios_write_config_word = pci_conf2_write_config_word; |
||
168 | pcibios_write_config_byte = pci_conf2_write_config_byte; |
||
169 | PCItype = 2; |
||
170 | } |
||
171 | return PCItype; |
||
172 | } |
||
173 | |||
174 | /*__________________________________________________________________________*/ |
||
175 | /*__________________________________________________________________________*/ |
||
176 | int pcibios_present(void) |
||
177 | { |
||
178 | return (PCItype != 0); |
||
179 | } |
||
180 | |||
181 | int pcibios_init(void) |
||
182 | { |
||
183 | if (ll_arch.x86.cpu < 3) { |
||
184 | return -1; /* CPU < 386 --> No PCI */ |
||
185 | } |
||
186 | PCItype = pci_check_direct(); |
||
187 | if (PCItype == 0) { |
||
188 | return -1; |
||
189 | } |
||
190 | return 1; |
||
191 | } |