// 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 for MemoryException { fn into(self) -> MemoryExceptionType { self.type_ } } impl Into for Exception { fn into(self) -> ExceptionType { self.type_ } }