SEC phase


下面是摘自PI Specification . Vol 1_PEI中的描述SEC Phase的话。http://www.uefi.org/
The Security (SEC) phase is the first phase in the PI Architecture architecture and is responsible for the following:Handling all platform restart eventsCreating a temporary memory storeServing as the root of trust in the systemPassing handoff information to the PEI Foundation
In addition to the minimum architecturally required handoff information, the SEC phase can pass optional information to the PEI Foundation, such as the SEC Platform Information PPI or information about the health of the processor.
下面来看代码是怎样实现这些function。代码下载:https://github.com/tianocore/edk2

EDK2 Code:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; file: UefiCpuPkg\ResetVector\Vtf0\Ia16\ResetVectorVtf0.asm
resetVector:
;
; Reset Vector
;
; This is where the processor will begin execution
;
    nop
    nop
    jmp     EarlyBspInitReal16

ALIGN   16
fourGigabytes:     


; file: UefiCpuPkg\ResetVector\Vtf0\Ia16\Init16.asm

; 16-bit initialization code
;
; @param[out] DI    'BP' to indicate boot-strap processor
;
EarlyBspInitReal16:
    mov     di, 'BP'
    jmp     short Main16


; file: UefiCpuPkg\ResetVector\Vtf0\Main.asm
; @file
; Main routine of the pre-SEC code up through the jump into SEC
;
BITS    16
;
; Modified:  EBX, ECX, EDX, EBP
;
; @param[in,out]  RAX/EAX  Initial value of the EAX register
;                          (BIST: Built-in Self Test)
; @param[in,out]  DI       'BP': boot-strap processor, or
;                          'AP': application processor
; @param[out]     RBP/EBP  Address of Boot Firmware Volume (BFV)
;
; @return         None  This routine jumps to SEC and does not return
;
Main16:
    OneTimeCall EarlyInit16
    ;
    ; Transition the processor from 16-bit real mode to 32-bit flat mode
    ;
    OneTimeCall TransitionFromReal16To32BitFlat

BITS    32
    ;
    ; Search for the Boot Firmware Volume (BFV)
    ;
    OneTimeCall Flat32SearchForBfvBase
    ;
    ; EBP - Start of BFV
    ;
    ; Search for the SEC entry point
    ;
    OneTimeCall Flat32SearchForSecEntryPoint
    ;
    ; ESI - SEC Core entry point
    ; EBP - Start of BFV
    ;
%ifdef ARCH_IA32
    ;
    ; Restore initial EAX value into the EAX register
    ;
    mov     eax, esp
    ;
    ; Jump to the 32-bit SEC entry point
    ;
    jmp     esi

%else
    ;
    ; Transition the processor from 32-bit flat mode to 64-bit flat mode
    ;
    OneTimeCall Transition32FlatTo64Flat

BITS    64
    ;
    ; Some values were calculated in 32-bit mode.  Make sure the upper
    ; 32-bits of 64-bit registers are zero for these values.
    ;
    mov     rax, 0x00000000ffffffff
    and     rsi, rax
    and     rbp, rax
    and     rsp, rax
    ;
    ; RSI - SEC Core entry point
    ; RBP - Start of BFV
    ;
    ; Restore initial EAX value into the RAX register
    ;
    mov     rax, rsp
    ;
    ; Jump to the 64-bit SEC entry point
    ;
    jmp     rsi
%endif
接下来调用SecCore Entry Point,不同的硬件平台会有不同的实现方式,原理相似。
# Module Name:
#
#  SecEntry.S
#
# Abstract:
#
#  This is the code that begins in protected mode.
#   It will transfer the control to pei core.
#
#------------------------------------------------------------------------------------------------------------------------------------------
ASM_GLOBAL  ASM_PFX(SecStartup)
# Pcds
ASM_GLOBAL  ASM_PFX(PcdGet32 (PcdPayloadFdMemBase))
#
# SecCore Entry Point
#
# Processor is in flat protected mode
#
# @param[in]  EAX   Initial value of the EAX register (BIST: Built-in Self Test)
# @param[in]  DI    'BP': boot-strap processor, or 'AP': application processor
# @param[in]  EBP   Pointer to the start of the Boot Firmware Volume
#
# @return     None  This routine does not return
#
ASM_GLOBAL ASM_PFX(_ModuleEntryPoint)
ASM_PFX(_ModuleEntryPoint):
  #
  # Disable all the interrupts
  #
  cli
  
  #
  # Construct the temporary memory at 0x80000, length 0x10000
  #
  movl $(BASE_512KB + SIZE_64KB), %esp
  #
  # Pass BFV into the PEI Core
  #
  pushl ASM_PFX(PcdGet32 (PcdPayloadFdMemBase))
  
  #
  # Pass stack base into the PEI Core
  #
  pushl $BASE_512KB
  #
  # Pass stack size into the PEI Core
  #
  pushl $SIZE_64KB
  #
  # Pass Control into the PEI Core
  #
  call SecStartup
  
  #
  # Never return to here
  #
  jmp .
