Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/pci/pci_host_generic_acpi.c
/*- | /*- | ||||
* Copyright (C) 2018 Cavium Inc. | |||||
* Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com> | * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com> | ||||
* Copyright (c) 2014 The FreeBSD Foundation | * Copyright (c) 2014 The FreeBSD Foundation | ||||
* All rights reserved. | * All rights reserved. | ||||
* | * | ||||
* This software was developed by Semihalf under | * This software was developed by Semihalf under | ||||
* the sponsorship of the FreeBSD Foundation. | * the sponsorship of the FreeBSD Foundation. | ||||
* | * | ||||
emaste: The previous statement is the standard one for Foundation-sponsored work, however I am not… | |||||
Not Done Inline ActionsYou are right. I should have kept this. Fixed. pdk_semihalf.com: You are right. I should have kept this. Fixed. | |||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
* modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
* are met: | * are met: | ||||
* 1. Redistributions of source code must retain the above copyright | * 1. Redistributions of source code must retain the above copyright | ||||
* notice, this list of conditions and the following disclaimer. | * notice, this list of conditions and the following disclaimer. | ||||
* 2. Redistributions in binary form must reproduce the above copyright | * 2. Redistributions in binary form must reproduce the above copyright | ||||
* notice, this list of conditions and the following disclaimer in the | * notice, this list of conditions and the following disclaimer in the | ||||
* documentation and/or other materials provided with the distribution. | * documentation and/or other materials provided with the distribution. | ||||
▲ Show 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | struct generic_pcie_acpi_softc { | ||||
ACPI_BUFFER ap_prt; /* interrupt routing table */ | ACPI_BUFFER ap_prt; /* interrupt routing table */ | ||||
}; | }; | ||||
/* Forward prototypes */ | /* Forward prototypes */ | ||||
static int generic_pcie_acpi_probe(device_t dev); | static int generic_pcie_acpi_probe(device_t dev); | ||||
static uint32_t generic_pcie_read_config(device_t dev, u_int bus, u_int slot, | static uint32_t generic_pcie_read_config(device_t dev, u_int bus, u_int slot, | ||||
u_int func, u_int reg, int bytes); | u_int func, u_int reg, int bytes); | ||||
static void generic_pcie_write_config(device_t dev, u_int bus, u_int slot, | static ACPI_STATUS pci_host_generic_acpi_parse_resource(ACPI_RESOURCE *, void *); | ||||
u_int func, u_int reg, uint32_t val, int bytes); | |||||
static int generic_pcie_release_resource(device_t dev, device_t child, | |||||
int type, int rid, struct resource *res); | |||||
static int | static int | ||||
generic_pcie_acpi_probe(device_t dev) | generic_pcie_acpi_probe(device_t dev) | ||||
{ | { | ||||
ACPI_DEVICE_INFO *devinfo; | ACPI_DEVICE_INFO *devinfo; | ||||
ACPI_HANDLE h; | ACPI_HANDLE h; | ||||
int root; | int root; | ||||
if (acpi_disabled("pcib") || (h = acpi_get_handle(dev)) == NULL || | if (acpi_disabled("pcib") || (h = acpi_get_handle(dev)) == NULL || | ||||
ACPI_FAILURE(AcpiGetObjectInfo(h, &devinfo))) | ACPI_FAILURE(AcpiGetObjectInfo(h, &devinfo))) | ||||
Not Done Inline ActionsCan you split the quirks out into a new review? It is mostly separate from the other changes. andrew: Can you split the quirks out into a new review? It is mostly separate from the other changes. | |||||
return (ENXIO); | return (ENXIO); | ||||
root = (devinfo->Flags & ACPI_PCI_ROOT_BRIDGE) != 0; | root = (devinfo->Flags & ACPI_PCI_ROOT_BRIDGE) != 0; | ||||
AcpiOsFree(devinfo); | AcpiOsFree(devinfo); | ||||
if (!root) | if (!root) | ||||
return (ENXIO); | return (ENXIO); | ||||
device_set_desc(dev, "Generic PCI host controller"); | device_set_desc(dev, "Generic PCI host controller"); | ||||
return (BUS_PROBE_GENERIC); | return (BUS_PROBE_GENERIC); | ||||
} | } | ||||
int | int | ||||
pci_host_generic_acpi_attach(device_t dev) | pci_host_generic_acpi_attach(device_t dev) | ||||
{ | { | ||||
struct generic_pcie_acpi_softc *sc; | struct generic_pcie_acpi_softc *sc; | ||||
ACPI_HANDLE handle; | ACPI_HANDLE handle; | ||||
ACPI_STATUS status; | |||||
int error; | int error; | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
handle = acpi_get_handle(dev); | handle = acpi_get_handle(dev); | ||||
if (ACPI_FAILURE(acpi_GetInteger(handle, "_CCA", &sc->base.coherent))) | if (ACPI_FAILURE(acpi_GetInteger(handle, "_CCA", &sc->base.coherent))) | ||||
sc->base.coherent = 0; | sc->base.coherent = 0; | ||||
if (bootverbose) | if (bootverbose) | ||||
device_printf(dev, "Bus is%s cache-coherent\n", | device_printf(dev, "Bus is%s cache-coherent\n", | ||||
sc->base.coherent ? "" : " not"); | sc->base.coherent ? "" : " not"); | ||||
acpi_pcib_fetch_prt(dev, &sc->ap_prt); | acpi_pcib_fetch_prt(dev, &sc->ap_prt); | ||||
error = pci_host_generic_core_attach(dev); | error = pci_host_generic_core_attach(dev); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
status = AcpiWalkResources(handle, "_CRS", | |||||
pci_host_generic_acpi_parse_resource, (void *)dev); | |||||
Not Done Inline ActionsAre these encoded as Producer resources instead of Consumer resources? jhb: Are these encoded as Producer resources instead of Consumer resources? | |||||
Not Done Inline ActionsThey are encoded as Producer resources. pdk_semihalf.com: They are encoded as Producer resources. | |||||
if (ACPI_FAILURE(status)) | |||||
return (ENXIO); | |||||
device_add_child(dev, "pci", -1); | device_add_child(dev, "pci", -1); | ||||
return (bus_generic_attach(dev)); | return (bus_generic_attach(dev)); | ||||
} | } | ||||
static int | static ACPI_STATUS | ||||
generic_pcie_acpi_route_interrupt(device_t bus, device_t dev, int pin) | pci_host_generic_acpi_parse_resource(ACPI_RESOURCE *res, void *arg) | ||||
{ | { | ||||
device_t dev = (device_t)arg; | |||||
struct generic_pcie_acpi_softc *sc; | struct generic_pcie_acpi_softc *sc; | ||||
rman_res_t min, max; | |||||
int error; | |||||
sc = device_get_softc(bus); | 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); | |||||
} | |||||
return (acpi_pcib_route_interrupt(bus, dev, pin, &sc->ap_prt)); | 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); | |||||
static struct rman * | return (AE_OK); | ||||
generic_pcie_acpi_rman(struct generic_pcie_acpi_softc *sc, int type) | } | ||||
static int | |||||
generic_pcie_acpi_route_interrupt(device_t bus, device_t dev, int pin) | |||||
{ | { | ||||
struct generic_pcie_acpi_softc *sc; | |||||
switch (type) { | sc = device_get_softc(bus); | ||||
case SYS_RES_IOPORT: | |||||
return (&sc->base.io_rman); | |||||
case SYS_RES_MEMORY: | |||||
return (&sc->base.mem_rman); | |||||
default: | |||||
break; | |||||
} | |||||
return (NULL); | return (acpi_pcib_route_interrupt(bus, dev, pin, &sc->ap_prt)); | ||||
} | } | ||||
static struct resource * | static struct resource * | ||||
pci_host_generic_acpi_alloc_resource(device_t dev, device_t child, int type, | 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) | 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) | #if defined(NEW_PCIB) && defined(PCI_RES_BUS) | ||||
struct generic_pcie_acpi_softc *sc; | struct generic_pcie_acpi_softc *sc; | ||||
if (type == PCI_RES_BUS) { | if (type == PCI_RES_BUS) { | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
return (pci_domain_alloc_bus(sc->base.ecam, child, rid, start, | return (pci_domain_alloc_bus(sc->base.ecam, child, rid, start, | ||||
end, count, flags)); | end, count, flags)); | ||||
} | } | ||||
#endif | #endif | ||||
return (bus_generic_alloc_resource(dev, child, type, rid, start, end, | if (type == SYS_RES_MEMORY) | ||||
count, flags)); | 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); | |||||
Not Done Inline ActionsWhy is this only needed for memory? andrew: Why is this only needed for memory? | |||||
Not Done Inline ActionsIn pci_host_generic_acpi_parse_resource we add memory regions to rman. Here we are allocating memory from it. pdk_semihalf.com: In `pci_host_generic_acpi_parse_resource` we add memory regions to rman. Here we are… | |||||
} | } | ||||
static int | static int | ||||
generic_pcie_acpi_activate_resource(device_t dev, device_t child, int type, | generic_pcie_acpi_activate_resource(device_t dev, device_t child, int type, | ||||
int rid, struct resource *r) | int rid, struct resource *r) | ||||
{ | { | ||||
struct generic_pcie_acpi_softc *sc; | struct generic_pcie_acpi_softc *sc; | ||||
int res; | int res; | ||||
▲ Show 20 Lines • Show All 121 Lines • ▼ Show 20 Lines | |||||
}; | }; | ||||
DEFINE_CLASS_1(pcib, generic_pcie_acpi_driver, generic_pcie_acpi_methods, | DEFINE_CLASS_1(pcib, generic_pcie_acpi_driver, generic_pcie_acpi_methods, | ||||
sizeof(struct generic_pcie_acpi_softc), generic_pcie_core_driver); | sizeof(struct generic_pcie_acpi_softc), generic_pcie_core_driver); | ||||
static devclass_t generic_pcie_acpi_devclass; | static devclass_t generic_pcie_acpi_devclass; | ||||
DRIVER_MODULE(pcib, acpi, generic_pcie_acpi_driver, generic_pcie_acpi_devclass, | DRIVER_MODULE(pcib, acpi, generic_pcie_acpi_driver, generic_pcie_acpi_devclass, | ||||
0, 0); | 0, 0); | ||||
Not Done Inline Actionsdo you know if these are temporary quirks for pre-prod systems only? emaste: do you know if these are temporary quirks for pre-prod systems only? | |||||
Not Done Inline ActionsThese quirks are necessary for current ThunderX2 revision. I have no information if there will be some future revisions with these things fixed. pdk_semihalf.com: These quirks are necessary for current ThunderX2 revision. I have no information if there will… | |||||
Not Done Inline ActionsIs there an erratum for this? I don't see anything in Linux, or my copy of the ThunderX2 known issues document. andrew: Is there an erratum for this? I don't see anything in Linux, or my copy of the ThunderX2 known… |
The previous statement is the standard one for Foundation-sponsored work, however I am not aware of the history of this file off hand.