1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#![feature(no_std, core, lang_items, asm, const_fn)]
#![feature(core_slice_ext, core_str_ext, core_intrinsics, slice_bytes)]
#![no_std]

use core::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, AtomicUsize,
                         ATOMIC_USIZE_INIT};
use core::fmt::{self, Write};
use core::mem;
use core::slice;
use core::slice::bytes::MutableByteVector;
use core::ptr;

pub mod arch;
#[macro_use]
pub mod console;
pub mod debug;
pub mod mm;
pub mod serial;
pub mod sync;
pub mod thread;

// This shouldn't be necessary, but ld claims core::Option::<T>::and_then contains
// references to the function. objdump disagrees, so there's something fishy
// going on here.
#[allow(unused_variables)]
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn _Unwind_Resume() {
    unimplemented!()
}

// Unimplemented for now. Want to use the system stack unwinder,
// which will involve linking against fun things like libgcc
// to get __gcc_personality_v0 or maybe using libunwind.
//
// Refer to the implementation of std::rt::unwind for more hints.
#[lang = "eh_personality"]
extern fn eh_personality() { }

/// Terminate current thread, possibly printing a diagnostic.
#[lang = "panic_fmt"] #[inline(never)] #[cold]
extern fn panic_fmt(args: core::fmt::Arguments,
                    file: &'static str,
                    line: u32) -> ! {
    println!("PANIC {}:{}: {}", file, line, args);
    unsafe {
        asm!("cli
              hlt" :::: "volatile");
        core::intrinsics::unreachable();
    }
}

use console::Console;

#[no_mangle]
pub extern "C" fn kmain() {
    {
        let mut console = console::default::Console::open();
        console.clear();
    }

    println!("BIOS memory map:");
    for region in mm::phys::MemoryMap::regions() {
        println!("{}", region);
    }
    unimplemented!();
}

#[repr(C)]
struct IDT {
    base_lo: u16,
    selector: u16,
    pad0: u8,
    attributes: u8,
    base_mid: u16,
    base_high: u32,
    pad1: u32
}

const TRAP: u8 = 0xF;
const INT: u8 = 0xE;

/*
macro_rules! idt_entry {
    ($func:expr, $ty:expr) => {
        IDT {
            base_lo: ($func as u64) as u16,
            selector: 8,                // Assumed to be in default code segment
            pad0: 0,
            attributes: 0x80 | $ty,     // P-bit
            base_mid: (($func as u64) >> 16) as u16,
            base_high: (($func as u64) >> 32) as u32,
            pad1: 0
        }
    };
}

macro_rules! idt {
    ($name:ident,
        $($func:ident => $ty:expr),*
    ) => (
        static $name: &'static [IDT] = &[ $(
            idt_entry!($func, $ty),
        )* ];
    )
}

idt!{x,
    vector_0 => TRAP
}
*/

#[repr(C)]
struct IDTR {
    limit: u16,
    base: *mut ()
}