elroy.c revision 1.8 1 /* $NetBSD: elroy.c,v 1.8 2024/12/28 16:48:32 skrll Exp $ */
2
3 /* $OpenBSD: elroy.c,v 1.5 2009/03/30 21:24:57 kettenis Exp $ */
4
5 /*
6 * Copyright (c) 2005 Michael Shalayeff
7 * All rights reserved.
8 *
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
18 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 */
21
22 /* #include "cardbus.h" */
23
24 #include <sys/param.h>
25 #include <sys/systm.h>
26 #include <sys/device.h>
27 #include <sys/reboot.h>
28 #include <sys/extent.h>
29
30 #include <machine/iomod.h>
31 #include <machine/autoconf.h>
32
33 #include <hppa/dev/cpudevs.h>
34
35 #if NCARDBUS > 0
36 #include <dev/cardbus/rbus.h>
37 #endif
38
39 #include <dev/pci/pcireg.h>
40 #include <dev/pci/pcivar.h>
41 #include <dev/pci/pcidevs.h>
42
43 #include <hppa/dev/elroyreg.h>
44 #include <hppa/dev/elroyvar.h>
45
46 #define ELROY_MEM_CHUNK 0x800000
47 #define ELROY_MEM_WINDOW (2 * ELROY_MEM_CHUNK)
48
49 int elroy_match(device_t, cfdata_t, void *);
50 void elroy_attach(device_t, device_t, void *);
51
52 CFATTACH_DECL_NEW(elroy, sizeof(struct elroy_softc), elroy_match, elroy_attach,
53 NULL, NULL);
54
55 extern struct cfdriver elroy_cd;
56
57 void elroy_write32(volatile uint32_t *, uint32_t);
58 uint32_t elroy_read32(volatile uint32_t *);
59 void elroy_attach_hook(device_t, device_t, struct pcibus_attach_args *);
60 int elroy_maxdevs(void *, int);
61 pcitag_t elroy_make_tag(void *, int, int, int);
62 void elroy_decompose_tag(void *, pcitag_t, int *, int *, int *);
63 pcireg_t elroy_conf_read(void *, pcitag_t, int);
64 void elroy_conf_write(void *, pcitag_t, int, pcireg_t);
65
66 int elroy_iomap(void *, bus_addr_t, bus_size_t, int, bus_space_handle_t *);
67 int elroy_memmap(void *, bus_addr_t, bus_size_t, int, bus_space_handle_t *);
68 int elroy_subregion(void *, bus_space_handle_t, bus_size_t, bus_size_t,
69 bus_space_handle_t *);
70 int elroy_ioalloc(void *, bus_addr_t, bus_addr_t, bus_size_t, bus_size_t,
71 bus_size_t, int, bus_addr_t *, bus_space_handle_t *);
72 int elroy_memalloc(void *, bus_addr_t, bus_addr_t, bus_size_t, bus_size_t,
73 bus_size_t, int, bus_addr_t *, bus_space_handle_t *);
74 void elroy_unmap(void *, bus_space_handle_t, bus_size_t);
75 void elroy_free(void *, bus_space_handle_t, bus_size_t);
76 void elroy_barrier(void *, bus_space_handle_t, bus_size_t, bus_size_t, int);
77 void *elroy_alloc_parent(device_t, struct pci_attach_args *, int);
78 void *elroy_vaddr(void *, bus_space_handle_t);
79 paddr_t elroy_mmap(void *, bus_addr_t, off_t, int, int);
80
81 uint8_t elroy_r1(void *, bus_space_handle_t, bus_size_t);
82 uint16_t elroy_r2(void *, bus_space_handle_t, bus_size_t);
83 uint32_t elroy_r4(void *, bus_space_handle_t, bus_size_t);
84 uint64_t elroy_r8(void *, bus_space_handle_t, bus_size_t);
85 uint16_t elroy_rs2(void *, bus_space_handle_t, bus_size_t);
86 uint32_t elroy_rs4(void *, bus_space_handle_t, bus_size_t);
87 uint64_t elroy_rs8(void *, bus_space_handle_t, bus_size_t);
88 void elroy_w1(void *, bus_space_handle_t, bus_size_t, uint8_t);
89 void elroy_w2(void *, bus_space_handle_t, bus_size_t, uint16_t);
90 void elroy_w4(void *, bus_space_handle_t, bus_size_t, uint32_t);
91 void elroy_w8(void *, bus_space_handle_t, bus_size_t, uint64_t);
92 void elroy_ws2(void *, bus_space_handle_t, bus_size_t, uint16_t);
93 void elroy_ws4(void *, bus_space_handle_t, bus_size_t, uint32_t);
94 void elroy_ws8(void *, bus_space_handle_t, bus_size_t, uint64_t);
95
96 void elroy_rm_1(void *, bus_space_handle_t, bus_size_t, uint8_t *,
97 bus_size_t);
98 void elroy_rm_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
99 bus_size_t);
100 void elroy_rm_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
101 bus_size_t);
102 void elroy_rm_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
103 bus_size_t);
104 void elroy_wm_1(void *, bus_space_handle_t, bus_size_t, const uint8_t *,
105 bus_size_t);
106 void elroy_wm_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
107 bus_size_t);
108 void elroy_wm_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
109 bus_size_t);
110 void elroy_wm_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
111 bus_size_t);
112 void elroy_sm_1(void *, bus_space_handle_t, bus_size_t, uint8_t,
113 bus_size_t);
114 void elroy_sm_2(void *, bus_space_handle_t, bus_size_t, uint16_t,
115 bus_size_t);
116 void elroy_sm_4(void *, bus_space_handle_t, bus_size_t, uint32_t,
117 bus_size_t);
118 void elroy_sm_8(void *, bus_space_handle_t, bus_size_t, uint64_t,
119 bus_size_t);
120
121 void elroy_rrm_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
122 bus_size_t);
123 void elroy_rrm_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
124 bus_size_t);
125 void elroy_rrm_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
126 bus_size_t);
127 void elroy_wrm_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
128 bus_size_t);
129 void elroy_wrm_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
130 bus_size_t);
131 void elroy_wrm_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
132 bus_size_t);
133 void elroy_rr_1(void *, bus_space_handle_t, bus_size_t, uint8_t *,
134 bus_size_t);
135 void elroy_rr_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
136 bus_size_t);
137 void elroy_rr_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
138 bus_size_t);
139 void elroy_rr_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
140 bus_size_t);
141 void elroy_wr_1(void *, bus_space_handle_t, bus_size_t, const uint8_t *,
142 bus_size_t);
143 void elroy_wr_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
144 bus_size_t);
145 void elroy_wr_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
146 bus_size_t);
147 void elroy_wr_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
148 bus_size_t);
149
150 void elroy_rrr_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
151 bus_size_t);
152 void elroy_rrr_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
153 bus_size_t);
154 void elroy_rrr_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
155 bus_size_t);
156 void elroy_wrr_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
157 bus_size_t);
158 void elroy_wrr_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
159 bus_size_t);
160 void elroy_wrr_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
161 bus_size_t);
162 void elroy_sr_1(void *, bus_space_handle_t, bus_size_t, uint8_t,
163 bus_size_t);
164 void elroy_sr_2(void *, bus_space_handle_t, bus_size_t, uint16_t,
165 bus_size_t);
166 void elroy_sr_4(void *, bus_space_handle_t, bus_size_t, uint32_t,
167 bus_size_t);
168 void elroy_sr_8(void *, bus_space_handle_t, bus_size_t, uint64_t,
169 bus_size_t);
170 void elroy_cp_1(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
171 bus_size_t, bus_size_t);
172 void elroy_cp_2(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
173 bus_size_t, bus_size_t);
174 void elroy_cp_4(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
175 bus_size_t, bus_size_t);
176 void elroy_cp_8(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
177 bus_size_t, bus_size_t);
178
179 int elroy_dmamap_create(void *, bus_size_t, int, bus_size_t, bus_size_t,
180 int, bus_dmamap_t *);
181 void elroy_dmamap_destroy(void *, bus_dmamap_t);
182 int elroy_dmamap_load(void *, bus_dmamap_t, void *, bus_size_t,
183 struct proc *, int);
184 int elroy_dmamap_load_mbuf(void *, bus_dmamap_t, struct mbuf *, int);
185 int elroy_dmamap_load_uio(void *, bus_dmamap_t, struct uio *, int);
186 int elroy_dmamap_load_raw(void *, bus_dmamap_t, bus_dma_segment_t *,
187 int, bus_size_t, int);
188 void elroy_dmamap_unload(void *, bus_dmamap_t);
189 void elroy_dmamap_sync(void *, bus_dmamap_t, bus_addr_t, bus_size_t,
190 int);
191 int elroy_dmamem_alloc(void *, bus_size_t, bus_size_t, bus_size_t,
192 bus_dma_segment_t *, int, int *, int);
193 void elroy_dmamem_free(void *, bus_dma_segment_t *, int);
194 int elroy_dmamem_map(void *, bus_dma_segment_t *, int, size_t,
195 void **, int);
196 void elroy_dmamem_unmap(void *, void *, size_t);
197 paddr_t elroy_dmamem_mmap(void *, bus_dma_segment_t *, int, off_t,
198 int, int);
199
200 int
201 elroy_match(device_t parent, cfdata_t cf, void *aux)
202 {
203 struct confargs *ca = aux;
204
205 if ((ca->ca_name && !strcmp(ca->ca_name, "lba")) ||
206 (ca->ca_type.iodc_type == HPPA_TYPE_BRIDGE &&
207 ca->ca_type.iodc_sv_model == HPPA_BRIDGE_DINO &&
208 ca->ca_type.iodc_model == 0x78))
209 return (1);
210
211 return (0);
212 }
213
214 void
215 elroy_write32(volatile uint32_t *p, uint32_t v)
216 {
217 *p = v;
218 }
219
220 uint32_t
221 elroy_read32(volatile uint32_t *p)
222 {
223 return *p;
224 }
225
226 void
227 elroy_attach_hook(device_t parent, device_t self,
228 struct pcibus_attach_args *pba)
229 {
230
231 }
232
233 int
234 elroy_maxdevs(void *v, int bus)
235 {
236 return (32);
237 }
238
239 pcitag_t
240 elroy_make_tag(void *v, int bus, int dev, int func)
241 {
242 if (bus > 255 || dev > 31 || func > 7)
243 panic("elroy_make_tag: bad request");
244
245 return ((bus << 16) | (dev << 11) | (func << 8));
246 }
247
248 void
249 elroy_decompose_tag(void *v, pcitag_t tag, int *bus, int *dev, int *func)
250 {
251 *bus = (tag >> 16) & 0xff;
252 *dev = (tag >> 11) & 0x1f;
253 *func= (tag >> 8) & 0x07;
254 }
255
256 pcireg_t
257 elroy_conf_read(void *v, pcitag_t tag, int reg)
258 {
259 struct elroy_softc *sc = v;
260 volatile struct elroy_regs *r = sc->sc_regs;
261 uint32_t arb_mask, err_cfg, control;
262 pcireg_t data;
263
264 /* printf("elroy_conf_read(%p, 0x%08x, 0x%x)", v, tag, reg); */
265
266 if ((unsigned int)reg >= PCI_CONF_SIZE)
267 return ((pcireg_t) -1);
268
269 arb_mask = elroy_read32(&r->arb_mask);
270 err_cfg = elroy_read32(&r->err_cfg);
271 control = elroy_read32(&r->control);
272 if (!arb_mask)
273 elroy_write32(&r->arb_mask, htole32(ELROY_ARB_ENABLE));
274 elroy_write32(&r->err_cfg, err_cfg |
275 htole32(ELROY_ERRCFG_SMART | ELROY_ERRCFG_CM));
276 elroy_write32(&r->control, (control | htole32(ELROY_CONTROL_CE)) &
277 ~htole32(ELROY_CONTROL_HF));
278
279 elroy_write32(&r->pci_conf_addr, htole32(tag | reg));
280 (void)elroy_read32(&r->pci_conf_addr);
281 data = elroy_read32(&r->pci_conf_data);
282
283 elroy_write32(&r->control, control |
284 htole32(ELROY_CONTROL_CE|ELROY_CONTROL_CL));
285 elroy_write32(&r->control, control);
286 elroy_write32(&r->err_cfg, err_cfg);
287 if (!arb_mask)
288 elroy_write32(&r->arb_mask, arb_mask);
289
290 data = le32toh(data);
291 /* printf("=0x%08x (@ 0x%08x)\n", data, le32toh(data1)); */
292 return (data);
293 }
294
295 void
296 elroy_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
297 {
298 struct elroy_softc *sc = v;
299 volatile struct elroy_regs *r = sc->sc_regs;
300 uint32_t arb_mask, err_cfg, control;
301
302 /* printf("elroy_conf_write(%p, 0x%08x, 0x%x, 0x%x)\n", v, tag, reg, data); */
303
304 if ((unsigned int)reg >= PCI_CONF_SIZE)
305 return;
306
307 arb_mask = elroy_read32(&r->arb_mask);
308 err_cfg = elroy_read32(&r->err_cfg);
309 control = elroy_read32(&r->control);
310 if (!arb_mask)
311 elroy_write32(&r->arb_mask, htole32(ELROY_ARB_ENABLE));
312 elroy_write32(&r->err_cfg, err_cfg |
313 htole32(ELROY_ERRCFG_SMART | ELROY_ERRCFG_CM));
314 elroy_write32(&r->control, (control | htole32(ELROY_CONTROL_CE)) &
315 ~htole32(ELROY_CONTROL_HF));
316
317 /* fix coalescing config writes errata by interleaving w/ a read */
318 elroy_write32(&r->pci_conf_addr, htole32(tag | PCI_ID_REG));
319 (void)elroy_read32(&r->pci_conf_addr);
320 (void)elroy_read32(&r->pci_conf_data);
321
322 elroy_write32(&r->pci_conf_addr, htole32(tag | reg));
323 (void)elroy_read32(&r->pci_conf_addr);
324 elroy_write32(&r->pci_conf_data, htole32(data));
325 (void)elroy_read32(&r->pci_conf_addr);
326
327 elroy_write32(&r->control, control |
328 htole32(ELROY_CONTROL_CE|ELROY_CONTROL_CL));
329 elroy_write32(&r->control, control);
330 elroy_write32(&r->err_cfg, err_cfg);
331 if (!arb_mask)
332 elroy_write32(&r->arb_mask, arb_mask);
333 }
334
335 int
336 elroy_iomap(void *v, bus_addr_t bpa, bus_size_t size,
337 int flags, bus_space_handle_t *bshp)
338 {
339 struct elroy_softc *sc = v;
340 /* volatile struct elroy_regs *r = sc->sc_regs; */
341 int error;
342
343 if ((error = bus_space_map(sc->sc_bt, bpa + sc->sc_iobase, size,
344 flags, bshp)))
345 return (error);
346
347 return (0);
348 }
349
350 int
351 elroy_memmap(void *v, bus_addr_t bpa, bus_size_t size,
352 int flags, bus_space_handle_t *bshp)
353 {
354 struct elroy_softc *sc = v;
355 /* volatile struct elroy_regs *r = sc->sc_regs; */
356 int error;
357
358 if ((error = bus_space_map(sc->sc_bt, bpa, size, flags, bshp)))
359 return (error);
360
361 return (0);
362 }
363
364 int
365 elroy_subregion(void *v, bus_space_handle_t bsh, bus_size_t offset,
366 bus_size_t size, bus_space_handle_t *nbshp)
367 {
368 *nbshp = bsh + offset;
369 return (0);
370 }
371
372 int
373 elroy_ioalloc(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size,
374 bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp,
375 bus_space_handle_t *bshp)
376 {
377 struct elroy_softc *sc = v;
378 volatile struct elroy_regs *r = sc->sc_regs;
379 bus_addr_t iostart, ioend;
380
381 iostart = r->io_base & ~htole32(ELROY_BASE_RE);
382 ioend = iostart + ~htole32(r->io_mask) + 1;
383 if (rstart < iostart || rend > ioend)
384 panic("elroy_ioalloc: bad region start/end");
385
386 rstart += sc->sc_iobase;
387 rend += sc->sc_iobase;
388 if (bus_space_alloc(sc->sc_bt, rstart, rend, size,
389 align, boundary, flags, addrp, bshp))
390 return (ENOMEM);
391
392 return (0);
393 }
394
395 int
396 elroy_memalloc(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size,
397 bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp,
398 bus_space_handle_t *bshp)
399 {
400 struct elroy_softc *sc = v;
401 /* volatile struct elroy_regs *r = sc->sc_regs; */
402
403 if (bus_space_alloc(sc->sc_bt, rstart, rend, size,
404 align, boundary, flags, addrp, bshp))
405 return (ENOMEM);
406
407 return (0);
408 }
409
410 void
411 elroy_unmap(void *v, bus_space_handle_t bsh, bus_size_t size)
412 {
413 struct elroy_softc *sc = v;
414
415 bus_space_free(sc->sc_bt, bsh, size);
416 }
417
418 void
419 elroy_free(void *v, bus_space_handle_t bh, bus_size_t size)
420 {
421 /* should be enough */
422 elroy_unmap(v, bh, size);
423 }
424
425 void
426 elroy_barrier(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int op)
427 {
428 struct elroy_softc *sc = v;
429 volatile struct elroy_regs *r = sc->sc_regs;
430
431 sync_caches();
432 if (op & BUS_SPACE_BARRIER_WRITE) {
433 (void)r->pci_id; /* flush write fifo */
434 sync_caches();
435 }
436 }
437
438 #if NCARDBUS > 0
439 void *
440 elroy_alloc_parent(device_t self, struct pci_attach_args *pa, int io)
441 {
442 #if 0 /* TODO */
443
444 struct elroy_softc *sc = pa->pa_pc->_cookie;
445 struct extent *ex;
446 bus_space_tag_t tag;
447 bus_addr_t start;
448 bus_size_t size;
449
450 if (io) {
451 ex = sc->sc_ioex;
452 tag = pa->pa_iot;
453 start = 0xa000;
454 size = 0x1000;
455 } else {
456 if (!sc->sc_memex) {
457 bus_space_handle_t memh;
458 bus_addr_t mem_start;
459
460 if (elroy_memalloc(sc, 0xf0800000, 0xff7fffff,
461 ELROY_MEM_WINDOW, ELROY_MEM_WINDOW, EX_NOBOUNDARY,
462 0, &mem_start, &memh))
463 return (NULL);
464
465 snprintf(sc->sc_memexname, sizeof(sc->sc_memexname),
466 "%s_mem", device_xname(sc->sc_dv));
467 if ((sc->sc_memex = extent_create(sc->sc_memexname,
468 mem_start, mem_start + ELROY_MEM_WINDOW,
469 NULL, 0, EX_NOWAIT | EX_MALLOCOK)) == NULL) {
470 extent_destroy(sc->sc_ioex);
471 bus_space_free(sc->sc_bt, memh,
472 ELROY_MEM_WINDOW);
473 return (NULL);
474 }
475 }
476 ex = sc->sc_memex;
477 tag = pa->pa_memt;
478 start = ex->ex_start;
479 size = ELROY_MEM_CHUNK;
480 }
481
482 if (extent_alloc_subregion(ex, start, ex->ex_end, size, size, 0,
483 EX_NOBOUNDARY, EX_NOWAIT, &start))
484 return (NULL);
485
486 extent_free(ex, start, size, EX_NOWAIT);
487 return rbus_new_root_share(tag, ex, start, size, 0);
488 #else
489 return (NULL);
490 #endif
491 }
492 #endif
493
494 void *
495 elroy_vaddr(void *v, bus_space_handle_t h)
496 {
497 return ((void *)h);
498 }
499
500 paddr_t
501 elroy_mmap(void *v, bus_addr_t addr, off_t off, int prot, int flags)
502 {
503 return btop(addr + off);
504 }
505
506 uint8_t
507 elroy_r1(void *v, bus_space_handle_t h, bus_size_t o)
508 {
509 h += o;
510 return *(volatile uint8_t *)h;
511 }
512
513 uint16_t
514 elroy_r2(void *v, bus_space_handle_t h, bus_size_t o)
515 {
516 volatile uint16_t *p;
517
518 h += o;
519 p = (volatile uint16_t *)h;
520 return (le16toh(*p));
521 }
522
523 uint32_t
524 elroy_r4(void *v, bus_space_handle_t h, bus_size_t o)
525 {
526 uint32_t data;
527
528 h += o;
529 data = *(volatile uint32_t *)h;
530 return (le32toh(data));
531 }
532
533 uint64_t
534 elroy_r8(void *v, bus_space_handle_t h, bus_size_t o)
535 {
536 uint64_t data;
537
538 h += o;
539 data = *(volatile uint64_t *)h;
540 return (le64toh(data));
541 }
542
543 uint16_t
544 elroy_rs2(void *v, bus_space_handle_t h, bus_size_t o)
545 {
546 volatile uint16_t *p;
547
548 h += o;
549 p = (volatile uint16_t *)h;
550 return (*p);
551 }
552
553 uint32_t
554 elroy_rs4(void *v, bus_space_handle_t h, bus_size_t o)
555 {
556 uint32_t data;
557
558 h += o;
559 data = *(volatile uint32_t *)h;
560 return data;
561 }
562
563 uint64_t
564 elroy_rs8(void *v, bus_space_handle_t h, bus_size_t o)
565 {
566 uint64_t data;
567
568 h += o;
569 data = *(volatile uint64_t *)h;
570 return data;
571 }
572
573 void
574 elroy_w1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t vv)
575 {
576 h += o;
577 *(volatile uint8_t *)h = vv;
578 }
579
580 void
581 elroy_w2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t vv)
582 {
583 volatile uint16_t *p;
584
585 h += o;
586 p = (volatile uint16_t *)h;
587 *p = htole16(vv);
588 }
589
590 void
591 elroy_w4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t vv)
592 {
593 h += o;
594 vv = htole32(vv);
595 *(volatile uint32_t *)h = vv;
596 }
597
598 void
599 elroy_w8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t vv)
600 {
601 h += o;
602 *(volatile uint64_t *)h = htole64(vv);
603 }
604
605 void
606 elroy_ws2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t vv)
607 {
608 volatile uint16_t *p;
609
610 h += o;
611 p = (volatile uint16_t *)h;
612 *p = vv;
613 }
614
615 void
616 elroy_ws4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t vv)
617 {
618 h += o;
619 *(volatile uint32_t *)h = vv;
620 }
621
622 void
623 elroy_ws8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t vv)
624 {
625 h += o;
626 *(volatile uint64_t *)h = vv;
627 }
628
629 void
630 elroy_rm_1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t *a, bus_size_t c)
631 {
632 volatile uint8_t *p;
633
634 h += o;
635 p = (volatile uint8_t *)h;
636 while (c--)
637 *a++ = *p;
638 }
639
640 void
641 elroy_rm_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t *a, bus_size_t c)
642 {
643 volatile uint16_t *p;
644
645 h += o;
646 p = (volatile uint16_t *)h;
647 while (c--)
648 *a++ = le16toh(*p);
649 }
650
651 void
652 elroy_rm_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t *a, bus_size_t c)
653 {
654 volatile uint32_t *p;
655
656 h += o;
657 p = (volatile uint32_t *)h;
658 while (c--)
659 *a++ = le32toh(*p);
660 }
661
662 void
663 elroy_rm_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t *a, bus_size_t c)
664 {
665 volatile uint64_t *p;
666
667 h += o;
668 p = (volatile uint64_t *)h;
669 while (c--)
670 *a++ = le64toh(*p);
671 }
672
673 void
674 elroy_wm_1(void *v, bus_space_handle_t h, bus_size_t o, const uint8_t *a, bus_size_t c)
675 {
676 volatile uint8_t *p;
677
678 h += o;
679 p = (volatile uint8_t *)h;
680 while (c--)
681 *p = *a++;
682 }
683
684 void
685 elroy_wm_2(void *v, bus_space_handle_t h, bus_size_t o, const uint16_t *a, bus_size_t c)
686 {
687 volatile uint16_t *p;
688
689 h += o;
690 p = (volatile uint16_t *)h;
691 while (c--)
692 *p = htole16(*a++);
693 }
694
695 void
696 elroy_wm_4(void *v, bus_space_handle_t h, bus_size_t o, const uint32_t *a, bus_size_t c)
697 {
698 volatile uint32_t *p;
699
700 h += o;
701 p = (volatile uint32_t *)h;
702 while (c--)
703 *p = htole32(*a++);
704 }
705
706 void
707 elroy_wm_8(void *v, bus_space_handle_t h, bus_size_t o, const uint64_t *a, bus_size_t c)
708 {
709 volatile uint64_t *p;
710
711 h += o;
712 p = (volatile uint64_t *)h;
713 while (c--)
714 *p = htole64(*a++);
715 }
716
717 void
718 elroy_sm_1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t vv, bus_size_t c)
719 {
720 volatile uint8_t *p;
721
722 h += o;
723 p = (volatile uint8_t *)h;
724 while (c--)
725 *p = vv;
726 }
727
728 void
729 elroy_sm_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t vv, bus_size_t c)
730 {
731 volatile uint16_t *p;
732
733 h += o;
734 p = (volatile uint16_t *)h;
735 vv = htole16(vv);
736 while (c--)
737 *p = vv;
738 }
739
740 void
741 elroy_sm_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t vv, bus_size_t c)
742 {
743 volatile uint32_t *p;
744
745 h += o;
746 p = (volatile uint32_t *)h;
747 vv = htole32(vv);
748 while (c--)
749 *p = vv;
750 }
751
752 void
753 elroy_sm_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t vv, bus_size_t c)
754 {
755 volatile uint64_t *p;
756
757 h += o;
758 p = (volatile uint64_t *)h;
759 vv = htole64(vv);
760 while (c--)
761 *p = vv;
762 }
763
764 void
765 elroy_rrm_2(void *v, bus_space_handle_t h, bus_size_t o,
766 uint16_t *a, bus_size_t c)
767 {
768 volatile uint16_t *p, *q = a;
769
770 h += o;
771 p = (volatile uint16_t *)h;
772 while (c--)
773 *q++ = *p;
774 }
775
776 void
777 elroy_rrm_4(void *v, bus_space_handle_t h, bus_size_t o,
778 uint32_t *a, bus_size_t c)
779 {
780 volatile uint32_t *p, *q = a;
781
782 h += o;
783 p = (volatile uint32_t *)h;
784 while (c--)
785 *q++ = *p;
786 }
787
788 void
789 elroy_rrm_8(void *v, bus_space_handle_t h, bus_size_t o,
790 uint64_t *a, bus_size_t c)
791 {
792 volatile uint64_t *p, *q = a;
793
794 h += o;
795 p = (volatile uint64_t *)h;
796 while (c--)
797 *q++ = *p;
798 }
799
800 void
801 elroy_wrm_2(void *v, bus_space_handle_t h, bus_size_t o,
802 const uint16_t *a, bus_size_t c)
803 {
804 volatile uint16_t *p;
805 const uint16_t *q = a;
806
807 h += o;
808 p = (volatile uint16_t *)h;
809 while (c--)
810 *p = *q++;
811 }
812
813 void
814 elroy_wrm_4(void *v, bus_space_handle_t h, bus_size_t o,
815 const uint32_t *a, bus_size_t c)
816 {
817 volatile uint32_t *p;
818 const uint32_t *q = a;
819
820 h += o;
821 p = (volatile uint32_t *)h;
822 while (c--)
823 *p = *q++;
824 }
825
826 void
827 elroy_wrm_8(void *v, bus_space_handle_t h, bus_size_t o,
828 const uint64_t *a, bus_size_t c)
829 {
830 volatile uint64_t *p;
831 const uint64_t *q = a;
832
833 h += o;
834 p = (volatile uint64_t *)h;
835 while (c--)
836 *p = *q++;
837 }
838
839 void
840 elroy_rr_1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t *a, bus_size_t c)
841 {
842 volatile uint8_t *p;
843
844 h += o;
845 p = (volatile uint8_t *)h;
846 while (c--)
847 *a++ = *p++;
848 }
849
850 void
851 elroy_rr_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t *a, bus_size_t c)
852 {
853 volatile uint16_t *p, data;
854
855 h += o;
856 p = (volatile uint16_t *)h;
857 while (c--) {
858 data = *p++;
859 *a++ = le16toh(data);
860 }
861 }
862
863 void
864 elroy_rr_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t *a, bus_size_t c)
865 {
866 volatile uint32_t *p, data;
867
868 h += o;
869 p = (volatile uint32_t *)h;
870 while (c--) {
871 data = *p++;
872 *a++ = le32toh(data);
873 }
874 }
875
876 void
877 elroy_rr_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t *a, bus_size_t c)
878 {
879 volatile uint64_t *p, data;
880
881 h += o;
882 p = (volatile uint64_t *)h;
883 while (c--) {
884 data = *p++;
885 *a++ = le64toh(data);
886 }
887 }
888
889 void
890 elroy_wr_1(void *v, bus_space_handle_t h, bus_size_t o, const uint8_t *a, bus_size_t c)
891 {
892 volatile uint8_t *p;
893
894 h += o;
895 p = (volatile uint8_t *)h;
896 while (c--)
897 *p++ = *a++;
898 }
899
900 void
901 elroy_wr_2(void *v, bus_space_handle_t h, bus_size_t o, const uint16_t *a, bus_size_t c)
902 {
903 volatile uint16_t *p, data;
904
905 h += o;
906 p = (volatile uint16_t *)h;
907 while (c--) {
908 data = *a++;
909 *p++ = htole16(data);
910 }
911 }
912
913 void
914 elroy_wr_4(void *v, bus_space_handle_t h, bus_size_t o, const uint32_t *a, bus_size_t c)
915 {
916 volatile uint32_t *p, data;
917
918 h += o;
919 p = (volatile uint32_t *)h;
920 while (c--) {
921 data = *a++;
922 *p++ = htole32(data);
923 }
924 }
925
926 void
927 elroy_wr_8(void *v, bus_space_handle_t h, bus_size_t o, const uint64_t *a, bus_size_t c)
928 {
929 volatile uint64_t *p, data;
930
931 h += o;
932 p = (volatile uint64_t *)h;
933 while (c--) {
934 data = *a++;
935 *p++ = htole64(data);
936 }
937 }
938
939 void
940 elroy_rrr_2(void *v, bus_space_handle_t h, bus_size_t o,
941 uint16_t *a, bus_size_t c)
942 {
943 volatile uint16_t *p, *q = a;
944
945 h += o;
946 p = (volatile uint16_t *)h;
947 while (c--)
948 *q++ = *p++;
949 }
950
951 void
952 elroy_rrr_4(void *v, bus_space_handle_t h, bus_size_t o,
953 uint32_t *a, bus_size_t c)
954 {
955 volatile uint32_t *p, *q = a;
956
957 h += o;
958 p = (volatile uint32_t *)h;
959 while (c--)
960 *q++ = *p++;
961 }
962
963 void
964 elroy_rrr_8(void *v, bus_space_handle_t h, bus_size_t o,
965 uint64_t *a, bus_size_t c)
966 {
967 volatile uint64_t *p, *q = a;
968
969 h += o;
970 p = (volatile uint64_t *)h;
971 while (c--)
972 *q++ = *p++;
973 }
974
975 void
976 elroy_wrr_2(void *v, bus_space_handle_t h, bus_size_t o,
977 const uint16_t *a, bus_size_t c)
978 {
979 volatile uint16_t *p;
980 const uint16_t *q = a;
981
982 h += o;
983 p = (volatile uint16_t *)h;
984 while (c--)
985 *p++ = *q++;
986 }
987
988 void
989 elroy_wrr_4(void *v, bus_space_handle_t h, bus_size_t o,
990 const uint32_t *a, bus_size_t c)
991 {
992 volatile uint32_t *p;
993 const uint32_t *q = a;
994
995 h += o;
996 p = (volatile uint32_t *)h;
997 while (c--)
998 *p++ = *q++;
999 }
1000
1001 void
1002 elroy_wrr_8(void *v, bus_space_handle_t h, bus_size_t o,
1003 const uint64_t *a, bus_size_t c)
1004 {
1005 volatile uint64_t *p;
1006 const uint64_t *q = a;
1007
1008 h += o;
1009 p = (volatile uint64_t *)h;
1010 while (c--)
1011 *p++ = *q++;
1012 }
1013
1014 void
1015 elroy_sr_1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t vv, bus_size_t c)
1016 {
1017 volatile uint8_t *p;
1018
1019 h += o;
1020 p = (volatile uint8_t *)h;
1021 while (c--)
1022 *p++ = vv;
1023 }
1024
1025 void
1026 elroy_sr_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t vv, bus_size_t c)
1027 {
1028 volatile uint16_t *p;
1029
1030 h += o;
1031 vv = htole16(vv);
1032 p = (volatile uint16_t *)h;
1033 while (c--)
1034 *p++ = vv;
1035 }
1036
1037 void
1038 elroy_sr_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t vv, bus_size_t c)
1039 {
1040 volatile uint32_t *p;
1041
1042 h += o;
1043 vv = htole32(vv);
1044 p = (volatile uint32_t *)h;
1045 while (c--)
1046 *p++ = vv;
1047 }
1048
1049 void
1050 elroy_sr_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t vv, bus_size_t c)
1051 {
1052 volatile uint64_t *p;
1053
1054 h += o;
1055 vv = htole64(vv);
1056 p = (volatile uint64_t *)h;
1057 while (c--)
1058 *p++ = vv;
1059 }
1060
1061 void
1062 elroy_cp_1(void *v, bus_space_handle_t h1, bus_size_t o1,
1063 bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1064 {
1065 while (c--)
1066 elroy_w1(v, h1, o1++, elroy_r1(v, h2, o2++));
1067 }
1068
1069 void
1070 elroy_cp_2(void *v, bus_space_handle_t h1, bus_size_t o1,
1071 bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1072 {
1073 while (c--) {
1074 elroy_w2(v, h1, o1, elroy_r2(v, h2, o2));
1075 o1 += 2;
1076 o2 += 2;
1077 }
1078 }
1079
1080 void
1081 elroy_cp_4(void *v, bus_space_handle_t h1, bus_size_t o1,
1082 bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1083 {
1084 while (c--) {
1085 elroy_w4(v, h1, o1, elroy_r4(v, h2, o2));
1086 o1 += 4;
1087 o2 += 4;
1088 }
1089 }
1090
1091 void
1092 elroy_cp_8(void *v, bus_space_handle_t h1, bus_size_t o1,
1093 bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1094 {
1095 while (c--) {
1096 elroy_w8(v, h1, o1, elroy_r8(v, h2, o2));
1097 o1 += 8;
1098 o2 += 8;
1099 }
1100 }
1101
1102 const struct hppa_bus_space_tag elroy_iomemt = {
1103 NULL,
1104
1105 NULL, elroy_unmap, elroy_subregion, NULL, elroy_free,
1106 elroy_barrier, elroy_vaddr, elroy_mmap,
1107 elroy_r1, elroy_r2, elroy_r4, elroy_r8,
1108 elroy_rs2, elroy_rs4, elroy_rs8,
1109 elroy_w1, elroy_w2, elroy_w4, elroy_w8,
1110 elroy_ws2, elroy_ws4, elroy_ws8,
1111 elroy_rm_1, elroy_rm_2, elroy_rm_4, elroy_rm_8,
1112 elroy_wm_1, elroy_wm_2, elroy_wm_4, elroy_wm_8,
1113 elroy_sm_1, elroy_sm_2, elroy_sm_4, elroy_sm_8,
1114 elroy_rrm_2, elroy_rrm_4, elroy_rrm_8,
1115 elroy_wrm_2, elroy_wrm_4, elroy_wrm_8,
1116 elroy_rr_1, elroy_rr_2, elroy_rr_4, elroy_rr_8,
1117 elroy_wr_1, elroy_wr_2, elroy_wr_4, elroy_wr_8,
1118 elroy_rrr_2, elroy_rrr_4, elroy_rrr_8,
1119 elroy_wrr_2, elroy_wrr_4, elroy_wrr_8,
1120 elroy_sr_1, elroy_sr_2, elroy_sr_4, elroy_sr_8,
1121 elroy_cp_1, elroy_cp_2, elroy_cp_4, elroy_cp_8
1122 };
1123
1124 int
1125 elroy_dmamap_create(void *v, bus_size_t size, int nsegments,
1126 bus_size_t maxsegsz, bus_size_t boundary, int flags, bus_dmamap_t *dmamp)
1127 {
1128 struct elroy_softc *sc = v;
1129
1130 /* TODO check the addresses, boundary, enable dma */
1131
1132 return (bus_dmamap_create(sc->sc_dmat, size, nsegments,
1133 maxsegsz, boundary, flags, dmamp));
1134 }
1135
1136 void
1137 elroy_dmamap_destroy(void *v, bus_dmamap_t map)
1138 {
1139 struct elroy_softc *sc = v;
1140
1141 bus_dmamap_destroy(sc->sc_dmat, map);
1142 }
1143
1144 int
1145 elroy_dmamap_load(void *v, bus_dmamap_t map, void *addr, bus_size_t size,
1146 struct proc *p, int flags)
1147 {
1148 struct elroy_softc *sc = v;
1149
1150 return (bus_dmamap_load(sc->sc_dmat, map, addr, size, p, flags));
1151 }
1152
1153 int
1154 elroy_dmamap_load_mbuf(void *v, bus_dmamap_t map, struct mbuf *m, int flags)
1155 {
1156 struct elroy_softc *sc = v;
1157
1158 return (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, flags));
1159 }
1160
1161 int
1162 elroy_dmamap_load_uio(void *v, bus_dmamap_t map, struct uio *uio, int flags)
1163 {
1164 struct elroy_softc *sc = v;
1165
1166 return (bus_dmamap_load_uio(sc->sc_dmat, map, uio, flags));
1167 }
1168
1169 int
1170 elroy_dmamap_load_raw(void *v, bus_dmamap_t map, bus_dma_segment_t *segs,
1171 int nsegs, bus_size_t size, int flags)
1172 {
1173 struct elroy_softc *sc = v;
1174
1175 return (bus_dmamap_load_raw(sc->sc_dmat, map, segs, nsegs, size, flags));
1176 }
1177
1178 void
1179 elroy_dmamap_unload(void *v, bus_dmamap_t map)
1180 {
1181 struct elroy_softc *sc = v;
1182
1183 bus_dmamap_unload(sc->sc_dmat, map);
1184 }
1185
1186 void
1187 elroy_dmamap_sync(void *v, bus_dmamap_t map, bus_addr_t off,
1188 bus_size_t len, int ops)
1189 {
1190 struct elroy_softc *sc = v;
1191
1192 bus_dmamap_sync(sc->sc_dmat, map, off, len, ops);
1193 }
1194
1195 int
1196 elroy_dmamem_alloc(void *v, bus_size_t size, bus_size_t alignment,
1197 bus_size_t boundary, bus_dma_segment_t *segs,
1198 int nsegs, int *rsegs, int flags)
1199 {
1200 struct elroy_softc *sc = v;
1201
1202 return (bus_dmamem_alloc(sc->sc_dmat, size, alignment, boundary,
1203 segs, nsegs, rsegs, flags));
1204 }
1205
1206 void
1207 elroy_dmamem_free(void *v, bus_dma_segment_t *segs, int nsegs)
1208 {
1209 struct elroy_softc *sc = v;
1210
1211 bus_dmamem_free(sc->sc_dmat, segs, nsegs);
1212 }
1213
1214 int
1215 elroy_dmamem_map(void *v, bus_dma_segment_t *segs, int nsegs, size_t size,
1216 void **kvap, int flags)
1217 {
1218 struct elroy_softc *sc = v;
1219
1220 return (bus_dmamem_map(sc->sc_dmat, segs, nsegs, size, kvap, flags));
1221 }
1222
1223 void
1224 elroy_dmamem_unmap(void *v, void *kva, size_t size)
1225 {
1226 struct elroy_softc *sc = v;
1227
1228 bus_dmamem_unmap(sc->sc_dmat, kva, size);
1229 }
1230
1231 paddr_t
1232 elroy_dmamem_mmap(void *v, bus_dma_segment_t *segs, int nsegs, off_t off,
1233 int prot, int flags)
1234 {
1235 struct elroy_softc *sc = v;
1236
1237 return (bus_dmamem_mmap(sc->sc_dmat, segs, nsegs, off, prot, flags));
1238 }
1239
1240 const struct hppa_bus_dma_tag elroy_dmat = {
1241 NULL,
1242 elroy_dmamap_create, elroy_dmamap_destroy,
1243 elroy_dmamap_load, elroy_dmamap_load_mbuf,
1244 elroy_dmamap_load_uio, elroy_dmamap_load_raw,
1245 elroy_dmamap_unload, elroy_dmamap_sync,
1246
1247 elroy_dmamem_alloc, elroy_dmamem_free, elroy_dmamem_map,
1248 elroy_dmamem_unmap, elroy_dmamem_mmap
1249 };
1250
1251 const struct hppa_pci_chipset_tag elroy_pc = {
1252 .pc_attach_hook = elroy_attach_hook,
1253 .pc_bus_maxdevs = elroy_maxdevs,
1254 .pc_make_tag = elroy_make_tag,
1255 .pc_decompose_tag = elroy_decompose_tag,
1256 .pc_conf_read = elroy_conf_read,
1257 .pc_conf_write = elroy_conf_write,
1258 .pc_intr_map = apic_intr_map,
1259 .pc_intr_string = apic_intr_string,
1260 .pc_intr_establish = apic_intr_establish,
1261 .pc_intr_disestablish = apic_intr_disestablish,
1262 #if NCARDBUS > 0
1263 .pc_alloc_parent = elroy_alloc_parent
1264 #endif
1265 };
1266
1267 void
1268 elroy_attach(device_t parent, device_t self, void *aux)
1269 {
1270 struct elroy_softc *sc = device_private(self);
1271 struct confargs *ca = (struct confargs *)aux;
1272 struct pcibus_attach_args pba;
1273 volatile struct elroy_regs *r;
1274 const char *p = NULL, *q;
1275 int i;
1276
1277 sc->sc_dv = self;
1278 sc->sc_hpa = ca->ca_hpa;
1279 sc->sc_bt = ca->ca_iot;
1280 sc->sc_dmat = ca->ca_dmatag;
1281 if (bus_space_map(sc->sc_bt, ca->ca_hpa, ca->ca_hpasz, 0, &sc->sc_bh)) {
1282 aprint_error(": can't map space\n");
1283 return;
1284 }
1285
1286 sc->sc_regs = r = bus_space_vaddr(sc->sc_bt, sc->sc_bh);
1287 elroy_write32(&r->pci_cmdstat, htole32(PCI_COMMAND_IO_ENABLE |
1288 PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE));
1289
1290 elroy_write32(&r->control, elroy_read32(&r->control) &
1291 ~htole32(ELROY_CONTROL_RF));
1292 for (i = 5000; i-- &&
1293 elroy_read32(&r->status) & htole32(ELROY_STATUS_RC); DELAY(10));
1294 if (i < 0) {
1295 char buf[128]; /* XXXNH */
1296
1297 snprintb(buf, sizeof(buf), ELROY_STATUS_BITS,
1298 htole32(r->status));
1299 aprint_error(": reset failed; status %s\n", buf);
1300 return;
1301 }
1302
1303 q = "";
1304 sc->sc_ver = PCI_REVISION(le32toh(elroy_read32(&r->pci_class)));
1305 switch ((ca->ca_type.iodc_model << 4) |
1306 (ca->ca_type.iodc_revision >> 4)) {
1307 case 0x782:
1308 p = "Elroy";
1309 switch (sc->sc_ver) {
1310 default:
1311 q = "+";
1312 case 5: sc->sc_ver = 0x40; break;
1313 case 4: sc->sc_ver = 0x30; break;
1314 case 3: sc->sc_ver = 0x22; break;
1315 case 2: sc->sc_ver = 0x21; break;
1316 case 1: sc->sc_ver = 0x20; break;
1317 case 0: sc->sc_ver = 0x10; break;
1318 }
1319 break;
1320
1321 case 0x783:
1322 p = "Mercury";
1323 break;
1324
1325 case 0x784:
1326 p = "Quicksilver";
1327 break;
1328
1329 default:
1330 p = "Mojo";
1331 break;
1332 }
1333
1334 aprint_normal(": %s TR%d.%d%s", p, sc->sc_ver >> 4, sc->sc_ver & 0xf,
1335 q);
1336 apic_attach(sc);
1337 aprint_normal("\n");
1338
1339 elroy_write32(&r->imask, htole32(0xffffffff << 30));
1340 elroy_write32(&r->ibase, htole32(ELROY_BASE_RE));
1341
1342 /* TODO reserve elroy's pci space ? */
1343
1344 #if 0
1345 printf("lmm %llx/%llx gmm %llx/%llx wlm %llx/%llx wgm %llx/%llx io %llx/%llx eio %llx/%llx\n",
1346 le64toh(r->lmmio_base), le64toh(r->lmmio_mask),
1347 le64toh(r->gmmio_base), le64toh(r->gmmio_mask),
1348 le64toh(r->wlmmio_base), le64toh(r->wlmmio_mask),
1349 le64toh(r->wgmmio_base), le64toh(r->wgmmio_mask),
1350 le64toh(r->io_base), le64toh(r->io_mask),
1351 le64toh(r->eio_base), le64toh(r->eio_mask));
1352 #endif
1353
1354 /* XXX evil hack! */
1355 sc->sc_iobase = 0xfee00000;
1356
1357 sc->sc_iot = elroy_iomemt;
1358 sc->sc_iot.hbt_cookie = sc;
1359 sc->sc_iot.hbt_map = elroy_iomap;
1360 sc->sc_iot.hbt_alloc = elroy_ioalloc;
1361 sc->sc_memt = elroy_iomemt;
1362 sc->sc_memt.hbt_cookie = sc;
1363 sc->sc_memt.hbt_map = elroy_memmap;
1364 sc->sc_memt.hbt_alloc = elroy_memalloc;
1365 sc->sc_pc = elroy_pc;
1366 sc->sc_pc._cookie = sc;
1367 sc->sc_dmatag = elroy_dmat;
1368 sc->sc_dmatag._cookie = sc;
1369
1370 memset(&pba, 0, sizeof(pba));
1371 pba.pba_iot = &sc->sc_iot;
1372 pba.pba_memt = &sc->sc_memt;
1373 pba.pba_dmat = &sc->sc_dmatag;
1374 pba.pba_pc = &sc->sc_pc;
1375 pba.pba_bus = 0; /* (le32toh(elroy_read32(&r->busnum)) & 0xff) >> 4; */
1376 pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY;
1377
1378 config_found(self, &pba, pcibusprint, CFARGS_NONE);
1379 }
1380