pci_subr.c revision 211430
169783Smsmith/*-
269783Smsmith * Copyright (c) 1994,1995 Stefan Esser, Wolfgang StanglMeier
369783Smsmith * Copyright (c) 2000 Michael Smith <msmith@freebsd.org>
469783Smsmith * Copyright (c) 2000 BSDi
569783Smsmith * All rights reserved.
669783Smsmith *
769783Smsmith * Redistribution and use in source and binary forms, with or without
869783Smsmith * modification, are permitted provided that the following conditions
969783Smsmith * are met:
1069783Smsmith * 1. Redistributions of source code must retain the above copyright
1169783Smsmith *    notice, this list of conditions and the following disclaimer.
1269783Smsmith * 2. Redistributions in binary form must reproduce the above copyright
1369783Smsmith *    notice, this list of conditions and the following disclaimer in the
1469783Smsmith *    documentation and/or other materials provided with the distribution.
1569783Smsmith * 3. The name of the author may not be used to endorse or promote products
1669783Smsmith *    derived from this software without specific prior written permission.
1769783Smsmith *
1869783Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1969783Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2069783Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2169783Smsmith * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2269783Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2369783Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2469783Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2569783Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2669783Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2769783Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2869783Smsmith * SUCH DAMAGE.
2969783Smsmith */
3069783Smsmith
31119418Sobrien#include <sys/cdefs.h>
32119418Sobrien__FBSDID("$FreeBSD: head/sys/dev/pci/pci_pci.c 211430 2010-08-17 15:44:52Z jhb $");
33119418Sobrien
3469783Smsmith/*
3569783Smsmith * PCI:PCI bridge support.
3669783Smsmith */
3769783Smsmith
3869783Smsmith#include <sys/param.h>
3969783Smsmith#include <sys/systm.h>
4069783Smsmith#include <sys/kernel.h>
41129876Sphk#include <sys/module.h>
4269783Smsmith#include <sys/bus.h>
43107546Simp#include <machine/bus.h>
44107546Simp#include <sys/rman.h>
45106844Smdodd#include <sys/sysctl.h>
4669783Smsmith
4769783Smsmith#include <machine/resource.h>
4869783Smsmith
49119285Simp#include <dev/pci/pcivar.h>
50119285Simp#include <dev/pci/pcireg.h>
51211430Sjhb#include <dev/pci/pci_private.h>
52119285Simp#include <dev/pci/pcib_private.h>
5369783Smsmith
5469783Smsmith#include "pcib_if.h"
5569783Smsmith
5669783Smsmithstatic int		pcib_probe(device_t dev);
57200341Sjkimstatic int		pcib_suspend(device_t dev);
58200341Sjkimstatic int		pcib_resume(device_t dev);
59211430Sjhbstatic int		pcib_power_for_sleep(device_t pcib, device_t dev,
60211430Sjhb			    int *pstate);
6169783Smsmith
6269783Smsmithstatic device_method_t pcib_methods[] = {
6369783Smsmith    /* Device interface */
6469783Smsmith    DEVMETHOD(device_probe,		pcib_probe),
6569783Smsmith    DEVMETHOD(device_attach,		pcib_attach),
66145661Simp    DEVMETHOD(device_detach,		bus_generic_detach),
6769783Smsmith    DEVMETHOD(device_shutdown,		bus_generic_shutdown),
68200341Sjkim    DEVMETHOD(device_suspend,		pcib_suspend),
69200341Sjkim    DEVMETHOD(device_resume,		pcib_resume),
7069783Smsmith
7169783Smsmith    /* Bus interface */
7269783Smsmith    DEVMETHOD(bus_print_child,		bus_generic_print_child),
7369783Smsmith    DEVMETHOD(bus_read_ivar,		pcib_read_ivar),
7469783Smsmith    DEVMETHOD(bus_write_ivar,		pcib_write_ivar),
7569783Smsmith    DEVMETHOD(bus_alloc_resource,	pcib_alloc_resource),
7669783Smsmith    DEVMETHOD(bus_release_resource,	bus_generic_release_resource),
7769783Smsmith    DEVMETHOD(bus_activate_resource,	bus_generic_activate_resource),
7869783Smsmith    DEVMETHOD(bus_deactivate_resource,	bus_generic_deactivate_resource),
7969783Smsmith    DEVMETHOD(bus_setup_intr,		bus_generic_setup_intr),
8069783Smsmith    DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
8169783Smsmith
8269783Smsmith    /* pcib interface */
8369783Smsmith    DEVMETHOD(pcib_maxslots,		pcib_maxslots),
8469783Smsmith    DEVMETHOD(pcib_read_config,		pcib_read_config),
8569783Smsmith    DEVMETHOD(pcib_write_config,	pcib_write_config),
8669783Smsmith    DEVMETHOD(pcib_route_interrupt,	pcib_route_interrupt),
87164264Sjhb    DEVMETHOD(pcib_alloc_msi,		pcib_alloc_msi),
88164264Sjhb    DEVMETHOD(pcib_release_msi,		pcib_release_msi),
89164264Sjhb    DEVMETHOD(pcib_alloc_msix,		pcib_alloc_msix),
90164264Sjhb    DEVMETHOD(pcib_release_msix,	pcib_release_msix),
91169221Sjhb    DEVMETHOD(pcib_map_msi,		pcib_map_msi),
92211430Sjhb    DEVMETHOD(pcib_power_for_sleep,	pcib_power_for_sleep),
9369783Smsmith
9469783Smsmith    { 0, 0 }
9569783Smsmith};
9669783Smsmith
97154079Sjhbstatic devclass_t pcib_devclass;
9869783Smsmith
99154079SjhbDEFINE_CLASS_0(pcib, pcib_driver, pcib_methods, sizeof(struct pcib_softc));
10069783SmsmithDRIVER_MODULE(pcib, pci, pcib_driver, pcib_devclass, 0, 0);
10169783Smsmith
10269783Smsmith/*
103163805Simp * Is the prefetch window open (eg, can we allocate memory in it?)
104163805Simp */
105163805Simpstatic int
106163805Simppcib_is_prefetch_open(struct pcib_softc *sc)
107163805Simp{
108163805Simp	return (sc->pmembase > 0 && sc->pmembase < sc->pmemlimit);
109163805Simp}
110163805Simp
111163805Simp/*
112163805Simp * Is the nonprefetch window open (eg, can we allocate memory in it?)
113163805Simp */
114163805Simpstatic int
115163805Simppcib_is_nonprefetch_open(struct pcib_softc *sc)
116163805Simp{
117163805Simp	return (sc->membase > 0 && sc->membase < sc->memlimit);
118163805Simp}
119163805Simp
120163805Simp/*
121163805Simp * Is the io window open (eg, can we allocate ports in it?)
122163805Simp */
123163805Simpstatic int
124163805Simppcib_is_io_open(struct pcib_softc *sc)
125163805Simp{
126163805Simp	return (sc->iobase > 0 && sc->iobase < sc->iolimit);
127163805Simp}
128163805Simp
129163805Simp/*
130200341Sjkim * Get current I/O decode.
131200341Sjkim */
132200341Sjkimstatic void
133200341Sjkimpcib_get_io_decode(struct pcib_softc *sc)
134200341Sjkim{
135200341Sjkim	device_t	dev;
136200341Sjkim	uint32_t	iolow;
137200341Sjkim
138200341Sjkim	dev = sc->dev;
139200341Sjkim
140200341Sjkim	iolow = pci_read_config(dev, PCIR_IOBASEL_1, 1);
141200341Sjkim	if ((iolow & PCIM_BRIO_MASK) == PCIM_BRIO_32)
142200341Sjkim		sc->iobase = PCI_PPBIOBASE(
143200341Sjkim		    pci_read_config(dev, PCIR_IOBASEH_1, 2), iolow);
144200341Sjkim	else
145200341Sjkim		sc->iobase = PCI_PPBIOBASE(0, iolow);
146200341Sjkim
147200341Sjkim	iolow = pci_read_config(dev, PCIR_IOLIMITL_1, 1);
148200341Sjkim	if ((iolow & PCIM_BRIO_MASK) == PCIM_BRIO_32)
149200341Sjkim		sc->iolimit = PCI_PPBIOLIMIT(
150200341Sjkim		    pci_read_config(dev, PCIR_IOLIMITH_1, 2), iolow);
151200341Sjkim	else
152200341Sjkim		sc->iolimit = PCI_PPBIOLIMIT(0, iolow);
153200341Sjkim}
154200341Sjkim
155200341Sjkim/*
156200341Sjkim * Get current memory decode.
157200341Sjkim */
158200341Sjkimstatic void
159200341Sjkimpcib_get_mem_decode(struct pcib_softc *sc)
160200341Sjkim{
161200341Sjkim	device_t	dev;
162200341Sjkim	pci_addr_t	pmemlow;
163200341Sjkim
164200341Sjkim	dev = sc->dev;
165200341Sjkim
166200341Sjkim	sc->membase = PCI_PPBMEMBASE(0,
167200341Sjkim	    pci_read_config(dev, PCIR_MEMBASE_1, 2));
168200341Sjkim	sc->memlimit = PCI_PPBMEMLIMIT(0,
169200341Sjkim	    pci_read_config(dev, PCIR_MEMLIMIT_1, 2));
170200341Sjkim
171200341Sjkim	pmemlow = pci_read_config(dev, PCIR_PMBASEL_1, 2);
172200341Sjkim	if ((pmemlow & PCIM_BRPM_MASK) == PCIM_BRPM_64)
173200341Sjkim		sc->pmembase = PCI_PPBMEMBASE(
174200341Sjkim		    pci_read_config(dev, PCIR_PMBASEH_1, 4), pmemlow);
175200341Sjkim	else
176200341Sjkim		sc->pmembase = PCI_PPBMEMBASE(0, pmemlow);
177200341Sjkim
178200341Sjkim	pmemlow = pci_read_config(dev, PCIR_PMLIMITL_1, 2);
179200341Sjkim	if ((pmemlow & PCIM_BRPM_MASK) == PCIM_BRPM_64)
180200341Sjkim		sc->pmemlimit = PCI_PPBMEMLIMIT(
181200341Sjkim		    pci_read_config(dev, PCIR_PMLIMITH_1, 4), pmemlow);
182200341Sjkim	else
183200341Sjkim		sc->pmemlimit = PCI_PPBMEMLIMIT(0, pmemlow);
184200341Sjkim}
185200341Sjkim
186200341Sjkim/*
187200341Sjkim * Restore previous I/O decode.
188200341Sjkim */
189200341Sjkimstatic void
190200341Sjkimpcib_set_io_decode(struct pcib_softc *sc)
191200341Sjkim{
192200341Sjkim	device_t	dev;
193200341Sjkim	uint32_t	iohi;
194200341Sjkim
195200341Sjkim	dev = sc->dev;
196200341Sjkim
197200341Sjkim	iohi = sc->iobase >> 16;
198200341Sjkim	if (iohi > 0)
199200341Sjkim		pci_write_config(dev, PCIR_IOBASEH_1, iohi, 2);
200200341Sjkim	pci_write_config(dev, PCIR_IOBASEL_1, sc->iobase >> 8, 1);
201200341Sjkim
202200341Sjkim	iohi = sc->iolimit >> 16;
203200341Sjkim	if (iohi > 0)
204200341Sjkim		pci_write_config(dev, PCIR_IOLIMITH_1, iohi, 2);
205200341Sjkim	pci_write_config(dev, PCIR_IOLIMITL_1, sc->iolimit >> 8, 1);
206200341Sjkim}
207200341Sjkim
208200341Sjkim/*
209200341Sjkim * Restore previous memory decode.
210200341Sjkim */
211200341Sjkimstatic void
212200341Sjkimpcib_set_mem_decode(struct pcib_softc *sc)
213200341Sjkim{
214200341Sjkim	device_t	dev;
215200341Sjkim	pci_addr_t	pmemhi;
216200341Sjkim
217200341Sjkim	dev = sc->dev;
218200341Sjkim
219200341Sjkim	pci_write_config(dev, PCIR_MEMBASE_1, sc->membase >> 16, 2);
220200341Sjkim	pci_write_config(dev, PCIR_MEMLIMIT_1, sc->memlimit >> 16, 2);
221200341Sjkim
222200341Sjkim	pmemhi = sc->pmembase >> 32;
223200341Sjkim	if (pmemhi > 0)
224200341Sjkim		pci_write_config(dev, PCIR_PMBASEH_1, pmemhi, 4);
225200341Sjkim	pci_write_config(dev, PCIR_PMBASEL_1, sc->pmembase >> 16, 2);
226200341Sjkim
227200341Sjkim	pmemhi = sc->pmemlimit >> 32;
228200341Sjkim	if (pmemhi > 0)
229200341Sjkim		pci_write_config(dev, PCIR_PMLIMITH_1, pmemhi, 4);
230200341Sjkim	pci_write_config(dev, PCIR_PMLIMITL_1, sc->pmemlimit >> 16, 2);
231200341Sjkim}
232200341Sjkim
233200341Sjkim/*
234200341Sjkim * Get current bridge configuration.
235200341Sjkim */
236200341Sjkimstatic void
237200341Sjkimpcib_cfg_save(struct pcib_softc *sc)
238200341Sjkim{
239200341Sjkim	device_t	dev;
240200341Sjkim
241200341Sjkim	dev = sc->dev;
242200341Sjkim
243200341Sjkim	sc->command = pci_read_config(dev, PCIR_COMMAND, 2);
244200341Sjkim	sc->pribus = pci_read_config(dev, PCIR_PRIBUS_1, 1);
245200341Sjkim	sc->secbus = pci_read_config(dev, PCIR_SECBUS_1, 1);
246200341Sjkim	sc->subbus = pci_read_config(dev, PCIR_SUBBUS_1, 1);
247200341Sjkim	sc->bridgectl = pci_read_config(dev, PCIR_BRIDGECTL_1, 2);
248200341Sjkim	sc->seclat = pci_read_config(dev, PCIR_SECLAT_1, 1);
249200341Sjkim	if (sc->command & PCIM_CMD_PORTEN)
250200341Sjkim		pcib_get_io_decode(sc);
251200341Sjkim	if (sc->command & PCIM_CMD_MEMEN)
252200341Sjkim		pcib_get_mem_decode(sc);
253200341Sjkim}
254200341Sjkim
255200341Sjkim/*
256200341Sjkim * Restore previous bridge configuration.
257200341Sjkim */
258200341Sjkimstatic void
259200341Sjkimpcib_cfg_restore(struct pcib_softc *sc)
260200341Sjkim{
261200341Sjkim	device_t	dev;
262200341Sjkim
263200341Sjkim	dev = sc->dev;
264200341Sjkim
265200341Sjkim	pci_write_config(dev, PCIR_COMMAND, sc->command, 2);
266200341Sjkim	pci_write_config(dev, PCIR_PRIBUS_1, sc->pribus, 1);
267200341Sjkim	pci_write_config(dev, PCIR_SECBUS_1, sc->secbus, 1);
268200341Sjkim	pci_write_config(dev, PCIR_SUBBUS_1, sc->subbus, 1);
269200341Sjkim	pci_write_config(dev, PCIR_BRIDGECTL_1, sc->bridgectl, 2);
270200341Sjkim	pci_write_config(dev, PCIR_SECLAT_1, sc->seclat, 1);
271200341Sjkim	if (sc->command & PCIM_CMD_PORTEN)
272200341Sjkim		pcib_set_io_decode(sc);
273200341Sjkim	if (sc->command & PCIM_CMD_MEMEN)
274200341Sjkim		pcib_set_mem_decode(sc);
275200341Sjkim}
276200341Sjkim
277200341Sjkim/*
27869783Smsmith * Generic device interface
27969783Smsmith */
28069783Smsmithstatic int
28169783Smsmithpcib_probe(device_t dev)
28269783Smsmith{
28369783Smsmith    if ((pci_get_class(dev) == PCIC_BRIDGE) &&
28469783Smsmith	(pci_get_subclass(dev) == PCIS_BRIDGE_PCI)) {
28569783Smsmith	device_set_desc(dev, "PCI-PCI bridge");
28669783Smsmith	return(-10000);
28769783Smsmith    }
28869783Smsmith    return(ENXIO);
28969783Smsmith}
29069783Smsmith
291102441Sjhbvoid
292102441Sjhbpcib_attach_common(device_t dev)
29369783Smsmith{
29469783Smsmith    struct pcib_softc	*sc;
295181789Simp    struct sysctl_ctx_list *sctx;
296181789Simp    struct sysctl_oid	*soid;
29769783Smsmith
29869783Smsmith    sc = device_get_softc(dev);
29969783Smsmith    sc->dev = dev;
30069783Smsmith
30169908Smsmith    /*
30269908Smsmith     * Get current bridge configuration.
30369908Smsmith     */
304200341Sjkim    sc->domain = pci_get_domain(dev);
305200341Sjkim    sc->secstat = pci_read_config(dev, PCIR_SECSTAT_1, 2);
306200341Sjkim    pcib_cfg_save(sc);
30769783Smsmith
30869908Smsmith    /*
309181789Simp     * Setup sysctl reporting nodes
310181789Simp     */
311181789Simp    sctx = device_get_sysctl_ctx(dev);
312181789Simp    soid = device_get_sysctl_tree(dev);
313181789Simp    SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "domain",
314182706Simp      CTLFLAG_RD, &sc->domain, 0, "Domain number");
315181789Simp    SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "pribus",
316182706Simp      CTLFLAG_RD, &sc->pribus, 0, "Primary bus number");
317181789Simp    SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "secbus",
318182706Simp      CTLFLAG_RD, &sc->secbus, 0, "Secondary bus number");
319181789Simp    SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "subbus",
320182706Simp      CTLFLAG_RD, &sc->subbus, 0, "Subordinate bus number");
321181789Simp
322181789Simp    /*
32369908Smsmith     * Quirk handling.
32469908Smsmith     */
32569908Smsmith    switch (pci_get_devid(dev)) {
326124365Simp    case 0x12258086:		/* Intel 82454KX/GX (Orion) */
32769908Smsmith	{
328119266Simp	    uint8_t	supbus;
32969908Smsmith
33069908Smsmith	    supbus = pci_read_config(dev, 0x41, 1);
33169908Smsmith	    if (supbus != 0xff) {
33269908Smsmith		sc->secbus = supbus + 1;
33369908Smsmith		sc->subbus = supbus + 1;
33469908Smsmith	    }
335124365Simp	    break;
33669908Smsmith	}
337124365Simp
338124365Simp    /*
339124365Simp     * The i82380FB mobile docking controller is a PCI-PCI bridge,
340124365Simp     * and it is a subtractive bridge.  However, the ProgIf is wrong
341124365Simp     * so the normal setting of PCIB_SUBTRACTIVE bit doesn't
342124365Simp     * happen.  There's also a Toshiba bridge that behaves this
343124365Simp     * way.
344124365Simp     */
345124365Simp    case 0x124b8086:		/* Intel 82380FB Mobile */
346124365Simp    case 0x060513d7:		/* Toshiba ???? */
347124365Simp	sc->flags |= PCIB_SUBTRACTIVE;
34869908Smsmith	break;
349149521Sjkim
350149521Sjkim    /* Compaq R3000 BIOS sets wrong subordinate bus number. */
351149521Sjkim    case 0x00dd10de:
352149521Sjkim	{
353149521Sjkim	    char *cp;
354149521Sjkim
355157949Sjkim	    if ((cp = getenv("smbios.planar.maker")) == NULL)
356149521Sjkim		break;
357157949Sjkim	    if (strncmp(cp, "Compal", 6) != 0) {
358157949Sjkim		freeenv(cp);
359149521Sjkim		break;
360157949Sjkim	    }
361157949Sjkim	    freeenv(cp);
362157949Sjkim	    if ((cp = getenv("smbios.planar.product")) == NULL)
363157949Sjkim		break;
364157949Sjkim	    if (strncmp(cp, "08A0", 4) != 0) {
365157949Sjkim		freeenv(cp);
366157949Sjkim		break;
367157949Sjkim	    }
368157949Sjkim	    freeenv(cp);
369149521Sjkim	    if (sc->subbus < 0xa) {
370149521Sjkim		pci_write_config(dev, PCIR_SUBBUS_1, 0xa, 1);
371149521Sjkim		sc->subbus = pci_read_config(dev, PCIR_SUBBUS_1, 1);
372149521Sjkim	    }
373149521Sjkim	    break;
374149521Sjkim	}
37569908Smsmith    }
37669908Smsmith
377165995Sjhb    if (pci_msi_device_blacklisted(dev))
378165995Sjhb	sc->flags |= PCIB_DISABLE_MSI;
379165995Sjhb
380124365Simp    /*
381124365Simp     * Intel 815, 845 and other chipsets say they are PCI-PCI bridges,
382124365Simp     * but have a ProgIF of 0x80.  The 82801 family (AA, AB, BAM/CAM,
383124365Simp     * BA/CA/DB and E) PCI bridges are HUB-PCI bridges, in Intelese.
384124365Simp     * This means they act as if they were subtractively decoding
385124365Simp     * bridges and pass all transactions.  Mark them and real ProgIf 1
386124365Simp     * parts as subtractive.
387124365Simp     */
388124365Simp    if ((pci_get_devid(dev) & 0xff00ffff) == 0x24008086 ||
389168157Sjhb      pci_read_config(dev, PCIR_PROGIF, 1) == PCIP_BRIDGE_PCI_SUBTRACTIVE)
390124365Simp	sc->flags |= PCIB_SUBTRACTIVE;
391124365Simp
39269783Smsmith    if (bootverbose) {
393172394Smarius	device_printf(dev, "  domain            %d\n", sc->domain);
39469783Smsmith	device_printf(dev, "  secondary bus     %d\n", sc->secbus);
39569783Smsmith	device_printf(dev, "  subordinate bus   %d\n", sc->subbus);
39669783Smsmith	device_printf(dev, "  I/O decode        0x%x-0x%x\n", sc->iobase, sc->iolimit);
397163805Simp	if (pcib_is_nonprefetch_open(sc))
398163805Simp	    device_printf(dev, "  memory decode     0x%jx-0x%jx\n",
399163805Simp	      (uintmax_t)sc->membase, (uintmax_t)sc->memlimit);
400163805Simp	if (pcib_is_prefetch_open(sc))
401163805Simp	    device_printf(dev, "  prefetched decode 0x%jx-0x%jx\n",
402163805Simp	      (uintmax_t)sc->pmembase, (uintmax_t)sc->pmemlimit);
403163805Simp	else
404163805Simp	    device_printf(dev, "  no prefetched decode\n");
405124365Simp	if (sc->flags & PCIB_SUBTRACTIVE)
406124365Simp	    device_printf(dev, "  Subtractively decoded bridge.\n");
40769783Smsmith    }
40869783Smsmith
40969783Smsmith    /*
41069783Smsmith     * XXX If the secondary bus number is zero, we should assign a bus number
411181798Simp     *     since the BIOS hasn't, then initialise the bridge.  A simple
412181798Simp     *     bus_alloc_resource with the a couple of busses seems like the right
413181798Simp     *     approach, but we don't know what busses the BIOS might have already
414181798Simp     *     assigned to other bridges on this bus that probe later than we do.
415181798Simp     *
416181798Simp     *     If the subordinate bus number is less than the secondary bus number,
41769783Smsmith     *     we should pick a better value.  One sensible alternative would be to
41869783Smsmith     *     pick 255; the only tradeoff here is that configuration transactions
419181798Simp     *     would be more widely routed than absolutely necessary.  We could
420181798Simp     *     then do a walk of the tree later and fix it.
42169783Smsmith     */
422102441Sjhb}
42369783Smsmith
424103042Sjhbint
425102441Sjhbpcib_attach(device_t dev)
426102441Sjhb{
427102441Sjhb    struct pcib_softc	*sc;
428102441Sjhb    device_t		child;
429102441Sjhb
430102441Sjhb    pcib_attach_common(dev);
431102441Sjhb    sc = device_get_softc(dev);
43269783Smsmith    if (sc->secbus != 0) {
433103016Sjhb	child = device_add_child(dev, "pci", sc->secbus);
43469783Smsmith	if (child != NULL)
43569783Smsmith	    return(bus_generic_attach(dev));
436181798Simp    }
43769783Smsmith
43869783Smsmith    /* no secondary bus; we should have fixed this */
43969783Smsmith    return(0);
44069783Smsmith}
44169783Smsmith
442102441Sjhbint
443200341Sjkimpcib_suspend(device_t dev)
444200341Sjkim{
445211430Sjhb	device_t	pcib;
446200341Sjkim	int		dstate, error;
447200341Sjkim
448200341Sjkim	pcib_cfg_save(device_get_softc(dev));
449200341Sjkim	error = bus_generic_suspend(dev);
450200341Sjkim	if (error == 0 && pci_do_power_resume) {
451211430Sjhb		dstate = PCI_POWERSTATE_D3;
452211430Sjhb		pcib = device_get_parent(device_get_parent(dev));
453211430Sjhb		if (PCIB_POWER_FOR_SLEEP(pcib, dev, &dstate) == 0)
454200341Sjkim			pci_set_powerstate(dev, dstate);
455200341Sjkim	}
456200341Sjkim	return (error);
457200341Sjkim}
458200341Sjkim
459200341Sjkimint
460200341Sjkimpcib_resume(device_t dev)
461200341Sjkim{
462211430Sjhb	device_t	pcib;
463200341Sjkim
464200341Sjkim	if (pci_do_power_resume) {
465211430Sjhb		pcib = device_get_parent(device_get_parent(dev));
466211430Sjhb		if (PCIB_POWER_FOR_SLEEP(pcib, dev, NULL) == 0)
467200341Sjkim			pci_set_powerstate(dev, PCI_POWERSTATE_D0);
468200341Sjkim	}
469200341Sjkim	pcib_cfg_restore(device_get_softc(dev));
470200341Sjkim	return (bus_generic_resume(dev));
471200341Sjkim}
472200341Sjkim
473200341Sjkimint
47469783Smsmithpcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
47569783Smsmith{
47669783Smsmith    struct pcib_softc	*sc = device_get_softc(dev);
47769783Smsmith
47869783Smsmith    switch (which) {
479172394Smarius    case PCIB_IVAR_DOMAIN:
480172394Smarius	*result = sc->domain;
481172394Smarius	return(0);
48269783Smsmith    case PCIB_IVAR_BUS:
48369783Smsmith	*result = sc->secbus;
48469783Smsmith	return(0);
48569783Smsmith    }
48669783Smsmith    return(ENOENT);
48769783Smsmith}
48869783Smsmith
489102441Sjhbint
49069783Smsmithpcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
49169783Smsmith{
49269783Smsmith    struct pcib_softc	*sc = device_get_softc(dev);
49369783Smsmith
49469783Smsmith    switch (which) {
495172394Smarius    case PCIB_IVAR_DOMAIN:
496172394Smarius	return(EINVAL);
49769783Smsmith    case PCIB_IVAR_BUS:
49869783Smsmith	sc->secbus = value;
499172394Smarius	return(0);
50069783Smsmith    }
50169783Smsmith    return(ENOENT);
50269783Smsmith}
50369783Smsmith
50469783Smsmith/*
50569783Smsmith * We have to trap resource allocation requests and ensure that the bridge
50669783Smsmith * is set up to, or capable of handling them.
50769783Smsmith */
508102441Sjhbstruct resource *
50969783Smsmithpcib_alloc_resource(device_t dev, device_t child, int type, int *rid,
510142051Simp    u_long start, u_long end, u_long count, u_int flags)
51169783Smsmith{
512124365Simp	struct pcib_softc	*sc = device_get_softc(dev);
513164130Sjhb	const char *name, *suffix;
514124365Simp	int ok;
51569783Smsmith
51669783Smsmith	/*
51769783Smsmith	 * Fail the allocation for this range if it's not supported.
51869783Smsmith	 */
519164130Sjhb	name = device_get_nameunit(child);
520164130Sjhb	if (name == NULL) {
521164130Sjhb		name = "";
522164130Sjhb		suffix = "";
523164130Sjhb	} else
524164130Sjhb		suffix = " ";
52569783Smsmith	switch (type) {
52669783Smsmith	case SYS_RES_IOPORT:
527107546Simp		ok = 0;
528124365Simp		if (!pcib_is_io_open(sc))
529124365Simp			break;
530124365Simp		ok = (start >= sc->iobase && end <= sc->iolimit);
531145652Smarcel
532145652Smarcel		/*
533145652Smarcel		 * Make sure we allow access to VGA I/O addresses when the
534145652Smarcel		 * bridge has the "VGA Enable" bit set.
535145652Smarcel		 */
536145652Smarcel		if (!ok && pci_is_vga_ioport_range(start, end))
537145652Smarcel			ok = (sc->bridgectl & PCIB_BCR_VGA_ENABLE) ? 1 : 0;
538145652Smarcel
539124365Simp		if ((sc->flags & PCIB_SUBTRACTIVE) == 0) {
540124365Simp			if (!ok) {
541124365Simp				if (start < sc->iobase)
542124365Simp					start = sc->iobase;
543124365Simp				if (end > sc->iolimit)
544124365Simp					end = sc->iolimit;
545142051Simp				if (start < end)
546142051Simp					ok = 1;
547124365Simp			}
548106844Smdodd		} else {
549124365Simp			ok = 1;
550189844Simp#if 0
551189792Simp			/*
552189792Simp			 * If we overlap with the subtractive range, then
553189792Simp			 * pick the upper range to use.
554189792Simp			 */
555189792Simp			if (start < sc->iolimit && end > sc->iobase)
556189792Simp				start = sc->iolimit + 1;
557189844Simp#endif
558106844Smdodd		}
559124365Simp		if (end < start) {
560142051Simp			device_printf(dev, "ioport: end (%lx) < start (%lx)\n",
561142051Simp			    end, start);
562124365Simp			start = 0;
563124365Simp			end = 0;
564124365Simp			ok = 0;
565124365Simp		}
566124365Simp		if (!ok) {
567164130Sjhb			device_printf(dev, "%s%srequested unsupported I/O "
568124365Simp			    "range 0x%lx-0x%lx (decoding 0x%x-0x%x)\n",
569164130Sjhb			    name, suffix, start, end, sc->iobase, sc->iolimit);
570124365Simp			return (NULL);
571124365Simp		}
572124365Simp		if (bootverbose)
573142051Simp			device_printf(dev,
574164130Sjhb			    "%s%srequested I/O range 0x%lx-0x%lx: in range\n",
575164130Sjhb			    name, suffix, start, end);
576124365Simp		break;
57769783Smsmith
57869783Smsmith	case SYS_RES_MEMORY:
579107546Simp		ok = 0;
580107546Simp		if (pcib_is_nonprefetch_open(sc))
581124365Simp			ok = ok || (start >= sc->membase && end <= sc->memlimit);
582107546Simp		if (pcib_is_prefetch_open(sc))
583124365Simp			ok = ok || (start >= sc->pmembase && end <= sc->pmemlimit);
584145652Smarcel
585145652Smarcel		/*
586145652Smarcel		 * Make sure we allow access to VGA memory addresses when the
587145652Smarcel		 * bridge has the "VGA Enable" bit set.
588145652Smarcel		 */
589145652Smarcel		if (!ok && pci_is_vga_memory_range(start, end))
590145652Smarcel			ok = (sc->bridgectl & PCIB_BCR_VGA_ENABLE) ? 1 : 0;
591145652Smarcel
592124365Simp		if ((sc->flags & PCIB_SUBTRACTIVE) == 0) {
593124365Simp			if (!ok) {
594124365Simp				ok = 1;
595124365Simp				if (flags & RF_PREFETCHABLE) {
596124365Simp					if (pcib_is_prefetch_open(sc)) {
597124365Simp						if (start < sc->pmembase)
598124365Simp							start = sc->pmembase;
599124365Simp						if (end > sc->pmemlimit)
600124365Simp							end = sc->pmemlimit;
601124365Simp					} else {
602124365Simp						ok = 0;
603124365Simp					}
604124365Simp				} else {	/* non-prefetchable */
605124365Simp					if (pcib_is_nonprefetch_open(sc)) {
606124365Simp						if (start < sc->membase)
607124365Simp							start = sc->membase;
608124365Simp						if (end > sc->memlimit)
609124365Simp							end = sc->memlimit;
610124365Simp					} else {
611124365Simp						ok = 0;
612124365Simp					}
613124365Simp				}
614107546Simp			}
615107546Simp		} else if (!ok) {
616124365Simp			ok = 1;	/* subtractive bridge: always ok */
617189844Simp#if 0
618124365Simp			if (pcib_is_nonprefetch_open(sc)) {
619189792Simp				if (start < sc->memlimit && end > sc->membase)
620189792Simp					start = sc->memlimit + 1;
621124365Simp			}
622124365Simp			if (pcib_is_prefetch_open(sc)) {
623189792Simp				if (start < sc->pmemlimit && end > sc->pmembase)
624189792Simp					start = sc->pmemlimit + 1;
625124365Simp			}
626189844Simp#endif
627106844Smdodd		}
628124365Simp		if (end < start) {
629142051Simp			device_printf(dev, "memory: end (%lx) < start (%lx)\n",
630142051Simp			    end, start);
631124365Simp			start = 0;
632124365Simp			end = 0;
633124365Simp			ok = 0;
634124365Simp		}
635124365Simp		if (!ok && bootverbose)
636124365Simp			device_printf(dev,
637164130Sjhb			    "%s%srequested unsupported memory range %#lx-%#lx "
638163805Simp			    "(decoding %#jx-%#jx, %#jx-%#jx)\n",
639164130Sjhb			    name, suffix, start, end,
640163805Simp			    (uintmax_t)sc->membase, (uintmax_t)sc->memlimit,
641163805Simp			    (uintmax_t)sc->pmembase, (uintmax_t)sc->pmemlimit);
642124365Simp		if (!ok)
643124365Simp			return (NULL);
644124365Simp		if (bootverbose)
645164130Sjhb			device_printf(dev,"%s%srequested memory range "
646142051Simp			    "0x%lx-0x%lx: good\n",
647164130Sjhb			    name, suffix, start, end);
648124365Simp		break;
64969908Smsmith
65069783Smsmith	default:
651124365Simp		break;
65269783Smsmith	}
653124365Simp	/*
654124365Simp	 * Bridge is OK decoding this resource, so pass it up.
655124365Simp	 */
656142051Simp	return (bus_generic_alloc_resource(dev, child, type, rid, start, end,
657142051Simp	    count, flags));
65869783Smsmith}
65969783Smsmith
66069783Smsmith/*
66169783Smsmith * PCIB interface.
66269783Smsmith */
663102441Sjhbint
66469783Smsmithpcib_maxslots(device_t dev)
66569783Smsmith{
66669908Smsmith    return(PCI_SLOTMAX);
66769783Smsmith}
66869783Smsmith
66969783Smsmith/*
67069783Smsmith * Since we are a child of a PCI bus, its parent must support the pcib interface.
67169783Smsmith */
672119266Simpuint32_t
673189792Simppcib_read_config(device_t dev, u_int b, u_int s, u_int f, u_int reg, int width)
67469783Smsmith{
67569783Smsmith    return(PCIB_READ_CONFIG(device_get_parent(device_get_parent(dev)), b, s, f, reg, width));
67669783Smsmith}
67769783Smsmith
678102441Sjhbvoid
679189792Simppcib_write_config(device_t dev, u_int b, u_int s, u_int f, u_int reg, uint32_t val, int width)
68069783Smsmith{
68169783Smsmith    PCIB_WRITE_CONFIG(device_get_parent(device_get_parent(dev)), b, s, f, reg, val, width);
68269783Smsmith}
68369783Smsmith
68469783Smsmith/*
68569783Smsmith * Route an interrupt across a PCI bridge.
68669783Smsmith */
687109229Sbennoint
68869783Smsmithpcib_route_interrupt(device_t pcib, device_t dev, int pin)
68969783Smsmith{
69069783Smsmith    device_t	bus;
69169783Smsmith    int		parent_intpin;
69269783Smsmith    int		intnum;
69369783Smsmith
69469783Smsmith    /*
69569783Smsmith     *
69669783Smsmith     * The PCI standard defines a swizzle of the child-side device/intpin to
69769783Smsmith     * the parent-side intpin as follows.
69869783Smsmith     *
69969783Smsmith     * device = device on child bus
70069783Smsmith     * child_intpin = intpin on child bus slot (0-3)
70169783Smsmith     * parent_intpin = intpin on parent bus slot (0-3)
70269783Smsmith     *
70369783Smsmith     * parent_intpin = (device + child_intpin) % 4
70469783Smsmith     */
705115234Sticso    parent_intpin = (pci_get_slot(dev) + (pin - 1)) % 4;
70669783Smsmith
70769783Smsmith    /*
70869783Smsmith     * Our parent is a PCI bus.  Its parent must export the pcib interface
70969783Smsmith     * which includes the ability to route interrupts.
71069783Smsmith     */
71169783Smsmith    bus = device_get_parent(pcib);
71269783Smsmith    intnum = PCIB_ROUTE_INTERRUPT(device_get_parent(bus), pcib, parent_intpin + 1);
713131398Sjhb    if (PCI_INTERRUPT_VALID(intnum) && bootverbose) {
714102977Sjhb	device_printf(pcib, "slot %d INT%c is routed to irq %d\n",
715102977Sjhb	    pci_get_slot(dev), 'A' + pin - 1, intnum);
71690554Smsmith    }
71769783Smsmith    return(intnum);
71869783Smsmith}
719107172Sjhb
720169221Sjhb/* Pass request to alloc MSI/MSI-X messages up to the parent bridge. */
721164264Sjhbint
722164264Sjhbpcib_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs)
723164264Sjhb{
724169902Sgallatin	struct pcib_softc *sc = device_get_softc(pcib);
725164264Sjhb	device_t bus;
726164264Sjhb
727165995Sjhb	if (sc->flags & PCIB_DISABLE_MSI)
728165995Sjhb		return (ENXIO);
729164264Sjhb	bus = device_get_parent(pcib);
730164264Sjhb	return (PCIB_ALLOC_MSI(device_get_parent(bus), dev, count, maxcount,
731164264Sjhb	    irqs));
732164264Sjhb}
733164264Sjhb
734169221Sjhb/* Pass request to release MSI/MSI-X messages up to the parent bridge. */
735164264Sjhbint
736164264Sjhbpcib_release_msi(device_t pcib, device_t dev, int count, int *irqs)
737164264Sjhb{
738164264Sjhb	device_t bus;
739164264Sjhb
740164264Sjhb	bus = device_get_parent(pcib);
741164264Sjhb	return (PCIB_RELEASE_MSI(device_get_parent(bus), dev, count, irqs));
742164264Sjhb}
743164264Sjhb
744164264Sjhb/* Pass request to alloc an MSI-X message up to the parent bridge. */
745164264Sjhbint
746169221Sjhbpcib_alloc_msix(device_t pcib, device_t dev, int *irq)
747164264Sjhb{
748169902Sgallatin	struct pcib_softc *sc = device_get_softc(pcib);
749164264Sjhb	device_t bus;
750164264Sjhb
751165995Sjhb	if (sc->flags & PCIB_DISABLE_MSI)
752165995Sjhb		return (ENXIO);
753164264Sjhb	bus = device_get_parent(pcib);
754169221Sjhb	return (PCIB_ALLOC_MSIX(device_get_parent(bus), dev, irq));
755164264Sjhb}
756164264Sjhb
757169221Sjhb/* Pass request to release an MSI-X message up to the parent bridge. */
758166176Sjhbint
759169221Sjhbpcib_release_msix(device_t pcib, device_t dev, int irq)
760166176Sjhb{
761166176Sjhb	device_t bus;
762166176Sjhb
763166176Sjhb	bus = device_get_parent(pcib);
764169221Sjhb	return (PCIB_RELEASE_MSIX(device_get_parent(bus), dev, irq));
765166176Sjhb}
766166176Sjhb
767169221Sjhb/* Pass request to map MSI/MSI-X message up to parent bridge. */
768164264Sjhbint
769169221Sjhbpcib_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr,
770169221Sjhb    uint32_t *data)
771164264Sjhb{
772164264Sjhb	device_t bus;
773180753Sluoqi	int error;
774164264Sjhb
775164264Sjhb	bus = device_get_parent(pcib);
776180753Sluoqi	error = PCIB_MAP_MSI(device_get_parent(bus), dev, irq, addr, data);
777180753Sluoqi	if (error)
778180753Sluoqi		return (error);
779180753Sluoqi
780180753Sluoqi	pci_ht_map_msi(pcib, *addr);
781180753Sluoqi	return (0);
782164264Sjhb}
783164264Sjhb
784211430Sjhb/* Pass request for device power state up to parent bridge. */
785211430Sjhbint
786211430Sjhbpcib_power_for_sleep(device_t pcib, device_t dev, int *pstate)
787211430Sjhb{
788211430Sjhb	device_t bus;
789211430Sjhb
790211430Sjhb	bus = device_get_parent(pcib);
791211430Sjhb	return (PCIB_POWER_FOR_SLEEP(bus, dev, pstate));
792211430Sjhb}
793211430Sjhb
794107172Sjhb/*
795107172Sjhb * Try to read the bus number of a host-PCI bridge using appropriate config
796107172Sjhb * registers.
797107172Sjhb */
798107172Sjhbint
799107172Sjhbhost_pcib_get_busno(pci_read_config_fn read_config, int bus, int slot, int func,
800119266Simp    uint8_t *busnum)
801107172Sjhb{
802119266Simp	uint32_t id;
803107172Sjhb
804107172Sjhb	id = read_config(bus, slot, func, PCIR_DEVVENDOR, 4);
805107248Sjhb	if (id == 0xffffffff)
806107172Sjhb		return (0);
807107172Sjhb
808107172Sjhb	switch (id) {
809107172Sjhb	case 0x12258086:
810107172Sjhb		/* Intel 824?? */
811107172Sjhb		/* XXX This is a guess */
812107172Sjhb		/* *busnum = read_config(bus, slot, func, 0x41, 1); */
813107172Sjhb		*busnum = bus;
814107172Sjhb		break;
815107172Sjhb	case 0x84c48086:
816107172Sjhb		/* Intel 82454KX/GX (Orion) */
817107172Sjhb		*busnum = read_config(bus, slot, func, 0x4a, 1);
818107172Sjhb		break;
819107172Sjhb	case 0x84ca8086:
820107172Sjhb		/*
821107172Sjhb		 * For the 450nx chipset, there is a whole bundle of
822107172Sjhb		 * things pretending to be host bridges. The MIOC will
823107172Sjhb		 * be seen first and isn't really a pci bridge (the
824107172Sjhb		 * actual busses are attached to the PXB's). We need to
825107172Sjhb		 * read the registers of the MIOC to figure out the
826107172Sjhb		 * bus numbers for the PXB channels.
827107172Sjhb		 *
828107172Sjhb		 * Since the MIOC doesn't have a pci bus attached, we
829107172Sjhb		 * pretend it wasn't there.
830107172Sjhb		 */
831107172Sjhb		return (0);
832107172Sjhb	case 0x84cb8086:
833107172Sjhb		switch (slot) {
834107172Sjhb		case 0x12:
835107172Sjhb			/* Intel 82454NX PXB#0, Bus#A */
836107248Sjhb			*busnum = read_config(bus, 0x10, func, 0xd0, 1);
837107172Sjhb			break;
838107172Sjhb		case 0x13:
839107172Sjhb			/* Intel 82454NX PXB#0, Bus#B */
840107248Sjhb			*busnum = read_config(bus, 0x10, func, 0xd1, 1) + 1;
841107172Sjhb			break;
842107172Sjhb		case 0x14:
843107172Sjhb			/* Intel 82454NX PXB#1, Bus#A */
844107248Sjhb			*busnum = read_config(bus, 0x10, func, 0xd3, 1);
845107172Sjhb			break;
846107172Sjhb		case 0x15:
847107172Sjhb			/* Intel 82454NX PXB#1, Bus#B */
848107248Sjhb			*busnum = read_config(bus, 0x10, func, 0xd4, 1) + 1;
849107172Sjhb			break;
850107172Sjhb		}
851107172Sjhb		break;
852107172Sjhb
853107172Sjhb		/* ServerWorks -- vendor 0x1166 */
854107172Sjhb	case 0x00051166:
855107172Sjhb	case 0x00061166:
856107172Sjhb	case 0x00081166:
857107172Sjhb	case 0x00091166:
858107172Sjhb	case 0x00101166:
859107172Sjhb	case 0x00111166:
860107172Sjhb	case 0x00171166:
861107172Sjhb	case 0x01011166:
862107172Sjhb	case 0x010f1014:
863107172Sjhb	case 0x02011166:
864107172Sjhb	case 0x03021014:
865107172Sjhb		*busnum = read_config(bus, slot, func, 0x44, 1);
866107172Sjhb		break;
867144110Sjhb
868144110Sjhb		/* Compaq/HP -- vendor 0x0e11 */
869144110Sjhb	case 0x60100e11:
870144110Sjhb		*busnum = read_config(bus, slot, func, 0xc8, 1);
871144110Sjhb		break;
872107172Sjhb	default:
873107172Sjhb		/* Don't know how to read bus number. */
874107172Sjhb		return 0;
875107172Sjhb	}
876107172Sjhb
877107172Sjhb	return 1;
878107172Sjhb}
879