Improved 32-bit x86 support

This commit is contained in:
Jeremy Soller
2022-08-18 14:57:15 -06:00
parent c09be1770b
commit 6b2439f1b9
6 changed files with 31 additions and 20 deletions

View File

@@ -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;

View File

@@ -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
",

View File

@@ -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());

View File

@@ -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::<Vec<_>>()
};
#[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 {

View File

@@ -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 {

View File

@@ -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<usize> {
Err(Error::new(syscall::error::ENOSYS))
}
#[cfg(target_arch = "x86")]
pub fn iopl(level: usize, stack: &mut InterruptStack) -> Result<usize> {
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<usize> {
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);
}