目录

  • 什么是RISC-V
  • RISC-V 发展
  • RISC-V指令集
  • RISC-V特权架构
  • RISC-V通用寄存器
  • RISC-V CSR寄存器
    • M模式CSR寄存器
    • S模式CSR寄存器
  • 总结

笔者学习RISC-V架构有一段时间了,总结了一下入门RISC-V的一些必备知识点。

什么是RISC-V

大家听过最多的处理器架构可能就是x86和ARM,x86架构主要用在PC端,ARM主要用在移动终端。学习嵌入式的小伙伴肯定都知道ARM,但是ARM是国外的,设计一款ARM架构的芯片,需要经过ARM公司的授权,同时会产生一些费用,这也带来了一个问题:假如有一天ARM公司不授权怎么办?

RISC-V架构就是为了解决这个问题的!RISC-V最早在2010年起源于加州大学伯克利分校,由于受够了现有处理器架构的复杂性和相关知识产权的限制,伯克利大学决定发明一种全新的、简单且开放免费的指令集架构。

从名字可以看出,RISC-V就是RISC的第五代指令集架构。而RISC-V目标就是“成为一种完全开放的指令集架构,可被任何学术机构或商业组织自由使用”。

RISC-V 发展

2015年成立了RISC-V基金会,这是个非营利性组织,主要为了维护和发展RISC-V。

目前RISC-V的IP供应商大部分是国内的厂商,例如sifive、阿里平头哥、Andes等等。而基于RISC-V架构设计的芯片厂商也基本是国内的。

可见,基于RISC-V架构设计的芯片,没有了像ARM需要授权等多方面的限制,可以做到自主可控。但由于RISC-V还处于发展的阶段,还有许多不完善的地方,有传言未来可能会形成x86、ARM、RISC-V三足鼎立的天下,但能够形成这个局面,还需要大家的共同努力。

RISC-V指令集

RISC-V指令集由“基本指令集 + 扩展指令集”组成。基本指令集是必选的,扩展指令集是可选的。意思就是可以根据你的实际需求,选择需要使用的指令。例如在一个项目中,如果不需要用到压缩指令,那么就不需要把压缩指令添加进来,从而做到定制化,这也是RISC-V的一大特点。

RISC-V指令集有RV32I、RV32E、RV64I、RV64E、RV64I等等,RV代表RISC-V,32/64代表32位或64位,I和E都是基本指令集,在I和E的基础上,可以添加D(双精度浮点扩展)、M(整数乘除法)、A(原子扩展)、C(压缩扩展)等扩展指令。例如,在RV64I基础上,添加原子、整数乘除法、双精度浮点、压缩指令,则该指令集称为RV64IMADC。

基本指令集和扩展指令集描述如下:

RISC-V特权架构

ARM有7种工作模式,而RISC-V也有不同的模式,这些模式在RISC-V中也被称为特权架构。

RISC-V总共有四种模式,分别是U、S、H和M模式: U模式被编码为00,S模式编码为01,H模式编码为10,M模式编码为11。Level越高,等级越高。等级越高,拥有的访问权限也更高。按照特权等级,有高到低依次为M、H、S、U。

上图中编码为10的模式是保留的,这个模式实际上就是H模式,H模式是用作虚拟化,但是目前RISC-V对虚拟化还不太完善,基本不支持。因此上图并没有将H模式标出来,而是作为保留。也正是因此,有人经常将RISC-V的模式说成三种U、S和M。

  • U模式:User,用户模式
  • S模式:Supervisor,监管者模式
  • M模式:Machine,机器模式

以RISC-V Linux为例,Linux应用程序处于U模式,Linux内核/uboot处于S模式,M模式则是OpenSBI。M模式拥有最高访问权限,Linux内核如果要访问CSR寄存器,则必须由S模式切换到M模式,由OpenSBI读取CSR寄存器,然后将数据返回给内核。

M模式是必须要选择的,RISC-V的裸机代码都运行在M模式下。

RISC-V通用寄存器

寄存器 ABI名称 说明
x0 zero 0值寄存器,硬编码为0,写入数据忽略,读取数据为0
x1 ra 用于返回地址(return address)
x2 sp 用于栈指针(stack pointer)
x3 gp 用于通用指针(global pointer)
x4 tp 用于线程指针
x5 t0 用于存放临时数据或者备用链接寄存器
x6~x7 t1~t2 用于存放临时数据寄存器
x8 s0/fp 需要保存的寄存器或者帧指针寄存器
x9 s1 需要保存寄存器
x10~x11 a0~a1 函数参数或者返回值寄存器
x12~x17 a2-a7 函数传递参数寄存器
x18~x27 s2-s11 需要保存的寄存器
x28~x31 t3~t6 用于存放临时数据寄存器

RISC-V有x0x31共32个通用寄存器,每个通用寄存器都有各自的用途,例如x2是作为sp栈指针、a0a1用来保存函数参数或返回值。x0寄存器被硬编码为了0,就是个0值寄存器。

ABI名称相当于这些通用寄存器的别名,在RISC-V汇编当中,都使用ABI名称来代表这些寄存器。

RISC-V CSR寄存器

CSR是控制状态寄存器,RISC-V中CSR寄存器,需要使用csrr、csrw、csrrw等特定指令进行访问。

RISC-V的CSR寄存器,M模式和S模式都有自己的寄存器,但是大体上相同。下面列举一些常用的CSR

M模式CSR寄存器

mstatus

状态寄存器,保存了全局中断使能状态和其他状态,例如切换模式前,保存当前模式。

mtvec

异常入口基地址寄存器。保存发生异常时需要跳转的地址。

medelegmideleg

​ medeleg是异常委托,mideleg是中断委托。例如,在M模式下发生异常或中断时,可以通过这两个寄存器,将中断/异常交给S模式或者其他模式处理。

mipmie

mie是中断使能寄存器,对需要使能的中断,在对应位使能。

mip是中断等待寄存器,表示目前正准备处理的中断。

hpm

全称Hardware Performance Monitor,硬件性能单元,用于性能计数。包括了两类寄存器:mhpmcounter和mhpmevent

  • ​ mhpmcounter:性能计数器
  • ​ mhpmevent:用于配置性能事件

mcounterenmcountinhibit

这两个也是是hpm相关的寄存器,主要用于控制hpm的使能、计数禁止。

  • ​ mcounteren:计数器使能
  • ​ mcountinhibit:禁止计数

mscratch

用于保存M模式指向hart上下文的指针,并在进入M模式的处理程序时,和用户寄存器交换。

mepc

发生中断时,当前程序的PC值,保存在mepc中,中断返回时,会从mepc读取PC值。

mcause

​ 用于保存发生中断或异常的情况,中断和异常描述如下:

1代表中断,0代表异常,每个异常/中断都有对应的编码值,通过mcause的值,可以很清楚的知道发生了什么中断或异常,特别在调试过程,mcause发挥了很大作用。

mvtal

异常值寄存器,例如发生异常时,保存出错的地址。

S模式CSR寄存器

S模式的CSR和M模式基本上是一样的,只不过将第一个字母m改为了s,例如mcause改为了scausemvtal改为了svtal。它们的功能基本相同,这里就不再赘述了。

需要注意的是,S模式除了拥有M模式相同功能的CSR外,另外还增加了一个stap寄存器。

stap寄存器主要是给MMU使用,stap寄存器保存了页表的基地址,MMU通过stap可以找到第一级页表,进而找到物理地址。stap寄存器涉及到的内容比较多,关于stap相关内容,以后会详细展开讲讲。

总结

以上就是入门RISC-V需要掌握的基本知识,主要还是一些寄存器的作用和特权架构。内容不多,比较基础,但是要真正掌握RISC-V,还需要多看一下汇编代码和裸机代码,才能深刻理解每个寄存器的作用以及不同特权架构下的区别,本文主要是RISC-V入门知识的总结。

原文链接: RISC-V 入门笔记(新手必看)

