So I'm trying to use the RISC-V SBI debug console extension of OpenSBI on Qemu using inline Rust assembly, but it isn't working. I've come to learn that the issue may be because of memory placement, but I'd still like to know if my assembly is correct to narrow my troubleshooting down, even if you don't know the SBI specification, I'd appreciate knowing if my general inline assembly format is correct:
pub fn debug_console_write(text: &str) -> SBIResult {
let mut sbi_result = SBIResult::new();
unsafe {
asm!(
"li a7, 0x4442434E", // Specifies SBI extension
"li a6, 0x00", // Specifies function ID in extension
"lw a0, ({})", // Provides number of bytes in string
"lw a1, ({})", // Provides pointer to string
"li a2, 0", // Provides the high end of the pointers address which should always be 0
"ecall", // Short for "enviroment call", in this case it's a call to the sbi
in(reg) &text.len(), // Provides number of bytes in string
in(reg) &text.as_ptr(), // Provides pointer to string
lateout("a0") sbi_result.error, // Puts error value from sbi call into result struct
lateout("a1") sbi_result.value, // Puts value value from sbi call into result struct
out("a7") _, // Clobbering a7
out("a6") _, // Clobbering a6
out("a2") _, // Clobbering a2
clobber_abi("system") // Clobbering everything else that the system specifcation specifies
);
}
return sbi_result
}
Note that the error
and value
fields are both isize
.
This works:
pub fn debug_console_write(text: &str) -> SBIResult {
let mut sbi_result = SBIResult::new();
unsafe {
asm!(
"li a7, 0x4442434E", // Specifies SBI extension
"li a6, 0x00", // Specifies function ID in extension
"li a2, 0", // Provides the high end of the pointers address which should always be 0
"ecall", // Short for "enviroment call", in this case it's a call to the sbi
lateout("a0") sbi_result.error, // Puts error value from sbi call into result struct
lateout("a1") sbi_result.value, // Puts value value from sbi call into result struct
in("a0") text.len(), // Provides number of bytes in string
in("a1") text.as_ptr(), // Provides pointer to string
clobber_abi("system")
);
}
return sbi_result
}
I'm not sure if the previous one worked or not because of other issues, but I know this one does, for now at least.