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
77struct bhndb_pci_eio;
78struct bhndb_pci_probe;
79
80static int		bhndb_pci_alloc_msi(struct bhndb_pci_softc *sc,
81			    int *msi_count);
82
83static int		bhndb_pci_add_children(struct bhndb_pci_softc *sc);
84
85static bhnd_devclass_t	bhndb_expected_pci_devclass(device_t dev);
86static bool		bhndb_is_pcie_attached(device_t dev);
87
88static int		bhndb_enable_pci_clocks(device_t dev);
89static int		bhndb_disable_pci_clocks(device_t dev);
90
91static int		bhndb_pci_compat_setregwin(device_t dev,
92			    device_t pci_dev, const struct bhndb_regwin *,
93			    bhnd_addr_t);
94static int		bhndb_pci_fast_setregwin(device_t dev, device_t pci_dev,
95			    const struct bhndb_regwin *, bhnd_addr_t);
96
97static void		bhndb_pci_write_core(struct bhndb_pci_softc *sc,
98			    bus_size_t offset, uint32_t value, u_int width);
99static uint32_t		bhndb_pci_read_core(struct bhndb_pci_softc *sc,
100			    bus_size_t offset, u_int width);
101
102static int		bhndb_pci_srsh_pi_war(struct bhndb_pci_softc *sc,
103			    struct bhndb_pci_probe *probe);
104
105static bus_addr_t	bhndb_pci_sprom_addr(struct bhndb_pci_softc *sc);
106static bus_size_t	bhndb_pci_sprom_size(struct bhndb_pci_softc *sc);
107
108static int		bhndb_pci_probe_alloc(struct bhndb_pci_probe **probe,
109			    device_t dev, bhnd_devclass_t pci_devclass);
110static void		bhndb_pci_probe_free(struct bhndb_pci_probe *probe);
111
112static int		bhndb_pci_probe_copy_core_table(
113			    struct bhndb_pci_probe *probe,
114			    struct bhnd_core_info **cores, u_int *ncores);
115static void		bhndb_pci_probe_free_core_table(
116			    struct bhnd_core_info *cores);
117
118static 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);
121static uint32_t		bhndb_pci_probe_read(struct bhndb_pci_probe *sc,
122			    bhnd_addr_t addr, bhnd_size_t offset, u_int width);
123
124static void		bhndb_pci_eio_init(struct bhndb_pci_eio *eio,
125			    struct bhndb_pci_probe *probe);
126static int		bhndb_pci_eio_map(struct bhnd_erom_io *eio,
127			    bhnd_addr_t addr, bhnd_size_t size);
128static int		bhndb_pci_eio_tell(struct bhnd_erom_io *eio,
129			    bhnd_addr_t *addr, bhnd_size_t *size);
130static 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
135static struct bhndb_pci_quirk	bhndb_pci_quirks[];
136static struct bhndb_pci_quirk	bhndb_pcie_quirks[];
137static struct bhndb_pci_quirk	bhndb_pcie2_quirks[];
138
139static 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 */
147struct 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 */
162struct 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
184static 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
197static 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
203static 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 */
210static struct bhndb_pci_core *
211bhndb_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 */
226static uint32_t
227bhndb_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 */
263static int
264bhndb_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
314cleanup:
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 */
327static int
328bhndb_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
354static int
355bhndb_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
470cleanup:
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
494static int
495bhndb_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
529static int
530bhndb_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
575static const struct bhndb_regwin *
576bhndb_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
591static bus_addr_t
592bhndb_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
608static bus_size_t
609bhndb_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 */
669static int
670bhndb_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 */
708static void
709bhndb_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 */
745static uint32_t
746bhndb_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 */
803static int
804bhndb_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
848static int
849bhndb_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
864static int
865bhndb_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
880static int
881bhndb_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 */
898static int
899bhndb_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 */
926static int
927bhndb_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
950static int
951bhndb_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 */
1007static bhnd_devclass_t
1008bhndb_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 */
1022static bool
1023bhndb_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 */
1047static int
1048bhndb_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 */
1100static int
1101bhndb_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
1128static bhnd_clksrc
1129bhndb_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
1152static int
1153bhndb_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
1169static int
1170bhndb_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 */
1189static int
1190bhndb_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() */
1201static int
1202bhndb_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() */
1234static int
1235bhndb_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 */
1286static int
1287bhndb_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
1377failed:
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 */
1406static void
1407bhndb_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 */
1429static int
1430bhndb_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 */
1448static void
1449bhndb_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 */
1458static bool
1459bhndb_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 */
1498static int
1499bhndb_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 */
1585static void
1586bhndb_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 */
1628static uint32_t
1629bhndb_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 */
1666static void
1667bhndb_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 */
1683static int
1684bhndb_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 */
1700static int
1701bhndb_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 */
1716static uint32_t
1717bhndb_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
1736static 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
1758DEFINE_CLASS_1(bhndb, bhndb_pci_driver, bhndb_pci_methods,
1759    sizeof(struct bhndb_pci_softc), bhndb_driver);
1760
1761MODULE_VERSION(bhndb_pci, 1);
1762MODULE_DEPEND(bhndb_pci, bhnd_pci_hostb, 1, 1, 1);
1763MODULE_DEPEND(bhndb_pci, pci, 1, 1, 1);
1764MODULE_DEPEND(bhndb_pci, bhndb, 1, 1, 1);
1765MODULE_DEPEND(bhndb_pci, bhnd, 1, 1, 1);
1766