什么是RISC-V?它为什么创建?它比以前的RISC架构有哪些改进?
(这是StackOverflow上RISC-V的维基.)
Berkeley的RISC-V实现称为Rocket Chip,它是用一种名为Chisel的硬件语言编写的.Chisel是面向对象的,我们团队中的人员很难学会如何有效地修改Rocket Chip代码.
我们为Chisel创造了这个学习之旅,这很棒.它来自基础知识,包括Scala的相关部分,最后是一系列来自Sodor和Rocket Chip代码的高级示例,所有这些都是动手练习:
http://learningjourney.intensivate.com
我们已经向社区开放了贡献,但似乎应该有其他好的地方来解释Rocket Chip代码中使用的高级Chisel编码实践.有人有链接吗?
RISC-V 当前软件特权级别未在任何 CSR 中设置。尽管如此,规范指出“在没有适当权限级别的情况下尝试访问 CSR...引发非法指令”。那么它如何实现(在硬件中)?
有人可以向我解释(RISC与CISC)与RISC-V ISA之间的巨大差异吗?我在互联网上找不到CISC和RISC-V之间的任何相关差异.
我目前正在致力于实现 RV32I 基本指令集。
我有一个关于 ADDI 指令的问题。手册中,如何理解这一条“ADDI rd,rs1,0用于实现MV rd,rs1汇编器伪指令”。
是否意味着ADDI rd, rs1, 0等于将rs1的内容移动到rd指定的寄存器?
最近,我正在研究RV32I基本指令集,我没有发现任何类似于LD r1,imm的指令。因此,我想知道汇编程序员如何将立即数加载到 RV32I 系统中的寄存器中?谢谢。
为此,程序员可以使用 ADDI r1、r0、imm。由于r0是常数0,所以该指令将imm移至寄存器r1。
不知道RV32的设计者是不是这样想的,用ADDI来代替LD r1,imm?
希望任何人都可以对此有所了解。谢谢。
在 RISC-V 非特权规范 V20191213 中,说明了以下内容(第 21 页)
无条件跳转指令均使用 PC 相对寻址来帮助支持位置无关代码。
查看JALR指令的定义,
间接跳转指令JALR(跳转链接寄存器)采用I型编码。通过将符号扩展的 12 位 I 立即数与寄存器 rs1 相加,然后将结果的最低有效位设置为零来获得目标地址。
这个地址计算显然与PC无关。那么,为什么规范声称所有跳转指令都使用 PC 相对寻址呢?
另外,PC 相对寻址如何支持位置无关代码?难道不应该是完全相反的吗?
assembly instruction-set cpu-architecture riscv position-independent-code
我对裸机编程非常陌生,以前从未接触过中断,但我一直在 RISC-V FE310-G002 SOC 供电的开发板上学习。
我一直在阅读有关 RISC-V WFI(等待中断)指令的内容,并且从手册中来看,听起来您不能依靠它来实际休眠核心。相反,它仅建议系统可以停止执行,并且应该将指令视为 NOP。然而,这对我来说似乎毫无用处。考虑以下 ASM 程序片段:
wfi_loop:
WFI
J wfi_loop
Run Code Online (Sandbox Code Playgroud)
由于不能依赖 WFI,因此必须执行此操作。然而,从中断处理程序中执行 MRET 后,您仍然会陷入循环中。因此,您必须使其以全局变量为条件,该全局变量的值在中断处理程序中更新。这看起来非常混乱。
此外,如果您的实现实际上遵循 WFI 指令,并且在执行 WFI 指令之前触发了中断,则整个内核将停止运行,直到触发其他中断,因为它将在 WFI 指令之前返回。
当没有工作要做时,该指令的唯一正确用法似乎是在内核调度程序内部。但即便如此,我认为您也不会想从中断处理程序返回到此类代码,而是从头开始重新启动调度程序算法。但这也会是一个问题,因为你必须以某种方式回滚堆栈,等等......
我一直在脑子里思考这个问题,但似乎无法找到安全的用途。也许,如果您以原子方式使用 CSRRS 启用中断,然后立即调用 WFI,如下所示:
CSRRSI zero, mie, 0x80
wfi_loop:
WFI
J wfi_loop
NOP
NOP
Run Code Online (Sandbox Code Playgroud)
然后确保在从中断处理程序调用 MRET 之前将 mepc 寄存器增加 8 个字节。在返回之前,还必须在中断处理程序内部的 mie 寄存器中再次禁用中断。只有当 WFI、J 和 NOP 都编码为 4 字节指令时,无论是否使用压缩指令,该解决方案才是安全的。它还取决于在 CSRRSI 指令启用后,程序计数器在可能触发中断之前到达 WFI 指令。然后,这将允许在代码中的安全位置触发中断,并以中断等待它的循环的方式返回。
我想我只是想了解我可以从硬件中获得什么行为,以及如何正确调用中断并返回并使用 WFI 指令?
对于 RISC-V,堆栈指针是否指向压入堆栈的最后一个数据,或者堆栈的下一个空闲地址位置?
当堆栈指针在程序的最开始处初始化时(例如crt.S)(即堆栈为空),堆栈指针是否应该初始化为指向第一个字将被压入的内存位置或之前的地址?(例如,假设堆栈的第一个元素将在 4092 处压入。那么,堆栈指针是从 4096 还是 4092 开始?)
指向其定义位置的指针将不胜感激。
我正在尝试使用 buildroot(busybox) 为 RISCV Arch 编译 linux。我之前使用的是 18.04 和 20.04,编译没有任何问题。现在,我已将其升级到 21.10 以构建其他一些东西。我已经移动了我的工具链,我可以使用which命令找到它。当我尝试编译 Linux 时,出现了一些在早期版本中没有遇到过的错误。
>>> host-m4 1.4.18 Building
In file included from /usr/include/signal.h:328,
from ./signal.h:52,
from c-stack.c:49:
c-stack.c:55:26: error: missing binary operator before token "("
55 | #elif HAVE_LIBSIGSEGV && SIGSTKSZ < 16384
| ^~~~~~~~
CC closein.o
c-stack.c:134:8: error: variably modified 'buffer' at file scope
134 | char buffer[SIGSTKSZ];
| ^~~~~~
CC closeout.o
Run Code Online (Sandbox Code Playgroud)
我对不同版本如何导致此错误感到困惑。
提前致谢。
riscv ×10
assembly ×4
buildroot ×1
busybox ×1
chisel ×1
interrupt ×1
isa ×1
linux-kernel ×1
riscv32 ×1
rocket-chip ×1