The branch main has been updated by cperciva:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=d70bac252d30adec4feba0c866dabe2c16a756d9

commit d70bac252d30adec4feba0c866dabe2c16a756d9
Author:     Colin Percival <cperc...@freebsd.org>
AuthorDate: 2025-02-27 00:31:08 +0000
Commit:     Colin Percival <cperc...@freebsd.org>
CommitDate: 2025-03-05 20:25:49 +0000

    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
---
 release/tools/ec2.conf    | 7 +++++--
 sys/dev/acpica/acpi_pci.c | 9 +++++++++
 sys/dev/acpica/acpivar.h  | 3 +++
 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__)
 /*

Reply via email to