### Read and Set Exception Return Address (ERA) - LoongArch64 Source: https://context7.com/godones/loongarch64/llms.txt Demonstrates reading the Exception Return Address (ERA) register to get the PC value at the time of an exception. It also shows how to set the return address, for example, to skip the instruction that caused the exception. ```rust use loongArch64::register; // 读取异常触发时的 PC let era = register::era::read(); let pc: usize = era.pc(); println!("异常发生地址: {:#x}", pc); // 修改返回地址(例如 syscall 后跳过触发指令) register::era::set_pc(pc + 4); ``` -------------------------------- ### Configure Exception Entry Base Address (EENTRY) - LoongArch64 Source: https://context7.com/godones/loongarch64/llms.txt Shows how to set the base address for exception and interrupt handlers using the Exception Entry Base Address (EENTRY) register. The address must be 4KB aligned. Reading the current configuration is also demonstrated. ```rust use loongArch64::register; // 设置异常处理入口地址(必须 4KB 对齐) extern "C" { fn exception_entry_base(); } let entry_addr = exception_entry_base as usize; assert_eq!(entry_addr & 0xfff, 0, "入口地址必须 4KB 对齐"); register::eentry::set_eentry(entry_addr); // 读取当前配置的入口基地址 let eentry = register::eentry::read(); println!("异常入口: {:#x}", eentry.eentry()); ``` -------------------------------- ### Manage TLB Entries in LoongArch64 Source: https://context7.com/godones/loongarch64/llms.txt Set TLB index, page size, and validity. Configure TLB low-entry attributes like physical page number and access permissions. ```rust use loongArch64::register; use loongArch64::register::MemoryAccessType; // --- TLB 表项填充示例 --- // 1. 设置 TLB 索引 register::tlbidx::set_index(0); // 选择第 0 项 register::tlbidx::set_ps(12); // 页大小:4KB (2^12) register::tlbidx::set_ne(false); // 标记表项有效 // 2. 检索 TLB:若命中,TLBIDX.index 更新为命中索引 // asm!("tlbsrch") — 通过 asm 模块调用 // 3. 读取 TLBIDX 状态 let tlbidx = register::tlbidx::read(); println!("TLB index={}, ps={}, ne={}", tlbidx.index(), tlbidx.ps(), tlbidx.ne()); // 4. 配置 TLB 低位表项(物理页号 + 属性) register::tlbelo0::set_valid(true); register::tlbelo0::set_dirty(true); register::tlbelo0::set_plv(0); // 内核态可访问 register::tlbelo0::set_mat(MemoryAccessType::CoherentCached); register::tlbelo0::set_global(false); register::tlbelo0::set_ppn(0x8000_0); // 物理页号(48位地址空间) ``` -------------------------------- ### Configure Direct Mapping Windows (DMW) in LoongArch64 Source: https://context7.com/godones/loongarch64/llms.txt Define mapping windows for direct address translation, binding virtual address segments to privilege levels and memory access types. ```rust use loongArch64::register; use loongArch64::register::MemoryAccessType; // 配置 DMW0:将 vseg=0x8 映射为强序不缓存(SUC),PLV0 可访问 register::dmw0::set_vseg(0x8); register::dmw0::set_mat(MemoryAccessType::StronglyOrderedUnCached); register::dmw0::set_plv0(true); // 内核态(Ring0)可访问 register::dmw0::set_plv3(false); // 用户态不可访问 // 配置 DMW1:将 vseg=0x9 映射为一致性缓存(CC),PLV0 可访问 register::dmw1::set_vseg(0x9); register::dmw1::set_mat(MemoryAccessType::CoherentCached); register::dmw1::set_plv0(true); // 读取并打印 DMW0 配置 let dmw0 = register::dmw0::read(); println!("{:?}", dmw0); // 输出:DMW0 { MAT: StronglyOrderedUnCached, vseg: 8, plv0: true, ... } ``` -------------------------------- ### Handle Exceptions and Interrupts with ESTAT - LoongArch64 Source: https://context7.com/godones/loongarch64/llms.txt Demonstrates reading the Exception Status Register (ESTAT) to determine the cause of an exception or interrupt, including system calls, page faults, TLB refills, timers, IPIs, and machine errors. Also shows how to set software interrupt bits. ```rust use loongArch64::register; use loongArch64::register::estat::{Trap, Exception, Interrupt}; // 在异常处理入口读取异常原因 let estat = register::estat::read(); match estat.cause() { Trap::Exception(Exception::Syscall) => { // 处理系统调用(Ecode = 0xB) } Trap::Exception(Exception::LoadPageFault) => { // 处理 LOAD 缺页(V=0),Ecode = 0x1 } Trap::Exception(Exception::StorePageFault) => { // 处理 STORE 缺页,Ecode = 0x2 } Trap::Exception(Exception::TLBRFill) => { // TLB 重填异常(通过 TLBRERA.IsTLBR 判断) } Trap::Interrupt(Interrupt::Timer) => { // 定时器中断(中断位 11) } Trap::Interrupt(Interrupt::IPI) => { // 处理器间中断(中断位 12) } Trap::MachineError(_) => { // 机器错误异常(通过 MERRCTL.IsMERR 判断) } Trap::Unknown => { /* 未知类型 */ } } // 读取原始中断状态位(bits 0-12) let is_bits: usize = estat.is(); // 触发软件中断 0 register::estat::set_sw(0, true); ``` -------------------------------- ### Add loongArch64 Dependency to Cargo.toml Source: https://context7.com/godones/loongarch64/llms.txt Add the loongArch64 crate as a dependency in your Cargo.toml file to use its features. ```toml [dependencies] loongArch64 = "0.2.6" ``` -------------------------------- ### Query LoongArch64 CPU Configuration Information Source: https://context7.com/godones/loongarch64/llms.txt Read the processor feature word using the 'cpucfg' instruction to query architecture capabilities like address bit widths and hardware feature support. ```rust use loongArch64::cpu::{ get_prid, get_arch, get_palen, get_valen, get_mmu_support_page, get_support_iocsr, get_ual, get_support_huge_page, get_support_rva, }; // 读取处理器标识(PRID) println!("PRID: {:#x}", get_prid()); // 查询地址位宽 println!("物理地址位数 PALEN: {}", get_palen()); // 通常 48 println!("虚拟地址位数 VALEN: {}", get_valen()); // 通常 48 // 查询硬件特性支持 println!("支持分页 MMU: {}", get_mmu_support_page()); println!("支持 IOCSR: {}", get_support_iocsr()); println!("支持非对齐访存: {}", get_ual()); println!("支持大页: {}", get_support_huge_page()); println!("支持 RVA: {}", get_support_rva()); ``` -------------------------------- ### Execute LoongArch64 Assembly Instructions Source: https://context7.com/godones/loongarch64/llms.txt Encapsulates specific LoongArch64 assembly instructions, such as 'idle', for use within Rust code. Only effective on the loongarch64 target. ```rust use loongArch64::asm; // 执行 idle 指令,令处理器进入低功耗等待状态(直到下一个中断) unsafe { asm::idle(); } ``` -------------------------------- ### CPU Configuration Information Query Source: https://context7.com/godones/loongarch64/llms.txt `CPUCFG` reads the processor feature word via the `cpucfg` instruction, providing an interface for querying architectural capabilities. ```APIDOC ## `cpu::CPUCFG` — CPU 配置信息查询 `CPUCFG` 通过 `cpucfg` 指令读取处理器特性字,提供架构能力查询接口。 ```rust use loongArch64::cpu::{ get_prid, get_arch, get_palen, get_valen, get_mmu_support_page, get_support_iocsr, get_ual, get_support_huge_page, get_support_rva, }; // 读取处理器标识(PRID) println!("PRID: {:#x}", get_prid()); // 查询地址位宽 println!("物理地址位数 PALEN: {}", get_palen()); // 通常 48 println!("虚拟地址位数 VALEN: {}", get_valen()); // 通常 48 // 查询硬件特性支持 println!("支持分页 MMU: {}", get_mmu_support_page()); println!("支持 IOCSR: {}", get_support_iocsr()); println!("支持非对齐访存: {}", get_ual()); println!("支持大页: {}", get_support_huge_page()); println!("支持 RVA: {}", get_support_rva()); ``` ``` -------------------------------- ### I/O Control Status Register Read/Write Source: https://context7.com/godones/loongarch64/llms.txt The `iocsr` module encapsulates the `iocsrrd`/`iocsrwr` instructions, providing byte, half-word, word, and double-word access interfaces for IOCSR. ```APIDOC ## `iocsr` — I/O 控制状态寄存器读写 `iocsr` 模块封装 `iocsrrd`/`iocsrwr` 指令,提供按字节、半字、字、双字粒度的 IOCSR 访问接口。 ```rust use loongArch64::iocsr::{ iocsr_read_b, iocsr_read_h, iocsr_read_w, iocsr_read_d, iocsr_write_b, iocsr_write_h, iocsr_write_w, iocsr_write_d, }; use loongArch64::consts::LOONGARCH_IOCSR_IPI_STATUS; // 读取 IPI 状态寄存器(32位) let ipi_status: u32 = iocsr_read_w(LOONGARCH_IOCSR_IPI_STATUS); println!("IPI 状态: {:#010x}", ipi_status); // 写入自定义 IOCSR 寄存器(64位) iocsr_write_d(0x1000, 0xDEAD_BEEF_0000_0001u64); // 按字节读取 let byte_val: u8 = iocsr_read_b(0x1000); ``` ``` -------------------------------- ### Configure and Control LoongArch64 Timer Registers Source: https://context7.com/godones/loongarch64/llms.txt Configure timer frequency, mode, and enable/disable it. Reads timer status and current count. Clears timer interrupt signals. ```rust use loongArch64::register; use loongArch64::time::{Time, get_timer_freq}; // 读取当前定时器频率(Hz) let freq = get_timer_freq(); println!("定时器频率: {} Hz", freq); // 配置定时器:周期模式,初始值为 freq(约 1 秒一次中断) let init_val = freq & !0x3; // 必须是 4 的整数倍 register::tcfg::set_init_val(init_val); register::tcfg::set_periodic(true); // 循环模式 register::tcfg::set_en(true); // 启动定时器 // 读取定时器配置状态 let tcfg = register::tcfg::read(); println!("{:?}", tcfg); // 输出:TCfg { is_enabled: true, is_periodic: true, InitVal of (dec) timer: } // 在定时器中断处理中读取当前计数值 let tval = register::tval::read(); // 清除定时器中断信号 register::ticlr::clear_timer(); // 使用 rdtime.d 指令读取稳定计数器 let timestamp: usize = Time::read(); ``` -------------------------------- ### Send Inter-Processor Interrupts (IPI) and Mailbox Messages in LoongArch64 Source: https://context7.com/godones/loongarch64/llms.txt Send IPIs to specific CPU cores and mailbox messages for multi-core synchronization and SMP boot scenarios. ```rust use loongArch64::ipi::{send_ipi_single, csr_mail_send}; // 向 CPU 1 发送 IPI,触发中断向量位 0 send_ipi_single(1, 1u32 << 0); // 向 CPU 2 的邮箱 0 发送启动地址(用于 SMP 核心唤醒) let boot_entry: u64 = 0x9000_0000_8020_0000; csr_mail_send(boot_entry, 2, 0); ``` -------------------------------- ### Configure ECFG Interrupts and VS - LoongArch64 Source: https://context7.com/godones/loongarch64/llms.txt Shows how to read the Exception Configuration Register (ECFG) and modify its local interrupt enable bits (LIE) and the VS field for exception entry spacing. Use LineBasedInterrupt for masking. ```rust use loongArch64::register; use loongArch64::register::ecfg::LineBasedInterrupt; // 读取当前中断使能配置 let ecfg = register::ecfg::read(); let lie: LineBasedInterrupt = ecfg.lie(); // 各中断本地使能位 let vs: usize = ecfg.vs(); // 入口间距指数 // 使能定时器中断和 IPI 中断 let mask = LineBasedInterrupt::TIMER | LineBasedInterrupt::IPI; register::ecfg::set_lie(mask); // 设置 VS=0,所有异常共用同一入口基地址 register::ecfg::set_vs(0); // 调试输出:ECFG { lie: TIMER | IPI, vs: 0 } println!("{:?}", ecfg); ``` -------------------------------- ### Read and Modify PRMD Register - LoongArch64 Source: https://context7.com/godones/loongarch64/llms.txt Demonstrates reading the Previous Mode Information Register (PRMD) to access saved privilege level, interrupt enable state, and watchpoint enable state before an exception. Manual setting is also shown. ```rust use loongArch64::register; use loongArch64::register::CpuMode; // 读取异常前保存的模式信息 let prmd = register::prmd::read(); let pplv: usize = prmd.pplv(); // 异常前特权级(0-3) let pie: bool = prmd.pie(); // 异常前中断使能状态 let pwe: bool = prmd.pwe(); // 异常前监视点使能状态 // 手动设置(通常由硬件自动维护,软件可在异常处理中修改) register::prmd::set_pplv(CpuMode::Ring0); register::prmd::set_pie(true); register::prmd::set_pwe(false); ``` -------------------------------- ### Direct Mapping Window Registers (DMW, CSR 0x180–0x183) Source: https://context7.com/godones/loongarch64/llms.txt Define mapping windows for direct address translation mode, binding the upper 4 bits of virtual address (vseg) with privilege level access permissions. ```APIDOC ## `register::dmw0`–`dmw3` — 直接映射配置窗口(DMW,CSR 0x180–0x183) DMW 寄存器定义直接地址翻译模式下的映射窗口,将虚拟地址的高 4 位(vseg)与各特权级访问许可绑定。 ```rust use loongArch64::register; use loongArch64::register::MemoryAccessType; // 配置 DMW0:将 vseg=0x8 映射为强序不缓存(SUC),PLV0 可访问 register::dmw0::set_vseg(0x8); register::dmw0::set_mat(MemoryAccessType::StronglyOrderedUnCached); register::dmw0::set_plv0(true); // 内核态(Ring0)可访问 register::dmw0::set_plv3(false); // 用户态不可访问 // 配置 DMW1:将 vseg=0x9 映射为一致性缓存(CC),PLV0 可访问 register::dmw1::set_vseg(0x9); register::dmw1::set_mat(MemoryAccessType::CoherentCached); register::dmw1::set_plv0(true); // 读取并打印 DMW0 配置 let dmw0 = register::dmw0::read(); println!("{:?}", dmw0); // 输出:DMW0 { MAT: StronglyOrderedUnCached, vseg: 8, plv0: true, ... } ``` ``` -------------------------------- ### TLB Index and Entry Registers Source: https://context7.com/godones/loongarch64/llms.txt Software-managed TLB registers, including index selection (TLBIDX), virtual address high bits (TLBEHI), and physical address mapping (TLBELO0/1). ```APIDOC ## `register::tlbidx` / `tlbehi` / `tlbelo0` / `tlbelo1` — TLB 索引与表项寄存器 TLB 相关寄存器用于软件管理 TLB,包括索引选择(TLBIDX)、虚拟地址高位(TLBEHI)和物理地址映射(TLBELO0/1)。 ```rust use loongArch64::register; use loongArch64::register::MemoryAccessType; // --- TLB 表项填充示例 --- // 1. 设置 TLB 索引 register::tlbidx::set_index(0); // 选择第 0 项 register::tlbidx::set_ps(12); // 页大小:4KB (2^12) register::tlbidx::set_ne(false); // 标记表项有效 // 2. 检索 TLB:若命中,TLBIDX.index 更新为命中索引 // asm!("tlbsrch") — 通过 asm 模块调用 // 3. 读取 TLBIDX 状态 let tlbidx = register::tlbidx::read(); println!("TLB index={}, ps={}, ne={}", tlbidx.index(), tlbidx.ps(), tlbidx.ne()); // 4. 配置 TLB 低位表项(物理页号 + 属性) register::tlbelo0::set_valid(true); register::tlbelo0::set_dirty(true); register::tlbelo0::set_plv(0); // 内核态可访问 register::tlbelo0::set_mat(MemoryAccessType::CoherentCached); register::tlbelo0::set_global(false); register::tlbelo0::set_ppn(0x8000_0); // 物理页号(48位地址空间) ``` ``` -------------------------------- ### register::eentry — Exception Entry Base Address Register (EENTRY, CSR 0xC) Source: https://context7.com/godones/loongarch64/llms.txt EENTRY configures the base address for general exceptions and interrupts. It requires 4KB alignment (the lower 12 bits must be 0). ```APIDOC ## register::eentry — Exception Entry Base Address Register (EENTRY, CSR 0xC) ### Description EENTRY configures the base address for general exceptions and interrupts. It requires 4KB alignment (the lower 12 bits must be 0). ### Method Rust (using `loongArch64::register::eentry` module) ### Usage Examples ```rust use loongArch64::register; // Set the exception handler entry point address (must be 4KB aligned) extern "C" { fn exception_entry_base(); } let entry_addr = exception_entry_base as usize; assert_eq!(entry_addr & 0xfff, 0, "Entry address must be 4KB aligned"); register::eentry::set_eentry(entry_addr); // Read the currently configured entry base address let eentry = register::eentry::read(); println!("Exception entry point: {:#x}", eentry.eentry()); ``` ``` -------------------------------- ### Read and Write I/O Control Status Registers (IOCSR) in LoongArch64 Source: https://context7.com/godones/loongarch64/llms.txt Access IOCSR using 'iocsrrd'/'iocsrwr' instructions with byte, half-word, word, or double-word granularity. ```rust use loongArch64::iocsr::{ iocsr_read_b, iocsr_read_h, iocsr_read_w, iocsr_read_d, iocsr_write_b, iocsr_write_h, iocsr_write_w, iocsr_write_d, }; use loongArch64::consts::LOONGARCH_IOCSR_IPI_STATUS; // 读取 IPI 状态寄存器(32位) let ipi_status: u32 = iocsr_read_w(LOONGARCH_IOCSR_IPI_STATUS); println!("IPI 状态: {:#010x}", ipi_status); // 写入自定义 IOCSR 寄存器(64位) iocsr_write_d(0x1000, 0xDEAD_BEEF_0000_0001u64); // 按字节读取 let byte_val: u8 = iocsr_read_b(0x1000); ``` -------------------------------- ### Inter-Processor Interrupt (IPI) and Mailbox Communication Source: https://context7.com/godones/loongarch64/llms.txt The `ipi` module provides interfaces for sending IPIs and mailbox messages to specific CPU cores, used for multi-core synchronization and SMP boot scenarios. ```APIDOC ## `ipi` — 处理器间中断(IPI)与邮箱通信 `ipi` 模块提供向指定 CPU 核发送 IPI 中断及邮箱消息的接口,用于多核同步与启动(SMP boot)场景。 ```rust use loongArch64::ipi::{send_ipi_single, csr_mail_send}; // 向 CPU 1 发送 IPI,触发中断向量位 0 send_ipi_single(1, 1u32 << 0); // 向 CPU 2 的邮箱 0 发送启动地址(用于 SMP 核心唤醒) let boot_entry: u64 = 0x9000_0000_8020_0000; csr_mail_send(boot_entry, 2, 0); ``` ``` -------------------------------- ### Assembly Instruction Encapsulation Source: https://context7.com/godones/loongarch64/llms.txt The `asm` module encapsulates specific LoongArch assembly instructions. It is only effective when `target_arch = "loongarch64"`; calls on other platforms will trigger `unimplemented!()`. ```APIDOC ## `asm` — 汇编指令封装 `asm` 模块封装特定 LoongArch 汇编指令,仅在 `target_arch = "loongarch64"` 时生效,其他平台调用时会触发 `unimplemented!()`。 ```rust use loongArch64::asm; // 执行 idle 指令,令处理器进入低功耗等待状态(直到下一个中断) unsafe { asm::idle(); } ``` ``` -------------------------------- ### Timer Registers (CSR 0x41–0x44) Source: https://context7.com/godones/loongarch64/llms.txt Control LoongArch64 built-in timers, including enabling, setting count mode (single/periodic), and initial values. Timer interrupts are triggered when the count reaches zero. ```APIDOC ## `register::tcfg` / `tval` / `tid` / `ticlr` — 定时器寄存器(CSR 0x41–0x44) 定时器寄存器组控制 LoongArch 内置定时器的使能、计数模式(单次/循环)及初始值,计数到 0 时触发定时器中断。 ```rust use loongArch64::register; use loongArch64::time::{Time, get_timer_freq}; // 读取当前定时器频率(Hz) let freq = get_timer_freq(); println!("定时器频率: {} Hz", freq); // 配置定时器:周期模式,初始值为 freq(约 1 秒一次中断) let init_val = freq & !0x3; // 必须是 4 的整数倍 register::tcfg::set_init_val(init_val); register::tcfg::set_periodic(true); // 循环模式 register::tcfg::set_en(true); // 启动定时器 // 读取定时器配置状态 let tcfg = register::tcfg::read(); println!("{:?}", tcfg); // 输出:TCfg { is_enabled: true, is_periodic: true, InitVal of (dec) timer: } // 在定时器中断处理中读取当前计数值 let tval = register::tval::read(); // 清除定时器中断信号 register::ticlr::clear_timer(); // 使用 rdtime.d 指令读取稳定计数器 let timestamp: usize = Time::read(); ``` ``` -------------------------------- ### Handle Machine Error Control Register (MERRCTL) in LoongArch64 Source: https://context7.com/godones/loongarch64/llms.txt Read the MERRCTL register to check for machine errors, determine repairability, identify the cause, and retrieve saved processor context. ```rust use loongArch64::register::ras::merrctl; // 读取机器错误状态 let merrctl = merrctl::read(); if merrctl.is_merr() { println!("机器错误异常已触发"); println!("可修复: {}", merrctl.repairable()); use loongArch64::register::ras::merrctl::MachineError; match merrctl.cause() { MachineError::CacheCheckError => println!("Cache 校验错误"), } // 读取异常前保存的现场 println!("异常前特权级: {}", merrctl.pplv()); println!("异常前中断使能: {}", merrctl.pie()); println!("异常前分页模式: {}", merrctl.ppg()); } ``` -------------------------------- ### register::ecfg — Exception Configuration Register (ECFG, CSR 0x4) Source: https://context7.com/godones/loongarch64/llms.txt ECFG controls the local enable bits for various interrupts and configures the spacing of exception/interrupt entry points (VS field). When VS=0, all entries share the same base address; when VS≠0, the spacing between entries is 2^VS instructions. ```APIDOC ## register::ecfg — Exception Configuration Register (ECFG, CSR 0x4) ### Description ECFG controls the local enable bits for various interrupts and configures the spacing of exception/interrupt entry points (VS field). When VS=0, all entries share the same base address; when VS≠0, the spacing between entries is 2^VS instructions. ### Method Rust (using `loongArch64::register::ecfg` module) ### Usage Examples ```rust use loongArch64::register; use loongArch64::register::ecfg::LineBasedInterrupt; // Read the current interrupt enable configuration let ecfg = register::ecfg::read(); let lie: LineBasedInterrupt = ecfg.lie(); // Local enable bits for each interrupt let vs: usize = ecfg.vs(); // Entry spacing exponent // Enable timer and IPI interrupts let mask = LineBasedInterrupt::TIMER | LineBasedInterrupt::IPI; register::ecfg::set_lie(mask); // Set VS=0, all exceptions share the same entry base address register::ecfg::set_vs(0); // Debug output: ECFG { lie: TIMER | IPI, vs: 0 } println!("{:?}", ecfg); ``` ``` -------------------------------- ### register::era — Exception Return Address Register (ERA, CSR 0x6) Source: https://context7.com/godones/loongarch64/llms.txt ERA stores the PC value at the time of a general exception (excluding TLB refill and machine errors). Upon completion of exception handling, the `ERTN` instruction jumps to this address. ```APIDOC ## register::era — Exception Return Address Register (ERA, CSR 0x6) ### Description ERA stores the PC value at the time of a general exception (excluding TLB refill and machine errors). Upon completion of exception handling, the `ERTN` instruction jumps to this address. ### Method Rust (using `loongArch64::register::era` module) ### Usage Examples ```rust use loongArch64::register; // Read the PC at the time of the exception let era = register::era::read(); let pc: usize = era.pc(); println!("Exception occurred at address: {:#x}", pc); // Modify the return address (e.g., to skip the instruction that triggered the exception after syscall) register::era::set_pc(pc + 4); ``` ``` -------------------------------- ### Read and Modify CRMD Register - LoongArch64 Source: https://context7.com/godones/loongarch64/llms.txt Demonstrates reading the Current Mode Information Register (CRMD) and modifying its fields like global interrupt enable and privilege level. Ensure correct usage of CpuMode and MemoryAccessType enums. ```rust use loongArch64::register; use loongArch64::register::{CpuMode, MemoryAccessType}; // 读取 CRMD 寄存器 let crmd = register::crmd::read(); // 查询当前特权级(Ring0=内核态, Ring3=用户态) let plv: CpuMode = crmd.plv(); // 查询全局中断使能 let ie: bool = crmd.ie(); // 查询地址翻译模式 let is_direct: bool = crmd.da(); // 直接地址翻译 let is_paging: bool = crmd.pg(); // 页表地址翻译 // 查询直接访问模式下取指/访存的内存访问类型 let datf: MemoryAccessType = crmd.datf(); // 取指 MAT let datm: MemoryAccessType = crmd.datm(); // 访存 MAT // 修改字段 register::crmd::set_ie(true); // 开启全局中断 register::crmd::set_plv(CpuMode::Ring0); // 设置内核态 register::crmd::set_da(true); // 启用直接地址翻译 register::crmd::set_pg(false); // 关闭分页翻译 register::crmd::set_datf(MemoryAccessType::CoherentCached); // 取指 CC register::crmd::set_datm(MemoryAccessType::CoherentCached); // 访存 CC register::crmd::set_we(false); // 关闭监视点 // 调试输出:CrMd { plv: Ring0, ie: true, we: false, is_paging_md: false, ... } println!("{:?}", crmd); ``` -------------------------------- ### register::estat — Exception Status Register (ESTAT, CSR 0x5) Source: https://context7.com/godones/loongarch64/llms.txt ESTAT records the primary (Ecode) and secondary (EsubCode) codes of the current exception, as well as status bits for each interrupt. The `cause()` method automatically identifies TLB refill exceptions, machine errors, general exceptions, and interrupts. ```APIDOC ## register::estat — Exception Status Register (ESTAT, CSR 0x5) ### Description ESTAT records the primary (Ecode) and secondary (EsubCode) codes of the current exception, as well as status bits for each interrupt. The `cause()` method automatically identifies TLB refill exceptions, machine errors, general exceptions, and interrupts. ### Method Rust (using `loongArch64::register::estat` module) ### Usage Examples ```rust use loongArch64::register; use loongArch64::register::estat::{Trap, Exception, Interrupt}; // Read the exception cause at the exception handler entry point let estat = register::estat::read(); match estat.cause() { Trap::Exception(Exception::Syscall) => { // Handle syscall (Ecode = 0xB) } Trap::Exception(Exception::LoadPageFault) => { // Handle LOAD page fault (V=0), Ecode = 0x1 } Trap::Exception(Exception::StorePageFault) => { // Handle STORE page fault, Ecode = 0x2 } Trap::Exception(Exception::TLBRFill) => { // TLB refill exception (determined by TLBRERA.IsTLBR) } Trap::Interrupt(Interrupt::Timer) => { // Timer interrupt (interrupt bit 11) } Trap::Interrupt(Interrupt::IPI) => { // Inter-processor interrupt (interrupt bit 12) } Trap::MachineError(_) => { // Machine error exception (determined by MERRCTL.IsMERR) } Trap::Unknown => { /* Unknown type */ } } // Read the raw interrupt status bits (bits 0-12) let is_bits: usize = estat.is(); // Trigger software interrupt 0 register::estat::set_sw(0, true); ``` ``` -------------------------------- ### register::prmd — Previous Mode Information Register (PRMD, CSR 0x1) Source: https://context7.com/godones/loongarch64/llms.txt When a non-TLB refill or machine error exception occurs, hardware automatically saves the PLV, IE, and WE from CRMD to PRMD for restoration upon exception return. ```APIDOC ## register::prmd — Previous Mode Information Register (PRMD, CSR 0x1) ### Description When a non-TLB refill or machine error exception occurs, hardware automatically saves the PLV, IE, and WE from CRMD to PRMD for restoration upon exception return. ### Method Rust (using `loongArch64::register::prmd` module) ### Usage Examples ```rust use loongArch64::register; use loongArch64::register::CpuMode; // Read the mode information saved before the exception let prmd = register::prmd::read(); let pplv: usize = prmd.pplv(); // Privilege level before exception (0-3) let pie: bool = prmd.pie(); // Interrupt enable status before exception let pwe: bool = prmd.pwe(); // Monitor enable status before exception // Manually set (usually maintained by hardware, software can modify in exception handler) register::prmd::set_pplv(CpuMode::Ring0); register::prmd::set_pie(true); register::prmd::set_pwe(false); ``` ``` -------------------------------- ### register::crmd — Current Mode Information Register (CRMD, CSR 0x0) Source: https://context7.com/godones/loongarch64/llms.txt The CRMD register stores the processor's current privilege level, global interrupt enable, monitor enable, and address translation mode. Hardware automatically sets the privilege level to 0 upon exception; upon returning with ERTN, the context is restored. ```APIDOC ## register::crmd — Current Mode Information Register (CRMD, CSR 0x0) ### Description The CRMD register stores the processor's current privilege level, global interrupt enable, monitor enable, and address translation mode. Hardware automatically sets the privilege level to 0 upon exception; upon returning with ERTN, the context is restored. ### Method Rust (using `loongArch64::register::crmd` module) ### Usage Examples ```rust use loongArch64::register; use loongArch64::register::{CpuMode, MemoryAccessType}; // Read the CRMD register let crmd = register::crmd::read(); // Query the current privilege level (Ring0=kernel mode, Ring3=user mode) let plv: CpuMode = crmd.plv(); // Query the global interrupt enable status let ie: bool = crmd.ie(); // Query the address translation mode let is_direct: bool = crmd.da(); // Direct address translation let is_paging: bool = crmd.pg(); // Paging address translation // Query the memory access type in direct access mode for instruction fetch/data access let datf: MemoryAccessType = crmd.datf(); // Instruction fetch MAT let datm: MemoryAccessType = crmd.datm(); // Data access MAT // Modify fields register::crmd::set_ie(true); // Enable global interrupts register::crmd::set_plv(CpuMode::Ring0); // Set to kernel mode register::crmd::set_da(true); // Enable direct address translation register::crmd::set_pg(false); // Disable paging translation register::crmd::set_datf(MemoryAccessType::CoherentCached); // Instruction fetch CC register::crmd::set_datm(MemoryAccessType::CoherentCached); // Data access CC register::crmd::set_we(false); // Disable monitor // Debug output: CrMd { plv: Ring0, ie: true, we: false, is_paging_md: false, ... } println!("{:?}", crmd); ``` ``` -------------------------------- ### Machine Error Control Register (MERRCTL, CSR 0x90) Source: https://context7.com/godones/loongarch64/llms.txt MERRCTL is a core register for RAS functionality, independently saving the processor's context (privilege level, interrupt enable, address translation mode, etc.) when a machine error exception occurs. ```APIDOC ## `register::merrctl` — 机器错误控制寄存器(MERRCTL,CSR 0x90) MERRCTL 是 RAS 功能的核心寄存器,独立保存机器错误异常触发时的处理器现场(特权级、中断使能、地址翻译模式等)。 ```rust use loongArch64::register::ras::merrctl; // 读取机器错误状态 let merrctl = merrctl::read(); if merrctl.is_merr() { println!("机器错误异常已触发"); println!("可修复: {}", merrctl.repairable()); use loongArch64::register::ras::merrctl::MachineError; match merrctl.cause() { MachineError::CacheCheckError => println!("Cache 校验错误"), } // 读取异常前保存的现场 println!("异常前特权级: {}", merrctl.pplv()); println!("异常前中断使能: {}", merrctl.pie()); println!("异常前分页模式: {}", merrctl.ppg()); } ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.