PCD

  • PCD Overview
    • PCD TYPES
    • PCD LIBRARY
  • PCD instrument
    • FixAtBuild PCD SYNTAX
    • PCD SOFTWARE
    • Fixed PCD AutoGen Code
    • DYNAMIC PCD
  • Special PCD

PCD Overview

PCD的主要目的就是把代码里面的可配置选项抽取出来,抽取出来的好处是倘若平台真的需要一些配置的时候,不需要修改源码,通过修改dsc把这些东西影响到,是最好的。这个PCD不止是要在编译过程中可以配置,还可以在运行时配置。

配置PCD有几种方式,目的是让platform时候更为容易进行定制化,减少effect
1:在build time时候,通过编译选项或者dsc的值进行设置从而影响源码;
2:在Boot过程中,通过某个Driver生成某种状态更改PCD的某些值;
3:作为BIOS,release出来的binary image也要提供可配置性。

PCD数据库保存所有动态类型的PCD信息。 PEI PCD数据库的结构是由构建工具根据指定平台的动态PCD使用情况生成的。 动态PCD,主要用作boot过程中相互进行交互沟通的一种方式,初始值肯定也是在build时候就设置好了。动态类型PCD用于动态确定值的配置/设置。 相反,静态类型PCD (FeatureFlag, FixedPcd, PatchablePcd)的值在构建时固定在最终生成的FD映像中。

PCD TYPES

FixedAtBuild PCD:值是在build time 时候就定好了的,在binary阶段是不可以改的,整个boot level也是不可以改的,可以认为就是一个宏,const 全局变量。这个PCD有一个好处,是一个module level的,非系统级别的,即是说不同模块可以配置不同PCD的值,典型的例子就是DEBUG Message 是否要输出Message的问题,这是由一个PCD来control的,由于是模块级别的,所以可以控制一个模块输出一个模块不输出。

FeatureFlag(control feature Boolean类型) 和FixAtBuild 是一类,可以认为是BOOLEAN类型的FixedAtBuild,只是支持静态build time的设置,而且是module level的。

PatchableInModule:module level,它可以patch(binary level 的patch),在boot time 也可以修改,但是能影响的也只是一个模块,一个Driver,在这个模块的修改不会影响到其他模块,相当于一个inf文件的source范围,但是和FixAtBuild不同的是,这只是一个全局变量,并不是const类型的,binary level可以修改的。

Dynamic/DynamicEx:动态的PCD,在整个boot过程中,有人set有人read,是可以一直修改的,作用域是system,system level,意思就是在整个BIOS,所有的模块访问Dynamic的PCD,都是共享的同一个值,某模块的修改会导致其他模块获取到的值也发生变化。Dynamic 又有三个子类:DynamicHII、DynamicVpd、DynamicEx

Dynamic与DynamicEx的区别:如果只是做source 的build就是说platform是从源码build出来的,没有binary在里面的时候,PCD用的都是Dynamic这种类型,如果在BIOS里面有一些模块是binary方式集成进来的而这些binary又需要用到PCD,那么这些Binary集成的要用到的PCD就必须要设置为Dynamic类型,这就是Dynamic与DynamicEx之间的区别。

Dynamic:PCD的值可以认为存在于hob或者memory中,会导致在下次启动时丢失上一次的值,获取到的是新define的值。

DynamicHII的关于PCD的值存在于EFI Variable中,可能对应的是一个NV的,non-volatile 的,即在某次PCD的值发生set之后,下次启动仍然是本次set的值。

DynamicVpd是属于另一种,ReadOnly,这个PCD的值存在VPD空间的,VPD是放在FLASH上的只读的,通常来说是一些系统的Default Section,工厂出厂的一些配置存放在这里,属于必不会被修改的。

PCD LIBRARY

为了方便code的编写,对PCD的使用引入PCDlib,这里面包含了常用的PCD接口,故而不用去可以学习内部实现是调用PPI 、Protocol或是直接映射,这些都被LIb隐藏了,所以在使用过程中,只需要关注PCD Protocol 和PCD PPI FUNCTION:PcdGetXX()、PcdSetXX()、 PcdGetExXX()、 PcdSetEx()、 PcdToken()、 PcdSetSku()、 PcdGetNextToken() 、PcdGetNextTokenSpace()、 CallBackOnSet() 、CancelCallBack() 。【“XX" = 8 16 32 Size Ptr Boolean】

PCDgetXX()和PCDSetXX()是用得最多的,属于统一化的API接口,无论哪一种Type都可以使用这两个,使用时会根据你具体Type类型,把这个Function map in到具体的PCDType所对应的值的上面。

PCD instrument

FixAtBuild PCD SYNTAX

Define : PCD 在.DEC文件中进行声明,就涉及到了Package,所以说PCD是一个Package的interface,就是说PCD是Package对外提供的接口之一。在定义过程中有两个需要注意的information,TokenSpaceGuid(PCD GUID说明到底在哪个Space 空间里)和TokenName(PCD 名字),这两个决定了PCD的唯一性,不可以重复,也不可以轻易改变。

Value为Default Value,Datum Type描述的是数据类型 UINT 8 16 等,倘若是VOID * 还得在[MaxSize]中填入这块Buffer的最大值128 256等,最后一个为Token number UINT32的。

[Guids.common]
PcdTokenSpaceGuidName = { 0xXXXXXXXX, 0xXXXX, 0xXXXX, { 0xXX, . . .}}
. . .
[Pcds...]
PcdTokenSpaceGuidName.PcdTokenName|Value[|DatumType[|MaxSize]]|Token

Reference:PCD在.inf文件中进行使用。在inf里一般来说有个Pcd Section,只要把这个PCD列上去就行了,通常也不会写值

[…Pcd…]
PcdTokenSpaceGuidName.PcdTokenName|[Value]

Modify:PCD在.DSC文件中进行配置,在这里会决定PCD的值和类型,若PCD在.DEC文件中进行了定义,在inf文件中使用,但在DSC中并没有重新set,这时候PCD就会使用默认值(.DEC的Value),类型则是支持的最初的类型,类型也是有一个优先级,优先考虑FixAtBuild,其次PatchInModule,然后Dynamic,DynamicEx。

[Pcds...]
PcdTokenSpaceGuidName.PcdTokenName|Value[|DatumType[|MaximumDatumSize]]

For Example:

Defined:(.dec)
[PcdsFixedAtBuild, PcdsPatchableInModule]->支持的两种类型
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x400|UINT32|0x30000003Referenced:(.inf)
MdeModulePkg\Universal\Variable\RuntimeDxe\VariableRuntimeDxe.inf
[Pcd]gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize  ## CONSUMESModified:(.dsc)
[PcdsFixedAtBuild]
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x00840 ->将0x400改为0x8400Use:(.c)
MdeModulePkg\Universal\Variable\RuntimeDxe\VariableNonVolatile.c // max NV variable size
mVariableModuleGlobal->MaxVariableSize = PcdGet32 (PcdMaxVariableSize)->UINT32 使用PcdGet32()

PCD SOFTWARE

PCD起作用并不是简简单单通过上述步骤就可以实现的, 在文件中描述完毕后通过Parsing Tool(实际就是Build Tool)进行parse,生成对应的AutoGen code,在code里面可以以PCD类型生成不同的PCD原型,然后被PCD Lib里的PCDGet32()、PCDGet16()等不同的function进行引用,而Driver Source Code里面,调用函数所用到的就是AutoGen中通过Build Tool生成的值,或是访问的方法。

关于动态的PCD,通过 build后parse,拿到所有的动态PCD,然后生成到Database里面,Compiler到一起,最后生成Driver Binary。存储在PE32 space,通过隔离Database,使得PCD的值可以进行修改替换,达到动态目的。

Fixed PCD AutoGen Code

For Example:
Example : MdeModulePkg\Universal\Variable\RuntimeDxe\VariableRuntimeDxe
Autogen.h

#define _PCD_TOKEN_PcdMaxVariableSize 250U
#define _PCD_SIZE_PcdMaxVariableSize 4
#define _PCD_GET_MODE_SIZE_PcdMaxVariableSize _PCD_SIZE_PcdMaxVariableSize
#define _PCD_VALUE_PcdMaxVariableSize 0x8400U --->在PCD SYNTAX举的例子,通过build生成的宏
extern const UINT32 _gPcd_FixedAtBuild_PcdMaxVariableSize;
#define _PCD_GET_MODE_32_PcdMaxVariableSize _gPcd_FixedAtBuild_PcdMaxVariableSize

Autogen.c

// Definition of PCDs used in this module
• • •
GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPcd_FixedAtBuild_PcdMaxVariableSize =
_PCD_VALUE_PcdMaxVariableSize;--->生成的GLobal Variable呼应.h中的宏

DYNAMIC PCD

For Example:

Defined:(.dec)
[PcdsDynamic]->支持类型
gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|0xffff|UINT16|0x30000001Modified:(.dsc)
[PcdsDynamicDefault]->在Dynamic Default这种Section下
gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|03Setting:(.c)
OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
PcdStatus = PcdSet16S (PcdPlatformBootTimeOut,GetFrontPageTimeoutFromQemu ());Use:(.c)
OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c
Timeout = PcdGet16 (PcdPlatformBootTimeOut);

