4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CPU DXE Module.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync are licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync which accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync http://opensource.org/licenses/bsd-license.php
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "CpuDxe.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// Global Variables
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIA32_IDT_GATE_DESCRIPTOR gIdtTable[INTERRUPT_VECTOR_NUMBER] = { 0 };
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_CPU_INTERRUPT_HANDLER ExternalVectorTable[0x100];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOLEAN InterruptState = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_HANDLE mCpuHandle = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOLEAN mIsFlushingGCD;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT64 mValidMtrrAddressMask = MTRR_LIB_CACHE_VALID_ADDRESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT64 mValidMtrrBitsMask = MTRR_LIB_MSR_VALID_MASK;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIA32_IDT_GATE_DESCRIPTOR *mOrigIdtEntry = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT16 mOrigIdtEntryCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncFIXED_MTRR mFixedMtrrTable[] = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MTRR_LIB_IA32_MTRR_FIX64K_00000,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0x10000
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MTRR_LIB_IA32_MTRR_FIX16K_80000,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0x80000,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0x4000
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MTRR_LIB_IA32_MTRR_FIX16K_A0000,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0xA0000,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0x4000
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MTRR_LIB_IA32_MTRR_FIX4K_C0000,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0xC0000,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0x1000
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MTRR_LIB_IA32_MTRR_FIX4K_C8000,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0xC8000,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0x1000
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MTRR_LIB_IA32_MTRR_FIX4K_D0000,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0xD0000,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0x1000
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MTRR_LIB_IA32_MTRR_FIX4K_D8000,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0xD8000,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0x1000
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MTRR_LIB_IA32_MTRR_FIX4K_E0000,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0xE0000,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0x1000
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MTRR_LIB_IA32_MTRR_FIX4K_E8000,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0xE8000,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0x1000
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MTRR_LIB_IA32_MTRR_FIX4K_F0000,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0xF0000,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0x1000
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MTRR_LIB_IA32_MTRR_FIX4K_F8000,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0xF8000,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0x1000
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync },
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_CPU_ARCH_PROTOCOL gCpu = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CpuFlushCpuDataCache,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CpuEnableInterrupt,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CpuDisableInterrupt,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CpuGetInterruptState,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CpuInit,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CpuRegisterInterruptHandler,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CpuGetTimerValue,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CpuSetMemoryAttributes,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 1, // NumberOfTimers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 4 // DmaBufferAlignment
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// Error code flag indicating whether or not an error code will be
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// pushed on the stack if an exception occurs.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// 1 means an error code will be pushed, otherwise 0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// bit 0 - exception 0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// bit 1 - exception 1
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// etc.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT32 mErrorCodeFlag = 0x00027d00;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// Local function prototypes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Set Interrupt Descriptor Table Handler Address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Index The Index of the interrupt descriptor table handle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Handler Handler address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSetInterruptDescriptorTableHandlerAddress (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN Index,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Handler OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// CPU Arch Protocol Functions
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Common exception handler.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param InterruptType Exception type
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param SystemContext EFI_SYSTEM_CONTEXT
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCommonExceptionHandler (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_EXCEPTION_TYPE InterruptType,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SYSTEM_CONTEXT SystemContext
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#if defined (MDE_CPU_IA32)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "!!!! IA32 Exception Type - %08x !!!!\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InterruptType
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((mErrorCodeFlag & (1 << InterruptType)) != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ExceptionData - %08x\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->ExceptionData
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "CS - %04x, EIP - %08x, EFL - %08x, SS - %04x\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Cs,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Eip,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Eflags,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Ss
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "DS - %04x, ES - %04x, FS - %04x, GS - %04x\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Ds,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Es,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Fs,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Gs
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "EAX - %08x, EBX - %08x, ECX - %08x, EDX - %08x\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Eax,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Ebx,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Ecx,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Edx
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ESP - %08x, EBP - %08x, ESI - %08x, EDI - %08x\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Esp,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Ebp,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Esi,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Edi
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "GDT - %08x LIM - %04x, IDT - %08x LIM - %04x\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Gdtr[0],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Gdtr[1],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Idtr[0],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Idtr[1]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "LDT - %08x, TR - %08x\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Ldtr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Tr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "CR0 - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Cr0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Cr2,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Cr3,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Cr4
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "DR0 - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Dr0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Dr1,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Dr2,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Dr3
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "DR6 - %08x, DR7 - %08x\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Dr6,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextIa32->Dr7
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#elif defined (MDE_CPU_X64)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "!!!! X64 Exception Type - %016lx !!!!\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT64)InterruptType
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((mErrorCodeFlag & (1 << InterruptType)) != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "ExceptionData - %016lx\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->ExceptionData
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "RIP - %016lx, RFL - %016lx\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Rip,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Rflags
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "RAX - %016lx, RCX - %016lx, RDX - %016lx\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Rax,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Rcx,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Rdx
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "RBX - %016lx, RSP - %016lx, RBP - %016lx\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Rbx,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Rsp,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Rbp
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "RSI - %016lx, RDI - %016lx\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Rsi,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Rdi
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "R8 - %016lx, R9 - %016lx, R10 - %016lx\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->R8,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->R9,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->R10
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "R11 - %016lx, R12 - %016lx, R13 - %016lx\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->R11,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->R12,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->R13
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "R14 - %016lx, R15 - %016lx\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->R14,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->R15
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "CS - %04lx, DS - %04lx, ES - %04lx, FS - %04lx, GS - %04lx, SS - %04lx\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Cs,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Ds,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Es,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Fs,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Gs,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Ss
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "GDT - %016lx; %04lx, IDT - %016lx; %04lx\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Gdtr[0],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Gdtr[1],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Idtr[0],
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Idtr[1]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "LDT - %016lx, TR - %016lx\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Ldtr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Tr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "CR0 - %016lx, CR2 - %016lx, CR3 - %016lx\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Cr0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Cr2,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Cr3
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "CR4 - %016lx, CR8 - %016lx\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Cr4,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Cr8
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "DR0 - %016lx, DR1 - %016lx, DR2 - %016lx\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Dr0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Dr1,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Dr2
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_D_ERROR,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "DR3 - %016lx, DR6 - %016lx, DR7 - %016lx\n",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Dr3,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Dr6,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemContext.SystemContextX64->Dr7
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#error CPU type not supported for exception information dump!
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Hang the system with CpuSleep so the processor will enter a lower power
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // state.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (TRUE) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CpuSleep ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync };
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Flush CPU data cache. If the instruction cache is fully coherent
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync with all DMA operations then function can just return EFI_SUCCESS.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This Protocol instance structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Start Physical address to start flushing from.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Length Number of bytes to flush. Round up to chipset
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync granularity.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param FlushType Specifies the type of flush operation to perform.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS If cache was flushed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_UNSUPPORTED If flush type is not supported.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR If requested range could not be flushed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCpuFlushCpuDataCache (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_CPU_ARCH_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_PHYSICAL_ADDRESS Start,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT64 Length,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_CPU_FLUSH_TYPE FlushType
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (FlushType == EfiCpuFlushTypeWriteBackInvalidate) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsmWbinvd ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (FlushType == EfiCpuFlushTypeInvalidate) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsmInvd ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Enables CPU interrupts.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This Protocol instance structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS If interrupts were enabled in the CPU
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR If interrupts could not be enabled on the CPU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCpuEnableInterrupt (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_CPU_ARCH_PROTOCOL *This
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EnableInterrupts ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InterruptState = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Disables CPU interrupts.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This Protocol instance structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS If interrupts were disabled in the CPU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR If interrupts could not be disabled on the CPU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCpuDisableInterrupt (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_CPU_ARCH_PROTOCOL *This
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DisableInterrupts ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InterruptState = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Return the state of interrupts.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This Protocol instance structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param State Pointer to the CPU's current interrupt state
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS If interrupts were disabled in the CPU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER State is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCpuGetInterruptState (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_CPU_ARCH_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT BOOLEAN *State
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (State == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *State = InterruptState;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Generates an INIT to the CPU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This Protocol instance structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param InitType Type of CPU INIT to perform
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS If CPU INIT occurred. This value should never be
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync seen.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR If CPU INIT failed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_UNSUPPORTED Requested type of CPU INIT not supported.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCpuInit (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_CPU_ARCH_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_CPU_INIT_TYPE InitType
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Registers a function to be called from the CPU interrupt handler.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This Protocol instance structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param InterruptType Defines which interrupt to hook. IA-32
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync valid range is 0x00 through 0xFF
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param InterruptHandler A pointer to a function of type
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_CPU_INTERRUPT_HANDLER that is called
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync when a processor interrupt occurs. A null
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pointer is an error condition.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS If handler installed or uninstalled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for InterruptType was previously installed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InterruptType was not previously installed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_UNSUPPORTED The interrupt specified by InterruptType
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is not supported.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCpuRegisterInterruptHandler (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_CPU_ARCH_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_EXCEPTION_TYPE InterruptType,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (InterruptType < 0 || InterruptType > 0xff) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (InterruptHandler == NULL && ExternalVectorTable[InterruptType] == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (InterruptHandler != NULL && ExternalVectorTable[InterruptType] != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ALREADY_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (InterruptHandler != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetInterruptDescriptorTableHandlerAddress ((UINTN)InterruptType, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Restore the original IDT handler address if InterruptHandler is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RestoreInterruptDescriptorTableHandlerAddress ((UINTN)InterruptType);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExternalVectorTable[InterruptType] = InterruptHandler;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Returns a timer value from one of the CPU's internal timers. There is no
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync inherent time interval between ticks but is a function of the CPU frequency.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This - Protocol instance structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param TimerIndex - Specifies which CPU timer is requested.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param TimerValue - Pointer to the returned timer value.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param TimerPeriod - A pointer to the amount of time that passes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync in femtoseconds (10-15) for each increment
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync of TimerValue. If TimerValue does not
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync increment at a predictable rate, then 0 is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync returned. The amount of time that has
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync passed between two calls to GetTimerValue()
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync can be calculated with the formula
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (TimerValue2 - TimerValue1) * TimerPeriod.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This parameter is optional and may be NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS - If the CPU timer count was returned.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_UNSUPPORTED - If the CPU does not have any readable timers.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR - If an error occurred while reading the timer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER - TimerIndex is not valid or TimerValue is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCpuGetTimerValue (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_CPU_ARCH_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 TimerIndex,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT64 *TimerValue,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT64 *TimerPeriod OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TimerValue == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TimerIndex != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *TimerValue = AsmReadTsc ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TimerPeriod != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // BugBug: Hard coded. Don't know how to do this generically
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *TimerPeriod = 1000000000;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Implementation of SetMemoryAttributes() service of CPU Architecture Protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function modifies the attributes for the memory region specified by BaseAddress and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Length from their current attributes to the attributes specified by Attributes.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This The EFI_CPU_ARCH_PROTOCOL instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BaseAddress The physical address that is the start address of a memory region.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Length The size in bytes of the memory region.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Attributes The bit mask of attributes to set for the memory region.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The attributes were set for the memory region.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BaseAddress and Length cannot be modified.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER Length is zero.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Attributes specified an illegal combination of attributes that
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync cannot be set together.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the memory resource range.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync resource range specified by BaseAddress and Length.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The bit mask of attributes is not support for the memory resource
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync range specified by BaseAddress and Length.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCpuSetMemoryAttributes (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_CPU_ARCH_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_PHYSICAL_ADDRESS BaseAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT64 Length,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT64 Attributes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RETURN_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MTRR_MEMORY_CACHE_TYPE CacheType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!IsMtrrSupported ()) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If this function is called because GCD SetMemorySpaceAttributes () is called
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // by RefreshGcdMemoryAttributes (), then we are just synchronzing GCD memory
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // map with MTRR values. So there is no need to modify MTRRs, just return immediately
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // to avoid unnecessary computing.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (mIsFlushingGCD) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG((EFI_D_ERROR, " Flushing GCD\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (Attributes) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case EFI_MEMORY_UC:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CacheType = CacheUncacheable;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case EFI_MEMORY_WC:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CacheType = CacheWriteCombining;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case EFI_MEMORY_WT:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CacheType = CacheWriteThrough;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case EFI_MEMORY_WP:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CacheType = CacheWriteProtected;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case EFI_MEMORY_WB:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CacheType = CacheWriteBack;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case EFI_MEMORY_UCE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case EFI_MEMORY_RP:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case EFI_MEMORY_XP:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case EFI_MEMORY_RUNTIME:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // call MTRR libary function
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = MtrrSetMemoryAttribute (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BaseAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Length,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CacheType
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return (EFI_STATUS) Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Initializes the valid bits mask and valid address mask for MTRRs.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function initializes the valid bits mask and valid address mask for MTRRs.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncInitializeMtrrMask (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 RegEax;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 PhysicalAddressBits;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (RegEax >= 0x80000008) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PhysicalAddressBits = (UINT8) RegEax;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mValidMtrrBitsMask = LShiftU64 (1, PhysicalAddressBits) - 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mValidMtrrAddressMask = mValidMtrrBitsMask & 0xfffffffffffff000ULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mValidMtrrBitsMask = MTRR_LIB_MSR_VALID_MASK;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mValidMtrrAddressMask = MTRR_LIB_CACHE_VALID_ADDRESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Gets GCD Mem Space type from MTRR Type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function gets GCD Mem Space type from MTRR Type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param MtrrAttributes MTRR memory type
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return GCD Mem Space type
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncUINT64
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncGetMemorySpaceAttributeFromMtrrType (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 MtrrAttributes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (MtrrAttributes) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case MTRR_CACHE_UNCACHEABLE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_MEMORY_UC;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case MTRR_CACHE_WRITE_COMBINING:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_MEMORY_WC;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case MTRR_CACHE_WRITE_THROUGH:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_MEMORY_WT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case MTRR_CACHE_WRITE_PROTECTED:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_MEMORY_WP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case MTRR_CACHE_WRITE_BACK:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_MEMORY_WB;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Searches memory descriptors covered by given memory range.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function searches into the Gcd Memory Space for descriptors
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (from StartIndex to EndIndex) that contains the memory range
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync specified by BaseAddress and Length.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param MemorySpaceMap Gcd Memory Space Map as array.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param NumberOfDescriptors Number of descriptors in map.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BaseAddress BaseAddress for the requested range.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Length Length for the requested range.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param StartIndex Start index into the Gcd Memory Space Map.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param EndIndex End index into the Gcd Memory Space Map.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Search successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND The requested descriptors does not exist.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSearchGcdMemorySpaces (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN NumberOfDescriptors,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_PHYSICAL_ADDRESS BaseAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT64 Length,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINTN *StartIndex,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINTN *EndIndex
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *StartIndex = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *EndIndex = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < NumberOfDescriptors; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BaseAddress >= MemorySpaceMap[Index].BaseAddress &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BaseAddress < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *StartIndex = Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BaseAddress + Length - 1 >= MemorySpaceMap[Index].BaseAddress &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BaseAddress + Length - 1 < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *EndIndex = Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_NOT_FOUND;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Sets the attributes for a specified range in Gcd Memory Space Map.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function sets the attributes for a specified range in
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Gcd Memory Space Map.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param MemorySpaceMap Gcd Memory Space Map as array
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param NumberOfDescriptors Number of descriptors in map
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param BaseAddress BaseAddress for the range
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Length Length for the range
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Attributes Attributes to set
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Memory attributes set successfully
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND The specified range does not exist in Gcd Memory Space
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSetGcdMemorySpaceAttributes (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN NumberOfDescriptors,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_PHYSICAL_ADDRESS BaseAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT64 Length,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT64 Attributes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN StartIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN EndIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PHYSICAL_ADDRESS RegionStart;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 RegionLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get all memory descriptors covered by the memory range
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = SearchGcdMemorySpaces (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MemorySpaceMap,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NumberOfDescriptors,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BaseAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Length,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &StartIndex,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &EndIndex
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Go through all related descriptors and set attributes accordingly
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = StartIndex; Index <= EndIndex; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeNonExistent) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Calculate the start and end address of the overlapping range
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BaseAddress >= MemorySpaceMap[Index].BaseAddress) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RegionStart = BaseAddress;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RegionStart = MemorySpaceMap[Index].BaseAddress;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (BaseAddress + Length - 1 < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RegionLength = BaseAddress + Length - RegionStart;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RegionLength = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - RegionStart;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set memory attributes according to MTRR attribute and the original attribute of descriptor
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gDS->SetMemorySpaceAttributes (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RegionStart,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RegionLength,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (MemorySpaceMap[Index].Attributes & ~EFI_MEMORY_CACHETYPE_MASK) | (MemorySpaceMap[Index].Capabilities & Attributes)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Refreshes the GCD Memory Space attributes according to MTRRs.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function refreshes the GCD Memory Space attributes according to MTRRs.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRefreshGcdMemoryAttributes (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN SubIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 RegValue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PHYSICAL_ADDRESS BaseAddress;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 Length;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 Attributes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 CurrentAttributes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 MtrrType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN NumberOfDescriptors;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 DefaultAttributes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VARIABLE_MTRR VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MTRR_FIXED_SETTINGS MtrrFixedSettings;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 FirmwareVariableMtrrCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 DefaultMemoryType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!IsMtrrSupported ()) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCount ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (FirmwareVariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mIsFlushingGCD = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MemorySpaceMap = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize the valid bits mask and valid address mask for MTRRs
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitializeMtrrMask ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the memory attribute of variable MTRRs
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MtrrGetMemoryAttributeInVariableMtrr (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mValidMtrrBitsMask,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mValidMtrrAddressMask,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VariableMtrr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the memory space map from GCD
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gDS->GetMemorySpaceMap (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &NumberOfDescriptors,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &MemorySpaceMap
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT_EFI_ERROR (Status);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DefaultMemoryType = (UINT8) MtrrGetDefaultMemoryType ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DefaultAttributes = GetMemorySpaceAttributeFromMtrrType (DefaultMemoryType);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set default attributes to all spaces.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < NumberOfDescriptors; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeNonExistent) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gDS->SetMemorySpaceAttributes (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MemorySpaceMap[Index].BaseAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MemorySpaceMap[Index].Length,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (MemorySpaceMap[Index].Attributes & ~EFI_MEMORY_CACHETYPE_MASK) |
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (MemorySpaceMap[Index].Capabilities & DefaultAttributes)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Go for variable MTRRs with WB attribute
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (VariableMtrr[Index].Valid &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VariableMtrr[Index].Type == MTRR_CACHE_WRITE_BACK) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetGcdMemorySpaceAttributes (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MemorySpaceMap,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NumberOfDescriptors,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VariableMtrr[Index].BaseAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VariableMtrr[Index].Length,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_MEMORY_WB
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Go for variable MTRRs with the attribute except for WB and UC attributes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (VariableMtrr[Index].Valid &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VariableMtrr[Index].Type != MTRR_CACHE_WRITE_BACK &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VariableMtrr[Index].Type != MTRR_CACHE_UNCACHEABLE) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Attributes = GetMemorySpaceAttributeFromMtrrType ((UINT8) VariableMtrr[Index].Type);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetGcdMemorySpaceAttributes (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MemorySpaceMap,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NumberOfDescriptors,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VariableMtrr[Index].BaseAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VariableMtrr[Index].Length,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Attributes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Go for variable MTRRs with UC attribute
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (VariableMtrr[Index].Valid &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VariableMtrr[Index].Type == MTRR_CACHE_UNCACHEABLE) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetGcdMemorySpaceAttributes (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MemorySpaceMap,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NumberOfDescriptors,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VariableMtrr[Index].BaseAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VariableMtrr[Index].Length,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_MEMORY_UC
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Go for fixed MTRRs
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Attributes = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BaseAddress = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Length = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MtrrGetFixedMtrr (&MtrrFixedSettings);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RegValue = MtrrFixedSettings.Mtrr[Index];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check for continuous fixed MTRR sections
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (SubIndex = 0; SubIndex < 8; SubIndex++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MtrrType = (UINT8) RShiftU64 (RegValue, SubIndex * 8);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CurrentAttributes = GetMemorySpaceAttributeFromMtrrType (MtrrType);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Length == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // A new MTRR attribute begins
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Attributes = CurrentAttributes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If fixed MTRR attribute changed, then set memory attribute for previous atrribute
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CurrentAttributes != Attributes) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetGcdMemorySpaceAttributes (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MemorySpaceMap,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NumberOfDescriptors,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BaseAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Length,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Attributes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BaseAddress = mFixedMtrrTable[Index].BaseAddress + mFixedMtrrTable[Index].Length * SubIndex;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Length = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Attributes = CurrentAttributes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Length += mFixedMtrrTable[Index].Length;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Handle the last fixed MTRR region
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetGcdMemorySpaceAttributes (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MemorySpaceMap,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NumberOfDescriptors,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BaseAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Length,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Attributes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Free memory space map allocated by GCD service GetMemorySpaceMap ()
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (MemorySpaceMap != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (MemorySpaceMap);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mIsFlushingGCD = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Set Interrupt Descriptor Table Handler Address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Index The Index of the interrupt descriptor table handle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Handler Handler address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSetInterruptDescriptorTableHandlerAddress (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN Index,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Handler OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN UintnHandler;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Handler != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UintnHandler = (UINTN) Handler;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UintnHandler = ((UINTN) AsmIdtVector00) + (8 * Index);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gIdtTable[Index].Bits.OffsetLow = (UINT16)UintnHandler;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gIdtTable[Index].Bits.Reserved_0 = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gIdtTable[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gIdtTable[Index].Bits.OffsetHigh = (UINT16)(UintnHandler >> 16);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#if defined (MDE_CPU_X64)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gIdtTable[Index].Bits.OffsetUpper = (UINT32)(UintnHandler >> 32);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gIdtTable[Index].Bits.Reserved_1 = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Restore original Interrupt Descriptor Table Handler Address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Index The Index of the interrupt descriptor table handle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncRestoreInterruptDescriptorTableHandlerAddress (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN Index
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Index < mOrigIdtEntryCount) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gIdtTable[Index].Bits.OffsetLow = mOrigIdtEntry[Index].Bits.OffsetLow;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gIdtTable[Index].Bits.OffsetHigh = mOrigIdtEntry[Index].Bits.OffsetHigh;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#if defined (MDE_CPU_X64)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gIdtTable[Index].Bits.OffsetUpper = mOrigIdtEntry[Index].Bits.OffsetUpper;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Initialize Interrupt Descriptor Table for interrupt handling.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncInitInterruptDescriptorTable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IA32_DESCRIPTOR OldIdtPtr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IA32_IDT_GATE_DESCRIPTOR *OldIdt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN OldIdtSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VOID *IdtPtrAlignmentBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IA32_DESCRIPTOR *IdtPtr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 CurrentCs;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VOID *IntHandler;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetMem (ExternalVectorTable, sizeof(ExternalVectorTable), 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get original IDT address and size.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsmReadIdtr ((IA32_DESCRIPTOR *) &OldIdtPtr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((OldIdtPtr.Base != 0) && ((OldIdtPtr.Limit & 7) == 7)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OldIdt = (IA32_IDT_GATE_DESCRIPTOR*) OldIdtPtr.Base;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OldIdtSize = (OldIdtPtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Save original IDT entry and IDT entry count.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mOrigIdtEntry = AllocateCopyPool (OldIdtPtr.Limit + 1, (VOID *) OldIdtPtr.Base);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (mOrigIdtEntry != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mOrigIdtEntryCount = (UINT16) OldIdtSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OldIdt = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OldIdtSize = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Intialize IDT
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CurrentCs = AsmReadCs();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < INTERRUPT_VECTOR_NUMBER; Index ++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If the old IDT had a handler for this interrupt, then
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // preserve it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Index < OldIdtSize) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IntHandler =
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (VOID*) (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OldIdt[Index].Bits.OffsetLow +
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (OldIdt[Index].Bits.OffsetHigh << 16)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#if defined (MDE_CPU_X64)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync + (((UINTN) OldIdt[Index].Bits.OffsetUpper) << 32)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IntHandler = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gIdtTable[Index].Bits.Selector = CurrentCs;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gIdtTable[Index].Bits.Reserved_0 = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gIdtTable[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetInterruptDescriptorTableHandlerAddress (Index, IntHandler);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Load IDT Pointer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdtPtrAlignmentBuffer = AllocatePool (sizeof (*IdtPtr) + 16);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdtPtr = ALIGN_POINTER (IdtPtrAlignmentBuffer, 16);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdtPtr->Base = (UINT32)(((UINTN)(VOID*) gIdtTable) & (BASE_4GB-1));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdtPtr->Limit = (UINT16) (sizeof (gIdtTable) - 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsmWriteIdtr (IdtPtr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (IdtPtrAlignmentBuffer);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize Exception Handlers
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = OldIdtSize; Index < 32; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = CpuRegisterInterruptHandler (&gCpu, Index, CommonExceptionHandler);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT_EFI_ERROR (Status);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the pointer to the array of C based exception handling routines.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitializeExternalVectorTablePtr (ExternalVectorTable);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Callback function for idle events.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Event Event whose notification function is being invoked.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Context The pointer to the notification function's context,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync which is implementation-dependent.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIdleLoopEventCallback (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_EVENT Event,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CpuSleep ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Initialize the state information for the CPU Architectural Protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param ImageHandle Image handle this driver.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param SystemTable Pointer to the System Table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Thread can be successfully created
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR Cannot create the thread
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncInitializeCpu (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE ImageHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SYSTEM_TABLE *SystemTable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_EVENT IdleLoopEvent;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Make sure interrupts are disabled
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DisableInterrupts ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Init GDT for DXE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitGlobalDescriptorTable ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Setup IDT pointer, IDT and interrupt entry points
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitInterruptDescriptorTable ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Install CPU Architectural Protocol
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->InstallMultipleProtocolInterfaces (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &mCpuHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiCpuArchProtocolGuid, &gCpu,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT_EFI_ERROR (Status);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Refresh GCD memory space map according to MTRR value.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RefreshGcdMemoryAttributes ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Setup a callback for idle events
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->CreateEventEx (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EVT_NOTIFY_SIGNAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TPL_NOTIFY,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IdleLoopEventCallback,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gIdleLoopEventGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IdleLoopEvent
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT_EFI_ERROR (Status);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync