Home | History | Annotate | Download | only in Ia32
      1 ;; @file
      2 ;  Provide FSP API entry points.
      3 ;
      4 ; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
      5 ; This program and the accompanying materials
      6 ; are licensed and made available under the terms and conditions of the BSD License
      7 ; which accompanies this distribution.  The full text of the license may be found at
      8 ; http://opensource.org/licenses/bsd-license.php.
      9 ;
     10 ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 ;;
     13 
     14     SECTION .text
     15 
     16 ;
     17 ; Following are fixed PCDs
     18 ;
     19 extern   ASM_PFX(PcdGet32(PcdTemporaryRamBase))
     20 extern   ASM_PFX(PcdGet32(PcdTemporaryRamSize))
     21 extern   ASM_PFX(PcdGet32(PcdFspTemporaryRamSize))
     22 
     23 struc FSPM_UPD_COMMON
     24     ; FSP_UPD_HEADER {
     25     .FspUpdHeader:            resd    8
     26     ; }
     27     ; FSPM_ARCH_UPD {
     28     .Revision:                resb    1
     29     .Reserved:                resb    3
     30     .NvsBufferPtr:            resd    1
     31     .StackBase:               resd    1
     32     .StackSize:               resd    1
     33     .BootLoaderTolumSize:     resd    1
     34     .BootMode:                resd    1
     35     .Reserved1:               resb    8
     36     ; }
     37     .size:
     38 endstruc
     39 
     40 ;
     41 ; Following functions will be provided in C
     42 ;
     43 extern ASM_PFX(SecStartup)
     44 extern ASM_PFX(FspApiCommon)
     45 
     46 ;
     47 ; Following functions will be provided in PlatformSecLib
     48 ;
     49 extern ASM_PFX(AsmGetFspBaseAddress)
     50 extern ASM_PFX(AsmGetFspInfoHeader)
     51 
     52 API_PARAM1_OFFSET            EQU   34h  ; ApiParam1 [ sub esp,8 + pushad + pushfd + push eax + call]
     53 FSP_HEADER_IMGBASE_OFFSET    EQU   1Ch
     54 FSP_HEADER_CFGREG_OFFSET     EQU   24h
     55 
     56 ;----------------------------------------------------------------------------
     57 ; FspMemoryInit API
     58 ;
     59 ; This FSP API is called after TempRamInit and initializes the memory.
     60 ;
     61 ;----------------------------------------------------------------------------
     62 global ASM_PFX(FspMemoryInitApi)
     63 ASM_PFX(FspMemoryInitApi):
     64   mov    eax,  3 ; FSP_API_INDEX.FspMemoryInitApiIndex
     65   jmp    ASM_PFX(FspApiCommon)
     66 
     67 ;----------------------------------------------------------------------------
     68 ; TempRamExitApi API
     69 ;
     70 ; This API tears down temporary RAM
     71 ;
     72 ;----------------------------------------------------------------------------
     73 global ASM_PFX(TempRamExitApi)
     74 ASM_PFX(TempRamExitApi):
     75   mov    eax,  4 ; FSP_API_INDEX.TempRamExitApiIndex
     76   jmp    ASM_PFX(FspApiCommon)
     77 
     78 ;----------------------------------------------------------------------------
     79 ; FspApiCommonContinue API
     80 ;
     81 ; This is the FSP API common entry point to resume the FSP execution
     82 ;
     83 ;----------------------------------------------------------------------------
     84 global ASM_PFX(FspApiCommonContinue)
     85 ASM_PFX(FspApiCommonContinue):
     86   ;
     87   ; EAX holds the API index
     88   ;
     89 
     90   ;
     91   ; FspMemoryInit API setup the initial stack frame
     92   ;
     93 
     94   ;
     95   ; Place holder to store the FspInfoHeader pointer
     96   ;
     97   push   eax
     98 
     99   ;
    100   ; Update the FspInfoHeader pointer
    101   ;
    102   push   eax
    103   call   ASM_PFX(AsmGetFspInfoHeader)
    104   mov    [esp + 4], eax
    105   pop    eax
    106 
    107   ;
    108   ; Create a Task Frame in the stack for the Boot Loader
    109   ;
    110   pushfd     ; 2 pushf for 4 byte alignment
    111   cli
    112   pushad
    113 
    114   ; Reserve 8 bytes for IDT save/restore
    115   sub     esp, 8
    116   sidt    [esp]
    117 
    118 
    119   ;  Get Stackbase and StackSize from FSPM_UPD Param 
    120   mov    edx, [esp + API_PARAM1_OFFSET] 
    121   cmp    edx, 0
    122   jnz    FspStackSetup  
    123 
    124   ; Get UPD default values if FspmUpdDataPtr (ApiParam1) is null
    125   push   eax
    126   call   ASM_PFX(AsmGetFspInfoHeader)
    127   mov    edx, [eax + FSP_HEADER_IMGBASE_OFFSET]
    128   add    edx, [eax + FSP_HEADER_CFGREG_OFFSET]
    129   pop    eax
    130   
    131   FspStackSetup:
    132   mov    edi, [edx + FSPM_UPD_COMMON.StackBase]
    133   mov    ecx, [edx + FSPM_UPD_COMMON.StackSize]
    134   add    edi, ecx
    135   ;
    136   ; Setup new FSP stack
    137   ;
    138   xchg    edi, esp                                ; Exchange edi and esp, edi will be assigned to the current esp pointer and esp will be Stack base + Stack size
    139   mov     ebx, esp                                ; Put Stack base + Stack size in ebx
    140 
    141   ;
    142   ; Pass the API Idx to SecStartup
    143   ;
    144   push    eax
    145 
    146   ;
    147   ; Pass the BootLoader stack to SecStartup
    148   ;
    149   push    edi
    150 
    151   ;
    152   ; Pass entry point of the PEI core
    153   ;
    154   call    ASM_PFX(AsmGetFspBaseAddress)
    155   mov     edi, eax
    156   call    ASM_PFX(AsmGetPeiCoreOffset)
    157   add     edi, eax
    158   push    edi
    159 
    160   ;
    161   ; Pass BFV into the PEI Core
    162   ; It uses relative address to calucate the actual boot FV base
    163   ; For FSP implementation with single FV, PcdFspBootFirmwareVolumeBase and
    164   ; PcdFspAreaBaseAddress are the same. For FSP with mulitple FVs,
    165   ; they are different. The code below can handle both cases.
    166   ;
    167   call    ASM_PFX(AsmGetFspBaseAddress)
    168   push    eax
    169 
    170   ;
    171   ; Pass stack base and size into the PEI Core
    172   ;
    173   sub     ebx, ecx            ; Stack base + Stack size - Stack size
    174   push    ebx
    175   push    ecx
    176 
    177   ;
    178   ; Pass Control into the PEI Core
    179   ;
    180   call    ASM_PFX(SecStartup)
    181   add     esp, 4
    182 exit:
    183   ret
    184 
    185 global ASM_PFX(FspPeiCoreEntryOff)
    186 ASM_PFX(FspPeiCoreEntryOff):
    187    ;
    188    ; This value will be pached by the build script
    189    ;
    190    DD    0x12345678
    191 
    192 global ASM_PFX(AsmGetPeiCoreOffset)
    193 ASM_PFX(AsmGetPeiCoreOffset):
    194    mov   eax, dword [ASM_PFX(FspPeiCoreEntryOff)]
    195    ret
    196 
    197 ;----------------------------------------------------------------------------
    198 ; Module Entrypoint API
    199 ;----------------------------------------------------------------------------
    200 global ASM_PFX(_ModuleEntryPoint)
    201 ASM_PFX(_ModuleEntryPoint):
    202   jmp $
    203