acpica, pci_host_generic_acpi: redo pci_host_generic_acpi.c
This is a major update for pci_host_generic_acpi.c, the current implementation has some gaps that are better fixed up in one go. The changes are to: * Follow x86 method of not adding PCI resources to PCI host bridge in ACPI code. This has been moved to pci_host_generic_acpi.c, where we walk thru its resources of the host bridge and add them. * Fixup code in pci_host_generic_acpi.c to read all decoded ranges and update the 'ranges' property. This allows us to share most of the code with generic implementation (and the FDT one). * Parse and setup IO ranges and bus ranges when walking the resources above. Drop most of the changes related to this from acpica code. * Add the ECAM memory area as mem resource 0. Implement the logic to get the ECAM area from MCFG (using bus range which we now decode), or from _CBA (using _BBN/bus range). Drop aarch64 ifdefs from acpica code which did part of this. * Switch resource activation to similar code as FDT implementation, this can be moved into generic implementation in a later pass. * Drop the mechanism of using the 7th bit of bus number as the domain, this is not correct and will work only in very specific cases. Use _SEG as PCI domain and use the bus ranges of the host bridge to provide start bus number. This commit should not make any functional change to dev/acpica/acpi.c for other architectures, almost all the changes there are to revert earlier additions in this file done for aarch64. Reviewed by: andrew Differential Revision: https://reviews.freebsd.org/D17791
This commit is contained in:
parent
d4d6ad3f05
commit
185c34f7c8
@ -179,9 +179,7 @@ static int acpi_child_location_str_method(device_t acdev, device_t child,
|
||||
char *buf, size_t buflen);
|
||||
static int acpi_child_pnpinfo_str_method(device_t acdev, device_t child,
|
||||
char *buf, size_t buflen);
|
||||
#if defined(__i386__) || defined(__amd64__)
|
||||
static void acpi_enable_pcie(void);
|
||||
#endif
|
||||
static void acpi_hint_device_unit(device_t acdev, device_t child,
|
||||
const char *name, int *unitp);
|
||||
static void acpi_reset_interfaces(device_t dev);
|
||||
@ -502,10 +500,8 @@ acpi_attach(device_t dev)
|
||||
goto out;
|
||||
}
|
||||
|
||||
#if defined(__i386__) || defined(__amd64__)
|
||||
/* Handle MCFG table if present. */
|
||||
acpi_enable_pcie();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Note that some systems (specifically, those with namespace evaluation
|
||||
@ -1286,11 +1282,10 @@ acpi_set_resource(device_t dev, device_t child, int type, int rid,
|
||||
struct acpi_softc *sc = device_get_softc(dev);
|
||||
struct acpi_device *ad = device_get_ivars(child);
|
||||
struct resource_list *rl = &ad->ad_rl;
|
||||
#if defined(__i386__) || defined(__amd64__)
|
||||
ACPI_DEVICE_INFO *devinfo;
|
||||
#endif
|
||||
rman_res_t end;
|
||||
|
||||
int allow;
|
||||
|
||||
/* Ignore IRQ resources for PCI link devices. */
|
||||
if (type == SYS_RES_IRQ &&
|
||||
ACPI_ID_PROBE(dev, child, pcilink_ids, NULL) <= 0)
|
||||
@ -1305,11 +1300,15 @@ acpi_set_resource(device_t dev, device_t child, int type, int rid,
|
||||
* x86 of a PCI bridge claiming the I/O ports used for PCI config
|
||||
* access.
|
||||
*/
|
||||
#if defined(__i386__) || defined(__amd64__)
|
||||
if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
|
||||
if (ACPI_SUCCESS(AcpiGetObjectInfo(ad->ad_handle, &devinfo))) {
|
||||
if ((devinfo->Flags & ACPI_PCI_ROOT_BRIDGE) != 0) {
|
||||
if (!(type == SYS_RES_IOPORT && start == CONF1_ADDR_PORT)) {
|
||||
#if defined(__i386__) || defined(__amd64__)
|
||||
allow = (type == SYS_RES_IOPORT && start == CONF1_ADDR_PORT);
|
||||
#else
|
||||
allow = 0;
|
||||
#endif
|
||||
if (!allow) {
|
||||
AcpiOsFree(devinfo);
|
||||
return (0);
|
||||
}
|
||||
@ -1317,7 +1316,6 @@ acpi_set_resource(device_t dev, device_t child, int type, int rid,
|
||||
AcpiOsFree(devinfo);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef INTRNG
|
||||
/* map with default for now */
|
||||
@ -1874,15 +1872,18 @@ acpi_isa_pnp_probe(device_t bus, device_t child, struct isa_pnp_id *ids)
|
||||
return_VALUE (result);
|
||||
}
|
||||
|
||||
#if defined(__i386__) || defined(__amd64__)
|
||||
/*
|
||||
* Look for a MCFG table. If it is present, use the settings for
|
||||
* domain (segment) 0 to setup PCI config space access via the memory
|
||||
* map.
|
||||
*
|
||||
* On non-x86 architectures (arm64 for now), this will be done from the
|
||||
* PCI host bridge driver.
|
||||
*/
|
||||
static void
|
||||
acpi_enable_pcie(void)
|
||||
{
|
||||
#if defined(__i386__) || defined(__amd64__)
|
||||
ACPI_TABLE_HEADER *hdr;
|
||||
ACPI_MCFG_ALLOCATION *alloc, *end;
|
||||
ACPI_STATUS status;
|
||||
@ -1901,31 +1902,8 @@ acpi_enable_pcie(void)
|
||||
}
|
||||
alloc++;
|
||||
}
|
||||
}
|
||||
#elif defined(__aarch64__)
|
||||
static void
|
||||
acpi_enable_pcie(device_t child, int segment)
|
||||
{
|
||||
ACPI_TABLE_HEADER *hdr;
|
||||
ACPI_MCFG_ALLOCATION *alloc, *end;
|
||||
ACPI_STATUS status;
|
||||
|
||||
status = AcpiGetTable(ACPI_SIG_MCFG, 1, &hdr);
|
||||
if (ACPI_FAILURE(status))
|
||||
return;
|
||||
|
||||
end = (ACPI_MCFG_ALLOCATION *)((char *)hdr + hdr->Length);
|
||||
alloc = (ACPI_MCFG_ALLOCATION *)((ACPI_TABLE_MCFG *)hdr + 1);
|
||||
while (alloc < end) {
|
||||
if (alloc->PciSegment == segment) {
|
||||
bus_set_resource(child, SYS_RES_MEMORY, 0,
|
||||
alloc->Address, 0x10000000);
|
||||
return;
|
||||
}
|
||||
alloc++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan all of the ACPI namespace and attach child devices.
|
||||
@ -2016,9 +1994,6 @@ acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status)
|
||||
{
|
||||
ACPI_DEVICE_INFO *devinfo;
|
||||
struct acpi_device *ad;
|
||||
#ifdef __aarch64__
|
||||
int segment;
|
||||
#endif
|
||||
struct acpi_prw_data prw;
|
||||
ACPI_OBJECT_TYPE type;
|
||||
ACPI_HANDLE h;
|
||||
@ -2121,13 +2096,6 @@ acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status)
|
||||
ad->ad_cls_class = strtoul(devinfo->ClassCode.String,
|
||||
NULL, 16);
|
||||
}
|
||||
#ifdef __aarch64__
|
||||
if ((devinfo->Flags & ACPI_PCI_ROOT_BRIDGE) != 0) {
|
||||
if (ACPI_SUCCESS(acpi_GetInteger(handle, "_SEG", &segment))) {
|
||||
acpi_enable_pcie(child, segment);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
AcpiOsFree(devinfo);
|
||||
}
|
||||
break;
|
||||
|
@ -63,8 +63,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/intr.h>
|
||||
|
||||
#include "pcib_if.h"
|
||||
|
||||
int pci_host_generic_acpi_attach(device_t);
|
||||
#include "acpi_bus_if.h"
|
||||
|
||||
/* Assembling ECAM Configuration Address */
|
||||
#define PCIE_BUS_SHIFT 20
|
||||
@ -100,6 +99,9 @@ static int generic_pcie_acpi_probe(device_t dev);
|
||||
static ACPI_STATUS pci_host_generic_acpi_parse_resource(ACPI_RESOURCE *, void *);
|
||||
static int generic_pcie_acpi_read_ivar(device_t, device_t, int, uintptr_t *);
|
||||
|
||||
/*
|
||||
* generic_pcie_acpi_probe - look for root bridge flag
|
||||
*/
|
||||
static int
|
||||
generic_pcie_acpi_probe(device_t dev)
|
||||
{
|
||||
@ -119,81 +121,201 @@ generic_pcie_acpi_probe(device_t dev)
|
||||
return (BUS_PROBE_GENERIC);
|
||||
}
|
||||
|
||||
int
|
||||
/*
|
||||
* pci_host_generic_acpi_parse_resource - parse PCI memory, IO and bus spaces
|
||||
* 'produced' by this bridge
|
||||
*/
|
||||
static ACPI_STATUS
|
||||
pci_host_generic_acpi_parse_resource(ACPI_RESOURCE *res, void *arg)
|
||||
{
|
||||
device_t dev = (device_t)arg;
|
||||
struct generic_pcie_acpi_softc *sc;
|
||||
struct rman *rm;
|
||||
rman_res_t min, max, off;
|
||||
int r;
|
||||
|
||||
rm = NULL;
|
||||
sc = device_get_softc(dev);
|
||||
r = sc->base.nranges;
|
||||
switch (res->Type) {
|
||||
case ACPI_RESOURCE_TYPE_ADDRESS16:
|
||||
min = res->Data.Address16.Address.Minimum;
|
||||
max = res->Data.Address16.Address.Maximum;
|
||||
break;
|
||||
case ACPI_RESOURCE_TYPE_ADDRESS32:
|
||||
min = res->Data.Address32.Address.Minimum;
|
||||
max = res->Data.Address32.Address.Maximum;
|
||||
off = res->Data.Address32.Address.TranslationOffset;
|
||||
break;
|
||||
case ACPI_RESOURCE_TYPE_ADDRESS64:
|
||||
if (res->Data.Address.ResourceType != ACPI_MEMORY_RANGE)
|
||||
break;
|
||||
min = res->Data.Address64.Address.Minimum;
|
||||
max = res->Data.Address64.Address.Maximum;
|
||||
off = res->Data.Address64.Address.TranslationOffset;
|
||||
break;
|
||||
default:
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
/* Save detected ranges */
|
||||
if (res->Data.Address.ResourceType == ACPI_MEMORY_RANGE ||
|
||||
res->Data.Address.ResourceType == ACPI_IO_RANGE) {
|
||||
sc->base.ranges[r].pci_base = min;
|
||||
sc->base.ranges[r].phys_base = min + off;
|
||||
sc->base.ranges[r].size = max - min + 1;
|
||||
if (res->Data.Address.ResourceType == ACPI_MEMORY_RANGE)
|
||||
sc->base.ranges[r].flags |= FLAG_MEM;
|
||||
else if (res->Data.Address.ResourceType == ACPI_IO_RANGE)
|
||||
sc->base.ranges[r].flags |= FLAG_IO;
|
||||
sc->base.nranges++;
|
||||
} else if (res->Data.Address.ResourceType == ACPI_BUS_NUMBER_RANGE) {
|
||||
sc->base.bus_start = min;
|
||||
sc->base.bus_end = max;
|
||||
}
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
pci_host_acpi_get_ecam_resource(device_t dev)
|
||||
{
|
||||
struct generic_pcie_acpi_softc *sc;
|
||||
struct acpi_device *ad;
|
||||
struct resource_list *rl;
|
||||
ACPI_TABLE_HEADER *hdr;
|
||||
ACPI_MCFG_ALLOCATION *mcfg_entry, *mcfg_end;
|
||||
ACPI_HANDLE handle;
|
||||
ACPI_STATUS status;
|
||||
rman_res_t base, start, end;
|
||||
int found, val;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
handle = acpi_get_handle(dev);
|
||||
|
||||
/* Try MCFG first */
|
||||
status = AcpiGetTable(ACPI_SIG_MCFG, 1, &hdr);
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
found = FALSE;
|
||||
mcfg_end = (ACPI_MCFG_ALLOCATION *)((char *)hdr + hdr->Length);
|
||||
mcfg_entry = (ACPI_MCFG_ALLOCATION *)((ACPI_TABLE_MCFG *)hdr + 1);
|
||||
while (mcfg_entry < mcfg_end && !found) {
|
||||
if (mcfg_entry->PciSegment == sc->base.ecam &&
|
||||
mcfg_entry->StartBusNumber <= sc->base.bus_start &&
|
||||
mcfg_entry->EndBusNumber >= sc->base.bus_start)
|
||||
found = TRUE;
|
||||
else
|
||||
mcfg_entry++;
|
||||
}
|
||||
if (found) {
|
||||
if (mcfg_entry->EndBusNumber < sc->base.bus_end) {
|
||||
device_printf(dev, "bus end mismatch! expected %d found %d.\n",
|
||||
sc->base.bus_end, (int)mcfg_entry->EndBusNumber);
|
||||
sc->base.bus_end = mcfg_entry->EndBusNumber;
|
||||
}
|
||||
base = mcfg_entry->Address;
|
||||
} else {
|
||||
device_printf(dev, "MCFG exists, but does not have bus %d-%d\n",
|
||||
sc->base.bus_start, sc->base.bus_end);
|
||||
return (ENXIO);
|
||||
}
|
||||
} else {
|
||||
status = acpi_GetInteger(handle, "_CBA", &val);
|
||||
if (ACPI_SUCCESS(status))
|
||||
base = val;
|
||||
else
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
/* add as MEM rid 0 */
|
||||
ad = device_get_ivars(dev);
|
||||
rl = &ad->ad_rl;
|
||||
start = base + (sc->base.bus_start << PCIE_BUS_SHIFT);
|
||||
end = base + ((sc->base.bus_end + 1) << PCIE_BUS_SHIFT) - 1;
|
||||
resource_list_add(rl, SYS_RES_MEMORY, 0, start, end, end - start + 1);
|
||||
if (bootverbose)
|
||||
device_printf(dev, "ECAM for bus %d-%d at mem %jx-%jx\n",
|
||||
sc->base.bus_start, sc->base.bus_end, start, end);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pci_host_generic_acpi_attach(device_t dev)
|
||||
{
|
||||
struct generic_pcie_acpi_softc *sc;
|
||||
ACPI_HANDLE handle;
|
||||
uint64_t phys_base;
|
||||
uint64_t pci_base;
|
||||
uint64_t size;
|
||||
ACPI_STATUS status;
|
||||
int error, bus_start;
|
||||
int error;
|
||||
int tuple;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
handle = acpi_get_handle(dev);
|
||||
|
||||
/* Get Start bus number for the PCI host bus is from _BBN method */
|
||||
status = acpi_GetInteger(handle, "_BBN", &sc->base.bus_start);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
device_printf(dev, "No _BBN, using start bus 0\n");
|
||||
sc->base.bus_start = 0;
|
||||
}
|
||||
sc->base.bus_end = 255;
|
||||
|
||||
/* Get PCI Segment (domain) needed for MCFG lookup */
|
||||
status = acpi_GetInteger(handle, "_SEG", &sc->base.ecam);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
device_printf(dev, "No _SEG for PCI Bus, using segment 0\n");
|
||||
sc->base.ecam = 0;
|
||||
}
|
||||
|
||||
/* Bus decode ranges */
|
||||
status = AcpiWalkResources(handle, "_CRS",
|
||||
pci_host_generic_acpi_parse_resource, (void *)dev);
|
||||
if (ACPI_FAILURE(status))
|
||||
return (ENXIO);
|
||||
|
||||
/* Coherency attribute */
|
||||
if (ACPI_FAILURE(acpi_GetInteger(handle, "_CCA", &sc->base.coherent)))
|
||||
sc->base.coherent = 0;
|
||||
if (bootverbose)
|
||||
device_printf(dev, "Bus is%s cache-coherent\n",
|
||||
sc->base.coherent ? "" : " not");
|
||||
|
||||
if (!ACPI_FAILURE(acpi_GetInteger(handle, "_BBN", &bus_start))) {
|
||||
sc->base.ecam = bus_start >> 7;
|
||||
sc->base.bus_start = bus_start & 0x7F;
|
||||
} else {
|
||||
sc->base.ecam = 0;
|
||||
sc->base.bus_start = 0;
|
||||
}
|
||||
sc->base.bus_end = 0xFF;
|
||||
|
||||
/* add config space resource */
|
||||
pci_host_acpi_get_ecam_resource(dev);
|
||||
acpi_pcib_fetch_prt(dev, &sc->ap_prt);
|
||||
|
||||
error = pci_host_generic_core_attach(dev);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
status = AcpiWalkResources(handle, "_CRS",
|
||||
pci_host_generic_acpi_parse_resource, (void *)dev);
|
||||
|
||||
if (ACPI_FAILURE(status))
|
||||
return (ENXIO);
|
||||
for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) {
|
||||
phys_base = sc->base.ranges[tuple].phys_base;
|
||||
pci_base = sc->base.ranges[tuple].pci_base;
|
||||
size = sc->base.ranges[tuple].size;
|
||||
if (phys_base == 0 || size == 0)
|
||||
continue; /* empty range element */
|
||||
if (sc->base.ranges[tuple].flags & FLAG_MEM) {
|
||||
error = rman_manage_region(&sc->base.mem_rman,
|
||||
phys_base, phys_base + size - 1);
|
||||
} else if (sc->base.ranges[tuple].flags & FLAG_IO) {
|
||||
error = rman_manage_region(&sc->base.io_rman,
|
||||
pci_base + PCI_IO_WINDOW_OFFSET,
|
||||
pci_base + PCI_IO_WINDOW_OFFSET + size - 1);
|
||||
} else
|
||||
continue;
|
||||
if (error) {
|
||||
device_printf(dev, "rman_manage_region() failed."
|
||||
"error = %d\n", error);
|
||||
rman_fini(&sc->base.mem_rman);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
|
||||
device_add_child(dev, "pci", -1);
|
||||
return (bus_generic_attach(dev));
|
||||
}
|
||||
|
||||
static ACPI_STATUS
|
||||
pci_host_generic_acpi_parse_resource(ACPI_RESOURCE *res, void *arg)
|
||||
{
|
||||
device_t dev = (device_t)arg;
|
||||
struct generic_pcie_acpi_softc *sc;
|
||||
rman_res_t min, max;
|
||||
int error;
|
||||
|
||||
switch (res->Type) {
|
||||
case ACPI_RESOURCE_TYPE_ADDRESS32:
|
||||
min = (rman_res_t)res->Data.Address32.Address.Minimum;
|
||||
max = (rman_res_t)res->Data.Address32.Address.Maximum;
|
||||
break;
|
||||
case ACPI_RESOURCE_TYPE_ADDRESS64:
|
||||
min = (rman_res_t)res->Data.Address64.Address.Minimum;
|
||||
max = (rman_res_t)res->Data.Address64.Address.Maximum;
|
||||
break;
|
||||
default:
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
error = rman_manage_region(&sc->base.mem_rman, min, max);
|
||||
if (error) {
|
||||
device_printf(dev, "unable to allocate %lx-%lx range\n", min, max);
|
||||
return (AE_NOT_FOUND);
|
||||
}
|
||||
device_printf(dev, "allocating %lx-%lx range\n", min, max);
|
||||
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
generic_pcie_acpi_read_ivar(device_t dev, device_t child, int index,
|
||||
uintptr_t *result)
|
||||
@ -203,7 +325,7 @@ generic_pcie_acpi_read_ivar(device_t dev, device_t child, int index,
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
if (index == PCIB_IVAR_BUS) {
|
||||
*result = sc->base.ecam * 0x80 + sc->base.bus_start;
|
||||
*result = sc->base.bus_start;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -223,50 +345,62 @@ generic_pcie_acpi_route_interrupt(device_t bus, device_t dev, int pin)
|
||||
struct generic_pcie_acpi_softc *sc;
|
||||
|
||||
sc = device_get_softc(bus);
|
||||
|
||||
return (acpi_pcib_route_interrupt(bus, dev, pin, &sc->ap_prt));
|
||||
}
|
||||
|
||||
static struct resource *
|
||||
pci_host_generic_acpi_alloc_resource(device_t dev, device_t child, int type,
|
||||
int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
|
||||
{
|
||||
struct resource *res = NULL;
|
||||
|
||||
#if defined(NEW_PCIB) && defined(PCI_RES_BUS)
|
||||
struct generic_pcie_acpi_softc *sc;
|
||||
|
||||
if (type == PCI_RES_BUS) {
|
||||
sc = device_get_softc(dev);
|
||||
return (pci_domain_alloc_bus(sc->base.ecam, child, rid, start,
|
||||
end, count, flags));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (type == SYS_RES_MEMORY)
|
||||
res = pci_host_generic_core_alloc_resource(dev, child, type,
|
||||
rid, start, end, count, flags);
|
||||
|
||||
if (res == NULL)
|
||||
res = bus_generic_alloc_resource(dev, child, type, rid, start, end,
|
||||
count, flags);
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
/*
|
||||
* Follow logic of FDT activate
|
||||
*/
|
||||
static int
|
||||
generic_pcie_acpi_activate_resource(device_t dev, device_t child, int type,
|
||||
int rid, struct resource *r)
|
||||
{
|
||||
struct generic_pcie_acpi_softc *sc;
|
||||
uint64_t phys_base;
|
||||
uint64_t pci_base;
|
||||
uint64_t size;
|
||||
int found;
|
||||
int res;
|
||||
int i;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
if ((res = rman_activate_resource(r)) != 0)
|
||||
return (res);
|
||||
|
||||
res = BUS_ACTIVATE_RESOURCE(device_get_parent(dev), child, type, rid,r);
|
||||
switch (type) {
|
||||
case SYS_RES_IOPORT:
|
||||
found = 0;
|
||||
for (i = 0; i < MAX_RANGES_TUPLES; i++) {
|
||||
pci_base = sc->base.ranges[i].pci_base;
|
||||
phys_base = sc->base.ranges[i].phys_base;
|
||||
size = sc->base.ranges[i].size;
|
||||
|
||||
if ((rid > pci_base) && (rid < (pci_base + size))) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
rman_set_start(r, rman_get_start(r) + phys_base);
|
||||
rman_set_end(r, rman_get_end(r) + phys_base);
|
||||
res = BUS_ACTIVATE_RESOURCE(device_get_parent(dev),
|
||||
child, type, rid, r);
|
||||
} else {
|
||||
device_printf(dev,
|
||||
"Failed to activate IOPORT resource\n");
|
||||
res = 0;
|
||||
}
|
||||
break;
|
||||
case SYS_RES_MEMORY:
|
||||
case SYS_RES_IRQ:
|
||||
res = BUS_ACTIVATE_RESOURCE(device_get_parent(dev), child,
|
||||
type, rid, r);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
@ -279,8 +413,17 @@ generic_pcie_acpi_deactivate_resource(device_t dev, device_t child, int type,
|
||||
if ((res = rman_deactivate_resource(r)) != 0)
|
||||
return (res);
|
||||
|
||||
res = BUS_DEACTIVATE_RESOURCE(device_get_parent(dev), child, type,
|
||||
rid, r);
|
||||
switch (type) {
|
||||
case SYS_RES_IOPORT:
|
||||
case SYS_RES_MEMORY:
|
||||
case SYS_RES_IRQ:
|
||||
res = BUS_DEACTIVATE_RESOURCE(device_get_parent(dev), child,
|
||||
type, rid, r);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
@ -347,30 +490,25 @@ static int
|
||||
generic_pcie_acpi_get_id(device_t pci, device_t child, enum pci_id_type type,
|
||||
uintptr_t *id)
|
||||
{
|
||||
struct generic_pcie_acpi_softc *sc;
|
||||
int err;
|
||||
|
||||
/* Use the PCI RID to find the MSI ID */
|
||||
if (type == PCI_ID_MSI) {
|
||||
sc = device_get_softc(pci);
|
||||
type = PCI_ID_RID;
|
||||
err = pcib_get_id(pci, child, type, id);
|
||||
if (err != 0)
|
||||
return (err);
|
||||
*id |= sc->base.ecam << 16;
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (pcib_get_id(pci, child, type, id));
|
||||
/*
|
||||
* Use the PCI RID to find the MSI ID for now, we support only 1:1
|
||||
* mapping
|
||||
*
|
||||
* On aarch64, more complex mapping would come from IORT table
|
||||
*/
|
||||
if (type == PCI_ID_MSI)
|
||||
return (pcib_get_id(pci, child, PCI_ID_RID, id));
|
||||
else
|
||||
return (pcib_get_id(pci, child, type, id));
|
||||
}
|
||||
|
||||
static device_method_t generic_pcie_acpi_methods[] = {
|
||||
DEVMETHOD(device_probe, generic_pcie_acpi_probe),
|
||||
DEVMETHOD(device_attach, pci_host_generic_acpi_attach),
|
||||
DEVMETHOD(bus_alloc_resource, pci_host_generic_acpi_alloc_resource),
|
||||
DEVMETHOD(bus_activate_resource, generic_pcie_acpi_activate_resource),
|
||||
DEVMETHOD(bus_deactivate_resource, generic_pcie_acpi_deactivate_resource),
|
||||
DEVMETHOD(bus_read_ivar, generic_pcie_acpi_read_ivar),
|
||||
DEVMETHOD(bus_activate_resource, generic_pcie_acpi_activate_resource),
|
||||
DEVMETHOD(bus_deactivate_resource,generic_pcie_acpi_deactivate_resource),
|
||||
|
||||
/* pcib interface */
|
||||
DEVMETHOD(pcib_route_interrupt, generic_pcie_acpi_route_interrupt),
|
||||
|
Loading…
x
Reference in New Issue
Block a user