git: ba1904937d9a - main - acpica: Extract _OSC parsing to a common file
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 12 Dec 2024 18:19:01 UTC
The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=ba1904937d9ae0539e39001467a1519b17177118 commit ba1904937d9ae0539e39001467a1519b17177118 Author: Andrew Turner <andrew@FreeBSD.org> AuthorDate: 2024-12-12 16:29:45 +0000 Commit: Andrew Turner <andrew@FreeBSD.org> CommitDate: 2024-12-12 18:00:22 +0000 acpica: Extract _OSC parsing to a common file This will be used by pci_host_generic_acpi.c so needs to be in a common location. Reviewed by: imp, jhb Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D48044 --- sys/dev/acpica/acpi_pcib.c | 59 ++++++++++++++++++++++++++++++++++++++++ sys/dev/acpica/acpi_pcib_acpi.c | 60 ++--------------------------------------- sys/dev/acpica/acpi_pcibvar.h | 1 + 3 files changed, 62 insertions(+), 58 deletions(-) diff --git a/sys/dev/acpica/acpi_pcib.c b/sys/dev/acpica/acpi_pcib.c index b16457ec853d..dfb4f143d5c4 100644 --- a/sys/dev/acpica/acpi_pcib.c +++ b/sys/dev/acpica/acpi_pcib.c @@ -38,6 +38,7 @@ #include <dev/acpica/acpivar.h> #include <dev/acpica/acpi_pcibvar.h> +#include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> #include "pcib_if.h" @@ -277,3 +278,61 @@ acpi_pcib_get_cpus(device_t pcib, device_t dev, enum cpu_sets op, return (bus_get_cpus(pcib, op, setsize, cpuset)); } + +int +acpi_pcib_osc(device_t pcib, uint32_t *ap_osc_ctl, uint32_t osc_ctl) +{ + ACPI_STATUS status; + ACPI_HANDLE handle; + uint32_t cap_set[3]; + + static uint8_t pci_host_bridge_uuid[ACPI_UUID_LENGTH] = { + 0x5b, 0x4d, 0xdb, 0x33, 0xf7, 0x1f, 0x1c, 0x40, + 0x96, 0x57, 0x74, 0x41, 0xc0, 0x3d, 0xd7, 0x66 + }; + + /* + * Don't invoke _OSC if a control is already granted. + * However, always invoke _OSC during attach when 0 is passed. + */ + if (osc_ctl != 0 && (*ap_osc_ctl & osc_ctl) == osc_ctl) + return (0); + + /* Support Field: Extended PCI Config Space, PCI Segment Groups, MSI */ + cap_set[PCI_OSC_SUPPORT] = PCIM_OSC_SUPPORT_EXT_PCI_CONF | + PCIM_OSC_SUPPORT_SEG_GROUP | PCIM_OSC_SUPPORT_MSI; + /* Active State Power Management, Clock Power Management Capability */ + if (pci_enable_aspm) + cap_set[PCI_OSC_SUPPORT] |= PCIM_OSC_SUPPORT_ASPM | + PCIM_OSC_SUPPORT_CPMC; + + /* Control Field */ + cap_set[PCI_OSC_CTL] = *ap_osc_ctl | osc_ctl; + + handle = acpi_get_handle(pcib); + status = acpi_EvaluateOSC(handle, pci_host_bridge_uuid, 1, + nitems(cap_set), cap_set, cap_set, false); + if (ACPI_FAILURE(status)) { + if (status == AE_NOT_FOUND) { + *ap_osc_ctl |= osc_ctl; + return (0); + } + device_printf(pcib, "_OSC failed: %s\n", + AcpiFormatException(status)); + return (EIO); + } + + /* + * _OSC may return an error in the status word, but will + * update the control mask always. _OSC should not revoke + * previously-granted controls. + */ + if ((cap_set[PCI_OSC_CTL] & *ap_osc_ctl) != *ap_osc_ctl) + device_printf(pcib, "_OSC revoked %#x\n", + (cap_set[PCI_OSC_CTL] & *ap_osc_ctl) ^ *ap_osc_ctl); + *ap_osc_ctl = cap_set[PCI_OSC_CTL]; + if ((*ap_osc_ctl & osc_ctl) != osc_ctl) + return (EIO); + + return (0); +} diff --git a/sys/dev/acpica/acpi_pcib_acpi.c b/sys/dev/acpica/acpi_pcib_acpi.c index bd005aed8fdc..e4cff4639a93 100644 --- a/sys/dev/acpica/acpi_pcib_acpi.c +++ b/sys/dev/acpica/acpi_pcib_acpi.c @@ -286,62 +286,6 @@ get_decoded_bus_range(struct acpi_hpcib_softc *sc, rman_res_t *startp, return (true); } -static int -acpi_pcib_osc(struct acpi_hpcib_softc *sc, uint32_t osc_ctl) -{ - ACPI_STATUS status; - uint32_t cap_set[3]; - - static uint8_t pci_host_bridge_uuid[ACPI_UUID_LENGTH] = { - 0x5b, 0x4d, 0xdb, 0x33, 0xf7, 0x1f, 0x1c, 0x40, - 0x96, 0x57, 0x74, 0x41, 0xc0, 0x3d, 0xd7, 0x66 - }; - - /* - * Don't invoke _OSC if a control is already granted. - * However, always invoke _OSC during attach when 0 is passed. - */ - if (osc_ctl != 0 && (sc->ap_osc_ctl & osc_ctl) == osc_ctl) - return (0); - - /* Support Field: Extended PCI Config Space, PCI Segment Groups, MSI */ - cap_set[PCI_OSC_SUPPORT] = PCIM_OSC_SUPPORT_EXT_PCI_CONF | - PCIM_OSC_SUPPORT_SEG_GROUP | PCIM_OSC_SUPPORT_MSI; - /* Active State Power Management, Clock Power Management Capability */ - if (pci_enable_aspm) - cap_set[PCI_OSC_SUPPORT] |= PCIM_OSC_SUPPORT_ASPM | - PCIM_OSC_SUPPORT_CPMC; - - /* Control Field */ - cap_set[PCI_OSC_CTL] = sc->ap_osc_ctl | osc_ctl; - - status = acpi_EvaluateOSC(sc->ap_handle, pci_host_bridge_uuid, 1, - nitems(cap_set), cap_set, cap_set, false); - if (ACPI_FAILURE(status)) { - if (status == AE_NOT_FOUND) { - sc->ap_osc_ctl |= osc_ctl; - return (0); - } - device_printf(sc->ap_dev, "_OSC failed: %s\n", - AcpiFormatException(status)); - return (EIO); - } - - /* - * _OSC may return an error in the status word, but will - * update the control mask always. _OSC should not revoke - * previously-granted controls. - */ - if ((cap_set[PCI_OSC_CTL] & sc->ap_osc_ctl) != sc->ap_osc_ctl) - device_printf(sc->ap_dev, "_OSC revoked %#x\n", - (cap_set[PCI_OSC_CTL] & sc->ap_osc_ctl) ^ sc->ap_osc_ctl); - sc->ap_osc_ctl = cap_set[PCI_OSC_CTL]; - if ((sc->ap_osc_ctl & osc_ctl) != osc_ctl) - return (EIO); - - return (0); -} - static int acpi_pcib_acpi_attach(device_t dev) { @@ -367,7 +311,7 @@ acpi_pcib_acpi_attach(device_t dev) if (!acpi_DeviceIsPresent(dev)) return (ENXIO); - acpi_pcib_osc(sc, 0); + acpi_pcib_osc(dev, &sc->ap_osc_ctl, 0); /* * Get our segment number by evaluating _SEG. @@ -759,7 +703,7 @@ acpi_pcib_request_feature(device_t pcib, device_t dev, enum pci_feature feature) return (EINVAL); } - return (acpi_pcib_osc(sc, osc_ctl)); + return (acpi_pcib_osc(dev, &sc->ap_osc_ctl, osc_ctl)); } static bus_dma_tag_t diff --git a/sys/dev/acpica/acpi_pcibvar.h b/sys/dev/acpica/acpi_pcibvar.h index 2b75c276f9d1..c763eeea1941 100644 --- a/sys/dev/acpica/acpi_pcibvar.h +++ b/sys/dev/acpica/acpi_pcibvar.h @@ -40,6 +40,7 @@ int acpi_pcib_route_interrupt(device_t pcib, device_t dev, int pin, ACPI_BUFFER *prtbuf); int acpi_pcib_power_for_sleep(device_t pcib, device_t dev, int *pstate); +int acpi_pcib_osc(device_t pcib, uint32_t *ap_osc_ctl, uint32_t osc_ctl); #endif /* _KERNEL */