108 lines
2.9 KiB
Rust
108 lines
2.9 KiB
Rust
// Copyright (c) 2025 taitep
|
|
// SPDX-License-Identifier: BSD-2-Clause
|
|
//
|
|
// This file is part of TRVE (https://gitea.taitep.se/taitep/trve)
|
|
// See LICENSE file in the project root for full license text.
|
|
|
|
use int_enum::IntEnum;
|
|
|
|
use crate::consts::{Addr, DWord};
|
|
|
|
#[repr(u8)]
|
|
#[allow(dead_code)]
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, IntEnum)]
|
|
pub enum ExceptionType {
|
|
InstructionAddressMisaligned = 0,
|
|
InstructionAccessFault = 1,
|
|
IllegalInstruction = 2,
|
|
Breakpoint = 3,
|
|
LoadAddressMisaligned = 4,
|
|
LoadAccessFault = 5,
|
|
StoreAmoAddressMisaligned = 6,
|
|
StoreAmoAccessFault = 7,
|
|
EnvironmentCallFromUMode = 8,
|
|
EnvironmentCallFromSMode = 9,
|
|
EnvironmentCallFromMMode = 11,
|
|
InstructionPageFault = 12,
|
|
LoadPageFault = 13,
|
|
StoreAmoPageFault = 15,
|
|
DoubleTrap = 16,
|
|
SoftwareCheck = 18,
|
|
HardwareError = 19,
|
|
}
|
|
|
|
impl ExceptionType {
|
|
pub fn with_no_value(self) -> Exception {
|
|
Exception {
|
|
type_: self,
|
|
value: 0,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub struct Exception {
|
|
pub type_: ExceptionType,
|
|
pub value: DWord,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub enum MemoryExceptionType {
|
|
AddressMisaligned,
|
|
AccessFault,
|
|
PageFault,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub struct MemoryException {
|
|
pub type_: MemoryExceptionType,
|
|
pub addr: Addr,
|
|
}
|
|
|
|
impl MemoryException {
|
|
pub(crate) fn to_exception_store(&self) -> Exception {
|
|
Exception {
|
|
type_: match self.type_ {
|
|
MemoryExceptionType::AddressMisaligned => ExceptionType::StoreAmoAddressMisaligned,
|
|
MemoryExceptionType::AccessFault => ExceptionType::StoreAmoAccessFault,
|
|
MemoryExceptionType::PageFault => ExceptionType::StoreAmoPageFault,
|
|
},
|
|
value: self.addr,
|
|
}
|
|
}
|
|
|
|
pub(crate) fn to_exception_instr(&self) -> Exception {
|
|
Exception {
|
|
type_: match self.type_ {
|
|
MemoryExceptionType::AddressMisaligned => ExceptionType::InstructionAccessFault,
|
|
MemoryExceptionType::AccessFault => ExceptionType::InstructionAccessFault,
|
|
MemoryExceptionType::PageFault => ExceptionType::InstructionPageFault,
|
|
},
|
|
value: self.addr,
|
|
}
|
|
}
|
|
|
|
pub(crate) fn to_exception_load(&self) -> Exception {
|
|
Exception {
|
|
type_: match self.type_ {
|
|
MemoryExceptionType::AddressMisaligned => ExceptionType::LoadAddressMisaligned,
|
|
MemoryExceptionType::AccessFault => ExceptionType::LoadAccessFault,
|
|
MemoryExceptionType::PageFault => ExceptionType::LoadPageFault,
|
|
},
|
|
value: self.addr,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Into<MemoryExceptionType> for MemoryException {
|
|
fn into(self) -> MemoryExceptionType {
|
|
self.type_
|
|
}
|
|
}
|
|
|
|
impl Into<ExceptionType> for Exception {
|
|
fn into(self) -> ExceptionType {
|
|
self.type_
|
|
}
|
|
}
|