parent
f35d74c734
commit
2f71eab39b
@ -1,105 +0,0 @@
|
||||
// Following copied from crate `x86_64`
|
||||
|
||||
use core::ops::{Index, IndexMut};
|
||||
|
||||
pub struct Idt {
|
||||
entries: [IdtEntry; 256],
|
||||
}
|
||||
|
||||
impl Idt {
|
||||
pub const fn new() -> Idt {
|
||||
Idt {entries: [IdtEntry::new(); 256]}
|
||||
}
|
||||
pub fn load(&'static self) {
|
||||
use x86_64::instructions::tables::{DescriptorTablePointer, lidt};
|
||||
use core::mem::size_of;
|
||||
|
||||
let ptr = DescriptorTablePointer {
|
||||
base: self as *const _ as u64,
|
||||
limit: (size_of::<Self>() - 1) as u16,
|
||||
};
|
||||
|
||||
unsafe { lidt(&ptr) };
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<u8> for Idt {
|
||||
type Output = IdtEntry;
|
||||
fn index(&self, index: u8) -> &Self::Output {
|
||||
&self.entries[index as usize]
|
||||
}
|
||||
}
|
||||
|
||||
impl IndexMut<u8> for Idt {
|
||||
fn index_mut(&mut self, index: u8) -> &mut Self::Output {
|
||||
&mut self.entries[index as usize]
|
||||
}
|
||||
}
|
||||
|
||||
// Following copied from Redox
|
||||
|
||||
bitflags! {
|
||||
pub struct IdtFlags: u8 {
|
||||
const PRESENT = 1 << 7;
|
||||
const RING_0 = 0 << 5;
|
||||
const RING_1 = 1 << 5;
|
||||
const RING_2 = 2 << 5;
|
||||
const RING_3 = 3 << 5;
|
||||
const SS = 1 << 4;
|
||||
const INTERRUPT = 0xE;
|
||||
const TRAP = 0xF;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[repr(packed)]
|
||||
pub struct IdtEntry {
|
||||
offsetl: u16,
|
||||
selector: u16,
|
||||
ist: u8,
|
||||
attribute: u8,
|
||||
offsetm: u16,
|
||||
offseth: u32,
|
||||
zero2: u32
|
||||
}
|
||||
|
||||
impl IdtEntry {
|
||||
pub const fn new() -> IdtEntry {
|
||||
IdtEntry {
|
||||
offsetl: 0,
|
||||
selector: 0,
|
||||
ist: 0,
|
||||
attribute: 0,
|
||||
offsetm: 0,
|
||||
offseth: 0,
|
||||
zero2: 0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_flags(&mut self, flags: IdtFlags) -> &mut Self {
|
||||
self.attribute = flags.bits;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_offset(&mut self, selector: u16, base: usize) -> &mut Self {
|
||||
self.selector = selector;
|
||||
self.offsetl = base as u16;
|
||||
self.offsetm = (base >> 16) as u16;
|
||||
self.offseth = (base >> 32) as u32;
|
||||
self
|
||||
}
|
||||
|
||||
// A function to set the offset more easily
|
||||
pub fn set_handler_fn(&mut self, func: unsafe extern fn()) -> &mut Self {
|
||||
self.set_flags(IdtFlags::PRESENT | IdtFlags::RING_0 | IdtFlags::INTERRUPT);
|
||||
self.set_offset(8, func as usize);
|
||||
self
|
||||
}
|
||||
|
||||
pub unsafe fn set_stack_index(&mut self, index: u16) -> &mut Self {
|
||||
// The hardware IST index starts at 1, but our software IST index
|
||||
// starts at 0. Therefore we need to add 1 here.
|
||||
self.ist = (index + 1) as u8;
|
||||
self
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
use self::idt::*;
|
||||
use spin::Once;
|
||||
use alloc::boxed::Box;
|
||||
|
||||
mod idt;
|
||||
|
||||
/// Alloc IDT at kernel heap, then init and load it.
|
||||
pub fn init() {
|
||||
let idt = Box::new({
|
||||
use arch::interrupt::{handler::*, consts::*};
|
||||
use arch::gdt::DOUBLE_FAULT_IST_INDEX;
|
||||
|
||||
let mut idt = Idt::new();
|
||||
for i in 0u8..=255 {
|
||||
idt[i].set_handler_fn(unsafe { __vectors[i as usize] });
|
||||
}
|
||||
|
||||
idt[T_SWITCH_TOK].set_flags(IdtFlags::PRESENT | IdtFlags::RING_3 | IdtFlags::INTERRUPT);
|
||||
// TODO: Enable interrupt during syscall
|
||||
idt[T_SYSCALL].set_flags(IdtFlags::PRESENT | IdtFlags::RING_3 | IdtFlags::INTERRUPT);
|
||||
idt[0x80].set_flags(IdtFlags::PRESENT | IdtFlags::RING_3 | IdtFlags::INTERRUPT);
|
||||
|
||||
unsafe {
|
||||
idt[T_DBLFLT].set_stack_index(DOUBLE_FAULT_IST_INDEX as u16);
|
||||
}
|
||||
idt
|
||||
});
|
||||
let idt = unsafe{ &*Box::into_raw(idt) };
|
||||
|
||||
idt.load();
|
||||
}
|
||||
|
||||
extern {
|
||||
//noinspection RsStaticConstNaming
|
||||
static __vectors: [extern fn(); 256];
|
||||
}
|
Loading…
Reference in new issue