trying to add atomic implementations in rv32, but still buggy

master
maoyuchaxue 6 years ago
parent 49cd04dce3
commit cfda03a0f2

@ -9,7 +9,7 @@
"cpu": "generic-rv32", "cpu": "generic-rv32",
"features": "", "features": "",
"max-atomic-width": "32", "max-atomic-width": "32",
"linker": "riscv64-unknown-elf-ld", "linker": "riscv32-unknown-elf-ld",
"linker-flavor": "ld", "linker-flavor": "ld",
"pre-link-args": { "pre-link-args": {
"ld": [ "ld": [

@ -28,37 +28,51 @@ use core::ptr::{read, write};
#[no_mangle] #[no_mangle]
pub unsafe extern fn __atomic_load_1(src: *const u8) -> u8 { pub unsafe extern fn __atomic_load_1(src: *const u8) -> u8 {
read(src) let mut res: u8 = 0;
asm!("amoadd.w.rl $0, zero, ($1)" : "=r"(res) : "r"(src) : "memory" : "volatile");
res
} }
#[no_mangle] #[no_mangle]
pub unsafe extern fn __atomic_load_2(src: *const u16) -> u16 { pub unsafe extern fn __atomic_load_2(src: *const u16) -> u16 {
read(src) let mut res: u16 = 0;
asm!("amoadd.w.rl $0, zero, ($1)" : "=r"(res) : "r"(src) : "memory" : "volatile");
res
} }
#[no_mangle] #[no_mangle]
pub unsafe extern fn __atomic_load_4(src: *const u32) -> u32 { pub unsafe extern fn __atomic_load_4(src: *const u32) -> u32 {
read(src) let mut res: u32 = 0;
asm!("amoadd.w.rl $0, zero, ($1)" : "=r"(res) : "r"(src) : "memory" : "volatile");
res
} }
#[no_mangle] #[no_mangle]
pub unsafe extern fn __atomic_store_1(dst: *mut u8, val: u8) { pub unsafe extern fn __atomic_store_1(dst: *mut u8, val: u8) {
write(dst, val) asm!("amoswap.w.aq zero, $0, ($1)" :: "r"(val), "r"(dst) : "memory" : "volatile");
} }
#[no_mangle] #[no_mangle]
pub unsafe extern fn __atomic_store_4(dst: *mut u32, val: u32) { pub unsafe extern fn __atomic_store_4(dst: *mut u32, val: u32) {
write(dst, val) asm!("amoswap.w.aq zero, $0, ($1)" :: "r"(val), "r"(dst) : "memory" : "volatile");
} }
unsafe fn __atomic_compare_exchange<T: PartialEq>(dst: *mut T, expected: *mut T, desired: T) -> bool { unsafe fn __atomic_compare_exchange<T: PartialEq>(dst: *mut T, expected: *mut T, desired: T) -> bool {
use super::interrupt; // use super::interrupt;
let flags = interrupt::disable_and_store(); // let flags = interrupt::disable_and_store();
let val = read(dst); // let val = read(dst);
let success = val == read(expected); // let success = val == read(expected);
write(dst, if success {desired} else {val}); // write(dst, if success {desired} else {val});
interrupt::restore(flags); // interrupt::restore(flags);
success // success
let mut val: T;
asm!("lr.w $0, ($1)" : "=r"(val) : "r"(dst) : "memory" : "volatile");
if val == *expected {
let mut sc_ret = 0;
asm!("sc.w $0, $1, ($2)" : "=r"(sc_ret) : "r"(desired), "r"(dst) : "memory" : "volatile");
return sc_ret == 0
}
false
} }
#[no_mangle] #[no_mangle]

@ -1,5 +1,8 @@
use core::fmt; use core::fmt;
use log::{self, Level, LevelFilter, Log, Metadata, Record}; use log::{self, Level, LevelFilter, Log, Metadata, Record};
use spin::Mutex;
static log_mutex: Mutex<()> = Mutex::new(());
pub fn init() { pub fn init() {
static LOGGER: SimpleLogger = SimpleLogger; static LOGGER: SimpleLogger = SimpleLogger;
@ -38,11 +41,13 @@ macro_rules! with_color {
fn print_in_color(args: fmt::Arguments, color: Color) { fn print_in_color(args: fmt::Arguments, color: Color) {
use arch::io; use arch::io;
let mutex = log_mutex.lock();
io::putfmt(with_color!(args, color)); io::putfmt(with_color!(args, color));
} }
pub fn print(args: fmt::Arguments) { pub fn print(args: fmt::Arguments) {
use arch::io; use arch::io;
let mutex = log_mutex.lock();
io::putfmt(args); io::putfmt(args);
} }

Loading…
Cancel
Save