// 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; #[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: u64, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum MemoryExceptionType { AddressMisaligned, AccessFault, PageFault, } impl MemoryExceptionType { pub(crate) fn with_addr(self, addr: u64) -> MemoryException { MemoryException { type_: self, addr } } } #[derive(Debug, Clone, Copy)] pub struct MemoryException { pub type_: MemoryExceptionType, pub addr: u64, } impl MemoryException { pub(crate) fn into_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 into_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 into_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_ } }