/** Save IDT entry for INT1 and update it. @param[in] IdtDescriptor Pointer to IDT Descriptor. @param[out] SavedIdtEntry Original IDT entry returned. **/ VOID SaveAndUpdateIdtEntry1 ( IN IA32_DESCRIPTOR *IdtDescriptor, OUT IA32_IDT_GATE_DESCRIPTOR *SavedIdtEntry ) { IA32_IDT_GATE_DESCRIPTOR *IdtEntry; UINT16 CodeSegment; UINTN InterruptHandler; IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor->Base; CopyMem (SavedIdtEntry, &IdtEntry[1], sizeof (IA32_IDT_GATE_DESCRIPTOR)); // // Use current CS as the segment selector of interrupt gate in IDT // CodeSegment = AsmReadCs (); InterruptHandler = (UINTN) &AsmInterruptHandle; IdtEntry[1].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler; IdtEntry[1].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16); IdtEntry[1].Bits.OffsetUpper = (UINT32)((UINTN)InterruptHandler >> 32); IdtEntry[1].Bits.Selector = CodeSegment; IdtEntry[1].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; }
/** Initialize IDT entries to support source level debug. **/ VOID InitializeDebugIdt ( VOID ) { IA32_IDT_GATE_DESCRIPTOR *IdtEntry; UINTN InterruptHandler; IA32_DESCRIPTOR IdtDescriptor; UINTN Index; UINT16 CodeSegment; UINT32 RegEdx; AsmReadIdtr (&IdtDescriptor); // // Use current CS as the segment selector of interrupt gate in IDT // CodeSegment = AsmReadCs (); IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base; for (Index = 0; Index < 20; Index ++) { if (((PcdGet32 (PcdExceptionsIgnoredByDebugger) & ~(BIT1 | BIT3)) & (1 << Index)) != 0) { // // If the exception is masked to be reserved except for INT1 and INT3, skip it // continue; } InterruptHandler = (UINTN)&Exception0Handle + Index * ExceptionStubHeaderSize; IdtEntry[Index].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler; IdtEntry[Index].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16); IdtEntry[Index].Bits.Selector = CodeSegment; IdtEntry[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; } InterruptHandler = (UINTN) &TimerInterruptHandle; IdtEntry[DEBUG_TIMER_VECTOR].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler; IdtEntry[DEBUG_TIMER_VECTOR].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16); IdtEntry[DEBUG_TIMER_VECTOR].Bits.Selector = CodeSegment; IdtEntry[DEBUG_TIMER_VECTOR].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; // // If the CPU supports Debug Extensions(CPUID:01 EDX:BIT2), then // Set DE flag in CR4 to enable IO breakpoint // AsmCpuid (1, NULL, NULL, NULL, &RegEdx); if ((RegEdx & BIT2) != 0) { AsmWriteCr4 (AsmReadCr4 () | BIT3); } }
/** Set a IDT entry for interrupt vector 3 for debug purpose. @param AcpiS3Context a pointer to a structure of ACPI_S3_CONTEXT **/ VOID SetIdtEntry ( IN ACPI_S3_CONTEXT *AcpiS3Context ) { INTERRUPT_GATE_DESCRIPTOR *IdtEntry; IA32_DESCRIPTOR *IdtDescriptor; UINTN S3DebugBuffer; // // Restore IDT for debug // IdtDescriptor = (IA32_DESCRIPTOR *) (UINTN) (AcpiS3Context->IdtrProfile); IdtEntry = (INTERRUPT_GATE_DESCRIPTOR *)(IdtDescriptor->Base + (3 * sizeof (INTERRUPT_GATE_DESCRIPTOR))); S3DebugBuffer = (UINTN) (AcpiS3Context->S3DebugBufferAddress); IdtEntry->OffsetLow = (UINT16)S3DebugBuffer; IdtEntry->SegmentSelector = (UINT16)AsmReadCs (); IdtEntry->Attributes = (UINT16)INTERRUPT_GATE_ATTRIBUTE; IdtEntry->OffsetHigh = (UINT16)(S3DebugBuffer >> 16); AsmWriteIdtr (IdtDescriptor); }
/** 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 ; }
/** Internal worker function to update IDT entries accordling to vector attributes. @param[in] IdtTable Pointer to IDT table. @param[in] TemplateMap Pointer to a buffer where the address map is returned. @param[in] ExceptionHandlerData Pointer to exception handler data. **/ VOID UpdateIdtTable ( IN IA32_IDT_GATE_DESCRIPTOR *IdtTable, IN EXCEPTION_HANDLER_TEMPLATE_MAP *TemplateMap, IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData ) { UINT16 CodeSegment; UINTN Index; UINTN InterruptHandler; RESERVED_VECTORS_DATA *ReservedVectors; ReservedVectors = ExceptionHandlerData->ReservedVectors; // // Use current CS as the segment selector of interrupt gate in IDT // CodeSegment = AsmReadCs (); for (Index = 0; Index < ExceptionHandlerData->IdtEntryCount; Index ++) { IdtTable[Index].Bits.Selector = CodeSegment; // // Check reserved vectors attributes // switch (ReservedVectors[Index].Attribute) { case EFI_VECTOR_HANDOFF_DO_NOT_HOOK: // // Keep original IDT entry // continue; case EFI_VECTOR_HANDOFF_HOOK_AFTER: InitializeSpinLock (&ReservedVectors[Index].SpinLock); CopyMem ( (VOID *) ReservedVectors[Index].HookAfterStubHeaderCode, (VOID *) TemplateMap->HookAfterStubHeaderStart, TemplateMap->ExceptionStubHeaderSize ); AsmVectorNumFixup ( (VOID *) ReservedVectors[Index].HookAfterStubHeaderCode, (UINT8) Index, (VOID *) TemplateMap->HookAfterStubHeaderStart ); // // Go on the following code // case EFI_VECTOR_HANDOFF_HOOK_BEFORE: // // Save original IDT handler address // ReservedVectors[Index].ExceptonHandler = ArchGetIdtHandler (&IdtTable[Index]); // // Go on the following code // default: // // Update new IDT entry // InterruptHandler = TemplateMap->ExceptionStart + Index * TemplateMap->ExceptionStubHeaderSize; ArchUpdateIdtEntry (&IdtTable[Index], InterruptHandler); break; } } }