aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Percival <cperciva@FreeBSD.org>2025-02-27 00:31:08 +0000
committerColin Percival <cperciva@FreeBSD.org>2025-03-05 20:25:49 +0000
commitd70bac252d30adec4feba0c866dabe2c16a756d9 (patch)
treef6d38883de78b4748293e4429e96dea748a4d4f1
parent202a2be0941edeb2652d64a3dbb1894b8867f3ac (diff)
acpi_pci: Add quirk for PSTAT_PME-before-detach
In order to signal to Graviton [123] systems that a device is ready to be "ejected" (after a detach request is made via the EC2 API) we need to set PCIM_PSTAT_PME to 1 and PCIM_PSTAT_PMEENABLE to 0. We are not aware of any rationale for this requirement beyond "another OS kernel happens to do this", i.e. this is effectively bug-for-bug compatibility. Arguably this should be done by the ACPI _EJ0 method on these systems, but it is not. Create a new ACPI_Q_CLEAR_PME_ON_DETACH quirk and set it in EC2 AMIs, and add the PCI register write to acpi_pci_device_notify_handler when that quirk is set. Reviewed by: jhb MFC after: 1 month Sponsored by: Amazon Differential Revision: https://reviews.freebsd.org/D49146
-rw-r--r--release/tools/ec2.conf7
-rw-r--r--sys/dev/acpica/acpi_pci.c9
-rw-r--r--sys/dev/acpica/acpivar.h3
3 files changed, 17 insertions, 2 deletions
diff --git a/release/tools/ec2.conf b/release/tools/ec2.conf
index b5a91d47decf..a8fc3854a0e2 100644
--- a/release/tools/ec2.conf
+++ b/release/tools/ec2.conf
@@ -72,8 +72,11 @@ ec2_common() {
# Graviton 1 through Graviton 4 have a bug in their ACPI where they
# mark the PL061's pins as needing to be configured in PullUp mode
- # (in fact the PL061 has no pullup/pulldown resistors).
- echo 'debug.acpi.quirks="8"' >> ${DESTDIR}/boot/loader.conf
+ # (in fact the PL061 has no pullup/pulldown resistors). Graviton 1
+ # through Graviton 3 have non-functional PCI _EJ0 and need a value
+ # written to the PCI power status register in order to eject a
+ # device.
+ echo 'debug.acpi.quirks="24"' >> ${DESTDIR}/boot/loader.conf
# Load the kernel module for the Amazon "Elastic Network Adapter"
echo 'if_ena_load="YES"' >> ${DESTDIR}/boot/loader.conf
diff --git a/sys/dev/acpica/acpi_pci.c b/sys/dev/acpica/acpi_pci.c
index 6411af02ee58..97704111839b 100644
--- a/sys/dev/acpica/acpi_pci.c
+++ b/sys/dev/acpica/acpi_pci.c
@@ -391,6 +391,8 @@ acpi_pci_device_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
{
device_t child, dev;
ACPI_STATUS status;
+ int pmc;
+ uint16_t pmstat;
int error;
dev = context;
@@ -416,6 +418,13 @@ acpi_pci_device_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
device_get_nameunit(child), error);
return;
}
+ if ((acpi_quirks & ACPI_Q_CLEAR_PME_ON_DETACH) &&
+ (pci_find_cap(child, PCIY_PMG, &pmc) == 0)) {
+ pmstat = pci_read_config(child, pmc + PCIR_POWER_STATUS, 2);
+ pmstat &= ~PCIM_PSTAT_PMEENABLE;
+ pmstat |= PCIM_PSTAT_PME;
+ pci_write_config(child, pmc + PCIR_POWER_STATUS, pmstat, 2);
+ }
status = acpi_SetInteger(h, "_EJ0", 1);
if (ACPI_FAILURE(status)) {
bus_topo_unlock();
diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h
index 668d0b51a1f3..830764434f48 100644
--- a/sys/dev/acpica/acpivar.h
+++ b/sys/dev/acpica/acpivar.h
@@ -230,6 +230,8 @@ extern struct mtx acpi_mutex;
* compatible flag and ignoring overrides that redirect IRQ 0 to pin 2.
* ACPI_Q_AEI_NOPULL: Specifies that _AEI objects incorrectly designate pins
* as "PullUp" and they should be treated as "NoPull" instead.
+ * ACPI_Q_CLEAR_PME_ON_DETACH: Specifies that PCIM_PSTAT_(PME & ~PMEENABLE)
+ * should be written to the power status register as part of ACPI Eject.
*/
extern int acpi_quirks;
#define ACPI_Q_OK 0
@@ -237,6 +239,7 @@ extern int acpi_quirks;
#define ACPI_Q_TIMER (1 << 1)
#define ACPI_Q_MADT_IRQ0 (1 << 2)
#define ACPI_Q_AEI_NOPULL (1 << 3)
+#define ACPI_Q_CLEAR_PME_ON_DETACH (1 << 4)
#if defined(__amd64__) || defined(__i386__)
/*