Beispiel #1
0
/**
  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;
}
Beispiel #2
0
/**
  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);
  }
}
Beispiel #3
0
/**
  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);
}
Beispiel #4
0
/**

  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 ;
}
Beispiel #5
0
/**
  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;
    }
  }
}