diff --git a/Cargo.toml b/Cargo.toml index 12fb17d..307be96 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "riscv" -version = "0.5.3" +version = "0.5.4" repository = "https://github.com/rust-embedded/riscv" authors = ["The RISC-V Team "] categories = ["embedded", "hardware-support", "no-std"] diff --git a/asm.S b/asm.S index 3f7202d..c6c293b 100644 --- a/asm.S +++ b/asm.S @@ -24,37 +24,252 @@ __sfence_vma: sfence.vma a0, a1 ret -REG_READ_WRITE(fcsr, 0x003) -REG_SET_CLEAR(fcsr, 0x003) +// User Trap Setup +RW(0x000, ustatus) // User status register +RW(0x004, uie) // User interrupt-enable register +RW(0x005, utvec) // User trap handler base address -// 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_WRITE(mstatus, 0x300) -REG_SET_CLEAR(mstatus, 0x300) -REG_READ_WRITE(mtvec, 0x305) -REG_READ(mvendorid, 0xF11) -REG_READ(marchid, 0xF12) -REG_READ(mimpid, 0xF13) -REG_READ(mhartid, 0xF14) +// User Trap Handling +RW(0x040, uscratch) // Scratch register for user trap handlers +RW(0x041, uepc) // User exception program counter +RW(0x042, ucause) // User trap cause +RW(0x043, utval) // User bad address or instruction +RW(0x044, uip) // User interrupt pending -// 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_WRITE(sstatus, 0x100) -REG_SET_CLEAR(sstatus, 0x100) -REG_READ(stval, 0x143) -REG_READ_WRITE(stvec, 0x105) +// User Floating-Point CSRs +RW(0x001, fflags) // Floating-Point Accrued Exceptions +RW(0x002, frm) // Floating-Point Dynamic Rounding Mode +RW(0x003, fcsr) // Floating-Point Control and Status Register (frm + fflags) -REG_READ(time, 0xC01) +// User Counter/Timers +RO( 0xC00, cycle) // Cycle counter for RDCYCLE instruction +RO( 0xC01, time) // Timer for RDTIME instruction +RO( 0xC02, instret) // Instructions-retired counter for RDINSTRET instruction +RO( 0xC03, hpmcounter3) // Performance-monitoring counter +RO( 0xC04, hpmcounter4) // Performance-monitoring counter +RO( 0xC05, hpmcounter5) // Performance-monitoring counter +RO( 0xC06, hpmcounter6) // Performance-monitoring counter +RO( 0xC07, hpmcounter7) // Performance-monitoring counter +RO( 0xC08, hpmcounter8) // Performance-monitoring counter +RO( 0xC09, hpmcounter9) // Performance-monitoring counter +RO( 0xC0A, hpmcounter10) // Performance-monitoring counter +RO( 0xC0B, hpmcounter11) // Performance-monitoring counter +RO( 0xC0C, hpmcounter12) // Performance-monitoring counter +RO( 0xC0D, hpmcounter13) // Performance-monitoring counter +RO( 0xC0E, hpmcounter14) // Performance-monitoring counter +RO( 0xC0F, hpmcounter15) // Performance-monitoring counter +RO( 0xC10, hpmcounter16) // Performance-monitoring counter +RO( 0xC11, hpmcounter17) // Performance-monitoring counter +RO( 0xC12, hpmcounter18) // Performance-monitoring counter +RO( 0xC13, hpmcounter19) // Performance-monitoring counter +RO( 0xC14, hpmcounter20) // Performance-monitoring counter +RO( 0xC15, hpmcounter21) // Performance-monitoring counter +RO( 0xC16, hpmcounter22) // Performance-monitoring counter +RO( 0xC17, hpmcounter23) // Performance-monitoring counter +RO( 0xC18, hpmcounter24) // Performance-monitoring counter +RO( 0xC19, hpmcounter25) // Performance-monitoring counter +RO( 0xC1A, hpmcounter26) // Performance-monitoring counter +RO( 0xC1B, hpmcounter27) // Performance-monitoring counter +RO( 0xC1C, hpmcounter28) // Performance-monitoring counter +RO( 0xC1D, hpmcounter29) // Performance-monitoring counter +RO( 0xC1E, hpmcounter30) // Performance-monitoring counter +RO( 0xC1F, hpmcounter31) // Performance-monitoring counter +RO32(0xC80, cycleh) // Upper 32 bits of cycle, RV32I only +RO32(0xC81, timeh) // Upper 32 bits of time, RV32I only +RO32(0xC82, instreth) // Upper 32 bits of instret, RV32I only +RO32(0xC83, hpmcounter3h) // Upper 32 bits of hpmcounter3, RV32I only +RO32(0xC84, hpmcounter4h) +RO32(0xC85, hpmcounter5h) +RO32(0xC86, hpmcounter6h) +RO32(0xC87, hpmcounter7h) +RO32(0xC88, hpmcounter8h) +RO32(0xC89, hpmcounter9h) +RO32(0xC8A, hpmcounter10h) +RO32(0xC8B, hpmcounter11h) +RO32(0xC8C, hpmcounter12h) +RO32(0xC8D, hpmcounter13h) +RO32(0xC8E, hpmcounter14h) +RO32(0xC8F, hpmcounter15h) +RO32(0xC90, hpmcounter16h) +RO32(0xC91, hpmcounter17h) +RO32(0xC92, hpmcounter18h) +RO32(0xC93, hpmcounter19h) +RO32(0xC94, hpmcounter20h) +RO32(0xC95, hpmcounter21h) +RO32(0xC96, hpmcounter22h) +RO32(0xC97, hpmcounter23h) +RO32(0xC98, hpmcounter24h) +RO32(0xC99, hpmcounter25h) +RO32(0xC9A, hpmcounter26h) +RO32(0xC9B, hpmcounter27h) +RO32(0xC9C, hpmcounter28h) +RO32(0xC9D, hpmcounter29h) +RO32(0xC9E, hpmcounter30h) +RO32(0xC9F, hpmcounter31h) + +// Supervisor Trap Setup +RW(0x100, sstatus) // Supervisor status register +RW(0x102, sedeleg) // Supervisor exception delegation register +RW(0x103, sideleg) // Supervisor interrupt delegation register +RW(0x104, sie) // Supervisor interrupt-enable register +RW(0x105, stvec) // Supervisor trap handler base address +RW(0x106, scounteren) // Supervisor counter enable + +// Supervisor Trap Handling +RW(0x140, sscratch) // Scratch register for supervisor trap handlers +RW(0x141, sepc) // Supervisor exception program counter +RW(0x142, scause) // Supervisor trap cause +RW(0x143, stval) // Supervisor bad address or instruction +RW(0x144, sip) // Supervisor interrupt pending + +// Supervisor Protection and Translation +RW(0x180, satp) // Supervisor address translation and protection + +// Machine Information Registers +RO(0xF11, mvendorid) // Vendor ID +RO(0xF12, marchid) // Architecture ID +RO(0xF13, mimpid) // Implementation ID +RO(0xF14, mhartid) // Hardware thread ID + +// Machine Trap Setup +RW(0x300, mstatus) // Machine status register +RW(0x301, misa) // ISA and extensions +RW(0x302, medeleg) // Machine exception delegation register +RW(0x303, mideleg) // Machine interrupt delegation register +RW(0x304, mie) // Machine interrupt-enable register +RW(0x305, mtvec) // Machine trap handler base address +RW(0x306, mcounteren) // Machine counter enable + +// Machine Trap Handling +RW(0x340, mscratch) // Scratch register for machine trap handlers +RW(0x341, mepc) // Machine exception program counter +RW(0x342, mcause) // Machine trap cause +RW(0x343, mtval) // Machine bad address or instruction +RW(0x344, mip) // Machine interrupt pending + +// Machine Protection and Translation +RW( 0x3A0, pmpcfg0) // Physical memory protection configuration +RW32(0x3A1, pmpcfg1) // Physical memory protection configuration, RV32 only +RW( 0x3A2, pmpcfg2) // Physical memory protection configuration +RW32(0x3A3, pmpcfg3) // Physical memory protection configuration, RV32 only +RW( 0x3B0, pmpaddr0) // Physical memory protection address register +RW( 0x3B1, pmpaddr1) // Physical memory protection address register +RW( 0x3B2, pmpaddr2) // Physical memory protection address register +RW( 0x3B3, pmpaddr3) // Physical memory protection address register +RW( 0x3B4, pmpaddr4) // Physical memory protection address register +RW( 0x3B5, pmpaddr5) // Physical memory protection address register +RW( 0x3B6, pmpaddr6) // Physical memory protection address register +RW( 0x3B7, pmpaddr7) // Physical memory protection address register +RW( 0x3B8, pmpaddr8) // Physical memory protection address register +RW( 0x3B9, pmpaddr9) // Physical memory protection address register +RW( 0x3BA, pmpaddr10) // Physical memory protection address register +RW( 0x3BB, pmpaddr11) // Physical memory protection address register +RW( 0x3BC, pmpaddr12) // Physical memory protection address register +RW( 0x3BD, pmpaddr13) // Physical memory protection address register +RW( 0x3BE, pmpaddr14) // Physical memory protection address register +RW( 0x3BF, pmpaddr15) // Physical memory protection address register + +// Machine Counter/Timers +RO( 0xB00, mcycle) // Machine cycle counter +RO( 0xB02, minstret) // Machine instructions-retired counter +RO( 0xB03, mhpmcounter3) // Machine performance-monitoring counter +RO( 0xB04, mhpmcounter4) // Machine performance-monitoring counter +RO( 0xB05, mhpmcounter5) // Machine performance-monitoring counter +RO( 0xB06, mhpmcounter6) // Machine performance-monitoring counter +RO( 0xB07, mhpmcounter7) // Machine performance-monitoring counter +RO( 0xB08, mhpmcounter8) // Machine performance-monitoring counter +RO( 0xB09, mhpmcounter9) // Machine performance-monitoring counter +RO( 0xB0A, mhpmcounter10) // Machine performance-monitoring counter +RO( 0xB0B, mhpmcounter11) // Machine performance-monitoring counter +RO( 0xB0C, mhpmcounter12) // Machine performance-monitoring counter +RO( 0xB0D, mhpmcounter13) // Machine performance-monitoring counter +RO( 0xB0E, mhpmcounter14) // Machine performance-monitoring counter +RO( 0xB0F, mhpmcounter15) // Machine performance-monitoring counter +RO( 0xB10, mhpmcounter16) // Machine performance-monitoring counter +RO( 0xB11, mhpmcounter17) // Machine performance-monitoring counter +RO( 0xB12, mhpmcounter18) // Machine performance-monitoring counter +RO( 0xB13, mhpmcounter19) // Machine performance-monitoring counter +RO( 0xB14, mhpmcounter20) // Machine performance-monitoring counter +RO( 0xB15, mhpmcounter21) // Machine performance-monitoring counter +RO( 0xB16, mhpmcounter22) // Machine performance-monitoring counter +RO( 0xB17, mhpmcounter23) // Machine performance-monitoring counter +RO( 0xB18, mhpmcounter24) // Machine performance-monitoring counter +RO( 0xB19, mhpmcounter25) // Machine performance-monitoring counter +RO( 0xB1A, mhpmcounter26) // Machine performance-monitoring counter +RO( 0xB1B, mhpmcounter27) // Machine performance-monitoring counter +RO( 0xB1C, mhpmcounter28) // Machine performance-monitoring counter +RO( 0xB1D, mhpmcounter29) // Machine performance-monitoring counter +RO( 0xB1E, mhpmcounter30) // Machine performance-monitoring counter +RO( 0xB1F, mhpmcounter31) // Machine performance-monitoring counter +RO32(0xB80, mcycleh) // Upper 32 bits of mcycle, RV32I only +RO32(0xB82, minstreth) // Upper 32 bits of minstret, RV32I only +RO32(0xB83, mhpmcounter3h) // Upper 32 bits of mhpmcounter3, RV32I only +RO32(0xB84, mhpmcounter4h) +RO32(0xB85, mhpmcounter5h) +RO32(0xB86, mhpmcounter6h) +RO32(0xB87, mhpmcounter7h) +RO32(0xB88, mhpmcounter8h) +RO32(0xB89, mhpmcounter9h) +RO32(0xB8A, mhpmcounter10h) +RO32(0xB8B, mhpmcounter11h) +RO32(0xB8C, mhpmcounter12h) +RO32(0xB8D, mhpmcounter13h) +RO32(0xB8E, mhpmcounter14h) +RO32(0xB8F, mhpmcounter15h) +RO32(0xB90, mhpmcounter16h) +RO32(0xB91, mhpmcounter17h) +RO32(0xB92, mhpmcounter18h) +RO32(0xB93, mhpmcounter19h) +RO32(0xB94, mhpmcounter20h) +RO32(0xB95, mhpmcounter21h) +RO32(0xB96, mhpmcounter22h) +RO32(0xB97, mhpmcounter23h) +RO32(0xB98, mhpmcounter24h) +RO32(0xB99, mhpmcounter25h) +RO32(0xB9A, mhpmcounter26h) +RO32(0xB9B, mhpmcounter27h) +RO32(0xB9C, mhpmcounter28h) +RO32(0xB9D, mhpmcounter29h) +RO32(0xB9E, mhpmcounter30h) +RO32(0xB9F, mhpmcounter31h) + +RW(0x323, mhpmevent3) // Machine performance-monitoring event selector +RW(0x324, mhpmevent4) // Machine performance-monitoring event selector +RW(0x325, mhpmevent5) // Machine performance-monitoring event selector +RW(0x326, mhpmevent6) // Machine performance-monitoring event selector +RW(0x327, mhpmevent7) // Machine performance-monitoring event selector +RW(0x328, mhpmevent8) // Machine performance-monitoring event selector +RW(0x329, mhpmevent9) // Machine performance-monitoring event selector +RW(0x32A, mhpmevent10) // Machine performance-monitoring event selector +RW(0x32B, mhpmevent11) // Machine performance-monitoring event selector +RW(0x32C, mhpmevent12) // Machine performance-monitoring event selector +RW(0x32D, mhpmevent13) // Machine performance-monitoring event selector +RW(0x32E, mhpmevent14) // Machine performance-monitoring event selector +RW(0x32F, mhpmevent15) // Machine performance-monitoring event selector +RW(0x330, mhpmevent16) // Machine performance-monitoring event selector +RW(0x331, mhpmevent17) // Machine performance-monitoring event selector +RW(0x332, mhpmevent18) // Machine performance-monitoring event selector +RW(0x333, mhpmevent19) // Machine performance-monitoring event selector +RW(0x334, mhpmevent20) // Machine performance-monitoring event selector +RW(0x335, mhpmevent21) // Machine performance-monitoring event selector +RW(0x336, mhpmevent22) // Machine performance-monitoring event selector +RW(0x337, mhpmevent23) // Machine performance-monitoring event selector +RW(0x338, mhpmevent24) // Machine performance-monitoring event selector +RW(0x339, mhpmevent25) // Machine performance-monitoring event selector +RW(0x33A, mhpmevent26) // Machine performance-monitoring event selector +RW(0x33B, mhpmevent27) // Machine performance-monitoring event selector +RW(0x33C, mhpmevent28) // Machine performance-monitoring event selector +RW(0x33D, mhpmevent29) // Machine performance-monitoring event selector +RW(0x33E, mhpmevent30) // Machine performance-monitoring event selector +RW(0x33F, mhpmevent31) // Machine performance-monitoring event selector + +// Debug/Trace Registers (shared with Debug Mode) +RW(0x7A0, tselect) // Debug/Trace trigger register select +RW(0x7A1, tdata1) // First Debug/Trace trigger data register +RW(0x7A2, tdata2) // Second Debug/Trace trigger data register +RW(0x7A3, tdata3) // Third Debug/Trace trigger data register + +// Debug Mode Registers +RW(0x7B0, dcsr) // Debug control and status register +RW(0x7B1, dpc) // Debug PC +RW(0x7B2, dscratch) // Debug scratch register diff --git a/asm.h b/asm.h index 3ec97f2..2b675e7 100644 --- a/asm.h +++ b/asm.h @@ -33,5 +33,16 @@ __clear_ ## name: \ #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) +#define RW(offset, name) REG_READ_WRITE(name, offset); REG_SET_CLEAR(name, offset) +#define RO(offset, name) REG_READ(name, offset) + +#if __riscv_xlen == 32 +#define RW32(offset, name) RW(offset, name) +#define RO32(offset, name) RO(offset, name) +#else +#define RW32(offset, name) +#define RO32(offset, name) +#endif + #endif /* __ASM_H */ diff --git a/asm32.S b/asm32.S deleted file mode 100644 index c163b64..0000000 --- a/asm32.S +++ /dev/null @@ -1,5 +0,0 @@ -#include "asm.h" - -REG_READ(mcycleh, 0xB80) -REG_READ(minstreth, 0xB82) -REG_READ(timeh, 0xC81) diff --git a/assemble.sh b/assemble.sh index e89b5d5..a24df9e 100755 --- a/assemble.sh +++ b/assemble.sh @@ -7,14 +7,12 @@ 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 -ar crs bin/riscv32imc-unknown-none-elf.a bin/$crate.o bin/$crate-32.o +riscv64-unknown-elf-gcc -c -mabi=ilp32 -march=rv32imc asm.S -o bin/$crate.o +ar crs bin/riscv32imac-unknown-none-elf.a bin/$crate.o +ar crs bin/riscv32imc-unknown-none-elf.a bin/$crate.o riscv64-unknown-elf-gcc -c -mabi=lp64 -march=rv64imac asm.S -o bin/$crate.o ar crs bin/riscv64imac-unknown-none-elf.a bin/$crate.o ar crs bin/riscv64gc-unknown-none-elf.a bin/$crate.o 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 index 2daa460..bd60165 100644 Binary files a/bin/riscv32imac-unknown-none-elf.a and b/bin/riscv32imac-unknown-none-elf.a differ diff --git a/bin/riscv32imc-unknown-none-elf.a b/bin/riscv32imc-unknown-none-elf.a index 2daa460..bd60165 100644 Binary files a/bin/riscv32imc-unknown-none-elf.a and b/bin/riscv32imc-unknown-none-elf.a differ diff --git a/bin/riscv64gc-unknown-none-elf.a b/bin/riscv64gc-unknown-none-elf.a index bc00a83..b1b370a 100644 Binary files a/bin/riscv64gc-unknown-none-elf.a and b/bin/riscv64gc-unknown-none-elf.a differ diff --git a/bin/riscv64imac-unknown-none-elf.a b/bin/riscv64imac-unknown-none-elf.a index bc00a83..b1b370a 100644 Binary files a/bin/riscv64imac-unknown-none-elf.a and b/bin/riscv64imac-unknown-none-elf.a differ diff --git a/src/register/fcsr.rs b/src/register/fcsr.rs index a6b2b13..ba204ff 100644 --- a/src/register/fcsr.rs +++ b/src/register/fcsr.rs @@ -64,6 +64,7 @@ impl Flags { } /// Rounding Mode +#[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum RoundingMode { RoundToNearestEven = 0b000, RoundTowardsZero = 0b001, diff --git a/src/register/hpmcounterx.rs b/src/register/hpmcounterx.rs new file mode 100644 index 0000000..5eb15b0 --- /dev/null +++ b/src/register/hpmcounterx.rs @@ -0,0 +1,82 @@ +macro_rules! reg { + ( + $addr:expr, $csrl:ident, $csrh:ident, $readf:ident, $writef:ident + ) => { + /// Performance-monitoring counter + pub mod $csrl { + read_csr_as_usize!($addr, $readf); + read_composite_csr!(super::$csrh::read(), read()); + } + } +} + +macro_rules! regh { + ( + $addr:expr, $csrh:ident, $readf:ident, $writef:ident + ) => { + /// Upper 32 bits of performance-monitoring counter (RV32I only) + pub mod $csrh { + read_csr_as_usize_rv32!($addr, $readf); + } + } +} + +reg!(0xC03, hpmcounter3, hpmcounter3h, __read_hpmcounter3, __write_hpmcounter3); +reg!(0xC04, hpmcounter4, hpmcounter4h, __read_hpmcounter4, __write_hpmcounter4); +reg!(0xC05, hpmcounter5, hpmcounter5h, __read_hpmcounter5, __write_hpmcounter5); +reg!(0xC06, hpmcounter6, hpmcounter6h, __read_hpmcounter6, __write_hpmcounter6); +reg!(0xC07, hpmcounter7, hpmcounter7h, __read_hpmcounter7, __write_hpmcounter7); +reg!(0xC08, hpmcounter8, hpmcounter8h, __read_hpmcounter8, __write_hpmcounter8); +reg!(0xC09, hpmcounter9, hpmcounter9h, __read_hpmcounter9, __write_hpmcounter9); +reg!(0xC0A, hpmcounter10, hpmcounter10h, __read_hpmcounter10, __write_hpmcounter10); +reg!(0xC0B, hpmcounter11, hpmcounter11h, __read_hpmcounter11, __write_hpmcounter11); +reg!(0xC0C, hpmcounter12, hpmcounter12h, __read_hpmcounter12, __write_hpmcounter12); +reg!(0xC0D, hpmcounter13, hpmcounter13h, __read_hpmcounter13, __write_hpmcounter13); +reg!(0xC0E, hpmcounter14, hpmcounter14h, __read_hpmcounter14, __write_hpmcounter14); +reg!(0xC0F, hpmcounter15, hpmcounter15h, __read_hpmcounter15, __write_hpmcounter15); +reg!(0xC10, hpmcounter16, hpmcounter16h, __read_hpmcounter16, __write_hpmcounter16); +reg!(0xC11, hpmcounter17, hpmcounter17h, __read_hpmcounter17, __write_hpmcounter17); +reg!(0xC12, hpmcounter18, hpmcounter18h, __read_hpmcounter18, __write_hpmcounter18); +reg!(0xC13, hpmcounter19, hpmcounter19h, __read_hpmcounter19, __write_hpmcounter19); +reg!(0xC14, hpmcounter20, hpmcounter20h, __read_hpmcounter20, __write_hpmcounter20); +reg!(0xC15, hpmcounter21, hpmcounter21h, __read_hpmcounter21, __write_hpmcounter21); +reg!(0xC16, hpmcounter22, hpmcounter22h, __read_hpmcounter22, __write_hpmcounter22); +reg!(0xC17, hpmcounter23, hpmcounter23h, __read_hpmcounter23, __write_hpmcounter23); +reg!(0xC18, hpmcounter24, hpmcounter24h, __read_hpmcounter24, __write_hpmcounter24); +reg!(0xC19, hpmcounter25, hpmcounter25h, __read_hpmcounter25, __write_hpmcounter25); +reg!(0xC1A, hpmcounter26, hpmcounter26h, __read_hpmcounter26, __write_hpmcounter26); +reg!(0xC1B, hpmcounter27, hpmcounter27h, __read_hpmcounter27, __write_hpmcounter27); +reg!(0xC1C, hpmcounter28, hpmcounter28h, __read_hpmcounter28, __write_hpmcounter28); +reg!(0xC1D, hpmcounter29, hpmcounter29h, __read_hpmcounter29, __write_hpmcounter29); +reg!(0xC1E, hpmcounter30, hpmcounter30h, __read_hpmcounter30, __write_hpmcounter30); +reg!(0xC1F, hpmcounter31, hpmcounter31h, __read_hpmcounter31, __write_hpmcounter31); + +regh!(0xC83, hpmcounter3h, __read_hpmcounter3h, __write_hpmcounter3h); +regh!(0xC84, hpmcounter4h, __read_hpmcounter4h, __write_hpmcounter4h); +regh!(0xC85, hpmcounter5h, __read_hpmcounter5h, __write_hpmcounter5h); +regh!(0xC86, hpmcounter6h, __read_hpmcounter6h, __write_hpmcounter6h); +regh!(0xC87, hpmcounter7h, __read_hpmcounter7h, __write_hpmcounter7h); +regh!(0xC88, hpmcounter8h, __read_hpmcounter8h, __write_hpmcounter8h); +regh!(0xC89, hpmcounter9h, __read_hpmcounter9h, __write_hpmcounter9h); +regh!(0xC8A, hpmcounter10h, __read_hpmcounter10h, __write_hpmcounter10h); +regh!(0xC8B, hpmcounter11h, __read_hpmcounter11h, __write_hpmcounter11h); +regh!(0xC8C, hpmcounter12h, __read_hpmcounter12h, __write_hpmcounter12h); +regh!(0xC8D, hpmcounter13h, __read_hpmcounter13h, __write_hpmcounter13h); +regh!(0xC8E, hpmcounter14h, __read_hpmcounter14h, __write_hpmcounter14h); +regh!(0xC8F, hpmcounter15h, __read_hpmcounter15h, __write_hpmcounter15h); +regh!(0xC90, hpmcounter16h, __read_hpmcounter16h, __write_hpmcounter16h); +regh!(0xC91, hpmcounter17h, __read_hpmcounter17h, __write_hpmcounter17h); +regh!(0xC92, hpmcounter18h, __read_hpmcounter18h, __write_hpmcounter18h); +regh!(0xC93, hpmcounter19h, __read_hpmcounter19h, __write_hpmcounter19h); +regh!(0xC94, hpmcounter20h, __read_hpmcounter20h, __write_hpmcounter20h); +regh!(0xC95, hpmcounter21h, __read_hpmcounter21h, __write_hpmcounter21h); +regh!(0xC96, hpmcounter22h, __read_hpmcounter22h, __write_hpmcounter22h); +regh!(0xC97, hpmcounter23h, __read_hpmcounter23h, __write_hpmcounter23h); +regh!(0xC98, hpmcounter24h, __read_hpmcounter24h, __write_hpmcounter24h); +regh!(0xC99, hpmcounter25h, __read_hpmcounter25h, __write_hpmcounter25h); +regh!(0xC9A, hpmcounter26h, __read_hpmcounter26h, __write_hpmcounter26h); +regh!(0xC9B, hpmcounter27h, __read_hpmcounter27h, __write_hpmcounter27h); +regh!(0xC9C, hpmcounter28h, __read_hpmcounter28h, __write_hpmcounter28h); +regh!(0xC9D, hpmcounter29h, __read_hpmcounter29h, __write_hpmcounter29h); +regh!(0xC9E, hpmcounter30h, __read_hpmcounter30h, __write_hpmcounter30h); +regh!(0xC9F, hpmcounter31h, __read_hpmcounter31h, __write_hpmcounter31h); diff --git a/src/register/macros.rs b/src/register/macros.rs index 02fc424..b71b4d4 100644 --- a/src/register/macros.rs +++ b/src/register/macros.rs @@ -118,6 +118,32 @@ macro_rules! write_csr { }; } +macro_rules! write_csr_rv32 { + ($csr_number:expr, $asm_fn: ident) => { + /// Writes the CSR + #[inline] + #[allow(unused_variables)] + unsafe fn _write(bits: usize) { + match () { + #[cfg(all(riscv32, feature = "inline-asm"))] + () => asm!("csrrw x0, $1, $0" :: "r"(bits), "i"($csr_number) :: "volatile"), + + #[cfg(all(riscv32, not(feature = "inline-asm")))] + () => { + extern "C" { + fn $asm_fn(bits: usize); + } + + $asm_fn(bits); + } + + #[cfg(not(riscv32))] + () => unimplemented!(), + } + } + }; +} + macro_rules! write_csr_as_usize { ($csr_number:expr, $asm_fn: ident) => { write_csr!($csr_number, $asm_fn); @@ -130,6 +156,18 @@ macro_rules! write_csr_as_usize { }; } +macro_rules! write_csr_as_usize_rv32 { + ($csr_number:expr, $asm_fn: ident) => { + write_csr_rv32!($csr_number, $asm_fn); + + /// Writes the CSR + #[inline] + pub fn write(bits: usize) { + unsafe{ _write(bits) } + } + }; +} + macro_rules! set { ($csr_number:expr, $asm_fn: ident) => { /// Set the CSR diff --git a/src/register/mcause.rs b/src/register/mcause.rs index 67e6d8c..e0e6ffb 100644 --- a/src/register/mcause.rs +++ b/src/register/mcause.rs @@ -7,14 +7,14 @@ pub struct Mcause { } /// Trap Cause -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum Trap { Interrupt(Interrupt), Exception(Exception), } /// Interrupt -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum Interrupt { UserSoft, SupervisorSoft, @@ -29,7 +29,7 @@ pub enum Interrupt { } /// Exception -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum Exception { InstructionMisaligned, InstructionFault, diff --git a/src/register/mepc.rs b/src/register/mepc.rs index 9871513..160dff5 100644 --- a/src/register/mepc.rs +++ b/src/register/mepc.rs @@ -1,3 +1,4 @@ //! mepc register read_csr_as_usize!(0x341, __read_mepc); +write_csr_as_usize!(0x341, __write_mepc); diff --git a/src/register/mhpmcounterx.rs b/src/register/mhpmcounterx.rs new file mode 100644 index 0000000..df3b6c4 --- /dev/null +++ b/src/register/mhpmcounterx.rs @@ -0,0 +1,84 @@ +macro_rules! reg { + ( + $addr:expr, $csrl:ident, $csrh:ident, $readf:ident, $writef:ident + ) => { + /// Machine performance-monitoring counter + pub mod $csrl { + read_csr_as_usize!($addr, $readf); + write_csr_as_usize!($addr, $writef); + read_composite_csr!(super::$csrh::read(), read()); + } + } +} + +macro_rules! regh { + ( + $addr:expr, $csrh:ident, $readf:ident, $writef:ident + ) => { + /// Upper 32 bits of machine performance-monitoring counter (RV32I only) + pub mod $csrh { + read_csr_as_usize_rv32!($addr, $readf); + write_csr_as_usize_rv32!($addr, $writef); + } + } +} + +reg!(0xB03, mhpmcounter3, mhpmcounter3h, __read_mhpmcounter3, __write_mhpmcounter3); +reg!(0xB04, mhpmcounter4, mhpmcounter4h, __read_mhpmcounter4, __write_mhpmcounter4); +reg!(0xB05, mhpmcounter5, mhpmcounter5h, __read_mhpmcounter5, __write_mhpmcounter5); +reg!(0xB06, mhpmcounter6, mhpmcounter6h, __read_mhpmcounter6, __write_mhpmcounter6); +reg!(0xB07, mhpmcounter7, mhpmcounter7h, __read_mhpmcounter7, __write_mhpmcounter7); +reg!(0xB08, mhpmcounter8, mhpmcounter8h, __read_mhpmcounter8, __write_mhpmcounter8); +reg!(0xB09, mhpmcounter9, mhpmcounter9h, __read_mhpmcounter9, __write_mhpmcounter9); +reg!(0xB0A, mhpmcounter10, mhpmcounter10h, __read_mhpmcounter10, __write_mhpmcounter10); +reg!(0xB0B, mhpmcounter11, mhpmcounter11h, __read_mhpmcounter11, __write_mhpmcounter11); +reg!(0xB0C, mhpmcounter12, mhpmcounter12h, __read_mhpmcounter12, __write_mhpmcounter12); +reg!(0xB0D, mhpmcounter13, mhpmcounter13h, __read_mhpmcounter13, __write_mhpmcounter13); +reg!(0xB0E, mhpmcounter14, mhpmcounter14h, __read_mhpmcounter14, __write_mhpmcounter14); +reg!(0xB0F, mhpmcounter15, mhpmcounter15h, __read_mhpmcounter15, __write_mhpmcounter15); +reg!(0xB10, mhpmcounter16, mhpmcounter16h, __read_mhpmcounter16, __write_mhpmcounter16); +reg!(0xB11, mhpmcounter17, mhpmcounter17h, __read_mhpmcounter17, __write_mhpmcounter17); +reg!(0xB12, mhpmcounter18, mhpmcounter18h, __read_mhpmcounter18, __write_mhpmcounter18); +reg!(0xB13, mhpmcounter19, mhpmcounter19h, __read_mhpmcounter19, __write_mhpmcounter19); +reg!(0xB14, mhpmcounter20, mhpmcounter20h, __read_mhpmcounter20, __write_mhpmcounter20); +reg!(0xB15, mhpmcounter21, mhpmcounter21h, __read_mhpmcounter21, __write_mhpmcounter21); +reg!(0xB16, mhpmcounter22, mhpmcounter22h, __read_mhpmcounter22, __write_mhpmcounter22); +reg!(0xB17, mhpmcounter23, mhpmcounter23h, __read_mhpmcounter23, __write_mhpmcounter23); +reg!(0xB18, mhpmcounter24, mhpmcounter24h, __read_mhpmcounter24, __write_mhpmcounter24); +reg!(0xB19, mhpmcounter25, mhpmcounter25h, __read_mhpmcounter25, __write_mhpmcounter25); +reg!(0xB1A, mhpmcounter26, mhpmcounter26h, __read_mhpmcounter26, __write_mhpmcounter26); +reg!(0xB1B, mhpmcounter27, mhpmcounter27h, __read_mhpmcounter27, __write_mhpmcounter27); +reg!(0xB1C, mhpmcounter28, mhpmcounter28h, __read_mhpmcounter28, __write_mhpmcounter28); +reg!(0xB1D, mhpmcounter29, mhpmcounter29h, __read_mhpmcounter29, __write_mhpmcounter29); +reg!(0xB1E, mhpmcounter30, mhpmcounter30h, __read_mhpmcounter30, __write_mhpmcounter30); +reg!(0xB1F, mhpmcounter31, mhpmcounter31h, __read_mhpmcounter31, __write_mhpmcounter31); + +regh!(0xB83, mhpmcounter3h, __read_mhpmcounter3h, __write_mhpmcounter3h); +regh!(0xB84, mhpmcounter4h, __read_mhpmcounter4h, __write_mhpmcounter4h); +regh!(0xB85, mhpmcounter5h, __read_mhpmcounter5h, __write_mhpmcounter5h); +regh!(0xB86, mhpmcounter6h, __read_mhpmcounter6h, __write_mhpmcounter6h); +regh!(0xB87, mhpmcounter7h, __read_mhpmcounter7h, __write_mhpmcounter7h); +regh!(0xB88, mhpmcounter8h, __read_mhpmcounter8h, __write_mhpmcounter8h); +regh!(0xB89, mhpmcounter9h, __read_mhpmcounter9h, __write_mhpmcounter9h); +regh!(0xB8A, mhpmcounter10h, __read_mhpmcounter10h, __write_mhpmcounter10h); +regh!(0xB8B, mhpmcounter11h, __read_mhpmcounter11h, __write_mhpmcounter11h); +regh!(0xB8C, mhpmcounter12h, __read_mhpmcounter12h, __write_mhpmcounter12h); +regh!(0xB8D, mhpmcounter13h, __read_mhpmcounter13h, __write_mhpmcounter13h); +regh!(0xB8E, mhpmcounter14h, __read_mhpmcounter14h, __write_mhpmcounter14h); +regh!(0xB8F, mhpmcounter15h, __read_mhpmcounter15h, __write_mhpmcounter15h); +regh!(0xB90, mhpmcounter16h, __read_mhpmcounter16h, __write_mhpmcounter16h); +regh!(0xB91, mhpmcounter17h, __read_mhpmcounter17h, __write_mhpmcounter17h); +regh!(0xB92, mhpmcounter18h, __read_mhpmcounter18h, __write_mhpmcounter18h); +regh!(0xB93, mhpmcounter19h, __read_mhpmcounter19h, __write_mhpmcounter19h); +regh!(0xB94, mhpmcounter20h, __read_mhpmcounter20h, __write_mhpmcounter20h); +regh!(0xB95, mhpmcounter21h, __read_mhpmcounter21h, __write_mhpmcounter21h); +regh!(0xB96, mhpmcounter22h, __read_mhpmcounter22h, __write_mhpmcounter22h); +regh!(0xB97, mhpmcounter23h, __read_mhpmcounter23h, __write_mhpmcounter23h); +regh!(0xB98, mhpmcounter24h, __read_mhpmcounter24h, __write_mhpmcounter24h); +regh!(0xB99, mhpmcounter25h, __read_mhpmcounter25h, __write_mhpmcounter25h); +regh!(0xB9A, mhpmcounter26h, __read_mhpmcounter26h, __write_mhpmcounter26h); +regh!(0xB9B, mhpmcounter27h, __read_mhpmcounter27h, __write_mhpmcounter27h); +regh!(0xB9C, mhpmcounter28h, __read_mhpmcounter28h, __write_mhpmcounter28h); +regh!(0xB9D, mhpmcounter29h, __read_mhpmcounter29h, __write_mhpmcounter29h); +regh!(0xB9E, mhpmcounter30h, __read_mhpmcounter30h, __write_mhpmcounter30h); +regh!(0xB9F, mhpmcounter31h, __read_mhpmcounter31h, __write_mhpmcounter31h); diff --git a/src/register/mhpmeventx.rs b/src/register/mhpmeventx.rs new file mode 100644 index 0000000..78f6fef --- /dev/null +++ b/src/register/mhpmeventx.rs @@ -0,0 +1,41 @@ +macro_rules! reg { + ( + $addr:expr, $csr:ident, $readf:ident, $writef:ident + ) => { + /// Machine performance-monitoring event selector + pub mod $csr { + read_csr_as_usize!($addr, $readf); + write_csr_as_usize!($addr, $writef); + } + } +} + +reg!(0x323, mhpmevent3, __read_mhpmevent3, __write_mhpmevent3); +reg!(0x324, mhpmevent4, __read_mhpmevent4, __write_mhpmevent4); +reg!(0x325, mhpmevent5, __read_mhpmevent5, __write_mhpmevent5); +reg!(0x326, mhpmevent6, __read_mhpmevent6, __write_mhpmevent6); +reg!(0x327, mhpmevent7, __read_mhpmevent7, __write_mhpmevent7); +reg!(0x328, mhpmevent8, __read_mhpmevent8, __write_mhpmevent8); +reg!(0x329, mhpmevent9, __read_mhpmevent9, __write_mhpmevent9); +reg!(0x32A, mhpmevent10, __read_mhpmevent10, __write_mhpmevent10); +reg!(0x32B, mhpmevent11, __read_mhpmevent11, __write_mhpmevent11); +reg!(0x32C, mhpmevent12, __read_mhpmevent12, __write_mhpmevent12); +reg!(0x32D, mhpmevent13, __read_mhpmevent13, __write_mhpmevent13); +reg!(0x32E, mhpmevent14, __read_mhpmevent14, __write_mhpmevent14); +reg!(0x32F, mhpmevent15, __read_mhpmevent15, __write_mhpmevent15); +reg!(0x330, mhpmevent16, __read_mhpmevent16, __write_mhpmevent16); +reg!(0x331, mhpmevent17, __read_mhpmevent17, __write_mhpmevent17); +reg!(0x332, mhpmevent18, __read_mhpmevent18, __write_mhpmevent18); +reg!(0x333, mhpmevent19, __read_mhpmevent19, __write_mhpmevent19); +reg!(0x334, mhpmevent20, __read_mhpmevent20, __write_mhpmevent20); +reg!(0x335, mhpmevent21, __read_mhpmevent21, __write_mhpmevent21); +reg!(0x336, mhpmevent22, __read_mhpmevent22, __write_mhpmevent22); +reg!(0x337, mhpmevent23, __read_mhpmevent23, __write_mhpmevent23); +reg!(0x338, mhpmevent24, __read_mhpmevent24, __write_mhpmevent24); +reg!(0x339, mhpmevent25, __read_mhpmevent25, __write_mhpmevent25); +reg!(0x33A, mhpmevent26, __read_mhpmevent26, __write_mhpmevent26); +reg!(0x33B, mhpmevent27, __read_mhpmevent27, __write_mhpmevent27); +reg!(0x33C, mhpmevent28, __read_mhpmevent28, __write_mhpmevent28); +reg!(0x33D, mhpmevent29, __read_mhpmevent29, __write_mhpmevent29); +reg!(0x33E, mhpmevent30, __read_mhpmevent30, __write_mhpmevent30); +reg!(0x33F, mhpmevent31, __read_mhpmevent31, __write_mhpmevent31); diff --git a/src/register/misa.rs b/src/register/misa.rs index 44ae950..792e22c 100644 --- a/src/register/misa.rs +++ b/src/register/misa.rs @@ -9,6 +9,7 @@ pub struct Misa { } /// Machine XLEN +#[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum MXL { XLEN32, XLEN64, diff --git a/src/register/mod.rs b/src/register/mod.rs index d7219ec..82fb0a1 100644 --- a/src/register/mod.rs +++ b/src/register/mod.rs @@ -13,33 +13,91 @@ #[macro_use] mod macros; +// TODO: User Trap Setup + + +// TODO: User Trap Handling + + +// User Floating-Point CSRs +// TODO: frm, fflags pub mod fcsr; -pub mod marchid; -pub mod mcause; -pub mod mcycle; -pub mod mcycleh; -pub mod mepc; -pub mod mhartid; -pub mod mie; -pub mod mimpid; -pub mod minstret; -pub mod minstreth; -pub mod mip; -pub mod misa; -pub mod mstatus; -pub mod mtvec; -pub mod mvendorid; +// User Counter/Timers +// TODO: cycle[h], instret[h] +pub mod time; +mod hpmcounterx; +pub use self::hpmcounterx::*; +pub mod timeh; + + +// Supervisor Trap Setup +// TODO: sedeleg, sideleg pub mod sstatus; -pub mod stvec; pub mod sie; -pub mod sip; -pub mod scause; -pub mod stval; -pub mod satp; +pub mod stvec; +// TODO: scounteren + + +// Supervisor Trap Handling pub mod sscratch; pub mod sepc; +pub mod scause; +pub mod stval; +pub mod sip; -pub mod time; -pub mod timeh; + +// Supervisor Protection and Translation +pub mod satp; + + +// Machine Information Registers +pub mod mvendorid; +pub mod marchid; +pub mod mimpid; +pub mod mhartid; + + +// Machine Trap Setup +pub mod mstatus; +pub mod misa; +// TODO: medeleg, mideleg +pub mod mie; +pub mod mtvec; +// TODO: mcounteren + + +// Machine Trap Handling +pub mod mscratch; +pub mod mepc; +pub mod mcause; +pub mod mtval; +pub mod mip; + + +// Machine Protection and Translation +mod pmpcfgx; +pub use self::pmpcfgx::*; +mod pmpaddrx; +pub use self::pmpaddrx::*; + + +// Machine Counter/Timers +pub mod mcycle; +pub mod minstret; +mod mhpmcounterx; +pub use self::mhpmcounterx::*; +pub mod mcycleh; +pub mod minstreth; + + +// Machine Counter Setup +mod mhpmeventx; +pub use self::mhpmeventx::*; + + +// TODO: Debug/Trace Registers (shared with Debug Mode) + + +// TODO: Debug Mode Registers diff --git a/src/register/mscratch.rs b/src/register/mscratch.rs new file mode 100644 index 0000000..c5ef9fe --- /dev/null +++ b/src/register/mscratch.rs @@ -0,0 +1,4 @@ +//! mscratch register + +read_csr_as_usize!(0x340, __read_mscratch); +write_csr_as_usize!(0x340, __write_mscratch); diff --git a/src/register/mstatus.rs b/src/register/mstatus.rs index 3988097..9693918 100644 --- a/src/register/mstatus.rs +++ b/src/register/mstatus.rs @@ -10,6 +10,7 @@ pub struct Mstatus { } /// Additional extension state +#[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum XS { /// All off AllOff = 0, @@ -25,6 +26,7 @@ pub enum XS { } /// Floating-point extension state +#[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum FS { Off = 0, Initial = 1, @@ -33,6 +35,7 @@ pub enum FS { } /// Machine Previous Privilege Mode +#[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum MPP { Machine = 3, Supervisor = 1, @@ -40,6 +43,7 @@ pub enum MPP { } /// Supervisor Previous Privilege Mode +#[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum SPP { Supervisor = 1, User = 0, diff --git a/src/register/mtval.rs b/src/register/mtval.rs new file mode 100644 index 0000000..2afb7cb --- /dev/null +++ b/src/register/mtval.rs @@ -0,0 +1,3 @@ +//! mtval register + +read_csr_as_usize!(0x343, __read_mtval); diff --git a/src/register/mtvec.rs b/src/register/mtvec.rs index d4f8c07..247e05f 100644 --- a/src/register/mtvec.rs +++ b/src/register/mtvec.rs @@ -7,6 +7,7 @@ pub struct Mtvec { } /// Trap mode +#[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum TrapMode { Direct = 0, Vectored = 1, diff --git a/src/register/pmpaddrx.rs b/src/register/pmpaddrx.rs new file mode 100644 index 0000000..d615dde --- /dev/null +++ b/src/register/pmpaddrx.rs @@ -0,0 +1,28 @@ +macro_rules! reg { + ( + $addr:expr, $csr:ident, $readf:ident, $writef:ident + ) => { + /// Physical memory protection address register + pub mod $csr { + read_csr_as_usize!($addr, $readf); + write_csr_as_usize!($addr, $writef); + } + } +} + +reg!(0x3B0, pmpaddr0, __read_pmpaddr0, __write_pmpaddr0); +reg!(0x3B1, pmpaddr1, __read_pmpaddr1, __write_pmpaddr1); +reg!(0x3B2, pmpaddr2, __read_pmpaddr2, __write_pmpaddr2); +reg!(0x3B3, pmpaddr3, __read_pmpaddr3, __write_pmpaddr3); +reg!(0x3B4, pmpaddr4, __read_pmpaddr4, __write_pmpaddr4); +reg!(0x3B5, pmpaddr5, __read_pmpaddr5, __write_pmpaddr5); +reg!(0x3B6, pmpaddr6, __read_pmpaddr6, __write_pmpaddr6); +reg!(0x3B7, pmpaddr7, __read_pmpaddr7, __write_pmpaddr7); +reg!(0x3B8, pmpaddr8, __read_pmpaddr8, __write_pmpaddr8); +reg!(0x3B9, pmpaddr9, __read_pmpaddr9, __write_pmpaddr9); +reg!(0x3BA, pmpaddr10, __read_pmpaddr10, __write_pmpaddr10); +reg!(0x3BB, pmpaddr11, __read_pmpaddr11, __write_pmpaddr11); +reg!(0x3BC, pmpaddr12, __read_pmpaddr12, __write_pmpaddr12); +reg!(0x3BD, pmpaddr13, __read_pmpaddr13, __write_pmpaddr13); +reg!(0x3BE, pmpaddr14, __read_pmpaddr14, __write_pmpaddr14); +reg!(0x3BF, pmpaddr15, __read_pmpaddr15, __write_pmpaddr15); diff --git a/src/register/pmpcfgx.rs b/src/register/pmpcfgx.rs new file mode 100644 index 0000000..ec27251 --- /dev/null +++ b/src/register/pmpcfgx.rs @@ -0,0 +1,23 @@ +/// Physical memory protection configuration +pub mod pmpcfg0 { + read_csr_as_usize!(0x3A0, __read_pmpcfg0); + write_csr_as_usize!(0x3A0, __write_pmpcfg0); +} + +/// Physical memory protection configuration, RV32 only +pub mod pmpcfg1 { + read_csr_as_usize_rv32!(0x3A1, __read_pmpcfg1); + write_csr_as_usize_rv32!(0x3A1, __write_pmpcfg1); +} + +/// Physical memory protection configuration +pub mod pmpcfg2 { + read_csr_as_usize!(0x3A2, __read_pmpcfg2); + write_csr_as_usize!(0x3A2, __write_pmpcfg2); +} + +/// Physical memory protection configuration, RV32 only +pub mod pmpcfg3 { + read_csr_as_usize_rv32!(0x3A3, __read_pmpcfg3); + write_csr_as_usize_rv32!(0x3A3, __write_pmpcfg3); +} diff --git a/src/register/satp.rs b/src/register/satp.rs index fa0c6ee..ffd347c 100644 --- a/src/register/satp.rs +++ b/src/register/satp.rs @@ -70,12 +70,14 @@ impl Satp { } #[cfg(riscv32)] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum Mode { Bare = 0, Sv32 = 1, } #[cfg(riscv64)] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum Mode { Bare = 0, Sv39 = 8, diff --git a/src/register/scause.rs b/src/register/scause.rs index 596ccef..0172f07 100644 --- a/src/register/scause.rs +++ b/src/register/scause.rs @@ -10,14 +10,14 @@ pub struct Scause { } /// Trap Cause -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum Trap { Interrupt(Interrupt), Exception(Exception), } /// Interrupt -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum Interrupt { UserSoft, SupervisorSoft, @@ -29,7 +29,7 @@ pub enum Interrupt { } /// Exception -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum Exception { InstructionMisaligned, InstructionFault, diff --git a/src/register/sstatus.rs b/src/register/sstatus.rs index ec4765a..550aaf2 100644 --- a/src/register/sstatus.rs +++ b/src/register/sstatus.rs @@ -10,14 +10,14 @@ pub struct Sstatus { } /// Supervisor Previous Privilege Mode -#[derive(Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum SPP { Supervisor = 1, User = 0, } /// Floating-point unit Status -#[derive(Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum FS { Off = 0, Initial = 1, diff --git a/src/register/stvec.rs b/src/register/stvec.rs index 5a179d0..aab918b 100644 --- a/src/register/stvec.rs +++ b/src/register/stvec.rs @@ -7,6 +7,7 @@ pub struct Stvec { } /// Trap mode +#[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum TrapMode { Direct = 0, Vectored = 1,