UefiCpuPkg VTF0 X64: Build page tables in NASM code
authorJordan Justen <jordan.l.justen@intel.com>
Mon, 18 Aug 2014 23:03:46 +0000 (23:03 +0000)
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 18 Aug 2014 23:03:46 +0000 (23:03 +0000)
Previously, we would build the page tables in
Tools/FixupForRawSection.py.

In order to let NASM build VTF0 from source during the EDK II build
process, we need to move this into the VTF0 NASM code.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15822 6f19259b-4bc3-4df7-8a09-765794883524

UefiCpuPkg/ResetVector/Vtf0/Ia16/ResetVectorVtf0.asm
UefiCpuPkg/ResetVector/Vtf0/Ia32/PageTables64.asm
UefiCpuPkg/ResetVector/Vtf0/Tools/FixupForRawSection.py
UefiCpuPkg/ResetVector/Vtf0/Vtf0.nasmb
UefiCpuPkg/ResetVector/Vtf0/X64/PageTables.asm [new file with mode: 0644]

index 610b956..142d9f3 100644 (file)
@@ -2,7 +2,7 @@
 ; @file\r
 ; First code executed by processor after resetting.\r
 ;\r
-; Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>\r
+; Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>\r
 ; This program and the accompanying materials\r
 ; are licensed and made available under the terms and conditions of the BSD License\r
 ; which accompanies this distribution.  The full text of the license may be found at\r
@@ -17,6 +17,19 @@ BITS    16
 \r
 ALIGN   16\r
 \r
+;\r
+; Pad the image size to 4k when page tables are in VTF0\r
+;\r
+; If the VTF0 image has page tables built in, then we need to make\r
+; sure the end of VTF0 is 4k above where the page tables end.\r
+;\r
+; This is required so the page tables will be 4k aligned when VTF0 is\r
+; located just below 0x100000000 (4GB) in the firmware device.\r
+;\r
+%ifdef ALIGN_TOP_TO_4K_FOR_PAGING\r
+    TIMES (0x1000 - ($ - EndOfPageTables) - 0x20) DB 0\r
+%endif\r
+\r
 applicationProcessorEntryPoint:\r
 ;\r
 ; Application Processors entry point\r
@@ -25,7 +38,7 @@ applicationProcessorEntryPoint:
 ; location.  (0xffffffe0)  This allows the Local APIC Startup IPI to be\r
 ; used to wake up the application processors.\r
 ;\r
-    jmp     short EarlyApInitReal16\r
+    jmp     EarlyApInitReal16\r
 \r
 ALIGN   8\r
 \r
@@ -50,7 +63,7 @@ resetVector:
 ;\r
     nop\r
     nop\r
-    jmp     short EarlyBspInitReal16\r
+    jmp     EarlyBspInitReal16\r
 \r
 ALIGN   16\r
 \r
index 0cfcbae..2e16e71 100644 (file)
@@ -21,9 +21,9 @@ BITS    32
 SetCr3ForPageTables64:\r
 \r
     ;\r
-    ; These pages are built into the ROM image by Tools/FixupForRawSection.py\r
+    ; These pages are built into the ROM image in X64/PageTables.asm\r
     ;\r
-    mov     eax, ((ADDR_OF_START_OF_RESET_CODE & ~0xfff) - 0x1000)\r
+    mov     eax, ADDR_OF(TopLevelPageDirectory)\r
     mov     cr3, eax\r
 \r
     OneTimeCallRet SetCr3ForPageTables64\r
index a9f21db..a70ce75 100644 (file)
@@ -16,95 +16,11 @@ import sys
 \r
 filename = sys.argv[1]\r
 \r
