Use x86's TaskStateSegment and use usize for stack pointers

This commit is contained in:
Philipp Oppermann
2016-12-21 00:12:19 +01:00
parent d1fb1516fa
commit ceb44d9c2e
8 changed files with 31 additions and 178 deletions

View File

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

View File

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

View File

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

View File

@@ -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)
}
}

View File

@@ -13,7 +13,6 @@
#![feature(asm)]
#![feature(naked_functions)]
#![feature(core_intrinsics)]
#![feature(nonzero)]
#![feature(drop_types_in_const)]
#![no_std]

View File

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

View File

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