Example Module: (OvmfPkg\Library\PlatformBootManagerLib)

Autogen.h
• • •
#define _PCD_SET_MODE_16_PcdPlatformBootTimeOut(Value)  LibPcdSet16(_PCD_TOKEN_PcdPlatformBootTimeOut, ( Value ))
#define _PCD_SET_MODE_16_S_PcdPlatformBootTimeOut(Value)  LibPcdSet16S(_PCD_TOKEN_PcdPlatformBootTimeOut, ( Value ))
DYNAMIC PCD AUTOGEN FILES

Autogen.c:Example Module: (MdeModulePkg/Universal/PCD/Dxe/Pcd)

DXE_PCD_DATABASE_INIT gDXEPcdDbInit = {
• • •
/* LocalTokenNumberTable */
• • •
offsetof(DXE_PCD_DATABASE, Init.PcdPlatformBootTimeOut_*1) | PCD_TYPE_DATA | PCD_DATUM_TYPE_UINT16,
• • •
{ 0x3U } /* PcdPlatformBootTimeOut_*1 { 0x3U } [1] */*1 GUID of PCD Variable PcdPlatformBootTimeOut

Special PCD

PCD的高级用法,确实能解决platform porting1过程中的一些问题,但相对来说比较复杂,所以并没有大范围推广。

Multi-Structure PCD:C data structure and assign the value to each sub-field directly

这个PCD解决的问题是当一个PCD和一个EFI Variable进行关联的时候,通常一个EFI Variable里面是一个C的Structure,就有可能关联到这个C Structure的某一个field,这时候就需要知道这个Struct的offset在哪里,这个对于维护和开发会带来难度,由于并不知道Struct的offset是多少,且当Struct改动之后关于PCD 的dsc也要进行修改,倘若有很多field需要使用,则需要定义更多的PCD,加大code的复杂度,故而引入MUlti—Structure PCD。本身而言,只是一个VOID * 的PCD,这个PCD mapping 到一个Structure,以后访问该PCD就相当于访问Structure,访问Structure中的每个field就相当于访问PCD然后通过PCD引用相应的field。

为了更容易使用Structure PCD,需要DSC能够支持对每个field的赋值,在C code能直接引用PCD,然后再把PCD mapping成一个structure,按照structure layout去访问每个field,总的来说,为了使单个域在dsc里面能够赋值,而且整个PCD在DSC里面也能赋值,这样就把所有的Structure赋值挪到DSC里面,就不需要在C source里面做。同时即便Structure修改了 DSC也不需要做任何改动,

Multi-Sku PCD:Multiple configurations generated at build time & set @ run time, (PI Spec Vol 3 chap. 8)

倘若有一个很大的Structure,如Platform 的setup的structure,这个Structure可能在一个平台有不同版本的board,每个board里面可能有一些细微的差别,可能会导致这个Setup的structure可能有些不同,这种情况下按照原来的配置方法可能要创建好几个DSC,每个DSC里面对PCD设置不同的值,相对来说比较复杂。那么这个PCD相当于有一个base,根据board的差异继承base数据然后只改差异的地方,支撑整个Structure。

DefaultStoresPCD:Support the default stores concept in UEFI specification, (UEFI, HII Chap. 32)

HII在启动起来之后有Reset to default等选项,用户可能在对setup选项进行修改之后,发现系统出现了各种各样的问题,这时候可能需要恢复到初始状态,选择reset to default标准的,相当于重置设置,另外一种manufaction default,相当于恢复出厂设置,那么这个值用StructPCD描述出来,根据对象为标准default还是manu default写入DSC里面,倘若需要使用,则进行配置使用即可。

For Example:声明一个structurePCD然后对每个Field进行赋值,Structure为:SMBIOS_TABLE_TYPE0。

gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType0BiosInformation| \{0x0}|SMBIOS_TABLE_TYPE0|0x80010000 {<HeaderFiles>IndustryStandard/SmBios.h
<Packages>MdePkg/MdePkg.decAdvancedFeaturePkg/AdvancedFeaturePkg.dec
}gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType0BiosInformation.Vendor|0x1
gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType0BiosInformation.BiosVersion|0x2
gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType0BiosInformation.BiosSegment|0xF000
gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType0BiosInformation.BiosReleaseDate|0x3
gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType0BiosInformation.BiosSize|0xFF
gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType0BiosInformation.BiosCharacteristics.\
PciIsSupported|1
gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType0BiosInformation.BiosCharacteristics.\
PlugAndPlayIsSupported|1

BIOS知识枝桠——PCD相关推荐

  1. BIOS知识枝桠——GPU

    GPU理论阐述 概念 功能 供应商 NVIDIA GPU 名称解读 显存 GPU/显卡信息查看.鉴别工具 显示接口 GPU通用计算编程 科普类文章,无实际技术相关,内容来源网络 概念 图形处理器(英语 ...

  2. BIOS知识枝桠—— Library

    Library overview Lib Overview Lib的文件结构 库的实体: 库的头文件: 库的Dec文件: 库函数的调用: MdePkg 常用Lib PUBLIC DEFINITIONS ...

  3. BIOS知识枝桠——FV

    FV 基本概念 架构组成 File Type&Section Type FV的访问 FV拓展 EFI IMAGE (PE/COFF) FV拓展 EFI OPTIONROM 基本概念 FD:固件 ...

  4. BIOS知识枝桠——Event

    Event 传统的中断模式 硬件中断 软件中断 Event Overview Event Function Event Use TPL Timer UEFI不再为开发者提供中断支持,但在UEFI内部还 ...

  5. BIOS知识枝桠——文件系统

    硬盘与文件系统 硬盘物理结构 MBR分区 GPU分区 FAT ROM Layout 硬盘物理结构 以一个机械硬盘为例,内部包括磁片.主轴.速写磁头.传动手臂.传动轴.反力矩弹簧装置,SSD没有这样的结 ...

  6. BIOS知识枝桠 -- PCIE

    博客内容来源为网络下载ppt,侵删 PCI的发展 PCI Local Bus 示意图 NoteBook上常见的PCIE Device:SSD DGPU WLAN LAN CardReader. 通过总 ...

  7. BIOS知识枝桠——SCI SMI IRQ

    SCI SMI 中断 中断分析 SCI SMI SMM SCI和SMI的异同 特殊的GPE: Q event SMI的几种常见的注册 SWSMI的触发 常见SMI的应用 中断 中断: 指当出现需要时, ...

  8. BIOS知识枝桠——Device Path

    EFI Device Path 定义&原型 文本表示形式 EFI Device Path种类 Hardware Device Path ACPI Device Path Messaging D ...

  9. BIOS知识枝桠——ACPI

    ACPI在BIOS中的应用 ACPI Overview Power State ACPI Table XSDT FADT ASL Code 变量和运算 函数 ACPI Overview 完全解读:Ad ...

  10. BIOS知识枝桠——HII

    HII Database HII OverView HII Protocol HII OverView HII(Human Interface Infrastructure), 定义了一套管理用户输入 ...

最新文章

  1. linux怎么允许远程root登录
  2. centOS 7 安装man中文版手册
  3. 以为是行废代码,原来有这作用!
  4. python使用界面-如何使用Python建立有窗口、按钮之类的图形界面
  5. hdu 5273(递推)
  6. SQLServer文件收缩-图形化+命令
  7. ajax核心技术1---XMLHttpRequset对象的使用
  8. MySQL高级知识(四)——Explain
  9. Lucene.Net的中文分词组件AdvancedChineseAnalyzer
  10. go tour - Go 入门实验教程
  11. [SCOI2016]背单词
  12. 中国计算机设计大赛作品(附代码与设计书,答辩PPT)
  13. 解决 SysFader:iexplore.exe应用程序错误
  14. 河北省谷歌高清卫星地图下载
  15. 高德地图js API实现多点标记marker,多点marker移除和鼠标滑入标点显示提示框
  16. 去加拿大跟Bengio读硕vs斯坦福全奖ML博士,选哪个?
  17. 2006年9月15日
  18. zip() 和zip(*)
  19. 一文搞定驱动签名流程(Win10)
  20. 超详细!一文讲透机器视觉常用的 3 种“目标识别”方法

热门文章

  1. JSP+实验室设备管理 毕业设计-附源码191409
  2. 计算机专业志愿者活动策划书模板,青春益起来之电脑义诊活动策划书
  3. php博客平台 开源,PHP开源博客Blog - PHP开源网(PHP-OPEN.ORG)
  4. burp小技巧之抓单个网站包
  5. 百善孝为先,万恶淫为首
  6. AM437X系列编译环境搭建
  7. h5唤起App两种方式 Schema Universal Link
  8. Opencv相机校准之棋盘格标定
  9. 35岁腾讯员工被裁员感叹:北京一套房,存款700多万,失业好焦虑
  10. Incorrect string value: '\\xE6\\xBF\\x80\\xE5\\x85\\x89...' for column 'rukuName' at row 1 QMYSQL: