Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ionescu007/SimpleVisor.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorionescu007 <aionescu+git@gmail.com>2016-09-03 19:12:39 +0300
committerionescu007 <aionescu+git@gmail.com>2016-09-03 19:12:39 +0300
commit98af3a870a27d66e820379056ea09153ef823332 (patch)
tree8cf0d7897585cbc257bf265907bb80852e4c4be3
parentf5dd1af02f22e2caf564dea4705bce2d42167061 (diff)
Officially add support for UEFI: Uefisor!
Documentation to follow.
-rw-r--r--nt/shvos.c (renamed from shvos.c)0
-rw-r--r--nt/shvosx64.asm (renamed from shvosx64.asm)0
-rw-r--r--shv.vcxproj10
-rw-r--r--shv.vcxproj.filters38
-rw-r--r--uefi/shvos.c391
-rw-r--r--uefi/shvosx64.asm99
6 files changed, 536 insertions, 2 deletions
diff --git a/shvos.c b/nt/shvos.c
index 5e44bd6..5e44bd6 100644
--- a/shvos.c
+++ b/nt/shvos.c
diff --git a/shvosx64.asm b/nt/shvosx64.asm
index 1e75175..1e75175 100644
--- a/shvosx64.asm
+++ b/nt/shvosx64.asm
diff --git a/shv.vcxproj b/shv.vcxproj
index fd0e09c..83c4c65 100644
--- a/shv.vcxproj
+++ b/shv.vcxproj
@@ -55,12 +55,15 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
- <ClCompile Include="shvos.c" />
<ClCompile Include="shv.c" />
<ClCompile Include="shvutil.c" />
<ClCompile Include="shvvmx.c" />
<ClCompile Include="shvvmxhv.c" />
<ClCompile Include="shvvp.c" />
+ <ClCompile Include="nt\shvos.c" />
+ <ClCompile Include="uefi\shvos.c">
+ <ExcludedFromBuild>true</ExcludedFromBuild>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="shv.h" />
@@ -70,7 +73,10 @@
</ItemGroup>
<ItemGroup>
<MASM Include="shvvmxhvx64.asm" />
- <MASM Include="shvosx64.asm" />
+ <MASM Include="nt\shvosx64.asm" />
+ <MASM Include="uefi\shvosx64.asm">
+ <ExcludedFromBuild>true</ExcludedFromBuild>
+ </MASM>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
diff --git a/shv.vcxproj.filters b/shv.vcxproj.filters
new file mode 100644
index 0000000..6e2914c
--- /dev/null
+++ b/shv.vcxproj.filters
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="shv.c" />
+ <ClCompile Include="shvutil.c" />
+ <ClCompile Include="shvvmx.c" />
+ <ClCompile Include="shvvmxhv.c" />
+ <ClCompile Include="shvvp.c" />
+ <ClCompile Include="nt\shvos.c">
+ <Filter>NT</Filter>
+ </ClCompile>
+ <ClCompile Include="uefi\shvos.c">
+ <Filter>UEFI</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="shv.h" />
+ <ClInclude Include="ntint.h" />
+ <ClInclude Include="shv_x.h" />
+ <ClInclude Include="vmx.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="NT">
+ <UniqueIdentifier>{dbe9fd1c-cc57-4f03-a093-03b3312ec3ac}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="UEFI">
+ <UniqueIdentifier>{1bdf620e-c034-447a-bf4f-c9e7004a2328}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <MASM Include="nt\shvosx64.asm">
+ <Filter>NT</Filter>
+ </MASM>
+ <MASM Include="uefi\shvosx64.asm">
+ <Filter>UEFI</Filter>
+ </MASM>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/uefi/shvos.c b/uefi/shvos.c
new file mode 100644
index 0000000..db19f21
--- /dev/null
+++ b/uefi/shvos.c
@@ -0,0 +1,391 @@
+/*++
+
+Copyright (c) Alex Ionescu. All rights reserved.
+
+Module Name:
+
+ shvos.c
+
+Abstract:
+
+ This module implements the OS-facing UEFI stubs for SimpleVisor.
+
+Author:
+
+ Alex Ionescu (@aionescu) 29-Aug-2016 - Initial version
+
+Environment:
+
+ Kernel mode only.
+
+--*/
+
+//
+// Basic UEFI Libraries
+//
+#include <Uefi.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+
+//
+// Boot and Runtime Services
+//
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+//
+// Multi-Processor Service
+//
+#include <Pi/PiDxeCis.h>
+#include <Protocol/MpService.h>
+
+//
+// Variable Arguments (CRT)
+//
+#include <varargs.h>
+
+//
+// External SimpleVisor Headers
+//
+#include "ntint.h"
+#include "shv_x.h"
+
+//
+// We run on any UEFI Specification
+//
+extern CONST UINT32 _gUefiDriverRevision = 0;
+
+//
+// Our name
+//
+CHAR8 *gEfiCallerBaseName = "SimpleVisor";
+
+//
+// PI Multi Processor Services Protocol
+//
+EFI_MP_SERVICES_PROTOCOL* _gPiMpService;
+
+//
+// TSS Segment we will use
+//
+#define KGDT64_SYS_TSS 0x60
+
+EFI_STATUS
+__forceinline
+ShvOsErrorToError (
+ INT32 Error
+ )
+{
+ //
+ // Convert the possible SimpleVisor errors into NT Hyper-V Errors
+ //
+ if (Error == SHV_STATUS_NOT_AVAILABLE)
+ {
+ return EFI_NOT_AVAILABLE_YET;
+ }
+ if (Error == SHV_STATUS_NO_RESOURCES)
+ {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ if (Error == SHV_STATUS_NOT_PRESENT)
+ {
+ return EFI_NOT_FOUND;
+ }
+ if (Error == SHV_STATUS_SUCCESS)
+ {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Unknown/unexpected error
+ //
+ return EFI_LOAD_ERROR;
+}
+
+VOID
+_str (
+ _In_ UINT16* Tr
+ )
+{
+ //
+ // Use the UEFI framework function
+ //
+ *Tr = AsmReadTr();
+}
+
+VOID
+_sldt (
+ _In_ UINT16* Ldtr
+ )
+{
+ //
+ // Use the UEFI framework function
+ //
+ *Ldtr = AsmReadLdtr();
+}
+
+VOID
+__lgdt (
+ _In_ IA32_DESCRIPTOR* Gdtr
+ )
+{
+ //
+ // Use the UEFI framework function
+ //
+ AsmWriteGdtr(Gdtr);
+}
+
+VOID
+ShvOsUnprepareProcessor (
+ _In_ PSHV_VP_DATA VpData
+ )
+{
+ UNREFERENCED_PARAMETER(VpData);
+
+ //
+ // Nothing to do
+ //
+}
+
+INT32
+ShvOsPrepareProcessor (
+ _In_ PSHV_VP_DATA VpData
+ )
+{
+ PKGDTENTRY64 TssEntry, NewGdt;
+ PKTSS64 Tss;
+ KDESCRIPTOR Gdtr;
+
+ //
+ // Clear AC in case it's not been reset yet
+ //
+ __writeeflags(__readeflags() & ~EFLAGS_ALIGN_CHECK);
+
+ //
+ // Capture the current GDT
+ //
+ _sgdt(&Gdtr.Limit);
+
+ //
+ // Allocate a new GDT as big as the old one, or to cover selector 0x60
+ //
+ NewGdt = AllocateRuntimeZeroPool(MAX(Gdtr.Limit + 1,
+ KGDT64_SYS_TSS + sizeof(*TssEntry)));
+ if (NewGdt == NULL)
+ {
+ return SHV_STATUS_NO_RESOURCES;
+ }
+
+ //
+ // Copy the old GDT
+ //
+ CopyMem(NewGdt, Gdtr.Base, Gdtr.Limit + 1);
+
+ //
+ // Allocate a TSS
+ //
+ Tss = AllocateRuntimeZeroPool(sizeof(*Tss));
+ if (Tss == NULL)
+ {
+ FreePool(NewGdt);
+ return SHV_STATUS_NO_RESOURCES;
+ }
+
+ //
+ // Fill out the TSS Entry
+ //
+ TssEntry = (PKGDTENTRY64)((uintptr_t)NewGdt + KGDT64_SYS_TSS);
+ TssEntry->BaseLow = (uintptr_t)Tss & 0xffff;
+ TssEntry->Bits.BaseMiddle = ((uintptr_t)Tss >> 16) & 0xff;
+ TssEntry->Bits.BaseHigh = ((uintptr_t)Tss >> 24) & 0xff;
+ TssEntry->BaseUpper = (uintptr_t)Tss >> 32;
+ TssEntry->LimitLow = sizeof(KTSS64) - 1;
+ TssEntry->Bits.Type = AMD64_TSS;
+ TssEntry->Bits.Dpl = 0;
+ TssEntry->Bits.Present = 1;
+ TssEntry->Bits.System = 0;
+ TssEntry->Bits.LongMode = 0;
+ TssEntry->Bits.DefaultBig = 0;
+ TssEntry->Bits.Granularity = 0;
+ TssEntry->MustBeZero = 0;
+
+ //
+ // Load the new GDT
+ //
+ Gdtr.Base = NewGdt;
+ Gdtr.Limit = KGDT64_SYS_TSS + sizeof(*TssEntry) - 1;
+ _lgdt(&Gdtr.Limit);
+
+ //
+ // Load the task register
+ //
+ _ltr(KGDT64_SYS_TSS);
+ return SHV_STATUS_SUCCESS;
+}
+
+VOID
+ShvOsRunCallbackOnProcessors (
+ _In_ PSHV_CPU_CALLBACK Routine,
+ _In_ VOID* Context
+ )
+{
+ //
+ // Call the routine on the current CPU
+ //
+ Routine(Context);
+
+ //
+ // And then on all other processors
+ //
+ _gPiMpService->StartupAllAPs(_gPiMpService,
+ Routine,
+ TRUE,
+ NULL,
+ 0,
+ Context,
+ NULL);
+}
+
+VOID
+ShvOsFreeContiguousAlignedMemory (
+ _In_ VOID* BaseAddress,
+ _In_ size_t Size
+ )
+{
+ //
+ // Free the memory
+ //
+ FreeAlignedPages(BaseAddress, Size);
+}
+
+VOID*
+ShvOsAllocateContigousAlignedMemory (
+ _In_ size_t Size
+ )
+{
+ //
+ // Allocate a contiguous chunk of RAM to back this allocation.
+ //
+ return AllocateAlignedRuntimePages(Size, EFI_PAGE_SIZE);
+}
+
+UINT64
+ShvOsGetPhysicalAddress (
+ _In_ VOID* BaseAddress
+ )
+{
+ //
+ // UEFI runs with paging disabled
+ //
+ return (UINT64)BaseAddress;
+}
+
+INT32
+ShvOsGetCurrentProcessorNumber (
+ VOID
+ )
+{
+ EFI_STATUS efiStatus;
+ UINTN cpuIndex;
+
+ //
+ // Ask PI MP Services for the CPU index
+ //
+ efiStatus = _gPiMpService->WhoAmI(_gPiMpService, &cpuIndex);
+ if (efiStatus != EFI_SUCCESS)
+ {
+ cpuIndex = ~0ULL;
+ }
+
+ //
+ // Return the index
+ //
+ return (INT32)cpuIndex;
+}
+
+INT32
+ShvOsGetActiveProcessorCount (
+ VOID
+ )
+{
+ EFI_STATUS efiStatus;
+ UINTN cpuCount, enabledCpuCount;
+
+ //
+ // Ask PI MP Services for how many CPUs there are
+ //
+ efiStatus = _gPiMpService->GetNumberOfProcessors(_gPiMpService,
+ &cpuCount,
+ &enabledCpuCount);
+ if (efiStatus != EFI_SUCCESS)
+ {
+ enabledCpuCount = 0;
+ }
+
+ //
+ // Return the count
+ //
+ return (INT32)enabledCpuCount;
+}
+
+VOID
+ShvOsDebugPrintWide (
+ _In_ CHAR16* Format,
+ ...
+ )
+{
+ VA_LIST arglist;
+ CHAR16* debugString;
+
+ //
+ // Call the debugger API
+ //
+ VA_START(arglist, Format);
+ debugString = CatVSPrint(NULL, Format, arglist);
+ Print(debugString);
+ FreePool(debugString);
+ VA_END(arglist);
+}
+
+EFI_STATUS
+EFIAPI
+UefiUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ //
+ // Call the hypervisor unloadpoint
+ //
+ ShvUnload();
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+UefiMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE* SystemTable
+ )
+{
+ EFI_STATUS efiStatus;
+
+ //
+ // Find the PI MpService protocol used for multi-processor startup
+ //
+ efiStatus = gBS->LocateProtocol(&gEfiMpServiceProtocolGuid,
+ NULL,
+ &_gPiMpService);
+ if (EFI_ERROR(efiStatus))
+ {
+ Print(L"Unable to locate the MpServices procotol: %r\n", efiStatus);
+ return efiStatus;
+ }
+
+ //
+ // Call the hypervisor entrypoint
+ //
+ return ShvOsErrorToError(ShvLoad());
+}
+
diff --git a/uefi/shvosx64.asm b/uefi/shvosx64.asm
new file mode 100644
index 0000000..c1bdf84
--- /dev/null
+++ b/uefi/shvosx64.asm
@@ -0,0 +1,99 @@
+;++
+;
+; Copyright (c) Alex Ionescu. All rights reserved.
+;
+; Module:
+;
+; shvx64.asm
+;
+; Abstract:
+;
+; This module implements AMD64-specific routines for the Simple Hyper Visor.
+;
+; Author:
+;
+; Alex Ionescu (@aionescu) 16-Mar-2016 - Initial version
+;
+; Environment:
+;
+; Kernel mode only.
+;
+;--
+
+ .code
+
+ _ltr PROC
+ ltr cx
+ _ltr ENDP
+
+ ShvOsCaptureContext PROC
+ pushfq
+ mov [rcx+78h], rax
+ mov [rcx+80h], rcx
+ mov [rcx+88h], rdx
+ mov [rcx+0B8h], r8
+ mov [rcx+0C0h], r9
+ mov [rcx+0C8h], r10
+ mov [rcx+0D0h], r11
+
+ mov word ptr [rcx+38h], cs
+ mov word ptr [rcx+3Ah], ds
+ mov word ptr [rcx+3Ch], es
+ mov word ptr [rcx+42h], ss
+ mov word ptr [rcx+3Eh], fs
+ mov word ptr [rcx+40h], gs
+
+ mov [rcx+90h], rbx
+ mov [rcx+0A0h], rbp
+ mov [rcx+0A8h], rsi
+ mov [rcx+0B0h], rdi
+ mov [rcx+0D8h], r12
+ mov [rcx+0E0h], r13
+ mov [rcx+0E8h], r14
+ mov [rcx+0F0h], r15
+
+ lea rax, [rsp+10h]
+ mov [rcx+98h], rax
+ mov rax, [rsp+8]
+ mov [rcx+0F8h], rax
+ mov eax, [rsp]
+ mov [rcx+44h], eax
+
+ add rsp, 8
+ ret
+ ShvOsCaptureContext ENDP
+
+ ShvOsRestoreContext PROC
+ mov ax, [rcx+42h]
+ mov [rsp+20h], ax
+ mov rax, [rcx+98h]
+ mov [rsp+18h], rax
+ mov eax, [rcx+44h]
+ mov [rsp+10h], eax
+ mov ax, [rcx+38h]
+ mov [rsp+8], ax
+ mov rax, [rcx+0F8h]
+ mov [rsp], rax
+
+ mov rax, [rcx+78h]
+ mov rdx, [rcx+88h]
+ mov r8, [rcx+0B8h]
+ mov r9, [rcx+0C0h]
+ mov r10, [rcx+0C8h]
+ mov r11, [rcx+0D0h]
+ cli
+
+ mov rbx, [rcx+90h]
+ mov rsi, [rcx+0A8h]
+ mov rdi, [rcx+0B0h]
+ mov rbp, [rcx+0A0h]
+ mov r12, [rcx+0D8h]
+ mov r13, [rcx+0E0h]
+ mov r14, [rcx+0E8h]
+ mov r15, [rcx+0F0h]
+ mov rcx, [rcx+80h]
+
+ iretq
+ ShvOsRestoreContext ENDP
+
+ end