acpi_pcib_acpi.c revision 166176
1132718Skan/*- 2132718Skan * Copyright (c) 2000 Michael Smith 3169689Skan * Copyright (c) 2000 BSDi 450397Sobrien * All rights reserved. 5132718Skan * 650397Sobrien * Redistribution and use in source and binary forms, with or without 790075Sobrien * modification, are permitted provided that the following conditions 850397Sobrien * are met: 990075Sobrien * 1. Redistributions of source code must retain the above copyright 1090075Sobrien * notice, this list of conditions and the following disclaimer. 1190075Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1290075Sobrien * notice, this list of conditions and the following disclaimer in the 1350397Sobrien * documentation and/or other materials provided with the distribution. 1490075Sobrien * 1590075Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1690075Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1790075Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1850397Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1950397Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2090075Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21169689Skan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22169689Skan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2350397Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24117395Skan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25117395Skan * SUCH DAMAGE. 26117395Skan */ 27117395Skan 28117395Skan#include <sys/cdefs.h> 29132718Skan__FBSDID("$FreeBSD: head/sys/dev/acpica/acpi_pcib_acpi.c 166176 2007-01-22 21:48:44Z jhb $"); 30117395Skan 31132718Skan#include "opt_acpi.h" 32169689Skan#include <sys/param.h> 33169689Skan#include <sys/bus.h> 34169689Skan#include <sys/kernel.h> 35169689Skan#include <sys/malloc.h> 36169689Skan#include <sys/module.h> 37169689Skan#include <sys/sysctl.h> 38169689Skan 39132718Skan#include <contrib/dev/acpica/acpi.h> 40132718Skan#include <dev/acpica/acpivar.h> 41132718Skan 42132718Skan#include <machine/pci_cfgreg.h> 43132718Skan#include <dev/pci/pcivar.h> 44132718Skan#include <dev/pci/pcib_private.h> 45169689Skan#include "pcib_if.h" 46169689Skan 47132718Skan#include <dev/acpica/acpi_pcibvar.h> 48132718Skan 49132718Skan/* Hooks for the ACPI CA debugging infrastructure. */ 50132718Skan#define _COMPONENT ACPI_BUS 51132718SkanACPI_MODULE_NAME("PCI_ACPI") 52132718Skan 53132718Skanstruct acpi_hpcib_softc { 54132718Skan device_t ap_dev; 55132718Skan ACPI_HANDLE ap_handle; 56132718Skan int ap_flags; 57132718Skan 58132718Skan int ap_segment; /* analagous to Alpha 'hose' */ 59132718Skan int ap_bus; /* bios-assigned bus number */ 60132718Skan 61132718Skan ACPI_BUFFER ap_prt; /* interrupt routing table */ 62132718Skan}; 63132718Skan 64132718Skanstatic int acpi_pcib_acpi_probe(device_t bus); 65132718Skanstatic int acpi_pcib_acpi_attach(device_t bus); 66132718Skanstatic int acpi_pcib_acpi_resume(device_t bus); 67132718Skanstatic int acpi_pcib_read_ivar(device_t dev, device_t child, 68132718Skan int which, uintptr_t *result); 69132718Skanstatic int acpi_pcib_write_ivar(device_t dev, device_t child, 70132718Skan int which, uintptr_t value); 71132718Skanstatic uint32_t acpi_pcib_read_config(device_t dev, int bus, int slot, 72132718Skan int func, int reg, int bytes); 73132718Skanstatic void acpi_pcib_write_config(device_t dev, int bus, int slot, 74132718Skan int func, int reg, uint32_t data, int bytes); 75132718Skanstatic int acpi_pcib_acpi_route_interrupt(device_t pcib, 76132718Skan device_t dev, int pin); 77132718Skanstatic int acpi_pcib_alloc_msi(device_t pcib, device_t dev, 78132718Skan int count, int maxcount, int *irqs); 79132718Skanstatic int acpi_pcib_alloc_msix(device_t pcib, device_t dev, 80132718Skan int index, int *irq); 81132718Skanstatic struct resource *acpi_pcib_acpi_alloc_resource(device_t dev, 82132718Skan device_t child, int type, int *rid, 83132718Skan u_long start, u_long end, u_long count, 84132718Skan u_int flags); 85132718Skan 86132718Skanstatic device_method_t acpi_pcib_acpi_methods[] = { 87132718Skan /* Device interface */ 88132718Skan DEVMETHOD(device_probe, acpi_pcib_acpi_probe), 89132718Skan DEVMETHOD(device_attach, acpi_pcib_acpi_attach), 90132718Skan DEVMETHOD(device_shutdown, bus_generic_shutdown), 91132718Skan DEVMETHOD(device_suspend, bus_generic_suspend), 92132718Skan DEVMETHOD(device_resume, acpi_pcib_acpi_resume), 93132718Skan 94132718Skan /* Bus interface */ 95132718Skan DEVMETHOD(bus_print_child, bus_generic_print_child), 96132718Skan DEVMETHOD(bus_read_ivar, acpi_pcib_read_ivar), 97132718Skan DEVMETHOD(bus_write_ivar, acpi_pcib_write_ivar), 98132718Skan DEVMETHOD(bus_alloc_resource, acpi_pcib_acpi_alloc_resource), 99132718Skan DEVMETHOD(bus_release_resource, bus_generic_release_resource), 100132718Skan DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 101132718Skan DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 102132718Skan DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 103132718Skan DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 104132718Skan 105132718Skan /* pcib interface */ 106132718Skan DEVMETHOD(pcib_maxslots, pcib_maxslots), 107132718Skan DEVMETHOD(pcib_read_config, acpi_pcib_read_config), 108132718Skan DEVMETHOD(pcib_write_config, acpi_pcib_write_config), 109132718Skan DEVMETHOD(pcib_route_interrupt, acpi_pcib_acpi_route_interrupt), 110132718Skan DEVMETHOD(pcib_alloc_msi, acpi_pcib_alloc_msi), 111132718Skan DEVMETHOD(pcib_release_msi, pcib_release_msi), 112132718Skan DEVMETHOD(pcib_alloc_msix, acpi_pcib_alloc_msix), 113132718Skan DEVMETHOD(pcib_remap_msix, pcib_remap_msix), 114132718Skan DEVMETHOD(pcib_release_msix, pcib_release_msix), 115132718Skan 116132718Skan {0, 0} 117132718Skan}; 118132718Skan 119132718Skanstatic devclass_t pcib_devclass; 120132718Skan 121132718SkanDEFINE_CLASS_0(pcib, acpi_pcib_acpi_driver, acpi_pcib_acpi_methods, 122132718Skan sizeof(struct acpi_hpcib_softc)); 123132718SkanDRIVER_MODULE(acpi_pcib, acpi, acpi_pcib_acpi_driver, pcib_devclass, 0, 0); 124132718SkanMODULE_DEPEND(acpi_pcib, acpi, 1, 1, 1); 125132718Skan 126132718Skanstatic int 127132718Skanacpi_pcib_acpi_probe(device_t dev) 128132718Skan{ 129132718Skan static char *pcib_ids[] = { "PNP0A03", NULL }; 130132718Skan 131132718Skan if (acpi_disabled("pcib") || 132132718Skan ACPI_ID_PROBE(device_get_parent(dev), dev, pcib_ids) == NULL) 133132718Skan return (ENXIO); 134132718Skan 135132718Skan if (pci_cfgregopen() == 0) 136132718Skan return (ENXIO); 137132718Skan device_set_desc(dev, "ACPI Host-PCI bridge"); 138132718Skan return (0); 139132718Skan} 140132718Skan 141132718Skanstatic int 142132718Skanacpi_pcib_acpi_attach(device_t dev) 143132718Skan{ 144132718Skan struct acpi_hpcib_softc *sc; 145132718Skan ACPI_STATUS status; 146132718Skan u_int addr, slot, func, busok; 147132718Skan uint8_t busno; 148132718Skan 149132718Skan ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 150132718Skan 151132718Skan sc = device_get_softc(dev); 152132718Skan sc->ap_dev = dev; 153132718Skan sc->ap_handle = acpi_get_handle(dev); 154132718Skan 155132718Skan /* 156132718Skan * Get our base bus number by evaluating _BBN. 157132718Skan * If this doesn't work, we assume we're bus number 0. 158132718Skan * 159132718Skan * XXX note that it may also not exist in the case where we are 160132718Skan * meant to use a private configuration space mechanism for this bus, 161132718Skan * so we should dig out our resources and check to see if we have 162132718Skan * anything like that. How do we do this? 16390075Sobrien * XXX If we have the requisite information, and if we don't think the 16490075Sobrien * default PCI configuration space handlers can deal with this bus, 16550397Sobrien * we should attach our own handler. 166132718Skan * XXX invoke _REG on this for the PCI config space address space? 167132718Skan * XXX It seems many BIOS's with multiple Host-PCI bridges do not set 16850397Sobrien * _BBN correctly. They set _BBN to zero for all bridges. Thus, 169132718Skan * if _BBN is zero and pcib0 already exists, we try to read our 170132718Skan * bus number from the configuration registers at address _ADR. 171132718Skan */ 172132718Skan status = acpi_GetInteger(sc->ap_handle, "_BBN", &sc->ap_bus); 173132718Skan if (ACPI_FAILURE(status)) { 174132718Skan if (status != AE_NOT_FOUND) { 175132718Skan device_printf(dev, "could not evaluate _BBN - %s\n", 176132718Skan AcpiFormatException(status)); 177132718Skan return_VALUE (ENXIO); 178132718Skan } else { 179132718Skan /* If it's not found, assume 0. */ 180132718Skan sc->ap_bus = 0; 181132718Skan } 182132718Skan } 183132718Skan 184132718Skan /* 185132718Skan * If the bus is zero and pcib0 already exists, read the bus number 186132718Skan * via PCI config space. 187132718Skan */ 188132718Skan busok = 1; 189132718Skan if (sc->ap_bus == 0 && devclass_get_device(pcib_devclass, 0) != dev) { 190132718Skan busok = 0; 191132718Skan status = acpi_GetInteger(sc->ap_handle, "_ADR", &addr); 192132718Skan if (ACPI_FAILURE(status)) { 193132718Skan if (status != AE_NOT_FOUND) { 194132718Skan device_printf(dev, "could not evaluate _ADR - %s\n", 195132718Skan AcpiFormatException(status)); 19650397Sobrien return_VALUE (ENXIO); 19750397Sobrien } else 198169689Skan device_printf(dev, "couldn't find _ADR\n"); 199132718Skan } else { 200132718Skan /* XXX: We assume bus 0. */ 201132718Skan slot = ACPI_ADR_PCI_SLOT(addr); 202132718Skan func = ACPI_ADR_PCI_FUNC(addr); 20350397Sobrien if (bootverbose) 204132718Skan device_printf(dev, "reading config registers from 0:%d:%d\n", 205132718Skan slot, func); 20650397Sobrien if (host_pcib_get_busno(pci_cfgregread, 0, slot, func, &busno) == 0) 207132718Skan device_printf(dev, "couldn't read bus number from cfg space\n"); 208132718Skan else { 209132718Skan sc->ap_bus = busno; 210132718Skan busok = 1; 211132718Skan } 212132718Skan } 213132718Skan } 214132718Skan 215132718Skan /* 216132718Skan * If nothing else worked, hope that ACPI at least lays out the 217169689Skan * host-PCI bridges in order and that as a result our unit number 218132718Skan * is actually our bus number. There are several reasons this 21950397Sobrien * might not be true. 220132718Skan */ 221132718Skan if (busok == 0) { 222132718Skan sc->ap_bus = device_get_unit(dev); 223132718Skan device_printf(dev, "trying bus number %d\n", sc->ap_bus); 224132718Skan } 22550397Sobrien 226132718Skan /* 22750397Sobrien * Get our segment number by evaluating _SEG 228146895Skan * It's OK for this to not exist. 229146895Skan */ 230146895Skan status = acpi_GetInteger(sc->ap_handle, "_SEG", &sc->ap_segment); 231146895Skan if (ACPI_FAILURE(status)) { 232146895Skan if (status != AE_NOT_FOUND) { 233132718Skan device_printf(dev, "could not evaluate _SEG - %s\n", 234146895Skan AcpiFormatException(status)); 235169689Skan return_VALUE (ENXIO); 236146895Skan } 237132718Skan /* If it's not found, assume 0. */ 238132718Skan sc->ap_segment = 0; 239132718Skan } 240132718Skan 241132718Skan return (acpi_pcib_attach(dev, &sc->ap_prt, sc->ap_bus)); 242132718Skan} 243132718Skan 244132718Skanstatic int 245132718Skanacpi_pcib_acpi_resume(device_t dev) 246132718Skan{ 247132718Skan 248132718Skan return (acpi_pcib_resume(dev)); 249132718Skan} 250132718Skan 25150397Sobrien/* 252132718Skan * Support for standard PCI bridge ivars. 253132718Skan */ 254132718Skanstatic int 25590075Sobrienacpi_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 256146895Skan{ 257146895Skan struct acpi_hpcib_softc *sc = device_get_softc(dev); 258146895Skan 259146895Skan switch (which) { 260132718Skan case PCIB_IVAR_BUS: 26190075Sobrien *result = sc->ap_bus; 262146895Skan return (0); 263146895Skan case ACPI_IVAR_HANDLE: 264146895Skan *result = (uintptr_t)sc->ap_handle; 265146895Skan return (0); 266146895Skan case ACPI_IVAR_FLAGS: 267146895Skan *result = (uintptr_t)sc->ap_flags; 268132718Skan return (0); 269132718Skan } 270132718Skan return (ENOENT); 27190075Sobrien} 272132718Skan 273132718Skanstatic int 274132718Skanacpi_pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value) 27590075Sobrien{ 276132718Skan struct acpi_hpcib_softc *sc = device_get_softc(dev); 277132718Skan 278132718Skan switch (which) { 27990075Sobrien case PCIB_IVAR_BUS: 280132718Skan sc->ap_bus = value; 281132718Skan return (0); 282132718Skan case ACPI_IVAR_HANDLE: 283132718Skan sc->ap_handle = (ACPI_HANDLE)value; 284132718Skan return (0); 28550397Sobrien case ACPI_IVAR_FLAGS: 286132718Skan sc->ap_flags = (int)value; 287132718Skan return (0); 288132718Skan } 289132718Skan return (ENOENT); 290132718Skan} 291132718Skan 29250397Sobrienstatic uint32_t 293132718Skanacpi_pcib_read_config(device_t dev, int bus, int slot, int func, int reg, 294132718Skan int bytes) 295169689Skan{ 296169689Skan return (pci_cfgregread(bus, slot, func, reg, bytes)); 29750397Sobrien} 298132718Skan 299132718Skanstatic void 300132718Skanacpi_pcib_write_config(device_t dev, int bus, int slot, int func, int reg, 301132718Skan uint32_t data, int bytes) 302132718Skan{ 303132718Skan pci_cfgregwrite(bus, slot, func, reg, data, bytes); 304132718Skan} 305132718Skan 306132718Skanstatic int 307132718Skanacpi_pcib_acpi_route_interrupt(device_t pcib, device_t dev, int pin) 308132718Skan{ 309132718Skan struct acpi_hpcib_softc *sc = device_get_softc(pcib); 310132718Skan 311132718Skan return (acpi_pcib_route_interrupt(pcib, dev, pin, &sc->ap_prt)); 312132718Skan} 313132718Skan 31450397Sobrienstatic int 315132718Skanacpi_pcib_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, 316132718Skan int *irqs) 317132718Skan{ 318132718Skan device_t bus; 319132718Skan 320132718Skan bus = device_get_parent(pcib); 321132718Skan return (PCIB_ALLOC_MSI(device_get_parent(bus), dev, count, maxcount, 322132718Skan irqs)); 323132718Skan} 324132718Skan 325132718Skanstatic int 326132718Skanacpi_pcib_alloc_msix(device_t pcib, device_t dev, int index, int *irq) 327132718Skan{ 328132718Skan device_t bus; 329132718Skan 330132718Skan bus = device_get_parent(pcib); 331132718Skan return (PCIB_ALLOC_MSIX(device_get_parent(bus), dev, index, irq)); 332132718Skan} 33350397Sobrien 334132718Skanstatic u_long acpi_host_mem_start = 0x80000000; 335132718SkanTUNABLE_ULONG("hw.acpi.host_mem_start", &acpi_host_mem_start); 336132718Skan 337132718Skanstruct resource * 338132718Skanacpi_pcib_acpi_alloc_resource(device_t dev, device_t child, int type, int *rid, 339132718Skan u_long start, u_long end, u_long count, u_int flags) 340132718Skan{ 341132718Skan /* 342132718Skan * If no memory preference is given, use upper 32MB slot most 343132718Skan * bioses use for their memory window. Typically other bridges 344132718Skan * before us get in the way to assert their preferences on memory. 345132718Skan * Hardcoding like this sucks, so a more MD/MI way needs to be 346132718Skan * found to do it. This is typically only used on older laptops 347132718Skan * that don't have pci busses behind pci bridge, so assuming > 32MB 348132718Skan * is liekly OK. 349132718Skan */ 350132718Skan if (type == SYS_RES_MEMORY && start == 0UL && end == ~0UL) 351132718Skan start = acpi_host_mem_start; 352132718Skan if (type == SYS_RES_IOPORT && start == 0UL && end == ~0UL) 353132718Skan start = 0x1000; 354132718Skan return (bus_generic_alloc_resource(dev, child, type, rid, start, end, 355132718Skan count, flags)); 356132718Skan} 35750397Sobrien