mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-16 22:37:49 +00:00
Use x86's TaskStateSegment and use usize for stack pointers
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use bit_field::BitField;
|
||||
use collections::vec::Vec;
|
||||
use interrupts::tss::TaskStateSegment;
|
||||
use x86::bits64::task::TaskStateSegment;
|
||||
|
||||
pub struct Gdt(Vec<u64>);
|
||||
|
||||
@@ -26,11 +26,11 @@ impl Gdt {
|
||||
}
|
||||
|
||||
pub fn load(&'static self) {
|
||||
use x86::dtables::{DescriptorTablePointer, lgdt};
|
||||
use x86::shared::dtables::{DescriptorTablePointer, lgdt};
|
||||
use core::mem::size_of;
|
||||
|
||||
let ptr = DescriptorTablePointer {
|
||||
base: self.0.as_ptr() as u64,
|
||||
base: self.0.as_ptr() as *const ::x86::shared::segmentation::SegmentDescriptor,
|
||||
limit: (self.0.len() * size_of::<u64>() - 1) as u16,
|
||||
};
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ impl EntryOptions {
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn set_stack_index(&mut self, index: u8) -> &mut Self {
|
||||
self.0.set_range(0..3, index.into());
|
||||
self.0.set_range(0..3, (index + 1).into());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
use spin::Once;
|
||||
use memory::MemoryController;
|
||||
use x86::bits64::task::TaskStateSegment;
|
||||
|
||||
mod idt;
|
||||
mod tss;
|
||||
mod gdt;
|
||||
|
||||
macro_rules! save_scratch_registers {
|
||||
@@ -92,22 +92,18 @@ macro_rules! handler_with_error_code {
|
||||
}
|
||||
|
||||
static IDT: Once<idt::Idt> = Once::new();
|
||||
static TSS: Once<tss::TaskStateSegment> = Once::new();
|
||||
static TSS: Once<TaskStateSegment> = Once::new();
|
||||
static GDT: Once<gdt::Gdt> = Once::new();
|
||||
|
||||
pub fn init(memory_controller: &mut MemoryController) {
|
||||
let double_fault_stack = memory_controller.alloc_stack(1)
|
||||
.expect("could not allocate double fault stack");
|
||||
|
||||
let mut double_fault_ist_index = 0;
|
||||
const DOUBLE_FAULT_IST_INDEX: u8 = 0;
|
||||
|
||||
let tss = TSS.call_once(|| {
|
||||
let mut tss = tss::TaskStateSegment::new();
|
||||
|
||||
double_fault_ist_index = tss.interrupt_stacks
|
||||
.insert_stack(double_fault_stack)
|
||||
.expect("IST flush_all");
|
||||
|
||||
let mut tss = TaskStateSegment::new();
|
||||
tss.ist[DOUBLE_FAULT_IST_INDEX as usize] = double_fault_stack.top() as u64;
|
||||
tss
|
||||
});
|
||||
|
||||
@@ -134,7 +130,7 @@ pub fn init(memory_controller: &mut MemoryController) {
|
||||
idt.set_handler(3, handler!(breakpoint_handler));
|
||||
idt.set_handler(6, handler!(invalid_opcode_handler));
|
||||
idt.set_handler(8, handler_with_error_code!(double_fault_handler))
|
||||
.set_stack_index(double_fault_ist_index);
|
||||
.set_stack_index(DOUBLE_FAULT_IST_INDEX);
|
||||
idt.set_handler(14, handler_with_error_code!(page_fault_handler));
|
||||
|
||||
idt
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
use memory::{Stack, StackPointer};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[repr(C, packed)]
|
||||
pub struct TaskStateSegment {
|
||||
reserved_0: u32,
|
||||
pub privilege_stacks: PrivilegeStackTable,
|
||||
reserved_1: u64,
|
||||
pub interrupt_stacks: InterruptStackTable,
|
||||
reserved_2: u64,
|
||||
reserved_3: u16,
|
||||
iomap_base: u16,
|
||||
}
|
||||
|
||||
impl TaskStateSegment {
|
||||
pub fn new() -> TaskStateSegment {
|
||||
TaskStateSegment {
|
||||
privilege_stacks: PrivilegeStackTable([None, None, None]),
|
||||
interrupt_stacks: InterruptStackTable([None, None, None, None, None, None, None]),
|
||||
iomap_base: 0,
|
||||
reserved_0: 0,
|
||||
reserved_1: 0,
|
||||
reserved_2: 0,
|
||||
reserved_3: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PrivilegeStackTable([Option<StackPointer>; 3]);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InterruptStackTable([Option<StackPointer>; 7]);
|
||||
|
||||
impl InterruptStackTable {
|
||||
pub fn insert_stack(&mut self, stack: Stack) -> Result<u8, Stack> {
|
||||
// TSS index starts at 1
|
||||
for (entry, i) in self.0.iter_mut().zip(1..) {
|
||||
if entry.is_none() {
|
||||
*entry = Some(stack.top());
|
||||
return Ok(i);
|
||||
}
|
||||
}
|
||||
Err(stack)
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@
|
||||
#![feature(asm)]
|
||||
#![feature(naked_functions)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(nonzero)]
|
||||
#![feature(drop_types_in_const)]
|
||||
#![no_std]
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
pub use self::area_frame_allocator::AreaFrameAllocator;
|
||||
pub use self::paging::remap_the_kernel;
|
||||
pub use self::stack_allocator::{Stack, StackPointer};
|
||||
pub use self::stack_allocator::Stack;
|
||||
use self::paging::PhysicalAddress;
|
||||
use multiboot2::BootInformation;
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use memory::paging::{self, Page, PageIter, ActivePageTable};
|
||||
use memory::{PAGE_SIZE, FrameAllocator};
|
||||
use core::nonzero::NonZero;
|
||||
|
||||
pub fn new_stack_allocator(page_range: PageIter) -> StackAllocator {
|
||||
StackAllocator { range: page_range }
|
||||
@@ -52,36 +51,24 @@ impl StackAllocator {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Stack {
|
||||
top: StackPointer,
|
||||
bottom: StackPointer,
|
||||
top: usize,
|
||||
bottom: usize,
|
||||
}
|
||||
|
||||
impl Stack {
|
||||
fn new(top: usize, bottom: usize) -> Stack {
|
||||
assert!(top > bottom);
|
||||
Stack {
|
||||
top: StackPointer::new(top),
|
||||
bottom: StackPointer::new(bottom),
|
||||
top: top,
|
||||
bottom: bottom,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn top(&self) -> StackPointer {
|
||||
pub fn top(&self) -> usize {
|
||||
self.top
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct StackPointer(NonZero<usize>);
|
||||
|
||||
impl StackPointer {
|
||||
fn new(ptr: usize) -> StackPointer {
|
||||
assert!(ptr != 0);
|
||||
StackPointer(unsafe { NonZero::new(ptr) })
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<usize> for StackPointer {
|
||||
fn into(self) -> usize {
|
||||
*self.0
|
||||
pub fn bottom(&self) -> usize {
|
||||
self.bottom
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user