From 4cb9df8fa81838f0f492e29592588558a55f04f0 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sun, 14 Aug 2016 11:45:47 -0600 Subject: [PATCH] Move arch to seperate crate --- arch/mod.rs | 7 ---- arch/x86_64/gdt.rs | 31 --------------- arch/x86_64/idt.rs | 75 ------------------------------------- arch/x86_64/io/io.rs | 61 ------------------------------ arch/x86_64/io/mmio.rs | 31 --------------- arch/x86_64/io/mod.rs | 9 ----- arch/x86_64/io/pio.rs | 83 ----------------------------------------- arch/x86_64/irq.rs | 10 ----- arch/x86_64/main.rs | 78 -------------------------------------- arch/x86_64/mem.rs | 69 ---------------------------------- arch/x86_64/mod.rs | 27 -------------- arch/x86_64/physical.rs | 11 ------ arch/x86_64/serial.rs | 39 ------------------- arch/x86_64/tss.rs | 22 ----------- lib.rs | 41 ++++++-------------- panic.rs | 25 +++++++++++++ 16 files changed, 36 insertions(+), 583 deletions(-) delete mode 100644 arch/mod.rs delete mode 100644 arch/x86_64/gdt.rs delete mode 100644 arch/x86_64/idt.rs delete mode 100644 arch/x86_64/io/io.rs delete mode 100644 arch/x86_64/io/mmio.rs delete mode 100644 arch/x86_64/io/mod.rs delete mode 100644 arch/x86_64/io/pio.rs delete mode 100644 arch/x86_64/irq.rs delete mode 100644 arch/x86_64/main.rs delete mode 100644 arch/x86_64/mem.rs delete mode 100644 arch/x86_64/mod.rs delete mode 100644 arch/x86_64/physical.rs delete mode 100644 arch/x86_64/serial.rs delete mode 100644 arch/x86_64/tss.rs create mode 100644 panic.rs diff --git a/arch/mod.rs b/arch/mod.rs deleted file mode 100644 index 924dc1a..0000000 --- a/arch/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -//! Architecture specific items - -#[cfg(target_arch = "x86_64")] -pub use self::x86_64::*; - -#[cfg(target_arch = "x86_64")] -pub mod x86_64; diff --git a/arch/x86_64/gdt.rs b/arch/x86_64/gdt.rs deleted file mode 100644 index 27648bb..0000000 --- a/arch/x86_64/gdt.rs +++ /dev/null @@ -1,31 +0,0 @@ -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; - } -} diff --git a/arch/x86_64/idt.rs b/arch/x86_64/idt.rs deleted file mode 100644 index 7cc422a..0000000 --- a/arch/x86_64/idt.rs +++ /dev/null @@ -1,75 +0,0 @@ -use core::mem; - -pub static mut IDTR: IdtDescriptor = IdtDescriptor { - size: 0, - offset: 0 -}; - -pub static mut IDT: [IdtEntry; 256] = [IdtEntry::new(); 256]; - -bitflags! { - pub flags IdtFlags: u8 { - const IDT_PRESENT = 1 << 7, - const IDT_RING_0 = 0 << 5, - const IDT_RING_1 = 1 << 5, - const IDT_RING_2 = 2 << 5, - const IDT_RING_3 = 3 << 5, - const IDT_SS = 1 << 4, - const IDT_INTERRUPT = 0xE, - const IDT_TRAP = 0xF, - } -} - -#[repr(packed)] -pub struct IdtDescriptor { - size: u16, - offset: u64 -} - -impl IdtDescriptor { - pub fn set_slice(&mut self, slice: &'static [IdtEntry]) { - self.size = (slice.len() * mem::size_of::() - 1) as u16; - self.offset = slice.as_ptr() as u64; - } - - pub unsafe fn load(&self) { - asm!("lidt [rax]" : : "{rax}"(self as *const _ as usize) : : "intel", "volatile"); - } -} - -#[derive(Copy, Clone, Debug)] -#[repr(packed)] -pub struct IdtEntry { - offsetl: u16, - selector: u16, - zero: u8, - attribute: u8, - offsetm: u16, - offseth: u32, - 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_flags(&mut self, flags: IdtFlags) { - self.attribute = flags.bits; - } - - pub fn set_offset(&mut self, selector: u16, base: usize) { - self.selector = selector; - self.offsetl = base as u16; - self.offsetm = (base >> 16) as u16; - self.offseth = (base >> 32) as u32; - } -} diff --git a/arch/x86_64/io/io.rs b/arch/x86_64/io/io.rs deleted file mode 100644 index a2d5fc6..0000000 --- a/arch/x86_64/io/io.rs +++ /dev/null @@ -1,61 +0,0 @@ -use core::cmp::PartialEq; -use core::ops::{BitAnd, BitOr, Not}; - -pub trait Io { - type Value: Copy + PartialEq + BitAnd + BitOr + Not; - - fn read(&self) -> Self::Value; - fn write(&mut self, value: Self::Value); - - fn readf(&self, flags: Self::Value) -> bool { - (self.read() & flags) as Self::Value == flags - } - - fn writef(&mut self, flags: Self::Value, value: bool) { - let tmp: Self::Value = match value { - true => self.read() | flags, - false => self.read() & !flags, - }; - self.write(tmp); - } -} - -pub struct ReadOnly { - inner: I -} - -impl ReadOnly { - pub fn new(inner: I) -> ReadOnly { - ReadOnly { - inner: inner - } - } - - pub fn read(&self) -> I::Value { - self.inner.read() - } - - pub fn readf(&self, flags: I::Value) -> bool { - self.inner.readf(flags) - } -} - -pub struct WriteOnly { - inner: I -} - -impl WriteOnly { - pub fn new(inner: I) -> WriteOnly { - WriteOnly { - inner: inner - } - } - - pub fn write(&mut self, value: I::Value) { - self.inner.write(value) - } - - pub fn writef(&mut self, flags: I::Value, value: bool) { - self.inner.writef(flags, value) - } -} diff --git a/arch/x86_64/io/mmio.rs b/arch/x86_64/io/mmio.rs deleted file mode 100644 index 1a1d199..0000000 --- a/arch/x86_64/io/mmio.rs +++ /dev/null @@ -1,31 +0,0 @@ -use core::intrinsics::{volatile_load, volatile_store}; -use core::mem::uninitialized; -use core::ops::{BitAnd, BitOr, Not}; - -use super::io::Io; - -#[repr(packed)] -pub struct Mmio { - value: T, -} - -impl Mmio { - /// Create a new Mmio without initializing - pub fn new() -> Self { - Mmio { - value: unsafe { uninitialized() } - } - } -} - -impl Io for Mmio where T: Copy + PartialEq + BitAnd + BitOr + Not { - type Value = T; - - fn read(&self) -> T { - unsafe { volatile_load(&self.value) } - } - - fn write(&mut self, value: T) { - unsafe { volatile_store(&mut self.value, value) }; - } -} diff --git a/arch/x86_64/io/mod.rs b/arch/x86_64/io/mod.rs deleted file mode 100644 index 86a1c34..0000000 --- a/arch/x86_64/io/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -/// I/O functions - -pub use self::io::*; -pub use self::mmio::*; -pub use self::pio::*; - -mod io; -mod mmio; -mod pio; diff --git a/arch/x86_64/io/pio.rs b/arch/x86_64/io/pio.rs deleted file mode 100644 index 1b10428..0000000 --- a/arch/x86_64/io/pio.rs +++ /dev/null @@ -1,83 +0,0 @@ -use core::marker::PhantomData; - -use super::io::Io; - -/// Generic PIO -#[derive(Copy, Clone)] -pub struct Pio { - port: u16, - value: PhantomData, -} - -impl Pio { - /// Create a PIO from a given port - pub fn new(port: u16) -> Self { - Pio:: { - port: port, - value: PhantomData, - } - } -} - -/// Read/Write for byte PIO -impl Io for Pio { - type Value = u8; - - /// Read - fn read(&self) -> u8 { - let value: u8; - unsafe { - asm!("in $0, $1" : "={al}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile"); - } - value - } - - /// Write - fn write(&mut self, value: u8) { - unsafe { - asm!("out $1, $0" : : "{al}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile"); - } - } -} - -/// Read/Write for word PIO -impl Io for Pio { - type Value = u16; - - /// Read - fn read(&self) -> u16 { - let value: u16; - unsafe { - asm!("in $0, $1" : "={ax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile"); - } - value - } - - /// Write - fn write(&mut self, value: u16) { - unsafe { - asm!("out $1, $0" : : "{ax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile"); - } - } -} - -/// Read/Write for doubleword PIO -impl Io for Pio { - type Value = u32; - - /// Read - fn read(&self) -> u32 { - let value: u32; - unsafe { - asm!("in $0, $1" : "={eax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile"); - } - value - } - - /// Write - fn write(&mut self, value: u32) { - unsafe { - asm!("out $1, $0" : : "{eax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile"); - } - } -} diff --git a/arch/x86_64/irq.rs b/arch/x86_64/irq.rs deleted file mode 100644 index bbceaa7..0000000 --- a/arch/x86_64/irq.rs +++ /dev/null @@ -1,10 +0,0 @@ -//! # IRQ handling -//! -//! This module defines IRQ handling functions. These functions should all be #[naked], -//! unsafe, extern, and end in `iretq` - -/// Interupt Request handler. -#[naked] -pub unsafe extern fn irq() { - -} diff --git a/arch/x86_64/main.rs b/arch/x86_64/main.rs deleted file mode 100644 index 50748b1..0000000 --- a/arch/x86_64/main.rs +++ /dev/null @@ -1,78 +0,0 @@ -/// This function is where the kernel sets up IRQ handlers -/// 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, IDT_PRESENT, IDT_RING_0, IDT_INTERRUPT}; -use super::mem::memset; - -extern { - /// The starting byte of the text (code) data segment. - static mut __text_start: u8; - /// The ending byte of the text (code) data segment. - static mut __text_end: u8; - /// The starting byte of the _.rodata_ (read-only data) segment. - static mut __rodata_start: u8; - /// The ending byte of the _.rodata_ (read-only data) segment. - static mut __rodata_end: u8; - /// The starting byte of the _.data_ segment. - static mut __data_start: u8; - /// The ending byte of the _.data_ segment. - static mut __data_end: u8; - /// The starting byte of the _.bss_ (uninitialized data) segment. - static mut __bss_start: u8; - /// The ending byte of the _.bss_ (uninitialized data) segment. - static mut __bss_end: u8; -} - -/// Test of zero values in BSS. -static BSS_TEST_ZERO: usize = 0; -/// Test of non-zero values in BSS. -static BSS_TEST_NONZERO: usize = 0xFFFFFFFFFFFFFFFF; - -#[no_mangle] -pub unsafe extern "C" fn kmain() { - asm!("xchg bx, bx" : : : : "intel", "volatile"); - - // Zero BSS, this initializes statics that are set to 0 - { - let start_ptr = &mut __bss_start as *mut u8; - let end_ptr = & __bss_end as *const u8 as usize; - - if start_ptr as usize <= end_ptr { - let size = end_ptr - start_ptr as usize; - memset(start_ptr, 0, size); - } - - //debug_assert_eq!(BSS_TEST_ZERO, 0); - //debug_assert_eq!(BSS_TEST_NONZERO, 0xFFFFFFFFFFFFFFFF); - } - - asm!("xchg bx, bx" : : : : "intel", "volatile"); - - //Set up IDT - for entry in IDT.iter_mut() { - entry.set_flags(IDT_PRESENT | IDT_RING_0 | IDT_INTERRUPT); - entry.set_offset(8, blank as usize); - } - IDTR.set_slice(&IDT); - IDTR.load(); - - asm!("xchg bx, bx" : : : : "intel", "volatile"); - - asm!("int 0xFF" : : : : "intel", "volatile"); - - asm!("xchg bx, bx" : : : : "intel", "volatile"); - - print!("TEST\n"); - - loop{ - asm!("hlt" : : : : "intel", "volatile"); - } -} - -#[naked] -pub unsafe extern "C" fn blank() { - asm!("xchg bx, bx" : : : : "intel", "volatile"); - asm!("iretq" : : : : "intel", "volatile"); -} diff --git a/arch/x86_64/mem.rs b/arch/x86_64/mem.rs deleted file mode 100644 index 8e1678c..0000000 --- a/arch/x86_64/mem.rs +++ /dev/null @@ -1,69 +0,0 @@ -/// Copy memory. -/// -/// Copy N bytes of memory from one location to another. -#[no_mangle] -pub unsafe extern fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 { - let mut i = 0; - while i < n { - *dest.offset(i as isize) = *src.offset(i as isize); - i += 1; - } - - dest -} - -/// Copy (possibly overlapping) memory. -/// -/// Copy N bytes of memory from src to dest. The memory areas may overlap. -#[no_mangle] -pub unsafe extern fn memmove(dest: *mut u8, src: *const u8, - n: usize) -> *mut u8 { - if src < dest as *const u8 { - let mut i = n; - while i != 0 { - i -= 1; - *dest.offset(i as isize) = *src.offset(i as isize); - } - } else { - let mut i = 0; - while i < n { - *dest.offset(i as isize) = *src.offset(i as isize); - i += 1; - } - } - - dest -} - -/// Set memory. -/// -/// Fill a block of memory with a specified value. -#[no_mangle] -pub unsafe extern fn memset(s: *mut u8, c: i32, n: usize) -> *mut u8 { - let mut i = 0; - while i < n { - *s.offset(i as isize) = c as u8; - i += 1; - } - - s -} - -/// Compare memory. -/// -/// Compare two blocks of memory. -#[no_mangle] -pub unsafe extern fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 { - let mut i = 0; - - while i < n { - let a = *s1.offset(i as isize); - let b = *s2.offset(i as isize); - if a != b { - return a as i32 - b as i32 - } - i += 1; - } - - 0 -} diff --git a/arch/x86_64/mod.rs b/arch/x86_64/mod.rs deleted file mode 100644 index d5180fc..0000000 --- a/arch/x86_64/mod.rs +++ /dev/null @@ -1,27 +0,0 @@ -//! X86_64 architecture primitives. - -/// Global descriptor table. -pub mod gdt; - -/// Interrupt descriptor table. -pub mod idt; - -/// IO handling. -pub mod io; - -/// IRQ handling. -pub mod irq; - -/// Initialization and main function. -pub mod main; - -/// Core memory routines. -pub mod mem; - -/// Serial driver and `print!` support. -pub mod serial; - -/// Task state segment. -pub mod tss; - -pub mod physical; diff --git a/arch/x86_64/physical.rs b/arch/x86_64/physical.rs deleted file mode 100644 index 8885cd1..0000000 --- a/arch/x86_64/physical.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! Typestrong address segregation. - -/// A physical address in memory. -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct Physical { - /// The position. - /// - /// Note that we do not use a pointer here to avoid simple mistakes where the programmer - /// confuse virtual and physical. - pub inner: u64, -} diff --git a/arch/x86_64/serial.rs b/arch/x86_64/serial.rs deleted file mode 100644 index dcc9abf..0000000 --- a/arch/x86_64/serial.rs +++ /dev/null @@ -1,39 +0,0 @@ -use core::fmt; -use super::io::{Io, Pio}; - -pub struct SerialConsole { - status: Pio, - data: Pio -} - -impl SerialConsole { - pub fn new() -> SerialConsole { - SerialConsole { - status: Pio::new(0x3F8 + 5), - data: Pio::new(0x3F8) - } - } - - pub fn write(&mut self, bytes: &[u8]) { - for byte in bytes.iter() { - while !self.status.readf(0x20) {} - self.data.write(*byte); - - if *byte == 8 { - while !self.status.readf(0x20) {} - self.data.write(0x20); - - while !self.status.readf(0x20) {} - self.data.write(8); - } - } - } -} - -impl fmt::Write for SerialConsole { - fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> { - self.write(s.as_bytes()); - - Ok(()) - } -} diff --git a/arch/x86_64/tss.rs b/arch/x86_64/tss.rs deleted file mode 100644 index 389de39..0000000 --- a/arch/x86_64/tss.rs +++ /dev/null @@ -1,22 +0,0 @@ -/// The Task State Segment. -#[repr(C, packed)] -#[derive(Debug, Default, Clone)] -pub struct Tss { - /// Reserved. - pub _reserved1: u32, - /// The stack-pointers (reg RSP) for the IO privilege level 0 through 2. - pub rsp: [u64; 3], - /// Reserved. - pub _reserved2: u32, - /// Reserved. - pub _reserved3: u32, - pub ist: [u64; 7], - /// Reserved. - pub _reserved4: u32, - /// Reserved. - pub _reserved5: u32, - // Reserved. - pub reserved6: u16, - /// The offset to the IOPB. - pub iomap_base: u16, -} diff --git a/lib.rs b/lib.rs index 23c0a18..b99e777 100644 --- a/lib.rs +++ b/lib.rs @@ -64,45 +64,26 @@ //! An error will be returned, `ENOBUFS`, if the buffer is not long enough for the name. //! In this case, it is recommended to add one page, 4096 bytes, to the buffer and retry. -#![feature(asm)] -#![feature(const_fn)] -#![feature(core_intrinsics)] #![feature(lang_items)] -#![feature(naked_functions)] #![no_std] #[macro_use] extern crate bitflags; -/// Print to console -macro_rules! print { - ($($arg:tt)*) => ({ - use $crate::core::fmt::Write; - let _ = write!($crate::arch::serial::SerialConsole::new(), $($arg)*); - }); -} - -/// Print with new line to console -macro_rules! println { - ($fmt:expr) => (print!(concat!($fmt, "\n"))); - ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*)); -} +use arch::interrupt::{set_interrupts, halt}; /// Architecture specific items -pub mod arch; +#[macro_use] +extern crate arch; -#[cfg(not(test))] -#[lang = "eh_personality"] -extern "C" fn eh_personality() {} +pub mod panic; -#[cfg(not(test))] -/// Required to handle panics -#[lang = "panic_fmt"] -extern "C" fn panic_fmt() -> ! {loop{}} - -#[allow(non_snake_case)] #[no_mangle] -/// Required to handle panics -pub extern "C" fn _Unwind_Resume() -> ! { - loop {} +pub extern fn kmain() { + println!("TEST"); + + unsafe { set_interrupts() }; + loop { + unsafe { halt() }; + } } diff --git a/panic.rs b/panic.rs new file mode 100644 index 0000000..fb90cfd --- /dev/null +++ b/panic.rs @@ -0,0 +1,25 @@ +//! Intrinsics for panic handling + +use arch::interrupt::halt; + +#[cfg(not(test))] +#[lang = "eh_personality"] +extern "C" fn eh_personality() {} + +#[cfg(not(test))] +/// Required to handle panics +#[lang = "panic_fmt"] +extern "C" fn panic_fmt() -> ! { + loop { + unsafe { halt() }; + } +} + +#[allow(non_snake_case)] +#[no_mangle] +/// Required to handle panics +pub extern "C" fn _Unwind_Resume() -> ! { + loop { + unsafe { halt() } + } +}