SecCore关键数据结构

SEC_IDT_TABLE 数据结构

typedef struct _SEC_IDT_TABLE {
  //
  // Reserved 8 bytes preceding IDT to store EFI_PEI_SERVICES**, since IDT base
  // address should be 8-byte alignment.
  // Note: For IA32, only the 4 bytes immediately preceding IDT is used to store
  // EFI_PEI_SERVICES**
  //
  UINT64            PeiService;
  UINT64            IdtTable[SEC_IDT_ENTRY_COUNT];
} SEC_IDT_TABLE;

IDT 


EFI_SEC_PEI_HAND_OFF 数据结构

       EFI_SEC_PEI_HAND_OFF 数据结构含有SEC-PEI Core 握手交接控制权时的所需信息,如临时RAM 的地址大小,栈的地址和Boot 

Firmware Volume 的地址,这些信息PEI Core 执行时都需要用到。

///
/// EFI_SEC_PEI_HAND_OFF structure holds information about
/// PEI core's operating environment, such as the size of location of
/// temporary RAM, the stack location and BFV location.
/// 
typedef struct _EFI_SEC_PEI_HAND_OFF {
  ///
  /// Size of the data structure.
  /// 
  UINT16  DataSize;

  ///
  /// Points to the first byte of the boot firmware volume,    指向 boot firmware volume 第一个字节
  /// which the PEI Dispatcher should search for 
  /// PEI modules.
  /// 
  VOID    *BootFirmwareVolumeBase;

  ///
  /// Size of the boot firmware volume, in bytes.              firmware volume 的大小,单位是byte(字节)
  /// 
  UINTN   BootFirmwareVolumeSize;

  ///
  /// Points to the first byte of the temporary RAM.           指向临时RAM的第一个字节
  /// 
  VOID    *TemporaryRamBase;

  ///
  /// Size of the temporary RAM, in bytes.                     临时RAM的大小
  /// 
  UINTN   TemporaryRamSize;

  ///
  /// Points to the first byte of the temporary RAM 
  /// available for use by the PEI Foundation. The area 
  /// described by PeiTemporaryRamBase and PeiTemporaryRamSize 
  /// must not extend outside beyond the area described by
  /// TemporaryRamBase & TemporaryRamSize. This area should not
  /// overlap with the area reported by StackBase and 
  /// StackSize.
  ///
  VOID    *PeiTemporaryRamBase;

  ///
  /// The size of the available temporary RAM available for 
  /// use by the PEI Foundation, in bytes.
  /// 
  UINTN   PeiTemporaryRamSize;

  ///
  /// Points to the first byte of the stack. 
  /// This are may be part of the memory described by 
  /// TemporaryRamBase and TemporaryRamSize 
  /// or may be an entirely separate area.
  /// 
  VOID    *StackBase;

  ///
  /// Size of the stack, in bytes.
  /// 
  UINTN   StackSize;
} EFI_SEC_PEI_HAND_OFF;


这个结构体所包含的信息,注释已经说得非常清楚了,主要就是pei core 的执行环境,RAM 的起始位置,大小,stack 的大小,起始位置。


2.4  数据结构关系图

     FindAndReportEntryPoints 函数在flash 中寻找PEI Core 并返回其入口地址


TemporaryRamMigration 函数

          TemporaryRamMigration函数把c 代码运行所需要的栈和堆从临时memory (cache as ram) 切换到常规内存(主memory), 别看Migration 这个单词逼格很高,其实质就是copy 的意思。

/**
  This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into
  permanent memory.

  @param[in] PeiServices            Pointer to the PEI Services Table.
  @param[in] TemporaryMemoryBase    Source Address in temporary memory from which the SEC or PEIM will copy the
                                Temporary RAM contents.
  @param[in] PermanentMemoryBase    Destination Address in permanent memory into which the SEC or PEIM will copy the
                                Temporary RAM contents.
  @param[in] CopySize               Amount of memory to migrate from temporary to permanent memory.

  @retval EFI_SUCCESS           The data was successfully returned.
  @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when
                                TemporaryMemoryBase > PermanentMemoryBase.

**/
EFI_STATUS
EFIAPI
SecTemporaryRamSupport (
  IN CONST EFI_PEI_SERVICES   **PeiServices,
  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
  IN UINTN                    CopySize
  )
{
  IA32_DESCRIPTOR   IdtDescriptor;
  VOID*             OldHeap;
  VOID*             NewHeap;
  VOID*             OldStack;
  VOID*             NewStack;
  UINTN             HeapSize;
  UINTN             StackSize;

  HeapSize   = CopySize * PcdGet8 (PcdFspHeapSizePercentage) / 100 ;
  StackSize  = CopySize - HeapSize;
    
  OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
  NewHeap = (VOID*)((UINTN)PermanentMemoryBase + StackSize);

  OldStack = (VOID*)((UINTN)TemporaryMemoryBase + HeapSize);
  NewStack = (VOID*)(UINTN)PermanentMemoryBase;

  //
  // Migrate Heap
  //
  CopyMem (NewHeap, OldHeap, HeapSize);

  //
  // Migrate Stack
  //
  CopyMem (NewStack, OldStack, StackSize);


  //
  // We need *not* fix the return address because currently,
  // The PeiCore is executed in flash.
  //

  //
  // Rebase IDT table in permanent memory
  //
  AsmReadIdtr (&IdtDescriptor);
  IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack;

  AsmWriteIdtr (&IdtDescriptor);

  //
  // Fixed the FSP data pointer
  //
  FspDataPointerFixUp ((UINTN)NewStack - (UINTN)OldStack);

  //
  // SecSwitchStack function must be invoked after the memory migration
  // immediatly, also we need fixup the stack change caused by new call into
  // permenent memory.
  //
  SecSwitchStack (
    (UINT32) (UINTN) OldStack,
    (UINT32) (UINTN) NewStack
    );

  return EFI_SUCCESS;
}

所谓迁移(migration) , 就是从一个地方搬到另一个地方,还有搬多少内容。即目的地,源地址,还有大小,而这个函数的三个参数刚好与这三个因素

匹配。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值