当前位置: 首页 > news >正文

【RISC-V CPU debug 专栏 4 -- RV CSR寄存器介绍】

文章目录

  • Overview
    • 1. CSR寄存器访问指令
    • 2. 为何CSR地址不是4字节对齐
      • (1) CSR寄存器空间是独立的地址空间
      • (2) 节省编码空间
      • (3) 对硬件实现的简化
    • 3. CSR的物理大小和对齐无关
    • 4. RISC-V 中的 GPR 寄存器及其作用
      • GPR 的详细用途
      • CSR(控制状态寄存器)与 GPR 的区别
      • GPR 和 CSR 结合使用的案例
    • 总结

Overview

思考个问题: RISC-V 64bit CSR 寄存器是如何访问的,为何地址不是4bytes 对齐?

在 RISC-V 中,CSR(控制和状态寄存器)的访问通过一组特定的指令实现,而这些寄存器的地址不是传统意义上的4字节对齐。这种设计源于架构的简化和优化考虑。以下是详细解释:

1. CSR寄存器访问指令

RISC-V 访问CSR寄存器通过以下指令实现:

  • CSRRW (Read and Write CSR):读取CSR寄存器的值并写入新值。
  • CSRRS (Read and Set CSR):读取CSR寄存器的值并设置指定位。
  • CSRRC (Read and Clear CSR):读取CSR寄存器的值并清除指定位。
    还有对应的立即数版本,如 CSRRWICSRRSICSRRCI

指令格式一般为

CSRRW rd, csr, rs1

其中:

rd 是目标寄存器。
csr 是要访问的CSR寄存器地址(12位)。
rs1 是源操作数的寄存器。

2. 为何CSR地址不是4字节对齐

CSR的地址并不与传统的内存字节对齐(如4字节或8字节),这是由RISC-V架构设计的独特性和使用场景决定的:

(1) CSR寄存器空间是独立的地址空间

CSR寄存器使用12位地址(总共支持4096个寄存器)。这些地址只是逻辑编号,而不是映射到系统中的物理内存或内存地址空间。无需遵循字节对齐的约束。

  • CSR访问采用专门的指令完成,不依赖常规的加载(LOAD)或存储(STORE)指令。

(2) 节省编码空间

RISC-V的指令集架构倾向于简化和节约编码空间。在指令格式中,csr字段固定为12位,存储CSR寄存器的地址。去掉对齐限制意味着12位地址可以覆盖所有CSR寄存器,避免浪费。

(3) 对硬件实现的简化

对CSR地址不做对齐要求能简化硬件设计。在硬件中,CSR寄存器通常实现为专门的逻辑单元,而不是存储在内存中的地址表,因此硬件不需要处理复杂的对齐逻辑。

3. CSR的物理大小和对齐无关

虽然CSR的地址可能不对齐,但RISC-V规范中明确规定CSR寄存器为XLEN位宽,即与指令集架构的位宽一致(32位或64位)。例如:

  • RV32:CSR为32位。
  • RV64:CSR为64位。

这种固定宽度确保了寄存器值的读取和写入与指令架构保持一致,不需要额外处理数据对齐。

4. RISC-V 中的 GPR 寄存器及其作用

RISC-V 指令集架构定义了一组通用寄存器(GPR, General Purpose Registers),这些寄存器的功能固定在指令集中,用于多种用途,包括存储临时变量、函数参数、返回地址等。

RISC-V 通用寄存器(GPR)概述
RISC-V 的 GPR 为 32 个,名称和编号如下:

编号名称别名作用
x0zero常量 0固定为 0,任何写入都会被忽略。
x1ra返回地址保存函数调用返回地址 (Return Address)。
x2sp堆栈指针指向堆栈的顶部,用于函数调用的堆栈管理。
x3gp全局指针通常指向全局变量区域。
x4tp线程指针保存线程局部存储的起始地址(多线程场景)。
x5-x7t0-t2临时寄存器用于临时变量存储,函数调用期间无须保存。
x8s0/fp保存寄存器用于保存值,函数调用期间需保持不变(可作为帧指针)。
x9s1保存寄存器与 s0 类似,用于保持值不变。
x10-x11a0-a1返回值/参数函数调用时传递第 1、2 个参数,或返回值。
x12-x17a2-a7参数寄存器函数调用时传递第 3 到第 8 个参数。
x18-x27s2-s11保存寄存器用于保存值,函数调用期间需保持不变。
x28-x31t3-t6临时寄存器用于临时计算,函数调用期间无须保存。

