文章目录

  • 前言
  • 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 源码解析相关推荐

  1. 谷歌BERT预训练源码解析(二):模型构建

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/weixin_39470744/arti ...

  2. 谷歌BERT预训练源码解析(三):训练过程

    目录 前言 源码解析 主函数 自定义模型 遮蔽词预测 下一句预测 规范化数据集 前言 本部分介绍BERT训练过程,BERT模型训练过程是在自己的TPU上进行的,这部分我没做过研究所以不做深入探讨.BE ...

  3. 谷歌BERT预训练源码解析(一):训练数据生成

    目录 预训练源码结构简介 输入输出 源码解析 参数 主函数 创建训练实例 下一句预测&实例生成 随机遮蔽 输出 结果一览 预训练源码结构简介 关于BERT,简单来说,它是一个基于Transfo ...

  4. Gin源码解析和例子——中间件(middleware)

    在<Gin源码解析和例子--路由>一文中,我们已经初识中间件.本文将继续探讨这个技术.(转载请指明出于breaksoftware的csdn博客) Gin的中间件,本质是一个匿名回调函数.这 ...

  5. Colly源码解析——结合例子分析底层实现

    通过<Colly源码解析--框架>分析,我们可以知道Colly执行的主要流程.本文将结合http://go-colly.org上的例子分析一些高级设置的底层实现.(转载请指明出于break ...

  6. libev源码解析——定时器监视器和组织形式

    我们先看下定时器监视器的数据结构.(转载请指明出于breaksoftware的csdn博客) /* invoked after a specific time, repeatable (based o ...

  7. libev源码解析——定时器原理

    本文将回答<libev源码解析--I/O模型>中抛出的两个问题.(转载请指明出于breaksoftware的csdn博客) 对于问题1:为什么backend_poll函数需要指定超时?我们 ...

  8. libev源码解析——I/O模型

    在<libev源码解析--总览>一文中,我们介绍过,libev是一个基于事件的循环库.本文将介绍其和事件及循环之间的关系.(转载请指明出于breaksoftware的csdn博客) 目前i ...

  9. libev源码解析——调度策略

    在<libev源码解析--监视器(watcher)结构和组织形式>中介绍过,监视器分为[2,-2]区间5个等级的优先级.等级为2的监视器最高优,然后依次递减.不区分监视器类型和关联的文件描 ...

最新文章

  1. Golang 单例模式 singleton pattern
  2. 网络推广外包——网络推广外包指出网站优化首先考虑关键词分类
  3. C++中检查vector是否包含给定元素的几种方式
  4. zend studio 9实用快捷键大全 分享ZEND STUDIO 9的常用快捷键,高亮显示相同变量。...
  5. asp.net添加删除表格_如何用openpyxl自动化编写Excel电子表格
  6. 【Linux学习】强大的文本分析工具AWK
  7. 双十一消费近万亿!1亿人见证数字物流,“尾款人”收货更快了?购物狂欢七大趋势浮现
  8. php 伪造请求连接,phpcurl发送伪造请求
  9. BZOJ1101 洛谷3455:[POI2007]ZAP——题解
  10. ajax跨域请求 html5,HTML5中使用postMessage实现Ajax跨域请求的方法
  11. nodejs连接mysql哪个版本_nodejs连接mysql
  12. Vue-cli3 ,js根据汉字或拼音模糊搜索功能,汉字支持同音字、多音字,支持首字母
  13. PLC编程入门:梯形图
  14. 阿里、美团内部大数据资料!果然牛逼!
  15. php测试数组函数,PHP-数组函数
  16. Origin Pro 8.5绘图导出图片空白边距问题
  17. 属于计算机网络资源子网的,属于计算机网络的资源子网.pdf
  18. 学习C语言的心路历程
  19. 修改cnn梯度下降——MEO方法应用
  20. 2008欧锦赛 球员名单 C组

热门文章

  1. 基于RTT Nano的多任务嵌入式程序设计
  2. emlog程序仿小刀娱乐网模板最终版本分享
  3. 一个月面试4家,3家Offer,来看看面霸真君如何面试的
  4. latex 表格添加注释
  5. 理想?妄想?区块链的社交工具之梦
  6. 二专业论文大功告成!谨抽时间一记!
  7. 由网管平台转型智慧运维,智和信通产品全线升级
  8. 【DSY】Migration 题解
  9. 云图科技,长沙VR全景拍摄用什么设备?
  10. java 自定义异常错误编码