|
@@ -24,7 +24,7 @@ const DYNAMIC_INFO_VALID_ADDRESSES: Range<usize> = 0x1000..0xf000;
|
|
|
const NEXT_ADDR_VALID_ADDRESSES: Range<usize> = 0x80000000..0x90000000;
|
|
|
|
|
|
// TODO unconstrained lifetime
|
|
|
-pub fn try_read_dynamic(paddr: usize) -> Result<DynamicInfo, ()> {
|
|
|
+pub fn read_paddr(paddr: usize) -> Result<DynamicInfo, ()> {
|
|
|
// check pointer before dereference
|
|
|
if !DYNAMIC_INFO_VALID_ADDRESSES.contains(&paddr)
|
|
|
|| !DYNAMIC_INFO_VALID_ADDRESSES.contains(&(paddr + size_of::<DynamicInfo>()))
|
|
@@ -35,19 +35,36 @@ pub fn try_read_dynamic(paddr: usize) -> Result<DynamicInfo, ()> {
|
|
|
Ok(ans)
|
|
|
}
|
|
|
|
|
|
-pub fn next_mode_mpp(info: &DynamicInfo) -> Result<mstatus::MPP, ()> {
|
|
|
- match info.next_mode {
|
|
|
- 0 => Ok(mstatus::MPP::User),
|
|
|
- 1 => Ok(mstatus::MPP::Supervisor),
|
|
|
- 3 => Ok(mstatus::MPP::Machine),
|
|
|
- _ => Err(()),
|
|
|
- }
|
|
|
+#[derive(Default)]
|
|
|
+pub struct DynamicError {
|
|
|
+ invalid_mpp: bool,
|
|
|
+ invalid_next_addr: bool,
|
|
|
}
|
|
|
|
|
|
-pub fn check_next_addr(info: &DynamicInfo) -> Result<usize, ()> {
|
|
|
- if NEXT_ADDR_VALID_ADDRESSES.contains(&info.next_addr) {
|
|
|
- Ok(info.next_addr)
|
|
|
- } else {
|
|
|
- Err(())
|
|
|
+pub fn mpp_next_addr(info: &DynamicInfo) -> Result<(mstatus::MPP, usize), DynamicError> {
|
|
|
+ let mut error = DynamicError::default();
|
|
|
+
|
|
|
+ // fail safe, errors will be aggregated after whole checking process.
|
|
|
+ let next_addr_valid = NEXT_ADDR_VALID_ADDRESSES.contains(&info.next_addr);
|
|
|
+ let mpp_valid = matches!(info.next_mode, 0 | 1 | 3);
|
|
|
+
|
|
|
+ if !next_addr_valid {
|
|
|
+ error.invalid_next_addr = true;
|
|
|
+ }
|
|
|
+ if !mpp_valid {
|
|
|
+ error.invalid_mpp = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if !next_addr_valid || !mpp_valid {
|
|
|
+ return Err(error);
|
|
|
}
|
|
|
+
|
|
|
+ let mpp = match info.next_mode {
|
|
|
+ 3 => mstatus::MPP::Machine,
|
|
|
+ 1 => mstatus::MPP::Supervisor,
|
|
|
+ // pattern `_` avoids `unreachable!`` which introduces panic handler.
|
|
|
+ 0 | _ => mstatus::MPP::User,
|
|
|
+ };
|
|
|
+
|
|
|
+ Ok((mpp, info.next_addr))
|
|
|
}
|