未完待续。。。。

子函数:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OneTimeCall是宏,用于模拟call指令,OneTimeCallRet 配合使用,因为在Reset Vector部分还没有RAM可用

%macro  OneTimeCall 1        
    jmp     %1
%1 %+ OneTimerCallReturn:
%endmacro

%macro  OneTimeCallRet 1
    jmp     %1 %+ OneTimerCallReturn
%endmacro

/* %macro是定义多行宏,定义一个名为OneTimeCall 的宏,接收一个参数(nasm汇编)*/
/*   %macro  宏名  参数名列表
          宏体
      %endmacro  */

OneTimeCall EarlyInit16相当于:
jmp EarlyInit16
EarlyInit16OneTimerCallReturn:    /*  需要注意的是%+可以连接字符串 */
下面依此类推
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;
; Modified:  EAX
;
; @param[in]  EAX   Initial value of the EAX register (BIST: Built-in Self Test)
; @param[out] ESP   Initial value of the EAX register (BIST: Built-in Self Test)
;
EarlyInit16:
    ;
    ; ESP -  Initial value of the EAX register (BIST: Built-in Self Test)
    ;
    mov     esp, eax
    debugInitialize
    OneTimeCallRet EarlyInit16
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; @file
; Transition from 16 bit real mode into 32 bit flat protected mode
%define SEC_DEFAULT_CR0  0x40000023
%define SEC_DEFAULT_CR4  0x640

BITS    16
;
; Modified:  EAX, EBX
;
TransitionFromReal16To32BitFlat:
    debugShowPostCode POSTCODE_16BIT_MODE
    cli           ; 0中断标志,防止有些硬件中断对程序的干扰 
    mov     bx, 0xf000
    mov     ds, bx
    mov     bx, ADDR16_OF(gdtr)             ; %define ADDR16_OF(x) (0x10000 - fourGigabytes + x) 

;A new base address must be loaded into the GDTR as part of the processor initialization process for protected-mode operation
 
o32 lgdt    [cs:bx]                                      ; lgdt   Load global descriptor table (GDT) register 
    mov     eax, SEC_DEFAULT_CR0      ; %define SEC_DEFAULT_CR0  0x40000023
    mov     cr0, eax                                     ; enter protector mode(enable bit : CD / NE / MP  / PE)
    jmp     LINEAR_CODE_SEL:dword ADDR_OF(jumpTo32BitAndLandHere)

BITS    32
jumpTo32BitAndLandHere:
    mov     eax, SEC_DEFAULT_CR4        ; %define SEC_DEFAULT_CR4  0x640
    mov     cr4, eax                                       ; enable MCE/OSFXSR/OSXMMEXCPT bit
    debugShowPostCode POSTCODE_32BIT_MODE
    ; Now we're in Protected16
    ; Set up the selectors for protected mode entry
    mov     ax, LINEAR_SEL
    mov     ds, ax
    mov     es, ax
    mov     fs, ax
    mov     gs, ax
    mov     ss, ax
    OneTimeCallRet TransitionFromReal16To32BitFlat
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; @file
; Search for the Boot Firmware Volume (BFV) base address
BITS    32
;
; Modified:  EAX, EBX
; Preserved: EDI, ESP
;
; @param[out]  EBP  Address of Boot Firmware Volume (BFV)
;
Flat32SearchForBfvBase:
    xor     eax, eax               ; clean eax

searchingForBfvHeaderLoop:
    ;
    ; We check for a firmware volume at every 4KB address in the top 16MB
    ; just below 4GB.  (Addresses at 0xffHHH000 where H is any hex digit.)
    ;
    sub     eax, 0x1000
    cmp     eax, 0xff000000
    jb      searchedForBfvHeaderButNotFound
    ;
    ; Check FFS GUID
    ;
    cmp     dword [eax + 0x10], FFS_GUID_DWORD0
    jne     searchingForBfvHeaderLoop
    cmp     dword [eax + 0x14], FFS_GUID_DWORD1
    jne     searchingForBfvHeaderLoop
    cmp     dword [eax + 0x18], FFS_GUID_DWORD2
    jne     searchingForBfvHeaderLoop
    cmp     dword [eax + 0x1c], FFS_GUID_DWORD3
    jne     searchingForBfvHeaderLoop
    ;
    ; Check FV Length
    ;
    cmp     dword [eax + 0x24], 0
    jne     searchingForBfvHeaderLoop
    mov     ebx, eax
    add     ebx, dword [eax + 0x20]
    jnz     searchingForBfvHeaderLoop
    jmp     searchedForBfvHeaderAndItWasFound
