/** @file * * Copyright (c) 2018, Hisilicon Limited. All rights reserved. * Copyright (c) 2018, Linaro Limited. All rights reserved. * * SPDX-License-Identifier: BSD-2-Clause-Patent * **/ #include "Einj.h" #include #include #include #include #include #include "OemApeiHi1620.h" #include EINJ_TABLE mEinj = { { ARM_ACPI_HEADER ( EFI_ACPI_6_0_ERROR_INJECTION_TABLE_SIGNATURE, EFI_ACPI_6_0_ERROR_INJECTION_TABLE_HEADER, EFI_ACPI_6_0_ERROR_INJECTION_TABLE_REVISION ), sizeof (EFI_ACPI_6_0_ERROR_INJECTION_TABLE_HEADER), 0x0, { 0x0, 0x0, 0x0 }, EINJ_ACTION_NO }, { { // 0 EFI_ACPI_6_0_EINJ_BEGIN_INJECTION_OPERATION EFI_ACPI_6_0_EINJ_BEGIN_INJECTION_OPERATION, EFI_ACPI_6_0_EINJ_WRITE_REGISTER_VALUE, EFI_ACPI_6_0_EINJ_PRESERVE_REGISTER, 0, { EFI_ACPI_6_0_SYSTEM_MEMORY, 64, 0, EFI_ACPI_6_0_QWORD, 0 }, EINJ_BEGIN_OPERATION_VALUE, EINJ_WRITE_MASK }, { // 1 EFI_ACPI_6_0_EINJ_GET_TRIGGER_ERROR_ACTION_TABLE EFI_ACPI_6_0_EINJ_GET_TRIGGER_ERROR_ACTION_TABLE, EFI_ACPI_6_0_EINJ_READ_REGISTER, 0, 0, { EFI_ACPI_6_0_SYSTEM_MEMORY, 64, 0, EFI_ACPI_6_0_QWORD, 0 }, 0, EINJ_READ_MASK }, { // 2 EFI_ACPI_6_0_EINJ_SET_ERROR_TYPE EFI_ACPI_6_0_EINJ_SET_ERROR_TYPE, EFI_ACPI_6_0_EINJ_WRITE_REGISTER, EFI_ACPI_6_0_EINJ_PRESERVE_REGISTER, 0, { EFI_ACPI_6_0_SYSTEM_MEMORY, 64, 0, EFI_ACPI_6_0_QWORD, 0 }, 0, EINJ_WRITE_MASK }, { // 3 EFI_ACPI_6_0_EINJ_GET_ERROR_TYPE EFI_ACPI_6_0_EINJ_GET_ERROR_TYPE, EFI_ACPI_6_0_EINJ_READ_REGISTER, 0, 0, { EFI_ACPI_6_0_SYSTEM_MEMORY, 64, 0, EFI_ACPI_6_0_QWORD, 0 }, 0, 0xFFFFFFFF }, { // 4 EFI_ACPI_6_0_EINJ_END_OPERATION EFI_ACPI_6_0_EINJ_END_OPERATION, EFI_ACPI_6_0_EINJ_WRITE_REGISTER_VALUE, EFI_ACPI_6_0_EINJ_PRESERVE_REGISTER, 0, { EFI_ACPI_6_0_SYSTEM_MEMORY, 64, 0, EFI_ACPI_6_0_QWORD, 0 }, EINJ_END_OPERATION_VALUE, 0xFFFFFFFF }, { // 5 EFI_ACPI_6_0_EINJ_EXECUTE_OPERATION EFI_ACPI_6_0_EINJ_EXECUTE_OPERATION, EFI_ACPI_6_0_EINJ_WRITE_REGISTER_VALUE, EFI_ACPI_6_0_EINJ_PRESERVE_REGISTER, 0, { EFI_ACPI_6_0_SYSTEM_MEMORY, 32, 0, EFI_ACPI_6_0_DWORD, GPIO1_BASE + GPIO_INT_MASK //0x40070008//0x4d000F00//GPIO0_BASE + GPIO0_SWPORT_DR_OFFSET }, 0, 0xFFFFFFFF //BIT0 }, { // 6 EFI_ACPI_6_0_EINJ_CHECK_BUSY_STATUS EFI_ACPI_6_0_EINJ_CHECK_BUSY_STATUS, EFI_ACPI_6_0_EINJ_READ_REGISTER_VALUE, 0, 0, { EFI_ACPI_6_0_SYSTEM_MEMORY, 64, 0, EFI_ACPI_6_0_QWORD, 0 }, 0x01, 0x01 }, { // 7 EFI_ACPI_6_0_EINJ_GET_COMMAND_STATUS EFI_ACPI_6_0_EINJ_GET_COMMAND_STATUS, EFI_ACPI_6_0_EINJ_READ_REGISTER, 0, 0, { EFI_ACPI_6_0_SYSTEM_MEMORY, 64, 0, EFI_ACPI_6_0_QWORD, 0 }, 0, 0x3 }, { // 8 EFI_ACPI_EINJ_SET_ERROR_TYPE_WITH_ADDRESS EFI_ACPI_EINJ_SET_ERROR_TYPE_WITH_ADDRESS, EFI_ACPI_6_0_EINJ_WRITE_REGISTER, EFI_ACPI_6_0_EINJ_PRESERVE_REGISTER, 0, { EFI_ACPI_6_0_SYSTEM_MEMORY, 64, 0, EFI_ACPI_6_0_QWORD, 0 }, 0, 0xFFFFFF }, { // 9 EFI_ACPI_EINJ_GET_EXCUTE_OPERATION_TIMINGS EFI_ACPI_EINJ_GET_EXCUTE_OPERATION_TIMINGS, EFI_ACPI_6_0_EINJ_WRITE_REGISTER, EFI_ACPI_6_0_EINJ_PRESERVE_REGISTER, 0, { EFI_ACPI_6_0_SYSTEM_MEMORY, 64, 0, EFI_ACPI_6_0_QWORD, 0 }, 0, 0xFFFFFF } } }; EINJ_TRIGGER_ERROR_ACTION mEinjTriggerErrorAction = { { sizeof (EFI_ACPI_6_0_EINJ_TRIGGER_ACTION_TABLE), 0, sizeof (EINJ_TRIGGER_ERROR_ACTION), EINJ_TRIGGER_ERROR_ACTION_NO }, { { EFI_ACPI_6_0_EINJ_TRIGGER_ERROR, EFI_ACPI_6_0_EINJ_NOOP, 0, 0, { EFI_ACPI_6_0_SYSTEM_MEMORY, 64, 0, EFI_ACPI_6_0_DWORD, 0 }, 0, 0 } } }; VOID EinjSetAcpiTable ( EINJ_CONTEXT *Context ) { UINTN AcpiTableHandle; EFI_STATUS Status; UINT8 Checksum; EFI_ACPI_SDT_HEADER *Table; EFI_ACPI_TABLE_VERSION TableVersion; UINTN TableKey; UINTN i; Context->EINJ->EinjTableHeader.Header.Length = sizeof (EINJ_TABLE); Checksum = CalculateCheckSum8 ( (UINT8*)(Context->EINJ), Context->EINJ->EinjTableHeader.Header.Length); Context->EINJ->EinjTableHeader.Header.Checksum = Checksum; AcpiTableHandle = 0; Status = mAcpiTableProtocol->InstallAcpiTable ( mAcpiTableProtocol, Context->EINJ, Context->EINJ->EinjTableHeader.Header.Length, &AcpiTableHandle ); for (i = 0; i < EFI_ACPI_MAX_NUM_TABLES; i++) { Status = mAcpiSdtProtocol->GetAcpiTable (i, &Table, &TableVersion, &TableKey); if (EFI_ERROR (Status)) { break; } if (Table->Signature != EFI_ACPI_6_0_ERROR_INJECTION_TABLE_SIGNATURE) { continue; } mApeiTrustedfirmwareData->EinjTableAddress = (EFI_PHYSICAL_ADDRESS)Table; mApeiTrustedfirmwareData->EinjDataStruct = (EFI_PHYSICAL_ADDRESS)Context->EinjData; } ASSERT_EFI_ERROR (Status) ; } //V2 EFI_STATUS EinjHeaderCreator ( EINJ_CONTEXT *Context ) { EFI_STATUS Status; EINJ_DATA_STRUCTURE *EinjData = NULL; Status = gBS->AllocatePool ( EfiReservedMemoryType, sizeof (EINJ_DATA_STRUCTURE), (VOID**)&EinjData ); if (EFI_ERROR (Status)) { return Status; } gBS->SetMem ( EinjData, sizeof (EINJ_DATA_STRUCTURE), 0 ); DEBUG ((DEBUG_INFO, "EINJ EinjData is at 0x%X,size =0x%x\n", EinjData, sizeof (EINJ_DATA_STRUCTURE))); EinjData->TriggerErrorActionTablePtr = (EINJ_TRIGGER_ERROR_ACTION*)(&(EinjData->TriggerErrorActionTable)); gBS->CopyMem ( EinjData->TriggerErrorActionTablePtr, &mEinjTriggerErrorAction, sizeof (EINJ_TRIGGER_ERROR_ACTION)); EinjData->OperationBegin = 0; EinjData->ErrorType = 0; EinjData->ErrorCapabilities = 0xFFF; EinjData->BusyStatus = 0; EinjData->CommandStatus = 0; mEinj.EinjInstructionEntry[0].RegisterRegion.Address = (UINT64)(&(EinjData->OperationBegin)); mEinj.EinjInstructionEntry[1].RegisterRegion.Address = (UINT64)(&(EinjData->TriggerErrorActionTablePtr)); mEinj.EinjInstructionEntry[2].RegisterRegion.Address = (UINT64)(&(EinjData->ErrorType)); mEinj.EinjInstructionEntry[3].RegisterRegion.Address = (UINT64)(&(EinjData->ErrorCapabilities)); mEinj.EinjInstructionEntry[4].RegisterRegion.Address = (UINT64)(&(EinjData->OperationBegin)); mEinj.EinjInstructionEntry[6].RegisterRegion.Address = (UINT64)(&(EinjData->BusyStatus)); mEinj.EinjInstructionEntry[7].RegisterRegion.Address = (UINT64)(&(EinjData->CommandStatus)); mEinj.EinjInstructionEntry[8].RegisterRegion.Address = (UINT64)(&(EinjData->ErrorTypeWithAddress)); mEinj.EinjInstructionEntry[9].RegisterRegion.Address = (UINT64)(&(EinjData->Timing)); EinjData->ErrorTypeWithAddress.VendorErrorTypeOffset = (UINT32)((UINTN)&(EinjData->VendorErrorTypeExtension) - (UINTN)&(EinjData->ErrorTypeWithAddress)); Context->EinjData = EinjData; Context->EINJ = &mEinj; Context->ExecuteOperationEntry = &mEinj.EinjInstructionEntry[5]; Context->GetErrorTypeEntry = &mEinj.EinjInstructionEntry[3]; return EFI_SUCCESS; } EFI_STATUS EinjConfigErrorInjectCapability ( EINJ_CONTEXT* Context, UINT32 BitsSupportedErrorType ) { EFI_ACPI_6_0_EINJ_INJECTION_INSTRUCTION_ENTRY* KeyEntry; UINT32* EinjCapablity; KeyEntry = Context->GetErrorTypeEntry; EinjCapablity = (UINT32*)KeyEntry->RegisterRegion.Address; *EinjCapablity = BitsSupportedErrorType; KeyEntry->Value = BitsSupportedErrorType; return EFI_SUCCESS; }