diff options
author | lgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524> | 2009-07-17 09:10:31 +0000 |
---|---|---|
committer | lgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524> | 2009-07-17 09:10:31 +0000 |
commit | 30fdf1140b8d1ce93f3821d986fa165552023440 (patch) | |
tree | c45c336a8955b1d03ea56d6c915a0e68a43b4ee9 /BaseTools/Source/C/GenPage | |
parent | 577e30cdb473e4af8e65fd6f75236691d0c8dfb3 (diff) | |
download | edk2-platforms-30fdf1140b8d1ce93f3821d986fa165552023440.tar.xz |
Check In tool source code based on Build tool project revision r1655.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8964 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'BaseTools/Source/C/GenPage')
-rw-r--r-- | BaseTools/Source/C/GenPage/GNUmakefile | 10 | ||||
-rw-r--r-- | BaseTools/Source/C/GenPage/GenPage.c | 424 | ||||
-rw-r--r-- | BaseTools/Source/C/GenPage/Makefile | 10 | ||||
-rw-r--r-- | BaseTools/Source/C/GenPage/VirtualMemory.h | 127 |
4 files changed, 571 insertions, 0 deletions
diff --git a/BaseTools/Source/C/GenPage/GNUmakefile b/BaseTools/Source/C/GenPage/GNUmakefile new file mode 100644 index 0000000000..a828168cd0 --- /dev/null +++ b/BaseTools/Source/C/GenPage/GNUmakefile @@ -0,0 +1,10 @@ +ARCH ?= IA32 +MAKEROOT ?= .. + +APPNAME = GenPage + +LIBS = -lCommon + +OBJECTS = GenPage.o + +include $(MAKEROOT)/Makefiles/app.makefile diff --git a/BaseTools/Source/C/GenPage/GenPage.c b/BaseTools/Source/C/GenPage/GenPage.c new file mode 100644 index 0000000000..99fbc1e472 --- /dev/null +++ b/BaseTools/Source/C/GenPage/GenPage.c @@ -0,0 +1,424 @@ +/** @file
+
+Copyright 2006 - 2008, 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:
+ GenPage.c
+
+Abstract:
+ Pre-Create a 4G page table (2M pages).
+ It's used in DUET x64 build needed to enter LongMode.
+
+ Create 4G page table (2M pages)
+
+ Linear Address
+ 63 48 47 39 38 30 29 21 20 0
+ +--------+-------+---------------+-----------+-----------------------------+
+ PML4 Directory-Ptr Directory Offset
+
+ Paging-Structures :=
+ PML4
+ (
+ Directory-Ptr Directory {512}
+ ) {4}
+**/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "VirtualMemory.h"
+#include "EfiUtilityMsgs.h"
+
+#define EFI_PAGE_BASE_OFFSET_IN_LDR 0x70000
+#define EFI_PAGE_BASE_ADDRESS (EFI_PAGE_BASE_OFFSET_IN_LDR + 0x20000)
+
+UINT32 gPageTableBaseAddress = EFI_PAGE_BASE_ADDRESS;
+UINT32 gPageTableOffsetInFile = EFI_PAGE_BASE_OFFSET_IN_LDR;
+
+#define EFI_MAX_ENTRY_NUM 512
+
+#define EFI_PML4_ENTRY_NUM 1
+#define EFI_PDPTE_ENTRY_NUM 4
+#define EFI_PDE_ENTRY_NUM EFI_MAX_ENTRY_NUM
+
+#define EFI_PML4_PAGE_NUM 1
+#define EFI_PDPTE_PAGE_NUM EFI_PML4_ENTRY_NUM
+#define EFI_PDE_PAGE_NUM (EFI_PML4_ENTRY_NUM * EFI_PDPTE_ENTRY_NUM)
+
+#define EFI_PAGE_NUMBER (EFI_PML4_PAGE_NUM + EFI_PDPTE_PAGE_NUM + EFI_PDE_PAGE_NUM)
+
+#define EFI_SIZE_OF_PAGE 0x1000
+#define EFI_PAGE_SIZE_2M 0x200000
+
+#define CONVERT_BIN_PAGE_ADDRESS(a) ((UINT8 *) a - PageTable + gPageTableBaseAddress)
+
+//
+// Utility Name
+//
+#define UTILITY_NAME "GenBootSector"
+
+//
+// Utility version information
+//
+#define UTILITY_MAJOR_VERSION 0
+#define UTILITY_MINOR_VERSION 1
+
+void
+Version (
+ void
+ )
+/*++
+
+Routine Description:
+
+ Displays the standard utility information to SDTOUT
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ printf ("%s v%d.%d -Utility to generate the EfiLoader image containing page table.\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);
+ printf ("Copyright (c) 2008 - 2009 Intel Corporation. All rights reserved.\n");
+}
+
+VOID
+Usage (
+ void
+ )
+{
+ Version();
+ printf ("\nUsage: \n\
+ GenPage\n\
+ -o, --output Filename containing page table\n\
+ [-b, --baseaddr baseaddress of page table]\n\
+ [-f, --offset offset in the file that page table will reside]\n\
+ [-v, --verbose]\n\
+ [--version]\n\
+ [-q, --quiet disable all messages except fatal errors]\n\
+ [-d, --debug[#]\n\
+ [-h, --help]\n\
+ EfiLoaderImageName\n");
+
+}
+
+void *
+CreateIdentityMappingPageTables (
+ void
+ )
+/*++
+
+Routine Description:
+ To create 4G PAE 2M pagetable
+
+Return:
+ void * - buffer containing created pagetable
+
+--*/
+{
+ UINT64 PageAddress;
+ UINT8 *PageTable;
+ UINT8 *PageTablePtr;
+ int PML4Index;
+ int PDPTEIndex;
+ int 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;
+
+ PageTable = (void *)malloc (EFI_PAGE_NUMBER * EFI_SIZE_OF_PAGE);
+ memset (PageTable, 0, (EFI_PAGE_NUMBER * EFI_SIZE_OF_PAGE));
+ PageTablePtr = PageTable;
+
+ PageAddress = 0;
+
+ //
+ // Page Table structure 3 level 2MB.
+ //
+ // Page-Map-Level-4-Table : bits 47-39
+ // Page-Directory-Pointer-Table : bits 38-30
+ //
+ // Page Table 2MB : Page-Directory(2M) : bits 29-21
+ //
+ //
+
+ PageMapLevel4Entry = (X64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K *)PageTablePtr;
+
+ for (PML4Index = 0; PML4Index < EFI_PML4_ENTRY_NUM; PML4Index++, PageMapLevel4Entry++) {
+ //
+ // Each Page-Map-Level-4-Table Entry points to the base address of a Page-Directory-Pointer-Table Entry
+ //
+ PageTablePtr += EFI_SIZE_OF_PAGE;
+ PageDirectoryPointerEntry = (X64_PAGE_MAP_AND_DIRECTORY_POINTER_2MB_4K *)PageTablePtr;
+
+ //
+ // Make a Page-Map-Level-4-Table Entry
+ //
+ PageMapLevel4Entry->Uint64 = (UINT64)(UINT32)(CONVERT_BIN_PAGE_ADDRESS (PageDirectoryPointerEntry));
+ PageMapLevel4Entry->Bits.ReadWrite = 1;
+ PageMapLevel4Entry->Bits.Present = 1;
+
+ for (PDPTEIndex = 0; PDPTEIndex < EFI_PDPTE_ENTRY_NUM; PDPTEIndex++, PageDirectoryPointerEntry++) {
+ //
+ // Each Page-Directory-Pointer-Table Entry points to the base address of a Page-Directory Entry
+ //
+ PageTablePtr += EFI_SIZE_OF_PAGE;
+ PageDirectoryEntry2MB = (X64_PAGE_TABLE_ENTRY_2M *)PageTablePtr;
+
+ //
+ // Make a Page-Directory-Pointer-Table Entry
+ //
+ PageDirectoryPointerEntry->Uint64 = (UINT64)(UINT32)(CONVERT_BIN_PAGE_ADDRESS (PageDirectoryEntry2MB));
+ PageDirectoryPointerEntry->Bits.ReadWrite = 1;
+ PageDirectoryPointerEntry->Bits.Present = 1;
+
+ for (PDEIndex = 0; PDEIndex < EFI_PDE_ENTRY_NUM; PDEIndex++, PageDirectoryEntry2MB++) {
+ //
+ // Make a Page-Directory Entry
+ //
+ PageDirectoryEntry2MB->Uint64 = (UINT64)PageAddress;
+ PageDirectoryEntry2MB->Bits.ReadWrite = 1;
+ PageDirectoryEntry2MB->Bits.Present = 1;
+ PageDirectoryEntry2MB->Bits.MustBe1 = 1;
+
+ PageAddress += EFI_PAGE_SIZE_2M;
+ }
+ }
+ }
+
+ return PageTable;
+}
+
+INT32
+GenBinPage (
+ void *BaseMemory,
+ char *NoPageFileName,
+ char *PageFileName
+ )
+/*++
+
+Routine Description:
+ Write the buffer containing page table to file at a specified offset.
+ Here the offset is defined as EFI_PAGE_BASE_OFFSET_IN_LDR.
+
+Arguments:
+ BaseMemory - buffer containing page table
+ NoPageFileName - file to write page table
+ PageFileName - file save to after writing
+
+return:
+ 0 : successful
+ -1 : failed
+
+--*/
+{
+ FILE *PageFile;
+ FILE *NoPageFile;
+ UINT8 Data;
+ unsigned long FileSize;
+
+ //
+ // Open files
+ //
+ PageFile = fopen (PageFileName, "w+b");
+ if (PageFile == NULL) {
+ Error (NoPageFileName, 0, 0x4002, "Invalid parameter option", "Output File %s open failure", PageFileName);
+ return -1;
+ }
+
+ NoPageFile = fopen (NoPageFileName, "r+b");
+ if (NoPageFile == NULL) {
+ Error (NoPageFileName, 0, 0x4002, "Invalid parameter option", "Input File %s open failure", NoPageFileName);
+ fclose (PageFile);
+ return -1;
+ }
+
+ //
+ // Check size - should not be great than EFI_PAGE_BASE_OFFSET_IN_LDR
+ //
+ fseek (NoPageFile, 0, SEEK_END);
+ FileSize = ftell (NoPageFile);
+ fseek (NoPageFile, 0, SEEK_SET);
+ if (FileSize > gPageTableOffsetInFile) {
+ Error (NoPageFileName, 0, 0x4002, "Invalid parameter option", "Input file size (0x%x) exceeds the Page Table Offset (0x%x)", FileSize, gPageTableOffsetInFile);
+ fclose (PageFile);
+ fclose (NoPageFile);
+ return -1;
+ }
+
+ //
+ // Write data
+ //
+ while (fread (&Data, sizeof(UINT8), 1, NoPageFile)) {
+ fwrite (&Data, sizeof(UINT8), 1, PageFile);
+ }
+
+ //
+ // Write PageTable
+ //
+ fseek (PageFile, gPageTableOffsetInFile, SEEK_SET);
+ fwrite (BaseMemory, (EFI_PAGE_NUMBER * EFI_SIZE_OF_PAGE), 1, PageFile);
+
+ //
+ // Close files
+ //
+ fclose (PageFile);
+ fclose (NoPageFile);
+
+ return 0;
+}
+
+int
+main (
+ int argc,
+ char **argv
+ )
+{
+ VOID *BaseMemory;
+ INTN result;
+ CHAR8 *OutputFile = NULL;
+ CHAR8 *InputFile = NULL;
+ EFI_STATUS Status;
+ UINT64 TempValue;
+
+ SetUtilityName("GenPage");
+
+ if (argc == 1) {
+ Usage();
+ return STATUS_ERROR;
+ }
+
+ argc --;
+ argv ++;
+
+ if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {
+ Usage();
+ return 0;
+ }
+
+ if (stricmp (argv[0], "--version") == 0) {
+ Version();
+ return 0;
+ }
+
+ while (argc > 0) {
+ if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--output") == 0)) {
+ if (argv[1] == NULL || argv[1][0] == '-') {
+ Error (NULL, 0, 1003, "Invalid option value", "Output file is missing for -o option");
+ return STATUS_ERROR;
+ }
+ OutputFile = argv[1];
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-b") == 0) || (stricmp (argv[0], "--baseaddr") == 0)) {
+ if (argv[1] == NULL || argv[1][0] == '-') {
+ Error (NULL, 0, 1003, "Invalid option value", "Base address is missing for -b option");
+ return STATUS_ERROR;
+ }
+ Status = AsciiStringToUint64 (argv[1], FALSE, &TempValue);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 1003, "Invalid option value", "Base address is not valid intergrator");
+ return STATUS_ERROR;
+ }
+ gPageTableBaseAddress = (UINT32) TempValue;
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-f") == 0) || (stricmp (argv[0], "--offset") == 0)) {
+ if (argv[1] == NULL || argv[1][0] == '-') {
+ Error (NULL, 0, 1003, "Invalid option value", "Offset is missing for -f option");
+ return STATUS_ERROR;
+ }
+ Status = AsciiStringToUint64 (argv[1], FALSE, &TempValue);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 1003, "Invalid option value", "Offset is not valid intergrator");
+ return STATUS_ERROR;
+ }
+ gPageTableOffsetInFile = (UINT32) TempValue;
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-v") ==0) || (stricmp (argv[0], "--verbose") == 0)) {
+ argc --;
+ argv ++;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {
+ if (argv[1] == NULL || argv[1][0] == '-') {
+ Error (NULL, 0, 1003, "Invalid option value", "Debug Level is not specified.");
+ return STATUS_ERROR;
+ }
+ Status = AsciiStringToUint64 (argv[1], FALSE, &TempValue);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 1003, "Invalid option value", "Debug Level is not valid intergrator.");
+ return STATUS_ERROR;
+ }
+ if (TempValue > 9) {
+ Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, currnt input level is %d", TempValue);
+ return STATUS_ERROR;
+ }
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if (argv[0][0] == '-') {
+ Error (NULL, 0, 1000, "Unknown option", argv[0]);
+ return STATUS_ERROR;
+ }
+
+ //
+ // Don't recognize the paramter.
+ //
+ InputFile = argv[0];
+ argc--;
+ argv++;
+ }
+
+ if (InputFile == NULL) {
+ Error (NULL, 0, 1003, "Invalid option value", "Input file is not specified");
+ return STATUS_ERROR;
+ }
+
+ //
+ // Create X64 page table
+ //
+ BaseMemory = CreateIdentityMappingPageTables ();
+
+ //
+ // Add page table to binary file
+ //
+ result = GenBinPage (BaseMemory, InputFile, OutputFile);
+ if (result < 0) {
+ return STATUS_ERROR;
+ }
+
+ return 0;
+}
+
diff --git a/BaseTools/Source/C/GenPage/Makefile b/BaseTools/Source/C/GenPage/Makefile new file mode 100644 index 0000000000..5faf037f44 --- /dev/null +++ b/BaseTools/Source/C/GenPage/Makefile @@ -0,0 +1,10 @@ +!INCLUDE ..\Makefiles\ms.common + +APPNAME = GenPage + +LIBS = $(LIB_PATH)\Common.lib + +OBJECTS = GenPage.obj + +!INCLUDE ..\Makefiles\ms.app + diff --git a/BaseTools/Source/C/GenPage/VirtualMemory.h b/BaseTools/Source/C/GenPage/VirtualMemory.h new file mode 100644 index 0000000000..b4baec86b2 --- /dev/null +++ b/BaseTools/Source/C/GenPage/VirtualMemory.h @@ -0,0 +1,127 @@ +/** @file
+
+Copyright 2006 - 2008, 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:
+
+ x64 Long Mode Virtual Memory Management Definitions
+
+ References:
+ 1) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 1:Basic Architecture, Intel
+ 2) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 2:Instruction Set Reference, Intel
+ 3) IA-32 Intel(R) Atchitecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel
+ 4) AMD64 Architecture Programmer's Manual Volume 2: System Programming
+**/
+
+#ifndef _VIRTUAL_MEMORY_H_
+#define _VIRTUAL_MEMORY_H_
+
+#include "CommonLib.h"
+
+#pragma pack(1)
+
+//
+// Page-Map Level-4 Offset (PML4) and
+// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB
+//
+
+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 Offset 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 Reserved:1; // Reserved
+ UINT64 MustBeZero:1; // Must Be Zero
+ UINT64 Reserved2:1; // Reserved
+ 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 2MB
+//
+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
|