From dc6fd1d12903015726a8a6f87f63e86141576a68 Mon Sep 17 00:00:00 2001 From: Jose Marinho Date: Tue, 28 Mar 2023 10:50:46 +0100 Subject: Detect GED device and keep track of _EVT The GED device is described by a _HID of ACPI0013. This code traverses the namespace identifying all GED devices. For each GED device in the namespace we record 1) the Interrupt objects and the _EVT method. This information is used when an interrupt is simulate. Cc: Catalin Marinas Cc: Sami Mujawar Cc: Samer El-Haj-Mahmoud Signed-off-by: Jose Marinho --- source/include/acglobal.h | 1 + source/include/aclocal.h | 9 +++ source/include/acnames.h | 1 + source/tools/acpiexec/aeinstall.c | 118 +++++++++++++++++++++++++++++++++++++- 4 files changed, 128 insertions(+), 1 deletion(-) diff --git a/source/include/acglobal.h b/source/include/acglobal.h index 28fc6514b..9df72a576 100644 --- a/source/include/acglobal.h +++ b/source/include/acglobal.h @@ -268,6 +268,7 @@ ACPI_GLOBAL (ACPI_TABLE_HANDLER, AcpiGbl_TableHandler); ACPI_GLOBAL (void *, AcpiGbl_TableHandlerContext); ACPI_GLOBAL (ACPI_INTERFACE_HANDLER, AcpiGbl_InterfaceHandler); ACPI_GLOBAL (ACPI_SCI_HANDLER_INFO *, AcpiGbl_SciHandlerList); +ACPI_GLOBAL (ACPI_GED_HANDLER_INFO *, AcpiGbl_GedHandlerList); /* Owner ID support */ diff --git a/source/include/aclocal.h b/source/include/aclocal.h index 2d7c8355a..99459a8b8 100644 --- a/source/include/aclocal.h +++ b/source/include/aclocal.h @@ -767,6 +767,15 @@ typedef struct acpi_field_info } ACPI_FIELD_INFO; +/* Information about the interrupt ID and _EVT of a GED device */ + +typedef struct acpi_ged_handler_info +{ + struct acpi_ged_handler_info *Next; + UINT32 IntId; /* The interrupt ID that triggers the execution ofthe EvtMethod. */ + ACPI_NAMESPACE_NODE *EvtMethod; /* The _EVT method to be executed when an interrupt with ID = IntID is received */ + +} ACPI_GED_HANDLER_INFO; /***************************************************************************** * diff --git a/source/include/acnames.h b/source/include/acnames.h index a6cdd2e2c..e9f0af8c8 100644 --- a/source/include/acnames.h +++ b/source/include/acnames.h @@ -164,6 +164,7 @@ #define METHOD_NAME__DDN "_DDN" #define METHOD_NAME__DIS "_DIS" #define METHOD_NAME__DMA "_DMA" +#define METHOD_NAME__EVT "_EVT" #define METHOD_NAME__HID "_HID" #define METHOD_NAME__INI "_INI" #define METHOD_NAME__PLD "_PLD" diff --git a/source/tools/acpiexec/aeinstall.c b/source/tools/acpiexec/aeinstall.c index 9e1940c3f..b855fcbce 100644 --- a/source/tools/acpiexec/aeinstall.c +++ b/source/tools/acpiexec/aeinstall.c @@ -176,6 +176,13 @@ AeInstallPciHandler ( void *Context, void **ReturnValue); +static ACPI_STATUS +AeInstallGedHandler ( + ACPI_HANDLE ObjHandle, + UINT32 Level, + void *Context, + void **ReturnValue); + BOOLEAN AcpiGbl_DisplayRegionAccess = FALSE; ACPI_CONNECTION_INFO AeMyContext; @@ -343,6 +350,110 @@ AeInstallRegionHandlers ( } } +/******************************************************************************* + * + * FUNCTION: AeInstallGedHandler + * + * PARAMETERS: ACPI_WALK_NAMESPACE callback + * + * RETURN: Status + * + * DESCRIPTION: Walk entire namespace, install a handler for every GED + * device found. + * + ******************************************************************************/ +static ACPI_STATUS +AeInstallGedHandler ( + ACPI_HANDLE ObjHandle, + UINT32 Level, + void *Context, + void **ReturnValue) +{ + + ACPI_BUFFER ReturnBuffer; + ACPI_STATUS Status; + ACPI_RESOURCE *ResourceList; + ACPI_RESOURCE_EXTENDED_IRQ *extended_irq_rsc; + ACPI_NAMESPACE_NODE *Node; + ACPI_NAMESPACE_NODE *EvtMethodNode; + + ACPI_FUNCTION_ENTRY(); + + /* Obtain the Namespace Node of this GED object handle. */ + Node = AcpiNsValidateHandle (ObjHandle); + if (!Node) + { + return (AE_BAD_PARAMETER); + } + + /* + * A GED device must have one _EVT method. + * Obtain the _EVT method and store it in the global + * GED register. + */ + Status = AcpiNsSearchOneScope ( + *ACPI_CAST_PTR (ACPI_NAME, METHOD_NAME__EVT), + Node, + ACPI_TYPE_METHOD, + &EvtMethodNode + ); + if (ACPI_FAILURE (Status)) + { + AcpiOsPrintf ("Failed to obtain _EVT method for the GED device.\n"); + return Status; + } + + ReturnBuffer.Pointer = NULL; + ReturnBuffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; + + Status = AcpiGetCurrentResources (ObjHandle, &ReturnBuffer); + if (ACPI_FAILURE (Status)) + { + AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n", + AcpiFormatException (Status)); + return Status; + } + + /* Traverse the _CRS resource list */ + ResourceList = ACPI_CAST_PTR (ACPI_RESOURCE, ReturnBuffer.Pointer); + while (ResourceList->Type != ACPI_RESOURCE_TYPE_END_TAG) { + + switch (ResourceList->Type) { + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: { + + /* + * Found an Interrupt resource. Link the interrupt resource + * and the _EVT method of this GED device in the GED event handler list. + */ + ACPI_GED_HANDLER_INFO *GedHandler = + ACPI_ALLOCATE (sizeof (ACPI_SCI_HANDLER_INFO)); + if (!GedHandler) + { + return AE_NO_MEMORY; + } + + GedHandler->Next = AcpiGbl_GedHandlerList; + AcpiGbl_GedHandlerList = GedHandler; + + extended_irq_rsc = &ResourceList->Data.ExtendedIrq; + + GedHandler->IntId = extended_irq_rsc->Interrupts[0]; + GedHandler->EvtMethod = EvtMethodNode; + + AcpiOsPrintf ("Interrupt ID %d\n", extended_irq_rsc->Interrupts[0]); + + break; + } + default: + + AcpiOsPrintf ("Resource type %X\n", ResourceList->Type); + } + + ResourceList = ACPI_NEXT_RESOURCE (ResourceList); + } + + return AE_OK; +} /******************************************************************************* * @@ -352,7 +463,7 @@ AeInstallRegionHandlers ( * * RETURN: Status * - * DESCRIPTION: Install handlers for all EC and PCI devices in the namespace + * DESCRIPTION: Install handlers for all EC, PCI and GED devices in the namespace * ******************************************************************************/ @@ -368,6 +479,11 @@ AeInstallDeviceHandlers ( /* Install a PCI handler */ AcpiGetDevices ("PNP0A08", AeInstallPciHandler, NULL, NULL); + + /* Install a GED handler */ + + AcpiGetDevices ("ACPI0013", AeInstallGedHandler, NULL, NULL); + return (AE_OK); } -- cgit v1.2.1