GPR 的详细用途

  1. 函数调用支持
  • 参数传递:a0a7 用于传递最多 8 个函数参数。

  • 返回值:a0a1 用于返回值。

  • 保存寄存器:s0-s11 用于保存值,在函数调用结束后保留原值(由被调用函数负责保存和恢复)。

  1. 临时数据存储
  • 临时寄存器:t0-t6 可供编译器或程序在函数内部存放临时变量。它们的值在函数调用时不要求保持一致。
  1. 控制流
  • 返回地址:rax1)用于存储跳转函数前的返回地址。

  • 堆栈指针:sp 用于支持栈帧管理(保存函数调用链等)。

  1. 操作系统和线程支持
  • 线程指针:tpx4)在多线程环境中,用于指向线程局部存储。
  1. 特殊用途
  • 零寄存器:zerox0)用于快速生成常量 0,节省指令资源。

CSR(控制状态寄存器)与 GPR 的区别

1. 功能对比

方面GPRCSR
数量32 个约 4096 个(受硬件实现限制)。
用途通用数据存储:函数参数、返回值、临时变量等存储状态信息和控制信号,例如异常状态、定时器等。
访问方式通过算术指令或内存访问指令(如 ADD、SW)。通过专用指令 CSRRW、CSRRS、CSRRC 等访问。
权限控制通常无特别权限限制某些 CSR 需要特权模式访问(如机器模式)。

2. 设计上的区别

  • 用途区别

    • GPR:用于数据操作和逻辑处理,通用且灵活,直接受用户程序或编译器控制。

    • CSR:用于硬件层面状态信息管理,涉及中断、模式切换、计时器控制等系统功能。

  • 访问效率

    • GPR:访问延迟低,直接作用于 ALU 和内存指令。

    • CSR:通过专用指令访问,可能影响性能,但提供丰富的控制功能。

  • 架构设计

    • GPR 是固定的、通用的。

    • CSR 是灵活可扩展的,不同的实现可支持特定扩展功能。

GPR 和 CSR 结合使用的案例

  1. 中断处理
  • GPR 用于保存中断发生前的工作寄存器状态。

  • CSR 存储中断原因(mcause)和异常发生的地址(mepc)。

示例代码:

# 进入中断服务
csrrw x5, mepc, x0     # 保存异常地址到 x5
csrr x6, mcause         # 获取中断原因到 x6
...
csrrw x0, mepc, x5     # 恢复异常地址
mret                   # 返回原来的运行状态
  1. 操作系统调度
  • GPR:调度程序中临时存放上下文数据。

  • CSR:存储当前运行模式(mstatus)或设置时间片中断(mtimecmp)。

总结

  • GPR 是处理器核心的数据工作寄存器 ,用于函数参数、临时数据和栈管理。

  • CSR 是控制和状态寄存器 ,用于控制芯片功能、管理中断和操作系统等高级功能。

  • GPR 是通用的、直接的;CSR 是专用的、特权的,二者共同作用,提供了高效而灵活的 RISC-V 体系结构支持。

CSR寄存器的访问和地址设计体现了RISC-V架构的核心哲学:简洁、模块化 和 高效。CSR地址不需要4字节对齐是因为它们不对应系统内存空间,而是独立的寄存器空间;这种设计节省了硬件复杂性和指令编码资源,同时满足了系统的功能需求。

相关文章:

【RISC-V CPU debug 专栏 4 -- RV CSR寄存器介绍】