-if filename.lower().find('ia32') >= 0:\r
-    d = open(sys.argv[1], 'rb').read()\r
-    c = ((len(d) + 4 + 7) & ~7) - 4\r
-    if c > len(d):\r
-        c -= len(d)\r
-        f = open(sys.argv[1], 'wb')\r
-        f.write('\x90' * c)\r
-        f.write(d)\r
-        f.close()\r
-else:\r
-    from struct import pack\r
-\r
-    PAGE_PRESENT             =     0x01\r
-    PAGE_READ_WRITE          =     0x02\r
-    PAGE_USER_SUPERVISOR     =     0x04\r
-    PAGE_WRITE_THROUGH       =     0x08\r
-    PAGE_CACHE_DISABLE       =    0x010\r
-    PAGE_ACCESSED            =    0x020\r
-    PAGE_DIRTY               =    0x040\r
-    PAGE_PAT                 =    0x080\r
-    PAGE_GLOBAL              =   0x0100\r
-    PAGE_2M_MBO              =    0x080\r
-    PAGE_2M_PAT              =  0x01000\r
-\r
-    def NopAlign4k(s):\r
-        c = ((len(s) + 0xfff) & ~0xfff) - len(s)\r
-        return ('\x90' * c) + s\r
-\r
-    def PageDirectoryEntries4GbOf2MbPages(baseAddress):\r
-\r
-        s = ''\r
-        for i in range(0x800):\r
-            i = (\r
-                    baseAddress + long(i << 21) +\r
-                    PAGE_2M_MBO +\r
-                    PAGE_CACHE_DISABLE +\r
-                    PAGE_ACCESSED +\r
-                    PAGE_DIRTY +\r
-                    PAGE_READ_WRITE +\r
-                    PAGE_PRESENT\r
-                )\r
-            s += pack('Q', i)\r
-        return s\r
-\r
-    def PageDirectoryPointerTable4GbOf2MbPages(pdeBase):\r
-        s = ''\r
-        for i in range(0x200):\r
-            i = (\r
-                    pdeBase +\r
-                    (min(i, 3) << 12) +\r
-                    PAGE_CACHE_DISABLE +\r
-                    PAGE_ACCESSED +\r
-                    PAGE_READ_WRITE +\r
-                    PAGE_PRESENT\r
-                )\r
-            s += pack('Q', i)\r
-        return s\r
-\r
-    def PageMapLevel4Table4GbOf2MbPages(pdptBase):\r
-        s = ''\r
-        for i in range(0x200):\r
-            i = (\r
-                    pdptBase +\r
-                    (min(i, 0) << 12) +\r
-                    PAGE_CACHE_DISABLE +\r
-                    PAGE_ACCESSED +\r
-                    PAGE_READ_WRITE +\r
-                    PAGE_PRESENT\r
-                )\r
-            s += pack('Q', i)\r
-        return s\r
-\r
-    def First4GbPageEntries(topAddress):\r
-        PDE = PageDirectoryEntries4GbOf2MbPages(0L)\r
-        pml4tBase = topAddress - 0x1000\r
-        pdptBase = pml4tBase - 0x1000\r
-        pdeBase = pdptBase - len(PDE)\r
-        PDPT = PageDirectoryPointerTable4GbOf2MbPages(pdeBase)\r
-        PML4T = PageMapLevel4Table4GbOf2MbPages(pdptBase)\r
-        return PDE + PDPT + PML4T\r
-\r
-    def AlignAndAddPageTables():\r
-        d = open(sys.argv[1], 'rb').read()\r
-        code = NopAlign4k(d)\r
-        topAddress = 0x100000000 - len(code)\r
-        d = ('\x90' * 4) + First4GbPageEntries(topAddress) + code\r
-        f = open(sys.argv[1], 'wb')\r
-        f.write(d)\r
-        f.close()\r
-\r
-    AlignAndAddPageTables()\r
-\r
+d = open(sys.argv[1], 'rb').read()\r
+c = ((len(d) + 4 + 7) & ~7) - 4\r
+if c > len(d):\r
+    c -= len(d)\r
+    f = open(sys.argv[1], 'wb')\r
+    f.write('\x90' * c)\r
+    f.write(d)\r
+    f.close()\r
index 31ac06a..f4a29e8 100644 (file)
 \r
 %include "PostCodes.inc"\r
 \r
