VOID PrepareHobLegacyTable ( IN HOB_TEMPLATE *Hob ) { #if 0 CHAR8 PrintBuffer[256]; #endif Hob->Acpi.Table = (EFI_PHYSICAL_ADDRESS)(UINTN)FindAcpiRsdPtr (); #if 0 AsciiSPrint (PrintBuffer, 256, "\nAcpiTable=0x%x ", (UINT32)(UINTN)Hob->Acpi.Table); PrintString (PrintBuffer); #endif Hob->Acpi20.Table = (EFI_PHYSICAL_ADDRESS)(UINTN)FindAcpiRsdPtr (); Hob->Smbios.Table = (EFI_PHYSICAL_ADDRESS)(UINTN)FindSMBIOSPtr (); #if 0 AsciiSPrint (PrintBuffer, 256, "SMBIOS Table=0x%x ", (UINT32)(UINTN)Hob->Smbios.Table); PrintString (PrintBuffer); #endif Hob->Mps.Table = (EFI_PHYSICAL_ADDRESS)(UINTN)FindMPSPtr (); #if 0 AsciiSPrint (PrintBuffer, 256, "MPS Table=0x%x\n", (UINT32)(UINTN)Hob->Mps.Table); PrintString (PrintBuffer); #endif PrepareMcfgTable (Hob); PrepareFadtTable (Hob); return ; }
/** This function is Dce entrypoint. @retval EFI_SUCCESS Dce entrypoint run successfully @retval EFI_UNSUPPORTED not support run TXT **/ EFI_STATUS DceEntryPoint ( VOID ) { VOID *Rsdp; MLE_PRIVATE_DATA *MlePrivateData; if ((AsmReadMsr64 (IA32_FEATURE_CONTROL_MSR_INDEX) & (IA32_FEATURE_CONTROL_SMX | IA32_FEATURE_CONTROL_LCK)) != (IA32_FEATURE_CONTROL_SMX | IA32_FEATURE_CONTROL_LCK)) { DEBUG ((EFI_D_ERROR, "(TXT) !!!SMX not enabled!\n")); return EFI_UNSUPPORTED; } MlePrivateData = GetMlePrivateData (); DEBUG ((EFI_D_INFO, "(TXT) DprBase - %08x\n", (UINTN)MlePrivateData->DcePrivateData.DprBase)); DEBUG ((EFI_D_INFO, "(TXT) DprSize - %08x\n", (UINTN)MlePrivateData->DcePrivateData.DprSize)); DEBUG ((EFI_D_INFO, "(TXT) PmrLowBase - %08x\n", (UINTN)MlePrivateData->DcePrivateData.PmrLowBase)); DEBUG ((EFI_D_INFO, "(TXT) PmrLowSize - %08x\n", (UINTN)MlePrivateData->DcePrivateData.PmrLowSize)); DEBUG ((EFI_D_INFO, "(TXT) LcpPoBase - %08x\n", (UINTN)MlePrivateData->DcePrivateData.LcpPoBase)); DEBUG ((EFI_D_INFO, "(TXT) LcpPoSize - %08x\n", (UINTN)MlePrivateData->DcePrivateData.LcpPoSize)); MlePrivateData->CpuNum = GetTxtCpuNumber (); MlePrivateData->DcePrivateData.DL_Entry = (EFI_PHYSICAL_ADDRESS)(UINTN)DL_Entry; MlePrivateData->DcePrivateData.DLME_Exit = (EFI_PHYSICAL_ADDRESS)(UINTN)DLME_Exit; Rsdp = FindAcpiRsdPtr (); DEBUG ((EFI_D_INFO, "(TXT) UefiRsdp - %08x\n", (UINTN)Rsdp)); if (Rsdp != NULL) { CopyMem (&MlePrivateData->UefiRsdp, Rsdp, sizeof(MlePrivateData->UefiRsdp)); } return EFI_SUCCESS; }
/** This function set TXT HEAP. @param MleLoadAddress MLE address @param MleLoadSize MLE size @param PageTableBase page table base **/ VOID TxtSetupHeap ( IN UINT64 MleLoadAddress, IN UINT64 MleLoadSize, IN UINT64 PageTableBase ) { VOID *TxtOsMleData; MLE_PRIVATE_DATA *MlePrivateData; DCE_PRIVATE_DATA *DcePrivateData; TXT_OS_TO_SINIT_DATA *OsSinitData; TXT_SINIT_TO_MLE_DATA *SinitMleData; TXT_ACM_FORMAT *SinitAcm; TXT_CHIPSET_ACM_INFORMATION_TABLE *ChipsetAcmInformationTable; UINTN TxtHeapSize; UINTN TxtHeapOccupiedSize; // // MlePrivateData // TxtOsMleData = GetTxtOsToMleData(); DEBUG((EFI_D_INFO, "(TXT) TxtOsMleData - 0x%x\n", TxtOsMleData)); *((UINT64 *)TxtOsMleData - 1) = sizeof(UINT64) + sizeof(TXT_OS_TO_MLE_DATA_STRUCT); MlePrivateData = GetMlePrivateData (); DcePrivateData = &MlePrivateData->DcePrivateData; AsmReadGdtr (&MlePrivateData->Gdtr); AsmReadIdtr (&MlePrivateData->Idtr); MlePrivateData->Ds = AsmReadDs (); MlePrivateData->TempEsp = (UINT32)(UINT32)((UINTN)GetTxtHeap () + GetTxtHeapSize () - MLE_TEMP_STACK_SIZE_RLP - 0x20); // // Patch CS/Offset in stack // // +---------+ // | Offset | // +---------+ // | CS | // +---------+ // | Dummy | // +---------+ // | Dummy | // +---------+ // | Dummy | // +---------+ // | Dummy | // +---------+ <- TempEsp if (PostInitAddr != 0) { MlePrivateData->PostSinitOffset = (UINT32)((UINTN)AsmMleEntryPoint + PostInitAddr); MlePrivateData->PostSinitSegment = (UINT32)AsmReadCs(); } MlePrivateData->Lock = 0; MlePrivateData->RlpInitializedNumber = 0; // // OsSinitData // OsSinitData = GetTxtOsToSinitData (); DEBUG((EFI_D_INFO, "(TXT) OsSinitData - 0x%x\n", OsSinitData)); *((UINT64 *)OsSinitData - 1) = sizeof(UINT64) + sizeof(*OsSinitData); OsSinitData->Version = TXT_OS_TO_SINIT_DATA_VERSION; OsSinitData->Flags = 0; OsSinitData->MLEPageTableBase = PageTableBase; // // We copy MleHeader to DPR // { TXT_MLE_HEADER *MleHeader; MleHeader = (TXT_MLE_HEADER *)(UINTN)MleLoadAddress; CopyMem (&MleHeader->Uuid, &gMleHeaderUuid, sizeof(gMleHeaderUuid)); MleHeader->HeaderLen = sizeof(*MleHeader); MleHeader->Version = TXT_MLE_HEADER_VERSION; MleHeader->EntryPoint = (UINT32)(UINTN)MleHeader + sizeof(*MleHeader); if (MleHeader->Version < TXT_MLE_HEADER_VERSION_2_1) { MleHeader->EntryPoint -= (sizeof(MleHeader->CmdlineStart) + sizeof(MleHeader->CmdlineEnd)); } // // Patch the instruction for ILP // *(UINT8 *)(UINTN)MleHeader->EntryPoint = 0x90; // nop *(UINT8 *)((UINTN)MleHeader->EntryPoint + 1) = 0xE9; // near jmp *(UINT32 *)((UINTN)MleHeader->EntryPoint + 2) = (UINT32)((UINTN)AsmMleEntryPoint - ((UINTN)MleHeader->EntryPoint + 6)); // minus next instruction // // Patch the instrution for RLPs: cli, hlt, and jmp $-2 // *(UINT32 *)((UINTN)MleHeader->EntryPoint + 6) = 0xFCEBF4FA; MleHeader->EntryPoint -= (UINT32)PageTableBase; if (MleHeader->Version >= TXT_MLE_HEADER_VERSION_1_1) { MleHeader->FirstValidPage = (UINT32)MleLoadAddress; MleHeader->FirstValidPage -= (UINT32)PageTableBase; MleHeader->MleStart = MleHeader->FirstValidPage; //MleHeader->MleEnd = MleHeader->MleStart + sizeof(*MleHeader) + 10; // Offset (1 nop + 5 jmp + 4 deadloop) MleHeader->MleEnd = MleHeader->MleStart + (UINT32)MleLoadSize; } if (MleHeader->Version >= TXT_MLE_HEADER_VERSION_2) { MleHeader->Capabilities = TXT_MLE_SINIT_CAPABILITY_GETSET_WAKEUP | TXT_MLE_SINIT_CAPABILITY_MONITOR_ADDRESS_RLP_WAKEUP; MleHeader->Capabilities |= TXT_MLE_SINIT_CAPABILITY_ECX_HAS_PAGE_TABLE; #ifdef STM_SUPPORT MleHeader->Capabilities |= TXT_MLE_SINIT_CAPABILITY_STM; #endif } if (MleHeader->Version >= TXT_MLE_HEADER_VERSION_2_1) { MleHeader->CmdlineStart = 0; // Not use MleHeader->CmdlineEnd = 0; // Not use } // // Done // OsSinitData->MLEHeaderBase = (UINT64)(UINTN)MleHeader; OsSinitData->MLEHeaderBase -= PageTableBase; OsSinitData->MLESize = (UINT64)(MleHeader->MleEnd - MleHeader->MleStart); } OsSinitData->PMRLowBase = MlePrivateData->DcePrivateData.PmrLowBase; OsSinitData->PMRLowSize = MlePrivateData->DcePrivateData.PmrLowSize; OsSinitData->PMRHighBase = MlePrivateData->DcePrivateData.PmrHighBase; OsSinitData->PMRHighSize = MlePrivateData->DcePrivateData.PmrHighSize; OsSinitData->LCPPOBase = MlePrivateData->DcePrivateData.LcpPoBase; OsSinitData->LCPPOSize = MlePrivateData->DcePrivateData.LcpPoSize; SinitAcm = (TXT_ACM_FORMAT *)(UINTN)TxtPubRead32 (TXT_SINIT_BASE); ChipsetAcmInformationTable = (TXT_CHIPSET_ACM_INFORMATION_TABLE *) \ ((UINTN)(SinitAcm + 1) + SinitAcm->KeySize * 4 + sizeof(UINT32) + ACM_PKCS_1_5_RSA_SIGNATURE_SIZE + SinitAcm->ScratchSize * 4 ); if ((ChipsetAcmInformationTable->Capabilities & TXT_MLE_SINIT_CAPABILITY_MONITOR_ADDRESS_RLP_WAKEUP) != 0) { OsSinitData->Capabilities = TXT_MLE_SINIT_CAPABILITY_MONITOR_ADDRESS_RLP_WAKEUP; } else { OsSinitData->Capabilities = TXT_MLE_SINIT_CAPABILITY_GETSET_WAKEUP; } OsSinitData->Version = ChipsetAcmInformationTable->OsSinitTableVer; if (ChipsetAcmInformationTable->OsSinitTableVer >= TXT_OS_TO_SINIT_DATA_VERSION_5) { OsSinitData->RsdpPtr = (UINT64)(UINTN)FindAcpiRsdPtr (); if (OsSinitData->RsdpPtr == 0) { OsSinitData->RsdpPtr = (UINT64)(UINTN)&MlePrivateData->UefiRsdp; } if (ChipsetAcmInformationTable->OsSinitTableVer >= TXT_OS_TO_SINIT_DATA_VERSION_6) { if (ChipsetAcmInformationTable->OsSinitTableVer >= TXT_OS_TO_SINIT_DATA_VERSION_7) { OsSinitData->Flags = TXT_OS_TO_SINIT_DATA_FLAGS_MAX_AGILE_POLICY; } // // Fill Event Log data there // TXT_HEAP_EXT_DATA_ELEMENT *Element; TXT_HEAP_EVENTLOG_EXT_ELEMENT *EventLogElement; TXT_EVENT_LOG_CONTAINER *EventLog; TXT_HEAP_EVENT_LOG_POINTER_ELEMENT2 *EventLogPointerElement2; TXT_HEAP_EVENT_LOG_POINTER_ELEMENT2_1 *EventLogPointerElement2_1; TXT_HEAP_EVENT_LOG_DESCR *EventLogDesc; UINTN Index; TCG_LOG_DESCRIPTOR *TcgLogDesc; TCG_PCR_EVENT_HDR *PcrEvent; *((UINT64 *)OsSinitData - 1) = sizeof(UINT64) + sizeof(*OsSinitData); Element = (TXT_HEAP_EXT_DATA_ELEMENT *)(OsSinitData + 1); if (DcePrivateData->TpmType == FRM_TPM_TYPE_TPM12) { // TPM1.2 Element->Type = TXT_HEAP_EXTDATA_TYPE_EVENTLOG_PTR; Element->Size = sizeof(TXT_HEAP_EXT_DATA_ELEMENT) + sizeof(TXT_HEAP_EVENTLOG_EXT_ELEMENT); EventLogElement = (TXT_HEAP_EVENTLOG_EXT_ELEMENT *)(Element + 1); DcePrivateData->EventLogElement = EventLogElement; // // Init EventLogContainer // EventLog = (TXT_EVENT_LOG_CONTAINER *)(UINTN)(MlePrivateData->DcePrivateData.EventLogBase); ZeroMem(EventLog, MAX_EVENT_LOG_BUFFER_SIZE); CopyMem(EventLog->Signature, TXT_EVENTLOG_SIGNATURE, sizeof(TXT_EVENTLOG_SIGNATURE)); EventLog->ContainerVersionMajor = TXT_EVENTLOG_CONTAINER_MAJOR_VERSION; EventLog->ContainerVersionMinor = TXT_EVENTLOG_CONTAINER_MINOR_VERSION; EventLog->PcrEventVersionMajor = TXT_EVENTLOG_EVENT_MAJOR_VERSION; EventLog->PcrEventVersionMinor = TXT_EVENTLOG_EVENT_MINOR_VERSION; EventLog->Size = MAX_EVENT_LOG_BUFFER_SIZE; EventLog->PcrEventsOffset = sizeof(*EventLog); EventLog->NextEventOffset = sizeof(*EventLog); EventLogElement->EventLogAddress = (UINT64)(UINTN)EventLog; *((UINT64 *)OsSinitData - 1) += Element->Size; Element = (TXT_HEAP_EXT_DATA_ELEMENT *)((UINTN)Element + Element->Size); } if (DcePrivateData->TpmType == FRM_TPM_TYPE_TPM2) { // TPM2.0 UINT16 TpmHashAlgo[] = { TPM_ALG_SHA1, TPM_ALG_SHA256, TPM_ALG_SHA384, TPM_ALG_SHA512, TPM_ALG_SM3_256 }; UINTN SubIndex; DcePrivateData->EventHashAlgoIDCount = 0; for (Index = 0; Index < sizeof(TpmHashAlgo) / sizeof(TpmHashAlgo[0]); Index++) { if ((DcePrivateData->ActivePcrBanks & (1 << Index)) != 0) { for (SubIndex = 0; SubIndex < DcePrivateData->AcmTpmHashAlgoIDCount; SubIndex++) { if (DcePrivateData->AcmTpmHashAlgoID[SubIndex] == TpmHashAlgo[Index]) { // Both TPM and ACM support this hash algo. DcePrivateData->EventHashAlgoID[DcePrivateData->EventHashAlgoIDCount] = TpmHashAlgo[Index]; DcePrivateData->EventHashAlgoIDCount++; } } } } if ((DcePrivateData->AcmCapabilities & TXT_MLE_SINIT_CAPABILITY_TCG2_COMPATIBILE_EVENTLOG) == 0) { Element->Type = TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2; EventLogPointerElement2 = (TXT_HEAP_EVENT_LOG_POINTER_ELEMENT2 *)(Element + 1); DcePrivateData->EventLogPointerElement2 = EventLogPointerElement2; EventLogPointerElement2->Count = DcePrivateData->EventHashAlgoIDCount; EventLogDesc = (TXT_HEAP_EVENT_LOG_DESCR *)(EventLogPointerElement2 + 1); Element->Size = sizeof(TXT_HEAP_EXT_DATA_ELEMENT) + sizeof(TXT_HEAP_EVENT_LOG_POINTER_ELEMENT2) + EventLogPointerElement2->Count * sizeof(TXT_HEAP_EVENT_LOG_DESCR); for (Index = 0; Index < EventLogPointerElement2->Count; Index++, EventLogDesc++) { EventLogDesc->HashAlgID = DcePrivateData->EventHashAlgoID[Index]; EventLogDesc->Reserved = 0; EventLogDesc->PhysicalAddress = (UINT64)(UINTN)(MlePrivateData->DcePrivateData.EventLogBase + MAX_EVENT_LOG_BUFFER_SIZE * (Index + 1)); ZeroMem((VOID *)(UINTN)EventLogDesc->PhysicalAddress, MAX_EVENT_LOG_BUFFER_SIZE); EventLogDesc->AllocatedEventContainerSize = MAX_EVENT_LOG_BUFFER_SIZE; if (EventLogDesc->HashAlgID == TPM_ALG_SHA) { PcrEvent = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogDesc->PhysicalAddress; TcgLogDesc = (TCG_LOG_DESCRIPTOR *)(PcrEvent + 1); PcrEvent->PCRIndex = 0; PcrEvent->EventType = EV_NO_ACTION; ZeroMem(&PcrEvent->Digest, sizeof(PcrEvent->Digest)); PcrEvent->EventSize = sizeof(TCG_LOG_DESCRIPTOR); CopyMem(TcgLogDesc->Signature, TCG_LOG_DESCRIPTOR_SIGNATURE, sizeof(TCG_LOG_DESCRIPTOR_SIGNATURE)); TcgLogDesc->Revision = TCG_LOG_DESCRIPTOR_REVISION; TcgLogDesc->DigestAlgID = DIGEST_ALG_ID_SHA_1; TcgLogDesc->DigestSize = SHA1_DIGEST_SIZE; EventLogDesc->FirstRecordOffset = sizeof(TCG_PCR_EVENT_HDR) + PcrEvent->EventSize; EventLogDesc->NextRecordOffset = sizeof(TCG_PCR_EVENT_HDR) + PcrEvent->EventSize; } else { EventLogDesc->FirstRecordOffset = 0; EventLogDesc->NextRecordOffset = 0; } } } else { Element->Type = TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2_1; EventLogPointerElement2_1 = (TXT_HEAP_EVENT_LOG_POINTER_ELEMENT2_1 *)(Element + 1); DcePrivateData->EventLogPointerElement2_1 = EventLogPointerElement2_1; EventLogPointerElement2_1->PhysicalAddress = (UINT64)(UINTN)(MlePrivateData->DcePrivateData.EventLogBase + MAX_EVENT_LOG_BUFFER_SIZE); ZeroMem((VOID *)(UINTN)EventLogPointerElement2_1->PhysicalAddress, MAX_EVENT_LOG_BUFFER_SIZE); EventLogPointerElement2_1->AllocatedEventContainerSize = MAX_EVENT_LOG_BUFFER_SIZE * 5; EventLogPointerElement2_1->FirstRecordOffset = 0; EventLogPointerElement2_1->NextRecordOffset = 0; } *((UINT64 *)OsSinitData - 1) += Element->Size; Element = (TXT_HEAP_EXT_DATA_ELEMENT *)((UINTN)Element + Element->Size); } Element->Type = TXT_HEAP_EXTDATA_TYPE_END; Element->Size = sizeof(TXT_HEAP_END_ELEMENT); *((UINT64 *)OsSinitData - 1) += sizeof(TXT_HEAP_END_ELEMENT); } } else { // Version 4 *((UINT64 *)OsSinitData - 1) = sizeof(UINT64) + sizeof(*OsSinitData) - sizeof(UINT64); } // // SinitMleData // SinitMleData = GetTxtSinitToMleData (); DEBUG((EFI_D_INFO, "(TXT) SinitMleData - 0x%x\n", SinitMleData)); *((UINT64 *)SinitMleData - 1) = 0; ZeroMem (SinitMleData, sizeof(*SinitMleData)); TxtHeapSize = GetTxtHeapSize (); TxtHeapOccupiedSize = GetTxtHeapOccupiedSize (); DEBUG ((EFI_D_INFO, "(TXT) TXT Heap base - %08x\n", GetTxtHeap ())); DEBUG ((EFI_D_INFO, "(TXT) TXT Heap size - %08x\n", TxtHeapSize)); DEBUG ((EFI_D_INFO, "(TXT) TXT BiosOsData - %08x\n", GetTxtBiosToOsData())); DEBUG ((EFI_D_INFO, "(TXT) TXT OsMleData - %08x\n", (UINTN)TxtOsMleData)); DEBUG ((EFI_D_INFO, "(TXT) TXT OsSinitData - %08x\n", (UINTN)OsSinitData)); DEBUG ((EFI_D_INFO, "(TXT) TXT SinitMleData - %08x\n", (UINTN)SinitMleData)); DEBUG ((EFI_D_INFO, "(TXT) TXT OccupiedSize - %08x\n", TxtHeapOccupiedSize)); // // Check heap // if (TxtHeapOccupiedSize >= TxtHeapSize) { DEBUG ((EFI_D_ERROR, "(TXT) ERROR: TXT Heap overflow - Occupied (%08x), Allocated (%08x)\n", TxtHeapOccupiedSize, TxtHeapSize)); ASSERT(FALSE); } if (OsSinitData->RsdpPtr != 0) { EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp; EFI_ACPI_DESCRIPTION_HEADER *Rsdt; EFI_ACPI_DESCRIPTION_HEADER *Xsdt; // validate ACPI RSDP/RSDT/XSDT Rsdp = (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)OsSinitData->RsdpPtr; DEBUG ((EFI_D_INFO, "(TXT) RSDP Address - %08x\n", Rsdp)); DEBUG ((EFI_D_INFO, "(TXT) RSDP Checksum - %02x\n", CalculateCheckSum8((UINT8 *)Rsdp, sizeof(EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER)))); if (Rsdp->Revision >= 2) { DEBUG ((EFI_D_INFO, "(TXT) RSDP Length - %08x\n", Rsdp->Length)); DEBUG ((EFI_D_INFO, "(TXT) RSDP ExtendedChecksum - %02x\n", CalculateCheckSum8((UINT8 *)Rsdp, Rsdp->Length))); } Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->RsdtAddress; DEBUG ((EFI_D_INFO, "(TXT) RSDT Address - %08x\n", Rsdt)); DEBUG ((EFI_D_INFO, "(TXT) RSDT Length - %08x\n", Rsdt->Length)); DEBUG ((EFI_D_INFO, "(TXT) RSDT Checksum - %02x\n", CalculateCheckSum8((UINT8 *)Rsdt, Rsdt->Length))); if (Rsdp->Revision >= 2) { Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->XsdtAddress; DEBUG ((EFI_D_INFO, "(TXT) XSDT Address - %016lx\n", Xsdt)); DEBUG ((EFI_D_INFO, "(TXT) XSDT Length - %08x\n", Xsdt->Length)); DEBUG ((EFI_D_INFO, "(TXT) XSDT Checksum - %02x\n", CalculateCheckSum8((UINT8 *)Xsdt, Xsdt->Length))); } } return ; }
VOID FillSysTablesInfo(VOID **Tables, UINT32 TablesSize) { UINT32 Table = 0; EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *RsdPtr; VOID *TablesPage; #define FLAG_OPTIONAL 1<<0 #define FLAG_NO_CHECKSUM 1<<1 static struct { UINT32 Signature; UINT32 Flags; CHAR8* Name; } TableInfo[] = { // MADT, optional { SIGNATURE_32('A', 'P', 'I', 'C'), FLAG_OPTIONAL, "MADT"}, // FACP (also called FADT) { SIGNATURE_32('F', 'A', 'C', 'P'), 0, "FADT"}, // FACS, according 5.2.9 of ACPI v2. spec FACS doesn't have checksum field { SIGNATURE_32('F', 'A', 'C', 'S'), FLAG_NO_CHECKSUM, "FACS"}, // DSDT { SIGNATURE_32('D', 'S', 'D', 'T'), 0, "DSDT"}, // SSDT { SIGNATURE_32('S', 'S', 'D', 'T'), FLAG_OPTIONAL, "SSDT"}, // HPET { SIGNATURE_32('H', 'P', 'E', 'T'), FLAG_OPTIONAL, "HPET"}, // MCFG { SIGNATURE_32('M', 'C', 'F', 'G'), FLAG_OPTIONAL, "MCFG"} }; UINT32 Index; RsdPtr = (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER*)FindAcpiRsdPtr(); ASSERT(RsdPtr != NULL); TablesPage = (VOID*)(UINTN)((RsdPtr->RsdtAddress) & ~0xfff); DEBUG((DEBUG_INFO, "TablesPage:%p\n", TablesPage)); for (Index = 0; Index < sizeof TableInfo / sizeof TableInfo[0]; Index++) { VOID *Ptr = FindSignature(TablesPage, TableInfo[Index].Signature, (BOOLEAN)((TableInfo[Index].Flags & FLAG_NO_CHECKSUM) != 0)); if (TableInfo[Index].Signature == SIGNATURE_32('F', 'A', 'C', 'P')) { // we actually have 2 FADTs, see https://xtracker.innotek.de/index.php?bug=4082 Ptr = FindSignature((UINT8*)Ptr+32, SIGNATURE_32('F', 'A', 'C', 'P'), FALSE); } if (!(TableInfo[Index].Flags & FLAG_OPTIONAL)) { if (!Ptr) DEBUG((EFI_D_ERROR, "%a: isn't optional %p\n", TableInfo[Index].Name, Ptr)); ASSERT(Ptr != NULL); } DEBUG((EFI_D_ERROR, "%a: %p\n", TableInfo[Index].Name, Ptr)); if (Ptr) Tables[Table++] = Ptr; } #if 0 // RSDT ASSERT(Table < TablesSize); Tables[Table] = FindSignature(TablesPage, SIGNATURE_32('R', 'S', 'D', 'T')); DEBUG ((EFI_D_ERROR, "RSDT: %p\n", Tables[Table])); ASSERT(Tables[Table] != NULL); Table++; // XSDT ASSERT(Table < TablesSize); Tables[Table] = FindSignature(TablesPage, SIGNATURE_32('X', 'S', 'D', 'T')); DEBUG ((EFI_D_ERROR, "XSDT: %p\n", Tables[Table])); ASSERT(Tables[Table] != NULL); Table++; #endif DEBUG((DEBUG_INFO, "We found %d tables from %d\n", Table, TablesSize)); Tables[Table] = NULL; }
VOID MemMapInitialization ( EFI_PHYSICAL_ADDRESS TopOfMemory ) { EFI_PHYSICAL_ADDRESS RsdPtr; EFI_PHYSICAL_ADDRESS AcpiTables; // // Create Memory Type Information HOB // BuildGuidDataHob ( &gEfiMemoryTypeInformationGuid, mDefaultMemoryTypeInformation, sizeof(mDefaultMemoryTypeInformation) ); // // Add PCI IO Port space available for PCI resource allocations. // BuildResourceDescriptorHob ( EFI_RESOURCE_IO, EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED, 0xC000, 0x4000 ); // // Add PCI MMIO space available to PCI resource allocations // if (TopOfMemory < BASE_2GB) { AddIoMemoryBaseSizeHob (BASE_2GB, 0xFC000000 - BASE_2GB); } else { AddIoMemoryBaseSizeHob (TopOfMemory, 0xFC000000 - TopOfMemory); } // // Local APIC range // AddIoMemoryBaseSizeHob (0xFEC80000, SIZE_512KB); // // I/O APIC range // AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_512KB); // // Video memory + Legacy BIOS region // This includes ACPI floating pointer region. // AddIoMemoryRangeHob (0x0A0000, BASE_1MB); // // Add ACPI memory, provided by VBox // RsdPtr = (EFI_PHYSICAL_ADDRESS)(UINTN)FindAcpiRsdPtr(); ASSERT(RsdPtr != 0); AcpiTables = (EFI_PHYSICAL_ADDRESS)*(UINT32*)((UINTN)RsdPtr + 16) & ~0xfff; ASSERT(AcpiTables != 0); // ACPI tables 64 K AddRomMemoryBaseSizeHob(AcpiTables, 0x10000); }
EFI_STATUS Main( VOID ) { EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupportProtocol; EFI_LEGACY_BIOS_PROTOCOL *LegacyBiosProtocol; UINT64 Handel = 0; UINTN DataSize = 0; EFI_TPL OldTpl; EFI_STATUS Status = EFI_UNSUPPORTED; Rsdp20Tbl_t *RsdpTable = 0; Rsdp20Tbl_t *LegacyRsdpTable = 0; RsdtTbl_t *RsdtTable = 0; XsdtTbl_t *XsdtTable = 0; SlicTbl_t *SlicTable = 0; AcpiTbl_t *AcpiTable = 0; VOID *LegacyAddress = 0; UINT8 SlpString[0x20] = { 0 }; UINTN i = 0; //=========================================================================// // code starts // //=========================================================================// SlicTable = (SlicTbl_t *)SLIC; //=========================================================================// // add Marker and Public Key to empty SLIC // //=========================================================================// DataSize = sizeof(Marker_t); if (RS->GetVariable(OaMarkerName, &OaMarkerGuid, 0, &DataSize, &SlicTable->Marker) != EFI_SUCCESS || DataSize != sizeof(Marker_t)) { return EFI_NOT_FOUND; } DataSize = sizeof(PublicKey_t); if (RS->GetVariable(OaPublicKeyName, &OaPublicKeyGuid, 0, &DataSize, &SlicTable->PublicKey) != EFI_SUCCESS || DataSize != sizeof(PublicKey_t)) { return EFI_NOT_FOUND; } //=========================================================================// // copy OemId, OemTableId from Marker to SLIC ACPI header // //=========================================================================// BS->CopyMem(SlicTable->Header.OemId, SlicTable->Marker.OemId, 6); BS->CopyMem(SlicTable->Header.OemTableId, SlicTable->Marker.OemTableId, 8); //=========================================================================// // add SLIC to ACPI tables // //=========================================================================// if(BS->LocateProtocol(&AcpiProtocolGuid, NULL, (VOID **) &AcpiSupportProtocol) == EFI_SUCCESS) { Status = AcpiSupportProtocol->SetAcpiTable(AcpiSupportProtocol, (VOID *)SLIC, TRUE, EFI_ACPI_TABLE_VERSION_1_0B|EFI_ACPI_TABLE_VERSION_2_0|EFI_ACPI_TABLE_VERSION_3_0, &Handel); } if (Status != EFI_SUCCESS) { return Status; } #if SLP_INJECT == 1 //=========================================================================// // add SLP 1.0 string to legacy region // //=========================================================================// DataSize = sizeof(SlpString); if (RS->GetVariable(OaSlpName, &OaSlpGuid, 0, &DataSize, SlpString) == EFI_SUCCESS) { if (BS->LocateProtocol(&LegacyBiosGuid, NULL, (VOID **)&LegacyBiosProtocol) == EFI_SUCCESS) { if (LegacyBiosProtocol->GetLegacyRegion(LegacyBiosProtocol, sizeof(SlpString), 1, 2, &LegacyAddress) == EFI_SUCCESS) { Status = LegacyBiosProtocol->CopyLegacyRegion(LegacyBiosProtocol, DataSize, LegacyAddress, SlpString); } } } #endif //=========================================================================// // find ACPI tables // //=========================================================================// OldTpl = BS->RaiseTPL(TPL_HIGH_LEVEL); Status = GetSystemConfigurationTable (&EfiAcpi20TableGuid, (VOID **)&RsdpTable); if (EFI_ERROR (Status)) { Status = GetSystemConfigurationTable (&EfiAcpiTableGuid, (VOID **)&RsdpTable); } if (Status == EFI_SUCCESS) { if (RsdpTable->Revision == 0) { RsdtTable = (RsdtTbl_t *) RsdpTable->RSDTAddress; } else if (RsdpTable->Revision == 2) { RsdtTable = (RsdtTbl_t *) RsdpTable->RSDTAddress; XsdtTable = (XsdtTbl_t *) RsdpTable->XSDTAddress; } else { return EFI_UNSUPPORTED; } } else { return EFI_NOT_FOUND; } //=========================================================================// // copy SLIC OemId, OemTableId to RSDP, RSDT, XSDT // //=========================================================================// #if PATCH_TABLES == 1 DataSize = (RsdtTable->Header.Length - sizeof(AcpiHeader_t)) << 2; for(i = 0 ; i < DataSize; i++) { AcpiTable = (AcpiTbl_t *) RsdtTable->Entry[i]; if (AcpiTable != NULL) { if (CompareMem(AcpiTable->Header.OemId, RsdtTable->Header.OemId, 6) == 0 && CompareMem(AcpiTable->Header.OemTableId, RsdtTable->Header.OemTableId, 8) == 0) { BS->CopyMem(AcpiTable->Header.OemId, SlicTable->Header.OemId, 6); BS->CopyMem(AcpiTable->Header.OemTableId, SlicTable->Header.OemTableId, 8); AcpiTable->Header.Checksum = 0; AcpiTable->Header.Checksum = ComputeChecksum((UINT8 *) AcpiTable, AcpiTable->Header.Length); } } } #endif BS->CopyMem(RsdtTable->Header.OemId, SlicTable->Header.OemId, 6); BS->CopyMem(RsdtTable->Header.OemTableId, SlicTable->Header.OemTableId, 8); RsdtTable->Header.Checksum = 0; RsdtTable->Header.Checksum = ComputeChecksum((UINT8 *) RsdtTable, RsdtTable->Header.Length); BS->CopyMem(RsdpTable->OemId, SlicTable->Header.OemId, 6); RsdpTable->Checksum = 0; RsdpTable->Checksum = ComputeChecksum((UINT8 *) RsdpTable, 0x14); if(RsdpTable->Revision == 2) { #if PATCH_TABLES == 1 DataSize = (XsdtTable->Header.Length - sizeof(AcpiHeader_t)) << 3; for(i = 0 ; i < DataSize; i++) { AcpiTable = (AcpiTbl_t *) (XsdtTable->Entry[i] & 0xFFFFFFFF); if (AcpiTable != NULL) { if (CompareMem(AcpiTable->Header.OemId, XsdtTable->Header.OemId, 6) == 0 && CompareMem(AcpiTable->Header.OemTableId, XsdtTable->Header.OemTableId, 8) == 0) { BS->CopyMem(AcpiTable->Header.OemId, SlicTable->Header.OemId, 6); BS->CopyMem(AcpiTable->Header.OemTableId, SlicTable->Header.OemTableId, 8); AcpiTable->Header.Checksum = 0; AcpiTable->Header.Checksum = ComputeChecksum((UINT8 *) AcpiTable, AcpiTable->Header.Length); } } } #endif RsdpTable->ExtendedChecksum = 0; RsdpTable->ExtendedChecksum = ComputeChecksum((UINT8 *) RsdpTable, RsdpTable->Length); BS->CopyMem(XsdtTable->Header.OemId, SlicTable->Header.OemId, 6); BS->CopyMem(XsdtTable->Header.OemTableId, SlicTable->Header.OemTableId, 8); XsdtTable->Header.Checksum = 0; XsdtTable->Header.Checksum = ComputeChecksum((UINT8 *) XsdtTable, XsdtTable->Header.Length); } //=========================================================================// // copy OemId to RSDP in legacy region // //=========================================================================// LegacyRsdpTable = (Rsdp20Tbl_t *) FindAcpiRsdPtr(); if (LegacyRsdpTable != NULL && LegacyUnlock() == EFI_SUCCESS) { BS->CopyMem(LegacyRsdpTable->OemId, SlicTable->Header.OemId, 6); LegacyRsdpTable->RSDTAddress = RsdpTable->RSDTAddress; LegacyRsdpTable->Checksum = 0; LegacyRsdpTable->Checksum = ComputeChecksum((UINT8 *) LegacyRsdpTable, 0x14); if(LegacyRsdpTable->Revision == 2) { LegacyRsdpTable->XSDTAddress = RsdpTable->XSDTAddress; LegacyRsdpTable->ExtendedChecksum = 0; LegacyRsdpTable->ExtendedChecksum = ComputeChecksum((UINT8 *) LegacyRsdpTable, LegacyRsdpTable->Length); } LegacyLock(); } BS->RestoreTPL(OldTpl); return Status; }