From 6b2439f1b9a2ef035a77613bfcf3d909a67adeca Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 18 Aug 2022 14:57:15 -0600 Subject: [PATCH] Improved 32-bit x86 support --- src/arch/x86/gdt.rs | 6 ++++++ src/context/arch/x86.rs | 19 +++++-------------- src/context/switch.rs | 4 ++-- src/scheme/irq.rs | 4 ++-- src/scheme/sys/mod.rs | 2 +- src/syscall/driver.rs | 16 +++++++++++++++- 6 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/arch/x86/gdt.rs b/src/arch/x86/gdt.rs index baddf22..41f7e4c 100644 --- a/src/arch/x86/gdt.rs +++ b/src/arch/x86/gdt.rs @@ -218,6 +218,12 @@ impl GdtEntry { } } + pub fn offset(&self) -> u32 { + (self.offsetl as u32) | + ((self.offsetm as u32) << 16) | + ((self.offseth as u32) << 24) + } + pub fn set_offset(&mut self, offset: u32) { self.offsetl = offset as u16; self.offsetm = (offset >> 16) as u8; diff --git a/src/context/arch/x86.rs b/src/context/arch/x86.rs index 5b62b42..6c874b3 100644 --- a/src/context/arch/x86.rs +++ b/src/context/arch/x86.rs @@ -3,6 +3,7 @@ use core::sync::atomic::AtomicBool; use alloc::sync::Arc; +use crate::gdt::{GDT, GDT_TSS}; use crate::paging::{RmmA, RmmArch}; use crate::syscall::FloatRegisters; @@ -134,12 +135,8 @@ pub unsafe fn switch_to(prev: &mut super::Context, next: &mut super::Context) { ); { - use x86::{bits64::segmentation::*, msr}; - - prev.arch.fsbase = msr::rdmsr(msr::IA32_FS_BASE) as usize; - msr::wrmsr(msr::IA32_FS_BASE, next.arch.fsbase as u64); - prev.arch.gsbase = msr::rdmsr(msr::IA32_KERNEL_GSBASE) as usize; - msr::wrmsr(msr::IA32_KERNEL_GSBASE, next.arch.gsbase as u64); + prev.arch.gsbase = GDT[GDT_TSS].offset() as usize; + GDT[GDT_TSS].set_offset(next.arch.gsbase as u32); } match next.addr_space { @@ -235,8 +232,6 @@ unsafe extern "cdecl" fn switch_to_inner() { #[allow(dead_code)] #[repr(packed)] pub struct SignalHandlerStack { - esi: usize, - edi: usize, edx: usize, ecx: usize, eax: usize, @@ -246,7 +241,7 @@ pub struct SignalHandlerStack { } #[naked] -unsafe extern fn signal_handler_wrapper() { +unsafe extern "C" fn signal_handler_wrapper() { #[inline(never)] unsafe extern "C" fn inner(stack: &SignalHandlerStack) { (stack.handler)(stack.sig); @@ -258,19 +253,15 @@ unsafe extern fn signal_handler_wrapper() { push eax push ecx push edx - push edi - push esi push esp call {inner} pop esp - pop esi - pop edi pop edx pop ecx pop eax - add esp, 16 + add esp, 8 ret ", diff --git a/src/context/switch.rs b/src/context/switch.rs index 8a565e5..afb489a 100644 --- a/src/context/switch.rs +++ b/src/context/switch.rs @@ -8,7 +8,7 @@ use spin::RwLock; use crate::context::signal::signal_handler; use crate::context::{arch, contexts, Context, Status, CONTEXT_ID}; -#[cfg(target_arch = "x86_64")] +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] use crate::gdt; use crate::interrupt::irq::PIT_TICKS; use crate::interrupt; @@ -164,7 +164,7 @@ pub unsafe fn switch() -> bool { from_context_guard.running = false; to_context.running = true; - #[cfg(target_arch = "x86_64")] + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { if let Some(ref stack) = to_context.kstack { gdt::set_tss_stack(stack.as_ptr() as usize + stack.len()); diff --git a/src/scheme/irq.rs b/src/scheme/irq.rs index dcf0172..3aec213 100644 --- a/src/scheme/irq.rs +++ b/src/scheme/irq.rs @@ -83,7 +83,7 @@ impl IrqScheme { *HANDLES.write() = Some(BTreeMap::new()); - #[cfg(all(feature = "acpi", target_arch = "x86_64"))] + #[cfg(all(feature = "acpi", any(target_arch = "x86", target_arch = "x86_64")))] let cpus = { use crate::acpi::madt::*; @@ -94,7 +94,7 @@ impl IrqScheme { _ => None, }).collect::>() }; - #[cfg(not(all(feature = "acpi", target_arch = "x86_64")))] + #[cfg(not(all(feature = "acpi", any(target_arch = "x86", target_arch = "x86_64"))))] let cpus = vec!(0); IrqScheme { diff --git a/src/scheme/sys/mod.rs b/src/scheme/sys/mod.rs index d8f1989..61f14b3 100644 --- a/src/scheme/sys/mod.rs +++ b/src/scheme/sys/mod.rs @@ -53,7 +53,7 @@ impl SysScheme { files.insert("syscall", Box::new(syscall::resource)); files.insert("uname", Box::new(uname::resource)); files.insert("env", Box::new(|| Ok(Vec::from(crate::init_env())))); - #[cfg(target_arch = "x86_64")] + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] files.insert("spurious_irq", Box::new(irq::spurious_irq_resource)); SysScheme { diff --git a/src/syscall/driver.rs b/src/syscall/driver.rs index bc350b8..f3d3d76 100644 --- a/src/syscall/driver.rs +++ b/src/syscall/driver.rs @@ -20,11 +20,24 @@ fn enforce_root() -> Result<()> { } } -#[cfg(not(target_arch = "x86_64"))] +#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] pub fn iopl(level: usize, stack: &mut InterruptStack) -> Result { Err(Error::new(syscall::error::ENOSYS)) } +#[cfg(target_arch = "x86")] +pub fn iopl(level: usize, stack: &mut InterruptStack) -> Result { + enforce_root()?; + + if level > 3 { + return Err(Error::new(EINVAL)); + } + + stack.iret.eflags = (stack.iret.eflags & !(3 << 12)) | ((level & 3) << 12); + + Ok(0) +} + #[cfg(target_arch = "x86_64")] pub fn iopl(level: usize, stack: &mut InterruptStack) -> Result { enforce_root()?; @@ -92,6 +105,7 @@ pub fn inner_physmap(physical_address: usize, size: usize, flags: PhysmapFlags) if flags.contains(PHYSMAP_WRITE) { page_flags = page_flags.write(true); } + #[cfg(target_arch = "x86_64")] // TODO: AARCH64 if flags.contains(PHYSMAP_WRITE_COMBINE) { page_flags = page_flags.custom_flag(EntryFlags::HUGE_PAGE.bits(), true); }