文章目录 Overview1. CSR寄存器访问指令2. 为何CSR地址不是4字节对齐(1) CSR寄存器空间是独立的地址空间(2) 节省编码空间(3) 对硬件实现的简化 3. CSR的物理大小和对齐无关4. RISC-V 中的 GPR 寄存器及其作用GPR 的详细用途CSR(控制状态寄存器)与 GPR 的…...

Object.defineProperty() 完整指南

Object.defineProperty() 完整指南 1. 基本概念 Object.defineProperty() 方法允许精确地添加或修改对象的属性。默认情况下,使用此方法添加的属性是不可修改的。 1.1 基本语法 Object.defineProperty(obj, prop, descriptor)参数说明: obj: 要定义…...

postgresql函数创建

postgresql的函数创建 1.创建函数的基本语法: CREATE [OR REPLACE] FUNCTION function_name(parameter_list) RETURNS return_type AS $$ BEGIN -- 函数体 END; $$ LANGUAGE language_name;2.创建函数时传入参数示例:add_user tbl_user表 | id | username | …...

ECMAScript 变量

文章目录 前言一、ECMAScript 变量二、var 关键字1、var 声明作用域2、var 声明提升(hoist)三、let 关键字四、const 关键字🔰 总结前言 任何语言的核心所描述的都是这门语言在最基本的层面上如何工作,涉及 语法、操作符、数据类型以及内置功能,在此基础之上才可以构建复…...

CAN总线波形中最后一位电平偏高或ACK电平偏高问题分析

参考:https://zhuanlan.zhihu.com/p/689336144 有时候看到CAN总线H和L的差值波形的最后一位电平会变高很多,这是什么原因呢? 实际上这是正常的现象,最后一位是ACK位。问题描述为:CAN总线ACK电平偏高。 下面分析下原因…...

【C++】22___STL常用算法

目录 一、常用遍历算法 二、常用查找算法 2.1 find 2.2 其它查找算法 三、常用排序算法 3.1 sort 3.2 其它排序算法 四、拷贝 & 替换 4.1 copy 4.2 其它算法 五、常用的算数生成算法 5.1 accumulate 5.2 fill 六、常用集合算法 6.1 set_intersection 6…...

意静明和-十成

十成 责任(健康)、使命(事业)、信念(意义)、自律(排诱)、自修(知识)、总结(四为)、执行(一事不拖)、人情&…...

easyui textbox使用placeholder无效

easyui textbox使用placeholder无效 在easyui 的textbox控件&#xff0c;请使用data-options 设定 示例 <input type text class easyui-textbox data-options "prompt:请输入您的邮箱"/>...

flux中的缓存

1. cache&#xff0c;onBackpressureBuffer。都是缓存。cache可以将hot流的数据缓存起来。onBackpressureBuffer也是缓存&#xff0c;但是当下游消费者的处理速度比上游生产者慢时&#xff0c;上游生产的数据会被暂时存储在缓冲区中&#xff0c;防止丢失。 2. Flux.range 默认…...

代码重定位详解

文章目录 一、段的概念以及重定位的引入1.1 问题的引入1.2 段的概念1.3 重定位 二、如何实现重定位2.1 程序中含有什么&#xff1f;2.2 谁来做重定位&#xff1f;2.3 怎么做重定位和清除BSS段&#xff1f;2.4 加载地址和链接地址的区别 三、散列文件使用与分析3.1 重定位的实质…...

活动预告 | Microsoft 365 在线技术公开课:让组织针对 Microsoft Copilot 做好准备

课程介绍 通过Microsoft Learn免费参加Microsoft 365在线技术公开课&#xff0c;建立您需要的技能&#xff0c;以创造新的机会并加速您对Microsoft云技术的理解。参加我们举办的“让组织针对 Microsoft Copilot for Microsoft 365 做好准备” 在线技术公开课活动&#xff0c;学…...

从0到机器视觉工程师(一):机器视觉工业相机总结

目录 相机的作用 工业相机 工业相机的优点 工业相机的种类 工业相机知名品牌 光源与打光 打光方式 亮暗场照明 亮暗场照明的应用 亮暗场照明的区别 前向光漫射照明 背光照明 背光照明的原理 背光照明的应用 同轴光照明 同轴光照明的应用 总结 相机的作用 相机…...

