5 个版本 (3 个破坏性更新)
0.4.0 | 2023年2月10日 |
---|---|
0.3.1 | 2023年1月24日 |
0.3.0 | 2022年12月2日 |
0.2.0 | 2022年8月10日 |
0.1.0 | 2022年6月21日 |
#6 in #xtensa
4,996 每月下载量
8KB
52 行
Xtensa 原子模拟陷阱处理程序
用法
额外的 RUSTFLAGS
将以下 rustflags 添加到您的项目中 .cargo/config.toml
。请注意不要覆盖任何现有的设置。
rustflags = [
# enable the atomic codegen option for Xtensa
"-C", "target-feature=+s32c1i",
# tell the core library have atomics even though it's not specified in the target definition
"--cfg", 'target_has_atomic="8"',
"--cfg", 'target_has_atomic="16"',
"--cfg", 'target_has_atomic="32"',
"--cfg", 'target_has_atomic="ptr"',
]
然后在异常处理程序中调用 atomic_emulation
。
工作原理
我们为具有 s32c1i
功能的硅构建代码,然后当我们的目标尝试执行这些指令时,它抛出一个非法指令异常,此时我们可以解码指令并在软件中模拟它。
在 Xtensa ISA 中只有一个需要模拟的原子指令,即 S32C1I
。然而,比较值写入到 SCOMPARE1
(特殊寄存器编号 12)寄存器中,因此在没有此功能的硅中,它将不存在。我们需要模拟指令和寄存器才能成功进行原子模拟。
请参阅 ISA RM 的 4.3.14.2 节中的原子比较交换循环示例。
指令 | 格式 | 指令组成 |
---|---|---|
WSR | RSR | 0001_0011_0000_0000_0000_0000 |
S32C1I | RRI8 | XXXX_XXXX_1110_XXXX_XXXX_0010 |
为了模拟 WSR 指令,我们必须首先解码它并验证目标寄存器是 12,即 SCOMPARE1
寄存器。一旦确认,我们就可以使用这个 crate 的虚拟 SCOMPARE1
来存储值。
S32C1I
指令的模拟稍微复杂一些。首先,我们解码整个指令以获取以下值:
目标寄存器
- 这包含我们要交换的新值源寄存器
- 这包含当前值在内存中的地址偏移量
- 可选的偏移量,用于添加到源寄存器中的地址
我们将 源地址
+ 偏移量
取反,以找到当前值并将其与存储在我们虚拟 SCOMPARE1
寄存器中的值进行比较。如果它们相等,则将新目标值写入内存中的 源地址
+ 偏移量
。无论新值是否写入,旧值都会始终写回目标寄存器。
使用xtensa_lx_rt的方式
关于如何使用此crate与xtensa-lx-rt的示例,可以在v0.3.1中找到。
在构建调试版本时,我遇到链接错误
请按照此处的说明进行操作,并添加以下内容。
[profile.dev.package.xtensa-atomic-emulation-trap]
opt-level = 'z'