From 3fe6b53334f1a92a3774f9eff2e18c48572b3b69 Mon Sep 17 00:00:00 2001 From: Priyanka Sar Date: Thu, 12 Mar 2026 16:16:33 +0530 Subject: [PATCH 1/2] corrected the if condition in the else branch and added flag in uartputc --- src/mp.rs | 2 +- src/uart.rs | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/mp.rs b/src/mp.rs index b731b0c..32d0bae 100644 --- a/src/mp.rs +++ b/src/mp.rs @@ -141,7 +141,7 @@ fn mpsearch() -> Option<*mut Mp> { } else { let p = unsafe {(((*bda.add(0x14) as u32) << 8) | (*bda.add(0x13) as u32)) * 1024}; mp = mpsearch1(p - 1024, 1024); - if !mp.is_some() { + if mp.is_some() { return mp; } } diff --git a/src/uart.rs b/src/uart.rs index b9e214e..2ed340a 100644 --- a/src/uart.rs +++ b/src/uart.rs @@ -1,6 +1,10 @@ use crate::x86::{outb, inb}; +use core::sync::atomic::{AtomicBool, Ordering}; + const COM1: u16 = 0x3F8; // COM1 port address +static UART: AtomicBool = AtomicBool::new(false); + pub fn uartinit() { // Turn off the FIFO. outb(COM1 + 2, 0); @@ -18,6 +22,7 @@ pub fn uartinit() { if inb(COM1 + 5) == 0xFF { return; } + UART.store(true, Ordering::Relaxed); // Announce that the UART is active. for p in "xv6...\n".chars() { uartputc(p); @@ -25,6 +30,9 @@ pub fn uartinit() { } pub fn uartputc(c: char) { + if !UART.load(Ordering::Relaxed) { + return; + } for _ in 0..128 { if inb(COM1 + 5) & 0x20 != 0 { break; From ee4c598e47333e7dc7860e066032a6bb6a10b6f3 Mon Sep 17 00:00:00 2001 From: Priyanka Sar Date: Thu, 12 Mar 2026 16:41:43 +0530 Subject: [PATCH 2/2] added functions mycpu and cpuid using the C logic --- src/mp.rs | 6 ++++-- src/proc.rs | 30 ++++++++++++++++++++++++++++++ src/x86.rs | 13 +++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/mp.rs b/src/mp.rs index 32d0bae..4efef60 100644 --- a/src/mp.rs +++ b/src/mp.rs @@ -71,12 +71,13 @@ pub const MPLINTR: u8 = 0x04; // One per system interrupt source pub struct MPWriteOnce { pub lapic_base: OnceCell<*mut u32>, pub ioapic_id: OnceCell, - pub cpus: OnceCell<[Cpu; NCPU]> + pub cpus: OnceCell<[Cpu; NCPU]>, + pub ncpu: OnceCell, } unsafe impl Sync for MPWriteOnce {} -pub static MP_ONCE: MPWriteOnce = MPWriteOnce { lapic_base: OnceCell::new(), ioapic_id: OnceCell::new(), cpus: OnceCell::new() }; +pub static MP_ONCE: MPWriteOnce = MPWriteOnce { lapic_base: OnceCell::new(), ioapic_id: OnceCell::new(), cpus: OnceCell::new(), ncpu: OnceCell::new() }; /// Calculates sum of bytes in a memory region /// @@ -233,6 +234,7 @@ pub fn mpinit() { panic!("Didn't find a suitable machine"); } MP_ONCE.cpus.set(cpus); + MP_ONCE.ncpu.set(ncpu); if mp.imcrp != 0 { // Bochs doesn't support IMCR, so this doesn't run on Bochs. diff --git a/src/proc.rs b/src/proc.rs index 8c26c78..2adb34a 100644 --- a/src/proc.rs +++ b/src/proc.rs @@ -1,3 +1,9 @@ +use crate::lapic::lapicid; +use crate::mp::MP_ONCE; +use crate::x86::readeflags; + +const FL_IF: u32 = 0x00000200; // Interrupt flag + #[derive(Debug, Clone, Copy)] pub struct Cpu { pub apicid: u8, // Local APIC ID @@ -7,4 +13,28 @@ impl Cpu { pub const fn new() -> Self { Self { apicid: 0 } } +} + +// Must be called with interrupts disabled to avoid the caller being +// rescheduled between reading lapicid and running through the loop. +pub fn mycpu() -> &'static Cpu { + if readeflags() & FL_IF != 0 { + panic!("mycpu called with interrupts enabled"); + } + let apicid = lapicid() as u8; + let cpus = MP_ONCE.cpus.get().unwrap(); + let ncpu = *MP_ONCE.ncpu.get().unwrap(); + for i in 0..ncpu { + if cpus[i].apicid == apicid { + return &cpus[i]; + } + } + panic!("unknown apicid"); +} + +// Must be called with interrupts disabled +pub fn cpuid() -> usize { + let cpu = mycpu() as *const Cpu; + let cpus = MP_ONCE.cpus.get().unwrap().as_ptr(); + unsafe { cpu.offset_from(cpus) as usize } } \ No newline at end of file diff --git a/src/x86.rs b/src/x86.rs index ac32315..aa1d87f 100644 --- a/src/x86.rs +++ b/src/x86.rs @@ -1,5 +1,18 @@ use core::arch::asm; +pub fn readeflags() -> u32 { + let eflags: u32; + unsafe { + asm!( + "pushfd", + "pop {0:e}", + out(reg) eflags, + options(nomem, nostack) + ); + } + eflags +} + pub fn inb(port: u16) -> u8 { let result: u8; unsafe {