diff options
Diffstat (limited to 'DuetPkg/DxeIpl/X64')
-rw-r--r-- | DuetPkg/DxeIpl/X64/CpuIoAccess.asm | 52 | ||||
-rw-r--r-- | DuetPkg/DxeIpl/X64/EnterDxeCore.asm | 45 | ||||
-rw-r--r-- | DuetPkg/DxeIpl/X64/Paging.c | 238 | ||||
-rw-r--r-- | DuetPkg/DxeIpl/X64/VirtualMemory.h | 117 |
4 files changed, 452 insertions, 0 deletions
diff --git a/DuetPkg/DxeIpl/X64/CpuIoAccess.asm b/DuetPkg/DxeIpl/X64/CpuIoAccess.asm new file mode 100644 index 0000000000..f1515e8c84 --- /dev/null +++ b/DuetPkg/DxeIpl/X64/CpuIoAccess.asm @@ -0,0 +1,52 @@ + title CpuIoAccess.asm
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2007, Intel Corporation
+; All rights reserved. This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+; Module Name:
+; CpuIoAccess.asm
+;
+; Abstract:
+; CPU IO Abstraction
+;
+;------------------------------------------------------------------------------
+
+
+.code
+
+;------------------------------------------------------------------------------
+; UINT8
+; CpuIoRead8 (
+; UINT16 Port // rcx
+; )
+;------------------------------------------------------------------------------
+CpuIoRead8 PROC PUBLIC
+ xor eax, eax
+ mov dx, cx
+ in al, dx
+ ret
+CpuIoRead8 ENDP
+
+;------------------------------------------------------------------------------
+; VOID
+; CpuIoWrite8 (
+; UINT16 Port, // rcx
+; UINT32 Data // rdx
+; )
+;------------------------------------------------------------------------------
+CpuIoWrite8 PROC PUBLIC
+ mov eax, edx
+ mov dx, cx
+ out dx, al
+ ret
+CpuIoWrite8 ENDP
+
+
+END
diff --git a/DuetPkg/DxeIpl/X64/EnterDxeCore.asm b/DuetPkg/DxeIpl/X64/EnterDxeCore.asm new file mode 100644 index 0000000000..a1eada3905 --- /dev/null +++ b/DuetPkg/DxeIpl/X64/EnterDxeCore.asm @@ -0,0 +1,45 @@ + TITLE EnterDxeCore.asm: Assembly code for the entering DxeCore
+;------------------------------------------------------------------------------
+;*
+;* Copyright 2006, Intel Corporation
+;* All rights reserved. This program and the accompanying materials
+;* are licensed and made available under the terms and conditions of the BSD License
+;* which accompanies this distribution. The full text of the license may be found at
+;* http://opensource.org/licenses/bsd-license.php
+;*
+;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;*
+;* EnterDxeCore.asm
+;*
+;* Abstract:
+;*
+;------------------------------------------------------------------------------
+
+.code
+
+;
+; VOID
+; EnterDxeMain (
+; IN VOID *StackTop, // rcx
+; IN VOID *DxeCoreEntryPoint, // rdx
+; IN VOID *Hob, // r8
+; IN VOID *PageTable // r9
+; )
+;
+EnterDxeMain PROC
+
+ mov cr3, r9
+ sub rcx, 32
+ mov rsp, rcx
+ mov rcx, r8
+ push 0
+ jmp rdx
+
+; should never get here
+ jmp $
+ ret
+
+EnterDxeMain ENDP
+
+END
diff --git a/DuetPkg/DxeIpl/X64/Paging.c b/DuetPkg/DxeIpl/X64/Paging.c new file mode 100644 index 0000000000..0377b6a39b --- /dev/null +++ b/DuetPkg/DxeIpl/X64/Paging.c @@ -0,0 +1,238 @@ +/*++
+
+Copyright (c) 2006 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+ Paging.c
+
+Abstract:
+
+Revision History:
+
+--*/
+
+#include "HobGeneration.h"
+#include "VirtualMemory.h"
+
+//
+// Create 2M-page table
+// PML4 (47:39)
+// PDPTE (38:30)
+// PDE (29:21)
+//
+
+#define EFI_2M_PAGE_BITS_NUM 21
+#define EFI_MAX_ENTRY_BITS_NUM 9
+
+#define EFI_PAGE_SIZE_4K 0x1000
+#define EFI_PAGE_SIZE_2M (1 << EFI_2M_PAGE_BITS_NUM)
+
+#ifndef MIN
+ #define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+#define ENTRY_NUM(x) ((UINTN)1 << (x))
+
+UINT8 gPML4BitsNum;
+UINT8 gPDPTEBitsNum;
+UINT8 gPDEBitsNum;
+
+UINTN gPageNum2M;
+UINTN gPageNum4K;
+
+VOID
+EnableNullPointerProtection (
+ UINT8 *PageTable
+ )
+{
+ X64_PAGE_TABLE_ENTRY_4K *PageTableEntry4KB;
+
+ PageTableEntry4KB = (X64_PAGE_TABLE_ENTRY_4K *) (PageTable + gPageNum2M * EFI_PAGE_SIZE_4K);
+ //
+ // Fill in the Page Table entries
+ // Mark 0~4K as not present
+ //
+ PageTableEntry4KB->Bits.Present = 0;
+
+ return ;
+}
+
+VOID
+X64Create4KPageTables (
+ UINT8 *PageTable
+ )
+/*++
+Routine Description:
+ Create 4K-Page-Table for the low 2M memory.
+ This will change the previously created 2M-Page-Table-Entry.
+--*/
+{
+ UINT64 PageAddress;
+ UINTN PTEIndex;
+ X64_PAGE_DIRECTORY_ENTRY_4K *PageDirectoryEntry4KB;
+ X64_PAGE_TABLE_ENTRY_4K *PageTableEntry4KB;
+
+ //
+ // Page Table structure 4 level 4K.
+ //
+ // PageMapLevel4Entry : bits 47-39
+ // PageDirectoryPointerEntry : bits 38-30
+ // Page Table 4K : PageDirectoryEntry4K : bits 29-21
+ // PageTableEntry : bits 20-12
+ //
+
+ PageTableEntry4KB = (X64_PAGE_TABLE_ENTRY_4K *)(PageTable + gPageNum2M * EFI_PAGE_SIZE_4K);
+
+ PageDirectoryEntry4KB = (X64_PAGE_DIRECTORY_ENTRY_4K *) (PageTable + 2 * EFI_PAGE_SIZE_4K);
+ PageDirectoryEntry4KB->Uint64 = (UINT64)(UINTN)PageTableEntry4KB;
+ PageDirectoryEntry4KB->Bits.ReadWrite = 1;
+ PageDirectoryEntry4KB->Bits.Present = 1;
+ PageDirectoryEntry4KB->Bits.MustBeZero = 0;
+
+ for (PTEIndex = 0, PageAddress = 0;
+ PTEIndex < ENTRY_NUM (EFI_MAX_ENTRY_BITS_NUM);
+ PTEIndex++, PageTableEntry4KB++, PageAddress += EFI_PAGE_SIZE_4K
+ ) {
+ //
+ // Fill in the Page Table entries
+ //
+ PageTableEntry4KB->Uint64 = (UINT64)PageAddress;
+ PageTableEntry4KB->Bits.ReadWrite = 1;
+ PageTableEntry4KB->Bits.Present = 1;
+ }
+
+ return ;
+}
+
+VOID
+X64Create2MPageTables (
+ UINT8 *PageTable
+ )
+{
+ UINT64 PageAddress;
+ UINT8 *TempPageTable;
+ UINTN PML4Index;
+ UINTN PDPTEIndex;
+ UINTN PDEIndex;
+ X64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K *PageMapLevel4Entry;
+ X64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K *PageDirectoryPointerEntry;
+ X64_PAGE_TABLE_ENTRY_2M *PageDirectoryEntry2MB;
+
+ TempPageTable = PageTable;
+ PageAddress = 0;
+
+ //
+ // Page Table structure 3 level 2MB.
+ //
+ // PageMapLevel4Entry : bits 47-39
+ // PageDirectoryPointerEntry : bits 38-30
+ // Page Table 2MB : PageDirectoryEntry2M : bits 29-21
+ //
+
+ PageMapLevel4Entry = (X64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K *)TempPageTable;
+
+ for (PML4Index = 0; PML4Index < ENTRY_NUM (gPML4BitsNum); PML4Index++, PageMapLevel4Entry++) {
+ //
+ // Each PML4 entry points to a page of Page Directory Pointer entires.
+ //
+ TempPageTable += EFI_PAGE_SIZE_4K;
+ PageDirectoryPointerEntry = (X64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K *)TempPageTable;
+
+ //
+ // Make a PML4 Entry
+ //
+ PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)(TempPageTable);
+ PageMapLevel4Entry->Bits.ReadWrite = 1;
+ PageMapLevel4Entry->Bits.Present = 1;
+
+ for (PDPTEIndex = 0; PDPTEIndex < ENTRY_NUM (gPDPTEBitsNum); PDPTEIndex++, PageDirectoryPointerEntry++) {
+ //
+ // Each Directory Pointer entries points to a page of Page Directory entires.
+ //
+ TempPageTable += EFI_PAGE_SIZE_4K;
+ PageDirectoryEntry2MB = (X64_PAGE_TABLE_ENTRY_2M *)TempPageTable;
+
+ //
+ // Fill in a Page Directory Pointer Entries
+ //
+ PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)(TempPageTable);
+ PageDirectoryPointerEntry->Bits.ReadWrite = 1;
+ PageDirectoryPointerEntry->Bits.Present = 1;
+
+ for (PDEIndex = 0; PDEIndex < ENTRY_NUM (gPDEBitsNum); PDEIndex++, PageDirectoryEntry2MB++) {
+ //
+ // Fill in the Page Directory entries
+ //
+ PageDirectoryEntry2MB->Uint64 = (UINT64)PageAddress;
+ PageDirectoryEntry2MB->Bits.ReadWrite = 1;
+ PageDirectoryEntry2MB->Bits.Present = 1;
+ PageDirectoryEntry2MB->Bits.MustBe1 = 1;
+
+ PageAddress += EFI_PAGE_SIZE_2M;
+ }
+ }
+ }
+
+ return ;
+}
+
+VOID *
+PreparePageTable (
+ VOID *PageNumberTop,
+ UINT8 SizeOfMemorySpace
+ )
+/*++
+Description:
+ Generate pagetable below PageNumberTop,
+ and return the bottom address of pagetable for putting other things later.
+--*/
+{
+ VOID *PageNumberBase;
+
+ SizeOfMemorySpace -= EFI_2M_PAGE_BITS_NUM;
+ gPDEBitsNum = MIN (SizeOfMemorySpace, EFI_MAX_ENTRY_BITS_NUM);
+ SizeOfMemorySpace = SizeOfMemorySpace - gPDEBitsNum;
+ gPDPTEBitsNum = MIN (SizeOfMemorySpace, EFI_MAX_ENTRY_BITS_NUM);
+ SizeOfMemorySpace = SizeOfMemorySpace - gPDPTEBitsNum;
+ gPML4BitsNum = SizeOfMemorySpace;
+ if (gPML4BitsNum > EFI_MAX_ENTRY_BITS_NUM) {
+ return NULL;
+ }
+
+ //
+ // Suppose we have:
+ // 2MPage:
+ // Entry: PML4 -> PDPTE -> PDE -> Page
+ // EntryNum: a b c
+ // then
+ // Occupy4KPage: 1 a a*b
+ //
+ // 2M 4KPage:
+ // Entry: PTE -> Page
+ // EntryNum: 512
+ // then
+ // Occupy4KPage: 1
+ //
+
+ gPageNum2M = 1 + ENTRY_NUM (gPML4BitsNum) + ENTRY_NUM (gPML4BitsNum + gPDPTEBitsNum);
+ gPageNum4K = 1;
+
+
+ PageNumberBase = (VOID *)((UINTN)PageNumberTop - (gPageNum2M + gPageNum4K) * EFI_PAGE_SIZE_4K);
+ ZeroMem (PageNumberBase, (gPageNum2M + gPageNum4K) * EFI_PAGE_SIZE_4K);
+
+ X64Create2MPageTables (PageNumberBase);
+ X64Create4KPageTables (PageNumberBase);
+ //
+ // Not enable NULL Pointer Protection if using INTx call
+ //
+// EnableNullPointerProtection (PageNumberBase);
+
+ return PageNumberBase;
+}
diff --git a/DuetPkg/DxeIpl/X64/VirtualMemory.h b/DuetPkg/DxeIpl/X64/VirtualMemory.h new file mode 100644 index 0000000000..6077de513f --- /dev/null +++ b/DuetPkg/DxeIpl/X64/VirtualMemory.h @@ -0,0 +1,117 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+ VirtualMemory.h
+
+Abstract:
+
+Revision History:
+
+--*/
+
+#ifndef _VIRTUAL_MEMORY_H_
+#define _VIRTUAL_MEMORY_H_
+
+#pragma pack(1)
+
+//
+// Page Map Level 4 Offset (PML4) and
+// Page Directory Pointer Table (PDPE) entries 4K & 2M
+//
+
+typedef union {
+ struct {
+ UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory
+ UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write
+ UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User
+ UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching
+ UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached
+ UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)
+ UINT64 Reserved:1; // Reserved
+ UINT64 MustBeZero:2; // Must Be Zero
+ UINT64 Available:3; // Available for use by system software
+ UINT64 PageTableBaseAddress:40; // Page Table Base Address
+ UINT64 AvabilableHigh:11; // Available for use by system software
+ UINT64 Nx:1; // No Execute bit
+ } Bits;
+ UINT64 Uint64;
+} X64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K;
+
+//
+// Page Directory Entry 4K
+//
+typedef union {
+ struct {
+ UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory
+ UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write
+ UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User
+ UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching
+ UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached
+ UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)
+ UINT64 MustBeZero:3; // Must Be Zero
+ UINT64 Available:3; // Available for use by system software
+ UINT64 PageTableBaseAddress:40; // Page Table Base Address
+ UINT64 AvabilableHigh:11; // Available for use by system software
+ UINT64 Nx:1; // No Execute bit
+ } Bits;
+ UINT64 Uint64;
+} X64_PAGE_DIRECTORY_ENTRY_4K;
+
+//
+// Page Table Entry 4K
+//
+typedef union {
+ struct {
+ UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory
+ UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write
+ UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User
+ UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching
+ UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached
+ UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)
+ UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page
+ UINT64 PAT:1; // 0 = Ignore Page Attribute Table
+ UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write
+ UINT64 Available:3; // Available for use by system software
+ UINT64 PageTableBaseAddress:40; // Page Table Base Address
+ UINT64 AvabilableHigh:11; // Available for use by system software
+ UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution
+ } Bits;
+ UINT64 Uint64;
+} X64_PAGE_TABLE_ENTRY_4K;
+
+//
+// Page Table Entry 2M
+//
+typedef union {
+ struct {
+ UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory
+ UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write
+ UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User
+ UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching
+ UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached
+ UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)
+ UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page
+ UINT64 MustBe1:1; // Must be 1
+ UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write
+ UINT64 Available:3; // Available for use by system software
+ UINT64 PAT:1; //
+ UINT64 MustBeZero:8; // Must be zero;
+ UINT64 PageTableBaseAddress:31; // Page Table Base Address
+ UINT64 AvabilableHigh:11; // Available for use by system software
+ UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution
+ } Bits;
+ UINT64 Uint64;
+} X64_PAGE_TABLE_ENTRY_2M;
+
+#pragma pack()
+
+#endif
|