33#include <IndustryStandard/Xen/arch-x86/hvm/start_info.h>
35#include <IndustryStandard/Xen/memory.h>
50STATIC UINT32 mE820EntriesCount;
75 if (mXenHvmloaderInfo !=
NULL) {
78 *Count = mXenHvmloaderInfo->E820EntriesCount;
87 if (mE820EntriesCount > 0) {
88 *Entries = mE820Entries;
89 *Count = mE820EntriesCount;
93 Parameters.nr_entries = 128;
94 set_xen_guest_handle (Parameters.buffer, mE820Entries);
98 ASSERT (ReturnCode == 0);
100 mE820EntriesCount = Parameters.nr_entries;
105 for (LoopIndex = 1; LoopIndex < mE820EntriesCount; LoopIndex++) {
106 for (Index = LoopIndex; Index < mE820EntriesCount; Index++) {
107 if (mE820Entries[Index - 1].BaseAddr > mE820Entries[Index].BaseAddr) {
108 TmpEntry = mE820Entries[Index];
109 mE820Entries[Index] = mE820Entries[Index - 1];
110 mE820Entries[Index - 1] = TmpEntry;
115 *Count = mE820EntriesCount;
116 *Entries = mE820Entries;
133 CHAR8 Sig[
sizeof (Info->Signature) + 1];
134 UINT32 *PVHResetVectorData;
135 RETURN_STATUS Status;
137 ASSERT (mXenLeaf != 0);
146 "Detected Xen version %d.%d\n",
164 (CHAR8 *)&Info->Signature,
165 sizeof (Info->Signature)
168 mXenHvmloaderInfo = Info;
170 mXenHvmloaderInfo =
NULL;
180 PVHResetVectorData = (VOID *)(
UINTN)
PcdGet32 (PcdXenPvhStartOfDayStructPtr);
184 if (PVHResetVectorData[1] ==
SIGNATURE_32 (
'X',
'P',
'V',
'H')) {
187 HVMStartInfo = (VOID *)(
UINTN)PVHResetVectorData[0];
188 if (HVMStartInfo->magic == XEN_HVM_START_MAGIC_VALUE) {
189 ASSERT (HVMStartInfo->rsdp_paddr != 0);
190 if (HVMStartInfo->rsdp_paddr != 0) {
191 mXenInfo.
RsdpPvh = (VOID *)(
UINTN)HVMStartInfo->rsdp_paddr;
230 Signature[12] =
'\0';
231 for (mXenLeaf = 0x40000000; mXenLeaf < 0x40010000; mXenLeaf += 0x100) {
235 (UINT32 *)&Signature[0],
236 (UINT32 *)&Signature[4],
237 (UINT32 *)&Signature[8]
240 if (!
AsciiStrCmp ((CHAR8 *)Signature,
"XenVMMXenVMM")) {
250XenHvmloaderDetected (
254 return (mXenHvmloaderInfo !=
NULL);
267 return mXenHvmloaderInfo ==
NULL;
271XenPublishRamRegions (
276 UINT32 E820EntriesCount;
283 DEBUG ((DEBUG_INFO,
"Using memory map provided by Xen\n"));
288 E820EntriesCount = 0;
292 AddMemoryBaseSizeHob (0, 0xA0000);
296 AddReservedMemoryBaseSizeHob (0xA0000, BASE_1MB - 0xA0000,
TRUE);
298 LapicBase =
PcdGet32 (PcdCpuLocalApicBaseAddress);
299 LapicEnd = LapicBase + SIZE_1MB;
300 AddIoMemoryRangeHob (LapicBase, LapicEnd);
302 for (Index = 0; Index < E820EntriesCount; Index++) {
308 Entry = &E820Map[Index];
313 Base =
ALIGN_VALUE (Entry->BaseAddr, (UINT64)EFI_PAGE_SIZE);
314 End = (Entry->BaseAddr + Entry->Length) & ~(UINT64)EFI_PAGE_MASK;
319 if (Base < BASE_1MB) {
327 switch (Entry->Type) {
328 case EfiAcpiAddressRangeMemory:
331 case EfiAcpiAddressRangeACPI:
332 AddReservedMemoryRangeHob (Base, End,
FALSE);
334 case EfiAcpiAddressRangeReserved:
345 ReservedEnd =
MIN (End, LapicBase);
346 if (ReservedBase < ReservedEnd) {
347 AddReservedMemoryRangeHob (ReservedBase, ReservedEnd,
FALSE);
353 ReservedBase =
MAX (Base, LapicEnd);
355 if (ReservedBase < ReservedEnd) {
356 AddReservedMemoryRangeHob (ReservedBase, ReservedEnd,
FALSE);
367PhysicalAddressIdentityMapping (
375 DEBUG ((DEBUG_INFO,
"Mapping 1:1 of address 0x%lx\n", (UINT64)AddressToMap));
380 Index = PML4_OFFSET (AddressToMap);
382 if (!L4[Index].Bits.Present) {
385 return EFI_OUT_OF_RESOURCES;
390 L4[Index].Bits.ReadWrite = 1;
391 L4[Index].Bits.Accessed = 1;
393 L4[Index].Bits.Present = 1;
399 Index = PDP_OFFSET (AddressToMap);
401 if (!L3[Index].Bits.Present) {
403 if (PageTable ==
NULL) {
404 return EFI_OUT_OF_RESOURCES;
407 ZeroMem (PageTable, EFI_PAGE_SIZE);
409 L3[Index].Bits.ReadWrite = 1;
410 L3[Index].Bits.Accessed = 1;
412 L3[Index].Bits.Present = 1;
418 Index = PDE_OFFSET (AddressToMap);
420 if (!PageTable[Index].Bits.Present) {
421 PageTable[Index].Bits.ReadWrite = 1;
422 PageTable[Index].Bits.Accessed = 1;
423 PageTable[Index].Bits.Dirty = 1;
424 PageTable[Index].Bits.MustBe1 = 1;
425 PageTable[Index].Bits.PageTableBaseAddress = AddressToMap >> 21;
426 PageTable[Index].Bits.Present = 1;
443 Parameters.domid = DOMID_SELF;
444 Parameters.space = XENMAPSPACE_shared_info;
446 Parameters.gpfn = (
UINTN)PagePtr >> EFI_PAGE_SHIFT;
448 if (ReturnCode != 0) {
449 return EFI_NO_MAPPING;
464 Parameters.domid = DOMID_SELF;
465 Parameters.gpfn = (
UINTN)PagePtr >> EFI_PAGE_SHIFT;
467 ASSERT (ReturnCode == 0);
477 UINT32 TscToSystemMultiplier;
482 Version = VcpuTime->Version;
484 TscToSystemMultiplier = VcpuTime->TscToSystemMultiplier;
485 TscShift = VcpuTime->TscShift;
487 }
while (((Version & 1) != 0) && (Version != VcpuTime->Version));
493 CpuFreq =
LShiftU64 (CpuFreq, -TscShift);
511 RETURN_STATUS Status;
515 CpuFreq = GetCpuFreq (VcpuTimeInfo);
517 if (EFI_ERROR (Status)) {
520 "XenDelay (%lu ns): delay too big in relation to CPU freq %lu Hz\n",
528 DelayTick =
DivU64x32 (Delay, 1000000000);
530 NewTick = Tick + DelayTick;
535 if (NewTick < Tick) {
559 UINT32 TimerTick, TimerTick2, DiffTimer;
560 UINT64 TscTick, TscTick2;
565 SharedInfo = (VOID *)((
UINTN)
PcdGet32 (PcdCpuLocalApicBaseAddress) + SIZE_1MB);
567 if (EFI_ERROR (Status)) {
570 "Failed to add page table entry for Xen shared info page: %r\n",
577 Status = MapSharedInfoPage (SharedInfo);
578 if (EFI_ERROR (Status)) {
581 "Failed to map Xen's shared info page: %r\n",
588 VcpuTimeInfo = &SharedInfo->VcpuInfo[0].Time;
595 XenDelay (VcpuTimeInfo, 1000000ULL);
599 DiffTimer = TimerTick - TimerTick2;
600 Status =
SafeUint64Mult (GetCpuFreq (VcpuTimeInfo), DiffTimer, &Dividend);
601 if (EFI_ERROR (Status)) {
602 DEBUG ((DEBUG_ERROR,
"overflow while calculating APIC frequency\n"));
605 "CPU freq: %lu Hz; APIC timer tick count for 1 ms: %u\n",
606 GetCpuFreq (VcpuTimeInfo),
614 DEBUG ((DEBUG_INFO,
"APIC Freq % 8lu Hz\n", Freq));
616 ASSERT (Freq <= MAX_UINT32);
617 Status =
PcdSet32S (PcdFSBClock, (UINT32)Freq);
620 UnmapXenPage (SharedInfo);
VOID *EFIAPI BuildGuidDataHob(IN CONST EFI_GUID *Guid, IN VOID *Data, IN UINTN DataLength)
UINT64 EFIAPI AsmReadTsc(VOID)
RETURN_STATUS EFIAPI AsciiStrnCpyS(OUT CHAR8 *Destination, IN UINTN DestMax, IN CONST CHAR8 *Source, IN UINTN Length)
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
INTN EFIAPI AsciiStrCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString)
VOID EFIAPI CpuDeadLoop(VOID)
VOID EFIAPI MemoryFence(VOID)
VOID EFIAPI CpuPause(VOID)
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
UINT64 EFIAPI DivU64x64Remainder(IN UINT64 Dividend, IN UINT64 Divisor, OUT UINT64 *Remainder OPTIONAL)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID EFIAPI CpuFlushTlb(VOID)
VOID EFIAPI InitializeApicTimer(IN UINTN DivideValue, IN UINT32 InitCount, IN BOOLEAN PeriodicMode, IN UINT8 Vector)
UINT32 EFIAPI GetApicTimerCurrentCount(VOID)
VOID EFIAPI DisableApicTimerInterrupt(VOID)
#define ALIGN_VALUE(Value, Alignment)
#define SIGNATURE_32(A, B, C, D)
#define ASSERT_EFI_ERROR(StatusParameter)
#define ASSERT_RETURN_ERROR(StatusParameter)
#define DEBUG(Expression)
UINT32 EFIAPI AsmCpuid(IN UINT32 Index, OUT UINT32 *RegisterEax OPTIONAL, OUT UINT32 *RegisterEbx OPTIONAL, OUT UINT32 *RegisterEcx OPTIONAL, OUT UINT32 *RegisterEdx OPTIONAL)
#define PcdGet32(TokenName)
#define PcdSet32S(TokenName, Value)
VOID *EFIAPI AllocatePages(IN UINTN Pages)
RETURN_STATUS EFIAPI SafeUint64Mult(IN UINT64 Multiplicand, IN UINT64 Multiplier, OUT UINT64 *Result)
UINT64 EFI_PHYSICAL_ADDRESS
INTN EFIAPI XenHypercallMemoryOp(IN UINTN Operation, IN OUT VOID *Arguments)
RETURN_STATUS EFIAPI XenHypercallLibInit(VOID)