From f6b4c005125a13bf1590ed53ec764ca85215acc8 Mon Sep 17 00:00:00 2001 From: Fawaz Tirmizi Date: Fri, 14 Oct 2022 10:50:53 -0700 Subject: [PATCH 1/6] Added `rust-toolchain.toml` --- rust-toolchain.toml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 rust-toolchain.toml diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 00000000..21c12ba5 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,7 @@ +[toolchain] +channel = "nightly" +targets = [ "riscv32i-unknown-none-elf", "riscv32imc-unknown-none-elf", + "riscv32imac-unknown-none-elf", "riscv64imac-unknown-none-elf", + "riscv64gc-unknown-none-elf"] +profile = "minimal" +components = [ "rustfmt" ] From cf894aaf45170529c540b07dab8a25bbf45ae8ee Mon Sep 17 00:00:00 2001 From: Fawaz Tirmizi Date: Tue, 11 Oct 2022 14:27:10 -0700 Subject: [PATCH 2/6] Removed all CSR macros Because the CSR modules are going to be rewritten, this was done to ensure that the crate can still build while this is happening. --- src/lib.rs | 4 +- src/register/mod.rs | 111 ++++++++++++++++++++++---------------------- 2 files changed, 57 insertions(+), 58 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f3e58f3c..a26a452a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,8 +16,8 @@ #![no_std] pub mod asm; -pub mod delay; -pub mod interrupt; +//pub mod delay; +//pub mod interrupt; pub mod register; #[macro_use] diff --git a/src/register/mod.rs b/src/register/mod.rs index baf0c8e3..bee3571e 100644 --- a/src/register/mod.rs +++ b/src/register/mod.rs @@ -14,87 +14,86 @@ mod macros; // User Trap Setup -pub mod uie; -pub mod ustatus; -pub mod utvec; +//pub mod uie; +//pub mod ustatus; +//pub mod utvec; // User Trap Handling -pub mod ucause; -pub mod uepc; -pub mod uip; -pub mod uscratch; -pub mod utval; +//pub mod ucause; +//pub mod uepc; +//pub mod uip; +//pub mod uscratch; +//pub mod utval; // User Floating-Point CSRs // TODO: frm, fflags -pub mod fcsr; +//pub mod fcsr; // User Counter/Timers -pub mod cycle; -pub mod cycleh; -mod hpmcounterx; -pub use self::hpmcounterx::*; -pub mod instret; -pub mod instreth; -pub mod time; -pub mod timeh; +//pub mod cycle; +//pub mod cycleh; +//mod hpmcounterx; +//pub use self::hpmcounterx::*; +//pub mod instret; +//pub mod instreth; +//pub mod time; +//pub mod timeh; // Supervisor Trap Setup // TODO: sedeleg, sideleg -pub mod scounteren; -pub mod sie; -pub mod sstatus; -pub mod stvec; +//pub mod scounteren; +//pub mod sie; +//pub mod sstatus; +//pub mod stvec; // Supervisor Trap Handling -pub mod scause; -pub mod sepc; -pub mod sip; -pub mod sscratch; -pub mod stval; - +//pub mod scause; +//pub mod sepc; +//pub mod sip; +//pub mod sscratch; +//pub mod stval; // Supervisor Protection and Translation -pub mod satp; +//pub mod satp; // Machine Information Registers -pub mod marchid; -pub mod mhartid; -pub mod mimpid; -pub mod mvendorid; +//pub mod marchid; +//pub mod mhartid; +//pub mod mimpid; +//pub mod mvendorid; // Machine Trap Setup -pub mod mcounteren; -pub mod medeleg; -pub mod mideleg; -pub mod mie; -pub mod misa; -pub mod mstatus; -pub mod mtvec; +//pub mod mcounteren; +//pub mod medeleg; +//pub mod mideleg; +//pub mod mie; +//pub mod misa; +//pub mod mstatus; +//pub mod mtvec; // Machine Trap Handling -pub mod mcause; -pub mod mepc; -pub mod mip; -pub mod mscratch; -pub mod mtval; +//pub mod mcause; +//pub mod mepc; +//pub mod mip; +//pub mod mscratch; +//pub mod mtval; // Machine Protection and Translation -mod pmpcfgx; -pub use self::pmpcfgx::*; -mod pmpaddrx; -pub use self::pmpaddrx::*; +//mod pmpcfgx; +//pub use self::pmpcfgx::*; +//mod pmpaddrx; +//pub use self::pmpaddrx::*; // Machine Counter/Timers -pub mod mcycle; -pub mod mcycleh; -mod mhpmcounterx; -pub use self::mhpmcounterx::*; -pub mod minstret; -pub mod minstreth; +//pub mod mcycle; +//pub mod mcycleh; +//mod mhpmcounterx; +//pub use self::mhpmcounterx::*; +//pub mod minstret; +//pub mod minstreth; // Machine Counter Setup -mod mhpmeventx; -pub use self::mhpmeventx::*; +//mod mhpmeventx; +//pub use self::mhpmeventx::*; // TODO: Debug/Trace Registers (shared with Debug Mode) From 374fc4f765bfd76d77e5875fa71cc153e96b5b19 Mon Sep 17 00:00:00 2001 From: Fawaz Tirmizi Date: Tue, 11 Oct 2022 14:52:09 -0700 Subject: [PATCH 3/6] Add module of CSR addresses --- CHANGELOG.md | 1 + src/register/addresses.rs | 680 ++++++++++++++++++++++++++++++++++++++ src/register/mod.rs | 2 + 3 files changed, 683 insertions(+) create mode 100644 src/register/addresses.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index d08afa25..7f00e66f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +- Disabled all CSR modules (`register::*`) (breaking change) ## [v0.9.0] - 2022-10-06 diff --git a/src/register/addresses.rs b/src/register/addresses.rs new file mode 100644 index 00000000..10698062 --- /dev/null +++ b/src/register/addresses.rs @@ -0,0 +1,680 @@ +//! Addresses for CSRs. Automatically generated by parse_opcodes. +//! +//! As the CSRs are implemented the `#[allow(unused)] around the respective +//! index should be removed. +#[allow(unused)] +pub const CSR_FFLAGS: u16 = 0x1; +#[allow(unused)] +pub const CSR_FRM: u16 = 0x2; +#[allow(unused)] +pub const CSR_FCSR: u16 = 0x3; +#[allow(unused)] +pub const CSR_VSTART: u16 = 0x8; +#[allow(unused)] +pub const CSR_VXSAT: u16 = 0x9; +#[allow(unused)] +pub const CSR_VXRM: u16 = 0xa; +#[allow(unused)] +pub const CSR_VCSR: u16 = 0xf; +#[allow(unused)] +pub const CSR_SEED: u16 = 0x15; +#[allow(unused)] +pub const CSR_CYCLE: u16 = 0xc00; +#[allow(unused)] +pub const CSR_TIME: u16 = 0xc01; +#[allow(unused)] +pub const CSR_INSTRET: u16 = 0xc02; +#[allow(unused)] +pub const CSR_HPMCOUNTER3: u16 = 0xc03; +#[allow(unused)] +pub const CSR_HPMCOUNTER4: u16 = 0xc04; +#[allow(unused)] +pub const CSR_HPMCOUNTER5: u16 = 0xc05; +#[allow(unused)] +pub const CSR_HPMCOUNTER6: u16 = 0xc06; +#[allow(unused)] +pub const CSR_HPMCOUNTER7: u16 = 0xc07; +#[allow(unused)] +pub const CSR_HPMCOUNTER8: u16 = 0xc08; +#[allow(unused)] +pub const CSR_HPMCOUNTER9: u16 = 0xc09; +#[allow(unused)] +pub const CSR_HPMCOUNTER10: u16 = 0xc0a; +#[allow(unused)] +pub const CSR_HPMCOUNTER11: u16 = 0xc0b; +#[allow(unused)] +pub const CSR_HPMCOUNTER12: u16 = 0xc0c; +#[allow(unused)] +pub const CSR_HPMCOUNTER13: u16 = 0xc0d; +#[allow(unused)] +pub const CSR_HPMCOUNTER14: u16 = 0xc0e; +#[allow(unused)] +pub const CSR_HPMCOUNTER15: u16 = 0xc0f; +#[allow(unused)] +pub const CSR_HPMCOUNTER16: u16 = 0xc10; +#[allow(unused)] +pub const CSR_HPMCOUNTER17: u16 = 0xc11; +#[allow(unused)] +pub const CSR_HPMCOUNTER18: u16 = 0xc12; +#[allow(unused)] +pub const CSR_HPMCOUNTER19: u16 = 0xc13; +#[allow(unused)] +pub const CSR_HPMCOUNTER20: u16 = 0xc14; +#[allow(unused)] +pub const CSR_HPMCOUNTER21: u16 = 0xc15; +#[allow(unused)] +pub const CSR_HPMCOUNTER22: u16 = 0xc16; +#[allow(unused)] +pub const CSR_HPMCOUNTER23: u16 = 0xc17; +#[allow(unused)] +pub const CSR_HPMCOUNTER24: u16 = 0xc18; +#[allow(unused)] +pub const CSR_HPMCOUNTER25: u16 = 0xc19; +#[allow(unused)] +pub const CSR_HPMCOUNTER26: u16 = 0xc1a; +#[allow(unused)] +pub const CSR_HPMCOUNTER27: u16 = 0xc1b; +#[allow(unused)] +pub const CSR_HPMCOUNTER28: u16 = 0xc1c; +#[allow(unused)] +pub const CSR_HPMCOUNTER29: u16 = 0xc1d; +#[allow(unused)] +pub const CSR_HPMCOUNTER30: u16 = 0xc1e; +#[allow(unused)] +pub const CSR_HPMCOUNTER31: u16 = 0xc1f; +#[allow(unused)] +pub const CSR_VL: u16 = 0xc20; +#[allow(unused)] +pub const CSR_VTYPE: u16 = 0xc21; +#[allow(unused)] +pub const CSR_VLENB: u16 = 0xc22; +#[allow(unused)] +pub const CSR_SSTATUS: u16 = 0x100; +#[allow(unused)] +pub const CSR_SEDELEG: u16 = 0x102; +#[allow(unused)] +pub const CSR_SIDELEG: u16 = 0x103; +#[allow(unused)] +pub const CSR_SIE: u16 = 0x104; +#[allow(unused)] +pub const CSR_STVEC: u16 = 0x105; +#[allow(unused)] +pub const CSR_SCOUNTEREN: u16 = 0x106; +#[allow(unused)] +pub const CSR_SENVCFG: u16 = 0x10a; +#[allow(unused)] +pub const CSR_SSCRATCH: u16 = 0x140; +#[allow(unused)] +pub const CSR_SEPC: u16 = 0x141; +#[allow(unused)] +pub const CSR_SCAUSE: u16 = 0x142; +#[allow(unused)] +pub const CSR_STVAL: u16 = 0x143; +#[allow(unused)] +pub const CSR_SIP: u16 = 0x144; +#[allow(unused)] +pub const CSR_SATP: u16 = 0x180; +#[allow(unused)] +pub const CSR_SCONTEXT: u16 = 0x5a8; +#[allow(unused)] +pub const CSR_VSSTATUS: u16 = 0x200; +#[allow(unused)] +pub const CSR_VSIE: u16 = 0x204; +#[allow(unused)] +pub const CSR_VSTVEC: u16 = 0x205; +#[allow(unused)] +pub const CSR_VSSCRATCH: u16 = 0x240; +#[allow(unused)] +pub const CSR_VSEPC: u16 = 0x241; +#[allow(unused)] +pub const CSR_VSCAUSE: u16 = 0x242; +#[allow(unused)] +pub const CSR_VSTVAL: u16 = 0x243; +#[allow(unused)] +pub const CSR_VSIP: u16 = 0x244; +#[allow(unused)] +pub const CSR_VSATP: u16 = 0x280; +#[allow(unused)] +pub const CSR_HSTATUS: u16 = 0x600; +#[allow(unused)] +pub const CSR_HEDELEG: u16 = 0x602; +#[allow(unused)] +pub const CSR_HIDELEG: u16 = 0x603; +#[allow(unused)] +pub const CSR_HIE: u16 = 0x604; +#[allow(unused)] +pub const CSR_HTIMEDELTA: u16 = 0x605; +#[allow(unused)] +pub const CSR_HCOUNTEREN: u16 = 0x606; +#[allow(unused)] +pub const CSR_HGEIE: u16 = 0x607; +#[allow(unused)] +pub const CSR_HENVCFG: u16 = 0x60a; +#[allow(unused)] +pub const CSR_HTVAL: u16 = 0x643; +#[allow(unused)] +pub const CSR_HIP: u16 = 0x644; +#[allow(unused)] +pub const CSR_HVIP: u16 = 0x645; +#[allow(unused)] +pub const CSR_HTINST: u16 = 0x64a; +#[allow(unused)] +pub const CSR_HGATP: u16 = 0x680; +#[allow(unused)] +pub const CSR_HCONTEXT: u16 = 0x6a8; +#[allow(unused)] +pub const CSR_HGEIP: u16 = 0xe12; +#[allow(unused)] +pub const CSR_UTVT: u16 = 0x7; +#[allow(unused)] +pub const CSR_UNXTI: u16 = 0x45; +#[allow(unused)] +pub const CSR_UINTSTATUS: u16 = 0x46; +#[allow(unused)] +pub const CSR_USCRATCHCSW: u16 = 0x48; +#[allow(unused)] +pub const CSR_USCRATCHCSWL: u16 = 0x49; +#[allow(unused)] +pub const CSR_STVT: u16 = 0x107; +#[allow(unused)] +pub const CSR_SNXTI: u16 = 0x145; +#[allow(unused)] +pub const CSR_SINTSTATUS: u16 = 0x146; +#[allow(unused)] +pub const CSR_SSCRATCHCSW: u16 = 0x148; +#[allow(unused)] +pub const CSR_SSCRATCHCSWL: u16 = 0x149; +#[allow(unused)] +pub const CSR_MTVT: u16 = 0x307; +#[allow(unused)] +pub const CSR_MNXTI: u16 = 0x345; +#[allow(unused)] +pub const CSR_MINTSTATUS: u16 = 0x346; +#[allow(unused)] +pub const CSR_MSCRATCHCSW: u16 = 0x348; +#[allow(unused)] +pub const CSR_MSCRATCHCSWL: u16 = 0x349; +#[allow(unused)] +pub const CSR_MSTATUS: u16 = 0x300; +#[allow(unused)] +pub const CSR_MISA: u16 = 0x301; +#[allow(unused)] +pub const CSR_MEDELEG: u16 = 0x302; +#[allow(unused)] +pub const CSR_MIDELEG: u16 = 0x303; +#[allow(unused)] +pub const CSR_MIE: u16 = 0x304; +#[allow(unused)] +pub const CSR_MTVEC: u16 = 0x305; +#[allow(unused)] +pub const CSR_MCOUNTEREN: u16 = 0x306; +#[allow(unused)] +pub const CSR_MENVCFG: u16 = 0x30a; +#[allow(unused)] +pub const CSR_MCOUNTINHIBIT: u16 = 0x320; +#[allow(unused)] +pub const CSR_MSCRATCH: u16 = 0x340; +#[allow(unused)] +pub const CSR_MEPC: u16 = 0x341; +#[allow(unused)] +pub const CSR_MCAUSE: u16 = 0x342; +#[allow(unused)] +pub const CSR_MTVAL: u16 = 0x343; +#[allow(unused)] +pub const CSR_MIP: u16 = 0x344; +#[allow(unused)] +pub const CSR_MTINST: u16 = 0x34a; +#[allow(unused)] +pub const CSR_MTVAL2: u16 = 0x34b; +#[allow(unused)] +pub const CSR_PMPCFG0: u16 = 0x3a0; +#[allow(unused)] +pub const CSR_PMPCFG1: u16 = 0x3a1; +#[allow(unused)] +pub const CSR_PMPCFG2: u16 = 0x3a2; +#[allow(unused)] +pub const CSR_PMPCFG3: u16 = 0x3a3; +#[allow(unused)] +pub const CSR_PMPCFG4: u16 = 0x3a4; +#[allow(unused)] +pub const CSR_PMPCFG5: u16 = 0x3a5; +#[allow(unused)] +pub const CSR_PMPCFG6: u16 = 0x3a6; +#[allow(unused)] +pub const CSR_PMPCFG7: u16 = 0x3a7; +#[allow(unused)] +pub const CSR_PMPCFG8: u16 = 0x3a8; +#[allow(unused)] +pub const CSR_PMPCFG9: u16 = 0x3a9; +#[allow(unused)] +pub const CSR_PMPCFG10: u16 = 0x3aa; +#[allow(unused)] +pub const CSR_PMPCFG11: u16 = 0x3ab; +#[allow(unused)] +pub const CSR_PMPCFG12: u16 = 0x3ac; +#[allow(unused)] +pub const CSR_PMPCFG13: u16 = 0x3ad; +#[allow(unused)] +pub const CSR_PMPCFG14: u16 = 0x3ae; +#[allow(unused)] +pub const CSR_PMPCFG15: u16 = 0x3af; +#[allow(unused)] +pub const CSR_PMPADDR0: u16 = 0x3b0; +#[allow(unused)] +pub const CSR_PMPADDR1: u16 = 0x3b1; +#[allow(unused)] +pub const CSR_PMPADDR2: u16 = 0x3b2; +#[allow(unused)] +pub const CSR_PMPADDR3: u16 = 0x3b3; +#[allow(unused)] +pub const CSR_PMPADDR4: u16 = 0x3b4; +#[allow(unused)] +pub const CSR_PMPADDR5: u16 = 0x3b5; +#[allow(unused)] +pub const CSR_PMPADDR6: u16 = 0x3b6; +#[allow(unused)] +pub const CSR_PMPADDR7: u16 = 0x3b7; +#[allow(unused)] +pub const CSR_PMPADDR8: u16 = 0x3b8; +#[allow(unused)] +pub const CSR_PMPADDR9: u16 = 0x3b9; +#[allow(unused)] +pub const CSR_PMPADDR10: u16 = 0x3ba; +#[allow(unused)] +pub const CSR_PMPADDR11: u16 = 0x3bb; +#[allow(unused)] +pub const CSR_PMPADDR12: u16 = 0x3bc; +#[allow(unused)] +pub const CSR_PMPADDR13: u16 = 0x3bd; +#[allow(unused)] +pub const CSR_PMPADDR14: u16 = 0x3be; +#[allow(unused)] +pub const CSR_PMPADDR15: u16 = 0x3bf; +#[allow(unused)] +pub const CSR_PMPADDR16: u16 = 0x3c0; +#[allow(unused)] +pub const CSR_PMPADDR17: u16 = 0x3c1; +#[allow(unused)] +pub const CSR_PMPADDR18: u16 = 0x3c2; +#[allow(unused)] +pub const CSR_PMPADDR19: u16 = 0x3c3; +#[allow(unused)] +pub const CSR_PMPADDR20: u16 = 0x3c4; +#[allow(unused)] +pub const CSR_PMPADDR21: u16 = 0x3c5; +#[allow(unused)] +pub const CSR_PMPADDR22: u16 = 0x3c6; +#[allow(unused)] +pub const CSR_PMPADDR23: u16 = 0x3c7; +#[allow(unused)] +pub const CSR_PMPADDR24: u16 = 0x3c8; +#[allow(unused)] +pub const CSR_PMPADDR25: u16 = 0x3c9; +#[allow(unused)] +pub const CSR_PMPADDR26: u16 = 0x3ca; +#[allow(unused)] +pub const CSR_PMPADDR27: u16 = 0x3cb; +#[allow(unused)] +pub const CSR_PMPADDR28: u16 = 0x3cc; +#[allow(unused)] +pub const CSR_PMPADDR29: u16 = 0x3cd; +#[allow(unused)] +pub const CSR_PMPADDR30: u16 = 0x3ce; +#[allow(unused)] +pub const CSR_PMPADDR31: u16 = 0x3cf; +#[allow(unused)] +pub const CSR_PMPADDR32: u16 = 0x3d0; +#[allow(unused)] +pub const CSR_PMPADDR33: u16 = 0x3d1; +#[allow(unused)] +pub const CSR_PMPADDR34: u16 = 0x3d2; +#[allow(unused)] +pub const CSR_PMPADDR35: u16 = 0x3d3; +#[allow(unused)] +pub const CSR_PMPADDR36: u16 = 0x3d4; +#[allow(unused)] +pub const CSR_PMPADDR37: u16 = 0x3d5; +#[allow(unused)] +pub const CSR_PMPADDR38: u16 = 0x3d6; +#[allow(unused)] +pub const CSR_PMPADDR39: u16 = 0x3d7; +#[allow(unused)] +pub const CSR_PMPADDR40: u16 = 0x3d8; +#[allow(unused)] +pub const CSR_PMPADDR41: u16 = 0x3d9; +#[allow(unused)] +pub const CSR_PMPADDR42: u16 = 0x3da; +#[allow(unused)] +pub const CSR_PMPADDR43: u16 = 0x3db; +#[allow(unused)] +pub const CSR_PMPADDR44: u16 = 0x3dc; +#[allow(unused)] +pub const CSR_PMPADDR45: u16 = 0x3dd; +#[allow(unused)] +pub const CSR_PMPADDR46: u16 = 0x3de; +#[allow(unused)] +pub const CSR_PMPADDR47: u16 = 0x3df; +#[allow(unused)] +pub const CSR_PMPADDR48: u16 = 0x3e0; +#[allow(unused)] +pub const CSR_PMPADDR49: u16 = 0x3e1; +#[allow(unused)] +pub const CSR_PMPADDR50: u16 = 0x3e2; +#[allow(unused)] +pub const CSR_PMPADDR51: u16 = 0x3e3; +#[allow(unused)] +pub const CSR_PMPADDR52: u16 = 0x3e4; +#[allow(unused)] +pub const CSR_PMPADDR53: u16 = 0x3e5; +#[allow(unused)] +pub const CSR_PMPADDR54: u16 = 0x3e6; +#[allow(unused)] +pub const CSR_PMPADDR55: u16 = 0x3e7; +#[allow(unused)] +pub const CSR_PMPADDR56: u16 = 0x3e8; +#[allow(unused)] +pub const CSR_PMPADDR57: u16 = 0x3e9; +#[allow(unused)] +pub const CSR_PMPADDR58: u16 = 0x3ea; +#[allow(unused)] +pub const CSR_PMPADDR59: u16 = 0x3eb; +#[allow(unused)] +pub const CSR_PMPADDR60: u16 = 0x3ec; +#[allow(unused)] +pub const CSR_PMPADDR61: u16 = 0x3ed; +#[allow(unused)] +pub const CSR_PMPADDR62: u16 = 0x3ee; +#[allow(unused)] +pub const CSR_PMPADDR63: u16 = 0x3ef; +#[allow(unused)] +pub const CSR_MSECCFG: u16 = 0x747; +#[allow(unused)] +pub const CSR_TSELECT: u16 = 0x7a0; +#[allow(unused)] +pub const CSR_TDATA1: u16 = 0x7a1; +#[allow(unused)] +pub const CSR_TDATA2: u16 = 0x7a2; +#[allow(unused)] +pub const CSR_TDATA3: u16 = 0x7a3; +#[allow(unused)] +pub const CSR_TINFO: u16 = 0x7a4; +#[allow(unused)] +pub const CSR_TCONTROL: u16 = 0x7a5; +#[allow(unused)] +pub const CSR_MCONTEXT: u16 = 0x7a8; +#[allow(unused)] +pub const CSR_MSCONTEXT: u16 = 0x7aa; +#[allow(unused)] +pub const CSR_DCSR: u16 = 0x7b0; +#[allow(unused)] +pub const CSR_DPC: u16 = 0x7b1; +#[allow(unused)] +pub const CSR_DSCRATCH0: u16 = 0x7b2; +#[allow(unused)] +pub const CSR_DSCRATCH1: u16 = 0x7b3; +#[allow(unused)] +pub const CSR_MCYCLE: u16 = 0xb00; +#[allow(unused)] +pub const CSR_MINSTRET: u16 = 0xb02; +#[allow(unused)] +pub const CSR_MHPMCOUNTER3: u16 = 0xb03; +#[allow(unused)] +pub const CSR_MHPMCOUNTER4: u16 = 0xb04; +#[allow(unused)] +pub const CSR_MHPMCOUNTER5: u16 = 0xb05; +#[allow(unused)] +pub const CSR_MHPMCOUNTER6: u16 = 0xb06; +#[allow(unused)] +pub const CSR_MHPMCOUNTER7: u16 = 0xb07; +#[allow(unused)] +pub const CSR_MHPMCOUNTER8: u16 = 0xb08; +#[allow(unused)] +pub const CSR_MHPMCOUNTER9: u16 = 0xb09; +#[allow(unused)] +pub const CSR_MHPMCOUNTER10: u16 = 0xb0a; +#[allow(unused)] +pub const CSR_MHPMCOUNTER11: u16 = 0xb0b; +#[allow(unused)] +pub const CSR_MHPMCOUNTER12: u16 = 0xb0c; +#[allow(unused)] +pub const CSR_MHPMCOUNTER13: u16 = 0xb0d; +#[allow(unused)] +pub const CSR_MHPMCOUNTER14: u16 = 0xb0e; +#[allow(unused)] +pub const CSR_MHPMCOUNTER15: u16 = 0xb0f; +#[allow(unused)] +pub const CSR_MHPMCOUNTER16: u16 = 0xb10; +#[allow(unused)] +pub const CSR_MHPMCOUNTER17: u16 = 0xb11; +#[allow(unused)] +pub const CSR_MHPMCOUNTER18: u16 = 0xb12; +#[allow(unused)] +pub const CSR_MHPMCOUNTER19: u16 = 0xb13; +#[allow(unused)] +pub const CSR_MHPMCOUNTER20: u16 = 0xb14; +#[allow(unused)] +pub const CSR_MHPMCOUNTER21: u16 = 0xb15; +#[allow(unused)] +pub const CSR_MHPMCOUNTER22: u16 = 0xb16; +#[allow(unused)] +pub const CSR_MHPMCOUNTER23: u16 = 0xb17; +#[allow(unused)] +pub const CSR_MHPMCOUNTER24: u16 = 0xb18; +#[allow(unused)] +pub const CSR_MHPMCOUNTER25: u16 = 0xb19; +#[allow(unused)] +pub const CSR_MHPMCOUNTER26: u16 = 0xb1a; +#[allow(unused)] +pub const CSR_MHPMCOUNTER27: u16 = 0xb1b; +#[allow(unused)] +pub const CSR_MHPMCOUNTER28: u16 = 0xb1c; +#[allow(unused)] +pub const CSR_MHPMCOUNTER29: u16 = 0xb1d; +#[allow(unused)] +pub const CSR_MHPMCOUNTER30: u16 = 0xb1e; +#[allow(unused)] +pub const CSR_MHPMCOUNTER31: u16 = 0xb1f; +#[allow(unused)] +pub const CSR_MHPMEVENT3: u16 = 0x323; +#[allow(unused)] +pub const CSR_MHPMEVENT4: u16 = 0x324; +#[allow(unused)] +pub const CSR_MHPMEVENT5: u16 = 0x325; +#[allow(unused)] +pub const CSR_MHPMEVENT6: u16 = 0x326; +#[allow(unused)] +pub const CSR_MHPMEVENT7: u16 = 0x327; +#[allow(unused)] +pub const CSR_MHPMEVENT8: u16 = 0x328; +#[allow(unused)] +pub const CSR_MHPMEVENT9: u16 = 0x329; +#[allow(unused)] +pub const CSR_MHPMEVENT10: u16 = 0x32a; +#[allow(unused)] +pub const CSR_MHPMEVENT11: u16 = 0x32b; +#[allow(unused)] +pub const CSR_MHPMEVENT12: u16 = 0x32c; +#[allow(unused)] +pub const CSR_MHPMEVENT13: u16 = 0x32d; +#[allow(unused)] +pub const CSR_MHPMEVENT14: u16 = 0x32e; +#[allow(unused)] +pub const CSR_MHPMEVENT15: u16 = 0x32f; +#[allow(unused)] +pub const CSR_MHPMEVENT16: u16 = 0x330; +#[allow(unused)] +pub const CSR_MHPMEVENT17: u16 = 0x331; +#[allow(unused)] +pub const CSR_MHPMEVENT18: u16 = 0x332; +#[allow(unused)] +pub const CSR_MHPMEVENT19: u16 = 0x333; +#[allow(unused)] +pub const CSR_MHPMEVENT20: u16 = 0x334; +#[allow(unused)] +pub const CSR_MHPMEVENT21: u16 = 0x335; +#[allow(unused)] +pub const CSR_MHPMEVENT22: u16 = 0x336; +#[allow(unused)] +pub const CSR_MHPMEVENT23: u16 = 0x337; +#[allow(unused)] +pub const CSR_MHPMEVENT24: u16 = 0x338; +#[allow(unused)] +pub const CSR_MHPMEVENT25: u16 = 0x339; +#[allow(unused)] +pub const CSR_MHPMEVENT26: u16 = 0x33a; +#[allow(unused)] +pub const CSR_MHPMEVENT27: u16 = 0x33b; +#[allow(unused)] +pub const CSR_MHPMEVENT28: u16 = 0x33c; +#[allow(unused)] +pub const CSR_MHPMEVENT29: u16 = 0x33d; +#[allow(unused)] +pub const CSR_MHPMEVENT30: u16 = 0x33e; +#[allow(unused)] +pub const CSR_MHPMEVENT31: u16 = 0x33f; +#[allow(unused)] +pub const CSR_MVENDORID: u16 = 0xf11; +#[allow(unused)] +pub const CSR_MARCHID: u16 = 0xf12; +#[allow(unused)] +pub const CSR_MIMPID: u16 = 0xf13; +#[allow(unused)] +pub const CSR_MHARTID: u16 = 0xf14; +#[allow(unused)] +pub const CSR_MCONFIGPTR: u16 = 0xf15; +#[allow(unused)] +pub const CSR_HTIMEDELTAH: u16 = 0x615; +#[allow(unused)] +pub const CSR_HENVCFGH: u16 = 0x61a; +#[allow(unused)] +pub const CSR_CYCLEH: u16 = 0xc80; +#[allow(unused)] +pub const CSR_TIMEH: u16 = 0xc81; +#[allow(unused)] +pub const CSR_INSTRETH: u16 = 0xc82; +#[allow(unused)] +pub const CSR_HPMCOUNTER3H: u16 = 0xc83; +#[allow(unused)] +pub const CSR_HPMCOUNTER4H: u16 = 0xc84; +#[allow(unused)] +pub const CSR_HPMCOUNTER5H: u16 = 0xc85; +#[allow(unused)] +pub const CSR_HPMCOUNTER6H: u16 = 0xc86; +#[allow(unused)] +pub const CSR_HPMCOUNTER7H: u16 = 0xc87; +#[allow(unused)] +pub const CSR_HPMCOUNTER8H: u16 = 0xc88; +#[allow(unused)] +pub const CSR_HPMCOUNTER9H: u16 = 0xc89; +#[allow(unused)] +pub const CSR_HPMCOUNTER10H: u16 = 0xc8a; +#[allow(unused)] +pub const CSR_HPMCOUNTER11H: u16 = 0xc8b; +#[allow(unused)] +pub const CSR_HPMCOUNTER12H: u16 = 0xc8c; +#[allow(unused)] +pub const CSR_HPMCOUNTER13H: u16 = 0xc8d; +#[allow(unused)] +pub const CSR_HPMCOUNTER14H: u16 = 0xc8e; +#[allow(unused)] +pub const CSR_HPMCOUNTER15H: u16 = 0xc8f; +#[allow(unused)] +pub const CSR_HPMCOUNTER16H: u16 = 0xc90; +#[allow(unused)] +pub const CSR_HPMCOUNTER17H: u16 = 0xc91; +#[allow(unused)] +pub const CSR_HPMCOUNTER18H: u16 = 0xc92; +#[allow(unused)] +pub const CSR_HPMCOUNTER19H: u16 = 0xc93; +#[allow(unused)] +pub const CSR_HPMCOUNTER20H: u16 = 0xc94; +#[allow(unused)] +pub const CSR_HPMCOUNTER21H: u16 = 0xc95; +#[allow(unused)] +pub const CSR_HPMCOUNTER22H: u16 = 0xc96; +#[allow(unused)] +pub const CSR_HPMCOUNTER23H: u16 = 0xc97; +#[allow(unused)] +pub const CSR_HPMCOUNTER24H: u16 = 0xc98; +#[allow(unused)] +pub const CSR_HPMCOUNTER25H: u16 = 0xc99; +#[allow(unused)] +pub const CSR_HPMCOUNTER26H: u16 = 0xc9a; +#[allow(unused)] +pub const CSR_HPMCOUNTER27H: u16 = 0xc9b; +#[allow(unused)] +pub const CSR_HPMCOUNTER28H: u16 = 0xc9c; +#[allow(unused)] +pub const CSR_HPMCOUNTER29H: u16 = 0xc9d; +#[allow(unused)] +pub const CSR_HPMCOUNTER30H: u16 = 0xc9e; +#[allow(unused)] +pub const CSR_HPMCOUNTER31H: u16 = 0xc9f; +#[allow(unused)] +pub const CSR_MSTATUSH: u16 = 0x310; +#[allow(unused)] +pub const CSR_MENVCFGH: u16 = 0x31a; +#[allow(unused)] +pub const CSR_MSECCFGH: u16 = 0x757; +#[allow(unused)] +pub const CSR_MCYCLEH: u16 = 0xb80; +#[allow(unused)] +pub const CSR_MINSTRETH: u16 = 0xb82; +#[allow(unused)] +pub const CSR_MHPMCOUNTER3H: u16 = 0xb83; +#[allow(unused)] +pub const CSR_MHPMCOUNTER4H: u16 = 0xb84; +#[allow(unused)] +pub const CSR_MHPMCOUNTER5H: u16 = 0xb85; +#[allow(unused)] +pub const CSR_MHPMCOUNTER6H: u16 = 0xb86; +#[allow(unused)] +pub const CSR_MHPMCOUNTER7H: u16 = 0xb87; +#[allow(unused)] +pub const CSR_MHPMCOUNTER8H: u16 = 0xb88; +#[allow(unused)] +pub const CSR_MHPMCOUNTER9H: u16 = 0xb89; +#[allow(unused)] +pub const CSR_MHPMCOUNTER10H: u16 = 0xb8a; +#[allow(unused)] +pub const CSR_MHPMCOUNTER11H: u16 = 0xb8b; +#[allow(unused)] +pub const CSR_MHPMCOUNTER12H: u16 = 0xb8c; +#[allow(unused)] +pub const CSR_MHPMCOUNTER13H: u16 = 0xb8d; +#[allow(unused)] +pub const CSR_MHPMCOUNTER14H: u16 = 0xb8e; +#[allow(unused)] +pub const CSR_MHPMCOUNTER15H: u16 = 0xb8f; +#[allow(unused)] +pub const CSR_MHPMCOUNTER16H: u16 = 0xb90; +#[allow(unused)] +pub const CSR_MHPMCOUNTER17H: u16 = 0xb91; +#[allow(unused)] +pub const CSR_MHPMCOUNTER18H: u16 = 0xb92; +#[allow(unused)] +pub const CSR_MHPMCOUNTER19H: u16 = 0xb93; +#[allow(unused)] +pub const CSR_MHPMCOUNTER20H: u16 = 0xb94; +#[allow(unused)] +pub const CSR_MHPMCOUNTER21H: u16 = 0xb95; +#[allow(unused)] +pub const CSR_MHPMCOUNTER22H: u16 = 0xb96; +#[allow(unused)] +pub const CSR_MHPMCOUNTER23H: u16 = 0xb97; +#[allow(unused)] +pub const CSR_MHPMCOUNTER24H: u16 = 0xb98; +#[allow(unused)] +pub const CSR_MHPMCOUNTER25H: u16 = 0xb99; +#[allow(unused)] +pub const CSR_MHPMCOUNTER26H: u16 = 0xb9a; +#[allow(unused)] +pub const CSR_MHPMCOUNTER27H: u16 = 0xb9b; +#[allow(unused)] +pub const CSR_MHPMCOUNTER28H: u16 = 0xb9c; +#[allow(unused)] +pub const CSR_MHPMCOUNTER29H: u16 = 0xb9d; +#[allow(unused)] +pub const CSR_MHPMCOUNTER30H: u16 = 0xb9e; +#[allow(unused)] +pub const CSR_MHPMCOUNTER31H: u16 = 0xb9f; diff --git a/src/register/mod.rs b/src/register/mod.rs index bee3571e..d044ae0d 100644 --- a/src/register/mod.rs +++ b/src/register/mod.rs @@ -13,6 +13,8 @@ #[macro_use] mod macros; +mod addresses; + // User Trap Setup //pub mod uie; //pub mod ustatus; From d1365eda1ef97702854e27d43e0b7e9f64612d65 Mon Sep 17 00:00:00 2001 From: Fawaz Tirmizi Date: Tue, 11 Oct 2022 14:57:13 -0700 Subject: [PATCH 4/6] Add macros for generating CSR functions This adds a couple of macros that will create a set of functions for a given CSR. Most of the time, only `ro_csr!` and `rw_csr!` will need to be invoked directly. --- CHANGELOG.md | 1 + Cargo.toml | 3 +- src/lib.rs | 1 + src/register/macros.rs | 365 +++++++++++++++++------------------------ 4 files changed, 158 insertions(+), 212 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f00e66f..e19fb945 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] - Disabled all CSR modules (`register::*`) (breaking change) +- Replaced CSR macros with new ones using `tock-registers` ## [v0.9.0] - 2022-10-06 diff --git a/Cargo.toml b/Cargo.toml index 43317ff0..ad7c99c6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,5 +19,6 @@ targets = [ [dependencies] bare-metal = "1.0.0" -bit_field = "0.10.0" embedded-hal = "0.2.6" +paste = "1.0.9" +tock-registers = "0.8.1" diff --git a/src/lib.rs b/src/lib.rs index a26a452a..a600984d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,6 +14,7 @@ //! - Wrappers around assembly instructions like `WFI`. #![no_std] +#![feature(asm_const)] pub mod asm; //pub mod delay; diff --git a/src/register/macros.rs b/src/register/macros.rs index 27241141..aae16c1c 100644 --- a/src/register/macros.rs +++ b/src/register/macros.rs @@ -1,255 +1,198 @@ -macro_rules! read_csr { - ($csr_number:literal) => { - /// Reads the CSR - #[inline] - unsafe fn _read() -> usize { - match () { - #[cfg(riscv)] - () => { - let r: usize; - core::arch::asm!(concat!("csrrs {0}, ", stringify!($csr_number), ", x0"), out(reg) r); - r - } - - #[cfg(not(riscv))] - () => unimplemented!(), - } - } - }; -} - -macro_rules! read_csr_rv32 { - ($csr_number:literal) => { - /// Reads the CSR - #[inline] - unsafe fn _read() -> usize { - match () { - #[cfg(riscv32)] - () => { - let r: usize; - core::arch::asm!(concat!("csrrs {0}, ", stringify!($csr_number), ", x0"), out(reg) r); - r - } - - #[cfg(not(riscv32))] - () => unimplemented!(), - } - } - }; -} +// Copyright (c) 2022 by Rivos Inc. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 -macro_rules! read_csr_as { - ($register:ident, $csr_number:literal) => { - read_csr!($csr_number); +//! Various macros to help with creating CSR modules - /// Reads the CSR - #[inline] - pub fn read() -> $register { - $register { - bits: unsafe { _read() }, - } +/// This macro generates the constants and types for a read-write CSR. +macro_rules! rw_csr { + // Use this if the CSR name can be matched exactly with the bitfield + // generated using `register_bitfields!` Most CSRs can use this version. + ($name:ident, $size:ty) => { + paste::paste! { + rw_csr!($name, [< $name:lower >], $size); } }; -} - -macro_rules! read_csr_as_usize { - ($csr_number:literal) => { - read_csr!($csr_number); - - /// Reads the CSR - #[inline] - pub fn read() -> usize { - unsafe { _read() } - } + // This version will need to be used if the CSR layout is not unique. An + // example would be the PMP CSRs, there are multiple with the exact same + // layout. Using this allows the same bitfield to be used multiple times. + // Ex: + // rw_csr!(pmpcfg0, pmpcfg, usize); + // rw_csr!(pmpcfg1, pmpcfg, usize); + // rw_csr!(pmpcfg2, pmpcfg, usize); + ($name:ident, $type:ty, $size:ty) => { + csr_boilerplate!($name, $type, $size); + csr_reads!($name, $size); + csr_writes!($name, $size); }; } -macro_rules! read_csr_as_usize_rv32 { - ($csr_number:literal) => { - read_csr_rv32!($csr_number); - - /// Reads the CSR - #[inline] - pub fn read() -> usize { - unsafe { _read() } - } +/// This macro generates the constants and types for a read-only CSR. +macro_rules! ro_csr { + ($name:ident, $size:ty) => { + csr_boilerplate!($name, $name, $size); + csr_reads!($name, $size); }; } -macro_rules! write_csr { - ($csr_number:literal) => { - /// Writes the CSR - #[inline] - #[allow(unused_variables)] - unsafe fn _write(bits: usize) { - match () { - #[cfg(riscv)] - () => core::arch::asm!(concat!("csrrw x0, ", stringify!($csr_number), ", {0}"), in(reg) bits), - - #[cfg(not(riscv))] - () => unimplemented!(), - } - } - }; -} +/// Generates the imports and types that all CSRs need +macro_rules! csr_boilerplate { + ($name:ident, $type:ty, $size:ty) => { + paste::paste! { + use core::arch::asm; -macro_rules! write_csr_rv32 { - ($csr_number:literal) => { - /// Writes the CSR - #[inline] - #[allow(unused_variables)] - unsafe fn _write(bits: usize) { - match () { - #[cfg(riscv32)] - () => core::arch::asm!(concat!("csrrw x0, ", stringify!($csr_number), ", {0}"), in(reg) bits), - - #[cfg(not(riscv32))] - () => unimplemented!(), - } - } - }; -} + use tock_registers::LocalRegisterCopy; + use tock_registers::register_bitfields; -macro_rules! write_csr_as_usize { - ($csr_number:literal) => { - write_csr!($csr_number); + /// This allows the enums to be accessed directly from the module's + /// namespace instead of having to go through the bitfield's as well + pub use [< $name:lower >]::*; - /// Writes the CSR - #[inline] - pub fn write(bits: usize) { - unsafe { _write(bits) } - } - }; -} + /// An alias of the CSR's index + const INDEX: u16 = $crate::register::addresses::[< CSR_ $name:upper >]; -macro_rules! write_csr_as_usize_rv32 { - ($csr_number:literal) => { - write_csr_rv32!($csr_number); + /// A typedef of the [`tock_registers::RegisterLongName`] associated with this CSR + type LongName = [< $name:lower >]::Register; - /// Writes the CSR - #[inline] - pub fn write(bits: usize) { - unsafe { _write(bits) } - } - }; -} + /// A typedef of the [`Field`] associated with this CSR + pub type Field = tock_registers::fields::Field<$size, LongName>; -macro_rules! set { - ($csr_number:literal) => { - /// Set the CSR - #[inline] - #[allow(unused_variables)] - unsafe fn _set(bits: usize) { - match () { - #[cfg(riscv)] - () => core::arch::asm!(concat!("csrrs x0, ", stringify!($csr_number), ", {0}"), in(reg) bits), - - #[cfg(not(riscv))] - () => unimplemented!(), - } + /// A typedef of the [`LocalRegisterCopy`] associated with this CSR + pub type Local = LocalRegisterCopy<$size, LongName>; } }; } -macro_rules! clear { - ($csr_number:literal) => { - /// Clear the CSR +/// Generates the read functions for a CSR +macro_rules! csr_reads { + ($name:ident, $size:ty) => { + /// Reads the contents of a CSR. + /// + /// This method corresponds to the RISC-V `CSRR rd, csr` + /// instruction where `rd = out(reg) `. #[inline] - #[allow(unused_variables)] - unsafe fn _clear(bits: usize) { - match () { - #[cfg(riscv)] - () => core::arch::asm!(concat!("csrrc x0, ", stringify!($csr_number), ", {0}"), in(reg) bits), - - #[cfg(not(riscv))] - () => unimplemented!(), + pub fn read() -> $size { + let r: $size; + unsafe { + asm!("csrr {rd}, {csr}", rd = out(reg) r, csr = const INDEX); } + r } - }; -} -macro_rules! set_csr { - ($(#[$attr:meta])*, $set_field:ident, $e:expr) => { - $(#[$attr])* + /// Returns a [`tock_registers::LocalRegisterCopy`] for the CSR. #[inline] - pub unsafe fn $set_field() { - _set($e); + pub fn read_local() -> Local { + Local::new(read()) } - }; -} -macro_rules! clear_csr { - ($(#[$attr:meta])*, $clear_field:ident, $e:expr) => { - $(#[$attr])* - #[inline] - pub unsafe fn $clear_field() { - _clear($e); + /// Atomically read the specified field + pub fn read_field(field: Field) -> $size { + field.read(read()) } - }; -} -macro_rules! set_clear_csr { - ($(#[$attr:meta])*, $set_field:ident, $clear_field:ident, $e:expr) => { - set_csr!($(#[$attr])*, $set_field, $e); - clear_csr!($(#[$attr])*, $clear_field, $e); + /// Returns true if one or more bits in the field are set + pub fn is_set(field: Field) -> bool { + read_field(field) != 0 + } } } -macro_rules! read_composite_csr { - ($hi:expr, $lo:expr) => { - /// Reads the CSR as a 64-bit value +/// Generates the write functions for a CSR +macro_rules! csr_writes { + ($name:ident, $size:ty) => { + /// Writes the value of a CSR. + /// + /// This method corresponds to the RISC-V `CSRW csr, rs` + /// instruction where `rs = in(reg) val_to_set`. #[inline] - pub fn read64() -> u64 { - match () { - #[cfg(riscv32)] - () => loop { - let hi = $hi; - let lo = $lo; - if hi == $hi { - return ((hi as u64) << 32) | lo as u64; - } - }, - - #[cfg(not(riscv32))] - () => $lo as u64, + pub fn write(val_to_set: $size) { + unsafe { + asm!("csrw {csr}, {rs}", rs = in(reg) val_to_set, csr = const INDEX); } } - }; -} -macro_rules! set_pmp { - () => { - /// Set the pmp configuration corresponding to the index + /// Write a [`tock_registers::LocalRegisterCopy`] to the CSR #[inline] - pub unsafe fn set_pmp(index: usize, range: Range, permission: Permission, locked: bool) { - #[cfg(riscv32)] - assert!(index < 4); - - #[cfg(riscv64)] - assert!(index < 8); - - let mut value = _read(); - let byte = (locked as usize) << 7 | (range as usize) << 3 | (permission as usize); - value.set_bits(8 * index..=8 * index + 7, byte); - _write(value); + pub fn write_local(local: Local) { + write(local.get()); } - }; -} -macro_rules! clear_pmp { - () => { - /// Clear the pmp configuration corresponding to the index + /// Atomically swap the contents of a CSR + /// + /// Reads the current value of a CSR and replaces it with the + /// specified value in a single instruction, returning the + /// previous value. + /// + /// This method corresponds to the RISC-V `CSRRW rd, csr, rs1` + /// instruction where `rs1 = in(reg) value_to_set` and `rd = + /// out(reg) `. #[inline] - pub unsafe fn clear_pmp(index: usize) { - #[cfg(riscv32)] - assert!(index < 4); + pub fn atomic_replace(val_to_set: $size) -> $size { + let r: $size; + unsafe { + asm!("csrrw {rd}, {csr}, {rs1}", + rd = out(reg) r, + csr = const INDEX, + rs1 = in(reg) val_to_set); + } + r + } + + /// Atomically read a CSR and set bits specified in a bitmask + /// + /// This method corresponds to the RISC-V `CSRRS rd, csr, rs1` + /// instruction where `rs1 = in(reg) bitmask` and `rd = out(reg) + /// `. + #[inline] + pub fn read_and_set_bits(bitmask: $size) -> $size { + let r: $size; + unsafe { + asm!("csrrs {rd}, {csr}, {rs1}", + rd = out(reg) r, + csr = const INDEX, + rs1 = in(reg) bitmask); + } + r + } + + /// Atomically read a CSR and set bits specified in a bitmask + /// + /// This method corresponds to the RISC-V `CSRRS rd, csr, rs1` + /// instruction where `rs1 = in(reg) bitmask` and `rd = out(reg) + /// `. + #[inline] + pub fn read_and_clear_bits(bitmask: $size) -> $size { + let r: $size; + unsafe { + asm!("csrrc {rd}, {csr}, {rs1}", + rd = out(reg) r, + csr = const INDEX, + rs1 = in(reg) bitmask); + } + r + } - #[cfg(riscv64)] - assert!(index < 8); + /// Atomically read field and set all bits to 1 + /// + /// This method corresponds to the RISC-V `CSRRS rd, csr, rs1` + /// instruction, where `rs1` is the bitmask described by the + /// [`Field`]. + /// + /// The previous value of the field is returned. + pub fn read_and_set_field(field: Field) -> $size { + field.read(read_and_set_bits(field.mask << field.shift)) + } - let mut value = _read(); - value.set_bits(8 * index..=8 * index + 7, 0); - _write(value); + /// Atomically read field and set all bits to 0 + /// + /// This method corresponds to the RISC-V `CSRRC rd, csr, rs1` + /// instruction, where `rs1` is the bitmask described by the + /// [`Field`]. + /// + /// The previous value of the field is returned. + pub fn read_and_clear_field(field: Field) -> $size { + field.read(read_and_clear_bits(field.mask << field.shift)) } - }; + + } } From 39100887c5bb92b87bfdf207ce98a4b00b6db38d Mon Sep 17 00:00:00 2001 From: Fawaz Tirmizi Date: Tue, 11 Oct 2022 15:12:26 -0700 Subject: [PATCH 5/6] Reimplement `register::mcause` --- CHANGELOG.md | 2 + src/register/addresses.rs | 1 - src/register/mcause.rs | 115 +++++++++++++++++--------------------- src/register/mod.rs | 2 +- 4 files changed, 54 insertions(+), 66 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e19fb945..8c603949 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] - Disabled all CSR modules (`register::*`) (breaking change) - Replaced CSR macros with new ones using `tock-registers` +- Reimplemeted CSR modules using new base functions: + - `mcause` ## [v0.9.0] - 2022-10-06 diff --git a/src/register/addresses.rs b/src/register/addresses.rs index 10698062..dd841234 100644 --- a/src/register/addresses.rs +++ b/src/register/addresses.rs @@ -216,7 +216,6 @@ pub const CSR_MCOUNTINHIBIT: u16 = 0x320; pub const CSR_MSCRATCH: u16 = 0x340; #[allow(unused)] pub const CSR_MEPC: u16 = 0x341; -#[allow(unused)] pub const CSR_MCAUSE: u16 = 0x342; #[allow(unused)] pub const CSR_MTVAL: u16 = 0x343; diff --git a/src/register/mcause.rs b/src/register/mcause.rs index 705ffff4..6bcf5de0 100644 --- a/src/register/mcause.rs +++ b/src/register/mcause.rs @@ -1,34 +1,75 @@ +// Copyright (c) 2022 by Rivos Inc. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + //! mcause register -/// mcause register -#[derive(Clone, Copy, Debug)] -pub struct Mcause { - bits: usize, +ro_csr!(mcause, usize); + +register_bitfields![usize, + #[cfg(target_pointer_width = "32")] + pub mcause [ + cause OFFSET(0) NUMBITS(31) [], + is_interrupt OFFSET(31) NUMBITS(1) [], + ], + + #[cfg(target_pointer_width = "64")] + pub mcause [ + cause OFFSET(0) NUMBITS(63) [], + is_interrupt OFFSET(63) NUMBITS(1) [], + ], +]; + +/// Get the cause of the latest interrupt +#[inline] +pub fn cause() -> Trap { + let cause: usize = read_field(mcause::cause); + if is_interrupt() { + Trap::Interrupt(Interrupt::from(cause)) + } else { + Trap::Exception(Exception::from(cause)) + } +} + +/// Returns `true` if the last trap was caused by an interrupt, otherwise +/// `false`. +#[inline] +pub fn is_interrupt() -> bool { + is_set(mcause::is_interrupt) } -/// Trap Cause +/// Returns `true` if the last trap was caused by an exception, otherwise +/// `false`. +#[inline] +pub fn is_exception() -> bool { + !is_interrupt() +} + +/// Enum wrapping both potential trap causes #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum Trap { Interrupt(Interrupt), Exception(Exception), } -/// Interrupt +// TODO: Maybe add a feature that changes these enums to use the actual values, +// and the conversion functions to use core::mem::transmute(). Assuming that +// the target platform doesn't use the reserved or custom interrupt lines this +// should be safe. This would only be worthwhile if the compiler doesn't already +// optimize the conversions out. +/// Interrupt causes #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum Interrupt { - UserSoft, SupervisorSoft, MachineSoft, - UserTimer, SupervisorTimer, MachineTimer, - UserExternal, SupervisorExternal, MachineExternal, Unknown, } -/// Exception +/// Exception causes #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum Exception { InstructionMisaligned, @@ -52,13 +93,10 @@ impl Interrupt { #[inline] pub fn from(nr: usize) -> Self { match nr { - 0 => Interrupt::UserSoft, 1 => Interrupt::SupervisorSoft, 3 => Interrupt::MachineSoft, - 4 => Interrupt::UserTimer, 5 => Interrupt::SupervisorTimer, 7 => Interrupt::MachineTimer, - 8 => Interrupt::UserExternal, 9 => Interrupt::SupervisorExternal, 11 => Interrupt::MachineExternal, _ => Interrupt::Unknown, @@ -88,54 +126,3 @@ impl Exception { } } } -impl Mcause { - /// Returns the contents of the register as raw bits - #[inline] - pub fn bits(&self) -> usize { - self.bits - } - - /// Returns the code field - #[inline] - pub fn code(&self) -> usize { - match () { - #[cfg(target_pointer_width = "32")] - () => self.bits & !(1 << 31), - #[cfg(target_pointer_width = "64")] - () => self.bits & !(1 << 63), - #[cfg(target_pointer_width = "128")] - () => self.bits & !(1 << 127), - } - } - - /// Trap Cause - #[inline] - pub fn cause(&self) -> Trap { - if self.is_interrupt() { - Trap::Interrupt(Interrupt::from(self.code())) - } else { - Trap::Exception(Exception::from(self.code())) - } - } - - /// Is trap cause an interrupt. - #[inline] - pub fn is_interrupt(&self) -> bool { - match () { - #[cfg(target_pointer_width = "32")] - () => self.bits & (1 << 31) == 1 << 31, - #[cfg(target_pointer_width = "64")] - () => self.bits & (1 << 63) == 1 << 63, - #[cfg(target_pointer_width = "128")] - () => self.bits & (1 << 127) == 1 << 127, - } - } - - /// Is trap cause an exception. - #[inline] - pub fn is_exception(&self) -> bool { - !self.is_interrupt() - } -} - -read_csr_as!(Mcause, 0x342); diff --git a/src/register/mod.rs b/src/register/mod.rs index d044ae0d..e32ff923 100644 --- a/src/register/mod.rs +++ b/src/register/mod.rs @@ -73,7 +73,7 @@ mod addresses; //pub mod mtvec; // Machine Trap Handling -//pub mod mcause; +pub mod mcause; //pub mod mepc; //pub mod mip; //pub mod mscratch; From ebe2c27dbe98bb8f3a299bfce19cc63016797ccb Mon Sep 17 00:00:00 2001 From: Fawaz Tirmizi Date: Tue, 11 Oct 2022 15:15:17 -0700 Subject: [PATCH 6/6] Reimplement `register::mtvec` --- CHANGELOG.md | 1 + src/register/addresses.rs | 1 - src/register/mod.rs | 2 +- src/register/mtvec.rs | 90 ++++++++++++++++++++++----------------- 4 files changed, 53 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c603949..94c77475 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Replaced CSR macros with new ones using `tock-registers` - Reimplemeted CSR modules using new base functions: - `mcause` + - `mtvec` ## [v0.9.0] - 2022-10-06 diff --git a/src/register/addresses.rs b/src/register/addresses.rs index dd841234..153cefe5 100644 --- a/src/register/addresses.rs +++ b/src/register/addresses.rs @@ -204,7 +204,6 @@ pub const CSR_MEDELEG: u16 = 0x302; pub const CSR_MIDELEG: u16 = 0x303; #[allow(unused)] pub const CSR_MIE: u16 = 0x304; -#[allow(unused)] pub const CSR_MTVEC: u16 = 0x305; #[allow(unused)] pub const CSR_MCOUNTEREN: u16 = 0x306; diff --git a/src/register/mod.rs b/src/register/mod.rs index e32ff923..ad16cc04 100644 --- a/src/register/mod.rs +++ b/src/register/mod.rs @@ -70,7 +70,7 @@ mod addresses; //pub mod mie; //pub mod misa; //pub mod mstatus; -//pub mod mtvec; +pub mod mtvec; // Machine Trap Handling pub mod mcause; diff --git a/src/register/mtvec.rs b/src/register/mtvec.rs index cc77011e..bbfc3c62 100644 --- a/src/register/mtvec.rs +++ b/src/register/mtvec.rs @@ -1,50 +1,62 @@ +// Copyright (c) 2022 by Rivos Inc. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + //! mtvec register -/// mtvec register -#[derive(Clone, Copy, Debug)] -pub struct Mtvec { - bits: usize, +rw_csr!(mtvec, usize); + +register_bitfields![usize, + #[cfg(target_pointer_width = "32")] + pub mtvec [ + mode OFFSET(0) NUMBITS(2) [ + Direct = 0, + Vectored = 1, + ], + base OFFSET(2) NUMBITS(30) [], + ], + #[cfg(target_pointer_width = "64")] + pub mtvec [ + mode OFFSET(0) NUMBITS(2) [ + Direct = 0, + Vectored = 1, + ], + base OFFSET(2) NUMBITS(62) [], + ], +]; + +/// Returns true if the trap vector mode is set to `Direct`. +#[inline] +pub fn is_direct() -> bool { + read_field(mode) == 0x0 } -/// Trap mode -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum TrapMode { - Direct = 0, - Vectored = 1, +/// Returns true if the trap vector mode is set to `Vectored`. +#[inline] +pub fn is_vectored() -> bool { + read_field(mode) == 0x1 } -impl Mtvec { - /// Returns the contents of the register as raw bits - #[inline] - pub fn bits(&self) -> usize { - self.bits - } - - /// Returns the trap-vector base-address - #[inline] - pub fn address(&self) -> usize { - self.bits - (self.bits & 0b11) - } - - /// Returns the trap-vector mode - #[inline] - pub fn trap_mode(&self) -> Option { - let mode = self.bits & 0b11; - match mode { - 0 => Some(TrapMode::Direct), - 1 => Some(TrapMode::Vectored), - _ => None, - } - } +/// Sets the trap vector mode to `Direct`. +#[inline] +pub fn set_direct() { + let mut local = read_local(); + local.write(mode::Direct); + write_local(local); } -read_csr_as!(Mtvec, 0x305); - -write_csr!(0x305); +/// Sets the trap vector mode to `Vectored`. +#[inline] +pub fn set_vectored() { + let mut local = read_local(); + local.write(mode::Vectored); + write_local(local); +} -/// Writes the CSR +/// Sets the trap vector base. #[inline] -pub unsafe fn write(addr: usize, mode: TrapMode) { - let bits = addr + mode as usize; - _write(bits); +pub fn set_base(base_val: usize) { + let mut local = read_local(); + local.write(base.val(base_val)); + write_local(local); }