Docker安装(Docker Engine安装)

一、Docker Engine和Desktop区别 Docker Engine 核心组件&#xff1a;Docker Engine是Docker的核心运行时引擎&#xff0c;负责构建、运行和管理容器。它包括守护进程&#xff08;dockerd&#xff09;、API和命令行工具客户端&#xff08;docker&#xff09;。适用环境&#…...

数组的深度监听deep

场景&#xff1a;组件提供的emit事件可能被占用&#xff0c;在不能使用事件提交的情况下&#xff0c;就要上watch数组监听了&#xff0c;但是是发现只有在数组的长度发生变化的时候才会触发监听&#xff0c;这怎么行。。。。。 对于对象数组的深度监听&#xff0c;如果没有正确…...

点击锁定按钮,锁定按钮要变成解锁按钮,然后状态要从待绑定变成 已锁定(升级版)

文章目录 1、updateInviteCodeStatus2、handleLock3、InviteCodeController4、InviteCodeService5、CrudRepository 点击锁定按钮&#xff0c;锁定按钮要变成解锁按钮&#xff0c;然后状态要从待绑定变成 已锁定&#xff1a;https://blog.csdn.net/m0_65152767/article/details…...

UniApp 性能优化策略

一、引言 在当今数字化时代&#xff0c;移动应用的性能成为影响用户留存与满意度的关键因素。UniApp 作为一款热门的跨平台开发框架&#xff0c;以一套代码适配多端的特性极大提升了开发效率&#xff0c;但同时也面临着性能优化的挑战。优化 UniApp 性能&#xff0c;不仅能够让…...

【Linux报告】实训六 重置超级用户密码

实训六 重置超级用户密码 2018编写-今日公布 【练习一】忘记root密码 步骤一&#xff1a;开启或重启系统&#xff0c;并且要在五秒之内按任何键&#xff1b; 步骤二&#xff1a;按任意键&#xff0c;停止进入系统&#xff0c;按【e】键&#xff0c;跳转新页面&#xff0c;再…...

smolagents:一个用于构建代理的简单库

HF推出 smolagents&#xff0c;一个非常简单的库&#xff0c;它能够解锁语言模型的代理功能。以下是它的简要介绍&#xff1a; from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModelagent CodeAgent(tools[DuckDuckGoSearchTool()], modelHfApiModel())agent…...

通过Dockerfile来实现项目可以指定读取不同环境的yml包

通过Dockerfile来实现项目可以指定读取不同环境的yml包 1. 挂载目录2. DockerFile3. 运行脚本deploy.sh4. 运行查看日志进入容器 5. 接口测试修改application-dev.yml 6. 优化Dockerfile7. 部分参数解释8. 优化不同环境下的日志也不同调整 Dockerfile修改部署脚本 deploy.sh重新…...

云手机 —— 手机矩阵的 “超级外挂

如何打造手机矩阵 打造手机矩阵主要包括以下几个步骤: 1.确定目标与需求:首先&#xff0c;明确打造手机矩阵的目的和需求&#xff0c;是为了进行电商运营、自媒体推广、任务管理还是其他目的。这将决定后续的手机数量、操作系统选择以及应用安装等。 2.选择手机与操作系统:根据…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)

题目 做法 启动靶机&#xff0c;点进去 点进去 查看URL&#xff0c;有 ?fileflag.php说明存在文件包含&#xff0c;原理是php://filter 协议 当它与包含函数结合时&#xff0c;php://filter流会被当作php文件执行。 用php://filter加编码&#xff0c;能让PHP把文件内容…...

【Linux】自动化构建-Make/Makefile

前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具&#xff1a;make/makfile 1.背景 在一个工程中源文件不计其数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;mak…...

在 Spring Boot 项目里,MYSQL中json类型字段使用

前言&#xff1a; 因为程序特殊需求导致&#xff0c;需要mysql数据库存储json类型数据&#xff0c;因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...