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