WIP: IDT in rust

This commit is contained in:
Jeremy Soller 2016-08-13 18:58:31 -06:00
commit dea137be73
5 changed files with 152 additions and 16 deletions

31
src/arch/x86_64/gdt.rs Normal file
View file

@ -0,0 +1,31 @@
pub const GDT_NULL: usize = 0;
pub const GDT_KERNEL_CODE: usize = 1;
pub const GDT_KERNEL_DATA: usize = 2;
pub const GDT_USER_CODE: usize = 3;
pub const GDT_USER_DATA: usize = 4;
pub const GDT_USER_TLS: usize = 5;
pub const GDT_TSS: usize = 6;
#[repr(packed)]
pub struct GdtDescriptor {
pub size: u16,
pub ptr: u64
}
#[repr(packed)]
pub struct GdtEntry {
pub limitl: u16,
pub basel: u16,
pub basem: u8,
pub attribute: u8,
pub flags_limith: u8,
pub baseh: u8
}
impl GdtEntry {
pub fn set_base(&mut self, base: usize) {
self.basel = base as u16;
self.basem = (base >> 16) as u8;
self.baseh = (base >> 24) as u8;
}
}

53
src/arch/x86_64/idt.rs Normal file
View file

@ -0,0 +1,53 @@
use core::mem;
pub static mut IDTR: IdtDescriptor = IdtDescriptor {
size: 0,
offset: 0
};
pub static mut IDT: [IdtEntry; 256] = [IdtEntry::new(); 256];
#[repr(packed)]
pub struct IdtDescriptor {
pub size: u16,
pub offset: u64
}
impl IdtDescriptor {
pub fn set_slice(&mut self, slice: &'static [IdtEntry]) {
self.size = (slice.len() * mem::size_of::<IdtEntry>() - 1) as u16;
self.offset = slice.as_ptr() as u64;
}
}
#[derive(Copy, Clone, Debug)]
#[repr(packed)]
pub struct IdtEntry {
pub offsetl: u16,
pub selector: u16,
pub zero: u8,
pub attribute: u8,
pub offsetm: u16,
pub offseth: u32,
pub zero2: u32
}
impl IdtEntry {
pub const fn new() -> IdtEntry {
IdtEntry {
offsetl: 0,
selector: 0,
zero: 0,
attribute: 0,
offsetm: 0,
offseth: 0,
zero2: 0
}
}
pub fn set_offset(&mut self, base: usize) {
self.offsetl = base as u16;
self.offsetm = (base >> 16) as u16;
self.offseth = (base >> 32) as u32;
}
}

View file

@ -2,10 +2,35 @@
/// It is increcibly unsafe, and should be minimal in nature
/// It must create the IDT with the correct entries, those entries are
/// defined in other files inside of the `arch` module
use super::idt::{IDTR, IDT};
#[naked]
#[no_mangle]
pub unsafe extern fn kmain() {
asm!("xchg bx, bx" : : : : "intel", "volatile");
loop{}
for entry in IDT.iter_mut() {
entry.attribute = 1 << 7 | 0xE;
entry.selector = 8;
entry.set_offset(&blank as *const _ as usize);
entry.zero = 0;
entry.zero2 = 0;
}
IDTR.set_slice(&IDT);
asm!("lidt [rax]" : : "{rax}"(&IDTR as *const _ as usize) : : "intel", "volatile");
asm!("xchg bx, bx" : : : : "intel", "volatile");
asm!("int 0xFF" : : : : "intel", "volatile");
loop{
asm!("hlt" : : : : "intel", "volatile");
}
}
#[naked]
pub unsafe extern fn blank() {
asm!("xchg bx, bx" : : : : "intel", "volatile");
asm!("iretq" : : : : "intel", "volatile");
}

View file

@ -1,3 +1,9 @@
/// Global descriptor table
pub mod gdt;
/// Interrupt descriptor table
pub mod idt;
/// IRQ Handling
pub mod irq;

20
src/arch/x86_64/tss.rs Normal file
View file

@ -0,0 +1,20 @@
#[repr(packed)]
pub struct Tss {
pub reserved1: u32,
pub sp0: u64,
pub sp1: u64,
pub sp2: u64,
pub reserved2: u32,
pub reserved3: u32,
pub ist1: u64,
pub ist2: u64,
pub ist3: u64,
pub ist4: u64,
pub ist5: u64,
pub ist6: u64,
pub ist7: u64,
pub reserved4: u32,
pub reserved5: u32,
pub reserved6: u16,
pub iomap_base: u16,
}