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