From 5ec846a61639d893cbdb59eb6ff071563171d306 Mon Sep 17 00:00:00 2001 From: Graham MacDonald Date: Wed, 8 Jul 2026 10:39:31 +0100 Subject: [PATCH 1/3] Bump rust, fix issues Signed-off-by: Graham MacDonald --- aarch64/src/vm.rs | 2 +- lib/x86_64-unknown-none-elf.json | 40 ++++++++++++++++---------------- port/src/allocator.rs | 2 +- rust-toolchain.toml | 2 +- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/aarch64/src/vm.rs b/aarch64/src/vm.rs index 7372fd4..8b9529a 100644 --- a/aarch64/src/vm.rs +++ b/aarch64/src/vm.rs @@ -516,7 +516,7 @@ impl RootPageTable { static next_free_device_page_va: AtomicUsize = AtomicUsize::new(KZERO + 0x100000000000); pub fn next_free_device_page4k() -> VaMapping { next_free_device_page_va - .fetch_update(Ordering::Relaxed, Ordering::Relaxed, |current| { + .try_update(Ordering::Relaxed, Ordering::Relaxed, |current| { Some(current + PageSize::Page4K.size()) }) .map(VaMapping::Addr) diff --git a/lib/x86_64-unknown-none-elf.json b/lib/x86_64-unknown-none-elf.json index 577880f..b1b2ca6 100644 --- a/lib/x86_64-unknown-none-elf.json +++ b/lib/x86_64-unknown-none-elf.json @@ -1,22 +1,22 @@ { - "llvm-target": "x86_64-unknown-none-elf", - "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", - "linker-flavor": "ld.lld", - "linker": "rust-lld", - "target-endian": "little", - "target-pointer-width": 64, - "target-c-int-width": 32, - "arch": "x86_64", - "os": "none", - "executables": true, - "relocation-model": "static", - "code-model": "kernel", - "disable-redzone": true, - "features": "-mmx,-sse,+soft-float", - "panic-strategy": "abort", - "frame-pointer": "always", - "pre-link-args": { - "ld.lld": ["-nostdlib"] - }, - "rustc-abi": "x86-softfloat" + "llvm-target": "x86_64-unknown-none-elf", + "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", + "linker-flavor": "ld.lld", + "linker": "rust-lld", + "target-endian": "little", + "target-pointer-width": 64, + "target-c-int-width": 32, + "arch": "x86_64", + "os": "none", + "executables": true, + "relocation-model": "static", + "code-model": "kernel", + "disable-redzone": true, + "features": "-mmx,-sse,+soft-float", + "panic-strategy": "abort", + "frame-pointer": "always", + "pre-link-args": { + "ld.lld": ["-nostdlib"] + }, + "rustc-abi": "softfloat" } diff --git a/port/src/allocator.rs b/port/src/allocator.rs index f020913..f2ee84b 100644 --- a/port/src/allocator.rs +++ b/port/src/allocator.rs @@ -88,7 +88,7 @@ impl BumpAlloc { let mut first = ptr::null_mut(); let mut adjust = 0; self.cursor - .fetch_update(Ordering::Relaxed, Ordering::Relaxed, |current| { + .try_update(Ordering::Relaxed, Ordering::Relaxed, |current| { first = base.wrapping_add(current); adjust = first.align_offset(align); let offset = current.checked_add(adjust).expect("alignment overflow"); diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 5563919..1711291 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,5 +1,5 @@ [toolchain] -channel = "nightly-2026-05-20" +channel = "nightly-2026-07-06" components = ["rustfmt", "rust-src", "clippy", "llvm-tools"] targets = [ "aarch64-unknown-none", From 7a2ca239b7fc2633c66c8be6af71cf98c9533271 Mon Sep 17 00:00:00 2001 From: Graham MacDonald Date: Wed, 8 Jul 2026 11:35:04 +0100 Subject: [PATCH 2/3] Tidy aarch64 registers Signed-off-by: Graham MacDonald --- aarch64/src/main.rs | 4 +- aarch64/src/reg/esr_el1.rs | 161 ++++++++++++++++++++++++ aarch64/src/reg/midr_el1.rs | 52 ++++++++ aarch64/src/reg/mod.rs | 2 + aarch64/src/registers.rs | 235 ------------------------------------ aarch64/src/trap.rs | 2 +- aarch64/src/uartmini.rs | 18 ++- aarch64/src/uartpl011.rs | 17 ++- 8 files changed, 246 insertions(+), 245 deletions(-) create mode 100644 aarch64/src/reg/esr_el1.rs create mode 100644 aarch64/src/reg/midr_el1.rs create mode 100644 aarch64/src/reg/mod.rs diff --git a/aarch64/src/main.rs b/aarch64/src/main.rs index a3eaa29..92ba6fc 100644 --- a/aarch64/src/main.rs +++ b/aarch64/src/main.rs @@ -17,6 +17,7 @@ mod mailbox; mod pagealloc; mod param; mod pre_mmu; +mod reg; mod registers; mod swtch; mod trap; @@ -33,6 +34,7 @@ use param::KZERO; use port::fdt::DeviceTree; use port::mem::{PhysAddr, PhysRange, VirtRange}; use port::println; +use reg::midr_el1::MidrEl1; use vm::{Entry, RootPageTableType, VaMapping}; use crate::kmem::{ @@ -134,7 +136,7 @@ pub extern "C" fn main9(dtb_va: usize) { println!(); println!("r9 from the Internet"); println!("DTB found at: {:#x}", dtb_va); - println!("midr_el1: {:?}", registers::MidrEl1::read()); + println!("midr_el1: {:?}", MidrEl1::read()); print_stacks(); diff --git a/aarch64/src/reg/esr_el1.rs b/aarch64/src/reg/esr_el1.rs new file mode 100644 index 0000000..ff65a31 --- /dev/null +++ b/aarch64/src/reg/esr_el1.rs @@ -0,0 +1,161 @@ +use core::fmt; + +use bitstruct::bitstruct; +use num_enum::TryFromPrimitive; + +bitstruct! { + #[derive(Copy, Clone)] + pub struct EsrEl1(pub u64) { + pub iss: u32 = 0..25; + pub il: bool = 25; + pub ec: u8 = 26..32; + pub iss2: u8 = 32..37; + } +} + +impl EsrEl1 { + /// Try to convert the error into an ExceptionClass enum, or return the original number + /// as the error. + pub fn exception_class_enum(&self) -> Result { + ExceptionClass::try_from(self.ec()).map_err(|e| e.number) + } +} + +impl fmt::Debug for EsrEl1 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("EsrEl1") + .field("iss", &format_args!("{:#010x}", self.iss())) + .field("il", &format_args!("{}", self.il())) + .field("ec", &format_args!("{:?}", self.exception_class_enum())) + .field("iss2", &format_args!("{:#04x}", self.iss2())) + .finish() + } +} + +/// Exception class maps to ESR_EL1 EC bits[31:26]. We skip aarch32 exceptions. +#[derive(Debug, Eq, PartialEq, TryFromPrimitive)] +#[repr(u8)] +pub enum ExceptionClass { + Unknown = 0, + WaitFor = 1, + FloatSimd = 7, + Ls64 = 10, + BranchTargetException = 13, + IllegalExecutionState = 14, + MsrMrsSystem = 24, + Sve = 25, + Tstart = 27, + PointerAuthFailure = 28, + Sme = 29, + GranuleProtectionCheck = 30, + InstructionAbortLowerEl = 32, + InstructionAbortSameEl = 33, + PcAlignmentFault = 34, + DataAbortLowerEl = 36, + DataAbortSameEl = 37, + SpAlignmentFault = 38, + MemoryOperationException = 39, + TrappedFloatingPointException = 44, + SError = 47, + BreakpointLowerEl = 48, + BreakpointSameEl = 49, + SoftwareStepLowerEl = 50, + SoftwareStepSameEl = 51, + WatchpointLowerEl = 52, + WatchpointSameEl = 53, + Brk = 60, +} + +bitstruct! { + #[derive(Copy, Clone)] + pub struct EsrEl1IssInstructionAbort(pub u32) { + ifsc: u8 = 0..6; + s1ptw: bool = 7; + ea: bool = 9; + fnv: bool = 10; + set: u8 = 11..13; + } +} + +#[allow(dead_code)] +impl EsrEl1IssInstructionAbort { + pub fn from_esr_el1(r: EsrEl1) -> Option { + r.exception_class_enum() + .ok() + .filter(|ec| *ec == ExceptionClass::InstructionAbortSameEl) + .map(|_| EsrEl1IssInstructionAbort(r.iss())) + } + + pub fn instruction_fault(&self) -> Result { + InstructionFaultStatusCode::try_from(self.ifsc()).map_err(|e| e.number) + } +} + +#[derive(Debug, Eq, PartialEq, TryFromPrimitive)] +#[repr(u8)] +pub enum InstructionFaultStatusCode { + AddressSizeFaultLevel0 = 0, + AddressSizeFaultLevel1 = 1, + AddressSizeFaultLevel2 = 2, + AddressSizeFaultLevel3 = 3, + TranslationFaultLevel0 = 4, + TranslationFaultLevel1 = 5, + TranslationFaultLevel2 = 6, + TranslationFaultLevel3 = 7, + AccessFlagFaultLevel0 = 8, + AccessFlagFaultLevel1 = 9, + AccessFlagFaultLevel2 = 10, + AccessFlagFaultLevel3 = 11, + PermissionFaultLevel0 = 12, + PermissionFaultLevel1 = 13, + PermissionFaultLevel2 = 14, + PermissionFaultLevel3 = 15, + SyncExtAbortNotOnWalkOrUpdate = 16, + SyncExtAbortOnWalkOrUpdateLevelNeg1 = 19, + SyncExtAbortOnWalkOrUpdateLevel0 = 20, + SyncExtAbortOnWalkOrUpdateLevel1 = 21, + SyncExtAbortOnWalkOrUpdateLevel2 = 22, + SyncExtAbortOnWalkOrUpdateLevel3 = 23, + SyncParityOrEccErrOnMemAccessNotOnWalk = 24, + SyncParityOrEccErrOnMemAccessOnWalkOrUpdateLevelNeg1 = 27, + SyncParityOrEccErrOnMemAccessOnWalkOrUpdateLevel0 = 28, + SyncParityOrEccErrOnMemAccessOnWalkOrUpdateLevel1 = 29, + SyncParityOrEccErrOnMemAccessOnWalkOrUpdateLevel2 = 30, + SyncParityOrEccErrOnMemAccessOnWalkOrUpdateLevel3 = 31, + GranuleProtectFaultOnWalkOrUpdateLevelNeg1 = 35, + GranuleProtectFaultOnWalkOrUpdateLevel0 = 36, + GranuleProtectFaultOnWalkOrUpdateLevel1 = 37, + GranuleProtectFaultOnWalkOrUpdateLevel2 = 38, + GranuleProtectFaultOnWalkOrUpdateLevel3 = 39, + GranuleProtectFaultNotOnWalkOrUpdateLevel = 40, + AddressSizeFaultLevelNeg1 = 41, + TranslationFaultLevelNeg1 = 43, + TlbConflictAbort = 48, + UnsupportedAtomicHardwareUpdateFault = 49, +} + +#[cfg(test)] +mod tests { + use super::*; + + // This test is useful for making sense of early-stage exceptions. Qemu + // will report an exception of the form below. Copy the ESR value into + // this test to break it down. + // + // Exception return from AArch64 EL2 to AArch64 EL1 PC 0x8006c + // Taking exception 3 [Prefetch Abort] on CPU 0 + // ...from EL1 to EL1 + // ...with ESR 0x21/0x86000004 + // ...with FAR 0x80090 + // ...with ELR 0x80090 + // ...to EL1 PC 0x200 PSTATE 0x3c5 + #[test] + fn test_parse_esr_el1() { + let r = EsrEl1(0x86000004); + assert_eq!(r.exception_class_enum().unwrap(), ExceptionClass::InstructionAbortSameEl); + assert_eq!( + EsrEl1IssInstructionAbort::from_esr_el1(r).unwrap().instruction_fault().unwrap(), + InstructionFaultStatusCode::TranslationFaultLevel0 + ); + } +} diff --git a/aarch64/src/reg/midr_el1.rs b/aarch64/src/reg/midr_el1.rs new file mode 100644 index 0000000..1f509dc --- /dev/null +++ b/aarch64/src/reg/midr_el1.rs @@ -0,0 +1,52 @@ +use core::fmt; + +use aarch64_cpu::registers::{MIDR_EL1, Readable}; +use bitstruct::bitstruct; +use num_enum::TryFromPrimitive; + +bitstruct! { + #[derive(Copy, Clone)] + pub struct MidrEl1(pub u64) { + revision: u8 = 0..4; + partnum: u16 = 4..16; + architecture: u8 = 16..20; + variant: u8 = 20..24; + implementer: u16 = 24..32; + } +} + +impl MidrEl1 { + pub fn read() -> Self { + Self(if cfg!(test) { 0 } else { MIDR_EL1.extract().into() }) + } + + pub fn partnum_enum(&self) -> Result { + PartNum::try_from(self.partnum()).map_err(|e| e.number) + } +} + +impl fmt::Debug for MidrEl1 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("MidrEl1") + .field("revision", &format_args!("{:#x}", self.revision())) + .field( + "partnum", + &format_args!("{:?}", self.partnum_enum().unwrap_or(PartNum::Unknown)), + ) + .field("architecture", &format_args!("{:#x}", self.architecture())) + .field("variant", &format_args!("{:#x}", self.variant())) + .field("implementer", &format_args!("{:#x}", self.implementer())) + .finish() + } +} + +/// Known IDs for midr_el1's partnum +#[derive(Debug, Eq, PartialEq, TryFromPrimitive)] +#[repr(u16)] +pub enum PartNum { + Unknown = 0, + RaspberryPi1 = 0xb76, + RaspberryPi2 = 0xc07, + RaspberryPi3 = 0xd03, + RaspberryPi4 = 0xd08, +} diff --git a/aarch64/src/reg/mod.rs b/aarch64/src/reg/mod.rs new file mode 100644 index 0000000..85646b0 --- /dev/null +++ b/aarch64/src/reg/mod.rs @@ -0,0 +1,2 @@ +pub mod esr_el1; +pub mod midr_el1; diff --git a/aarch64/src/registers.rs b/aarch64/src/registers.rs index cb00320..e166f95 100644 --- a/aarch64/src/registers.rs +++ b/aarch64/src/registers.rs @@ -1,241 +1,6 @@ #![allow(non_upper_case_globals)] -use aarch64_cpu::registers::MIDR_EL1; -use aarch64_cpu::registers::Readable; -use bitstruct::bitstruct; -use core::fmt; -use num_enum::TryFromPrimitive; - // GPIO registers pub const GPFSEL1: usize = 0x04; // GPIO function select register 1 pub const GPPUD: usize = 0x94; // GPIO pin pull up/down enable pub const GPPUDCLK0: usize = 0x98; // GPIO pin pull up/down enable clock 0 - -// UART 0 (PL011) registers -#[allow(unused)] -pub const UART0_DR: usize = 0x00; // Data register -#[allow(unused)] -pub const UART0_FR: usize = 0x18; // Flag register -pub const UART0_IBRD: usize = 0x24; // Integer baud rate divisor -pub const UART0_FBRD: usize = 0x28; // Fractional baud rate divisor -pub const UART0_LCRH: usize = 0x2c; // Line control register -pub const UART0_CR: usize = 0x30; // Control register -pub const UART0_IMSC: usize = 0x38; // Interrupt mask set clear register -pub const UART0_ICR: usize = 0x44; // Interrupt clear register - -// AUX registers, offset from aux_reg -pub const AUX_ENABLE: usize = 0x04; // AUX enable register (Mini Uart, SPIs) - -// UART1 registers, offset from miniuart_reg -pub const AUX_MU_IO: usize = 0x00; // AUX IO data register -pub const AUX_MU_IER: usize = 0x04; // Mini Uart interrupt enable register -pub const AUX_MU_IIR: usize = 0x08; // Mini Uart interrupt identify register -pub const AUX_MU_LCR: usize = 0x0c; // Mini Uart line control register -pub const AUX_MU_MCR: usize = 0x10; // Mini Uart line control register -pub const AUX_MU_LSR: usize = 0x14; // Mini Uart line status register -pub const AUX_MU_CNTL: usize = 0x20; // Mini Uart control register -pub const AUX_MU_BAUD: usize = 0x28; // Mini Uart baudrate register - -bitstruct! { - #[derive(Copy, Clone)] - pub struct MidrEl1(pub u64) { - revision: u8 = 0..4; - partnum: u16 = 4..16; - architecture: u8 = 16..20; - variant: u8 = 20..24; - implementer: u16 = 24..32; - } -} - -impl MidrEl1 { - pub fn read() -> Self { - Self(if cfg!(test) { 0 } else { MIDR_EL1.extract().into() }) - } - - pub fn partnum_enum(&self) -> Result { - PartNum::try_from(self.partnum()).map_err(|e| e.number) - } -} - -impl fmt::Debug for MidrEl1 { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("MidrEl1") - .field("revision", &format_args!("{:#x}", self.revision())) - .field( - "partnum", - &format_args!("{:?}", self.partnum_enum().unwrap_or(PartNum::Unknown)), - ) - .field("architecture", &format_args!("{:#x}", self.architecture())) - .field("variant", &format_args!("{:#x}", self.variant())) - .field("implementer", &format_args!("{:#x}", self.implementer())) - .finish() - } -} - -/// Known IDs for midr_el1's partnum -#[derive(Debug, Eq, PartialEq, TryFromPrimitive)] -#[repr(u16)] -pub enum PartNum { - Unknown = 0, - RaspberryPi1 = 0xb76, - RaspberryPi2 = 0xc07, - RaspberryPi3 = 0xd03, - RaspberryPi4 = 0xd08, -} - -bitstruct! { - #[derive(Copy, Clone)] - pub struct EsrEl1(pub u64) { - pub iss: u32 = 0..25; - pub il: bool = 25; - pub ec: u8 = 26..32; - pub iss2: u8 = 32..37; - } -} - -impl EsrEl1 { - /// Try to convert the error into an ExceptionClass enum, or return the original number - /// as the error. - pub fn exception_class_enum(&self) -> Result { - ExceptionClass::try_from(self.ec()).map_err(|e| e.number) - } -} - -impl fmt::Debug for EsrEl1 { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("EsrEl1") - .field("iss", &format_args!("{:#010x}", self.iss())) - .field("il", &format_args!("{}", self.il())) - .field("ec", &format_args!("{:?}", self.exception_class_enum())) - .field("iss2", &format_args!("{:#04x}", self.iss2())) - .finish() - } -} - -/// Exception class maps to ESR_EL1 EC bits[31:26]. We skip aarch32 exceptions. -#[derive(Debug, Eq, PartialEq, TryFromPrimitive)] -#[repr(u8)] -pub enum ExceptionClass { - Unknown = 0, - WaitFor = 1, - FloatSimd = 7, - Ls64 = 10, - BranchTargetException = 13, - IllegalExecutionState = 14, - MsrMrsSystem = 24, - Sve = 25, - Tstart = 27, - PointerAuthFailure = 28, - Sme = 29, - GranuleProtectionCheck = 30, - InstructionAbortLowerEl = 32, - InstructionAbortSameEl = 33, - PcAlignmentFault = 34, - DataAbortLowerEl = 36, - DataAbortSameEl = 37, - SpAlignmentFault = 38, - MemoryOperationException = 39, - TrappedFloatingPointException = 44, - SError = 47, - BreakpointLowerEl = 48, - BreakpointSameEl = 49, - SoftwareStepLowerEl = 50, - SoftwareStepSameEl = 51, - WatchpointLowerEl = 52, - WatchpointSameEl = 53, - Brk = 60, -} - -bitstruct! { - #[derive(Copy, Clone)] - pub struct EsrEl1IssInstructionAbort(pub u32) { - ifsc: u8 = 0..6; - s1ptw: bool = 7; - ea: bool = 9; - fnv: bool = 10; - set: u8 = 11..13; - } -} - -#[allow(dead_code)] -impl EsrEl1IssInstructionAbort { - pub fn from_esr_el1(r: EsrEl1) -> Option { - r.exception_class_enum() - .ok() - .filter(|ec| *ec == ExceptionClass::InstructionAbortSameEl) - .map(|_| EsrEl1IssInstructionAbort(r.iss())) - } - - pub fn instruction_fault(&self) -> Result { - InstructionFaultStatusCode::try_from(self.ifsc()).map_err(|e| e.number) - } -} - -#[derive(Debug, Eq, PartialEq, TryFromPrimitive)] -#[repr(u8)] -pub enum InstructionFaultStatusCode { - AddressSizeFaultLevel0 = 0, - AddressSizeFaultLevel1 = 1, - AddressSizeFaultLevel2 = 2, - AddressSizeFaultLevel3 = 3, - TranslationFaultLevel0 = 4, - TranslationFaultLevel1 = 5, - TranslationFaultLevel2 = 6, - TranslationFaultLevel3 = 7, - AccessFlagFaultLevel0 = 8, - AccessFlagFaultLevel1 = 9, - AccessFlagFaultLevel2 = 10, - AccessFlagFaultLevel3 = 11, - PermissionFaultLevel0 = 12, - PermissionFaultLevel1 = 13, - PermissionFaultLevel2 = 14, - PermissionFaultLevel3 = 15, - SyncExtAbortNotOnWalkOrUpdate = 16, - SyncExtAbortOnWalkOrUpdateLevelNeg1 = 19, - SyncExtAbortOnWalkOrUpdateLevel0 = 20, - SyncExtAbortOnWalkOrUpdateLevel1 = 21, - SyncExtAbortOnWalkOrUpdateLevel2 = 22, - SyncExtAbortOnWalkOrUpdateLevel3 = 23, - SyncParityOrEccErrOnMemAccessNotOnWalk = 24, - SyncParityOrEccErrOnMemAccessOnWalkOrUpdateLevelNeg1 = 27, - SyncParityOrEccErrOnMemAccessOnWalkOrUpdateLevel0 = 28, - SyncParityOrEccErrOnMemAccessOnWalkOrUpdateLevel1 = 29, - SyncParityOrEccErrOnMemAccessOnWalkOrUpdateLevel2 = 30, - SyncParityOrEccErrOnMemAccessOnWalkOrUpdateLevel3 = 31, - GranuleProtectFaultOnWalkOrUpdateLevelNeg1 = 35, - GranuleProtectFaultOnWalkOrUpdateLevel0 = 36, - GranuleProtectFaultOnWalkOrUpdateLevel1 = 37, - GranuleProtectFaultOnWalkOrUpdateLevel2 = 38, - GranuleProtectFaultOnWalkOrUpdateLevel3 = 39, - GranuleProtectFaultNotOnWalkOrUpdateLevel = 40, - AddressSizeFaultLevelNeg1 = 41, - TranslationFaultLevelNeg1 = 43, - TlbConflictAbort = 48, - UnsupportedAtomicHardwareUpdateFault = 49, -} - -#[cfg(test)] -mod tests { - use super::*; - - // This test is useful for making sense of early-stage exceptions. Qemu - // will report an exception of the form below. Copy the ESR value into - // this test to break it down. - // - // Exception return from AArch64 EL2 to AArch64 EL1 PC 0x8006c - // Taking exception 3 [Prefetch Abort] on CPU 0 - // ...from EL1 to EL1 - // ...with ESR 0x21/0x86000004 - // ...with FAR 0x80090 - // ...with ELR 0x80090 - // ...to EL1 PC 0x200 PSTATE 0x3c5 - #[test] - fn test_parse_esr_el1() { - let r = EsrEl1(0x86000004); - assert_eq!(r.exception_class_enum().unwrap(), ExceptionClass::InstructionAbortSameEl); - assert_eq!( - EsrEl1IssInstructionAbort::from_esr_el1(r).unwrap().instruction_fault().unwrap(), - InstructionFaultStatusCode::TranslationFaultLevel0 - ); - } -} diff --git a/aarch64/src/trap.rs b/aarch64/src/trap.rs index c1aa41b..d02874e 100644 --- a/aarch64/src/trap.rs +++ b/aarch64/src/trap.rs @@ -1,6 +1,6 @@ use core::fmt; -use crate::registers::EsrEl1; +use crate::reg::esr_el1::EsrEl1; use port::println; #[cfg(not(test))] diff --git a/aarch64/src/uartmini.rs b/aarch64/src/uartmini.rs index fa5ab8a..909c674 100644 --- a/aarch64/src/uartmini.rs +++ b/aarch64/src/uartmini.rs @@ -5,15 +5,25 @@ use port::mem::{PhysRange, VirtRange}; use crate::deviceutil::map_device_register; use crate::io::{delay, read_reg, write_or_reg, write_reg}; -use crate::registers::{ - AUX_ENABLE, AUX_MU_BAUD, AUX_MU_CNTL, AUX_MU_IER, AUX_MU_IIR, AUX_MU_IO, AUX_MU_LCR, - AUX_MU_LSR, AUX_MU_MCR, GPFSEL1, GPPUD, GPPUDCLK0, -}; +use crate::registers::{GPFSEL1, GPPUD, GPPUDCLK0}; use crate::vm; #[cfg(not(test))] use port::println; +// AUX registers, offset from aux_reg +pub const AUX_ENABLE: usize = 0x04; // AUX enable register (Mini Uart, SPIs) + +// UART1 registers, offset from miniuart_reg +pub const AUX_MU_IO: usize = 0x00; // AUX IO data register +pub const AUX_MU_IER: usize = 0x04; // Mini Uart interrupt enable register +pub const AUX_MU_IIR: usize = 0x08; // Mini Uart interrupt identify register +pub const AUX_MU_LCR: usize = 0x0c; // Mini Uart line control register +pub const AUX_MU_MCR: usize = 0x10; // Mini Uart line control register +pub const AUX_MU_LSR: usize = 0x14; // Mini Uart line status register +pub const AUX_MU_CNTL: usize = 0x20; // Mini Uart control register +pub const AUX_MU_BAUD: usize = 0x28; // Mini Uart baudrate register + /// MiniUart is assigned to UART1 on the Raspberry Pi. It is easier to use with /// real hardware, as it requires no additional configuration. Conversely, it's /// harded to use with QEMU, as it can't be used with the `nographic` switch. diff --git a/aarch64/src/uartpl011.rs b/aarch64/src/uartpl011.rs index 9157cce..77ad6c0 100644 --- a/aarch64/src/uartpl011.rs +++ b/aarch64/src/uartpl011.rs @@ -1,9 +1,6 @@ use crate::deviceutil::map_device_register; use crate::io::{GpioPull, delay, read_reg, write_reg}; -use crate::registers::{ - GPPUD, GPPUDCLK0, UART0_CR, UART0_DR, UART0_FBRD, UART0_FR, UART0_IBRD, UART0_ICR, UART0_IMSC, - UART0_LCRH, -}; +use crate::registers::{GPPUD, GPPUDCLK0}; use crate::{mailbox, vm}; use port::Result; use port::devcons::Uart; @@ -13,6 +10,18 @@ use port::mem::{PhysRange, VirtRange}; #[cfg(not(test))] use port::println; +// UART 0 (PL011) registers +#[allow(unused)] +pub const UART0_DR: usize = 0x00; // Data register +#[allow(unused)] +pub const UART0_FR: usize = 0x18; // Flag register +pub const UART0_IBRD: usize = 0x24; // Integer baud rate divisor +pub const UART0_FBRD: usize = 0x28; // Fractional baud rate divisor +pub const UART0_LCRH: usize = 0x2c; // Line control register +pub const UART0_CR: usize = 0x30; // Control register +pub const UART0_IMSC: usize = 0x38; // Interrupt mask set clear register +pub const UART0_ICR: usize = 0x44; // Interrupt clear register + #[allow(dead_code)] pub struct Pl011Uart { gpio_virtrange: VirtRange, From 617ee80fa0654000651ec320982ca49b0e809804 Mon Sep 17 00:00:00 2001 From: Graham MacDonald Date: Sat, 11 Jul 2026 21:10:41 +0100 Subject: [PATCH 3/3] add rust analyzer to rustup Signed-off-by: Graham MacDonald --- rust-toolchain.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 1711291..c74d35b 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,6 +1,6 @@ [toolchain] channel = "nightly-2026-07-06" -components = ["rustfmt", "rust-src", "clippy", "llvm-tools"] +components = ["rustfmt", "rust-analyzer", "rust-src", "clippy", "llvm-tools"] targets = [ "aarch64-unknown-none", "riscv64gc-unknown-none-elf",