需求背景:
客户的主板有两种,一个支持PowerDelivery USB Hub(一种USB Hub,支持Type-C接头进行充电),另一个不支持PD,要用同一个BIOS支持两种版型,并且给OS汇报的信息要正确。
解决方案:
首先,EC去Detect PD是否存在,如果存在的话就会往EcRam内写一个Flag,BIOS可以在Post过程中读取Flag。然后根据Flag的变化使用InstallApci Protocol安装不同SSDT。
注意要点:
1、gEfiAcpiTableProtocolGuid
这是一个关于AcpiTable的Protocol,支持Install、Uninstall。事实上它只是在原本的AcpiTable上面追加了一个DefinitionBlock。
2、Asl code的编写要点
TableSignature,是指表的类型可以是,USB Hub的汇报本应该属于DSDT,但是一个AcpiTable里面只能有一个DSDT,如果这里还用DSDT的话,OsLoader在处理的时候会认为错误,产生蓝屏、宕机,但是DSDT本身是允许补充的,SSDT就是对DSDT的补充,所以这里的正确解决方法就是用SSDT作为TableSignature。
还有External(),这个method也需要注意,我们的Hub的层级结构是定死的,我们要列出层级结构,但是编译会报错,所以External很有用,具体参考下图
3、关于编译后的aml在FV内存放顺序的管理
在EDK2架构中,代码依赖Python对进行语言处理(主要是替换),实际上EDK2中使用的并不是纯正的C语言,而是加入了许多特殊的标识符,例如PCD、gEfiCallerIdGuid以及FFS操作时需要用到的SectionType等等,这些东西都是在Python脚本中定义的标识符,在编译之前,Python脚本会先将这些标识符处理为标准C代码,存放在Build目录里面,然后才是调用cl.exe进行编译、链接;最后所有生成的二进制文件会由Python按照FDF文件里面的顺序,拼接成一个连续的BIOS文件。
所以,基于此原理,我们可以控制编译后生成的二进制文件在BIOS Fv内排列顺序。具体就是由fdf文件内的Rules模块控制。
在FDF文件内需要对Driver做RuleOverride = RULE_NAME的特殊字符修饰。
上图是创建的Rule。
如此,就可以将两个ASL code编译生成的*.aml文件按照INF文档中include的顺序在FV内顺序排列。所以Get的时候只要根据序号寻址即可。