IntelFsp2WrapperPkg SecFspWrapperPlatformSecLibSample: Convert ASM to NASM
authorLiming Gao <liming.gao@intel.com>
Wed, 8 Jun 2016 09:54:45 +0000 (17:54 +0800)
committerLiming Gao <liming.gao@intel.com>
Tue, 28 Jun 2016 01:52:05 +0000 (09:52 +0800)
Manually converts Ia32/PeiCoreEntry.asm, Ia32/SecEntry.asm and Ia32/Stack.asm
to Ia32/PeiCoreEntry.nasm, Ia32/SecEntry.nasm and Ia32/Stack.nasm.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Liming Gao <liming.gao@intel.com>
IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.nasm [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.nasm [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.nasm [new file with mode: 0644]
IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf

diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.nasm b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.nasm
new file mode 100644 (file)
index 0000000..a51c498
--- /dev/null
@@ -0,0 +1,136 @@
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2016, 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
+; Module Name:\r
+;\r
+;  PeiCoreEntry.nasm\r
+;\r
+; Abstract:\r
+;\r
+;   Find and call SecStartup\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+SECTION .text\r
+\r
+extern ASM_PFX(SecStartup)\r
+extern ASM_PFX(PlatformInit)\r
+\r
+global ASM_PFX(CallPeiCoreEntryPoint)\r
+ASM_PFX(CallPeiCoreEntryPoint):\r
+  ;\r
+  ; Obtain the hob list pointer\r
+  ;\r
+  mov     eax, [esp+4]\r
+  ;\r
+  ; Obtain the stack information\r
+  ;   ECX: start of range\r
+  ;   EDX: end of range\r
+  ;\r
+  mov     ecx, [esp+8]\r
+  mov     edx, [esp+0xC]\r
+\r
+  ;\r
+  ; Platform init\r
+  ;\r
+  pushad\r
+  push edx\r
+  push ecx\r
+  push eax\r
+  call ASM_PFX(PlatformInit)\r
+  pop  eax\r
+  pop  eax\r
+  pop  eax\r
+  popad\r
+\r
+  ;\r
+  ; Set stack top pointer\r
+  ;\r
+  mov     esp, edx\r
+\r
+  ;\r
+  ; Push the hob list pointer\r
+  ;\r
+  push    eax\r
+\r
+  ;\r
+  ; Save the value\r
+  ;   ECX: start of range\r
+  ;   EDX: end of range\r
+  ;\r
+  mov     ebp, esp\r
+  push    ecx\r
+  push    edx\r
+\r
+  ;\r
+  ; Push processor count to stack first, then BIST status (AP then BSP)\r
+  ;\r
+  mov     eax, 1\r
+  cpuid\r
+  shr     ebx, 16\r
+  and     ebx, 0xFF\r
+  cmp     bl, 1\r
+  jae     PushProcessorCount\r
+\r
+  ;\r
+  ; Some processors report 0 logical processors.  Effectively 0 = 1.\r
+  ; So we fix up the processor count\r
+  ;\r
+  inc     ebx\r
+\r
+PushProcessorCount:\r
+  push    ebx\r
+\r
+  ;\r
+  ; We need to implement a long-term solution for BIST capture.  For now, we just copy BSP BIST\r
+  ; for all processor threads\r
+  ;\r
+  xor     ecx, ecx\r
+  mov     cl, bl\r
+PushBist:\r
+  movd    eax, mm0\r
+  push    eax\r
+  loop    PushBist\r
+\r
+  ; Save Time-Stamp Counter\r
+  movd eax, mm5\r
+  push eax\r
+\r
+  movd eax, mm6\r
+  push eax\r
+\r
+  ;\r
+  ; Pass entry point of the PEI core\r
+  ;\r
+  mov     edi, 0xFFFFFFE0\r
+  push    DWORD [edi]\r
+\r
+  ;\r
+  ; Pass BFV into the PEI Core\r
+  ;\r
+  mov     edi, 0xFFFFFFFC\r
+  push    DWORD [edi]\r
+\r
+  ;\r
+  ; Pass stack size into the PEI Core\r
+  ;\r
+  mov     ecx, [ebp - 4]\r
+  mov     edx, [ebp - 8]\r
+  push    ecx       ; RamBase\r
+\r
+  sub     edx, ecx\r
+  push    edx       ; RamSize\r
+\r
+  ;\r
+  ; Pass Control into the PEI Core\r
+  ;\r
+  call ASM_PFX(SecStartup)\r
+\r
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.nasm b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.nasm
new file mode 100644 (file)
index 0000000..8bae7c5
--- /dev/null
@@ -0,0 +1,341 @@
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2016, 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
+; Module Name:\r
+;\r
+;  SecEntry.asm\r
+;\r
+; Abstract:\r
+;\r
+;  This is the code that goes from real-mode to protected mode.\r
+;  It consumes the reset vector, calls TempRamInit API from FSP binary.\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+#include "Fsp.h"\r
+\r
+SECTION .text\r
+\r
+extern   ASM_PFX(CallPeiCoreEntryPoint)\r
+extern   ASM_PFX(FsptUpdDataPtr)\r
+\r
+; Pcds\r
+extern   ASM_PFX(PcdGet32 (PcdFsptBaseAddress))\r
+\r
+;----------------------------------------------------------------------------\r
+;\r
+; Procedure:    _ModuleEntryPoint\r
+;\r
+; Input:        None\r
+;\r
+; Output:       None\r
+;\r
+; Destroys:     Assume all registers\r
+;\r
+; Description:\r
+;\r
+;   Transition to non-paged flat-model protected mode from a\r
+;   hard-coded GDT that provides exactly two descriptors.\r
+;   This is a bare bones transition to protected mode only\r
+;   used for a while in PEI and possibly DXE.\r
+;\r
+;   After enabling protected mode, a far jump is executed to\r
+;   transfer to PEI using the newly loaded GDT.\r
+;\r
+; Return:       None\r
+;\r
+;  MMX Usage:\r
+;              MM0 = BIST State\r
+;              MM5 = Save time-stamp counter value high32bit\r
+;              MM6 = Save time-stamp counter value low32bit.\r
+;\r
+;----------------------------------------------------------------------------\r
+\r
+BITS 16\r
+align 4\r
+global ASM_PFX(ModuleEntryPoint)\r
+ASM_PFX(ModuleEntryPoint):\r
+  fninit                                ; clear any pending Floating point exceptions\r
+  ;\r
+  ; Store the BIST value in mm0\r
+  ;\r
+  movd    mm0, eax\r
+\r
+  ;\r
+  ; Save time-stamp counter value\r
+  ; rdtsc load 64bit time-stamp counter to EDX:EAX\r
+  ;\r
+  rdtsc\r
+  movd    mm5, edx\r
+  movd    mm6, eax\r
+\r
+  ;\r
+  ; Load the GDT table in GdtDesc\r
+  ;\r
+  mov     esi,  GdtDesc\r
+  DB      66h\r
+  lgdt    [cs:si]\r
+\r
+  ;\r
+  ; Transition to 16 bit protected mode\r
+  ;\r
+  mov     eax, cr0                   ; Get control register 0\r
+  or      eax, 00000003h             ; Set PE bit (bit #0) & MP bit (bit #1)\r
+  mov     cr0, eax                   ; Activate protected mode\r
+\r
+  mov     eax, cr4                   ; Get control register 4\r
+  or      eax, 00000600h             ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)\r
+  mov     cr4, eax\r
+\r
+  ;\r
+  ; Now we're in 16 bit protected mode\r
+  ; Set up the selectors for 32 bit protected mode entry\r
+  ;\r
+  mov     ax, SYS_DATA_SEL\r
+  mov     ds, ax\r
+  mov     es, ax\r
+  mov     fs, ax\r
+  mov     gs, ax\r
+  mov     ss, ax\r
+\r
+  ;\r
+  ; Transition to Flat 32 bit protected mode\r
+  ; The jump to a far pointer causes the transition to 32 bit mode\r
+  ;\r
+  mov esi, ProtectedModeEntryLinearAddress\r
+  jmp   dword far  [cs:si]\r
+\r
+;----------------------------------------------------------------------------\r
+;\r
+; Procedure:    ProtectedModeEntryPoint\r
+;\r
+; Input:        None\r
+;\r
+; Output:       None\r
+;\r
+; Destroys:     Assume all registers\r
+;\r
+; Description:\r
+;\r
+; This function handles:\r
+;   Call two basic APIs from FSP binary\r
+;   Initializes stack with some early data (BIST, PEI entry, etc)\r
+;\r
+; Return:       None\r
+;\r
+;----------------------------------------------------------------------------\r
+\r
+BITS 32\r
+align 4\r
+ProtectedModeEntryPoint:\r
+\r
+  ; Find the fsp info header\r
+  mov  edi, [ASM_PFX(PcdGet32 (PcdFsptBaseAddress))]\r
+\r
+  mov  eax, dword [edi + FVH_SIGINATURE_OFFSET]\r
+  cmp  eax, FVH_SIGINATURE_VALID_VALUE\r
+  jnz  FspHeaderNotFound\r
+\r
+  xor  eax, eax\r
+  mov  ax, word [edi + FVH_EXTHEADER_OFFSET_OFFSET]\r
+  cmp  ax, 0\r
+  jnz  FspFvExtHeaderExist\r
+\r
+  xor  eax, eax\r
+  mov  ax, word [edi + FVH_HEADER_LENGTH_OFFSET]   ; Bypass Fv Header\r
+  add  edi, eax\r
+  jmp  FspCheckFfsHeader\r
+\r
+FspFvExtHeaderExist:\r
+  add  edi, eax\r
+  mov  eax, dword [edi + FVH_EXTHEADER_SIZE_OFFSET]  ; Bypass Ext Fv Header\r
+  add  edi, eax\r
+\r
+  ; Round up to 8 byte alignment\r
+  mov  eax, edi\r
+  and  al,  07h\r
+  jz   FspCheckFfsHeader\r
+\r
+  and  edi, 0FFFFFFF8h\r
+  add  edi, 08h\r
+\r
+FspCheckFfsHeader:\r
+  ; Check the ffs guid\r
+  mov  eax, dword [edi]\r
+  cmp  eax, FSP_HEADER_GUID_DWORD1\r
+  jnz  FspHeaderNotFound\r
+\r
+  mov  eax, dword [edi + 4]\r
+  cmp  eax, FSP_HEADER_GUID_DWORD2\r
+  jnz  FspHeaderNotFound\r
+\r
+  mov  eax, dword [edi + 8]\r
+  cmp  eax, FSP_HEADER_GUID_DWORD3\r
+  jnz  FspHeaderNotFound\r
+\r
+  mov  eax, dword [edi + 0Ch]\r
+  cmp  eax, FSP_HEADER_GUID_DWORD4\r
+  jnz  FspHeaderNotFound\r
+\r
+  add  edi, FFS_HEADER_SIZE_VALUE       ; Bypass the ffs header\r
+\r
+  ; Check the section type as raw section\r
+  mov  al, byte [edi + SECTION_HEADER_TYPE_OFFSET]\r
+  cmp  al, 019h\r
+  jnz FspHeaderNotFound\r
+\r
+  add  edi, RAW_SECTION_HEADER_SIZE_VALUE ; Bypass the section header\r
+  jmp FspHeaderFound\r
+\r
+FspHeaderNotFound:\r
+  jmp  $\r
+\r
+FspHeaderFound:\r
+  ; Get the fsp TempRamInit Api address\r
+  mov eax, dword [edi + FSP_HEADER_IMAGEBASE_OFFSET]\r
+  add eax, dword [edi + FSP_HEADER_TEMPRAMINIT_OFFSET]\r
+\r
+  ; Setup the hardcode stack\r
+  mov esp, TempRamInitStack\r
+\r
+  ; Call the fsp TempRamInit Api\r
+  jmp eax\r
+\r
+TempRamInitDone:\r
+  cmp eax, 8000000Eh      ;Check if EFI_NOT_FOUND returned. Error code for Microcode Update not found.\r
+  je  CallSecFspInit      ;If microcode not found, don't hang, but continue.\r
+\r
+  cmp eax, 0              ;Check if EFI_SUCCESS retuned.\r
+  jnz FspApiFailed\r
+\r
+  ;   ECX: start of range\r
+  ;   EDX: end of range\r
+CallSecFspInit:\r
+  xor     eax, eax\r
+  mov     esp, edx\r
+\r
+  ; Align the stack at DWORD\r
+  add  esp,  3\r
+  and  esp, 0FFFFFFFCh\r
+\r
+  push    edx\r
+  push    ecx\r
+  push    eax ; zero - no hob list yet\r
+  call    ASM_PFX(CallPeiCoreEntryPoint)\r
+\r
+FspApiFailed:\r
+  jmp $\r
+\r
+align 10h\r
+TempRamInitStack:\r
+    DD  TempRamInitDone\r
+    DD  ASM_PFX(FsptUpdDataPtr); TempRamInitParams\r
+\r
+;\r
+; ROM-based Global-Descriptor Table for the Tiano PEI Phase\r
+;\r
+align 16\r
+global  ASM_PFX(BootGdtTable)\r
+\r
+;\r
+; GDT[0]: 0x00: Null entry, never used.\r
+;\r
+NULL_SEL            EQU $ - GDT_BASE    ; Selector [0]\r
+GDT_BASE:\r
+ASM_PFX(BootGdtTable):\r
+                    DD  0\r
+                    DD  0\r
+;\r
+; Linear data segment descriptor\r
+;\r
+LINEAR_SEL          EQU $ - GDT_BASE    ; Selector [0x8]\r
+    DW  0FFFFh                          ; limit 0xFFFFF\r
+    DW  0                               ; base 0\r
+    DB  0\r
+    DB  092h                            ; present, ring 0, data, expand-up, writable\r
+    DB  0CFh                            ; page-granular, 32-bit\r
+    DB  0\r
+;\r
+; Linear code segment descriptor\r
+;\r
+LINEAR_CODE_SEL     EQU $ - GDT_BASE    ; Selector [0x10]\r
+    DW  0FFFFh                          ; limit 0xFFFFF\r
+    DW  0                               ; base 0\r
+    DB  0\r
+    DB  09Bh                            ; present, ring 0, data, expand-up, not-writable\r
+    DB  0CFh                            ; page-granular, 32-bit\r
+    DB  0\r
+;\r
+; System data segment descriptor\r
+;\r
+SYS_DATA_SEL        EQU $ - GDT_BASE    ; Selector [0x18]\r
+    DW  0FFFFh                          ; limit 0xFFFFF\r
+    DW  0                               ; base 0\r
+    DB  0\r
+    DB  093h                            ; present, ring 0, data, expand-up, not-writable\r
+    DB  0CFh                            ; page-granular, 32-bit\r
+    DB  0\r
+\r
+;\r
+; System code segment descriptor\r
+;\r
+SYS_CODE_SEL        EQU $ - GDT_BASE    ; Selector [0x20]\r
+    DW  0FFFFh                          ; limit 0xFFFFF\r
+    DW  0                               ; base 0\r
+    DB  0\r
+    DB  09Ah                            ; present, ring 0, data, expand-up, writable\r
+    DB  0CFh                            ; page-granular, 32-bit\r
+    DB  0\r
+;\r
+; Spare segment descriptor\r
+;\r
+SYS16_CODE_SEL      EQU $ - GDT_BASE    ; Selector [0x28]\r
+    DW  0FFFFh                          ; limit 0xFFFFF\r
+    DW  0                               ; base 0\r
+    DB  0Eh                             ; Changed from F000 to E000.\r
+    DB  09Bh                            ; present, ring 0, code, expand-up, writable\r
+    DB  00h                             ; byte-granular, 16-bit\r
+    DB  0\r
+;\r
+; Spare segment descriptor\r
+;\r
+SYS16_DATA_SEL      EQU $ - GDT_BASE    ; Selector [0x30]\r
+    DW  0FFFFh                          ; limit 0xFFFF\r
+    DW  0                               ; base 0\r
+    DB  0\r
+    DB  093h                            ; present, ring 0, data, expand-up, not-writable\r
+    DB  00h                             ; byte-granular, 16-bit\r
+    DB  0\r
+\r
+;\r
+; Spare segment descriptor\r
+;\r
+SPARE5_SEL          EQU $ - GDT_BASE    ; Selector [0x38]\r
+    DW  0                               ; limit 0\r
+    DW  0                               ; base 0\r
+    DB  0\r
+    DB  0                               ; present, ring 0, data, expand-up, writable\r
+    DB  0                               ; page-granular, 32-bit\r
+    DB  0\r
+GDT_SIZE            EQU $ - GDT_BASE    ; Size, in bytes\r
+\r
+;\r
+; GDT Descriptor\r
+;\r
+GdtDesc:                                ; GDT descriptor\r
+    DW  GDT_SIZE - 1                    ; GDT limit\r
+    DD  GDT_BASE                        ; GDT base address\r
+\r
+\r
+ProtectedModeEntryLinearAddress:\r
+ProtectedModeEntryLinear:\r
+  DD      ProtectedModeEntryPoint  ; Offset of our 32 bit code\r
+  DW      LINEAR_CODE_SEL\r
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.nasm b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.nasm
new file mode 100644 (file)
index 0000000..304678d
--- /dev/null
@@ -0,0 +1,79 @@
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2016, 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
+; Abstract:\r
+;\r
+;   Switch the stack from temporary memory to permenent memory.\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+    SECTION .text\r
+\r
+;------------------------------------------------------------------------------\r
+; VOID\r
+; EFIAPI\r
+; SecSwitchStack (\r
+;   UINT32   TemporaryMemoryBase,\r
+;   UINT32   PermanentMemoryBase\r
+;   );\r
+;------------------------------------------------------------------------------\r
+global ASM_PFX(SecSwitchStack)\r
+ASM_PFX(SecSwitchStack):\r
+    ;\r
+    ; Save three register: eax, ebx, ecx\r
+    ;\r
+    push  eax\r
+    push  ebx\r
+    push  ecx\r
+    push  edx\r
+\r
+    ;\r
+    ; !!CAUTION!! this function address's is pushed into stack after\r
+    ; migration of whole temporary memory, so need save it to permanent\r
+    ; memory at first!\r
+    ;\r
+\r
+    mov   ebx, [esp + 20]          ; Save the first parameter\r
+    mov   ecx, [esp + 24]          ; Save the second parameter\r
+\r
+    ;\r
+    ; Save this function's return address into permanent memory at first.\r
+    ; Then, Fixup the esp point to permanent memory\r
+    ;\r
+    mov   eax, esp\r
+    sub   eax, ebx\r
+    add   eax, ecx\r
+    mov   edx, dword [esp]         ; copy pushed register's value to permanent memory\r
+    mov   dword [eax], edx\r
+    mov   edx, dword [esp + 4]\r
+    mov   dword [eax + 4], edx\r
+    mov   edx, dword [esp + 8]\r
+    mov   dword [eax + 8], edx\r
+    mov   edx, dword [esp + 12]\r
+    mov   dword [eax + 12], edx\r
+    mov   edx, dword [esp + 16]    ; Update this function's return address into permanent memory\r
+    mov   dword [eax + 16], edx\r
+    mov   esp, eax                     ; From now, esp is pointed to permanent memory\r
+\r
+    ;\r
+    ; Fixup the ebp point to permanent memory\r
+    ;\r
+    mov   eax, ebp\r
+    sub   eax, ebx\r
+    add   eax, ecx\r
+    mov   ebp, eax                ; From now, ebp is pointed to permanent memory\r
+\r
+    pop   edx\r
+    pop   ecx\r
+    pop   ebx\r
+    pop   eax\r
+    ret\r
+\r
index 30393d2..5945319 100644 (file)
@@ -53,6 +53,9 @@
   Ia32/SecEntry.S\r
   Ia32/PeiCoreEntry.S\r
   Ia32/Stack.S\r
+  Ia32/SecEntry.nasm\r
+  Ia32/PeiCoreEntry.nasm\r
+  Ia32/Stack.nasm\r
 \r
 ################################################################################\r
 #\r