• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

SOC/IP验证工程师

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

arm v8r中MRRC指令的详细用法

在ARMv8-R架构中,MRRC指令(Move from Coprocessor to two Registers) 是MCRR的逆操作,用于从协处理器(主要是CP15)读取64位数据到两个32位ARM寄存器。作为系统控制和性能监控的关键指令,以下是其深度解析:


⚙️ 一、指令格式与参数解析

MRRC{<cond>} p15, <opc1>, <Rt>, <Rt2>, <CRm>
  • {<cond>}:可选条件码(如EQ/NE)
  • p15:系统控制协处理器(固定CP15)
  • <opc1>:操作码1(0-15),定义操作类型
  • <Rt>:目标寄存器1,存放64位数据的低32位
  • <Rt2>:目标寄存器2,存放64位数据的高32位
  • <CRm>:源协处理器寄存器(c0-c15)

📌 关键约束:

  1. Rt和Rt2必须是相邻寄存器(如R0+R1)
  2. 禁止使用PC(R15)
  3. 仅支持特权模式执行

⚡️ 二、核心应用场景

1. 读取64位性能计数器

MRRC p15, 0, R0, R1, c14  ; 读取PMCCNTR → R0(低32位) + R1(高32位)

2. 获取内存域配置

MRRC p15, 0, R2, R3, c3   ; 读取DACR → R2(低32位) + R3(高32位)

3. TLB状态监控

MRRC p15, 0, R4, R5, c8   ; 读取TLB状态信息

4. PMU事件计数器读取

MRRC p15, 4, R6, R7, c9   ; 读取PMEVCNTRn事件计数器

🔍 三、参数组合速查表(CP15)

功能 <opc1> <CRm> 指令示例 数据流向
PMCCNTR (周期计数器) 0 c14 MRRC p15,0,R0,R1,c14 CP15 → R0(低) + R1(高)
DACR (域控制) 0 c3 MRRC p15,0,R2,R3,c3 CP15 → R2(低) + R3(高)
TLB状态 0 c8 MRRC p15,0,R4,R5,c8 CP15 → R4(低) + R5(高)
PMEVCNTRn (事件计数器) 4-7 c9 MRRC p15,4,R6,R7,c9 CP15 → R6(低) + R7(高)

💡 注:opc1值需参考具体芯片手册(如Cortex-R82 TRM)


⚠️ 四、关键使用规则

1. 寄存器配对原则

// 合法配对
MRRC p15, 0, R0, R1, c14  // R0+R1 (相邻)
MRRC p15, 0, R2, R3, c14  // R2+R3 (相邻)

// 非法配对(触发未定义指令)
MRRC p15, 0, R0, R2, c14  // 非相邻寄存器
MRRC p15, 0, R1, R2, c14  // R1+R2(未对齐)

2. 特权级保护

MRC_current_mode .req R8
; 检查当前模式
MRS MRC_current_mode, CPSR
TST MRC_current_mode, #0x1F  ; 提取模式位
BNE user_mode_error          ; 非特权模式跳转错误处理

3. 内存屏障建议

ISB                    ; 确保之前指令完成
MRRC p15, 0, R0, R1, c14 ; 读取PMCCNTR
DSB                    ; 保证后续操作使用最新值

🛠️ 五、完整示例:性能监控分析

1. 读取性能计数器

read_pmccntr:
    ISB                    ; 指令同步屏障
    MRRC p15, 0, R0, R1, c14  ; 读取PMCCNTR
    DSB                    ; 数据同步屏障
    ; R0 = 低32位, R1 = 高32位
    BX LR                  ; 返回

2. 计算代码段执行周期

start_benchmark:
    ; 重置计数器
    MCRR p15, 0, RZR, RZR, c14  ; 写入0到PMCCNTR
    ISB
    ; --- 被测代码段 ---
    BL target_function
    ; --- 结束测试 ---
    MRRC p15, 0, R2, R3, c14  ; 读取周期计数
    ; 组合64位值: R3:R2

⚠️ 六、常见错误与调试

1. 未定义指令异常

原因:

  • 用户模式执行
  • 寄存器不配对
  • 无效opc1/CRm

解决方案:

UNDEF_HANDLER:
    MRS R0, ESR_EL1        ; 读取异常原因
    TST R0, #0x3F0000      ; 检查EC字段
    BNE not_mrc_error      ; 非未定义指令跳转
    ; 修复逻辑...

2. 数据不一致

原因:

  • 遗漏ISB/DSB
  • 计数器溢出未处理

解决方案:

uint64_t safe_read_pmccntr() {
    uint32_t hi1, lo, hi2;
    do {
        asm volatile(
            "MRRC p15, 0, %0, %1, c14 \n"
            "MRRC p15, 0, %2, %1, c14 \n"  // 重读高32位
            : "=r"(lo), "=r"(hi1), "=r"(hi2)
        );
    } while (hi1 != hi2); // 检查高32位是否一致
    return ((uint64_t)hi1 << 32) | lo;
}

💎 总结

MRRC在ARMv8-R中的核心价值是精确读取64位系统状态:

  1. 性能分析:获取纳秒级执行周期(PMCCNTR)
  2. 系统诊断:监控内存域/TLB状态
  3. 实时监控:PMU事件计数器分析

最佳实践:

  1. 严格寄存器配对:使用相邻寄存器对(如R0+R1)
  2. 屏障指令:ISB前置 + DSB后置
  3. 溢出处理:循环读取验证高32位一致性
  4. 特权保护:仅在内核/特权代码使用

完整规范参考:《ARMv8-R Architecture Reference Manual》第C3章 "System Control Coprocessor"

posted on 2025-08-02 20:16  SOC验证工程师  阅读(36)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3