searchedForBfvHeaderButNotFound:
    ;
    ; Hang if the SEC entry point was not found
    ;
    debugShowPostCode POSTCODE_BFV_NOT_FOUND
    ;
    ; 0xbfbfbfbf in the EAX & EBP registers helps signal what failed
    ; for debugging purposes.
    ;
    mov     eax, 0xBFBFBFBF
    mov     ebp, eax
    jmp     $
searchedForBfvHeaderAndItWasFound:
    mov     ebp, eax
    debugShowPostCode POSTCODE_BFV_FOUND
    OneTimeCallRet Flat32SearchForBfvBase
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; @file
; Search for the SEC Core entry point
BITS    32
%define EFI_FV_FILETYPE_SECURITY_CORE         0x03
;
; Modified:  EAX, EBX, ECX, EDX
; Preserved: EDI, EBP, ESP
;
; @param[in]   EBP  Address of Boot Firmware Volume (BFV)
; @param[out]  ESI  SEC Core Entry Point Address
;
Flat32SearchForSecEntryPoint:
    ;
    ; Initialize EBP and ESI to 0
    ;
    xor     ebx, ebx
    mov     esi, ebx
    ;
    ; Pass over the BFV header
    ;
    mov     eax, ebp
    mov     bx, [ebp + 0x30]
    add     eax, ebx
    jc      secEntryPointWasNotFound
    jmp     searchingForFfsFileHeaderLoop
moveForwardWhileSearchingForFfsFileHeaderLoop:
    ;
    ; Make forward progress in the search
    ;
    inc     eax
    jc      secEntryPointWasNotFound
searchingForFfsFileHeaderLoop:
    test    eax, eax
    jz      secEntryPointWasNotFound
    ;
    ; Ensure 8 byte alignment
    ;
    add     eax, 7
    jc      secEntryPointWasNotFound
    and     al, 0xf8
    ;
    ; Look to see if there is an FFS file at eax
    ;
    mov     bl, [eax + 0x17]
    test    bl, 0x20
    jz      moveForwardWhileSearchingForFfsFileHeaderLoop
    mov     ecx, [eax + 0x14]
    and     ecx, 0x00ffffff
    or      ecx, ecx
    jz      moveForwardWhileSearchingForFfsFileHeaderLoop
    add     ecx, eax
    jz      jumpSinceWeFoundTheLastFfsFile
    jc      moveForwardWhileSearchingForFfsFileHeaderLoop
jumpSinceWeFoundTheLastFfsFile:
    ;
    ; There seems to be a valid file at eax
    ;
    cmp     byte [eax + 0x12], EFI_FV_FILETYPE_SECURITY_CORE ; Check File Type
    jne     readyToTryFfsFileAtEcx
fileTypeIsSecCore:
    OneTimeCall GetEntryPointOfFfsFile
    test    eax, eax
    jnz     doneSeachingForSecEntryPoint
readyToTryFfsFileAtEcx:
    ;
    ; Try the next FFS file at ECX
    ;
    mov     eax, ecx
    jmp     searchingForFfsFileHeaderLoop
secEntryPointWasNotFound:
    xor     eax, eax
doneSeachingForSecEntryPoint:
    mov     esi, eax
    test    esi, esi
    jnz     secCoreEntryPointWasFound
secCoreEntryPointWasNotFound:
    ;
    ; Hang if the SEC entry point was not found
    ;
    debugShowPostCode POSTCODE_SEC_NOT_FOUND
    jz      $
secCoreEntryPointWasFound:
    debugShowPostCode POSTCODE_SEC_FOUND
    OneTimeCallRet Flat32SearchForSecEntryPoint
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Transition from 32 bit flat protected mode into 64 bit flat protected mode

BITS    32
;
; Modified:  EAX
;
Transition32FlatTo64Flat:
    OneTimeCall SetCr3ForPageTables64
    mov     eax, cr4
    bts     eax, 5                      ; enable PAE
    mov     cr4, eax                    
    mov     ecx, 0xc0000080
    rdmsr
    bts     eax, 8                      ; set LME
    wrmsr
    mov     eax, cr0
    bts     eax, 31                     ; set PG
    mov     cr0, eax                  ; enable paging
    jmp     LINEAR_CODE64_SEL:ADDR_OF(jumpTo64BitAndLandHere)

BITS    64
jumpTo64BitAndLandHere:
    debugShowPostCode POSTCODE_64BIT_MODE
    OneTimeCallRet Transition32FlatTo64Flat
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; @file
; Sets the CR3 register for 64-bit paging
BITS    32
;
; Modified:  EAX
;
SetCr3ForPageTables64:
    ;
    ; These pages are built into the ROM image in X64/PageTables.asm
    ;
    mov     eax, ADDR_OF(TopLevelPageDirectory)
    mov     cr3, eax
    OneTimeCallRet SetCr3ForPageTables64
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值