BIOS-CXL RcrbAccessLib 源码解析
文章目录
- 前言
- 1. RcrbAccessLib.c
- 1.1. ProgramMemBar0Register()
- 1.2. ClearMmioForCxlPort()
- 1.3. GetMemBar0()
- 2. Cxl20/Cxl20RcrbBaseLib.c
- 2.1. GetRcrbBar()
- 3. Spr/SprRcrbBaseLib.c
- 3.1. GetRcrbBar()
- 3.2. SetRcrbBar()
- 3.3. ClearRcrbBar()
前言
如果需要PDF,可以去 Github Markdown 文件 上下载 markdown 文件,自行转录。记得顺手点星收藏。
1. RcrbAccessLib.c
1.1. ProgramMemBar0Register()
- 为 CXL 端口探测和设置 64bit MEMBAR0 寄存器。有一些寄存器只能写一次,不要探测这些寄存器。此外,probed size 在 MemBar0Size 中返回。
/**Routine to probe and program the 64-bit MEMBAR0 register for CXL port.Some reg can be writen ONCE. Don't probe for such reg, instead use thehardcoded value from MemBar0Size which provided by caller. Otherwise,the probed size is returned in MemBar0Size@param[in] RcrbBaseAddr RCRB base address@param[in] BarRegOff The offset of the Bar register@param[in] MmioStartAddr The start address of available MMIO resource@param[in] Probe Probe the Membar0 size by writing FFFF?@param[out] MemBar0Base The pointer to the base address of MMIO resource allocated for MEMBAR0@param[in out] MemBar0Size The pointer to the size of MMIO resource requested by MEMBAR0@retval EFI_SUCCESS - Function return successfully.EFI_INVALID_PARAMETER - Input parameter is invalid.
**/
EFI_STATUS
EFIAPI
ProgramMemBar0Register (IN UINTN RcrbBaseAddr,IN UINT32 BarRegOff,IN UINT32 MmioStartAddr,IN BOOLEAN Probe,OUT UINT64 *MemBar0Base,IN OUT UINT64 *MemBar0Size)
{UINT32 DataBuffer, Data32;UINT64 Data64;// 检查参数if (MemBar0Base == NULL || MemBar0Size == NULL) {DEBUG ((DEBUG_ERROR, "\nInvalid input parameters!!\n"));ASSERT (FALSE);return EFI_INVALID_PARAMETER;}//// Save the original low 32bit value of MEMBAR0// MEMBAR0 低32位的值DataBuffer = MmioRead32 (RcrbBaseAddr + BarRegOff);if (Probe == TRUE) {//// Probe the MEMBAR0 size// 向寄存器写全1,得到大小MmioWrite32 (RcrbBaseAddr + BarRegOff, 0xFFFFFFFF); //Low 32 bitsMmioWrite32 (RcrbBaseAddr + BarRegOff + 4, 0xFFFFFFFF); //High 32 bitsData32 = MmioRead32 (RcrbBaseAddr + BarRegOff + 4); //Read back the high 32 bitsData64 = Data32;Data32 = MmioRead32 (RcrbBaseAddr + BarRegOff); //Read back the low 32 bitsData32 &= 0xFFFFFFF0; //Clearing the encoding information bits 0-3 for memoryData64 = LShiftU64 (Data64, 32) | Data32;// 写1可操作的位变为1,不可操作的仍然是0,所以最后一步要取反加1得出大小*MemBar0Size = ~Data64 + 1;}//// Adjust the MMIO base address to meet the alignment// 判断对齐*MemBar0Base = (MmioStartAddr + *MemBar0Size - 1) & (~(*MemBar0Size - 1));if ((UINT64) MmioStartAddr != *MemBar0Base) {DEBUG ((DEBUG_ERROR, " Warning: Created a Memory Hole: 0x%x ~ 0x%x\n", MmioStartAddr, *MemBar0Base - 1));}DEBUG ((DEBUG_ERROR, " MEMBAR0: Base = 0x%lx, Size = 0x%lx\n", *MemBar0Base, *MemBar0Size));//// Program the MEMBAR0 register// 设置 MEMBAR0 寄存器,写入原来的值Data32 = ((UINT32) (*MemBar0Base & 0xFFFFFFF0)) | (DataBuffer & 0xF);LogMmioWrite32 (RcrbBaseAddr + BarRegOff, Data32);Data32 = (UINT32) RShiftU64 (*MemBar0Base, 32);LogMmioWrite32 (RcrbBaseAddr + BarRegOff + 4, Data32);return EFI_SUCCESS;
}
1.2. ClearMmioForCxlPort()
- 常规清楚 64-bit MEMBAR0 寄存器
1.3. GetMemBar0()
- 使用 CXL RCRBBAR 寄存器得到 MEMBAR0 基地址
/**Get MEMBAR0 base address using the CXL RCRBBAR register.@param[in] SocId - Socket ID@param[in] CtrId - Controller ID@param[in] BarRegOff - The offset of the Bar register@param[in] Dp - DP or UP, default is DP@retval - The 64-bit RCRBBAR base address or 0 if failed.
**/
UINT64
EFIAPI
GetMemBar0 (IN UINT8 SocId,IN UINT8 CtrId,IN UINT32 BarRegOff,IN BOOLEAN Dp)
{UINT32 RcrbBar;UINT64 MemBar0;UINT32 MemBar0High, MemBar0Low;// DP RCRBRcrbBar = (UINT32)GetRcrbBar (SocId, CtrId, TYPE_CXL_RCRB);if (RcrbBar == 0) {return 0;}if (Dp == FALSE) {// UP RCRB, Offset 4KRcrbBar += CXL_RCRB_BAR_SIZE_PER_PORT;}// 读 MemBar0 中的地址并返回MemBar0High = MmioRead32 (RcrbBar + BarRegOff + 4);MemBar0 = MemBar0High;MemBar0Low = MmioRead32 (RcrbBar + BarRegOff);MemBar0Low &= 0xFFFFFFF0; //Clearing the encoding information bits 0-3 for memoryMemBar0 = LShiftU64 (MemBar0, 32) | MemBar0Low;return MemBar0;
}
2. Cxl20/Cxl20RcrbBaseLib.c
2.1. GetRcrbBar()
- 从 CXL RCRBBAR 寄存器得到 RCRB 基地址
/**Get RCRB base address from the CXL RCRBBAR register.@param[in] SocId Socket ID@param[in] CtrId Controller ID@param[in] CxlFlag Unused; Keep it for compatibility@retval The 64-bit RCRBBAR base address or 0 if failed.
**/
UINT64
EFIAPI
GetRcrbBar (IN UINT8 SocId,IN UINT8 CtrId,IN BOOLEAN CxlFlag)
{UINT64 RcrbBarBase;CPU_CSR_ACCESS_VAR *CpuCsrAccessVarPtr;// 使用系统函数获得CpuCsrAccessVarPtr = GetSysCpuCsrAccessVar();if (CpuCsrAccessVarPtr->Cxl1p1Rcrb[SocId][CtrId].Cxl1p1RcrbValid) {RcrbBarBase = CpuCsrAccessVarPtr->Cxl1p1Rcrb[SocId][CtrId].Cxl1p1RcrbBase;} else {RcrbBarBase = 0;}CXL_DEBUG_LOG ("\t%a (): RcrbBarBase = %x\n", __FUNCTION__, RcrbBarBase);return RcrbBarBase;
}
3. Spr/SprRcrbBaseLib.c
3.1. GetRcrbBar()
- 从 CXL RCRBBAR 寄存器得到 RCRB 基地址。接口平台相关,未找到相关资料
/**Get RCRBBAR base address from the CXL RCRBBAR register.@param[in] SocId - Socket ID@param[in] CtrId - Controller ID@param[in] CxlFlag - Indicate what type of the control, TRUE: Pcie G5 - CXL; FALSE: Pcie G4 - DMI@retval - The 64-bit RCRBBAR base address or 0 if failed.
**/
UINT64
EFIAPI
GetRcrbBar (IN UINT8 SocId,IN UINT8 CtrId,IN BOOLEAN CxlFlag)
{UINT64 RcrbBarBase;UINT32 Data32;UINT32 RcrbBarAddrLow, RcrbBarAddrHigh;CPU_CSR_ACCESS_VAR *CpuCsrAccessVarPtr;if (CxlFlag) {CpuCsrAccessVarPtr = GetSysCpuCsrAccessVar();RcrbBarBase = CpuCsrAccessVarPtr->Cxl1p1Rcrb[SocId][CtrId].Cxl1p1RcrbBase;if (CpuCsrAccessVarPtr->Cxl1p1Rcrb[SocId][CtrId].Cxl1p1RcrbValid) {return RcrbBarBase;} else {DEBUG ((DEBUG_ERROR, "\nWARNING: CXL DP RCRBBAR is 0!!\n"));return 0;}} else {if ((((BIT0 << SocId) & GetPchPresentBitMap()) == 0) || (CtrId != 0)) {DEBUG ((DEBUG_ERROR, "\nInput parameter is invalid!\n"));ASSERT (FALSE);return 0;}RcrbBarAddrLow = RCRBBAR_N0_SB_PRVT_PCIE_G4_REG;RcrbBarAddrHigh = RCRBBAR_N1_SB_PRVT_PCIE_G4_REG;}Data32 = UsraCsrRead (SocId, CtrId, RcrbBarAddrHigh);RcrbBarBase = Data32;Data32 = UsraCsrRead (SocId, CtrId, RcrbBarAddrLow);RcrbBarBase = (LShiftU64 (RcrbBarBase, 32) | (Data32 & 0xFFFFFFFE));if (RcrbBarBase == 0) {DEBUG ((DEBUG_ERROR, "\nWARNING: CXL DP RCRBBAR is 0!!\n"));}return RcrbBarBase;
}
3.2. SetRcrbBar()
- 为 CXL or PCIe 端口设置 RcrbBar
/**Set RCRBBar for CXL or PCIe Port@param SocId Socket ID@param CtrId Controller ID@param CxlFlag Indicate what type of the control, TRUE: Pcie G5 - CXL; FALSE: Pcie G4 - DMI@param BarAddr RCRB Bar Address@retval - EFI_UNSUPPORTED: the function not implemented- EFI_SUCCESS: the function is excuted successfully
**/
EFI_STATUS
EFIAPI
SetRcrbBar (IN UINT8 SocId,IN UINT8 CtrId,IN BOOLEAN CxlFlag,IN UINT32 BarAddr)
{RCRBBAR_N0_SB_PRVT_PCIE_G5_STRUCT RcrbBarCxlDpN0;RCRBBAR_N0_SB_PRVT_PCIE_G4_STRUCT RcrbBarDmiN0;CPU_CSR_ACCESS_VAR *CpuCsrAccessVarPtr;if (CxlFlag) {//// RCRB should be allocated below 4GB, so just program the N1 register to 0// RCRB 应该分配在 4G 以下UsraCsrWrite (SocId, CtrId, RCRBBAR_N1_SB_PRVT_PCIE_G5_REG, 0);//// Note:// By spec, the RcrbBar must be 8KB aligned.// - In this routine, the input BarAddr is likely to be the MmiolBase of the stack to which the CXL belongs, and// it is directly programmed to RcrbBar register, which assumes the stack's MmiolBase is at least 8KB aligned.//RcrbBarCxlDpN0.Data = 0;RcrbBarCxlDpN0.Bits.baddr = BarAddr >> 13;RcrbBarCxlDpN0.Bits.en = 1;UsraCsrWrite (SocId, CtrId, RCRBBAR_N0_SB_PRVT_PCIE_G5_REG, RcrbBarCxlDpN0.Data);CpuCsrAccessVarPtr = GetSysCpuCsrAccessVar ();CpuCsrAccessVarPtr->Cxl1p1Rcrb[SocId][CtrId].Cxl1p1RcrbBase = BarAddr;CpuCsrAccessVarPtr->Cxl1p1Rcrb[SocId][CtrId].Cxl1p1RcrbValid = TRUE;} else {if (CtrId != 0) {DEBUG ((DEBUG_ERROR, "\nInput parameter is invalid!\n"));ASSERT (FALSE);return EFI_INVALID_PARAMETER;}UsraCsrWrite (SocId, CtrId, RCRBBAR_N1_SB_PRVT_PCIE_G4_REG, 0);RcrbBarDmiN0.Data = 0;RcrbBarDmiN0.Bits.baddr = BarAddr >> 13;RcrbBarDmiN0.Bits.en = 1;UsraCsrWrite (SocId, CtrId, RCRBBAR_N0_SB_PRVT_PCIE_G4_REG, RcrbBarDmiN0.Data);}DEBUG ((DEBUG_ERROR, " %a (): RcrbBase = 0x%08X\n", __FUNCTION__, BarAddr));return EFI_SUCCESS;
}
3.3. ClearRcrbBar()
- 清除 RCRBBar
/**Clear RCRBBar for CXL or PCIe Port.@param[in] SocId - Socket ID@param[in] CtrId - Controller ID@param[in] CxlFlag - Indicate what type of the control, TRUE: Pcie G5 - CXL; FALSE: Pcie G4 - DMI@retval EFI_SUCCESS - Function completed successfully@retval EFI_INVALID_PARAMETER - Fuction failed due to input parameter wrong
**/
EFI_STATUS
EFIAPI
ClearRcrbBar (IN UINT8 SocId,IN UINT8 CtrId,IN BOOLEAN CxlFlag)
{if (CxlFlag) {UsraCsrWrite (SocId, CtrId, RCRBBAR_N1_SB_PRVT_PCIE_G5_REG, 0);UsraCsrWrite (SocId, CtrId, RCRBBAR_N0_SB_PRVT_PCIE_G5_REG, 0);} else {if ((SocId != GetSysSbspSocketIdNv ()) || (CtrId != 0)) {DEBUG ((DEBUG_ERROR, "\nInput parameter is invalid!\n"));ASSERT (FALSE);return EFI_INVALID_PARAMETER;}UsraCsrWrite (SocId, CtrId, RCRBBAR_N1_SB_PRVT_PCIE_G4_REG, 0);UsraCsrWrite (SocId, CtrId, RCRBBAR_N0_SB_PRVT_PCIE_G4_REG, 0);}return EFI_SUCCESS;
}
BIOS-CXL RcrbAccessLib 源码解析相关推荐
- 谷歌BERT预训练源码解析(二):模型构建
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/weixin_39470744/arti ...
- 谷歌BERT预训练源码解析(三):训练过程
目录 前言 源码解析 主函数 自定义模型 遮蔽词预测 下一句预测 规范化数据集 前言 本部分介绍BERT训练过程,BERT模型训练过程是在自己的TPU上进行的,这部分我没做过研究所以不做深入探讨.BE ...
- 谷歌BERT预训练源码解析(一):训练数据生成
目录 预训练源码结构简介 输入输出 源码解析 参数 主函数 创建训练实例 下一句预测&实例生成 随机遮蔽 输出 结果一览 预训练源码结构简介 关于BERT,简单来说,它是一个基于Transfo ...
- Gin源码解析和例子——中间件(middleware)
在<Gin源码解析和例子--路由>一文中,我们已经初识中间件.本文将继续探讨这个技术.(转载请指明出于breaksoftware的csdn博客) Gin的中间件,本质是一个匿名回调函数.这 ...
- Colly源码解析——结合例子分析底层实现
通过<Colly源码解析--框架>分析,我们可以知道Colly执行的主要流程.本文将结合http://go-colly.org上的例子分析一些高级设置的底层实现.(转载请指明出于break ...
- libev源码解析——定时器监视器和组织形式
我们先看下定时器监视器的数据结构.(转载请指明出于breaksoftware的csdn博客) /* invoked after a specific time, repeatable (based o ...
- libev源码解析——定时器原理
本文将回答<libev源码解析--I/O模型>中抛出的两个问题.(转载请指明出于breaksoftware的csdn博客) 对于问题1:为什么backend_poll函数需要指定超时?我们 ...
- libev源码解析——I/O模型
在<libev源码解析--总览>一文中,我们介绍过,libev是一个基于事件的循环库.本文将介绍其和事件及循环之间的关系.(转载请指明出于breaksoftware的csdn博客) 目前i ...
- libev源码解析——调度策略
在<libev源码解析--监视器(watcher)结构和组织形式>中介绍过,监视器分为[2,-2]区间5个等级的优先级.等级为2的监视器最高优,然后依次递减.不区分监视器类型和关联的文件描 ...
最新文章
- Golang 单例模式 singleton pattern
- 网络推广外包——网络推广外包指出网站优化首先考虑关键词分类
- C++中检查vector是否包含给定元素的几种方式
- zend studio 9实用快捷键大全 分享ZEND STUDIO 9的常用快捷键,高亮显示相同变量。...
- asp.net添加删除表格_如何用openpyxl自动化编写Excel电子表格
- 【Linux学习】强大的文本分析工具AWK
- 双十一消费近万亿!1亿人见证数字物流,“尾款人”收货更快了?购物狂欢七大趋势浮现
- php 伪造请求连接,phpcurl发送伪造请求
- BZOJ1101 洛谷3455:[POI2007]ZAP——题解
- ajax跨域请求 html5,HTML5中使用postMessage实现Ajax跨域请求的方法
- nodejs连接mysql哪个版本_nodejs连接mysql
- Vue-cli3 ,js根据汉字或拼音模糊搜索功能,汉字支持同音字、多音字,支持首字母
- PLC编程入门:梯形图
- 阿里、美团内部大数据资料!果然牛逼!
- php测试数组函数,PHP-数组函数
- Origin Pro 8.5绘图导出图片空白边距问题
- 属于计算机网络资源子网的,属于计算机网络的资源子网.pdf
- 学习C语言的心路历程
- 修改cnn梯度下降——MEO方法应用
- 2008欧锦赛 球员名单 C组