如何在 RISC-V 中实现睡眠实用程序?

How to implement sleep utility in RISC-V?

我想实现 sleep 实用程序,它接收秒数作为输入并在 risc-v 处理器上运行的教育 xv6 操作系统上暂停给定秒数。

OS 已经有获取节拍数和暂停数的系统调用:https://github.com/mit-pdos/xv6-riscv/blob/riscv/kernel/sysproc.c#L56

定时器使用定时器向量初始化:https://github.com/mit-pdos/xv6-riscv/blob/riscv/kernel/kernelvec.S#L93 定时器向量使用 CLINT_MTIMECMP 函数初始化,该函数告诉定时器控制器何时唤醒下一个中断。

我不明白的是如何知道滴答之间的时间以及在 1 秒内完成了多少滴答。

编辑:“qemu timebase riscv mtime”的快速 google 找到一个 google groups chat,它指出 RDTIME 是自启动以来的纳秒,mtime 是一个模拟的 10Mhz 时钟。

我没有进行搜索来查找您需要的信息,但我想我有一些上下文信息可以帮助您找到它。我建议搜索 QEMU 文档/代码(可能来自 Github 搜索)以了解 mtimemtimecmp 是如何工作的。

在规范1的第 10.1 节(计数器 - 基本计数器和定时器)中,解释了 RDTIME psuedo-instruction 应该有一些固定的节拍率,可以根据实施 2 确定。根据特权规范 3.

中的定义,该滴答率也将共享给 mtimecmpmtime

我假设睡眠系统调用使用的滴答声与规范中的这些滴答声相同。在那种情况下,xv6 只是一个内核,不会定义有多少 ticks/second 。似乎 xv6 是在 qemu 之上 运行 制作的,因此 ticks/second 的定义应该在 qemu 代码中的某处定义并且可能被记录下来。

old wiki for QEMU-riscv 可以清楚地看出 SiFive CLINT 定义了 xv6 需要工作的特性,但我怀疑它是否指定了如何知道 tickrate。 Spike 还支持 CLINT 接口,因此在处理它的 spike 中搜索代码也可能具有指导意义。

1我参考了非特权规范的20191213版本

2

The RDTIME pseudoinstruction reads the low XLEN bits of the time CSR, which counts wall-clock real time that has passed from an arbitrary start time in the past. RDTIMEH is an RV32I-only in- struction that reads bits 63–32 of the same real-time counter. The underlying 64-bit counter should never overflow in practice. The execution environment should provide a means of determining the period of the real-time counter (seconds/tick). The period must be constant. The real-time clocks of all harts in a single user application should be synchronized to within one tick of the real-time clock. The environment should provide a means to determine the accuracy of the clock.

3

3.1.10 Machine Timer Registers (mtime and mtimecmp) Platforms provide a real-time counter, exposed as a memory-mapped machine-mode read-write register, mtime. mtime must run at constant frequency, and the platform must provide a mechanism for determining the timebase of mtime.