1 /* $OpenBSD: bonito.c,v 1.36 2022/08/22 00:35:07 cheloha Exp $ */
2 /* $NetBSD: bonito_mainbus.c,v 1.11 2008/04/28 20:23:10 martin Exp $ */
3 /* $NetBSD: bonito_pci.c,v 1.5 2008/04/28 20:23:28 martin Exp $ */
4
5 /*
6 * Copyright (c) 2009, 2010 Miodrag Vallat.
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20 /*-
21 * Copyright (c) 2001 The NetBSD Foundation, Inc.
22 * All rights reserved.
23 *
24 * This code is derived from software contributed to The NetBSD Foundation
25 * by Jason R. Thorpe.
26 *
27 * Redistribution and use in source and binary forms, with or without
28 * modification, are permitted provided that the following conditions
29 * are met:
30 * 1. Redistributions of source code must retain the above copyright
31 * notice, this list of conditions and the following disclaimer.
32 * 2. Redistributions in binary form must reproduce the above copyright
33 * notice, this list of conditions and the following disclaimer in the
34 * documentation and/or other materials provided with the distribution.
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
37 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
38 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
40 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
41 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
42 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
43 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
44 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 * POSSIBILITY OF SUCH DAMAGE.
47 */
48
49 /*
50 * PCI configuration space support for the Loongson PCI and memory controller
51 * chip, which is derived from the Algorithmics BONITO chip.
52 */
53
54 #include <sys/param.h>
55 #include <sys/systm.h>
56 #include <sys/device.h>
57 #include <sys/extent.h>
58 #include <sys/malloc.h>
59
60 #include <machine/autoconf.h>
61 #include <machine/bus.h>
62 #include <machine/cpu.h>
63 #include <mips64/mips_cpu.h>
64 #include <machine/intr.h>
65
66 #include <dev/pci/pcidevs.h>
67 #include <dev/pci/pcireg.h>
68 #include <dev/pci/pcivar.h>
69 #include <dev/pci/ppbreg.h>
70
71 #include <loongson/dev/bonitoreg.h>
72 #include <loongson/dev/bonitovar.h>
73 #include <loongson/dev/bonito_irq.h>
74
75 #include <uvm/uvm_extern.h>
76
77 #if 0
78 #define BONITO_DEBUG
79 #endif
80
81 int bonito_match(struct device *, void *, void *);
82 void bonito_attach(struct device *, struct device *, void *);
83
84 const struct cfattach bonito_ca = {
85 sizeof(struct bonito_softc), bonito_match, bonito_attach
86 };
87
88 struct cfdriver bonito_cd = {
89 NULL, "bonito", DV_DULL
90 };
91
92 #define wbflush() mips_sync()
93
94 bus_addr_t bonito_pa_to_device(paddr_t);
95 paddr_t bonito_device_to_pa(bus_addr_t);
96
97 void bonito_intr_makemasks(void);
98 uint32_t bonito_intr_2e(uint32_t, struct trapframe *);
99 uint32_t bonito_intr_2f(uint32_t, struct trapframe *);
100 void bonito_intr_dispatch(uint64_t, int, struct trapframe *);
101
102 void bonito_attach_hook(struct device *, struct device *,
103 struct pcibus_attach_args *);
104 int bonito_bus_maxdevs(void *, int);
105 pcitag_t bonito_make_tag(void *, int, int, int);
106 void bonito_decompose_tag(void *, pcitag_t, int *, int *, int *);
107 int bonito_conf_size(void *, pcitag_t);
108 pcireg_t bonito_conf_read(void *, pcitag_t, int);
109 pcireg_t bonito_conf_read_internal(const struct bonito_config *, pcitag_t, int);
110 void bonito_conf_write(void *, pcitag_t, int, pcireg_t);
111 int bonito_pci_intr_map(struct pci_attach_args *, pci_intr_handle_t *);
112 const char *
113 bonito_pci_intr_string(void *, pci_intr_handle_t);
114 void *bonito_pci_intr_establish(void *, pci_intr_handle_t, int,
115 int (*)(void *), void *, char *);
116 void bonito_pci_intr_disestablish(void *, void *);
117
118 int bonito_conf_addr(const struct bonito_config *, pcitag_t, int,
119 u_int32_t *, u_int32_t *);
120
121 void bonito_splx(int);
122
123 /*
124 * Bonito interrupt handling declarations.
125 * See <loongson/dev/bonito_irq.h> for details.
126 */
127 struct intrhand *bonito_intrhand[BONITO_NINTS];
128 uint64_t bonito_intem;
129 uint64_t bonito_imask[NIPLS];
130
131 struct machine_bus_dma_tag bonito_bus_dma_tag = {
132 ._dmamap_create = _dmamap_create,
133 ._dmamap_destroy = _dmamap_destroy,
134 ._dmamap_load = _dmamap_load,
135 ._dmamap_load_mbuf = _dmamap_load_mbuf,
136 ._dmamap_load_uio = _dmamap_load_uio,
137 ._dmamap_load_raw = _dmamap_load_raw,
138 ._dmamap_load_buffer = _dmamap_load_buffer,
139 ._dmamap_unload = _dmamap_unload,
140 ._dmamap_sync = _dmamap_sync,
141
142 ._dmamem_alloc = _dmamem_alloc,
143 ._dmamem_free = _dmamem_free,
144 ._dmamem_map = _dmamem_map,
145 ._dmamem_unmap = _dmamem_unmap,
146 ._dmamem_mmap = _dmamem_mmap,
147
148 ._pa_to_device = bonito_pa_to_device,
149 ._device_to_pa = bonito_device_to_pa
150 };
151
152 int bonito_io_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
153 bus_space_handle_t *);
154 int bonito_mem_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
155 bus_space_handle_t *);
156
157 struct mips_bus_space bonito_pci_io_space_tag = {
158 .bus_base = PHYS_TO_XKPHYS(BONITO_PCIIO_BASE, CCA_NC),
159 ._space_read_1 = generic_space_read_1,
160 ._space_write_1 = generic_space_write_1,
161 ._space_read_2 = generic_space_read_2,
162 ._space_write_2 = generic_space_write_2,
163 ._space_read_4 = generic_space_read_4,
164 ._space_write_4 = generic_space_write_4,
165 ._space_read_8 = generic_space_read_8,
166 ._space_write_8 = generic_space_write_8,
167 ._space_read_raw_2 = generic_space_read_raw_2,
168 ._space_write_raw_2 = generic_space_write_raw_2,
169 ._space_read_raw_4 = generic_space_read_raw_4,
170 ._space_write_raw_4 = generic_space_write_raw_4,
171 ._space_read_raw_8 = generic_space_read_raw_8,
172 ._space_write_raw_8 = generic_space_write_raw_8,
173 ._space_map = bonito_io_map,
174 ._space_unmap = generic_space_unmap,
175 ._space_subregion = generic_space_region,
176 ._space_vaddr = generic_space_vaddr,
177 ._space_mmap = generic_space_mmap
178 };
179
180 struct mips_bus_space bonito_pci_mem_space_tag = {
181 .bus_base = PHYS_TO_XKPHYS(0, CCA_NC),
182 ._space_read_1 = generic_space_read_1,
183 ._space_write_1 = generic_space_write_1,
184 ._space_read_2 = generic_space_read_2,
185 ._space_write_2 = generic_space_write_2,
186 ._space_read_4 = generic_space_read_4,
187 ._space_write_4 = generic_space_write_4,
188 ._space_read_8 = generic_space_read_8,
189 ._space_write_8 = generic_space_write_8,
190 ._space_read_raw_2 = generic_space_read_raw_2,
191 ._space_write_raw_2 = generic_space_write_raw_2,
192 ._space_read_raw_4 = generic_space_read_raw_4,
193 ._space_write_raw_4 = generic_space_write_raw_4,
194 ._space_read_raw_8 = generic_space_read_raw_8,
195 ._space_write_raw_8 = generic_space_write_raw_8,
196 ._space_map = bonito_mem_map,
197 ._space_unmap = generic_space_unmap,
198 ._space_subregion = generic_space_region,
199 ._space_vaddr = generic_space_vaddr,
200 ._space_mmap = generic_space_mmap
201 };
202
203 int
bonito_match(struct device * parent,void * vcf,void * aux)204 bonito_match(struct device *parent, void *vcf, void *aux)
205 {
206 struct mainbus_attach_args *maa = aux;
207
208 if (loongson_ver >= 0x3a)
209 return (0);
210
211 if (strcmp(maa->maa_name, bonito_cd.cd_name) == 0)
212 return (1);
213
214 return (0);
215 }
216
217 void
bonito_attach(struct device * parent,struct device * self,void * aux)218 bonito_attach(struct device *parent, struct device *self, void *aux)
219 {
220 struct bonito_softc *sc = (struct bonito_softc *)self;
221 struct pcibus_attach_args pba;
222 pci_chipset_tag_t pc = &sc->sc_pc;
223 const struct bonito_config *bc;
224 uint32_t reg;
225
226 /*
227 * Loongson 2F processors do not use a real Bonito64 chip but
228 * their own derivative, which is no longer 100% compatible.
229 * We need to make sure we never try to access an unimplemented
230 * register...
231 */
232 if (loongson_ver >= 0x2f)
233 sc->sc_compatible = 0;
234 else
235 sc->sc_compatible = 1;
236
237 reg = PCI_REVISION(REGVAL(BONITO_PCI_REG(PCI_CLASS_REG)));
238 if (sc->sc_compatible) {
239 printf(": BONITO Memory and PCI controller, %s rev %d.%d\n",
240 BONITO_REV_FPGA(reg) ? "FPGA" : "ASIC",
241 BONITO_REV_MAJOR(reg), BONITO_REV_MINOR(reg));
242 } else {
243 printf(": memory and PCI-X controller, rev %d\n",
244 PCI_REVISION(REGVAL(BONITO_PCI_REG(PCI_CLASS_REG))));
245 }
246
247 bc = sys_platform->bonito_config;
248 sc->sc_bonito = bc;
249 SLIST_INIT(&sc->sc_hook);
250
251 #ifdef BONITO_DEBUG
252 if (!sc->sc_compatible)
253 printf("ISR4C: %08x\n", REGVAL(BONITO_PCI_REG(0x4c)));
254 printf("PCIMAP: %08x\n", REGVAL(BONITO_PCIMAP));
255 printf("MEMWIN: %08x.%08x - %08x.%08x\n",
256 REGVAL(BONITO_MEM_WIN_BASE_H), REGVAL(BONITO_MEM_WIN_BASE_L),
257 REGVAL(BONITO_MEM_WIN_MASK_H), REGVAL(BONITO_MEM_WIN_MASK_L));
258 if (!sc->sc_compatible) {
259 printf("HITSEL0: %08x.%08x\n",
260 REGVAL(LOONGSON_PCI_HIT0_SEL_H),
261 REGVAL(LOONGSON_PCI_HIT0_SEL_L));
262 printf("HITSEL1: %08x.%08x\n",
263 REGVAL(LOONGSON_PCI_HIT1_SEL_H),
264 REGVAL(LOONGSON_PCI_HIT1_SEL_L));
265 printf("HITSEL2: %08x.%08x\n",
266 REGVAL(LOONGSON_PCI_HIT2_SEL_H),
267 REGVAL(LOONGSON_PCI_HIT2_SEL_L));
268 }
269 printf("PCI BAR 0:%08x 1:%08x 2:%08x 3:%08x 4:%08x 5:%08x\n",
270 REGVAL(BONITO_PCI_REG(PCI_MAPREG_START + 0 * 4)),
271 REGVAL(BONITO_PCI_REG(PCI_MAPREG_START + 1 * 4)),
272 REGVAL(BONITO_PCI_REG(PCI_MAPREG_START + 2 * 4)),
273 REGVAL(BONITO_PCI_REG(PCI_MAPREG_START + 3 * 4)),
274 REGVAL(BONITO_PCI_REG(PCI_MAPREG_START + 4 * 4)),
275 REGVAL(BONITO_PCI_REG(PCI_MAPREG_START + 5 * 4)));
276 #endif
277
278 /*
279 * Setup proper arbitration.
280 */
281
282 if (!sc->sc_compatible) {
283 /*
284 * According to Linux, changing the value of this register
285 * ``avoids deadlock of PCI reading/writing lock operation''.
286 *
287 * Unfortunately, documentation for the Implementation
288 * Specific Registers (ISR40 to ISR5C) is only found in the
289 * chinese version of the Loongson 2F documentation.
290 *
291 * The particular bit we set here is ``mas_read_defer''.
292 */
293 /* c2000001 -> d2000001 */
294 REGVAL(BONITO_PCI_REG(0x4c)) |= 0x10000000;
295
296 /* all pci devices may need to hold the bus */
297 reg = REGVAL(LOONGSON_PXARB_CFG);
298 reg &= ~LOONGSON_PXARB_RUDE_DEV_MSK;
299 reg |= 0xfe << LOONGSON_PXARB_RUDE_DEV_SHFT;
300 REGVAL(LOONGSON_PXARB_CFG) = reg;
301 (void)REGVAL(LOONGSON_PXARB_CFG);
302 }
303
304 /*
305 * Setup interrupt handling.
306 */
307
308 REGVAL(BONITO_GPIOIE) = bc->bc_gpioIE;
309 REGVAL(BONITO_INTEDGE) = bc->bc_intEdge;
310 if (sc->sc_compatible)
311 REGVAL(BONITO_INTSTEER) = bc->bc_intSteer;
312 REGVAL(BONITO_INTPOL) = bc->bc_intPol;
313
314 REGVAL(BONITO_INTENCLR) = 0xffffffff;
315 (void)REGVAL(BONITO_INTENCLR);
316
317 if (sc->sc_compatible) {
318 bonito_intem |= BONITO_INTRMASK_MASTERERR;
319 }
320
321 if (loongson_ver >= 0x2f)
322 set_intr(INTPRI_BONITO, CR_INT_4, bonito_intr_2f);
323 else
324 set_intr(INTPRI_BONITO, CR_INT_0, bonito_intr_2e);
325 register_splx_handler(bonito_splx);
326
327 /*
328 * Attach PCI bus.
329 */
330
331 pc->pc_conf_v = sc;
332 pc->pc_attach_hook = bonito_attach_hook;
333 pc->pc_bus_maxdevs = bonito_bus_maxdevs;
334 pc->pc_make_tag = bonito_make_tag;
335 pc->pc_decompose_tag = bonito_decompose_tag;
336 pc->pc_conf_size = bonito_conf_size;
337 pc->pc_conf_read = bonito_conf_read;
338 pc->pc_conf_write = bonito_conf_write;
339
340 pc->pc_intr_v = sc;
341 pc->pc_intr_map = bonito_pci_intr_map;
342 pc->pc_intr_string = bonito_pci_intr_string;
343 pc->pc_intr_establish = bonito_pci_intr_establish;
344 pc->pc_intr_disestablish = bonito_pci_intr_disestablish;
345
346 bzero(&pba, sizeof pba);
347 pba.pba_busname = "pci";
348 pba.pba_iot = &bonito_pci_io_space_tag;
349 pba.pba_memt = &bonito_pci_mem_space_tag;
350 pba.pba_dmat = &bonito_bus_dma_tag;
351 pba.pba_pc = pc;
352 pba.pba_domain = pci_ndomains++;
353 pba.pba_bus = 0;
354 #ifdef notyet
355 pba.pba_ioex = bonito_get_resource_extent(pc, 1);
356 pba.pba_memex = bonito_get_resource_extent(pc, 0);
357 #endif
358
359 config_found(&sc->sc_dev, &pba, bonito_print);
360 }
361
362 bus_addr_t
bonito_pa_to_device(paddr_t pa)363 bonito_pa_to_device(paddr_t pa)
364 {
365 return pa ^ loongson_dma_base;
366 }
367
368 paddr_t
bonito_device_to_pa(bus_addr_t addr)369 bonito_device_to_pa(bus_addr_t addr)
370 {
371 return addr ^ loongson_dma_base;
372 }
373
374 int
bonito_print(void * aux,const char * pnp)375 bonito_print(void *aux, const char *pnp)
376 {
377 struct pcibus_attach_args *pba = aux;
378
379 if (pnp)
380 printf("%s at %s", pba->pba_busname, pnp);
381 printf(" bus %d", pba->pba_bus);
382
383 return UNCONF;
384 }
385
386 /*
387 * Bonito interrupt handling
388 */
389
390 void *
bonito_intr_establish(int irq,int type,int level,int (* handler)(void *),void * arg,const char * name)391 bonito_intr_establish(int irq, int type, int level, int (*handler)(void *),
392 void *arg, const char *name)
393 {
394 struct intrhand **p, *q, *ih;
395 int s;
396
397 #ifdef DIAGNOSTIC
398 if (irq >= BONITO_NINTS || irq == BONITO_ISA_IRQ(2) || irq < 0)
399 panic("bonito_intr_establish: illegal irq %d", irq);
400 #endif
401
402 level &= ~IPL_MPSAFE;
403
404 ih = malloc(sizeof *ih, M_DEVBUF, M_NOWAIT);
405 if (ih == NULL)
406 return NULL;
407
408 ih->ih_next = NULL;
409 ih->ih_fun = handler;
410 ih->ih_arg = arg;
411 ih->ih_level = level;
412 ih->ih_irq = irq;
413 evcount_attach(&ih->ih_count, name, &ih->ih_irq);
414
415 s = splhigh();
416
417 /*
418 * Figure out where to put the handler.
419 * This is O(N^2), but we want to preserve the order, and N is
420 * generally small.
421 */
422 for (p = &bonito_intrhand[irq]; (q = *p) != NULL; p = &q->ih_next)
423 ;
424 *p = ih;
425
426 bonito_intem |= 1UL << irq;
427 bonito_intr_makemasks();
428
429 splx(s); /* causes hw mask update */
430
431 return (ih);
432 }
433
434 void
bonito_intr_disestablish(void * vih)435 bonito_intr_disestablish(void *vih)
436 {
437 struct intrhand *ih = (struct intrhand *)vih;
438 struct intrhand **p, *q;
439 int irq = ih->ih_irq;
440 int s;
441
442 #ifdef DIAGNOSTIC
443 if (irq >= BONITO_NINTS || irq == BONITO_ISA_IRQ(2) || irq < 0)
444 panic("bonito_intr_disestablish: illegal irq %d", irq);
445 #endif
446
447 s = splhigh();
448
449 evcount_detach(&ih->ih_count);
450
451 for (p = &bonito_intrhand[irq]; (q = *p) != NULL; p = &q->ih_next)
452 if (q == ih)
453 break;
454 #ifdef DIAGNOSTIC
455 if (q == NULL)
456 panic("bonito_intr_disestablish: never registered");
457 #endif
458 *p = ih->ih_next;
459
460 if (ih->ih_next == NULL && p == &bonito_intrhand[irq]) {
461 bonito_intem &= ~(1UL << irq);
462 bonito_intr_makemasks();
463 /*
464 * No need to clear a bit in INTEN through INTCLR,
465 * splhigh() took care of disabling everything and
466 * splx() will not reenable this source after the
467 * mask update.
468 */
469 }
470
471 splx(s);
472
473 free(ih, M_DEVBUF, sizeof *ih);
474 }
475
476 /*
477 * Update interrupt masks. This is for designs without legacy PIC.
478 */
479
480 void
bonito_splx(int newipl)481 bonito_splx(int newipl)
482 {
483 struct cpu_info *ci = curcpu();
484
485 /* Update masks to new ipl. Order highly important! */
486 ci->ci_ipl = newipl;
487 bonito_setintrmask(newipl);
488
489 /* Trigger deferred clock interrupt if it is now unmasked. */
490 if (ci->ci_clock_deferred && newipl < IPL_CLOCK)
491 md_triggerclock();
492
493 /* If we still have softints pending trigger processing. */
494 if (ci->ci_softpending != 0 && newipl < IPL_SOFTINT)
495 setsoftintr0();
496 }
497
498 void
bonito_setintrmask(int level)499 bonito_setintrmask(int level)
500 {
501 uint64_t active;
502 uint32_t clear, set;
503 register_t sr;
504
505 active = bonito_intem & ~bonito_imask[level];
506 /* be sure to mask high bits, there may be other interrupt sources */
507 clear = BONITO_DIRECT_MASK(bonito_imask[level]);
508 set = BONITO_DIRECT_MASK(active);
509
510 sr = disableintr();
511
512 if (clear != 0) {
513 REGVAL(BONITO_INTENCLR) = clear;
514 (void)REGVAL(BONITO_INTENCLR);
515 }
516 if (set != 0) {
517 REGVAL(BONITO_INTENSET) = set;
518 (void)REGVAL(BONITO_INTENSET);
519 }
520
521 setsr(sr);
522 }
523
524 /*
525 * Recompute interrupt masks.
526 */
527 void
bonito_intr_makemasks()528 bonito_intr_makemasks()
529 {
530 int irq, level;
531 struct intrhand *q;
532 uint intrlevel[BONITO_NINTS];
533
534 /* First, figure out which levels each IRQ uses. */
535 for (irq = 0; irq < BONITO_NINTS; irq++) {
536 uint levels = 0;
537 for (q = bonito_intrhand[irq]; q != NULL; q = q->ih_next)
538 levels |= 1 << q->ih_level;
539 intrlevel[irq] = levels;
540 }
541
542 /*
543 * Then figure out which IRQs use each level.
544 * Note that we make sure never to overwrite imask[IPL_HIGH], in
545 * case an interrupt occurs during intr_disestablish() and causes
546 * an unfortunate splx() while we are here recomputing the masks.
547 */
548 for (level = IPL_NONE; level < IPL_HIGH; level++) {
549 uint64_t irqs = 0;
550 for (irq = 0; irq < BONITO_NINTS; irq++)
551 if (intrlevel[irq] & (1 << level))
552 irqs |= 1UL << irq;
553 bonito_imask[level] = irqs;
554 }
555
556 /*
557 * There are tty, network and disk drivers that use free() at interrupt
558 * time, so vm > (tty | net | bio).
559 *
560 * Enforce a hierarchy that gives slow devices a better chance at not
561 * dropping data.
562 */
563 bonito_imask[IPL_NET] |= bonito_imask[IPL_BIO];
564 bonito_imask[IPL_TTY] |= bonito_imask[IPL_NET];
565 bonito_imask[IPL_VM] |= bonito_imask[IPL_TTY];
566 bonito_imask[IPL_CLOCK] |= bonito_imask[IPL_VM];
567
568 /*
569 * These are pseudo-levels.
570 */
571 bonito_imask[IPL_NONE] = 0;
572 bonito_imask[IPL_HIGH] = -1UL;
573 }
574
575 /*
576 * Process native interrupts
577 */
578
579 uint32_t
bonito_intr_2e(uint32_t hwpend,struct trapframe * frame)580 bonito_intr_2e(uint32_t hwpend, struct trapframe *frame)
581 {
582 uint64_t imr, isr, mask;
583
584 isr = REGVAL(BONITO_INTISR);
585
586 /*
587 * According to Linux code, Bonito64 - at least on Loongson
588 * systems - triggers an interrupt during DMA, which is to be
589 * ignored. Smells like a chip errata to me.
590 */
591 while (ISSET(isr, BONITO_INTRMASK_MASTERERR)) {
592 delay(1);
593 isr = REGVAL(BONITO_INTISR);
594 }
595
596 isr &= BONITO_INTRMASK_GPIN;
597 imr = REGVAL(BONITO_INTEN);
598 isr &= imr;
599 #ifdef DEBUG
600 printf("pci interrupt: imr %04x isr %04x\n", imr, isr);
601 #endif
602 if (isr == 0)
603 return 0; /* not for us */
604
605 /*
606 * Mask all pending interrupts.
607 */
608 REGVAL(BONITO_INTENCLR) = isr;
609 (void)REGVAL(BONITO_INTENCLR);
610
611 /*
612 * If interrupts are spl-masked, mask them and wait for splx()
613 * to reenable them when necessary.
614 */
615 if ((mask = isr & bonito_imask[frame->ipl]) != 0) {
616 isr &= ~mask;
617 imr &= ~mask;
618 }
619
620 /*
621 * Now process allowed interrupts.
622 */
623 if (isr != 0) {
624 bonito_intr_dispatch(isr, 30, frame);
625
626 /*
627 * Reenable interrupts which have been serviced.
628 */
629 REGVAL(BONITO_INTENSET) = imr;
630 (void)REGVAL(BONITO_INTENSET);
631 }
632
633 return hwpend;
634 }
635
636 uint32_t
bonito_intr_2f(uint32_t hwpend,struct trapframe * frame)637 bonito_intr_2f(uint32_t hwpend, struct trapframe *frame)
638 {
639 uint64_t imr, isr, mask;
640
641 isr = REGVAL(BONITO_INTISR) & LOONGSON_INTRMASK_LVL4;
642 imr = REGVAL(BONITO_INTEN);
643 isr &= imr;
644 #ifdef DEBUG
645 printf("pci interrupt: imr %04x isr %04x\n", imr, isr);
646 #endif
647 if (isr == 0)
648 return 0; /* not for us */
649
650 /*
651 * Mask all pending interrupts.
652 */
653 REGVAL(BONITO_INTENCLR) = isr;
654 (void)REGVAL(BONITO_INTENCLR);
655
656 /*
657 * If interrupts are spl-masked, mask them and wait for splx()
658 * to reenable them when necessary.
659 */
660 if ((mask = isr & bonito_imask[frame->ipl]) != 0) {
661 isr &= ~mask;
662 imr &= ~mask;
663 }
664
665 /*
666 * Now process allowed interrupts.
667 */
668 if (isr != 0) {
669 bonito_intr_dispatch(isr,
670 LOONGSON_INTR_DRAM_PARERR /* skip non-pci interrupts */,
671 frame);
672
673 /*
674 * Reenable interrupts which have been serviced.
675 */
676 REGVAL(BONITO_INTENSET) = imr;
677 (void)REGVAL(BONITO_INTENSET);
678 }
679
680 return hwpend;
681 }
682
683 void
bonito_intr_dispatch(uint64_t isr,int startbit,struct trapframe * frame)684 bonito_intr_dispatch(uint64_t isr, int startbit, struct trapframe *frame)
685 {
686 int lvl, bitno;
687 uint64_t tmpisr, mask;
688 struct intrhand *ih;
689 int rc;
690
691 /* Service higher level interrupts first */
692 for (lvl = IPL_HIGH - 1; lvl != IPL_NONE; lvl--) {
693 tmpisr = isr & (bonito_imask[lvl] ^ bonito_imask[lvl - 1]);
694 if (tmpisr == 0)
695 continue;
696 for (bitno = startbit, mask = 1UL << bitno; mask != 0;
697 bitno--, mask >>= 1) {
698 if ((tmpisr & mask) == 0)
699 continue;
700
701 rc = 0;
702 for (ih = bonito_intrhand[bitno]; ih != NULL;
703 ih = ih->ih_next) {
704 splraise(ih->ih_level);
705 if ((*ih->ih_fun)(ih->ih_arg) != 0) {
706 rc = 1;
707 ih->ih_count.ec_count++;
708 }
709 curcpu()->ci_ipl = frame->ipl;
710 }
711 if (rc == 0) {
712 printf("spurious interrupt %d\n", bitno);
713 #ifdef DEBUG
714 printf("ISR %08x IMR %08x ipl %d mask %08x\n",
715 REGVAL(BONITO_INTISR), REGVAL(BONITO_INTEN),
716 frame->ipl, bonito_imask[frame->ipl]);
717 #ifdef DDB
718 db_enter();
719 #endif
720 #endif
721 }
722
723 if ((isr ^= mask) == 0)
724 return;
725 if ((tmpisr ^= mask) == 0)
726 break;
727 }
728 }
729 }
730
731 /*
732 * various PCI helpers
733 */
734
735 void
bonito_attach_hook(struct device * parent,struct device * self,struct pcibus_attach_args * pba)736 bonito_attach_hook(struct device *parent, struct device *self,
737 struct pcibus_attach_args *pba)
738 {
739 pci_chipset_tag_t pc = pba->pba_pc;
740 struct bonito_softc *sc = pc->pc_conf_v;
741 const struct bonito_config *bc = sc->sc_bonito;
742
743 if (pba->pba_bus != 0)
744 return;
745
746 (*bc->bc_attach_hook)(pc);
747 }
748
749 /*
750 * PCI configuration space access routines
751 */
752
753 int
bonito_bus_maxdevs(void * v,int busno)754 bonito_bus_maxdevs(void *v, int busno)
755 {
756 struct bonito_softc *sc = v;
757 const struct bonito_config *bc = sc->sc_bonito;
758
759 return busno == 0 ? 32 - bc->bc_adbase : 32;
760 }
761
762 pcitag_t
bonito_make_tag(void * unused,int b,int d,int f)763 bonito_make_tag(void *unused, int b, int d, int f)
764 {
765 return (b << 16) | (d << 11) | (f << 8);
766 }
767
768 void
bonito_decompose_tag(void * unused,pcitag_t tag,int * bp,int * dp,int * fp)769 bonito_decompose_tag(void *unused, pcitag_t tag, int *bp, int *dp, int *fp)
770 {
771 if (bp != NULL)
772 *bp = (tag >> 16) & 0xff;
773 if (dp != NULL)
774 *dp = (tag >> 11) & 0x1f;
775 if (fp != NULL)
776 *fp = (tag >> 8) & 0x7;
777 }
778
779 int
bonito_conf_addr(const struct bonito_config * bc,pcitag_t tag,int offset,u_int32_t * cfgoff,u_int32_t * pcimap_cfg)780 bonito_conf_addr(const struct bonito_config *bc, pcitag_t tag, int offset,
781 u_int32_t *cfgoff, u_int32_t *pcimap_cfg)
782 {
783 int b, d, f;
784
785 bonito_decompose_tag(NULL, tag, &b, &d, &f);
786
787 if (b == 0) {
788 d += bc->bc_adbase;
789 if (d > 31)
790 return 1;
791 *cfgoff = (1 << d) | (f << 8) | offset;
792 *pcimap_cfg = 0;
793 } else {
794 *cfgoff = tag | offset;
795 *pcimap_cfg = BONITO_PCIMAPCFG_TYPE1;
796 }
797
798 return 0;
799 }
800
801 /* PCI Configuration Space access hook structure */
802 struct bonito_cfg_hook {
803 SLIST_ENTRY(bonito_cfg_hook) next;
804 int (*read)(void *, pci_chipset_tag_t, pcitag_t, int, pcireg_t *);
805 int (*write)(void *, pci_chipset_tag_t, pcitag_t, int, pcireg_t);
806 void *cookie;
807 };
808
809 int
bonito_pci_hook(pci_chipset_tag_t pc,void * cookie,int (* r)(void *,pci_chipset_tag_t,pcitag_t,int,pcireg_t *),int (* w)(void *,pci_chipset_tag_t,pcitag_t,int,pcireg_t))810 bonito_pci_hook(pci_chipset_tag_t pc, void *cookie,
811 int (*r)(void *, pci_chipset_tag_t, pcitag_t, int, pcireg_t *),
812 int (*w)(void *, pci_chipset_tag_t, pcitag_t, int, pcireg_t))
813 {
814 struct bonito_softc *sc = pc->pc_conf_v;
815 struct bonito_cfg_hook *bch;
816
817 bch = malloc(sizeof *bch, M_DEVBUF, M_NOWAIT);
818 if (bch == NULL)
819 return ENOMEM;
820
821 bch->read = r;
822 bch->write = w;
823 bch->cookie = cookie;
824 SLIST_INSERT_HEAD(&sc->sc_hook, bch, next);
825 return 0;
826 }
827
828 int
bonito_conf_size(void * v,pcitag_t tag)829 bonito_conf_size(void *v, pcitag_t tag)
830 {
831 return PCI_CONFIG_SPACE_SIZE;
832 }
833
834 pcireg_t
bonito_conf_read(void * v,pcitag_t tag,int offset)835 bonito_conf_read(void *v, pcitag_t tag, int offset)
836 {
837 struct bonito_softc *sc = v;
838 struct bonito_cfg_hook *hook;
839 pcireg_t data;
840
841 SLIST_FOREACH(hook, &sc->sc_hook, next) {
842 if (hook->read != NULL &&
843 (*hook->read)(hook->cookie, &sc->sc_pc, tag, offset,
844 &data) != 0)
845 return data;
846 }
847
848 return bonito_conf_read_internal(sc->sc_bonito, tag, offset);
849 }
850
851 pcireg_t
bonito_conf_read_internal(const struct bonito_config * bc,pcitag_t tag,int offset)852 bonito_conf_read_internal(const struct bonito_config *bc, pcitag_t tag,
853 int offset)
854 {
855 pcireg_t data;
856 u_int32_t cfgoff, pcimap_cfg;
857 register_t sr;
858 uint64_t imr;
859
860 if (bonito_conf_addr(bc, tag, offset, &cfgoff, &pcimap_cfg))
861 return (pcireg_t)-1;
862
863 sr = disableintr();
864 imr = REGVAL(BONITO_INTEN);
865 REGVAL(BONITO_INTENCLR) = 0xffffffff;
866 (void)REGVAL(BONITO_INTENCLR);
867
868 /* clear aborts */
869 REGVAL(BONITO_PCI_REG(PCI_COMMAND_STATUS_REG)) |=
870 PCI_STATUS_MASTER_ABORT | PCI_STATUS_MASTER_TARGET_ABORT;
871
872 /* high 16 bits of address go into PciMapCfg register */
873 REGVAL(BONITO_PCIMAP_CFG) = (cfgoff >> 16) | pcimap_cfg;
874 (void)REGVAL(BONITO_PCIMAP_CFG);
875 wbflush();
876
877 /* low 16 bits of address are offset into config space */
878 data = REGVAL(BONITO_PCICFG_BASE + (cfgoff & 0xfffc));
879
880 /* check for error */
881 if (REGVAL(BONITO_PCI_REG(PCI_COMMAND_STATUS_REG)) &
882 (PCI_STATUS_MASTER_ABORT | PCI_STATUS_MASTER_TARGET_ABORT)) {
883 REGVAL(BONITO_PCI_REG(PCI_COMMAND_STATUS_REG)) |=
884 PCI_STATUS_MASTER_ABORT | PCI_STATUS_MASTER_TARGET_ABORT;
885 data = (pcireg_t) -1;
886 }
887
888 REGVAL(BONITO_INTENSET) = imr;
889 (void)REGVAL(BONITO_INTENSET);
890 setsr(sr);
891
892 return data;
893 }
894
895 void
bonito_conf_write(void * v,pcitag_t tag,int offset,pcireg_t data)896 bonito_conf_write(void *v, pcitag_t tag, int offset, pcireg_t data)
897 {
898 struct bonito_softc *sc = v;
899 u_int32_t cfgoff, pcimap_cfg;
900 struct bonito_cfg_hook *hook;
901 register_t sr;
902 uint64_t imr;
903
904 SLIST_FOREACH(hook, &sc->sc_hook, next) {
905 if (hook->write != NULL &&
906 (*hook->write)(hook->cookie, &sc->sc_pc, tag, offset,
907 data) != 0)
908 return;
909 }
910
911 if (bonito_conf_addr(sc->sc_bonito, tag, offset, &cfgoff, &pcimap_cfg))
912 panic("bonito_conf_write");
913
914 sr = disableintr();
915 imr = REGVAL(BONITO_INTEN);
916 REGVAL(BONITO_INTENCLR) = 0xffffffff;
917 (void)REGVAL(BONITO_INTENCLR);
918
919 /* clear aborts */
920 REGVAL(BONITO_PCI_REG(PCI_COMMAND_STATUS_REG)) |=
921 PCI_STATUS_MASTER_ABORT | PCI_STATUS_MASTER_TARGET_ABORT;
922
923 /* high 16 bits of address go into PciMapCfg register */
924 REGVAL(BONITO_PCIMAP_CFG) = (cfgoff >> 16) | pcimap_cfg;
925 (void)REGVAL(BONITO_PCIMAP_CFG);
926 wbflush();
927
928 /* low 16 bits of address are offset into config space */
929 REGVAL(BONITO_PCICFG_BASE + (cfgoff & 0xfffc)) = data;
930
931 REGVAL(BONITO_INTENSET) = imr;
932 (void)REGVAL(BONITO_INTENSET);
933 setsr(sr);
934 }
935
936 /*
937 * PCI Interrupt handling
938 */
939
940 int
bonito_pci_intr_map(struct pci_attach_args * pa,pci_intr_handle_t * ihp)941 bonito_pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
942 {
943 struct bonito_softc *sc = pa->pa_pc->pc_intr_v;
944 const struct bonito_config *bc = sc->sc_bonito;
945 int bus, dev, fn, pin;
946
947 *ihp = (pci_intr_handle_t)-1;
948
949 if (pa->pa_intrpin == 0) /* no interrupt needed */
950 return 1;
951
952 #ifdef DIAGNOSTIC
953 if (pa->pa_intrpin > 4) {
954 printf("%s: bad interrupt pin %d\n", __func__, pa->pa_intrpin);
955 return 1;
956 }
957 #endif
958
959 pci_decompose_tag(pa->pa_pc, pa->pa_tag, &bus, &dev, &fn);
960 if (pa->pa_bridgetag) {
961 pin = PPB_INTERRUPT_SWIZZLE(pa->pa_rawintrpin, dev);
962 *ihp = pa->pa_bridgeih[pin - 1];
963 } else {
964 if (bus == 0)
965 *ihp = (*bc->bc_intr_map)(dev, fn, pa->pa_intrpin);
966
967 if (*ihp == (pci_intr_handle_t)-1)
968 return 1;
969 }
970
971 return 0;
972 }
973
974 const char *
bonito_pci_intr_string(void * cookie,pci_intr_handle_t ih)975 bonito_pci_intr_string(void *cookie, pci_intr_handle_t ih)
976 {
977 static char irqstr[1 + 12];
978
979 if (BONITO_IRQ_IS_ISA(ih))
980 snprintf(irqstr, sizeof irqstr, "isa irq %lu",
981 BONITO_IRQ_TO_ISA(ih));
982 else
983 snprintf(irqstr, sizeof irqstr, "irq %lu", ih);
984 return irqstr;
985 }
986
987 void *
bonito_pci_intr_establish(void * cookie,pci_intr_handle_t ih,int level,int (* cb)(void *),void * cbarg,char * name)988 bonito_pci_intr_establish(void *cookie, pci_intr_handle_t ih, int level,
989 int (*cb)(void *), void *cbarg, char *name)
990 {
991 return bonito_intr_establish(ih, IST_LEVEL, level, cb, cbarg, name);
992 }
993
994 void
bonito_pci_intr_disestablish(void * cookie,void * ihp)995 bonito_pci_intr_disestablish(void *cookie, void *ihp)
996 {
997 bonito_intr_disestablish(ihp);
998 }
999
1000 /*
1001 * bus_space mapping routines.
1002 */
1003
1004 /*
1005 * Legacy I/O access protection.
1006 * Since MI ISA code does not expect bus access to cause any failure when
1007 * accessing missing hardware, but only receive bogus data in return, we
1008 * force bus_space_map() to fail if there is no hardware there.
1009 */
1010
1011 int
bonito_io_map(bus_space_tag_t t,bus_addr_t offs,bus_size_t size,int flags,bus_space_handle_t * bshp)1012 bonito_io_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size, int flags,
1013 bus_space_handle_t *bshp)
1014 {
1015 const struct legacy_io_range *r;
1016 bus_addr_t rend;
1017
1018 if (offs < BONITO_PCIIO_LEGACY) {
1019 if ((r = sys_platform->legacy_io_ranges) == NULL)
1020 return ENXIO;
1021
1022 rend = offs + size - 1;
1023 for (; r->start != 0; r++)
1024 if (offs >= r->start && rend <= r->end)
1025 break;
1026
1027 if (r->end == 0)
1028 return ENXIO;
1029 }
1030
1031 *bshp = t->bus_base + offs;
1032 return 0;
1033 }
1034
1035 /*
1036 * PCI memory access.
1037 * Things are a bit complicated here, as we can either use one of the 64MB
1038 * windows in PCILO space (making sure ranges spanning multiple windows will
1039 * turn contiguous), or a direct access within the PCIHI space.
1040 * Note that, on 2F systems, only the PCIHI range for which CPU->PCI accesses
1041 * are enabled in the crossbar is usable.
1042 */
1043
1044 int
bonito_mem_map(bus_space_tag_t t,bus_addr_t offs,bus_size_t size,int flags,bus_space_handle_t * bshp)1045 bonito_mem_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size, int flags,
1046 bus_space_handle_t *bshp)
1047 {
1048 uint32_t pcimap;
1049 bus_addr_t pcilo_w[3];
1050 bus_addr_t ws, we, w;
1051 bus_addr_t end = offs + size - 1;
1052 int pcilo_window;
1053
1054 pcimap = REGVAL(BONITO_PCIMAP);
1055
1056 /*
1057 * Try a PCIHI mapping first.
1058 */
1059
1060 if (loongson_ver >= 0x2f) {
1061 if (offs >= LS2F_PCIHI_BASE && end <= LS2F_PCIHI_TOP) {
1062 *bshp = t->bus_base + offs;
1063 return 0;
1064 }
1065 } else {
1066 /*
1067 * Only try HI space if we do not have memory setup there.
1068 */
1069 if (physmem <= atop(BONITO_PCILO_BASE)) {
1070 /* PCI1.5 */
1071 if (offs >= BONITO_PCIHI_BASE &&
1072 end <= BONITO_PCIHI_TOP) {
1073 *bshp = t->bus_base + offs;
1074 return 0;
1075 }
1076
1077 /* PCI2 */
1078 w = pcimap & BONITO_PCIMAP_PCIMAP_2 ? 0x80000000UL : 0;
1079 if (offs >= w && end < (w + 0x80000000UL)) {
1080 *bshp = t->bus_base + 0x80000000UL + (offs - w);
1081 return 0;
1082 }
1083 }
1084 }
1085
1086 /*
1087 * No luck, try a PCILO mapping.
1088 */
1089
1090 /*
1091 * Decode PCIMAP, and figure out what PCILO mappings are
1092 * possible.
1093 */
1094
1095 pcilo_w[0] = (pcimap & BONITO_PCIMAP_PCIMAP_LO0) >>
1096 BONITO_PCIMAP_PCIMAP_LO0_SHIFT;
1097 pcilo_w[1] = (pcimap & BONITO_PCIMAP_PCIMAP_LO1) >>
1098 BONITO_PCIMAP_PCIMAP_LO1_SHIFT;
1099 pcilo_w[2] = (pcimap & BONITO_PCIMAP_PCIMAP_LO2) >>
1100 BONITO_PCIMAP_PCIMAP_LO2_SHIFT;
1101
1102 /*
1103 * Check if the 64MB areas we want to span are all available as
1104 * contiguous PCILO mappings.
1105 */
1106
1107 ws = offs >> 26;
1108 we = end >> 26;
1109
1110 pcilo_window = -1;
1111 if (ws == pcilo_w[0])
1112 pcilo_window = 0;
1113 else if (ws == pcilo_w[1])
1114 pcilo_window = 1;
1115 else if (ws == pcilo_w[2])
1116 pcilo_window = 2;
1117
1118 if (pcilo_window >= 0) {
1119 /* contiguous area test */
1120 for (w = ws + 1; w <= we; w++) {
1121 if (pcilo_window + (w - ws) > 2 ||
1122 w != pcilo_w[pcilo_window + (w - ws)]) {
1123 pcilo_window = -1;
1124 break;
1125 }
1126 }
1127 }
1128
1129 if (pcilo_window >= 0) {
1130 *bshp = t->bus_base + BONITO_PCILO_BASE +
1131 BONITO_PCIMAP_WINBASE(pcilo_window) +
1132 BONITO_PCIMAP_WINOFFSET(offs);
1133 return 0;
1134 }
1135
1136 return EINVAL;
1137 }
1138
1139 /*
1140 * PCI resource handling
1141 */
1142
1143 struct extent *
bonito_get_resource_extent(pci_chipset_tag_t pc,int io)1144 bonito_get_resource_extent(pci_chipset_tag_t pc, int io)
1145 {
1146 struct bonito_softc *sc = pc->pc_conf_v;
1147 struct extent *ex;
1148 char *exname;
1149 size_t exnamesz;
1150 uint32_t reg;
1151 int errors;
1152
1153 exnamesz = 1 + 16 + 4;
1154 exname = (char *)malloc(exnamesz, M_DEVBUF, M_NOWAIT);
1155 if (exname == NULL)
1156 return NULL;
1157 snprintf(exname, exnamesz, "%s%s", sc->sc_dev.dv_xname,
1158 io ? "_io" : "_mem");
1159
1160 ex = extent_create(exname, 0, 0xffffffff, M_DEVBUF, NULL, 0,
1161 EX_NOWAIT | EX_FILLED);
1162 if (ex == NULL)
1163 goto out;
1164
1165 errors = 0;
1166 if (io) {
1167 /*
1168 * Reserve the low 16KB of I/O space to the legacy hardware,
1169 * if any.
1170 */
1171 if (extent_free(ex, BONITO_PCIIO_LEGACY, BONITO_PCIIO_SIZE,
1172 EX_NOWAIT) != 0)
1173 errors++;
1174 } else {
1175 reg = REGVAL(BONITO_PCIMAP);
1176 if (extent_free(ex,
1177 BONITO_PCIMAP_WINBASE((reg & BONITO_PCIMAP_PCIMAP_LO0) >>
1178 BONITO_PCIMAP_PCIMAP_LO0_SHIFT),
1179 BONITO_PCIMAP_WINSIZE, EX_NOWAIT) != 0)
1180 errors++;
1181 if (extent_free(ex,
1182 BONITO_PCIMAP_WINBASE((reg & BONITO_PCIMAP_PCIMAP_LO1) >>
1183 BONITO_PCIMAP_PCIMAP_LO1_SHIFT),
1184 BONITO_PCIMAP_WINSIZE, EX_NOWAIT) != 0)
1185 errors++;
1186 if (extent_free(ex,
1187 BONITO_PCIMAP_WINBASE((reg & BONITO_PCIMAP_PCIMAP_LO2) >>
1188 BONITO_PCIMAP_PCIMAP_LO2_SHIFT),
1189 BONITO_PCIMAP_WINSIZE, EX_NOWAIT) != 0)
1190 errors++;
1191
1192 if (sc->sc_compatible) {
1193 /* XXX make PCIMAP_HI available if PCIMAP_2 set */
1194 }
1195 }
1196
1197 if (errors != 0) {
1198 extent_destroy(ex);
1199 ex = NULL;
1200 }
1201
1202 #ifdef BONITO_DEBUG
1203 extent_print(ex);
1204 #endif
1205
1206 out:
1207 free(exname, M_DEVBUF, exnamesz);
1208
1209 return ex;
1210 }
1211
1212 /*
1213 * Functions used during early system configuration (before bonito attaches).
1214 */
1215
1216 pcitag_t bonito_make_tag_early(int, int, int);
1217 pcireg_t bonito_conf_read_early(pcitag_t, int);
1218
1219 pcitag_t
bonito_make_tag_early(int b,int d,int f)1220 bonito_make_tag_early(int b, int d, int f)
1221 {
1222 return bonito_make_tag(NULL, b, d, f);
1223 }
1224
1225 pcireg_t
bonito_conf_read_early(pcitag_t tag,int reg)1226 bonito_conf_read_early(pcitag_t tag, int reg)
1227 {
1228 return bonito_conf_read_internal(sys_platform->bonito_config, tag, reg);
1229 }
1230
1231 void
bonito_early_setup()1232 bonito_early_setup()
1233 {
1234 pci_make_tag_early = bonito_make_tag_early;
1235 pci_conf_read_early = bonito_conf_read_early;
1236
1237 early_mem_t = &bonito_pci_mem_space_tag;
1238 early_io_t = &bonito_pci_io_space_tag;
1239 }
1240