+%ifdef ARCH_X64\r
+%include "X64/PageTables.asm"\r
+%endif\r
+\r
 %ifdef DEBUG_PORT80\r
   %include "Port80Debug.asm"\r
 %elifdef DEBUG_SERIAL\r
diff --git a/UefiCpuPkg/ResetVector/Vtf0/X64/PageTables.asm b/UefiCpuPkg/ResetVector/Vtf0/X64/PageTables.asm
new file mode 100644 (file)
index 0000000..3d703c7
--- /dev/null
@@ -0,0 +1,78 @@
+;------------------------------------------------------------------------------\r
+; @file\r
+; Emits Page Tables for 1:1 mapping of the addresses 0 - 0x100000000 (4GB)\r
+;\r
+; Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>\r
+; This program and the accompanying materials\r
+; are licensed and made available under the terms and conditions of the BSD License\r
+; which accompanies this distribution.  The full text of the license may be found at\r
+; http://opensource.org/licenses/bsd-license.php\r
+;\r
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+BITS    64\r
+\r
+%define ALIGN_TOP_TO_4K_FOR_PAGING\r
+\r
+%define PAGE_PRESENT            0x01\r
+%define PAGE_READ_WRITE         0x02\r
+%define PAGE_USER_SUPERVISOR    0x04\r
+%define PAGE_WRITE_THROUGH      0x08\r
+%define PAGE_CACHE_DISABLE     0x010\r
+%define PAGE_ACCESSED          0x020\r
+%define PAGE_DIRTY             0x040\r
+%define PAGE_PAT               0x080\r
+%define PAGE_GLOBAL           0x0100\r
+%define PAGE_2M_MBO            0x080\r
+%define PAGE_2M_PAT          0x01000\r
+\r
+%define PAGE_2M_PDE_ATTR (PAGE_2M_MBO + \\r
+                          PAGE_ACCESSED + \\r
+                          PAGE_DIRTY + \\r
+                          PAGE_READ_WRITE + \\r
+                          PAGE_PRESENT)\r
+\r
+%define PAGE_PDP_ATTR (PAGE_ACCESSED + \\r
+                       PAGE_READ_WRITE + \\r
+                       PAGE_PRESENT)\r
+\r
+%define PGTBLS_OFFSET(x) ((x) - TopLevelPageDirectory)\r
+%define PGTBLS_ADDR(x) (ADDR_OF(TopLevelPageDirectory) + (x))\r
+\r
+%define PDP(offset) (ADDR_OF(TopLevelPageDirectory) + (offset) + \\r
+                     PAGE_PDP_ATTR)\r
+%define PTE_2MB(x) ((x << 21) + PAGE_2M_PDE_ATTR)\r
+\r
+TopLevelPageDirectory:\r
+\r
+    ;\r
+    ; Top level Page Directory Pointers (1 * 512GB entry)\r
+    ;\r
+    DQ      PDP(0x1000)\r
+\r
+\r
+    ;\r
+    ; Next level Page Directory Pointers (4 * 1GB entries => 4GB)\r
+    ;\r
+    TIMES 0x1000-PGTBLS_OFFSET($) DB 0\r
+\r
+    DQ      PDP(0x2000)\r
+    DQ      PDP(0x3000)\r
+    DQ      PDP(0x4000)\r
+    DQ      PDP(0x5000)\r
+\r
+    ;\r
+    ; Page Table Entries (2048 * 2MB entries => 4GB)\r
+    ;\r
+    TIMES 0x2000-PGTBLS_OFFSET($) DB 0\r
+\r
+%assign i 0\r
+%rep    0x800\r
+    DQ      PTE_2MB(i)\r
+    %assign i i+1\r
+%endrep\r
+\r
+EndOfPageTables:\r