From a5dafceab95aacbe93dc2f1bf310e8a4319501c5 Mon Sep 17 00:00:00 2001 From: Emma Turner Date: Wed, 27 Mar 2024 17:23:53 +0000 Subject: [PATCH] RISC-V: fix fcsr read/write fcsr only allows certain parts to be written/read to, and is partially shadowed by both frm and fflags --- src/kernel_tx_demo/Cargo.lock | 21 +++++-- .../src/machine_state/csregisters.rs | 62 +++++++++++++++++++ 2 files changed, 78 insertions(+), 5 deletions(-) diff --git a/src/kernel_tx_demo/Cargo.lock b/src/kernel_tx_demo/Cargo.lock index 8656dbf36d74..d7efef2af619 100644 --- a/src/kernel_tx_demo/Cargo.lock +++ b/src/kernel_tx_demo/Cargo.lock @@ -1316,11 +1316,11 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.56" +version = "0.10.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729b745ad4a5575dd06a3e1af1414bd330ee561c01b3899eb584baeaa8def17e" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.1", "cfg-if 1.0.0", "foreign-types", "libc", @@ -1346,14 +1346,24 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-src" +version = "300.2.3+3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cff92b6f71555b61bb9315f7c64da3ca43d87531622120fea0195fc761b4843" +dependencies = [ + "cc", +] + [[package]] name = "openssl-sys" -version = "0.9.91" +version = "0.9.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" dependencies = [ "cc", "libc", + "openssl-src", "pkg-config", "vcpkg", ] @@ -2397,6 +2407,7 @@ dependencies = [ "clap", "ctrlc", "notify", + "openssl", "websocket", ] diff --git a/src/risc_v/interpreter/src/machine_state/csregisters.rs b/src/risc_v/interpreter/src/machine_state/csregisters.rs index 09f13843092b..a545bf17e45a 100644 --- a/src/risc_v/interpreter/src/machine_state/csregisters.rs +++ b/src/risc_v/interpreter/src/machine_state/csregisters.rs @@ -683,6 +683,18 @@ impl CSRegister { /// Since extension C is supported, we only make the low bit read-only 0 const WARL_MASK_XEPC: CSRValue = !1; + /// FCSR mask + const FCSR_MASK: CSRValue = Self::FRM_MASK | Self::FFLAGS_MASK; + + /// FRM mask + const FRM_MASK: CSRValue = 0b111 << Self::FRM_SHIFT; + + /// FRM is bits 5..7 + const FRM_SHIFT: usize = 5; + + /// FFLAGS mask + const FFLAGS_MASK: CSRValue = 0b11111; + /// Get the default value for the register. fn default_value(&self) -> u64 { match self { @@ -1112,6 +1124,20 @@ impl CSRegisters { let mie_only = mie & !CSRegister::WARL_MASK_SIP_SIE; (CSRegister::mie, sie_only | mie_only) } + CSRegister::fcsr => (CSRegister::fcsr, value & CSRegister::FCSR_MASK), + CSRegister::frm => { + let fcsr = self.registers.read(CSRegister::fcsr as usize); + let fcsr = fcsr & !CSRegister::FRM_MASK; + ( + CSRegister::fcsr, + ((value << CSRegister::FRM_SHIFT) & CSRegister::FRM_MASK) | fcsr, + ) + } + CSRegister::fflags => { + let fcsr = self.registers.read(CSRegister::fcsr as usize); + let fcsr = fcsr & !CSRegister::FFLAGS_MASK; + (CSRegister::fcsr, (value & CSRegister::FFLAGS_MASK) | fcsr) + } _ => (reg, value), } } @@ -1133,6 +1159,8 @@ impl CSRegisters { CSRegister::sstatus => CSRegister::mstatus, CSRegister::sip => CSRegister::mip, CSRegister::sie => CSRegister::mie, + CSRegister::fflags => CSRegister::fcsr, + CSRegister::frm => CSRegister::fcsr, reg => reg, } as usize) }); @@ -1142,6 +1170,9 @@ impl CSRegisters { CSRegister::sstatus => xstatus::sstatus_from_mstatus(source_reg_value), CSRegister::sip => source_reg_value & CSRegister::WARL_MASK_SIP_SIE, CSRegister::sie => source_reg_value & CSRegister::WARL_MASK_SIP_SIE, + CSRegister::fcsr => source_reg_value & CSRegister::FCSR_MASK, + CSRegister::frm => (source_reg_value & CSRegister::FRM_MASK) >> CSRegister::FRM_SHIFT, + CSRegister::fflags => source_reg_value & CSRegister::FFLAGS_MASK, _ => source_reg_value, } } @@ -1621,4 +1652,35 @@ mod tests { csregs.reset(); }); }); + + backend_test!(test_fcsr, F, { + let mut backend = create_backend!(CSRegistersLayout, F); + let mut csrs = create_state!(CSRegisters, CSRegistersLayout, F, backend); + + // check starting values + assert_eq!(0, csrs.read(CSRegister::fcsr)); + assert_eq!(0, csrs.read(CSRegister::frm)); + assert_eq!(0, csrs.read(CSRegister::fflags)); + + // writing to fcsr is reflected in frm/fflags + csrs.write(CSRegister::fcsr, u64::MAX); + + assert_eq!(0xff, csrs.read(CSRegister::fcsr)); + assert_eq!(0b111, csrs.read(CSRegister::frm)); + assert_eq!(0b11111, csrs.read(CSRegister::fflags)); + + // writing to frm is reflected in fcsr + csrs.write(CSRegister::frm, 0b010); + + assert_eq!(0b01011111, csrs.read(CSRegister::fcsr)); + assert_eq!(0b010, csrs.read(CSRegister::frm)); + assert_eq!(0b11111, csrs.read(CSRegister::fflags)); + + // writing to fflags is reflected in fcsr + csrs.write(CSRegister::fflags, 0b01010); + + assert_eq!(0b01001010, csrs.read(CSRegister::fcsr)); + assert_eq!(0b010, csrs.read(CSRegister::frm)); + assert_eq!(0b01010, csrs.read(CSRegister::fflags)); + }); } -- GitLab