📄 aeexec.c
字号:
* * PARAMETERS: Standard region handler parameters * * RETURN: Status * * DESCRIPTION: Test handler - Handles some dummy regions via memory that can * be manipulated in Ring 3. * *****************************************************************************/ACPI_STATUSAeRegionHandler ( UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, ACPI_INTEGER *Value, void *HandlerContext, void *RegionContext){ ACPI_OPERAND_OBJECT *RegionObject = (ACPI_OPERAND_OBJECT*) RegionContext; ACPI_PHYSICAL_ADDRESS BaseAddress; ACPI_SIZE Length; BOOLEAN BufferExists; REGION *RegionElement; void *BufferValue; UINT32 ByteWidth; UINT32 i; UINT8 SpaceId; ACPI_FUNCTION_NAME (AeRegionHandler); /* * If the object is not a region, simply return */ if (RegionObject->Region.Type != ACPI_TYPE_REGION) { return AE_OK; } /* * Find the region's address space and length before searching * the linked list. */ BaseAddress = RegionObject->Region.Address; Length = (ACPI_SIZE) RegionObject->Region.Length; SpaceId = RegionObject->Region.SpaceId; ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Operation Region request on %s at 0x%X\n", AcpiUtGetRegionName (RegionObject->Region.SpaceId), (UINT32) Address)); if (SpaceId == ACPI_ADR_SPACE_SMBUS) { Length = 0; switch (Function & ACPI_IO_MASK) { case ACPI_READ: switch (Function >> 16) { case AML_FIELD_ATTRIB_SMB_QUICK: case AML_FIELD_ATTRIB_SMB_SEND_RCV: case AML_FIELD_ATTRIB_SMB_BYTE: Length = 1; break; case AML_FIELD_ATTRIB_SMB_WORD: case AML_FIELD_ATTRIB_SMB_WORD_CALL: Length = 2; break; case AML_FIELD_ATTRIB_SMB_BLOCK: case AML_FIELD_ATTRIB_SMB_BLOCK_CALL: Length = 32; break; default: break; } break; case ACPI_WRITE: switch (Function >> 16) { case AML_FIELD_ATTRIB_SMB_QUICK: case AML_FIELD_ATTRIB_SMB_SEND_RCV: case AML_FIELD_ATTRIB_SMB_BYTE: case AML_FIELD_ATTRIB_SMB_WORD: case AML_FIELD_ATTRIB_SMB_BLOCK: Length = 0; break; case AML_FIELD_ATTRIB_SMB_WORD_CALL: Length = 2; break; case AML_FIELD_ATTRIB_SMB_BLOCK_CALL: Length = 32; break; default: break; } break; default: break; } for (i = 0; i < Length; i++) { ((UINT8 *) Value)[i+2] = (UINT8) (0xA0 + i); } ((UINT8 *) Value)[0] = 0x7A; ((UINT8 *) Value)[1] = (UINT8) Length; return AE_OK; } /* * Search through the linked list for this region's buffer */ BufferExists = FALSE; RegionElement = AeRegions.RegionList; if (AeRegions.NumberOfRegions) { while (!BufferExists && RegionElement) { if (RegionElement->Address == BaseAddress && RegionElement->Length == Length && RegionElement->SpaceId == SpaceId) { BufferExists = TRUE; } else { RegionElement = RegionElement->NextRegion; } } } /* * If the Region buffer does not exist, create it now */ if (!BufferExists) { /* * Do the memory allocations first */ RegionElement = AcpiOsAllocate (sizeof (REGION)); if (!RegionElement) { return AE_NO_MEMORY; } RegionElement->Buffer = AcpiOsAllocate (Length); if (!RegionElement->Buffer) { AcpiOsFree (RegionElement); return AE_NO_MEMORY; } ACPI_MEMSET (RegionElement->Buffer, 0, Length); RegionElement->Address = BaseAddress; RegionElement->Length = Length; RegionElement->SpaceId = SpaceId; RegionElement->NextRegion = NULL; /* * Increment the number of regions and put this one * at the head of the list as it will probably get accessed * more often anyway. */ AeRegions.NumberOfRegions += 1; if (AeRegions.RegionList) { RegionElement->NextRegion = AeRegions.RegionList; } AeRegions.RegionList = RegionElement; } /* * Calculate the size of the memory copy */ ByteWidth = (BitWidth / 8); if (BitWidth % 8) { ByteWidth += 1; } /* * The buffer exists and is pointed to by RegionElement. * We now need to verify the request is valid and perform the operation. * * NOTE: RegionElement->Length is in bytes, therefore it we compare against * ByteWidth (see above) */ if (((ACPI_INTEGER) Address + ByteWidth) > ((ACPI_INTEGER)(RegionElement->Address) + RegionElement->Length)) { ACPI_WARNING ((AE_INFO, "Request on [%4.4s] is beyond region limit Req-%X+%X, Base=%X, Len-%X", (RegionObject->Region.Node)->Name.Ascii, (UINT32) Address, ByteWidth, (UINT32)(RegionElement->Address), RegionElement->Length)); return AE_AML_REGION_LIMIT; } /* * Get BufferValue to point to the "address" in the buffer */ BufferValue = ((UINT8 *) RegionElement->Buffer + ((ACPI_INTEGER) Address - (ACPI_INTEGER) RegionElement->Address)); /* * Perform a read or write to the buffer space */ switch (Function) { case ACPI_READ: /* * Set the pointer Value to whatever is in the buffer */ ACPI_MEMCPY (Value, BufferValue, ByteWidth); break; case ACPI_WRITE: /* * Write the contents of Value to the buffer */ ACPI_MEMCPY (BufferValue, Value, ByteWidth); break; default: return AE_BAD_PARAMETER; } return AE_OK;}/****************************************************************************** * * FUNCTION: AeRegionInit * * PARAMETERS: None * * RETURN: Status * * DESCRIPTION: Opregion init function. * *****************************************************************************/ACPI_STATUSAeRegionInit ( ACPI_HANDLE RegionHandle, UINT32 Function, void *HandlerContext, void **RegionContext){ /* * Real simple, set the RegionContext to the RegionHandle */ *RegionContext = RegionHandle; return AE_OK;}/****************************************************************************** * * FUNCTION: AeNotifyHandler * * PARAMETERS: Standard notify handler parameters * * RETURN: Status * * DESCRIPTION: System notify handler for AcpiExec utility. Used by the ASL * test suite(s) to communicate errors and other information to * this utility via the Notify() operator. * *****************************************************************************/voidAeNotifyHandler ( ACPI_HANDLE Device, UINT32 Value, void *Context){ switch (Value) {#if 0 case 0: printf ("**** Method Error 0x%X: Results not equal\n", Value); if (AcpiGbl_DebugFile) { AcpiOsPrintf ("**** Method Error: Results not equal\n"); } break; case 1: printf ("**** Method Error: Incorrect numeric result\n"); if (AcpiGbl_DebugFile) { AcpiOsPrintf ("**** Method Error: Incorrect numeric result\n"); } break; case 2: printf ("**** Method Error: An operand was overwritten\n"); if (AcpiGbl_DebugFile) { AcpiOsPrintf ("**** Method Error: An operand was overwritten\n"); } break;#endif default: printf ("**** Received a Notify on Device [%4.4s] %p value 0x%X\n", AcpiUtGetNodeName (Device), Device, Value); if (AcpiGbl_DebugFile) { AcpiOsPrintf ("**** Received a notify, value 0x%X\n", Value); } (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL); break; }}/****************************************************************************** * * FUNCTION: AeExceptionHandler * * PARAMETERS: Standard exception handler parameters * * RETURN: Status * * DESCRIPTION: System exception handler for AcpiExec utility. * *****************************************************************************/ACPI_STATUSAeExceptionHandler ( ACPI_STATUS AmlStatus, ACPI_NAME Name, UINT16 Opcode, UINT32 AmlOffset, void *Context){ ACPI_STATUS NewAmlStatus = AmlStatus; ACPI_STATUS Status; ACPI_BUFFER ReturnObj; ACPI_OBJECT_LIST ArgList; ACPI_OBJECT Arg[3]; const char *Exception; Exception = AcpiFormatException (AmlStatus); AcpiOsPrintf ("**** AcpiExec: Exception %s during execution ", Exception); if (Name) { AcpiOsPrintf ("of method [%4.4s]", (char *) &Name); } else { AcpiOsPrintf ("at module level (table load)"); } AcpiOsPrintf (" Opcode [%s] @%X\n", AcpiPsGetOpcodeName (Opcode), AmlOffset); /* * Invoke the _ERR method if present * * Setup parameter object */ ArgList.Count = 3; ArgList.Pointer = Arg; Arg[0].Type = ACPI_TYPE_INTEGER; Arg[0].Integer.Value = AmlStatus; Arg[1].Type = ACPI_TYPE_STRING; Arg[1].String.Pointer = (char *) Exception; Arg[1].String.Length = ACPI_STRLEN (Exception); Arg[2].Type = ACPI_TYPE_INTEGER; Arg[2].Integer.Value = AcpiOsGetThreadId(); /* Setup return buffer */ ReturnObj.Pointer = NULL; ReturnObj.Length = ACPI_ALLOCATE_BUFFER; Status = AcpiEvaluateObject (NULL, "\\_ERR", &ArgList, &ReturnObj); if (ACPI_SUCCESS (Status)) { if (ReturnObj.Pointer) { /* Override original status */ NewAmlStatus = (ACPI_STATUS) ((ACPI_OBJECT *) ReturnObj.Pointer)->Integer.Value; AcpiOsFree (ReturnObj.Pointer); } } else if (Status != AE_NOT_FOUND) { AcpiOsPrintf ("**** AcpiExec: Could not execute _ERR method, %s\n", AcpiFormatException (Status)); } /* Global override */ if (AcpiGbl_IgnoreErrors) { NewAmlStatus = AE_OK; } if (NewAmlStatus != AmlStatus) { AcpiOsPrintf ("**** AcpiExec: Exception override, new status %s\n", AcpiFormatException (NewAmlStatus)); } return (NewAmlStatus);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -