diff --git a/src/arch/metal.rs b/src/arch/metal.rs index 5dc056a1..5593e399 100644 --- a/src/arch/metal.rs +++ b/src/arch/metal.rs @@ -131,6 +131,13 @@ impl Architecture for MetalArch { Csr::Vstval => asm_write_csr!("vstval"), Csr::Vsip => asm_write_csr!("vsip"), Csr::Vsatp => asm_write_csr!("vsatp"), + Csr::Vstart => todo!(), + Csr::Vxsat => todo!(), + Csr::Vxrm => todo!(), + Csr::Vcsr => todo!(), + Csr::Vl => todo!(), + Csr::Vtype => todo!(), + Csr::Vlenb => todo!(), Csr::Unknown => (), }; @@ -226,6 +233,13 @@ impl Architecture for MetalArch { Csr::Vstval => asm_read_csr!("vstval"), Csr::Vsip => asm_read_csr!("vsip"), Csr::Vsatp => asm_read_csr!("vsatp"), + Csr::Vstart => todo!(), + Csr::Vxsat => todo!(), + Csr::Vxrm => todo!(), + Csr::Vcsr => todo!(), + Csr::Vl => todo!(), + Csr::Vtype => todo!(), + Csr::Vlenb => todo!(), Csr::Unknown => value = 0, }; @@ -342,6 +356,7 @@ impl Architecture for MetalArch { has_s_extension: (misa as usize & misa::S) != 0, has_sstc_extension, is_sstc_enabled: false, // Since the virtual menvcfg is initialized with 0 + has_v_extension: false, }, } } @@ -613,6 +628,13 @@ impl Architecture for MetalArch { Csr::Vstval => asm_clear_csr_bits!("vstval"), Csr::Vsip => asm_clear_csr_bits!("vsip"), Csr::Vsatp => asm_clear_csr_bits!("vsatp"), + Csr::Vstart => todo!(), + Csr::Vxsat => todo!(), + Csr::Vxrm => todo!(), + Csr::Vcsr => todo!(), + Csr::Vl => todo!(), + Csr::Vtype => todo!(), + Csr::Vlenb => todo!(), Csr::Unknown => (), }; @@ -709,6 +731,13 @@ impl Architecture for MetalArch { Csr::Vstval => asm_set_csr_bits!("vstval"), Csr::Vsip => asm_set_csr_bits!("vsip"), Csr::Vsatp => asm_set_csr_bits!("vsatp"), + Csr::Vstart => todo!(), + Csr::Vxsat => todo!(), + Csr::Vxrm => todo!(), + Csr::Vcsr => todo!(), + Csr::Vl => todo!(), + Csr::Vtype => todo!(), + Csr::Vlenb => todo!(), Csr::Unknown => (), }; diff --git a/src/arch/mod.rs b/src/arch/mod.rs index f558c327..7e1714d3 100644 --- a/src/arch/mod.rs +++ b/src/arch/mod.rs @@ -154,6 +154,8 @@ pub struct ExtensionsCapability { pub has_h_extension: bool, /// Supervisor extension pub has_s_extension: bool, + /// Vector extension + pub has_v_extension: bool, /// If the sstc extension is supported pub has_sstc_extension: bool, /// If the sstc extension is enabled diff --git a/src/arch/registers.rs b/src/arch/registers.rs index c89e0d0f..63063121 100644 --- a/src/arch/registers.rs +++ b/src/arch/registers.rs @@ -204,6 +204,23 @@ pub enum Csr { /// Virtual Supervisor Address Translation and Protection Vsatp, + /// Vector extension + /// + /// Vector Start Index CSR + Vstart, + /// Vector Fixed-Point Saturation Flag + Vxsat, + /// Vector Fixed-Point Rounding Mode Register + Vxrm, + /// Vector Control and Status Register + Vcsr, + /// Vector Length Register + Vl, + /// Vector Type Register + Vtype, + /// Vector Byte Length + Vlenb, + /// An unknown CSR Unknown, } diff --git a/src/arch/userspace.rs b/src/arch/userspace.rs index 5630e486..1574fa91 100644 --- a/src/arch/userspace.rs +++ b/src/arch/userspace.rs @@ -24,6 +24,7 @@ static HOST_CTX: Mutex = Mutex::new(VirtContext::new( has_s_extension: true, has_sstc_extension: false, is_sstc_enabled: false, + has_v_extension: false, }, )); @@ -111,6 +112,7 @@ impl Architecture for HostArch { extensions: ExtensionsCapability { has_h_extension: false, has_s_extension: true, + has_v_extension: true, has_sstc_extension: false, is_sstc_enabled: false, }, @@ -193,6 +195,19 @@ impl Architecture for HostArch { Csr::Vstval => ctx.csr.vstval, Csr::Vsip => ctx.csr.vsip, Csr::Vsatp => ctx.csr.vsatp, + Csr::Vstart => ctx.csr.vstart as usize, + Csr::Vxsat => { + if ctx.csr.vxsat { + 1 + } else { + 0 + } + } + Csr::Vxrm => ctx.csr.vxrm as usize, + Csr::Vcsr => ctx.csr.vcsr as usize, + Csr::Vl => ctx.csr.vl, + Csr::Vtype => ctx.csr.vtype, + Csr::Vlenb => ctx.csr.vlenb, Csr::Unknown => panic!("Unkown csr!"), } } @@ -277,6 +292,13 @@ impl Architecture for HostArch { Csr::Vstval => ctx.csr.vstval = value, Csr::Vsip => ctx.csr.vsip = value, Csr::Vsatp => ctx.csr.vsatp = value, + Csr::Vstart => ctx.csr.vstart = value as u16, + Csr::Vxsat => ctx.csr.vxsat = (value & 0x1) != 0, + Csr::Vxrm => ctx.csr.vxrm = (value & 0b11) as u8, + Csr::Vcsr => ctx.csr.vcsr = (value & 0b111) as u8, + Csr::Vl => ctx.csr.vl = value, + Csr::Vtype => ctx.csr.vtype = value, + Csr::Vlenb => ctx.csr.vlenb = value, Csr::Unknown => panic!("Unkown csr!"), } prev_val diff --git a/src/decoder.rs b/src/decoder.rs index c49bb5b9..84f50f68 100644 --- a/src/decoder.rs +++ b/src/decoder.rs @@ -756,6 +756,57 @@ impl MiralisContext { } } + // Vector extension + 0x8 => { + if !self.hw.extensions.has_v_extension { + Csr::Unknown + } else { + Csr::Vstart + } + } + 0x9 => { + if !self.hw.extensions.has_v_extension { + Csr::Unknown + } else { + Csr::Vxsat + } + } + 0xa => { + if !self.hw.extensions.has_v_extension { + Csr::Unknown + } else { + Csr::Vxrm + } + } + 0xf => { + if !self.hw.extensions.has_v_extension { + Csr::Unknown + } else { + Csr::Vcsr + } + } + 0xc20 => { + if !self.hw.extensions.has_v_extension { + Csr::Unknown + } else { + Csr::Vl + } + } + 0xc21 => { + if !self.hw.extensions.has_v_extension { + Csr::Unknown + } else { + Csr::Vtype + } + } + 0xc22 => { + if !self.hw.extensions.has_v_extension { + Csr::Unknown + } else { + Csr::Vlenb + } + } + _ => { log::debug!("Unknown CSR: 0x{:x}", csr); Csr::Unknown diff --git a/src/virt/csr.rs b/src/virt/csr.rs index 0825e4f7..cbc0963e 100644 --- a/src/virt/csr.rs +++ b/src/virt/csr.rs @@ -199,6 +199,22 @@ impl RegisterContextGetter for VirtContext { } } Csr::Vsatp => self.csr.vsatp, + + // Vector extension + Csr::Vstart => self.csr.vstart as usize, + Csr::Vxsat => { + if self.csr.vxsat { + 1 + } else { + 0 + } + } + Csr::Vxrm => self.csr.vxrm as usize, + Csr::Vcsr => self.csr.vcsr as usize, + Csr::Vl => self.csr.vl, + Csr::Vtype => self.csr.vtype, + Csr::Vlenb => self.csr.vlenb, + // Unknown Csr::Unknown => panic!("Tried to access unknown CSR: {:?}", register), } @@ -613,6 +629,19 @@ impl HwRegisterContextSetter for VirtContext { self.csr.vsip = value & write_vsip_mask } Csr::Vsatp => self.csr.vsatp = value, + + // Vector extension + Csr::Vstart => { + let vstart_length = 8; // This assumes vlen is equal 3 + self.csr.vstart = (value & ((1 << (vstart_length + 1)) - 1)) as u16 + } + Csr::Vxsat => self.csr.vxsat = (value & 0x1) != 0, + Csr::Vxrm => self.csr.vxrm = (value & 0b11) as u8, + Csr::Vcsr => self.csr.vcsr = (value & 0b111) as u8, + Csr::Vl => self.csr.vl = value, + Csr::Vtype => self.csr.vtype = value, + Csr::Vlenb => self.csr.vlenb = value, + // Unknown Csr::Unknown => panic!("Tried to access unknown CSR: {:?}", register), } diff --git a/src/virt/mod.rs b/src/virt/mod.rs index f2b60bb2..802445d0 100644 --- a/src/virt/mod.rs +++ b/src/virt/mod.rs @@ -119,6 +119,13 @@ impl VirtContext { pmpaddr: [0; 64], mhpmcounter: [0; 29], mhpmevent: [0; 29], + vstart: 0, + vxsat: false, + vxrm: 0, + vcsr: 0, + vl: 0, + vtype: 0, + vlenb: 0, }, pc: 0, mode: Mode::M, @@ -204,6 +211,13 @@ pub struct VirtCsr { pub pmpaddr: [usize; 64], pub mhpmcounter: [usize; 29], pub mhpmevent: [usize; 29], + pub vstart: u16, + pub vxsat: bool, + pub vxrm: u8, // 2 bits wide + pub vcsr: u8, // 3 bits wide + pub vl: usize, + pub vtype: usize, + pub vlenb: usize, } impl VirtCsr {