This source file includes following definitions.
- sti_pci_match
- sti_pci_attach
- sti_check_rom
- sti_readbar
- sti_pci_enable_rom
- sti_pci_disable_rom
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <sys/param.h>
21 #include <sys/systm.h>
22 #include <sys/device.h>
23
24 #include <dev/pci/pcireg.h>
25 #include <dev/pci/pcivar.h>
26 #include <dev/pci/pcidevs.h>
27
28 #include <dev/wscons/wsdisplayvar.h>
29
30 #include <dev/ic/stireg.h>
31 #include <dev/ic/stivar.h>
32
33 int sti_pci_match(struct device *, void *, void *);
34 void sti_pci_attach(struct device *, struct device *, void *);
35
36 struct sti_pci_softc {
37 struct sti_softc sc_base;
38
39 pci_chipset_tag_t sc_pc;
40 pcitag_t sc_tag;
41 };
42
43 struct cfattach sti_pci_ca = {
44 sizeof(struct sti_pci_softc), sti_pci_match, sti_pci_attach
45 };
46
47 const struct pci_matchid sti_pci_devices[] = {
48 { PCI_VENDOR_HP, PCI_PRODUCT_HP_VISUALIZE_EG },
49 { PCI_VENDOR_HP, PCI_PRODUCT_HP_VISUALIZE_FX2 },
50 { PCI_VENDOR_HP, PCI_PRODUCT_HP_VISUALIZE_FX4 },
51 { PCI_VENDOR_HP, PCI_PRODUCT_HP_VISUALIZE_FX6 },
52 { PCI_VENDOR_HP, PCI_PRODUCT_HP_VISUALIZE_FXE },
53 };
54
55 int sti_readbar(struct sti_softc *, struct pci_attach_args *, u_int, int);
56 int sti_check_rom(struct sti_pci_softc *, struct pci_attach_args *);
57 void sti_pci_enable_rom(struct sti_softc *);
58 void sti_pci_disable_rom(struct sti_softc *);
59
60 int sti_pci_is_console(struct pci_attach_args *, bus_addr_t *);
61
62 int
63 sti_pci_match(struct device *parent, void *cf, void *aux)
64 {
65 struct pci_attach_args *paa = aux;
66
67 return (pci_matchbyid(paa, sti_pci_devices,
68 sizeof(sti_pci_devices) / sizeof(sti_pci_devices[0])));
69 }
70
71 void
72 sti_pci_attach(struct device *parent, struct device *self, void *aux)
73 {
74 struct sti_pci_softc *spc = (void *)self;
75 struct pci_attach_args *paa = aux;
76
77 spc->sc_pc = paa->pa_pc;
78 spc->sc_tag = paa->pa_tag;
79 spc->sc_base.sc_enable_rom = sti_pci_enable_rom;
80 spc->sc_base.sc_disable_rom = sti_pci_disable_rom;
81
82 printf("\n");
83
84 if (sti_check_rom(spc, paa) != 0)
85 return;
86
87 printf("%s", self->dv_xname);
88 if (sti_attach_common(&spc->sc_base, STI_CODEBASE_MAIN) == 0) {
89 if (sti_pci_is_console(paa, spc->sc_base.bases) != 0)
90 spc->sc_base.sc_flags |= STI_CONSOLE;
91 startuphook_establish(sti_end_attach, spc);
92 }
93 }
94
95
96
97
98 int
99 sti_check_rom(struct sti_pci_softc *spc, struct pci_attach_args *pa)
100 {
101 struct sti_softc *sc = &spc->sc_base;
102 pcireg_t address, mask;
103 bus_space_handle_t romh;
104 bus_size_t romsize, subsize, stiromsize;
105 bus_addr_t selected, offs, suboffs;
106 u_int32_t tmp;
107 int i;
108 int rc;
109
110
111 address = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG);
112 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, ~PCI_ROM_ENABLE);
113 mask = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG);
114 address |= PCI_ROM_ENABLE;
115 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, address);
116 sc->sc_flags |= STI_ROM_ENABLED;
117
118
119
120
121
122 romsize = PCI_ROM_SIZE(mask);
123 rc = bus_space_map(pa->pa_memt, PCI_ROM_ADDR(address), romsize,
124 0, &romh);
125 sti_pci_disable_rom(sc);
126 if (rc != 0) {
127 printf("%s: can't map PCI ROM (%d)\n",
128 sc->sc_dev.dv_xname, rc);
129 goto fail2;
130 }
131
132
133
134
135
136 selected = (bus_addr_t)-1;
137 for (offs = 0; offs < romsize; offs += subsize) {
138 sti_pci_enable_rom(sc);
139
140
141
142 tmp = bus_space_read_4(pa->pa_memt, romh, offs + 0);
143 tmp = letoh32(tmp);
144 if (tmp != 0x55aa0000) {
145 sti_pci_disable_rom(sc);
146 if (offs == 0) {
147 printf("%s: invalid PCI ROM header signature"
148 " (%08x)\n",
149 sc->sc_dev.dv_xname, tmp);
150 rc = EINVAL;
151 }
152 break;
153 }
154
155
156
157
158 tmp = bus_space_read_4(pa->pa_memt, romh, offs + 4);
159 tmp = letoh32(tmp);
160 if (tmp != 0x00000001) {
161 sti_pci_disable_rom(sc);
162 if (offs == 0) {
163 printf("%s: invalid PCI ROM type (%08x)\n",
164 sc->sc_dev.dv_xname, tmp);
165 rc = EINVAL;
166 }
167 break;
168 }
169
170 subsize = (bus_addr_t)bus_space_read_2(pa->pa_memt, romh,
171 offs + 0x0c);
172 subsize <<= 9;
173
174 #ifdef STIDEBUG
175 sti_pci_disable_rom(sc);
176 printf("ROM offset %08x size %08x type %08x",
177 offs, subsize, tmp);
178 sti_pci_enable_rom(sc);
179 #endif
180
181
182
183
184
185
186
187 suboffs = offs +(bus_addr_t)bus_space_read_2(pa->pa_memt, romh,
188 offs + 0x18);
189 tmp = bus_space_read_4(pa->pa_memt, romh, suboffs + 0);
190 tmp = letoh32(tmp);
191 if (tmp != 0x50434952) {
192 sti_pci_disable_rom(sc);
193 if (offs == 0) {
194 printf("%s: invalid PCI data signature"
195 " (%08x)\n",
196 sc->sc_dev.dv_xname, tmp);
197 rc = EINVAL;
198 } else {
199 #ifdef STIDEBUG
200 printf(" invalid PCI data signature %08x\n",
201 tmp);
202 #endif
203 continue;
204 }
205 }
206
207 tmp = bus_space_read_1(pa->pa_memt, romh, suboffs + 0x14);
208 sti_pci_disable_rom(sc);
209 #ifdef STIDEBUG
210 printf(" code %02x", tmp);
211 #endif
212
213 switch (tmp) {
214 #ifdef __hppa__
215 case 0x10:
216 if (selected == (bus_addr_t)-1)
217 selected = offs;
218 break;
219 #endif
220 #ifdef __i386__
221 case 0x00:
222 if (selected == (bus_addr_t)-1)
223 selected = offs;
224 break;
225 #endif
226 default:
227 #ifdef STIDEBUG
228 printf(" (wrong architecture)");
229 #endif
230 break;
231 }
232
233 #ifdef STIDEBUG
234 if (selected == offs)
235 printf(" -> SELECTED");
236 printf("\n");
237 #endif
238 }
239
240 if (selected == (bus_addr_t)-1) {
241 if (rc == 0) {
242 printf("%s: found no ROM with correct microcode"
243 " architecture\n", sc->sc_dev.dv_xname);
244 rc = ENOEXEC;
245 }
246 goto fail;
247 }
248
249
250
251
252
253 sti_pci_enable_rom(sc);
254 offs = selected +
255 (bus_addr_t)bus_space_read_2(pa->pa_memt, romh, selected + 0x0e);
256 for (i = 0; i < STI_REGION_MAX; i++) {
257 rc = sti_readbar(sc, pa, i,
258 bus_space_read_1(pa->pa_memt, romh, offs + i));
259 if (rc != 0)
260 goto fail;
261 }
262
263
264
265
266
267 offs = selected +
268 (bus_addr_t)bus_space_read_4(pa->pa_memt, romh, selected + 0x08);
269 stiromsize = (bus_addr_t)bus_space_read_4(pa->pa_memt, romh,
270 offs + 0x18);
271 stiromsize = letoh32(stiromsize);
272 sti_pci_disable_rom(sc);
273
274
275
276
277
278
279 bus_space_unmap(pa->pa_memt, romh, romsize);
280 rc = bus_space_map(pa->pa_memt, PCI_ROM_ADDR(address) + offs,
281 stiromsize, 0, &sc->romh);
282 if (rc != 0) {
283 printf("%s: can't map STI ROM (%d)\n",
284 sc->sc_dev.dv_xname, rc);
285 goto fail2;
286 }
287 sc->memt = pa->pa_memt;
288
289 return (0);
290
291 fail:
292 bus_space_unmap(pa->pa_memt, romh, romsize);
293 fail2:
294 sti_pci_disable_rom(sc);
295
296 return (rc);
297 }
298
299
300
301
302 int
303 sti_readbar(struct sti_softc *sc, struct pci_attach_args *pa, u_int region,
304 int bar)
305 {
306 bus_addr_t addr;
307 bus_size_t size;
308 u_int32_t cf;
309 int rc;
310
311 if (bar == 0) {
312 sc->bases[region] = 0;
313 return (0);
314 }
315
316 #ifdef DIAGNOSTIC
317 if (bar < PCI_MAPREG_START || bar > PCI_MAPREG_PPB_END) {
318 sti_pci_disable_rom(sc);
319 printf("%s: unexpected bar %02x for region %d\n",
320 sc->sc_dev.dv_xname, bar, region);
321 sti_pci_enable_rom(sc);
322 }
323 #endif
324
325 cf = pci_conf_read(pa->pa_pc, pa->pa_tag, bar);
326
327 if (PCI_MAPREG_TYPE(cf) == PCI_MAPREG_TYPE_IO)
328 rc = pci_io_find(pa->pa_pc, pa->pa_tag, bar, &addr, &size);
329 else
330 rc = pci_mem_find(pa->pa_pc, pa->pa_tag, bar, &addr, &size,
331 NULL);
332
333 if (rc != 0) {
334 sti_pci_disable_rom(sc);
335 printf("%s: invalid bar %02x for region %d\n",
336 sc->sc_dev.dv_xname, bar, region);
337 sti_pci_enable_rom(sc);
338 return (rc);
339 }
340
341 sc->bases[region] = addr;
342 return (0);
343 }
344
345
346
347
348 void
349 sti_pci_enable_rom(struct sti_softc *sc)
350 {
351 struct sti_pci_softc *spc = (struct sti_pci_softc *)sc;
352 pcireg_t address;
353
354 if (!ISSET(sc->sc_flags, STI_ROM_ENABLED)) {
355 address = pci_conf_read(spc->sc_pc, spc->sc_tag, PCI_ROM_REG);
356 address |= PCI_ROM_ENABLE;
357 pci_conf_write(spc->sc_pc, spc->sc_tag, PCI_ROM_REG, address);
358 SET(sc->sc_flags, STI_ROM_ENABLED);
359 }
360 }
361
362
363
364
365 void
366 sti_pci_disable_rom(struct sti_softc *sc)
367 {
368 struct sti_pci_softc *spc = (struct sti_pci_softc *)sc;
369 pcireg_t address;
370
371 if (ISSET(sc->sc_flags, STI_ROM_ENABLED)) {
372 address = pci_conf_read(spc->sc_pc, spc->sc_tag, PCI_ROM_REG);
373 address &= ~PCI_ROM_ENABLE;
374 pci_conf_write(spc->sc_pc, spc->sc_tag, PCI_ROM_REG, address);
375
376 CLR(sc->sc_flags, STI_ROM_ENABLED);
377 }
378 }