xref: /freebsd/sys/dev/acpica/acpi_pcib_acpi.c (revision 2357939bc239bd5334a169b62313806178dd8f30)
1 /*-
2  * Copyright (c) 2000 Michael Smith
3  * Copyright (c) 2000 BSDi
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  *	$FreeBSD$
28  */
29 #include "opt_acpi.h"
30 #include <sys/param.h>
31 #include <sys/bus.h>
32 #include <sys/malloc.h>
33 #include <sys/kernel.h>
34 
35 #include "acpi.h"
36 
37 #include <dev/acpica/acpivar.h>
38 
39 #include <machine/pci_cfgreg.h>
40 #include <dev/pci/pcivar.h>
41 #include <dev/pci/pcib_private.h>
42 #include "pcib_if.h"
43 
44 #include <dev/acpica/acpi_pcibvar.h>
45 
46 /*
47  * Hooks for the ACPI CA debugging infrastructure
48  */
49 #define _COMPONENT	ACPI_BUS
50 ACPI_MODULE_NAME("PCI_ACPI")
51 
52 struct acpi_hpcib_softc {
53     device_t		ap_dev;
54     ACPI_HANDLE		ap_handle;
55 
56     int			ap_segment;	/* analagous to Alpha 'hose' */
57     int			ap_bus;		/* bios-assigned bus number */
58 
59     ACPI_BUFFER		ap_prt;		/* interrupt routing table */
60 };
61 
62 
63 static int		acpi_pcib_acpi_probe(device_t bus);
64 static int		acpi_pcib_acpi_attach(device_t bus);
65 static int		acpi_pcib_acpi_resume(device_t bus);
66 static int		acpi_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result);
67 static int		acpi_pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value);
68 static u_int32_t	acpi_pcib_read_config(device_t dev, int bus, int slot, int func, int reg, int bytes);
69 static void		acpi_pcib_write_config(device_t dev, int bus, int slot, int func, int reg,
70 					       u_int32_t data, int bytes);
71 static int		acpi_pcib_acpi_route_interrupt(device_t pcib,
72     device_t dev, int pin);
73 static struct resource *acpi_pcib_acpi_alloc_resource(device_t dev,
74   			    device_t child, int type, int *rid,
75 			    u_long start, u_long end, u_long count,
76 			    u_int flags);
77 
78 static device_method_t acpi_pcib_acpi_methods[] = {
79     /* Device interface */
80     DEVMETHOD(device_probe,		acpi_pcib_acpi_probe),
81     DEVMETHOD(device_attach,		acpi_pcib_acpi_attach),
82     DEVMETHOD(device_shutdown,		bus_generic_shutdown),
83     DEVMETHOD(device_suspend,		bus_generic_suspend),
84     DEVMETHOD(device_resume,		acpi_pcib_acpi_resume),
85 
86     /* Bus interface */
87     DEVMETHOD(bus_print_child,		bus_generic_print_child),
88     DEVMETHOD(bus_read_ivar,		acpi_pcib_read_ivar),
89     DEVMETHOD(bus_write_ivar,		acpi_pcib_write_ivar),
90     DEVMETHOD(bus_alloc_resource,	acpi_pcib_acpi_alloc_resource),
91     DEVMETHOD(bus_release_resource,	bus_generic_release_resource),
92     DEVMETHOD(bus_activate_resource,	bus_generic_activate_resource),
93     DEVMETHOD(bus_deactivate_resource, 	bus_generic_deactivate_resource),
94     DEVMETHOD(bus_setup_intr,		bus_generic_setup_intr),
95     DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
96 
97     /* pcib interface */
98     DEVMETHOD(pcib_maxslots,		pcib_maxslots),
99     DEVMETHOD(pcib_read_config,		acpi_pcib_read_config),
100     DEVMETHOD(pcib_write_config,	acpi_pcib_write_config),
101     DEVMETHOD(pcib_route_interrupt,	acpi_pcib_acpi_route_interrupt),
102 
103     {0, 0}
104 };
105 
106 static driver_t acpi_pcib_acpi_driver = {
107     "pcib",
108     acpi_pcib_acpi_methods,
109     sizeof(struct acpi_hpcib_softc),
110 };
111 
112 DRIVER_MODULE(acpi_pcib, acpi, acpi_pcib_acpi_driver, pcib_devclass, 0, 0);
113 MODULE_DEPEND(acpi_pcib, acpi, 1, 1, 1);
114 
115 static int
116 acpi_pcib_acpi_probe(device_t dev)
117 {
118 
119     if ((acpi_get_type(dev) == ACPI_TYPE_DEVICE) &&
120 	!acpi_disabled("pci") &&
121 	acpi_MatchHid(dev, "PNP0A03")) {
122 
123 	if (!pci_cfgregopen())
124 		return(ENXIO);
125 
126 	/*
127 	 * Set device description
128 	 */
129 	device_set_desc(dev, "ACPI Host-PCI bridge");
130 	return(0);
131     }
132     return(ENXIO);
133 }
134 
135 static int
136 acpi_pcib_acpi_attach(device_t dev)
137 {
138     struct acpi_hpcib_softc	*sc;
139     ACPI_STATUS			status;
140     u_int addr, slot, func, busok;
141     uint8_t busno;
142 
143     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
144 
145     sc = device_get_softc(dev);
146     sc->ap_dev = dev;
147     sc->ap_handle = acpi_get_handle(dev);
148 
149     /*
150      * Get our base bus number by evaluating _BBN.
151      * If this doesn't work, we assume we're bus number 0.
152      *
153      * XXX note that it may also not exist in the case where we are
154      *     meant to use a private configuration space mechanism for this bus,
155      *     so we should dig out our resources and check to see if we have
156      *     anything like that.  How do we do this?
157      * XXX If we have the requisite information, and if we don't think the
158      *     default PCI configuration space handlers can deal with this bus,
159      *     we should attach our own handler.
160      * XXX invoke _REG on this for the PCI config space address space?
161      * XXX It seems many BIOS's with multiple Host-PCI bridges do not set
162      *     _BBN correctly.  They set _BBN to zero for all bridges.  Thus,
163      *     if _BBN is zero and pcib0 already exists, we try to read our
164      *     bus number from the configuration registers at address _ADR.
165      */
166     status = acpi_GetInteger(sc->ap_handle, "_BBN", &sc->ap_bus);
167     if (ACPI_FAILURE(status)) {
168 	if (status != AE_NOT_FOUND) {
169 	    device_printf(dev, "could not evaluate _BBN - %s\n",
170 		AcpiFormatException(status));
171 	    return_VALUE(ENXIO);
172 	} else {
173 	    /* if it's not found, assume 0 */
174 	    sc->ap_bus = 0;
175 	}
176     }
177 
178     /*
179      * If the bus is zero and pcib0 already exists, read the bus number
180      * via PCI config space.
181      */
182     busok = 1;
183     if (sc->ap_bus == 0 && devclass_get_device(pcib_devclass, 0) != dev) {
184 	busok = 0;
185 	status = acpi_GetInteger(sc->ap_handle, "_ADR", &addr);
186 	if (ACPI_FAILURE(status)) {
187 	    if (status != AE_NOT_FOUND) {
188 		device_printf(dev, "could not evaluate _ADR - %s\n",
189 		    AcpiFormatException(status));
190 		return_VALUE(ENXIO);
191 	    } else
192 		device_printf(dev, "could not determine config space address\n");
193 	} else {
194 	    /* XXX: We assume bus 0. */
195 	    slot = addr >> 16;
196 	    func = addr & 0xffff;
197 	    if (bootverbose)
198 		device_printf(dev, "reading config registers from 0:%d:%d\n",
199 		    slot, func);
200 	    if (host_pcib_get_busno(pci_cfgregread, 0, slot, func, &busno) == 0)
201 		device_printf(dev, "could not read bus number from config space\n");
202 	    else {
203 		sc->ap_bus = busno;
204 		busok = 1;
205 	    }
206 	}
207     }
208 
209     /*
210      * If nothing else worked, hope that ACPI at least lays out the
211      * host-PCI bridges in order and that as a result our unit number
212      * is actually our bus number.  There are several reasons this
213      * might not be true.
214      */
215     if (busok == 0) {
216 	sc->ap_bus = device_get_unit(dev);
217 	device_printf(dev, "trying bus number %d\n", sc->ap_bus);
218     }
219 
220     /*
221      * Get our segment number by evaluating _SEG
222      * It's OK for this to not exist.
223      */
224     if (ACPI_FAILURE(status = acpi_GetInteger(sc->ap_handle, "_SEG", &sc->ap_segment))) {
225 	if (status != AE_NOT_FOUND) {
226 	    device_printf(dev, "could not evaluate _SEG - %s\n", AcpiFormatException(status));
227 	    return_VALUE(ENXIO);
228 	}
229 	/* if it's not found, assume 0 */
230 	sc->ap_segment = 0;
231     }
232 
233     return (acpi_pcib_attach(dev, &sc->ap_prt, sc->ap_bus));
234 }
235 
236 static int
237 acpi_pcib_acpi_resume(device_t dev)
238 {
239     struct acpi_hpcib_softc	*sc = device_get_softc(dev);
240 
241     return (acpi_pcib_resume(dev, &sc->ap_prt, sc->ap_bus));
242 }
243 
244 /*
245  * Support for standard PCI bridge ivars.
246  */
247 static int
248 acpi_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
249 {
250     struct acpi_hpcib_softc	*sc = device_get_softc(dev);
251 
252     switch (which) {
253     case  PCIB_IVAR_BUS:
254 	*result = sc->ap_bus;
255 	return(0);
256     case  ACPI_IVAR_HANDLE:
257 	*result = (uintptr_t)sc->ap_handle;
258 	return(0);
259     }
260     return(ENOENT);
261 }
262 
263 static int
264 acpi_pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
265 {
266     struct acpi_hpcib_softc 	*sc = device_get_softc(dev);
267 
268     switch (which) {
269     case  PCIB_IVAR_BUS:
270 	sc->ap_bus = value;
271 	return(0);
272     }
273     return(ENOENT);
274 }
275 
276 static u_int32_t
277 acpi_pcib_read_config(device_t dev, int bus, int slot, int func, int reg, int bytes)
278 {
279     return(pci_cfgregread(bus, slot, func, reg, bytes));
280 }
281 
282 static void
283 acpi_pcib_write_config(device_t dev, int bus, int slot, int func, int reg, u_int32_t data, int bytes)
284 {
285     pci_cfgregwrite(bus, slot, func, reg, data, bytes);
286 }
287 
288 static int
289 acpi_pcib_acpi_route_interrupt(device_t pcib, device_t dev, int pin)
290 {
291     struct acpi_hpcib_softc *sc;
292 
293     /* find the bridge softc */
294     sc = device_get_softc(pcib);
295     return (acpi_pcib_route_interrupt(pcib, dev, pin, &sc->ap_prt));
296 }
297 
298 struct resource *
299 acpi_pcib_acpi_alloc_resource(device_t dev, device_t child, int type, int *rid,
300   u_long start, u_long end, u_long count, u_int flags)
301 {
302 	/*
303 	 * If no memory preference is given, use upper 256MB slot most
304 	 * bioses use for their memory window.  Typically other bridges
305 	 * before us get in the way to assert their preferences on memory.
306 	 * Hardcoding like this sucks, so a more MD/MI way needs to be
307 	 * found to do it.
308 	 */
309 	if (type == SYS_RES_MEMORY && start == 0UL && end == ~0UL)
310 		start = 0xf0000000;
311 	return (bus_generic_alloc_resource(dev, child, type, rid, start, end,
312 	    count, flags));
313 }
314