From 3652547073f8ee918d345e29c21f718bac270429 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Sat, 22 Dec 2018 09:10:20 +0100 Subject: [PATCH 1/6] Simplify #[cfg()] predicate expressions --- build.rs | 13 +++++++++++++ src/asm.rs | 8 ++++---- src/interrupt.rs | 8 ++++---- src/register/macros.rs | 20 ++++++++++---------- src/register/satp.rs | 24 ++++++++++++------------ src/register/sstatus.rs | 4 ++-- 6 files changed, 45 insertions(+), 32 deletions(-) create mode 100644 build.rs diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..30db72e --- /dev/null +++ b/build.rs @@ -0,0 +1,13 @@ +use std::env; + +fn main() { + let target = env::var("TARGET").unwrap(); + + if target.starts_with("riscv32") { + println!("cargo:rustc-cfg=riscv"); + println!("cargo:rustc-cfg=riscv32"); + } else if target.starts_with("riscv64") { + println!("cargo:rustc-cfg=riscv"); + println!("cargo:rustc-cfg=riscv64"); + } +} diff --git a/src/asm.rs b/src/asm.rs index 0e22238..389146d 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -5,9 +5,9 @@ macro_rules! instruction { #[inline] pub unsafe fn $fnname() { match () { - #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] + #[cfg(riscv)] () => asm!($asm :::: "volatile"), - #[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))] + #[cfg(not(riscv))] () => unimplemented!(), } } @@ -22,11 +22,11 @@ instruction!(sfence_vma_all, "sfence.vma"); #[inline] -#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] +#[cfg(riscv)] pub unsafe fn sfence_vma(asid: usize, addr: usize) { asm!("sfence.vma $0, $1" :: "r"(asid), "r"(addr) :: "volatile"); } #[inline] -#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))] +#[cfg(not(riscv))] pub fn sfence_vma(_asid: usize, _addr: usize) {} diff --git a/src/interrupt.rs b/src/interrupt.rs index 06980cb..b569e11 100644 --- a/src/interrupt.rs +++ b/src/interrupt.rs @@ -8,9 +8,9 @@ use register::mstatus; #[inline] pub unsafe fn disable() { match () { - #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] + #[cfg(riscv)] () => mstatus::clear_mie(), - #[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))] + #[cfg(not(riscv))] () => unimplemented!(), } } @@ -23,9 +23,9 @@ pub unsafe fn disable() { #[inline] pub unsafe fn enable() { match () { - #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] + #[cfg(riscv)] () => mstatus::set_mie(), - #[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))] + #[cfg(not(riscv))] () => unimplemented!(), } } diff --git a/src/register/macros.rs b/src/register/macros.rs index a922443..ec0e1e1 100644 --- a/src/register/macros.rs +++ b/src/register/macros.rs @@ -2,7 +2,7 @@ macro_rules! read_csr { ($csr_number:expr) => { /// Reads the CSR #[inline] - #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] + #[cfg(riscv)] unsafe fn _read() -> usize { let r: usize; asm!("csrrs $0, $1, x0" : "=r"(r) : "i"($csr_number) :: "volatile"); @@ -10,7 +10,7 @@ macro_rules! read_csr { } #[inline] - #[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))] + #[cfg(not(riscv))] unsafe fn _read() -> usize { unimplemented!() } @@ -21,7 +21,7 @@ macro_rules! read_csr_rv32 { ($csr_number:expr) => { /// Reads the CSR #[inline] - #[cfg(target_arch = "riscv32")] + #[cfg(riscv32)] unsafe fn _read() -> usize { let r: usize; asm!("csrrs $0, $1, x0" : "=r"(r) : "i"($csr_number) :: "volatile"); @@ -29,7 +29,7 @@ macro_rules! read_csr_rv32 { } #[inline] - #[cfg(not(target_arch = "riscv32"))] + #[cfg(not(riscv32))] unsafe fn _read() -> usize { unimplemented!() } @@ -76,13 +76,13 @@ macro_rules! write_csr { ($csr_number:expr) => { /// Writes the CSR #[inline] - #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] + #[cfg(riscv)] unsafe fn _write(bits: usize) { asm!("csrrw x0, $1, $0" :: "r"(bits), "i"($csr_number) :: "volatile"); } #[inline] - #[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))] + #[cfg(not(riscv))] unsafe fn _write(_bits: usize) { unimplemented!() } @@ -105,13 +105,13 @@ macro_rules! set { ($csr_number:expr) => { /// Set the CSR #[inline] - #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] + #[cfg(riscv)] unsafe fn _set(bits: usize) { asm!("csrrs x0, $1, $0" :: "r"(bits), "i"($csr_number) :: "volatile"); } #[inline] - #[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))] + #[cfg(not(riscv))] unsafe fn _set(_bits: usize) { unimplemented!() } @@ -122,13 +122,13 @@ macro_rules! clear { ($csr_number:expr) => { /// Clear the CSR #[inline] - #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] + #[cfg(riscv)] unsafe fn _clear(bits: usize) { asm!("csrrc x0, $1, $0" :: "r"(bits), "i"($csr_number) :: "volatile"); } #[inline] - #[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))] + #[cfg(not(riscv))] unsafe fn _clear(_bits: usize) { unimplemented!() } diff --git a/src/register/satp.rs b/src/register/satp.rs index 37c50fe..2f00334 100644 --- a/src/register/satp.rs +++ b/src/register/satp.rs @@ -1,6 +1,6 @@ //! satp register -#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] +#[cfg(riscv)] use bit_field::BitField; /// satp register @@ -18,7 +18,7 @@ impl Satp { /// Current address-translation scheme #[inline] - #[cfg(target_arch = "riscv32")] + #[cfg(riscv32)] pub fn mode(&self) -> Mode { match self.bits.get_bit(31) { false => Mode::Bare, @@ -28,7 +28,7 @@ impl Satp { /// Current address-translation scheme #[inline] - #[cfg(target_arch = "riscv64")] + #[cfg(riscv64)] pub fn mode(&self) -> Mode { match self.bits.get_bits(60..64) { 0 => Mode::Bare, @@ -42,40 +42,40 @@ impl Satp { /// Address space identifier #[inline] - #[cfg(target_arch = "riscv32")] + #[cfg(riscv32)] pub fn asid(&self) -> usize { self.bits.get_bits(22..31) } /// Address space identifier #[inline] - #[cfg(target_arch = "riscv64")] + #[cfg(riscv64)] pub fn asid(&self) -> usize { self.bits.get_bits(44..60) } /// Physical page number #[inline] - #[cfg(target_arch = "riscv32")] + #[cfg(riscv32)] pub fn ppn(&self) -> usize { self.bits.get_bits(0..22) } /// Physical page number #[inline] - #[cfg(target_arch = "riscv64")] + #[cfg(riscv64)] pub fn ppn(&self) -> usize { self.bits.get_bits(0..44) } } -#[cfg(target_arch = "riscv32")] +#[cfg(riscv32)] pub enum Mode { Bare = 0, Sv32 = 1, } -#[cfg(target_arch = "riscv64")] +#[cfg(riscv64)] pub enum Mode { Bare = 0, Sv39 = 8, @@ -88,7 +88,7 @@ read_csr_as!(Satp, 0x180); write_csr!(0x180); #[inline] -#[cfg(target_arch = "riscv32")] +#[cfg(riscv32)] pub unsafe fn set(mode: Mode, asid: usize, ppn: usize) { let mut bits = 0usize; bits.set_bits(31..32, mode as usize); @@ -98,11 +98,11 @@ pub unsafe fn set(mode: Mode, asid: usize, ppn: usize) { } #[inline] -#[cfg(target_arch = "riscv64")] +#[cfg(riscv64)] pub unsafe fn set(mode: Mode, asid: usize, ppn: usize) { let mut bits = 0usize; bits.set_bits(60..64, mode as usize); bits.set_bits(44..60, asid); bits.set_bits(0..44, ppn); _write(bits); -} \ No newline at end of file +} diff --git a/src/register/sstatus.rs b/src/register/sstatus.rs index 8181fb2..ee11533 100644 --- a/src/register/sstatus.rs +++ b/src/register/sstatus.rs @@ -123,14 +123,14 @@ set_clear_csr!(set_sum, clear_sum, 1 << 18); /// Supervisor Previous Privilege Mode #[inline] -#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] +#[cfg(riscv)] pub unsafe fn set_spp(spp: SPP) { _set((spp as usize) << 8); } /// The status of the floating-point unit #[inline] -#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] +#[cfg(riscv)] pub unsafe fn set_fs(fs: FS) { _set((fs as usize) << 13); } From 41378757c0529b4cce532cc4e76f9b7ca56f8344 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Sat, 22 Dec 2018 10:32:52 +0100 Subject: [PATCH 2/6] Do not require const-fn and asm features --- Cargo.toml | 1 + ci/script.sh | 2 +- src/asm.rs | 23 ++++++---- src/lib.rs | 3 +- src/register/macros.rs | 95 +++++++++++++++++++++++++----------------- 5 files changed, 75 insertions(+), 49 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0365b93..683f51a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,4 +13,5 @@ bare-metal = "0.2.0" bit_field = "0.9.0" [features] +const-fn = ["bare-metal/const-fn"] inline-asm = [] \ No newline at end of file diff --git a/ci/script.sh b/ci/script.sh index eb1a313..dde6273 100644 --- a/ci/script.sh +++ b/ci/script.sh @@ -4,7 +4,7 @@ main() { cargo check --target $TARGET if [ $TRAVIS_RUST_VERSION = nightly ]; then - cargo check --target $TARGET --features inline-asm + cargo check --target $TARGET --features 'const-fn inline-asm' fi } diff --git a/src/asm.rs b/src/asm.rs index 389146d..d258383 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -5,8 +5,12 @@ macro_rules! instruction { #[inline] pub unsafe fn $fnname() { match () { - #[cfg(riscv)] + #[cfg(all(riscv, feature = "inline-asm"))] () => asm!($asm :::: "volatile"), + + #[cfg(all(riscv, not(feature = "inline-asm")))] + () => unimplemented!(), + #[cfg(not(riscv))] () => unimplemented!(), } @@ -22,11 +26,16 @@ instruction!(sfence_vma_all, "sfence.vma"); #[inline] -#[cfg(riscv)] +#[allow(unused_variables)] pub unsafe fn sfence_vma(asid: usize, addr: usize) { - asm!("sfence.vma $0, $1" :: "r"(asid), "r"(addr) :: "volatile"); -} + match () { + #[cfg(all(riscv, feature = "inline-asm"))] + () => asm!("sfence.vma $0, $1" :: "r"(asid), "r"(addr) :: "volatile"), -#[inline] -#[cfg(not(riscv))] -pub fn sfence_vma(_asid: usize, _addr: usize) {} + #[cfg(all(riscv, not(feature = "inline-asm")))] + () => unimplemented!(), + + #[cfg(not(riscv))] + () => unimplemented!(), + } +} diff --git a/src/lib.rs b/src/lib.rs index aa952cf..a73ed12 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,8 +8,7 @@ #![no_std] #![deny(warnings)] -#![feature(asm)] -#![feature(const_fn)] +#![cfg_attr(feature = "inline-asm", feature(asm))] extern crate bare_metal; extern crate bit_field; diff --git a/src/register/macros.rs b/src/register/macros.rs index ec0e1e1..7520584 100644 --- a/src/register/macros.rs +++ b/src/register/macros.rs @@ -2,17 +2,21 @@ macro_rules! read_csr { ($csr_number:expr) => { /// Reads the CSR #[inline] - #[cfg(riscv)] unsafe fn _read() -> usize { - let r: usize; - asm!("csrrs $0, $1, x0" : "=r"(r) : "i"($csr_number) :: "volatile"); - r - } + match () { + #[cfg(all(riscv, feature = "inline-asm"))] + () => { + let r: usize; + asm!("csrrs $0, $1, x0" : "=r"(r) : "i"($csr_number) :: "volatile"); + r + } - #[inline] - #[cfg(not(riscv))] - unsafe fn _read() -> usize { - unimplemented!() + #[cfg(all(riscv, not(feature = "inline-asm")))] + () => unimplemented!(), + + #[cfg(not(riscv))] + () => unimplemented!(), + } } }; } @@ -21,17 +25,21 @@ macro_rules! read_csr_rv32 { ($csr_number:expr) => { /// Reads the CSR #[inline] - #[cfg(riscv32)] unsafe fn _read() -> usize { - let r: usize; - asm!("csrrs $0, $1, x0" : "=r"(r) : "i"($csr_number) :: "volatile"); - r - } + match () { + #[cfg(all(riscv32, feature = "inline-asm"))] + () => { + let r: usize; + asm!("csrrs $0, $1, x0" : "=r"(r) : "i"($csr_number) :: "volatile"); + r + } - #[inline] - #[cfg(not(riscv32))] - unsafe fn _read() -> usize { - unimplemented!() + #[cfg(all(riscv32, not(feature = "inline-asm")))] + () => unimplemented!(), + + #[cfg(not(riscv32))] + () => unimplemented!(), + } } }; } @@ -76,15 +84,18 @@ macro_rules! write_csr { ($csr_number:expr) => { /// Writes the CSR #[inline] - #[cfg(riscv)] + #[allow(unused_variables)] unsafe fn _write(bits: usize) { - asm!("csrrw x0, $1, $0" :: "r"(bits), "i"($csr_number) :: "volatile"); - } + match () { + #[cfg(all(riscv, feature = "inline-asm"))] + () => asm!("csrrw x0, $1, $0" :: "r"(bits), "i"($csr_number) :: "volatile"), - #[inline] - #[cfg(not(riscv))] - unsafe fn _write(_bits: usize) { - unimplemented!() + #[cfg(all(riscv, not(feature = "inline-asm")))] + () => unimplemented!(), + + #[cfg(not(riscv))] + () => unimplemented!(), + } } }; } @@ -105,15 +116,18 @@ macro_rules! set { ($csr_number:expr) => { /// Set the CSR #[inline] - #[cfg(riscv)] + #[allow(unused_variables)] unsafe fn _set(bits: usize) { - asm!("csrrs x0, $1, $0" :: "r"(bits), "i"($csr_number) :: "volatile"); - } + match () { + #[cfg(all(riscv, feature = "inline-asm"))] + () => asm!("csrrs x0, $1, $0" :: "r"(bits), "i"($csr_number) :: "volatile"), - #[inline] - #[cfg(not(riscv))] - unsafe fn _set(_bits: usize) { - unimplemented!() + #[cfg(all(riscv, not(feature = "inline-asm")))] + () => unimplemented!(), + + #[cfg(not(riscv))] + () => unimplemented!(), + } } }; } @@ -122,15 +136,18 @@ macro_rules! clear { ($csr_number:expr) => { /// Clear the CSR #[inline] - #[cfg(riscv)] + #[allow(unused_variables)] unsafe fn _clear(bits: usize) { - asm!("csrrc x0, $1, $0" :: "r"(bits), "i"($csr_number) :: "volatile"); - } + match () { + #[cfg(all(riscv, feature = "inline-asm"))] + () => asm!("csrrc x0, $1, $0" :: "r"(bits), "i"($csr_number) :: "volatile"), - #[inline] - #[cfg(not(riscv))] - unsafe fn _clear(_bits: usize) { - unimplemented!() + #[cfg(all(riscv, not(feature = "inline-asm")))] + () => unimplemented!(), + + #[cfg(not(riscv))] + () => unimplemented!(), + } } }; } From 061579f97eddfab3aa8e5d32c7e28ef761b5902a Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Sun, 23 Dec 2018 09:44:08 +0100 Subject: [PATCH 3/6] Call external functions when inline-asm is not set --- src/asm.rs | 24 ++++++++++---- src/register/macros.rs | 66 ++++++++++++++++++++++++++++----------- src/register/mcause.rs | 2 +- src/register/mcycle.rs | 2 +- src/register/mcycleh.rs | 2 +- src/register/mepc.rs | 2 +- src/register/mie.rs | 6 ++-- src/register/minstret.rs | 2 +- src/register/minstreth.rs | 2 +- src/register/mip.rs | 2 +- src/register/misa.rs | 2 +- src/register/mstatus.rs | 6 ++-- src/register/mtvec.rs | 4 +-- src/register/mvendorid.rs | 2 +- src/register/satp.rs | 4 +-- src/register/scause.rs | 2 +- src/register/sepc.rs | 4 +-- src/register/sie.rs | 6 ++-- src/register/sip.rs | 2 +- src/register/sscratch.rs | 4 +-- src/register/sstatus.rs | 6 ++-- src/register/stval.rs | 2 +- src/register/stvec.rs | 4 +-- src/register/time.rs | 2 +- src/register/timeh.rs | 2 +- 25 files changed, 102 insertions(+), 60 deletions(-) diff --git a/src/asm.rs b/src/asm.rs index d258383..cf451a3 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -1,7 +1,7 @@ //! Assembly instructions macro_rules! instruction { - ($fnname:ident, $asm:expr) => ( + ($fnname:ident, $asm:expr, $asm_fn:ident) => ( #[inline] pub unsafe fn $fnname() { match () { @@ -9,7 +9,13 @@ macro_rules! instruction { () => asm!($asm :::: "volatile"), #[cfg(all(riscv, not(feature = "inline-asm")))] - () => unimplemented!(), + () => { + extern "C" { + fn $asm_fn(); + } + + $asm_fn(); + } #[cfg(not(riscv))] () => unimplemented!(), @@ -20,9 +26,9 @@ macro_rules! instruction { /// Priviledged ISA Instructions -instruction!(ebreak, "ebreak"); -instruction!(wfi, "wfi"); -instruction!(sfence_vma_all, "sfence.vma"); +instruction!(ebreak, "ebreak", __ebreak); +instruction!(wfi, "wfi", __wfi); +instruction!(sfence_vma_all, "sfence.vma", __sfence_vma_all); #[inline] @@ -33,7 +39,13 @@ pub unsafe fn sfence_vma(asid: usize, addr: usize) { () => asm!("sfence.vma $0, $1" :: "r"(asid), "r"(addr) :: "volatile"), #[cfg(all(riscv, not(feature = "inline-asm")))] - () => unimplemented!(), + () => { + extern "C" { + fn __sfence_vma(asid: usize, addr: usize); + } + + __sfence_vma(asid, addr); + } #[cfg(not(riscv))] () => unimplemented!(), diff --git a/src/register/macros.rs b/src/register/macros.rs index 7520584..cda38ac 100644 --- a/src/register/macros.rs +++ b/src/register/macros.rs @@ -1,5 +1,5 @@ macro_rules! read_csr { - ($csr_number:expr) => { + ($csr_number:expr, $asm_fn: ident) => { /// Reads the CSR #[inline] unsafe fn _read() -> usize { @@ -12,7 +12,13 @@ macro_rules! read_csr { } #[cfg(all(riscv, not(feature = "inline-asm")))] - () => unimplemented!(), + () => { + extern "C" { + fn $asm_fn() -> usize; + } + + $asm_fn() + } #[cfg(not(riscv))] () => unimplemented!(), @@ -22,7 +28,7 @@ macro_rules! read_csr { } macro_rules! read_csr_rv32 { - ($csr_number:expr) => { + ($csr_number:expr, $asm_fn: ident) => { /// Reads the CSR #[inline] unsafe fn _read() -> usize { @@ -35,7 +41,13 @@ macro_rules! read_csr_rv32 { } #[cfg(all(riscv32, not(feature = "inline-asm")))] - () => unimplemented!(), + () => { + extern "C" { + fn $asm_fn() -> usize; + } + + $asm_fn() + } #[cfg(not(riscv32))] () => unimplemented!(), @@ -45,8 +57,8 @@ macro_rules! read_csr_rv32 { } macro_rules! read_csr_as { - ($register:ident, $csr_number:expr) => { - read_csr!($csr_number); + ($register:ident, $csr_number:expr, $asm_fn: ident) => { + read_csr!($csr_number, $asm_fn); /// Reads the CSR #[inline] @@ -57,8 +69,8 @@ macro_rules! read_csr_as { } macro_rules! read_csr_as_usize { - ($csr_number:expr) => { - read_csr!($csr_number); + ($csr_number:expr, $asm_fn: ident) => { + read_csr!($csr_number, $asm_fn); /// Reads the CSR #[inline] @@ -69,8 +81,8 @@ macro_rules! read_csr_as_usize { } macro_rules! read_csr_as_usize_rv32 { - ($csr_number:expr) => { - read_csr_rv32!($csr_number); + ($csr_number:expr, $asm_fn: ident) => { + read_csr_rv32!($csr_number, $asm_fn); /// Reads the CSR #[inline] @@ -81,7 +93,7 @@ macro_rules! read_csr_as_usize_rv32 { } macro_rules! write_csr { - ($csr_number:expr) => { + ($csr_number:expr, $asm_fn: ident) => { /// Writes the CSR #[inline] #[allow(unused_variables)] @@ -91,7 +103,13 @@ macro_rules! write_csr { () => asm!("csrrw x0, $1, $0" :: "r"(bits), "i"($csr_number) :: "volatile"), #[cfg(all(riscv, not(feature = "inline-asm")))] - () => unimplemented!(), + () => { + extern "C" { + fn $asm_fn(bits: usize); + } + + $asm_fn(bits); + } #[cfg(not(riscv))] () => unimplemented!(), @@ -101,8 +119,8 @@ macro_rules! write_csr { } macro_rules! write_csr_as_usize { - ($csr_number:expr) => { - write_csr!($csr_number); + ($csr_number:expr, $asm_fn: ident) => { + write_csr!($csr_number, $asm_fn); /// Writes the CSR #[inline] @@ -113,7 +131,7 @@ macro_rules! write_csr_as_usize { } macro_rules! set { - ($csr_number:expr) => { + ($csr_number:expr, $asm_fn: ident) => { /// Set the CSR #[inline] #[allow(unused_variables)] @@ -123,7 +141,13 @@ macro_rules! set { () => asm!("csrrs x0, $1, $0" :: "r"(bits), "i"($csr_number) :: "volatile"), #[cfg(all(riscv, not(feature = "inline-asm")))] - () => unimplemented!(), + () => { + extern "C" { + fn $asm_fn(bits: usize); + } + + $asm_fn(bits); + } #[cfg(not(riscv))] () => unimplemented!(), @@ -133,7 +157,7 @@ macro_rules! set { } macro_rules! clear { - ($csr_number:expr) => { + ($csr_number:expr, $asm_fn: ident) => { /// Clear the CSR #[inline] #[allow(unused_variables)] @@ -143,7 +167,13 @@ macro_rules! clear { () => asm!("csrrc x0, $1, $0" :: "r"(bits), "i"($csr_number) :: "volatile"), #[cfg(all(riscv, not(feature = "inline-asm")))] - () => unimplemented!(), + () => { + extern "C" { + fn $asm_fn(bits: usize); + } + + $asm_fn(bits); + } #[cfg(not(riscv))] () => unimplemented!(), diff --git a/src/register/mcause.rs b/src/register/mcause.rs index e659383..67e6d8c 100644 --- a/src/register/mcause.rs +++ b/src/register/mcause.rs @@ -136,4 +136,4 @@ impl Mcause { } } -read_csr_as!(Mcause, 0x342); +read_csr_as!(Mcause, 0x342, __read_mcause); diff --git a/src/register/mcycle.rs b/src/register/mcycle.rs index f2905fc..41e8115 100644 --- a/src/register/mcycle.rs +++ b/src/register/mcycle.rs @@ -1,3 +1,3 @@ //! mcycle register -read_csr_as_usize!(0xB00); +read_csr_as_usize!(0xB00, __read_mcycle); diff --git a/src/register/mcycleh.rs b/src/register/mcycleh.rs index 31ca70c..784dca4 100644 --- a/src/register/mcycleh.rs +++ b/src/register/mcycleh.rs @@ -1,3 +1,3 @@ //! mcycleh register -read_csr_as_usize_rv32!(0xB80); +read_csr_as_usize_rv32!(0xB80, __read_mcycleh); diff --git a/src/register/mepc.rs b/src/register/mepc.rs index 4fc7863..9871513 100644 --- a/src/register/mepc.rs +++ b/src/register/mepc.rs @@ -1,3 +1,3 @@ //! mepc register -read_csr_as_usize!(0x341); +read_csr_as_usize!(0x341, __read_mepc); diff --git a/src/register/mie.rs b/src/register/mie.rs index 0828cd8..cd4fcc2 100644 --- a/src/register/mie.rs +++ b/src/register/mie.rs @@ -68,9 +68,9 @@ impl Mie { } } -read_csr_as!(Mie, 0x304); -set!(0x304); -clear!(0x304); +read_csr_as!(Mie, 0x304, __read_mie); +set!(0x304, __set_mie); +clear!(0x304, __clear_mie); /// User Software Interrupt Enable set_clear_csr!(set_usoft, clear_usoft, 1 << 0); diff --git a/src/register/minstret.rs b/src/register/minstret.rs index aa072fd..6aba6b3 100644 --- a/src/register/minstret.rs +++ b/src/register/minstret.rs @@ -1,3 +1,3 @@ //! minstret register -read_csr_as_usize!(0xB02); +read_csr_as_usize!(0xB02, __read_minstret); diff --git a/src/register/minstreth.rs b/src/register/minstreth.rs index 5548399..56bc54e 100644 --- a/src/register/minstreth.rs +++ b/src/register/minstreth.rs @@ -1,3 +1,3 @@ //! minstreth register -read_csr_as_usize_rv32!(0xB82); +read_csr_as_usize_rv32!(0xB82, __read_minstreth); diff --git a/src/register/mip.rs b/src/register/mip.rs index 39f1edd..076a019 100644 --- a/src/register/mip.rs +++ b/src/register/mip.rs @@ -68,4 +68,4 @@ impl Mip { } } -read_csr_as!(Mip, 0x344); +read_csr_as!(Mip, 0x344, __read_mip); diff --git a/src/register/misa.rs b/src/register/misa.rs index 9a2482d..bd52508 100644 --- a/src/register/misa.rs +++ b/src/register/misa.rs @@ -47,7 +47,7 @@ impl Misa { } } -read_csr!(0x301); +read_csr!(0x301, __read_misa); /// Reads the CSR #[inline] diff --git a/src/register/mstatus.rs b/src/register/mstatus.rs index 30ba4ec..f49967a 100644 --- a/src/register/mstatus.rs +++ b/src/register/mstatus.rs @@ -79,9 +79,9 @@ impl Mstatus { } -read_csr_as!(Mstatus, 0x300); -set!(0x300); -clear!(0x300); +read_csr_as!(Mstatus, 0x300, __read_mstatus); +set!(0x300, __set_mstatus); +clear!(0x300, __clear_mstatus); /// User Interrupt Enable set_clear_csr!(set_uie, clear_uie, 1 << 0); diff --git a/src/register/mtvec.rs b/src/register/mtvec.rs index efa475e..d4f8c07 100644 --- a/src/register/mtvec.rs +++ b/src/register/mtvec.rs @@ -34,9 +34,9 @@ impl Mtvec { } } -read_csr_as!(Mtvec, 0x305); +read_csr_as!(Mtvec, 0x305, __read_mtvec); -write_csr!(0x305); +write_csr!(0x305, __write_mtvec); /// Writes the CSR #[inline] diff --git a/src/register/mvendorid.rs b/src/register/mvendorid.rs index c2f831f..a76ffb8 100644 --- a/src/register/mvendorid.rs +++ b/src/register/mvendorid.rs @@ -20,7 +20,7 @@ impl Mvendorid { } } -read_csr!(0xF11); +read_csr!(0xF11, __read_mvendorid); /// Reads the CSR #[inline] diff --git a/src/register/satp.rs b/src/register/satp.rs index 2f00334..fa0c6ee 100644 --- a/src/register/satp.rs +++ b/src/register/satp.rs @@ -84,8 +84,8 @@ pub enum Mode { Sv64 = 11, } -read_csr_as!(Satp, 0x180); -write_csr!(0x180); +read_csr_as!(Satp, 0x180, __read_satp); +write_csr!(0x180, __write_satp); #[inline] #[cfg(riscv32)] diff --git a/src/register/scause.rs b/src/register/scause.rs index 505202d..596ccef 100644 --- a/src/register/scause.rs +++ b/src/register/scause.rs @@ -115,4 +115,4 @@ impl Scause { } } -read_csr_as!(Scause, 0x142); +read_csr_as!(Scause, 0x142, __read_scause); diff --git a/src/register/sepc.rs b/src/register/sepc.rs index a39d1bd..aba69df 100644 --- a/src/register/sepc.rs +++ b/src/register/sepc.rs @@ -1,4 +1,4 @@ //! sepc register -read_csr_as_usize!(0x141); -write_csr_as_usize!(0x141); +read_csr_as_usize!(0x141, __read_sepc); +write_csr_as_usize!(0x141, __write_sepc); diff --git a/src/register/sie.rs b/src/register/sie.rs index 10d3845..1ea8a7c 100644 --- a/src/register/sie.rs +++ b/src/register/sie.rs @@ -52,9 +52,9 @@ impl Sie { } } -read_csr_as!(Sie, 0x104); -set!(0x104); -clear!(0x104); +read_csr_as!(Sie, 0x104, __read_sie); +set!(0x104, __set_sie); +clear!(0x104, __clear_sie); /// User Software Interrupt Enable set_clear_csr!(set_usoft, clear_usoft, 1 << 0); diff --git a/src/register/sip.rs b/src/register/sip.rs index bd419e7..f625661 100644 --- a/src/register/sip.rs +++ b/src/register/sip.rs @@ -52,4 +52,4 @@ impl Sip { } } -read_csr_as!(Sip, 0x144); +read_csr_as!(Sip, 0x144, __read_sip); diff --git a/src/register/sscratch.rs b/src/register/sscratch.rs index d910d6e..349812c 100644 --- a/src/register/sscratch.rs +++ b/src/register/sscratch.rs @@ -1,4 +1,4 @@ //! sscratch register -read_csr_as_usize!(0x140); -write_csr_as_usize!(0x140); +read_csr_as_usize!(0x140, __read_sscratch); +write_csr_as_usize!(0x140, __write_sscratch); diff --git a/src/register/sstatus.rs b/src/register/sstatus.rs index ee11533..455d405 100644 --- a/src/register/sstatus.rs +++ b/src/register/sstatus.rs @@ -104,9 +104,9 @@ impl Sstatus { } } -read_csr_as!(Sstatus, 0x100); -set!(0x100); -clear!(0x100); +read_csr_as!(Sstatus, 0x100, __read_sstatus); +set!(0x100, __set_sstatus); +clear!(0x100, __clear_sstatus); /// User Interrupt Enable set_clear_csr!(set_uie, clear_uie, 1 << 0); diff --git a/src/register/stval.rs b/src/register/stval.rs index fb37ee9..722cc19 100644 --- a/src/register/stval.rs +++ b/src/register/stval.rs @@ -1,3 +1,3 @@ //! stval register -read_csr_as_usize!(0x143); +read_csr_as_usize!(0x143, __read_stval); diff --git a/src/register/stvec.rs b/src/register/stvec.rs index d780795..5a179d0 100644 --- a/src/register/stvec.rs +++ b/src/register/stvec.rs @@ -34,8 +34,8 @@ impl Stvec { } } -read_csr_as!(Stvec, 0x105); -write_csr!(0x105); +read_csr_as!(Stvec, 0x105, __read_stvec); +write_csr!(0x105, __write_stvec); /// Writes the CSR #[inline] diff --git a/src/register/time.rs b/src/register/time.rs index e626742..8793475 100644 --- a/src/register/time.rs +++ b/src/register/time.rs @@ -1,3 +1,3 @@ //! time register -read_csr_as_usize!(0xC01); +read_csr_as_usize!(0xC01, __read_time); diff --git a/src/register/timeh.rs b/src/register/timeh.rs index 884c9ab..ff725db 100644 --- a/src/register/timeh.rs +++ b/src/register/timeh.rs @@ -1,3 +1,3 @@ //! timeh register -read_csr_as_usize_rv32!(0xC81); +read_csr_as_usize_rv32!(0xC81, __read_timeh); From a51143d366eedfe5ab30bfdf5f1f491ce230f549 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Sun, 23 Dec 2018 11:25:04 +0100 Subject: [PATCH 4/6] Implement asm functions --- .gitignore | 3 ++ asm.S | 55 +++++++++++++++++++++++++++++ asm.h | 37 +++++++++++++++++++ asm32.S | 5 +++ assemble.sh | 16 +++++++++ bin/riscv32imac-unknown-none-elf.a | Bin 0 -> 6186 bytes bin/riscv32imc-unknown-none-elf.a | Bin 0 -> 6186 bytes build.rs | 15 +++++++- check-blobs.sh | 21 +++++++++++ 9 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 asm.S create mode 100644 asm.h create mode 100644 asm32.S create mode 100755 assemble.sh create mode 100644 bin/riscv32imac-unknown-none-elf.a create mode 100644 bin/riscv32imc-unknown-none-elf.a create mode 100755 check-blobs.sh diff --git a/.gitignore b/.gitignore index 1e7caa9..e38997a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ Cargo.lock target/ +bin/*.after +bin/*.before +bin/*.o diff --git a/asm.S b/asm.S new file mode 100644 index 0000000..030dfd1 --- /dev/null +++ b/asm.S @@ -0,0 +1,55 @@ +#include "asm.h" + +.section .text.__ebreak +.global __ebreak +__ebreak: + ebreak + ret + +.section .text.__wfi +.global __wfi +__wfi: + wfi + ret + +.section .text.__sfence_vma_all +.global __sfence_vma_all +__sfence_vma_all: + sfence.vma + ret + +.section .text.__sfence_vma +.global __sfence_vma +__sfence_vma: + sfence.vma a0, a1 + ret + + +// M-mode registers +REG_READ(mcause, 0x342) +REG_READ(mcycle, 0xB00) +REG_READ(mepc, 0x341) +REG_READ(mie, 0x304) +REG_SET_CLEAR(mie, 0x304) +REG_READ(minstret, 0xB02) +REG_READ(mip, 0x344) +REG_READ(misa, 0x301) +REG_READ(mstatus, 0x300) +REG_SET_CLEAR(mstatus, 0x300) +REG_READ_WRITE(mtvec, 0x305) +REG_READ(mvendorid, 0xF11) + +// S-mode registers +REG_READ_WRITE(satp, 0x180) +REG_READ(scause, 0x142) +REG_READ_WRITE(sepc, 0x141) +REG_READ(sie, 0x104) +REG_SET_CLEAR(sie, 0x104) +REG_READ(sip, 0x144) +REG_READ_WRITE(sscratch, 0x140) +REG_READ(sstatus, 0x100) +REG_SET_CLEAR(sstatus, 0x100) +REG_READ(stval, 0x143) +REG_READ_WRITE(stvec, 0x105) + +REG_READ(time, 0xC01) diff --git a/asm.h b/asm.h new file mode 100644 index 0000000..3ec97f2 --- /dev/null +++ b/asm.h @@ -0,0 +1,37 @@ +#ifndef __ASM_H +#define __ASM_H + +#define REG_READ(name, offset) \ +.section .text.__read_ ## name; \ +.global __read_ ## name; \ +__read_ ## name: \ + csrrs a0, offset, x0; \ + ret + +#define REG_WRITE(name, offset) \ +.section .text.__write_ ## name; \ +.global __write_ ## name; \ +__write_ ## name: \ + csrrw x0, offset, a0; \ + ret + +#define REG_SET(name, offset) \ +.section .text.__set_ ## name; \ +.global __set_ ## name; \ +__set_ ## name: \ + csrrs x0, offset, a0; \ + ret + +#define REG_CLEAR(name, offset) \ +.section .text.__clear_ ## name; \ +.global __clear_ ## name; \ +__clear_ ## name: \ + csrrc x0, offset, a0; \ + ret + + +#define REG_READ_WRITE(name, offset) REG_READ(name, offset); REG_WRITE(name, offset) +#define REG_SET_CLEAR(name, offset) REG_SET(name, offset); REG_CLEAR(name, offset) + +#endif /* __ASM_H */ + diff --git a/asm32.S b/asm32.S new file mode 100644 index 0000000..c163b64 --- /dev/null +++ b/asm32.S @@ -0,0 +1,5 @@ +#include "asm.h" + +REG_READ(mcycleh, 0xB80) +REG_READ(minstreth, 0xB82) +REG_READ(timeh, 0xC81) diff --git a/assemble.sh b/assemble.sh new file mode 100755 index 0000000..30e6fd2 --- /dev/null +++ b/assemble.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -euxo pipefail + +crate=riscv + +# remove existing blobs because otherwise this will append object files to the old blobs +rm -f bin/*.a + +riscv64-unknown-elf-gcc -c -mabi=ilp32 -march=rv32imac asm.S -o bin/$crate.o +riscv64-unknown-elf-gcc -c -mabi=ilp32 -march=rv32imac asm32.S -o bin/$crate-32.o +ar crs bin/riscv32imac-unknown-none-elf.a bin/$crate.o bin/$crate-32.o +cp bin/riscv32imac-unknown-none-elf.a bin/riscv32imc-unknown-none-elf.a + +rm bin/$crate.o +rm bin/$crate-32.o diff --git a/bin/riscv32imac-unknown-none-elf.a b/bin/riscv32imac-unknown-none-elf.a new file mode 100644 index 0000000000000000000000000000000000000000..2346b0c7c353b2d5da3e59c875ce2f09ccd08a42 GIT binary patch literal 6186 zcmeI0O=w(I6vt08ou)~@Ui00rbkcU(SmPKqrcq0YVpJrHY+AYyr!SK!8JbDsyw{`^ z#1Q=0bRp_OH=-ggltNup6h%Z_1gfqSR7AV6xDe4QC@#cv?$_LNoJ&Lyiuhpeod0>h zd+)pN-g)zXxBpOFE6p5kyD`U)Ay4YqFLSw(+lCEsybS;b0GfZl_CB3o0_ab%Se~kt z*{Q2wyw(aC3mJm>7<+%t13b) zu9;XjRGCZCS~;y(n6HOP?BXPi)6SgWMvV$~>pYN0$geX3TO zwhbq7N*!v{2t_7rgoz%L!Mp(`Zh$({7o=m|PQ?uWDA{LqRY8P+R(_|}_7 z^pZc`_UQP;JxxtbxbXGS1V2Mv0epzR3DU#r^Z*RP_0as(@=^km5tYzRu+!1~v%2QRq!VZx%WddW+EQLU#z=DRh_6-9q;W z-7EA~p|=UWUFaP`?-aUE=v_kRgzgu5x6pfp-Yaxo=zT)(7kYrLxCqyiKjRUuCx3<_ zSPT9YM$iHUuf+(~!6Bww;eMvu;3(7UA!d35oMd_L)7#(x)7#-7(>vfUrgy>w(|vG^ z>0MA_ItK~U{qPvmyWtt8_rOa`?}ay*&cl05?}JNB?}sm#MsxGOefaO&2Phqo{2i44oIaS8#^|+=GI^=Ukh$7!2Ke)G{9wX0%;EI7$5dx4Bfo-2yQ9B4GQjw05>MMa{=zC z;K-BNYsJuAUqx`w1-M59N1m=xd(R5)l>qmu;9d)GZwu~1fcsc*Zw9z;1V`(v(KxOO z?t=iA!3PMUu8kEh#?am84#9mA;PQg|G{B7r4!4TjHDKuaoem1}aNh^G zbAr1X;9eHoZvpP2;Qk13D}q~tlhbH^zY<(qfTOuZ)E)FLaTy=v2QYITe(0G_?_>0q zZvPW7gdg#>|68hT4jaQxM>a2*OEVJ^gFo|ubJk>p1a+PX*hPyj+xkUW2kM6q2q}6 kmOI>s`bGSZr^25?@b~l`p7ZxLY`^mN)Quh zd+)pN-g)zXxBpOFE6p5kyD`U)Ay4YqFLSw(+lCEsybS;b0GfZl_CB3o0_ab%Se~kt z*{Q2wyw(aC3mJm>7<+%t13b) zu9;XjRGCZCS~;y(n6HOP?BXPi)6SgWMvV$~>pYN0$geX3TO zwhbq7N*!v{2t_7rgoz%L!Mp(`Zh$({7o=m|PQ?uWDA{LqRY8P+R(_|}_7 z^pZc`_UQP;JxxtbxbXGS1V2Mv0epzR3DU#r^Z*RP_0as(@=^km5tYzRu+!1~v%2QRq!VZx%WddW+EQLU#z=DRh_6-9q;W z-7EA~p|=UWUFaP`?-aUE=v_kRgzgu5x6pfp-Yaxo=zT)(7kYrLxCqyiKjRUuCx3<_ zSPT9YM$iHUuf+(~!6Bww;eMvu;3(7UA!d35oMd_L)7#(x)7#-7(>vfUrgy>w(|vG^ z>0MA_ItK~U{qPvmyWtt8_rOa`?}ay*&cl05?}JNB?}sm#MsxGOefaO&2Phqo{2i44oIaS8#^|+=GI^=Ukh$7!2Ke)G{9wX0%;EI7$5dx4Bfo-2yQ9B4GQjw05>MMa{=zC z;K-BNYsJuAUqx`w1-M59N1m=xd(R5)l>qmu;9d)GZwu~1fcsc*Zw9z;1V`(v(KxOO z?t=iA!3PMUu8kEh#?am84#9mA;PQg|G{B7r4!4TjHDKuaoem1}aNh^G zbAr1X;9eHoZvpP2;Qk13D}q~tlhbH^zY<(qfTOuZ)E)FLaTy=v2QYITe(0G_?_>0q zZvPW7gdg#>|68hT4jaQxM>a2*OEVJ^gFo|ubJk>p1a+PX*hPyj+xkUW2kM6q2q}6 kmOI>s`bGSZr^25?@b~l`p7ZxLY`^mN)Qu bin/${filename%.a}.before +done + +./assemble.sh + +for lib in $(ls bin/*.a); do + filename=$(basename $lib) + riscv64-unknown-elf-objdump -Cd $lib > bin/${filename%.a}.after +done + +for cksum in $(ls bin/*.after); do + diff -u $cksum ${cksum%.after}.before +done From 02c9295587ffa76e2ae54092dcf714df0655a457 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Sun, 23 Dec 2018 11:37:47 +0100 Subject: [PATCH 5/6] Check binary blobs during CI --- .travis.yml | 1 + ci/install.sh | 3 +++ ci/script.sh | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/.travis.yml b/.travis.yml index a3c9cf2..d479105 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,6 +28,7 @@ before_install: set -e install: - bash ci/install.sh + - export PATH="$PATH:$PWD/gcc/bin" script: - bash ci/script.sh diff --git a/ci/install.sh b/ci/install.sh index 3c41921..fa98970 100644 --- a/ci/install.sh +++ b/ci/install.sh @@ -4,6 +4,9 @@ main() { if [ $TARGET != x86_64-unknown-linux-gnu ]; then rustup target add $TARGET fi + + mkdir gcc + curl -L https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-8.1.0-2018.12.0-x86_64-linux-ubuntu14.tar.gz | tar --strip-components=1 -C gcc -xz } main diff --git a/ci/script.sh b/ci/script.sh index dde6273..9aa0d7a 100644 --- a/ci/script.sh +++ b/ci/script.sh @@ -6,6 +6,10 @@ main() { if [ $TRAVIS_RUST_VERSION = nightly ]; then cargo check --target $TARGET --features 'const-fn inline-asm' fi + + if [ $TARGET = x86_64-unknown-linux-gnu ]; then + ./check-blobs.sh + fi } main From 7e2103e56690a13b6bd1f03021674f33bcfdb418 Mon Sep 17 00:00:00 2001 From: Vadim Kaushan Date: Sun, 23 Dec 2018 19:33:44 +0100 Subject: [PATCH 6/6] Check build on stable --- .travis.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.travis.yml b/.travis.yml index d479105..01ba0e8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,14 @@ matrix: rust: nightly if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) + - env: TARGET=x86_64-unknown-linux-gnu + rust: stable + if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) + + - env: TARGET=riscv32imac-unknown-none-elf + rust: stable + if: (branch = staging OR branch = trying OR branch = master) OR (type = pull_request AND branch = master) + before_install: set -e install: