xref: /freebsd/sys/dev/bhnd/bhndb/bhndb_pci.c (revision 4d846d26)
1 /*-
2  * Copyright (c) 2015-2016 Landon Fuller <landon@landonf.org>
3  * Copyright (c) 2017 The FreeBSD Foundation
4  * All rights reserved.
5  *
6  * Portions of this software were developed by Landon Fuller
7  * under sponsorship from the FreeBSD Foundation.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer,
14  *    without modification.
15  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
16  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
17  *    redistribution must be conditioned upon including a substantially
18  *    similar Disclaimer requirement for further binary redistribution.
19  *
20  * NO WARRANTY
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
24  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
25  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
26  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
29  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31  * THE POSSIBILITY OF SUCH DAMAGES.
32  */
33 
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36 
37 /*
38  * PCI-specific implementation for the BHNDB bridge driver.
39  *
40  * Provides support for bridging from a PCI parent bus to a BHND-compatible
41  * bus (e.g. bcma or siba) via a Broadcom PCI core configured in end-point
42  * mode.
43  *
44  * This driver handles all initial generic host-level PCI interactions with a
45  * PCI/PCIe bridge core operating in endpoint mode. Once the bridged bhnd(4)
46  * bus has been enumerated, this driver works in tandem with a core-specific
47  * bhnd_pci_hostb driver to manage the PCI core.
48  */
49 
50 #include <sys/param.h>
51 #include <sys/kernel.h>
52 #include <sys/bus.h>
53 #include <sys/limits.h>
54 #include <sys/malloc.h>
55 #include <sys/module.h>
56 #include <sys/systm.h>
57 
58 #include <dev/pci/pcireg.h>
59 #include <dev/pci/pcivar.h>
60 
61 #include <dev/bhnd/bhnd.h>
62 #include <dev/bhnd/bhndreg.h>
63 
64 #include <dev/bhnd/bhnd_erom.h>
65 #include <dev/bhnd/bhnd_eromvar.h>
66 
67 #include <dev/bhnd/siba/sibareg.h>
68 
69 #include <dev/bhnd/cores/pci/bhnd_pcireg.h>
70 
71 #include "bhnd_pwrctl_hostb_if.h"
72 
73 #include "bhndb_pcireg.h"
74 #include "bhndb_pcivar.h"
75 #include "bhndb_private.h"
76 
77 struct bhndb_pci_eio;
78 struct bhndb_pci_probe;
79 
80 static int		bhndb_pci_alloc_msi(struct bhndb_pci_softc *sc,
81 			    int *msi_count);
82 
83 static int		bhndb_pci_add_children(struct bhndb_pci_softc *sc);
84 
85 static bhnd_devclass_t	bhndb_expected_pci_devclass(device_t dev);
86 static bool		bhndb_is_pcie_attached(device_t dev);
87 
88 static int		bhndb_enable_pci_clocks(device_t dev);
89 static int		bhndb_disable_pci_clocks(device_t dev);
90 
91 static int		bhndb_pci_compat_setregwin(device_t dev,
92 			    device_t pci_dev, const struct bhndb_regwin *,
93 			    bhnd_addr_t);
94 static int		bhndb_pci_fast_setregwin(device_t dev, device_t pci_dev,
95 			    const struct bhndb_regwin *, bhnd_addr_t);
96 
97 static void		bhndb_pci_write_core(struct bhndb_pci_softc *sc,
98 			    bus_size_t offset, uint32_t value, u_int width);
99 static uint32_t		bhndb_pci_read_core(struct bhndb_pci_softc *sc,
100 			    bus_size_t offset, u_int width);
101 
102 static int		bhndb_pci_srsh_pi_war(struct bhndb_pci_softc *sc,
103 			    struct bhndb_pci_probe *probe);
104 
105 static bus_addr_t	bhndb_pci_sprom_addr(struct bhndb_pci_softc *sc);
106 static bus_size_t	bhndb_pci_sprom_size(struct bhndb_pci_softc *sc);
107 
108 static int		bhndb_pci_probe_alloc(struct bhndb_pci_probe **probe,
109 			    device_t dev, bhnd_devclass_t pci_devclass);
110 static void		bhndb_pci_probe_free(struct bhndb_pci_probe *probe);
111 
112 static int		bhndb_pci_probe_copy_core_table(
113 			    struct bhndb_pci_probe *probe,
114 			    struct bhnd_core_info **cores, u_int *ncores);
115 static void		bhndb_pci_probe_free_core_table(
116 			    struct bhnd_core_info *cores);
117 
118 static void		bhndb_pci_probe_write(struct bhndb_pci_probe *sc,
119 			    bhnd_addr_t addr, bhnd_size_t offset,
120 			    uint32_t value, u_int width);
121 static uint32_t		bhndb_pci_probe_read(struct bhndb_pci_probe *sc,
122 			    bhnd_addr_t addr, bhnd_size_t offset, u_int width);
123 
124 static void		bhndb_pci_eio_init(struct bhndb_pci_eio *eio,
125 			    struct bhndb_pci_probe *probe);
126 static int		bhndb_pci_eio_map(struct bhnd_erom_io *eio,
127 			    bhnd_addr_t addr, bhnd_size_t size);
128 static int		bhndb_pci_eio_tell(struct bhnd_erom_io *eio,
129 			    bhnd_addr_t *addr, bhnd_size_t *size);
130 static uint32_t		bhndb_pci_eio_read(struct bhnd_erom_io *eio,
131 			    bhnd_size_t offset, u_int width);
132 
133 #define	BHNDB_PCI_MSI_COUNT	1
134 
135 static struct bhndb_pci_quirk	bhndb_pci_quirks[];
136 static struct bhndb_pci_quirk	bhndb_pcie_quirks[];
137 static struct bhndb_pci_quirk	bhndb_pcie2_quirks[];
138 
139 static struct bhndb_pci_core bhndb_pci_cores[] = {
140 	BHNDB_PCI_CORE(PCI,	bhndb_pci_quirks),
141 	BHNDB_PCI_CORE(PCIE,	bhndb_pcie_quirks),
142 	BHNDB_PCI_CORE(PCIE2,	bhndb_pcie2_quirks),
143 	BHNDB_PCI_CORE_END
144 };
145 
146 /* bhndb_pci erom I/O instance state */
147 struct bhndb_pci_eio {
148 	struct bhnd_erom_io		 eio;
149 	bool				 mapped;	/**< true if a valid mapping exists */
150 	bhnd_addr_t			 addr;		/**< mapped address */
151 	bhnd_size_t			 size;		/**< mapped size */
152 	struct bhndb_pci_probe		*probe;		/**< borrowed probe reference */
153 };
154 
155 /**
156  * Provides early bus access to the bridged device's cores and core enumeration
157  * table.
158  *
159  * May be safely used during probe or early device attach, prior to calling
160  * bhndb_attach().
161  */
162 struct bhndb_pci_probe {
163 	device_t			 dev;		/**< bridge device */
164 	device_t			 pci_dev;	/**< parent PCI device */
165 	struct bhnd_chipid		 cid;		/**< chip identification */
166 	struct bhnd_core_info		 hostb_core;	/**< PCI bridge core info */
167 
168 	struct bhndb_pci_eio		 erom_io;	/**< erom I/O instance */
169 	bhnd_erom_class_t		*erom_class;	/**< probed erom class */
170 	bhnd_erom_t			*erom;		/**< erom parser */
171 	struct bhnd_core_info		*cores;		/**< erom-owned core table */
172 	u_int				 ncores;	/**< number of cores */
173 
174 	const struct bhndb_regwin	*m_win;		/**< mapped register window, or NULL if no mapping */
175 	struct resource			*m_res;		/**< resource containing the register window, or NULL if no window mapped */
176 	bhnd_addr_t			 m_target;	/**< base address mapped by m_win */
177 	bhnd_addr_t			 m_addr;	/**< mapped address */
178 	bhnd_size_t			 m_size;	/**< mapped size */
179 	bool				 m_valid;	/**< true if a valid mapping exists, false otherwise */
180 
181 	struct bhndb_host_resources	*hr;		/**< backing host resources */
182 };
183 
184 static struct bhndb_pci_quirk bhndb_pci_quirks[] = {
185 	/* Backplane interrupt flags must be routed via siba-specific
186 	 * SIBA_CFG0_INTVEC configuration register; the BHNDB_PCI_INT_MASK
187 	 * PCI configuration register is unsupported. */
188 	{{ BHND_MATCH_CHIP_TYPE		(SIBA) },
189 	 { BHND_MATCH_CORE_REV		(HWREV_LTE(5)) },
190 		BHNDB_PCI_QUIRK_SIBA_INTVEC },
191 
192 	/* All PCI core revisions require the SRSH work-around */
193 	BHNDB_PCI_QUIRK(HWREV_ANY,	BHNDB_PCI_QUIRK_SRSH_WAR),
194 	BHNDB_PCI_QUIRK_END
195 };
196 
197 static struct bhndb_pci_quirk bhndb_pcie_quirks[] = {
198 	/* All PCIe-G1 core revisions require the SRSH work-around */
199 	BHNDB_PCI_QUIRK(HWREV_ANY,	BHNDB_PCI_QUIRK_SRSH_WAR),
200 	BHNDB_PCI_QUIRK_END
201 };
202 
203 static struct bhndb_pci_quirk bhndb_pcie2_quirks[] = {
204 	BHNDB_PCI_QUIRK_END
205 };
206 
207 /**
208  * Return the device table entry for @p ci, or NULL if none.
209  */
210 static struct bhndb_pci_core *
211 bhndb_pci_find_core(struct bhnd_core_info *ci)
212 {
213 	for (size_t i = 0; !BHNDB_PCI_IS_CORE_END(&bhndb_pci_cores[i]); i++) {
214 		struct bhndb_pci_core *entry = &bhndb_pci_cores[i];
215 
216 		if (bhnd_core_matches(ci, &entry->match))
217 			return (entry);
218 	}
219 
220 	return (NULL);
221 }
222 
223 /**
224  * Return all quirk flags for the given @p cid and @p ci.
225  */
226 static uint32_t
227 bhndb_pci_get_core_quirks(struct bhnd_chipid *cid, struct bhnd_core_info *ci)
228 {
229 	struct bhndb_pci_core	*entry;
230 	struct bhndb_pci_quirk	*qtable;
231 	uint32_t		 quirks;
232 
233 	quirks = 0;
234 
235 	/* No core entry? */
236 	if ((entry = bhndb_pci_find_core(ci)) == NULL)
237 		return (quirks);
238 
239 	/* No quirks? */
240 	if ((qtable = entry->quirks) == NULL)
241 		return (quirks);
242 
243 	for (size_t i = 0; !BHNDB_PCI_IS_QUIRK_END(&qtable[i]); i++) {
244 		struct bhndb_pci_quirk *q = &qtable[i];
245 
246 		if (!bhnd_chip_matches(cid, &q->chip_desc))
247 			continue;
248 
249 		if (!bhnd_core_matches(ci, &q->core_desc))
250 			continue;
251 
252 		quirks |= q->quirks;
253 	}
254 
255 	return (quirks);
256 }
257 
258 /**
259  * Default bhndb_pci implementation of device_probe().
260  *
261  * Verifies that the parent is a PCI/PCIe device.
262  */
263 static int
264 bhndb_pci_probe(device_t dev)
265 {
266 	struct bhndb_pci_probe	*probe;
267 	struct bhndb_pci_core	*entry;
268 	bhnd_devclass_t		 hostb_devclass;
269 	device_t		 parent, parent_bus;
270 	devclass_t		 pci, bus_devclass;
271 	int			 error;
272 
273 	probe = NULL;
274 
275 	/* Our parent must be a PCI/PCIe device. */
276 	pci = devclass_find("pci");
277 	parent = device_get_parent(dev);
278 	parent_bus = device_get_parent(parent);
279 	if (parent_bus == NULL)
280 		return (ENXIO);
281 
282 	/* The bus device class may inherit from 'pci' */
283 	for (bus_devclass = device_get_devclass(parent_bus);
284 	    bus_devclass != NULL;
285 	    bus_devclass = devclass_get_parent(bus_devclass))
286 	{
287 		if (bus_devclass == pci)
288 			break;
289 	}
290 
291 	if (bus_devclass != pci)
292 		return (ENXIO);
293 
294 	/* Enable clocks */
295 	if ((error = bhndb_enable_pci_clocks(dev)))
296 		return (error);
297 
298 	/* Identify the chip and enumerate the bridged cores */
299 	hostb_devclass = bhndb_expected_pci_devclass(dev);
300 	if ((error = bhndb_pci_probe_alloc(&probe, dev, hostb_devclass)))
301 		goto cleanup;
302 
303 	/* Look for a matching core table entry */
304 	if ((entry = bhndb_pci_find_core(&probe->hostb_core)) == NULL) {
305 		error = ENXIO;
306 		goto cleanup;
307 	}
308 
309 	device_set_desc(dev, "PCI-BHND bridge");
310 
311 	/* fall-through */
312 	error = BUS_PROBE_DEFAULT;
313 
314 cleanup:
315 	if (probe != NULL)
316 		bhndb_pci_probe_free(probe);
317 
318 	bhndb_disable_pci_clocks(dev);
319 
320 	return (error);
321 }
322 
323 /**
324  * Attempt to allocate MSI interrupts, returning the count in @p msi_count
325  * on success.
326  */
327 static int
328 bhndb_pci_alloc_msi(struct bhndb_pci_softc *sc, int *msi_count)
329 {
330 	int error, count;
331 
332 	/* Is MSI available? */
333 	if (pci_msi_count(sc->parent) < BHNDB_PCI_MSI_COUNT)
334 		return (ENXIO);
335 
336 	/* Allocate expected message count */
337 	count = BHNDB_PCI_MSI_COUNT;
338 	if ((error = pci_alloc_msi(sc->parent, &count))) {
339 		device_printf(sc->dev, "failed to allocate MSI interrupts: "
340 		    "%d\n", error);
341 
342 		return (error);
343 	}
344 
345 	if (count < BHNDB_PCI_MSI_COUNT) {
346 		pci_release_msi(sc->parent);
347 		return (ENXIO);
348 	}
349 
350 	*msi_count = count;
351 	return (0);
352 }
353 
354 static int
355 bhndb_pci_attach(device_t dev)
356 {
357 	struct bhndb_pci_softc	*sc;
358 	struct bhnd_chipid	 cid;
359 	struct bhnd_core_info	*cores, hostb_core;
360 	bhnd_erom_class_t	*erom_class;
361 	struct bhndb_pci_probe	*probe;
362 	u_int			 ncores;
363 	int			 irq_rid;
364 	int			 error;
365 
366 	sc = device_get_softc(dev);
367 	sc->dev = dev;
368 	sc->parent = device_get_parent(dev);
369 	sc->pci_devclass = bhndb_expected_pci_devclass(dev);
370 	sc->pci_quirks = 0;
371 	sc->set_regwin = NULL;
372 
373 	BHNDB_PCI_LOCK_INIT(sc);
374 
375 	probe = NULL;
376 	cores = NULL;
377 
378 	/* Enable PCI bus mastering */
379 	pci_enable_busmaster(sc->parent);
380 
381 	/* Enable clocks (if required by this hardware) */
382 	if ((error = bhndb_enable_pci_clocks(sc->dev)))
383 		goto cleanup;
384 
385 	/* Identify the chip and enumerate the bridged cores */
386 	error = bhndb_pci_probe_alloc(&probe, dev, sc->pci_devclass);
387 	if (error)
388 		goto cleanup;
389 
390 	sc->pci_quirks = bhndb_pci_get_core_quirks(&probe->cid,
391 	    &probe->hostb_core);
392 
393 	/* Select the appropriate register window handler */
394 	if (probe->cid.chip_type == BHND_CHIPTYPE_SIBA) {
395 		sc->set_regwin = bhndb_pci_compat_setregwin;
396 	} else {
397 		sc->set_regwin = bhndb_pci_fast_setregwin;
398 	}
399 
400 	/*
401 	 * Fix up our PCI base address in the SPROM shadow, if necessary.
402 	 *
403 	 * This must be done prior to accessing any static register windows
404 	 * that map the PCI core.
405 	 */
406 	if ((error = bhndb_pci_srsh_pi_war(sc, probe)))
407 		goto cleanup;
408 
409 	/* Set up PCI interrupt handling */
410 	if (bhndb_pci_alloc_msi(sc, &sc->msi_count) == 0) {
411 		/* MSI uses resource IDs starting at 1 */
412 		irq_rid = 1;
413 
414 		device_printf(dev, "Using MSI interrupts on %s\n",
415 		    device_get_nameunit(sc->parent));
416 	} else {
417 		sc->msi_count = 0;
418 		irq_rid = 0;
419 
420 		device_printf(dev, "Using INTx interrupts on %s\n",
421 		    device_get_nameunit(sc->parent));
422 	}
423 
424 	sc->isrc = bhndb_alloc_intr_isrc(sc->parent, irq_rid, 0, RM_MAX_END, 1,
425 	    RF_SHAREABLE | RF_ACTIVE);
426 	if (sc->isrc == NULL) {
427 		device_printf(sc->dev, "failed to allocate interrupt "
428 		    "resource\n");
429 		error = ENXIO;
430 		goto cleanup;
431 	}
432 
433 	/*
434 	 * Copy out the probe results and then free our probe state, releasing
435 	 * its exclusive ownership of host bridge resources.
436 	 *
437 	 * This must be done prior to full configuration of the bridge via
438 	 * bhndb_attach().
439 	 */
440 	cid = probe->cid;
441 	erom_class = probe->erom_class;
442 	hostb_core = probe->hostb_core;
443 
444 	error = bhndb_pci_probe_copy_core_table(probe, &cores, &ncores);
445 	if (error) {
446 		cores = NULL;
447 		goto cleanup;
448 	}
449 
450 	bhndb_pci_probe_free(probe);
451 	probe = NULL;
452 
453 	/* Perform bridge attach */
454 	error = bhndb_attach(dev, &cid, cores, ncores, &hostb_core, erom_class);
455 	if (error)
456 		goto cleanup;
457 
458 	/* Add any additional child devices */
459 	if ((error = bhndb_pci_add_children(sc)))
460 		goto cleanup;
461 
462 	/* Probe and attach our children */
463 	if ((error = bus_generic_attach(dev)))
464 		goto cleanup;
465 
466 	bhndb_pci_probe_free_core_table(cores);
467 
468 	return (0);
469 
470 cleanup:
471 	device_delete_children(dev);
472 
473 	if (sc->isrc != NULL)
474 		bhndb_free_intr_isrc(sc->isrc);
475 
476 	if (sc->msi_count > 0)
477 		pci_release_msi(sc->parent);
478 
479 	if (cores != NULL)
480 		bhndb_pci_probe_free_core_table(cores);
481 
482 	if (probe != NULL)
483 		bhndb_pci_probe_free(probe);
484 
485 	bhndb_disable_pci_clocks(sc->dev);
486 
487 	pci_disable_busmaster(sc->parent);
488 
489 	BHNDB_PCI_LOCK_DESTROY(sc);
490 
491 	return (error);
492 }
493 
494 static int
495 bhndb_pci_detach(device_t dev)
496 {
497 	struct bhndb_pci_softc	*sc;
498 	int			 error;
499 
500 	sc = device_get_softc(dev);
501 
502 	/* Attempt to detach our children */
503 	if ((error = bus_generic_detach(dev)))
504 		return (error);
505 
506 	/* Perform generic bridge detach */
507 	if ((error = bhndb_generic_detach(dev)))
508 		return (error);
509 
510 	/* Disable clocks (if required by this hardware) */
511 	if ((error = bhndb_disable_pci_clocks(sc->dev)))
512 		return (error);
513 
514 	/* Free our interrupt resources */
515 	bhndb_free_intr_isrc(sc->isrc);
516 
517 	/* Release MSI interrupts */
518 	if (sc->msi_count > 0)
519 		pci_release_msi(sc->parent);
520 
521 	/* Disable PCI bus mastering */
522 	pci_disable_busmaster(sc->parent);
523 
524 	BHNDB_PCI_LOCK_DESTROY(sc);
525 
526 	return (0);
527 }
528 
529 static int
530 bhndb_pci_add_children(struct bhndb_pci_softc *sc)
531 {
532 	bus_size_t		 nv_sz;
533 	int			 error;
534 
535 	/**
536 	 * If SPROM is mapped directly into BAR0, add child NVRAM
537 	 * device.
538 	 */
539 	nv_sz = bhndb_pci_sprom_size(sc);
540 	if (nv_sz > 0) {
541 		struct bhndb_devinfo	*dinfo;
542 		device_t		 child;
543 
544 		if (bootverbose) {
545 			device_printf(sc->dev, "found SPROM (%ju bytes)\n",
546 			    (uintmax_t)nv_sz);
547 		}
548 
549 		/* Add sprom device, ordered early enough to be available
550 		 * before the bridged bhnd(4) bus is attached. */
551 		child = BUS_ADD_CHILD(sc->dev,
552 		    BHND_PROBE_ROOT + BHND_PROBE_ORDER_EARLY, "bhnd_nvram", -1);
553 		if (child == NULL) {
554 			device_printf(sc->dev, "failed to add sprom device\n");
555 			return (ENXIO);
556 		}
557 
558 		/* Initialize device address space and resource covering the
559 		 * BAR0 SPROM shadow. */
560 		dinfo = device_get_ivars(child);
561 		dinfo->addrspace = BHNDB_ADDRSPACE_NATIVE;
562 
563 		error = bus_set_resource(child, SYS_RES_MEMORY, 0,
564 		    bhndb_pci_sprom_addr(sc), nv_sz);
565 		if (error) {
566 			device_printf(sc->dev,
567 			    "failed to register sprom resources\n");
568 			return (error);
569 		}
570 	}
571 
572 	return (0);
573 }
574 
575 static const struct bhndb_regwin *
576 bhndb_pci_sprom_regwin(struct bhndb_pci_softc *sc)
577 {
578 	struct bhndb_resources		*bres;
579 	const struct bhndb_hwcfg	*cfg;
580 	const struct bhndb_regwin	*sprom_win;
581 
582 	bres = sc->bhndb.bus_res;
583 	cfg = bres->cfg;
584 
585 	sprom_win = bhndb_regwin_find_type(cfg->register_windows,
586 	    BHNDB_REGWIN_T_SPROM, BHNDB_PCI_V0_BAR0_SPROM_SIZE);
587 
588 	return (sprom_win);
589 }
590 
591 static bus_addr_t
592 bhndb_pci_sprom_addr(struct bhndb_pci_softc *sc)
593 {
594 	const struct bhndb_regwin	*sprom_win;
595 	struct resource			*r;
596 
597 	/* Fetch the SPROM register window */
598 	sprom_win = bhndb_pci_sprom_regwin(sc);
599 	KASSERT(sprom_win != NULL, ("requested sprom address on PCI_V2+"));
600 
601 	/* Fetch the associated resource */
602 	r = bhndb_host_resource_for_regwin(sc->bhndb.bus_res->res, sprom_win);
603 	KASSERT(r != NULL, ("missing resource for sprom window\n"));
604 
605 	return (rman_get_start(r) + sprom_win->win_offset);
606 }
607 
608 static bus_size_t
609 bhndb_pci_sprom_size(struct bhndb_pci_softc *sc)
610 {
611 	const struct bhndb_regwin	*sprom_win;
612 	uint32_t			 sctl;
613 	bus_size_t			 sprom_sz;
614 
615 	sprom_win = bhndb_pci_sprom_regwin(sc);
616 
617 	/* PCI_V2 and later devices map SPROM/OTP via ChipCommon */
618 	if (sprom_win == NULL)
619 		return (0);
620 
621 	/* Determine SPROM size */
622 	sctl = pci_read_config(sc->parent, BHNDB_PCI_SPROM_CONTROL, 4);
623 	if (sctl & BHNDB_PCI_SPROM_BLANK)
624 		return (0);
625 
626 	switch (sctl & BHNDB_PCI_SPROM_SZ_MASK) {
627 	case BHNDB_PCI_SPROM_SZ_1KB:
628 		sprom_sz = (1 * 1024);
629 		break;
630 
631 	case BHNDB_PCI_SPROM_SZ_4KB:
632 		sprom_sz = (4 * 1024);
633 		break;
634 
635 	case BHNDB_PCI_SPROM_SZ_16KB:
636 		sprom_sz = (16 * 1024);
637 		break;
638 
639 	case BHNDB_PCI_SPROM_SZ_RESERVED:
640 	default:
641 		device_printf(sc->dev, "invalid PCI sprom size 0x%x\n", sctl);
642 		return (0);
643 	}
644 
645 	/* If the device has a larger SPROM than can be addressed via our SPROM
646 	 * register window, the SPROM image data will still be located within
647 	 * the window's addressable range */
648 	sprom_sz = MIN(sprom_sz, sprom_win->win_size);
649 
650 	return (sprom_sz);
651 }
652 
653 /**
654  * Return the host resource providing a static mapping of the PCI core's
655  * registers.
656  *
657  * @param	sc		bhndb PCI driver state.
658  * @param	offset		The required readable offset within the PCI core
659  *				register block.
660  * @param	size		The required readable size at @p offset.
661  * @param[out]	res		On success, the host resource containing our PCI
662  *				core's register window.
663  * @param[out]	res_offset	On success, the @p offset relative to @p res.
664  *
665  * @retval 0		success
666  * @retval ENXIO	if a valid static register window mapping the PCI core
667  *			registers is not available.
668  */
669 static int
670 bhndb_pci_get_core_regs(struct bhndb_pci_softc *sc, bus_size_t offset,
671     bus_size_t size, struct resource **res, bus_size_t *res_offset)
672 {
673 	const struct bhndb_regwin	*win;
674 	struct resource			*r;
675 
676 	/* Locate the static register window mapping the requested offset */
677 	win = bhndb_regwin_find_core(sc->bhndb.bus_res->cfg->register_windows,
678 	    sc->pci_devclass, 0, BHND_PORT_DEVICE, 0, 0, offset, size);
679 	if (win == NULL) {
680 		device_printf(sc->dev, "missing PCI core register window\n");
681 		return (ENXIO);
682 	}
683 
684 	/* Fetch the resource containing the register window */
685 	r = bhndb_host_resource_for_regwin(sc->bhndb.bus_res->res, win);
686 	if (r == NULL) {
687 		device_printf(sc->dev, "missing PCI core register resource\n");
688 		return (ENXIO);
689 	}
690 
691 	KASSERT(offset >= win->d.core.offset, ("offset %#jx outside of "
692 	    "register window", (uintmax_t)offset));
693 
694 	*res = r;
695 	*res_offset = win->win_offset + (offset - win->d.core.offset);
696 
697 	return (0);
698 }
699 
700 /**
701  * Write a 1, 2, or 4 byte data item to the PCI core's registers at @p offset.
702  *
703  * @param sc		bhndb PCI driver state.
704  * @param offset	register write offset.
705  * @param value		value to be written.
706  * @param width		item width (1, 2, or 4 bytes).
707  */
708 static void
709 bhndb_pci_write_core(struct bhndb_pci_softc *sc, bus_size_t offset,
710     uint32_t value, u_int width)
711 {
712 	struct resource	*r;
713 	bus_size_t	 r_offset;
714 	int		 error;
715 
716 	error = bhndb_pci_get_core_regs(sc, offset, width, &r, &r_offset);
717 	if (error) {
718 		panic("no PCI register window mapping %#jx+%#x: %d",
719 		    (uintmax_t)offset, width, error);
720 	}
721 
722 	switch (width) {
723 	case 1:
724 		bus_write_1(r, r_offset, value);
725 		break;
726 	case 2:
727 		bus_write_2(r, r_offset, value);
728 		break;
729 	case 4:
730 		bus_write_4(r, r_offset, value);
731 		break;
732 	default:
733 		panic("invalid width: %u", width);
734 	}
735 }
736 
737 /**
738  * Read a 1, 2, or 4 byte data item from the PCI core's registers
739  * at @p offset.
740  *
741  * @param sc		bhndb PCI driver state.
742  * @param offset	register read offset.
743  * @param width		item width (1, 2, or 4 bytes).
744  */
745 static uint32_t
746 bhndb_pci_read_core(struct bhndb_pci_softc *sc, bus_size_t offset, u_int width)
747 {
748 	struct resource	*r;
749 	bus_size_t	 r_offset;
750 	int		 error;
751 
752 	error = bhndb_pci_get_core_regs(sc, offset, width, &r, &r_offset);
753 	if (error) {
754 		panic("no PCI register window mapping %#jx+%#x: %d",
755 		    (uintmax_t)offset, width, error);
756 	}
757 
758 	switch (width) {
759 	case 1:
760 		return (bus_read_1(r, r_offset));
761 	case 2:
762 		return (bus_read_2(r, r_offset));
763 	case 4:
764 		return (bus_read_4(r, r_offset));
765 	default:
766 		panic("invalid width: %u", width);
767 	}
768 }
769 
770 /**
771  * Fix-up power on defaults for SPROM-less devices.
772  *
773  * On SPROM-less devices, the PCI(e) cores will be initialized with their their
774  * Power-on-Reset defaults; this can leave the BHND_PCI_SRSH_PI value pointing
775  * to the wrong backplane address. This value is used by the PCI core when
776  * performing address translation between static register windows in BAR0 that
777  * map the PCI core's register block, and backplane address space.
778  *
779  * When translating accesses via these BAR0 regions, the PCI bridge determines
780  * the base address of the PCI core by concatenating:
781  *
782  *	[bits]	[source]
783  *	31:16	bits [31:16] of the enumeration space address (e.g. 0x18000000)
784  *	15:12	value of BHND_PCI_SRSH_PI from the PCI core's SPROM shadow
785  *	11:0	bits [11:0] of the PCI bus address
786  *
787  * For example, on a PCI_V0 device, the following PCI core register offsets are
788  * mapped into BAR0:
789  *
790  *	[BAR0 offset]		[description]		[PCI core offset]
791  *	0x1000-0x17FF		sprom shadow		0x800-0xFFF
792  *	0x1800-0x1DFF		device registers	0x000-0x5FF
793  *	0x1E00+0x1FFF		siba config registers	0xE00-0xFFF
794  *
795  * This function checks -- and if necessary, corrects -- the BHND_PCI_SRSH_PI
796  * value in the SPROM shadow.
797  *
798  * This workaround must applied prior to accessing any static register windows
799  * that map the PCI core.
800  *
801  * Applies to all PCI and PCIe-G1 core revisions.
802  */
803 static int
804 bhndb_pci_srsh_pi_war(struct bhndb_pci_softc *sc,
805     struct bhndb_pci_probe *probe)
806 {
807 	struct bhnd_core_match	md;
808 	bhnd_addr_t		pci_addr;
809 	bhnd_size_t		pci_size;
810 	bus_size_t		srsh_offset;
811 	uint16_t		srsh_val, pci_val;
812 	uint16_t		val;
813 	int			error;
814 
815 	if ((sc->pci_quirks & BHNDB_PCI_QUIRK_SRSH_WAR) == 0)
816 		return (0);
817 
818 	/* Use an equality match descriptor to look up our PCI core's base
819 	 * address in the EROM */
820 	md = bhnd_core_get_match_desc(&probe->hostb_core);
821 	error = bhnd_erom_lookup_core_addr(probe->erom, &md, BHND_PORT_DEVICE,
822 	    0, 0, NULL, &pci_addr, &pci_size);
823 	if (error) {
824 		device_printf(sc->dev, "no base address found for the PCI host "
825 		    "bridge core: %d\n", error);
826 		return (error);
827 	}
828 
829 	/* Fetch the SPROM SRSH_PI value */
830 	srsh_offset = BHND_PCI_SPROM_SHADOW + BHND_PCI_SRSH_PI_OFFSET;
831 	val = bhndb_pci_probe_read(probe, pci_addr, srsh_offset, sizeof(val));
832 	srsh_val = (val & BHND_PCI_SRSH_PI_MASK) >> BHND_PCI_SRSH_PI_SHIFT;
833 
834 	/* If it doesn't match PCI core's base address, update the SPROM
835 	 * shadow */
836 	pci_val = (pci_addr & BHND_PCI_SRSH_PI_ADDR_MASK) >>
837 	    BHND_PCI_SRSH_PI_ADDR_SHIFT;
838 	if (srsh_val != pci_val) {
839 		val &= ~BHND_PCI_SRSH_PI_MASK;
840 		val |= (pci_val << BHND_PCI_SRSH_PI_SHIFT);
841 		bhndb_pci_probe_write(probe, pci_addr, srsh_offset, val,
842 		    sizeof(val));
843 	}
844 
845 	return (0);
846 }
847 
848 static int
849 bhndb_pci_resume(device_t dev)
850 {
851 	struct bhndb_pci_softc	*sc;
852 	int			 error;
853 
854 	sc = device_get_softc(dev);
855 
856 	/* Enable clocks (if supported by this hardware) */
857 	if ((error = bhndb_enable_pci_clocks(sc->dev)))
858 		return (error);
859 
860 	/* Perform resume */
861 	return (bhndb_generic_resume(dev));
862 }
863 
864 static int
865 bhndb_pci_suspend(device_t dev)
866 {
867 	struct bhndb_pci_softc	*sc;
868 	int			 error;
869 
870 	sc = device_get_softc(dev);
871 
872 	/* Disable clocks (if supported by this hardware) */
873 	if ((error = bhndb_disable_pci_clocks(sc->dev)))
874 		return (error);
875 
876 	/* Perform suspend */
877 	return (bhndb_generic_suspend(dev));
878 }
879 
880 static int
881 bhndb_pci_set_window_addr(device_t dev, const struct bhndb_regwin *rw,
882     bhnd_addr_t addr)
883 {
884 	struct bhndb_pci_softc *sc = device_get_softc(dev);
885 	return (sc->set_regwin(sc->dev, sc->parent, rw, addr));
886 }
887 
888 /**
889  * A siba(4) and bcma(4)-compatible bhndb_set_window_addr implementation.
890  *
891  * On siba(4) devices, it's possible that writing a PCI window register may
892  * not succeed; it's necessary to immediately read the configuration register
893  * and retry if not set to the desired value.
894  *
895  * This is not necessary on bcma(4) devices, but other than the overhead of
896  * validating the register, there's no harm in performing the verification.
897  */
898 static int
899 bhndb_pci_compat_setregwin(device_t dev, device_t pci_dev,
900     const struct bhndb_regwin *rw, bhnd_addr_t addr)
901 {
902 	int		error;
903 	int		reg;
904 
905 	if (rw->win_type != BHNDB_REGWIN_T_DYN)
906 		return (ENODEV);
907 
908 	reg = rw->d.dyn.cfg_offset;
909 	for (u_int i = 0; i < BHNDB_PCI_BARCTRL_WRITE_RETRY; i++) {
910 		if ((error = bhndb_pci_fast_setregwin(dev, pci_dev, rw, addr)))
911 			return (error);
912 
913 		if (pci_read_config(pci_dev, reg, 4) == addr)
914 			return (0);
915 
916 		DELAY(10);
917 	}
918 
919 	/* Unable to set window */
920 	return (ENODEV);
921 }
922 
923 /**
924  * A bcma(4)-only bhndb_set_window_addr implementation.
925  */
926 static int
927 bhndb_pci_fast_setregwin(device_t dev, device_t pci_dev,
928     const struct bhndb_regwin *rw, bhnd_addr_t addr)
929 {
930 	/* The PCI bridge core only supports 32-bit addressing, regardless
931 	 * of the bus' support for 64-bit addressing */
932 	if (addr > UINT32_MAX)
933 		return (ERANGE);
934 
935 	switch (rw->win_type) {
936 	case BHNDB_REGWIN_T_DYN:
937 		/* Addresses must be page aligned */
938 		if (addr % rw->win_size != 0)
939 			return (EINVAL);
940 
941 		pci_write_config(pci_dev, rw->d.dyn.cfg_offset, addr, 4);
942 		break;
943 	default:
944 		return (ENODEV);
945 	}
946 
947 	return (0);
948 }
949 
950 static int
951 bhndb_pci_populate_board_info(device_t dev, device_t child,
952     struct bhnd_board_info *info)
953 {
954 	struct bhndb_pci_softc	*sc;
955 
956 	sc = device_get_softc(dev);
957 
958 	/*
959 	 * On a subset of Apple BCM4360 modules, always prefer the
960 	 * PCI subdevice to the SPROM-supplied boardtype.
961 	 *
962 	 * TODO:
963 	 *
964 	 * Broadcom's own drivers implement this override, and then later use
965 	 * the remapped BCM4360 board type to determine the required
966 	 * board-specific workarounds.
967 	 *
968 	 * Without access to this hardware, it's unclear why this mapping
969 	 * is done, and we must do the same. If we can survey the hardware
970 	 * in question, it may be possible to replace this behavior with
971 	 * explicit references to the SPROM-supplied boardtype(s) in our
972 	 * quirk definitions.
973 	 */
974 	if (pci_get_subvendor(sc->parent) == PCI_VENDOR_APPLE) {
975 		switch (info->board_type) {
976 		case BHND_BOARD_BCM94360X29C:
977 		case BHND_BOARD_BCM94360X29CP2:
978 		case BHND_BOARD_BCM94360X51:
979 		case BHND_BOARD_BCM94360X51P2:
980 			info->board_type = 0;	/* allow override below */
981 			break;
982 		default:
983 			break;
984 		}
985 	}
986 
987 	/* If NVRAM did not supply vendor/type/devid info, provide the PCI
988 	 * subvendor/subdevice/device values. */
989 	if (info->board_vendor == 0)
990 		info->board_vendor = pci_get_subvendor(sc->parent);
991 
992 	if (info->board_type == 0)
993 		info->board_type = pci_get_subdevice(sc->parent);
994 
995 	if (info->board_devid == 0)
996 		info->board_devid = pci_get_device(sc->parent);
997 
998 	return (0);
999 }
1000 
1001 /**
1002  * Examine the bridge device @p dev and return the expected host bridge
1003  * device class.
1004  *
1005  * @param dev The bhndb bridge device
1006  */
1007 static bhnd_devclass_t
1008 bhndb_expected_pci_devclass(device_t dev)
1009 {
1010 	if (bhndb_is_pcie_attached(dev))
1011 		return (BHND_DEVCLASS_PCIE);
1012 	else
1013 		return (BHND_DEVCLASS_PCI);
1014 }
1015 
1016 /**
1017  * Return true if the bridge device @p dev is attached via PCIe,
1018  * false otherwise.
1019  *
1020  * @param dev The bhndb bridge device
1021  */
1022 static bool
1023 bhndb_is_pcie_attached(device_t dev)
1024 {
1025 	int reg;
1026 
1027 	if (pci_find_cap(device_get_parent(dev), PCIY_EXPRESS, &reg) == 0)
1028 		return (true);
1029 
1030 	return (false);
1031 }
1032 
1033 /**
1034  * Enable externally managed clocks, if required.
1035  *
1036  * Some PCI chipsets (BCM4306, possibly others) chips do not support
1037  * the idle low-power clock. Clocking must be bootstrapped at
1038  * attach/resume by directly adjusting GPIO registers exposed in the
1039  * PCI config space, and correspondingly, explicitly shutdown at
1040  * detach/suspend.
1041  *
1042  * @note This function may be safely called prior to device attach, (e.g.
1043  * from DEVICE_PROBE).
1044  *
1045  * @param dev The bhndb bridge device
1046  */
1047 static int
1048 bhndb_enable_pci_clocks(device_t dev)
1049 {
1050 	device_t		pci_dev;
1051 	uint32_t		gpio_in, gpio_out, gpio_en;
1052 	uint32_t		gpio_flags;
1053 	uint16_t		pci_status;
1054 
1055 	pci_dev = device_get_parent(dev);
1056 
1057 	/* Only supported and required on PCI devices */
1058 	if (bhndb_is_pcie_attached(dev))
1059 		return (0);
1060 
1061 	/* Read state of XTAL pin */
1062 	gpio_in = pci_read_config(pci_dev, BHNDB_PCI_GPIO_IN, 4);
1063 	if (gpio_in & BHNDB_PCI_GPIO_XTAL_ON)
1064 		return (0); /* already enabled */
1065 
1066 	/* Fetch current config */
1067 	gpio_out = pci_read_config(pci_dev, BHNDB_PCI_GPIO_OUT, 4);
1068 	gpio_en = pci_read_config(pci_dev, BHNDB_PCI_GPIO_OUTEN, 4);
1069 
1070 	/* Set PLL_OFF/XTAL_ON pins to HIGH and enable both pins */
1071 	gpio_flags = (BHNDB_PCI_GPIO_PLL_OFF|BHNDB_PCI_GPIO_XTAL_ON);
1072 	gpio_out |= gpio_flags;
1073 	gpio_en |= gpio_flags;
1074 
1075 	pci_write_config(pci_dev, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
1076 	pci_write_config(pci_dev, BHNDB_PCI_GPIO_OUTEN, gpio_en, 4);
1077 	DELAY(1000);
1078 
1079 	/* Reset PLL_OFF */
1080 	gpio_out &= ~BHNDB_PCI_GPIO_PLL_OFF;
1081 	pci_write_config(pci_dev, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
1082 	DELAY(5000);
1083 
1084 	/* Clear any PCI 'sent target-abort' flag. */
1085 	pci_status = pci_read_config(pci_dev, PCIR_STATUS, 2);
1086 	pci_status &= ~PCIM_STATUS_STABORT;
1087 	pci_write_config(pci_dev, PCIR_STATUS, pci_status, 2);
1088 
1089 	return (0);
1090 }
1091 
1092 /**
1093  * Disable externally managed clocks, if required.
1094  *
1095  * This function may be safely called prior to device attach, (e.g.
1096  * from DEVICE_PROBE).
1097  *
1098  * @param dev The bhndb bridge device
1099  */
1100 static int
1101 bhndb_disable_pci_clocks(device_t dev)
1102 {
1103 	device_t	pci_dev;
1104 	uint32_t	gpio_out, gpio_en;
1105 
1106 	pci_dev = device_get_parent(dev);
1107 
1108 	/* Only supported and required on PCI devices */
1109 	if (bhndb_is_pcie_attached(dev))
1110 		return (0);
1111 
1112 	/* Fetch current config */
1113 	gpio_out = pci_read_config(pci_dev, BHNDB_PCI_GPIO_OUT, 4);
1114 	gpio_en = pci_read_config(pci_dev, BHNDB_PCI_GPIO_OUTEN, 4);
1115 
1116 	/* Set PLL_OFF to HIGH, XTAL_ON to LOW. */
1117 	gpio_out &= ~BHNDB_PCI_GPIO_XTAL_ON;
1118 	gpio_out |= BHNDB_PCI_GPIO_PLL_OFF;
1119 	pci_write_config(pci_dev, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
1120 
1121 	/* Enable both output pins */
1122 	gpio_en |= (BHNDB_PCI_GPIO_PLL_OFF|BHNDB_PCI_GPIO_XTAL_ON);
1123 	pci_write_config(pci_dev, BHNDB_PCI_GPIO_OUTEN, gpio_en, 4);
1124 
1125 	return (0);
1126 }
1127 
1128 static bhnd_clksrc
1129 bhndb_pci_pwrctl_get_clksrc(device_t dev, device_t child,
1130 	bhnd_clock clock)
1131 {
1132 	struct bhndb_pci_softc	*sc;
1133 	uint32_t		 gpio_out;
1134 
1135 	sc = device_get_softc(dev);
1136 
1137 	/* Only supported on PCI devices */
1138 	if (bhndb_is_pcie_attached(sc->dev))
1139 		return (BHND_CLKSRC_UNKNOWN);
1140 
1141 	/* Only ILP is supported */
1142 	if (clock != BHND_CLOCK_ILP)
1143 		return (BHND_CLKSRC_UNKNOWN);
1144 
1145 	gpio_out = pci_read_config(sc->parent, BHNDB_PCI_GPIO_OUT, 4);
1146 	if (gpio_out & BHNDB_PCI_GPIO_SCS)
1147 		return (BHND_CLKSRC_PCI);
1148 	else
1149 		return (BHND_CLKSRC_XTAL);
1150 }
1151 
1152 static int
1153 bhndb_pci_pwrctl_gate_clock(device_t dev, device_t child,
1154 	bhnd_clock clock)
1155 {
1156 	struct bhndb_pci_softc *sc = device_get_softc(dev);
1157 
1158 	/* Only supported on PCI devices */
1159 	if (bhndb_is_pcie_attached(sc->dev))
1160 		return (ENODEV);
1161 
1162 	/* Only HT is supported */
1163 	if (clock != BHND_CLOCK_HT)
1164 		return (ENXIO);
1165 
1166 	return (bhndb_disable_pci_clocks(sc->dev));
1167 }
1168 
1169 static int
1170 bhndb_pci_pwrctl_ungate_clock(device_t dev, device_t child,
1171 	bhnd_clock clock)
1172 {
1173 	struct bhndb_pci_softc *sc = device_get_softc(dev);
1174 
1175 	/* Only supported on PCI devices */
1176 	if (bhndb_is_pcie_attached(sc->dev))
1177 		return (ENODEV);
1178 
1179 	/* Only HT is supported */
1180 	if (clock != BHND_CLOCK_HT)
1181 		return (ENXIO);
1182 
1183 	return (bhndb_enable_pci_clocks(sc->dev));
1184 }
1185 
1186 /**
1187  * BHNDB_MAP_INTR_ISRC()
1188  */
1189 static int
1190 bhndb_pci_map_intr_isrc(device_t dev, struct resource *irq,
1191     struct bhndb_intr_isrc **isrc)
1192 {
1193 	struct bhndb_pci_softc *sc = device_get_softc(dev);
1194 
1195 	/* There's only one bridged interrupt to choose from */
1196 	*isrc = sc->isrc;
1197 	return (0);
1198 }
1199 
1200 /* siba-specific implementation of BHNDB_ROUTE_INTERRUPTS() */
1201 static int
1202 bhndb_pci_route_siba_interrupts(struct bhndb_pci_softc *sc, device_t child)
1203 {
1204 	uint32_t	sbintvec;
1205 	u_int		ivec;
1206 	int		error;
1207 
1208 	KASSERT(sc->pci_quirks & BHNDB_PCI_QUIRK_SIBA_INTVEC,
1209 	    ("route_siba_interrupts not supported by this hardware"));
1210 
1211 	/* Fetch the sbflag# for the child */
1212 	if ((error = bhnd_get_intr_ivec(child, 0, &ivec)))
1213 		return (error);
1214 
1215 	if (ivec > (sizeof(sbintvec)*8) - 1 /* aka '31' */) {
1216 		/* This should never be an issue in practice */
1217 		device_printf(sc->dev, "cannot route interrupts to high "
1218 		    "sbflag# %u\n", ivec);
1219 		return (ENXIO);
1220 	}
1221 
1222 	BHNDB_PCI_LOCK(sc);
1223 
1224 	sbintvec = bhndb_pci_read_core(sc, SB0_REG_ABS(SIBA_CFG0_INTVEC), 4);
1225 	sbintvec |= (1 << ivec);
1226 	bhndb_pci_write_core(sc, SB0_REG_ABS(SIBA_CFG0_INTVEC), sbintvec, 4);
1227 
1228 	BHNDB_PCI_UNLOCK(sc);
1229 
1230 	return (0);
1231 }
1232 
1233 /* BHNDB_ROUTE_INTERRUPTS() */
1234 static int
1235 bhndb_pci_route_interrupts(device_t dev, device_t child)
1236 {
1237 	struct bhndb_pci_softc	*sc;
1238 	struct bhnd_core_info	 core;
1239 	uint32_t		 core_bit;
1240 	uint32_t		 intmask;
1241 
1242 	sc = device_get_softc(dev);
1243 
1244 	if (sc->pci_quirks & BHNDB_PCI_QUIRK_SIBA_INTVEC)
1245 		return (bhndb_pci_route_siba_interrupts(sc, child));
1246 
1247 	core = bhnd_get_core_info(child);
1248 	if (core.core_idx > BHNDB_PCI_SBIM_COREIDX_MAX) {
1249 		/* This should never be an issue in practice */
1250 		device_printf(dev, "cannot route interrupts to high core "
1251 		    "index %u\n", core.core_idx);
1252 		return (ENXIO);
1253 	}
1254 
1255 	BHNDB_PCI_LOCK(sc);
1256 
1257 	core_bit = (1<<core.core_idx) << BHNDB_PCI_SBIM_SHIFT;
1258 	intmask = pci_read_config(sc->parent, BHNDB_PCI_INT_MASK, 4);
1259 	intmask |= core_bit;
1260 	pci_write_config(sc->parent, BHNDB_PCI_INT_MASK, intmask, 4);
1261 
1262 	BHNDB_PCI_UNLOCK(sc);
1263 
1264 	return (0);
1265 }
1266 
1267 /**
1268  * Using the generic PCI bridge hardware configuration, allocate, initialize
1269  * and return a new bhndb_pci probe state instance.
1270  *
1271  * On success, the caller assumes ownership of the returned probe instance, and
1272  * is responsible for releasing this reference using bhndb_pci_probe_free().
1273  *
1274  * @param[out]	probe		On success, the newly allocated probe instance.
1275  * @param	dev		The bhndb_pci bridge device.
1276  * @param	hostb_devclass	The expected device class of the bridge core.
1277  *
1278  * @retval 0		success
1279  * @retval non-zero	if allocating the probe state fails, a regular
1280  * 			unix error code will be returned.
1281  *
1282  * @note This function requires exclusive ownership over allocating and
1283  * configuring host bridge resources, and should only be called prior to
1284  * completion of device attach and full configuration of the bridge.
1285  */
1286 static int
1287 bhndb_pci_probe_alloc(struct bhndb_pci_probe **probe, device_t dev,
1288     bhnd_devclass_t hostb_devclass)
1289 {
1290 	struct bhndb_pci_probe		*p;
1291 	struct bhnd_erom_io		*eio;
1292 	const struct bhndb_hwcfg	*hwcfg;
1293 	const struct bhnd_chipid	*hint;
1294 	device_t			 parent_dev;
1295 	int				 error;
1296 
1297 	parent_dev = device_get_parent(dev);
1298 	eio = NULL;
1299 
1300 	p = malloc(sizeof(*p), M_BHND, M_ZERO|M_WAITOK);
1301 	p->dev = dev;
1302 	p->pci_dev = parent_dev;
1303 
1304 	/* Our register window mapping state must be initialized at this point,
1305 	 * as bhndb_pci_eio will begin making calls into
1306 	 * bhndb_pci_probe_(read|write|get_mapping) */
1307 	p->m_win = NULL;
1308 	p->m_res = NULL;
1309 	p->m_valid = false;
1310 
1311 	bhndb_pci_eio_init(&p->erom_io, p);
1312 	eio = &p->erom_io.eio;
1313 
1314 	/* Fetch our chipid hint (if any) and generic hardware configuration */
1315 	hwcfg = BHNDB_BUS_GET_GENERIC_HWCFG(parent_dev, dev);
1316 	hint = BHNDB_BUS_GET_CHIPID(parent_dev, dev);
1317 
1318 	/* Allocate our host resources */
1319 	error = bhndb_alloc_host_resources(&p->hr, dev, parent_dev, hwcfg);
1320 	if (error) {
1321 		p->hr = NULL;
1322 		goto failed;
1323 	}
1324 
1325 	/* Map the first bus core from our bridged bhnd(4) bus */
1326 	error = bhnd_erom_io_map(eio, BHND_DEFAULT_CHIPC_ADDR,
1327 	    BHND_DEFAULT_CORE_SIZE);
1328 	if (error)
1329 		goto failed;
1330 
1331 	/* Probe for a usable EROM class, and read the chip identifier */
1332 	p->erom_class = bhnd_erom_probe_driver_classes(
1333 	    device_get_devclass(dev), eio, hint, &p->cid);
1334 	if (p->erom_class == NULL) {
1335 		device_printf(dev, "device enumeration unsupported; no "
1336 		    "compatible driver found\n");
1337 
1338 		error = ENXIO;
1339 		goto failed;
1340 	}
1341 
1342 	/* Allocate EROM parser */
1343 	p->erom = bhnd_erom_alloc(p->erom_class, &p->cid, eio);
1344 	if (p->erom == NULL) {
1345 		device_printf(dev, "failed to allocate device enumeration "
1346 		    "table parser\n");
1347 		error = ENXIO;
1348 		goto failed;
1349 	}
1350 
1351 	/* The EROM I/O instance is now owned by our EROM parser */
1352 	eio = NULL;
1353 
1354 	/* Read the full core table */
1355 	error = bhnd_erom_get_core_table(p->erom, &p->cores, &p->ncores);
1356 	if (error) {
1357 		device_printf(p->dev, "error fetching core table: %d\n",
1358 		    error);
1359 
1360 		p->cores = NULL;
1361 		goto failed;
1362 	}
1363 
1364 	/* Identify the host bridge core */
1365 	error = bhndb_find_hostb_core(p->cores, p->ncores, hostb_devclass,
1366 	    &p->hostb_core);
1367 	if (error) {
1368 		device_printf(dev, "failed to identify the host bridge "
1369 		    "core: %d\n", error);
1370 
1371 		goto failed;
1372 	}
1373 
1374 	*probe = p;
1375 	return (0);
1376 
1377 failed:
1378 	if (eio != NULL) {
1379 		KASSERT(p->erom == NULL, ("I/O instance will be freed by "
1380 		    "its owning parser"));
1381 
1382 		bhnd_erom_io_fini(eio);
1383 	}
1384 
1385 	if (p->erom != NULL) {
1386 		if (p->cores != NULL)
1387 			bhnd_erom_free_core_table(p->erom, p->cores);
1388 
1389 		bhnd_erom_free(p->erom);
1390 	} else {
1391 		KASSERT(p->cores == NULL, ("cannot free erom-owned core table "
1392 		    "without erom reference"));
1393 	}
1394 
1395 	if (p->hr != NULL)
1396 		bhndb_release_host_resources(p->hr);
1397 
1398 	free(p, M_BHND);
1399 
1400 	return (error);
1401 }
1402 
1403 /**
1404  * Free the given @p probe instance and any associated host bridge resources.
1405  */
1406 static void
1407 bhndb_pci_probe_free(struct bhndb_pci_probe *probe)
1408 {
1409 	bhnd_erom_free_core_table(probe->erom, probe->cores);
1410 	bhnd_erom_free(probe->erom);
1411 	bhndb_release_host_resources(probe->hr);
1412 	free(probe, M_BHND);
1413 }
1414 
1415 /**
1416  * Return a copy of probed core table from @p probe.
1417  *
1418  * @param	probe		The probe instance.
1419  * @param[out]	cores		On success, a copy of the probed core table. The
1420  *				caller is responsible for freeing this table
1421  *				bhndb_pci_probe_free_core_table().
1422  * @param[out]	ncores		On success, the number of cores found in
1423  *				@p cores.
1424  *
1425  * @retval 0		success
1426  * @retval non-zero	if enumerating the bridged bhnd(4) bus fails, a regular
1427  * 			unix error code will be returned.
1428  */
1429 static int
1430 bhndb_pci_probe_copy_core_table(struct bhndb_pci_probe *probe,
1431     struct bhnd_core_info **cores, u_int *ncores)
1432 {
1433 	size_t len = sizeof(**cores) * probe->ncores;
1434 
1435 	*cores = malloc(len, M_BHND, M_WAITOK);
1436 	memcpy(*cores, probe->cores, len);
1437 
1438 	*ncores = probe->ncores;
1439 
1440 	return (0);
1441 }
1442 
1443 /**
1444  * Free a core table previously returned by bhndb_pci_probe_copy_core_table().
1445  *
1446  * @param cores The core table to be freed.
1447  */
1448 static void
1449 bhndb_pci_probe_free_core_table(struct bhnd_core_info *cores)
1450 {
1451 	free(cores, M_BHND);
1452 }
1453 
1454 /**
1455  * Return true if @p addr and @p size are mapped by the dynamic register window
1456  * backing @p probe.
1457  */
1458 static bool
1459 bhndb_pci_probe_has_mapping(struct bhndb_pci_probe *probe, bhnd_addr_t addr,
1460     bhnd_size_t size)
1461 {
1462 	if (!probe->m_valid)
1463 		return (false);
1464 
1465 	KASSERT(probe->m_win != NULL, ("missing register window"));
1466 	KASSERT(probe->m_res != NULL, ("missing regwin resource"));
1467 	KASSERT(probe->m_win->win_type == BHNDB_REGWIN_T_DYN,
1468 	    ("unexpected window type %d", probe->m_win->win_type));
1469 
1470 	if (addr < probe->m_target)
1471 		return (false);
1472 
1473 	if (addr >= probe->m_target + probe->m_win->win_size)
1474 		return (false);
1475 
1476 	if ((probe->m_target + probe->m_win->win_size) - addr < size)
1477 		return (false);
1478 
1479 	return (true);
1480 }
1481 
1482 /**
1483  * Attempt to adjust the dynamic register window backing @p probe to permit
1484  * accessing @p size bytes at @p addr.
1485  *
1486  * @param	probe		The bhndb_pci probe state to be modified.
1487  * @param	addr		The address at which @p size bytes will mapped.
1488  * @param	size		The number of bytes to be mapped.
1489  * @param[out]	res		On success, will be set to the host resource
1490  *				mapping @p size bytes at @p addr.
1491  * @param[out]	res_offset	On success, will be set to the offset of @addr
1492  *				within @p res.
1493  *
1494  * @retval 0		success
1495  * @retval non-zero	if an error occurs adjusting the backing dynamic
1496  *			register window.
1497  */
1498 static int
1499 bhndb_pci_probe_map(struct bhndb_pci_probe *probe, bhnd_addr_t addr,
1500     bhnd_size_t offset, bhnd_size_t size, struct resource **res,
1501     bus_size_t *res_offset)
1502 {
1503 	const struct bhndb_regwin	*regwin, *regwin_table;
1504 	struct resource			*regwin_res;
1505 	bhnd_addr_t			 target;
1506 	int				 error;
1507 
1508 	/* Determine the absolute address */
1509 	if (BHND_SIZE_MAX - offset < addr) {
1510 		device_printf(probe->dev, "invalid offset %#jx+%#jx\n", addr,
1511 		    offset);
1512 		return (ENXIO);
1513 	}
1514 
1515 	addr += offset;
1516 
1517 	/* Can we use the existing mapping? */
1518 	if (bhndb_pci_probe_has_mapping(probe, addr, size)) {
1519 		*res = probe->m_res;
1520 		*res_offset = (addr - probe->m_target) +
1521 		    probe->m_win->win_offset;
1522 
1523 		return (0);
1524 	}
1525 
1526 	/* Locate a useable dynamic register window */
1527 	regwin_table = probe->hr->cfg->register_windows;
1528 	regwin = bhndb_regwin_find_type(regwin_table,
1529 	    BHNDB_REGWIN_T_DYN, size);
1530 	if (regwin == NULL) {
1531 		device_printf(probe->dev, "unable to map %#jx+%#jx; no "
1532 		    "usable dynamic register window found\n", addr,
1533 		    size);
1534 		return (ENXIO);
1535 	}
1536 
1537 	/* Locate the host resource mapping our register window */
1538 	regwin_res = bhndb_host_resource_for_regwin(probe->hr, regwin);
1539 	if (regwin_res == NULL) {
1540 		device_printf(probe->dev, "unable to map %#jx+%#jx; no "
1541 		    "usable register resource found\n", addr, size);
1542 		return (ENXIO);
1543 	}
1544 
1545 	/* Page-align the target address */
1546 	target = addr - (addr % regwin->win_size);
1547 
1548 	/* Configure the register window */
1549 	error = bhndb_pci_compat_setregwin(probe->dev, probe->pci_dev,
1550 	    regwin, target);
1551 	if (error) {
1552 		device_printf(probe->dev, "failed to configure dynamic "
1553 		    "register window: %d\n", error);
1554 		return (error);
1555 	}
1556 
1557 	/* Update our mapping state */
1558 	probe->m_win = regwin;
1559 	probe->m_res = regwin_res;
1560 	probe->m_addr = addr;
1561 	probe->m_size = size;
1562 	probe->m_target = target;
1563 	probe->m_valid = true;
1564 
1565 	*res = regwin_res;
1566 	*res_offset = (addr - target) + regwin->win_offset;
1567 
1568 	return (0);
1569 }
1570 
1571 /**
1572  * Write a data item to the bridged address space at the given @p offset from
1573  * @p addr.
1574  *
1575  * A dynamic register window will be used to map @p addr.
1576  *
1577  * @param probe		The bhndb_pci probe state to be used to perform the
1578  *			write.
1579  * @param addr		The base address.
1580  * @param offset	The offset from @p addr at which @p value will be
1581  *			written.
1582  * @param value		The data item to be written.
1583  * @param width		The data item width (1, 2, or 4 bytes).
1584  */
1585 static void
1586 bhndb_pci_probe_write(struct bhndb_pci_probe *probe, bhnd_addr_t addr,
1587     bhnd_size_t offset, uint32_t value, u_int width)
1588 {
1589 	struct resource	*r;
1590 	bus_size_t	 res_offset;
1591 	int		 error;
1592 
1593 	/* Map the target address */
1594 	error = bhndb_pci_probe_map(probe, addr, offset, width, &r,
1595 	    &res_offset);
1596 	if (error) {
1597 		device_printf(probe->dev, "error mapping %#jx+%#jx for "
1598 		    "writing: %d\n", addr, offset, error);
1599 		return;
1600 	}
1601 
1602 	/* Perform write */
1603 	switch (width) {
1604 	case 1:
1605 		return (bus_write_1(r, res_offset, value));
1606 	case 2:
1607 		return (bus_write_2(r, res_offset, value));
1608 	case 4:
1609 		return (bus_write_4(r, res_offset, value));
1610 	default:
1611 		panic("unsupported width: %u", width);
1612 	}
1613 }
1614 
1615 /**
1616  * Read a data item from the bridged address space at the given @p offset
1617  * from @p addr.
1618  *
1619  * A dynamic register window will be used to map @p addr.
1620  *
1621  * @param probe		The bhndb_pci probe state to be used to perform the
1622  *			read.
1623  * @param addr		The base address.
1624  * @param offset	The offset from @p addr at which to read a data item of
1625  *			@p width bytes.
1626  * @param width		Item width (1, 2, or 4 bytes).
1627  */
1628 static uint32_t
1629 bhndb_pci_probe_read(struct bhndb_pci_probe *probe, bhnd_addr_t addr,
1630     bhnd_size_t offset, u_int width)
1631 {
1632 	struct resource	*r;
1633 	bus_size_t	 res_offset;
1634 	int		 error;
1635 
1636 	/* Map the target address */
1637 	error = bhndb_pci_probe_map(probe, addr, offset, width, &r,
1638 	    &res_offset);
1639 	if (error) {
1640 		device_printf(probe->dev, "error mapping %#jx+%#jx for "
1641 		    "reading: %d\n", addr, offset, error);
1642 		return (UINT32_MAX);
1643 	}
1644 
1645 	/* Perform read */
1646 	switch (width) {
1647 	case 1:
1648 		return (bus_read_1(r, res_offset));
1649 	case 2:
1650 		return (bus_read_2(r, res_offset));
1651 	case 4:
1652 		return (bus_read_4(r, res_offset));
1653 	default:
1654 		panic("unsupported width: %u", width);
1655 	}
1656 }
1657 
1658 /**
1659  * Initialize a new bhndb PCI bridge EROM I/O instance. All I/O will be
1660  * performed using @p probe.
1661  *
1662  * @param pio		The instance to be initialized.
1663  * @param probe		The bhndb_pci probe state to be used to perform all
1664  *			I/O.
1665  */
1666 static void
1667 bhndb_pci_eio_init(struct bhndb_pci_eio *pio, struct bhndb_pci_probe *probe)
1668 {
1669 	memset(pio, 0, sizeof(*pio));
1670 
1671 	pio->eio.map = bhndb_pci_eio_map;
1672 	pio->eio.tell = bhndb_pci_eio_tell;
1673 	pio->eio.read = bhndb_pci_eio_read;
1674 	pio->eio.fini = NULL;
1675 
1676 	pio->mapped = false;
1677 	pio->addr = 0;
1678 	pio->size = 0;
1679 	pio->probe = probe;
1680 }
1681 
1682 /* bhnd_erom_io_map() implementation */
1683 static int
1684 bhndb_pci_eio_map(struct bhnd_erom_io *eio, bhnd_addr_t addr,
1685     bhnd_size_t size)
1686 {
1687 	struct bhndb_pci_eio *pio = (struct bhndb_pci_eio *)eio;
1688 
1689 	if (BHND_ADDR_MAX - addr < size)
1690 		return (EINVAL); /* addr+size would overflow */
1691 
1692 	pio->addr = addr;
1693 	pio->size = size;
1694 	pio->mapped = true;
1695 
1696 	return (0);
1697 }
1698 
1699 /* bhnd_erom_io_tell() implementation */
1700 static int
1701 bhndb_pci_eio_tell(struct bhnd_erom_io *eio, bhnd_addr_t *addr,
1702     bhnd_size_t *size)
1703 {
1704 	struct bhndb_pci_eio *pio = (struct bhndb_pci_eio *)eio;
1705 
1706 	if (!pio->mapped)
1707 		return (ENXIO);
1708 
1709 	*addr = pio->addr;
1710 	*size = pio->size;
1711 
1712 	return (0);
1713 }
1714 
1715 /* bhnd_erom_io_read() implementation */
1716 static uint32_t
1717 bhndb_pci_eio_read(struct bhnd_erom_io *eio, bhnd_size_t offset, u_int width)
1718 {
1719 	struct bhndb_pci_eio *pio = (struct bhndb_pci_eio *)eio;
1720 
1721 	/* Must have a valid mapping */
1722 	if (!pio->mapped)
1723 		panic("no active mapping");
1724 
1725 	/* The requested subrange must fall within the existing mapped range */
1726 	if (offset > pio->size ||
1727 	    width > pio->size ||
1728 	    pio->size - offset < width)
1729 	{
1730 		panic("invalid offset %#jx", offset);
1731 	}
1732 
1733 	return (bhndb_pci_probe_read(pio->probe, pio->addr, offset, width));
1734 }
1735 
1736 static device_method_t bhndb_pci_methods[] = {
1737 	/* Device interface */
1738 	DEVMETHOD(device_probe,				bhndb_pci_probe),
1739 	DEVMETHOD(device_attach,			bhndb_pci_attach),
1740 	DEVMETHOD(device_resume,			bhndb_pci_resume),
1741 	DEVMETHOD(device_suspend,			bhndb_pci_suspend),
1742 	DEVMETHOD(device_detach,			bhndb_pci_detach),
1743 
1744 	/* BHNDB interface */
1745 	DEVMETHOD(bhndb_set_window_addr,		bhndb_pci_set_window_addr),
1746 	DEVMETHOD(bhndb_populate_board_info,		bhndb_pci_populate_board_info),
1747 	DEVMETHOD(bhndb_map_intr_isrc,			bhndb_pci_map_intr_isrc),
1748 	DEVMETHOD(bhndb_route_interrupts,		bhndb_pci_route_interrupts),
1749 
1750 	/* BHND PWRCTL hostb interface */
1751 	DEVMETHOD(bhnd_pwrctl_hostb_get_clksrc,		bhndb_pci_pwrctl_get_clksrc),
1752 	DEVMETHOD(bhnd_pwrctl_hostb_gate_clock,		bhndb_pci_pwrctl_gate_clock),
1753 	DEVMETHOD(bhnd_pwrctl_hostb_ungate_clock,	bhndb_pci_pwrctl_ungate_clock),
1754 
1755 	DEVMETHOD_END
1756 };
1757 
1758 DEFINE_CLASS_1(bhndb, bhndb_pci_driver, bhndb_pci_methods,
1759     sizeof(struct bhndb_pci_softc), bhndb_driver);
1760 
1761 MODULE_VERSION(bhndb_pci, 1);
1762 MODULE_DEPEND(bhndb_pci, bhnd_pci_hostb, 1, 1, 1);
1763 MODULE_DEPEND(bhndb_pci, pci, 1, 1, 1);
1764 MODULE_DEPEND(bhndb_pci, bhndb, 1, 1, 1);
1765 MODULE_DEPEND(bhndb_pci, bhnd, 1, 1, 1);
1766