RISC-V入门笔记(新手必看!)相关推荐

  1. FFmpeg视频处理入门教程(新手必看)

    本文主要介绍了FFmpeg视频处理入门教程,它功能强大,用途广泛,是许多音频和视频格式的标准编码/解码实现,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 FFmpeg 是视频处理最常用的开源软件. ...

  2. the crew 服务器维护,飙酷车神 the crew入门指南 新手必看

    就如同我们所知道的那样,EA 极品飞车的跳票,让<飙酷车神the crew>成为了今年竞速游戏的重头戏,而飙酷车神本身又融合了无缝式衔接的沙盒玩法,与我们所熟知的一般赛车游戏略有不同.接下 ...

  3. python新手入门代码-新手必看:手把手教你入门 Python

    原标题:新手必看:手把手教你入门 Python 本文为 AI 研习社编译的技术博客,原标题 : Learning Python: From Zero to Hero 翻译 |永恒如新的日常校对 | 酱 ...

  4. python手把手入门_新手必看:手把手教你入门 Python

    首先,Python是什么?据它的创始人Guido van Rossum而言, "Python是一种高级编程语言,它的核心设计思想是代码可读性和允许程序员用几行代码来表达观点的语法." ...

  5. 新手必看:生成对抗网络的初学者入门指导

    新手必看:生成对抗网络的初学者入门指导 https://www.cnblogs.com/DicksonJYL/p/9698877.html 本文为 AI 研习社编译的技术博客,原标题 A Beginn ...

  6. 新手如何快速入门Python(菜鸟必看篇)

    学习任何一门语言都是从入门(1年左右),通过不间断练习达到熟练水准(3到5年),少数人最终能精通语言,成为执牛耳者,他们是金字塔的最顶层.虽然万事开头难,但好的开始是成功的一半,今天这篇文章就来谈谈如 ...

  7. zbrush次世代零基础新手必看入门教程第一部分:建模

    zbrush零基础新手必看入门教程.在第一部分中,将向您展示了如何建模...... 欢迎阅读zbrush零基础新手必看入门教程的第一部分.这部分将带您直接开始,并向您展示如何从头开始创建一个吸引人的角 ...

  8. zbrush零基础新手必看入门教程第三部分:构成

    zbrush零基础新手必看入门教程,在第三部分,如何构建模型并修复任何变形...... 第01步:打破对称性 在你开始构图之前,了解你想要角色的位置是很重要的,特别是如果你在讲故事.姿势将赋予你的角色 ...

  9. python新手入门总结_初学python的操作难点总结(新手必看篇)

    如下所示: 1 在cmd下 盘与盘之间的切换 直接 D或d: 就好 2 查找当前盘或者文件下面的目录 直接 dir 3 想在一个盘下进去一个文件夹,用cd空格目标文件 cd p 4 写文件的第一个字母 ...

最新文章

  1. 用Graphviz来画图 1
  2. 如何在VS2013配置CUDA,并编译生成DLL
  3. python之变量操作
  4. Alpine Linux 3.9.1 发布,面向安全的轻量级 Linux 发行版
  5. 项目感言--功能的模块化
  6. 153.复用的相关概念 154.信道共享技术有哪些?
  7. 瞬变电磁法的基本原理与TEM正演技术
  8. POJ-3621 Sightseeing Cows 最优比率环、01分数规划
  9. VK Cup 2015 - Qualification Round 1 A. Reposts(树)
  10. 你应当如何学习C++(以及编程)(rev#1)
  11. 【小技巧】【堆】【优先队列】优先队列初始化
  12. javascript-变量的命名-数据类型-注释
  13. deepin下深度终端使用ssh-agent(xshell中的xagent功能)
  14. 阶乘末尾连续零的个数
  15. 将文本写在图片上,自定义字体,自动换行,自定义行间距
  16. Python使用Telnetlib模块实现telnet远程操作
  17. u深度u盘制作与装系统教程
  18. 华为静态,动态NAT,Easy IP实验!超详细,有手就能学会
  19. jersey 过滤_jersey 过滤器
  20. Android设备指纹认证

热门文章

  1. 哔哩哔哩视屏下载的几种方法
  2. 通过blacklist来禁用驱动
  3. java中什么是接口代码详解
  4. LINUX之静态库共享库
  5. 项目03--当当网源码解读
  6. Leetcode 1235. Maximum Profit in Job Scheduling (python)
  7. 齐博x1如何调用系统自定义字段
  8. 远程入侵原装乘用车(中)
  9. 疯狂足球——Android手机游戏开发(实习报告)
  10. JavaScript诞生二十年,作者Brendan Eich自述10天内开发出JS语言