(&self, addr: u16)
| 130 | } |
| 131 | |
| 132 | pub fn read(&self, addr: u16) -> Result<u64, VmError> { |
| 133 | use addr::{ |
| 134 | CYCLE, FCSR, FFLAGS, FRM, INSTRET, MCAUSE, MCOUNTEREN, MEDELEG, MEPC, MHARTID, MIDELEG, |
| 135 | MIE, MIP, MISA, MSCRATCH, MSTATUS, MTVAL, MTVEC, SATP, SCAUSE, SCOUNTEREN, SEPC, SIE, |
| 136 | SIP, SSCRATCH, SSTATUS, STVAL, STVEC, TIME, |
| 137 | }; |
| 138 | match addr { |
| 139 | FFLAGS => Ok(u64::from(self.fflags)), |
| 140 | FRM => Ok(u64::from(self.frm)), |
| 141 | FCSR => Ok((u64::from(self.frm) << 5) | u64::from(self.fflags)), |
| 142 | CYCLE => Ok(self.cycle), |
| 143 | // TIME is aliased to the cycle counter (no separate real-time clock). |
| 144 | TIME => Ok(self.cycle), |
| 145 | INSTRET => Ok(self.instret), |
| 146 | |
| 147 | // sstatus is the S-mode-visible subset of mstatus. |
| 148 | SSTATUS => Ok(self.mstatus & SSTATUS_MASK), |
| 149 | // sie is the S-mode-visible subset of mie. |
| 150 | SIE => Ok(self.mie & S_IRQ_MASK), |
| 151 | STVEC => Ok(self.stvec), |
| 152 | // SCOUNTEREN: stub - all counters accessible from lower modes. |
| 153 | SCOUNTEREN => Ok(0), |
| 154 | SSCRATCH => Ok(self.sscratch), |
| 155 | SEPC => Ok(self.sepc), |
| 156 | SCAUSE => Ok(self.scause), |
| 157 | STVAL => Ok(self.stval), |
| 158 | // sip is the S-mode-visible subset of mip. |
| 159 | SIP => Ok(self.mip & S_IRQ_MASK), |
| 160 | SATP => Ok(self.satp), |
| 161 | |
| 162 | MSTATUS => Ok(self.mstatus), |
| 163 | MISA => Ok(self.misa), |
| 164 | MEDELEG => Ok(self.medeleg), |
| 165 | MIDELEG => Ok(self.mideleg), |
| 166 | // PMP CSRs |
| 167 | 0x3A0 => Ok(self.pmpcfg0), |
| 168 | 0x3B0 => Ok(self.pmpaddr0), |
| 169 | MIE => Ok(self.mie), |
| 170 | MTVEC => Ok(self.mtvec), |
| 171 | // MCOUNTEREN: stub - counters accessible from S/U modes. |
| 172 | MCOUNTEREN => Ok(0), |
| 173 | MSCRATCH => Ok(self.mscratch), |
| 174 | MEPC => Ok(self.mepc), |
| 175 | MCAUSE => Ok(self.mcause), |
| 176 | MTVAL => Ok(self.mtval), |
| 177 | MIP => Ok(self.mip), |
| 178 | MHARTID => Ok(0), |
| 179 | _ => Err(VmError::IllegalInstruction(u32::from(addr))), |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | pub fn write(&mut self, addr: u16, val: u64) -> Result<(), VmError> { |
| 184 | use addr::{ |
no outgoing calls