xref: /openbsd/sys/arch/loongson/dev/bonito.c (revision 85caa4b9)
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