Author: ion
Date: Sun Sep 6 20:55:50 2015
New Revision: 69071
URL:
http://svn.reactos.org/svn/reactos?rev=69071&view=rev
Log:
[BOOTMGFW]
- Fix some heap bugs. It (works?) now, at least for one allocation.
- Fix GCC support for Phase 1 Architectural Initialization.
- Implement Time measurement for Hyper-V compatible hypervisors (tested with Virtual Box
5.0!) as well as non-hypervisors (also tested)
Added:
trunk/reactos/boot/environ/lib/platform/time.c (with props)
Modified:
trunk/reactos/boot/environ/CMakeLists.txt
trunk/reactos/boot/environ/include/bl.h
trunk/reactos/boot/environ/lib/arch/i386/arch.c
trunk/reactos/boot/environ/lib/bootlib.c
trunk/reactos/boot/environ/lib/firmware/efi/firmware.c
trunk/reactos/boot/environ/lib/mm/heapalloc.c
Modified: trunk/reactos/boot/environ/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/CMakeLists.tx…
==============================================================================
--- trunk/reactos/boot/environ/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/CMakeLists.txt [iso-8859-1] Sun Sep 6 20:55:50 2015
@@ -17,7 +17,8 @@
lib/mm/pagealloc.c
lib/mm/heapalloc.c
lib/mm/blkalloc.c
- lib/mm/descriptor.c)
+ lib/mm/descriptor.c
+ lib/platform/time.c)
if(ARCH STREQUAL "i386")
list(APPEND BOOTLIB_ASM_SOURCE
Modified: trunk/reactos/boot/environ/include/bl.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/include/bl.h?…
==============================================================================
--- trunk/reactos/boot/environ/include/bl.h [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/include/bl.h [iso-8859-1] Sun Sep 6 20:55:50 2015
@@ -522,6 +522,18 @@
_Inout_ EFI_PHYSICAL_ADDRESS* Memory
);
+NTSTATUS
+EfiStall (
+ _In_ ULONG StallTime
+ );
+
+/* PLATFORM TIMER ROUTINES ***************************************************/
+
+NTSTATUS
+BlpTimeCalibratePerformanceCounter (
+ VOID
+ );
+
/* UTILITY ROUTINES **********************************************************/
EFI_STATUS
Modified: trunk/reactos/boot/environ/lib/arch/i386/arch.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/arch/i386…
==============================================================================
--- trunk/reactos/boot/environ/lib/arch/i386/arch.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/arch/i386/arch.c [iso-8859-1] Sun Sep 6 20:55:50 2015
@@ -19,13 +19,20 @@
/* FUNCTIONS *****************************************************************/
VOID
-//__declspec(naked) fixme: gcc
+DECLSPEC_NORETURN
ArchTrapNoProcess (
VOID
)
{
/* Do nothing, this is an unsupported debugging interrupt */
- // _asm { iret } FIXME: GCC
+#if defined(__GNUC__)
+ __asm__ __volatile__ ("iret");
+#elif defined (_MSC_VER)
+ _asm { iret };
+#else
+#error wtf are you using
+#endif
+ __assume(0);
}
VOID
@@ -208,8 +215,13 @@
IdtBase = (PKIDTENTRY)Idtr.Base;
/* Get the Code Segment */
- // _asm { mov CodeSegment, cs } FIXME: GCC
- CodeSegment = 8; // fix fix
+#if defined(__GNUC__)
+ __asm__ __volatile__ ("mov %%cs,%0\n\t" :"=r"
(CodeSegment));
+#elif defined (_MSC_VER)
+ _asm { mov CodeSegment, cs };
+#else
+#error wtf are you using
+#endif
/* Set up INT 3, ASSERT, and SECURITY_ASSERT to be no-op (for Rtl) */
IdtBase[3].Offset = (USHORT)(ULONG_PTR)ArchTrapNoProcess;
@@ -230,7 +242,13 @@
__lidt(&Idtr);
/* Reset FPU state */
- // __asm { fninit } FIXME: GCC
+#if defined(__GNUC__)
+ __asm__ __volatile__ ("fninit");
+#elif defined (_MSC_VER)
+ _asm { fninit };
+#else
+#error wtf are you using
+#endif
}
else
{
Modified: trunk/reactos/boot/environ/lib/bootlib.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/bootlib.c…
==============================================================================
--- trunk/reactos/boot/environ/lib/bootlib.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/bootlib.c [iso-8859-1] Sun Sep 6 20:55:50 2015
@@ -132,6 +132,50 @@
goto Quickie;
}
+ /* Initialize firmware now that the heap, etc works */
+ Status = BlpFwInitialize(1, FirmwareDescriptor);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Destroy memory manager in phase 1 */
+ //BlpMmDestroy(1);
+ EarlyPrint(L"Firmware2 init failed!\n");
+ return Status;
+ }
+
+#if 0
+ /* Modern systems have an undocumented BCD system for the boot frequency */
+ Status = BlGetBootOptionInteger(BlpApplicationEntry.BcdData,
+ 0x15000075,
+ &BootFrequency);
+ if (NT_SUCCESS(Status) && (BootFrequency))
+ {
+ /* Use it if present */
+ BlpTimePerformanceFrequency = BootFrequency;
+ }
+ else
+#endif
+ {
+ /* Use the TSC for calibration */
+ Status = BlpTimeCalibratePerformanceCounter();
+ if (!NT_SUCCESS(Status))
+ {
+ /* Destroy memory manager in phase 1 */
+ EarlyPrint(L"TSC calibration failed\n");
+ //BlpMmDestroy(1);
+ return Status;
+ }
+ }
+
+ /* Now setup the rest of the architecture (IDT, etc) */
+ Status = BlpArchInitialize(1);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Destroy memory manager in phase 1 */
+ EarlyPrint(L"Arch2 init failed\n");
+ //BlpMmDestroy(1);
+ return Status;
+ }
+
EarlyPrint(L"TODO!\n");
Status = STATUS_NOT_IMPLEMENTED;
Modified: trunk/reactos/boot/environ/lib/firmware/efi/firmware.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/firmware/…
==============================================================================
--- trunk/reactos/boot/environ/lib/firmware/efi/firmware.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/firmware/efi/firmware.c [iso-8859-1] Sun Sep 6
20:55:50 2015
@@ -207,6 +207,35 @@
/* Make the EFI call */
EfiStatus = EfiBS->FreePages(PhysicalAddress, Pages);
+
+ /* Switch back to protected mode if we came from there */
+ if (OldMode != BlRealMode)
+ {
+ BlpArchSwitchContext(OldMode);
+ }
+
+ /* Convert the error to an NTSTATUS */
+ return EfiGetNtStatusCode(EfiStatus);
+}
+
+NTSTATUS
+EfiStall (
+ _In_ ULONG StallTime
+ )
+{
+ BL_ARCH_MODE OldMode;
+ EFI_STATUS EfiStatus;
+
+ /* Are we in protected mode? */
+ OldMode = CurrentExecutionContext->Mode;
+ if (OldMode != BlRealMode)
+ {
+ /* FIXME: Not yet implemented */
+ return STATUS_NOT_IMPLEMENTED;
+ }
+
+ /* Make the EFI call */
+ EfiStatus = EfiBS->Stall(StallTime);
/* Switch back to protected mode if we came from there */
if (OldMode != BlRealMode)
@@ -749,7 +778,7 @@
{
/* Set the initial key toggle state */
KeyToggleState = EFI_TOGGLE_STATE_VALID | 40;
- EfiConInExSetState(EfiST->ConsoleInHandle, &KeyToggleState);
+ EfiConInExSetState(EfiConInEx, &KeyToggleState);
}
/* Setup the watchdog timer */
Modified: trunk/reactos/boot/environ/lib/mm/heapalloc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/mm/heapal…
==============================================================================
--- trunk/reactos/boot/environ/lib/mm/heapalloc.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/mm/heapalloc.c [iso-8859-1] Sun Sep 6 20:55:50 2015
@@ -47,10 +47,10 @@
typedef struct _BL_HEAP_BOUNDARIES
{
LIST_ENTRY ListEntry;
- ULONG_PTR HeapHigh;
+ ULONG_PTR HeapEnd;
ULONG_PTR HeapLimit;
- ULONG_PTR HeapBottom;
- PBL_BUSY_HEAP_ENTRY HeapTop;
+ ULONG_PTR HeapBase;
+ PBL_BUSY_HEAP_ENTRY HeapStart;
} BL_HEAP_BOUNDARIES, *PBL_HEAP_BOUNDARIES;
ULONG HapInitializationStatus;
@@ -125,7 +125,7 @@
/* Check if we have a page free above the heap */
HeapLimit = Heap->HeapLimit + PAGE_SIZE;
- if (HeapLimit <= Heap->HeapHigh)
+ if (HeapLimit <= Heap->HeapEnd)
{
EarlyPrint(L"Heap extension TODO\n");
return STATUS_INSUFFICIENT_RESOURCES;
@@ -147,32 +147,32 @@
/* Set the heap bottom, limit, and top */
NewHeap = (PBL_HEAP_BOUNDARIES)HeapBase->Buffer;
- NewHeap->HeapBottom = (ULONG_PTR)HeapBase;
+ NewHeap->HeapBase = (ULONG_PTR)HeapBase;
NewHeap->HeapLimit = (ULONG_PTR)HeapBase + AlignedSize;
- NewHeap->HeapTop = (PBL_BUSY_HEAP_ENTRY)(NewHeap + 1);
+ NewHeap->HeapStart = (PBL_BUSY_HEAP_ENTRY)(NewHeap + 1);
/* Set the buffer links */
HeapBase->BufferPrevious.P = NULL;
- HeapBase->BufferNext.P = NewHeap->HeapTop;
+ HeapBase->BufferNext.P = NewHeap->HeapStart;
/* Set the buffer at the top of the heap and mark it as being free */
- NewHeap->HeapTop->BufferPrevious.P = HeapBase;
- NewHeap->HeapTop->BufferNext.P = NewHeap->HeapTop;
- NewHeap->HeapTop->BufferNext.BufferFree = 1;
- NewHeap->HeapTop->BufferNext.BufferOnHeap = 1;
+ NewHeap->HeapStart->BufferPrevious.P = HeapBase;
+ NewHeap->HeapStart->BufferNext.P = NewHeap->HeapStart;
+ NewHeap->HeapStart->BufferNext.BufferFree = 1;
+ NewHeap->HeapStart->BufferNext.BufferOnHeap = 1;
/* Is this the first heap ever? */
if (IsListEmpty(&MmHeapBoundaries))
{
/* We will host the free list at the top of the heap */
- MmFreeList = (PBL_FREE_HEAP_ENTRY*)((ULONG_PTR)NewHeap->HeapLimit -
sizeof(BL_HEAP_BOUNDARIES));
+ MmFreeList = (PBL_FREE_HEAP_ENTRY*)((ULONG_PTR)NewHeap->HeapLimit - 8 *
sizeof(PBL_FREE_HEAP_ENTRY));
NewHeap->HeapLimit = (ULONG_PTR)MmFreeList;
RtlZeroMemory(MmFreeList, 8 * sizeof(PBL_FREE_HEAP_ENTRY));
}
/* Remove a page on top */
HeapLimit = NewHeap->HeapLimit;
- NewHeap->HeapHigh = NewHeap->HeapLimit;
+ NewHeap->HeapEnd = NewHeap->HeapLimit;
NewHeap->HeapLimit -= PAGE_SIZE;
/* Add us into the heap list */
@@ -595,29 +595,24 @@
ListEntry);
/* Check if we have space in the heap page for this allocation? */
- FreeEntry = Heap->HeapTop;
+ FreeEntry = Heap->HeapStart;
NextEntry = (PBL_BUSY_HEAP_ENTRY)((ULONG_PTR)FreeEntry + BufferSize);
-
- EarlyPrint(L"Free Entry: %p Size: %lx Next: %p\n", FreeEntry,
BufferSize, NextEntry);
-
- EarlyPrint(L"Heap Limit: %p\n", Heap->HeapLimit);
- EarlyPrint(L"Minus one busy entry: %p\n", Heap->HeapLimit -
sizeof(BL_BUSY_HEAP_ENTRY));
if ((NextEntry >= FreeEntry) &&
((ULONG_PTR)NextEntry <= Heap->HeapLimit -
sizeof(BL_BUSY_HEAP_ENTRY)))
{
/* Update the heap top pointer past this allocation */
- Heap->HeapTop = NextEntry;
+ Heap->HeapStart = NextEntry;
/* Make this allocation point to the slot */
- FreeEntry->BufferNext.P = Heap->HeapTop;
+ FreeEntry->BufferNext.P = Heap->HeapStart;
/* And make the free heap entry point back to us */
- Heap->HeapTop->BufferNext.P = FreeEntry;
+ Heap->HeapStart->BufferNext.P = FreeEntry;
/* Mark the heap entry as being free and on the heap */
- Heap->HeapTop->BufferNext.BufferFree = 1;
- Heap->HeapTop->BufferNext.BufferOnHeap = 1;
+ Heap->HeapStart->BufferNext.BufferFree = 1;
+ Heap->HeapStart->BufferNext.BufferOnHeap = 1;
/* The previously freed entry on the heap page is now ours */
BusyEntry = FreeEntry;
@@ -639,6 +634,7 @@
BusyEntry->BufferNext.P = MmHapDecodeLink(BusyEntry->BufferNext);
/* Return the entry's data buffer */
+ EarlyPrint(L"Returning buffer at 0x%p\n", &BusyEntry->Buffer);
return &BusyEntry->Buffer;
}
@@ -668,8 +664,8 @@
Heap = CONTAINING_RECORD(NextEntry, BL_HEAP_BOUNDARIES, ListEntry);
/* Is this entry part of this heap? */
- if (((ULONG_PTR)Heap->HeapBottom <= (ULONG_PTR)BusyEntry) &&
- ((ULONG_PTR)BusyEntry < (ULONG_PTR)Heap->HeapTop))
+ if (((ULONG_PTR)Heap->HeapBase <= (ULONG_PTR)BusyEntry) &&
+ ((ULONG_PTR)BusyEntry < (ULONG_PTR)Heap->HeapStart))
{
/* Ignore double-free */
if (BusyEntry->BufferNext.BufferFree)
Added: trunk/reactos/boot/environ/lib/platform/time.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/platform/…
==============================================================================
--- trunk/reactos/boot/environ/lib/platform/time.c (added)
+++ trunk/reactos/boot/environ/lib/platform/time.c [iso-8859-1] Sun Sep 6 20:55:50 2015
@@ -0,0 +1,88 @@
+/*
+ * COPYRIGHT: See COPYING.ARM in the top level directory
+ * PROJECT: ReactOS UEFI Boot Library
+ * FILE: boot/environ/lib/platform/time.c
+ * PURPOSE: Boot Library Time Management Routines
+ * PROGRAMMER: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include "bl.h"
+
+/* DATA VARIABLES ************************************************************/
+
+ULONGLONG BlpTimePerformanceFrequency;
+
+NTSTATUS
+BlpTimeMeasureTscFrequency (
+ VOID
+ )
+{
+ ULONG Count;
+ INT CpuInfo[4];
+ ULONGLONG TimeStamp1, TimeStamp2, Delta;
+
+ /* Check if the ISVM bit it set, meaning we're in a hypervisor */
+ __cpuid(CpuInfo, 1);
+ Count = CpuInfo[2] & 0x80000000 ? 10 : 1;
+
+ /* Loop trying to get an accurate TSC */
+ do
+ {
+ /* Stall for 1us and get count 1 */
+ EfiStall(1);
+ TimeStamp1 = __rdtsc();
+
+ /* Stall for 1000us and get count 2*/
+ EfiStall(1000);
+ TimeStamp2 = __rdtsc();
+
+ /* Stall for 9000us and get the difference */
+ EfiStall(9000);
+ Delta = __rdtsc() - TimeStamp2;
+
+ /* Keep going as long as the TSC is fluctuating */
+ --Count;
+ } while (((TimeStamp2 - TimeStamp1) > Delta) && (Count));
+
+ /* Set the frequency based on the two measurements we took */
+ BlpTimePerformanceFrequency = 125 * (Delta - (TimeStamp2 - TimeStamp1)) &
0x1FFFFFFFFFFFFFF;
+ EarlyPrint(L"Computed frequency as: %I64d\n",
BlpTimePerformanceFrequency);
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+BlpTimeCalibratePerformanceCounter (
+ VOID
+ )
+{
+ INT CpuInfo[4];
+
+ /* Check if the ISVM bit it set, meaning we're in a hypervisor */
+ __cpuid(CpuInfo, 1);
+ if (CpuInfo[2] & 0x80000000)
+ {
+ /* Get the Hypervisor Identification Leaf */
+ __cpuid(CpuInfo, 0x40000001);
+
+ /* Is this Hyper-V? */
+ if (CpuInfo[0] == '1#vH')
+ {
+ /* Get the Hypervisor Feature Identification Leaf */
+ __cpuid(CpuInfo, 0x40000003);
+
+ /* Check if HV_X64_MSR_REFERENCE_TSC is present */
+ if (CpuInfo[3] & 0x100)
+ {
+ /* Read the TSC frequency from the MSR */
+ BlpTimePerformanceFrequency = __readmsr(0x40000022);
+ EarlyPrint(L"Using frequency as: %I64d\n",
BlpTimePerformanceFrequency);
+ return STATUS_SUCCESS;
+ }
+ }
+ }
+
+ /* On other systems, compute it */
+ return BlpTimeMeasureTscFrequency();
+}
Propchange: trunk/reactos/boot/environ/lib/platform/time.c
------------------------------------------------------------------------------
svn:eol-style = native