diff options
Diffstat (limited to 'tobba/src')
-rw-r--r-- | tobba/src/lib.rs | 21 | ||||
-rw-r--r-- | tobba/src/x86.rs | 217 | ||||
-rw-r--r-- | tobba/src/x86_64.rs | 19 | ||||
-rw-r--r-- | tobba/src/x86_shared.rs | 409 |
4 files changed, 0 insertions, 666 deletions
diff --git a/tobba/src/lib.rs b/tobba/src/lib.rs deleted file mode 100644 index f18a44d..0000000 --- a/tobba/src/lib.rs +++ /dev/null @@ -1,21 +0,0 @@ -#![cfg(any(target_arch="x86", target_arch="x86_64"))] - -#![no_std] -#![crate_name="cpu"] -#![crate_type="rlib"] -#![feature(asm)] -#![feature(associated_consts)] - -#[macro_use] -extern crate bitflags; - -pub use cpu::*; - -#[cfg(target_arch="x86")] -#[path = "x86.rs"] -mod cpu; -#[cfg(target_arch="x86_64")] -#[path = "x86_64.rs"] -mod cpu; - -pub mod std { pub use core::*; } diff --git a/tobba/src/x86.rs b/tobba/src/x86.rs deleted file mode 100644 index d307dd1..0000000 --- a/tobba/src/x86.rs +++ /dev/null @@ -1,217 +0,0 @@ -#![allow(non_upper_case_globals)] - -pub use self::x86_shared::*; - -use core::mem::size_of; - -mod x86_shared; - -bitflags! { - pub flags GdtAccess: u8 { - const Accessed = 1 << 0, - const Writable = 1 << 1, - const Direction = 1 << 2, - const Executable = 1 << 3, - const NotTss = 1 << 4, - } -} - -#[derive(Copy, Clone, Debug)] -#[repr(C, packed)] -pub struct GdtEntry { - limit: u16, - base1: u16, - base2: u8, - access: u8, - flags: u8, - base3: u8, -} - -#[derive(Copy, Clone)] -#[repr(C, packed)] -pub struct IdtEntry { - offset1: u16, - selector: u16, - reserved: u8, - flags: u8, - offset2: u16 -} - -impl GdtEntry { - pub const NULL: GdtEntry = GdtEntry { - base1: 0, - base2: 0, - base3: 0, - access: 0, - limit: 0, - flags: 0 - }; - - pub fn new(base: *const (), limit: usize, access: GdtAccess, dpl: PrivilegeLevel) -> GdtEntry { - let (limit, flags) = if limit < 0x100000 { - ((limit & 0xFFFF) as u16, ((limit & 0xF0000) >> 16) as u8 | 0x40u8) - } else { - if ((limit - 0xFFF) & 0xFFF) > 0 { - panic!("bad segment limit for GDT entry"); - } - (((limit & 0xFFFF000) >> 12) as u16, ((limit & 0xF0000000) >> 28) as u8 | 0xC0u8) - }; - GdtEntry { - base1: base as u16, - base2: ((base as usize & 0xFF0000) >> 16) as u8, - base3: ((base as usize & 0xFF000000) >> 24) as u8, - access: access.bits() | ((dpl as u8) << 5) | 0x80, - limit: limit, - flags: flags - } - } -} - -impl IdtEntry { - pub const NULL: IdtEntry = IdtEntry { - offset1: 0, - selector: 0, - reserved: 0, - flags: 0, - offset2: 0 - }; - - pub fn new(f: unsafe extern "C" fn(), dpl: PrivilegeLevel, block: bool) -> IdtEntry { - IdtEntry { - offset1: f as u16, - offset2: ((f as usize & 0xFFFF0000) >> 16) as u16, - selector: 8, - reserved: 0, - flags: if block { 0x8E } else { 0x8F } | ((dpl as u8) << 5) - } - } -} - -#[derive(Copy, Clone, Debug)] -#[repr(C, packed)] -pub struct Tss { - pub link: u16, - reserved0: u16, - pub esp0: u32, - pub ss0: u16, - reserved1: u16, - pub esp1: u32, - pub ss1: u16, - reserved2: u16, - pub esp2: u32, - pub ss2: u16, - reserved3: u16, - - pub cr3: u32, - pub eip: u32, - pub eflags: u32, - - pub eax: u32, - pub ecx: u32, - pub edx: u32, - pub ebx: u32, - pub esp: u32, - pub ebp: u32, - pub esi: u32, - pub edi: u32, - - pub es: u16, - reserved4: u16, - pub cs: u16, - reserved5: u16, - pub ss: u16, - reserved6: u16, - pub ds: u16, - reserved7: u16, - pub fs: u16, - reserved8: u16, - pub gs: u16, - reserved9: u16, - pub ldtr: u16, - reserved10: u32, - pub iobp_offset: u16 -} - -impl Tss { - pub fn new() -> Tss { - Tss { - link: 0, - reserved0: 0, - esp0: 0, - ss0: 0, - reserved1: 0, - esp1: 0, - ss1: 0, - reserved2: 0, - esp2: 0, - ss2: 0, - reserved3: 0, - cr3: 0, - eip: 0, - eflags: 0, - eax: 0, - ecx: 0, - edx: 0, - ebx: 0, - esp: 0, - ebp: 0, - esi: 0, - edi: 0, - es: 0, - reserved4: 0, - cs: 0, - reserved5: 0, - ss: 0, - reserved6: 0, - ds: 0, - reserved7: 0, - fs: 0, - reserved8: 0, - gs: 0, - reserved9: 0, - ldtr: 0, - reserved10: 0, - iobp_offset: size_of::<Tss>() as u16 - } - } -} - -#[inline(always)] -pub fn get_flags() -> Flags { - unsafe { - let r: usize; - asm!("pushfd; pop $0" : "=r"(r) ::: "intel"); - Flags::from_bits_truncate(r) - } -} - -#[inline(always)] -pub unsafe fn set_flags(val: Flags) { - asm!("push $0; popfd" :: "r"(val.bits()) : "flags" : "volatile", "intel"); -} - -#[inline(always)] -pub unsafe fn set_gdt(gdt: &[GdtEntry]) { - #[repr(C, packed)] - struct GDTR { - limit: u16, - ptr: *const GdtEntry, - } - asm!("lgdtl $0" :: "*m"(&GDTR { ptr: gdt.as_ptr(), limit: (gdt.len()*size_of::<GdtEntry>() - 1) as u16 }) :: "volatile"); -} - -#[inline(always)] -pub unsafe fn set_idt(idt: &[IdtEntry]) { - #[repr(C, packed)] - struct IDTR { - limit: u16, - ptr: *const IdtEntry, - } - asm!("lidtl $0" :: "*m"(&IDTR { ptr: idt.as_ptr(), limit: idt.len() as u16 * 8 }) :: "volatile"); -} - -#[inline(always)] -pub unsafe fn stack_jmp(stack: *mut (), ip: *const ()) -> ! { - asm!("mov esp, $0; jmp $1" :: "rg"(stack), "r"(ip) :: "volatile", "intel"); - loop { } -} diff --git a/tobba/src/x86_64.rs b/tobba/src/x86_64.rs deleted file mode 100644 index 64c0efd..0000000 --- a/tobba/src/x86_64.rs +++ /dev/null @@ -1,19 +0,0 @@ -#![allow(non_upper_case_globals)] - -pub use self::x86_shared::*; - -mod x86_shared; - -#[inline(always)] -pub fn get_flags() -> Flags { - unsafe { - let r: usize; - asm!("pushfq; pop $0" : "=r"(r) ::: "intel"); - Flags::from_bits_truncate(r) - } -} - -#[inline(always)] -pub unsafe fn set_flags(val: Flags) { - asm!("push $0; popfq" :: "r"(val.bits()) : "flags" : "volatile", "intel"); -} diff --git a/tobba/src/x86_shared.rs b/tobba/src/x86_shared.rs deleted file mode 100644 index 4c1169f..0000000 --- a/tobba/src/x86_shared.rs +++ /dev/null @@ -1,409 +0,0 @@ -#![allow(non_upper_case_globals)] - -bitflags! { - pub flags Flags: usize { - const CarryFlag = 1 << 0, - const ParityFlag = 1 << 2, - const AdjustFlag = 1 << 4, - const ZeroFlag = 1 << 6, - const SignFlag = 1 << 7, - const TrapFlag = 1 << 8, - const InterruptFlag = 1 << 9, - const DirectionFlag = 1 << 10, - const OverflowFlag = 1 << 11, - const Iopl1 = 1 << 12, - const Iopl2 = 1 << 13, - const NestedTaskFlag = 1 << 14, - const ResumeFlag = 1 << 16, - const Virtual8086Flag = 1 << 17, - const AlignmentFlag = 1 << 18, - const VirtualInterruptFlag = 1 << 19, - const VirtualInterruptPending = 1 << 20, - const CpuIdFlag = 1 << 21 - } -} - -bitflags! { - pub flags Cr0: usize { - const ProtectedMode = 1 << 0, - const MonitorCoprocessor = 1 << 1, - const EmulateCoprocessor = 1 << 2, - const TaskSwitched = 1 << 3, - const ExtensionType = 1 << 4, - const NumericError = 1 << 5, - const WriteProtect = 1 << 16, - const AlignmentMask = 1 << 18, - const NotWriteThrough = 1 << 29, - const CacheDisable = 1 << 30, - const EnablePaging = 1 << 31 - } -} - -bitflags! { - pub flags Cr4: usize { - const EnableVme = 1 << 0, - const VirtualInterrupts = 1 << 1, - const TimeStampDisable = 1 << 2, - const DebuggingExtensions = 1 << 3, - const EnablePse = 1 << 4, - const EnablePae = 1 << 5, - const EnableMachineCheck = 1 << 6, - const EnableGlobalPages = 1 << 7, - const EnablePpmc = 1 << 8, - const EnableSse = 1 << 9, - const UnmaskedSse = 1 << 10, - const EnableVmx = 1 << 13, - const EnableSmx = 1 << 14, - const EnablePcid = 1 << 17, - const EnableOsXSave = 1 << 18, - const EnableSmep = 1 << 20, - const EnableSmap = 1 << 21 - } -} - -bitflags!( - pub flags Features: u64 { - const Fpu = 1 << 0, - const Virtual8086 = 1 << 1, - const DebugExtension = 1 << 2, - const PageSizeExtension = 1 << 3, - const TimeStampCounter = 1 << 4, - const ModelSpecificRegister = 1 << 5, - const PhysicalAddressExtension = 1 << 6, - const MachineCheckException = 1 << 7, - const Cx8 = 1 << 8, // CMPXCHG8 - const Apic = 1 << 9, - const SysEnter = 1 << 11, - const MemoryTypeRange = 1 << 12, - const PageGlobal = 1 << 13, - const MachineCheckArchitecture = 1 << 14, - const CMov = 1 << 15, - const PageAttributeTable = 1 << 16, - const PageSizeExtension36 = 1 << 17, - const ProcessorSerial = 1 << 18, - const CacheFlush = 1 << 19, - const DebugStore = 1 << 21, - const Acpi = 1 << 22, - const Mmx = 1 << 23, - const FxSave = 1 << 24, - const Sse = 1 << 25, - const Sse2 = 1 << 26, - const SelfSnoop = 1 << 27, - const HyperThreading = 1 << 28, - const ThermalMonitor = 1 << 29, - const Ia64 = 1 << 30, - const PendingBreak = 1 << 31, - - const Sse3 = 1 << (32 + 0), - const PclMulQdq = 1 << (32 + 1), // what - const DebugStore64 = 1 << (32 + 2), - const Monitor = 1 << (32 + 3), - const CplDebugStore = 1 << (32 + 4), - const Vmx = 1 << (32 + 5), - const SaferMode = 1 << (32 + 6), - const EnhancedSpeedStep = 1 << (32 + 7), - const ThermalMonitor2 = 1 << (32 + 8), - const Ssse3 = 1 << (32 + 9), - const L1ContextId = 1 << (32 + 10), - const Fma = 1 << (32 + 12), - const Cx16 = 1 << (32 + 13), // CMPXCHG16B - const Xtpr = 1 << (32 + 14), // I have no idea what this is - const PerformanceMonitor = 1 << (32 + 15), - const ProcessContextId = 1 << (32 + 17), - const DirectCache = 1 << (32 + 18), - const Sse41 = 1 << (32 + 19), - const Sse42 = 1 << (32 + 20), - const X2Apic = 1 << (32 + 21), - const MovBe = 1 << (32 + 22), - const PopulationCount = 1 << (32 + 23), - const TscDeadline = 1 << (32 + 24), - const AesNi = 1 << (32 + 25), - const XSave = 1 << (32 + 26), - const OsXSave = 1 << (32 + 27), - const Avx = 1 << (32 + 28), - const HalfPrecision = 1 << (32 + 29), - const HwRandom = 1 << (32 + 30) - } -); - -#[derive(Copy, Clone, PartialEq, Eq)] -pub enum Exception { - DivisionByZero = 0, - Debug = 1, - Nmi = 2, - Breakpoint = 3, - Overflow = 4, - Bounds = 5, - InvalidOpcode = 6, - NotAvailable = 7, - DoubleFault = 8, - CoprocessorSegment = 9, - Tss = 10, - NotPresent = 11, - StackSegment = 12, - GeneralProtection = 13, - PageFault = 14, - Fpu = 16, - Alignment = 17, - MachineCheck = 18, - Simd = 19, - Virtualization = 20, - Security = 30 -} - -impl Exception { - pub fn from_code(code: u32) -> Option<Exception> { - Some(match code { - 0 => Exception::DivisionByZero, - 1 => Exception::Debug, - 2 => Exception::Nmi, - 3 => Exception::Breakpoint, - 4 => Exception::Overflow, - 5 => Exception::Bounds, - 6 => Exception::InvalidOpcode, - 7 => Exception::NotAvailable, - 8 => Exception::DoubleFault, - 9 => Exception::CoprocessorSegment, - 10 => Exception::Tss, - 11 => Exception::NotPresent, - 12 => Exception::StackSegment, - 13 => Exception::GeneralProtection, - 14 => Exception::PageFault, - 16 => Exception::Fpu, - 17 => Exception::Alignment, - 18 => Exception::MachineCheck, - 19 => Exception::Simd, - 20 => Exception::Virtualization, - 30 => Exception::Security, - - _ => return None - }) - } -} - -#[derive(Copy, Clone, PartialEq, Eq)] -pub enum Msr { - ApicBase = 0x1B -} - -#[inline(always)] -pub fn cpuid(function: u32) -> (u32, u32, u32, u32) { - unsafe { - let (eax, ebx, ecx, edx): (u32, u32, u32, u32); - asm!("cpuid" : "={eax}"(eax), "={ebx}"(ebx), "={ecx}"(ecx), "={edx}"(edx) : "{eax}"(function)); - (eax, ebx, ecx, edx) - } -} - -#[inline(always)] -pub fn supports() -> Features { - let (_, _, feature_ecx, feature_edx) = cpuid(1); - Features { - bits: ((feature_ecx as u64) << 32) | (feature_edx as u64) - } -} - -#[inline(always)] -pub unsafe fn read_msr(msr: Msr) -> u64 { - let (r1, r2): (u32, u32); - asm!("rdmsr" : "={eax}"(r1), "={edx}"(r2) : "{ecx}"(msr as u32) :: "intel"); - r1 as u64 | ((r2 as u64) << 32) -} - -#[derive(Copy, Clone, PartialEq, Eq)] -pub enum PrivilegeLevel { - Ring0 = 0, - Ring1 = 1, - Ring2 = 2, - Ring3 = 3, -} - -#[derive(Copy, Clone, PartialEq, Eq)] -#[repr(C, packed)] -pub struct SegmentSelector { - data: u16 -} - -impl SegmentSelector { - #[inline(always)] - pub fn new(index: u16, rpl: PrivilegeLevel) -> SegmentSelector { - SegmentSelector { - data: index << 3 | rpl as u16 - } - } - - pub fn bits(&self) -> u16 { - self.data - } -} - -#[inline(always)] -pub unsafe fn set_tr(selector: SegmentSelector) { - asm!("ltr $0" :: "r"(selector.bits()) :: "volatile", "intel"); -} - -#[inline(always)] -pub unsafe fn set_ss(selector: SegmentSelector) { - asm!("mov ss, $0" :: "r"(selector.bits()) :: "volatile", "intel"); -} - -#[inline(always)] -pub unsafe fn set_ds(selector: SegmentSelector) { - asm!("mov ds, $0" :: "r"(selector.bits()) :: "volatile", "intel"); -} - -#[inline(always)] -pub unsafe fn set_es(selector: SegmentSelector) { - asm!("mov es, $0" :: "r"(selector.bits()) :: "volatile", "intel"); -} - -#[inline(always)] -pub unsafe fn set_gs(selector: SegmentSelector) { - asm!("mov gs, $0" :: "r"(selector.bits()) :: "volatile", "intel"); -} - -#[inline(always)] -pub unsafe fn set_fs(selector: SegmentSelector) { - asm!("mov fs, $0" :: "r"(selector.bits()) :: "volatile", "intel"); -} - -#[inline(always)] -pub unsafe fn set_cs(selector: SegmentSelector) { - asm!("push $0; - push $$1f - lret; - 1:" :: "ri"(selector.bits() as usize) :: "volatile"); -} - -#[inline(always)] -pub fn get_cr0() -> Cr0 { - unsafe { - let r: usize; - asm!("mov $0, cr0" : "=r"(r) ::: "intel"); - Cr0::from_bits_truncate(r) - } -} - -#[inline(always)] -pub fn get_cr2() -> usize { - unsafe { - let r: usize; - asm!("mov $0, cr2" : "=r"(r) ::: "intel"); - r - } -} - -#[inline(always)] -pub fn get_cr3() -> usize { - unsafe { - let r: usize; - asm!("mov $0, cr3" : "=r"(r) ::: "intel"); - r - } -} - -#[inline(always)] -pub fn get_cr4() -> Cr4 { - unsafe { - let r: usize; - asm!("mov $0, cr4" : "=r"(r) ::: "intel"); - Cr4::from_bits_truncate(r) - } -} - -#[inline(always)] -pub unsafe fn set_cr0(flags: Cr0) { - asm!("mov cr0, $0" :: "r"(flags.bits()) :: "volatile", "intel"); -} - -#[inline(always)] -pub unsafe fn set_cr3(val: usize) { - asm!("mov cr3, $0" :: "r"(val) :: "volatile", "intel"); -} - -#[inline(always)] -pub unsafe fn set_cr4(flags: Cr4) { - asm!("mov cr4, $0" :: "r"(flags.bits()) :: "volatile", "intel"); -} - -#[inline(always)] -pub unsafe fn enable_interrupts() { - asm!("sti" :::: "volatile", "intel"); -} - -#[inline(always)] -pub unsafe fn disable_interrupts() { - asm!("cli" :::: "volatile", "intel"); -} - -#[inline(always)] -pub unsafe fn halt() { - asm!("hlt" :::: "volatile", "intel"); -} - -#[inline(always)] -pub unsafe fn out8(port: u16, value: u8) { - asm!("out $0, $1" :: "{dx}"(port), "{al}"(value) :: "volatile", "intel"); -} - -#[inline(always)] -pub unsafe fn out16(port: u16, value: u16) { - asm!("out $0, $1" :: "{dx}"(port), "{ax}"(value) :: "volatile", "intel"); -} - -#[inline(always)] -pub unsafe fn out32(port: u16, value: u32) { - asm!("out $0, $1" :: "{dx}"(port), "{eax}"(value) :: "volatile", "intel"); -} - -#[inline(always)] -pub unsafe fn outs8(port: u16, buf: &[u8]) { - asm!("rep outsb dx, [esi]" :: "{ecx}"(buf.len()), "{dx}"(port), "{esi}"(buf.as_ptr()) : "ecx", "edi" : "intel"); -} - -#[inline(always)] -pub unsafe fn outs16(port: u16, buf: &[u16]) { - asm!("rep outsw dx, [esi]" :: "{ecx}"(buf.len()), "{dx}"(port), "{esi}"(buf.as_ptr()) : "ecx", "edi" : "intel"); -} - -#[inline(always)] -pub unsafe fn outs32(port: u16, buf: &[u32]) { - asm!("rep outsd dx, [esi]" :: "{ecx}"(buf.len()), "{dx}"(port), "{esi}"(buf.as_ptr()) : "ecx", "edi" : "intel"); -} - - -#[inline(always)] -pub unsafe fn in8(port: u16) -> u8 { - let r: u8; - asm!("in $0, $1" : "={al}"(r) : "{dx}"(port) :: "intel"); - r -} - -#[inline(always)] -pub unsafe fn in16(port: u16) -> u16 { - let r: u16; - asm!("in $0, $1" : "={ax}"(r) : "{dx}"(port) :: "intel"); - r -} - -#[inline(always)] -pub unsafe fn in32(port: u16) -> u32 { - let r: u32; - asm!("in $0, $1" : "={eax}"(r) : "{dx}"(port) :: "intel"); - r -} - -#[inline(always)] -pub unsafe fn ins8(port: u16, buf: &mut [u8]) { - asm!("rep insb [edi], dx" :: "{ecx}"(buf.len()), "{dx}"(port), "{edi}"(buf.as_ptr()) : "ecx", "edi" : "intel"); -} - -#[inline(always)] -pub unsafe fn ins16(port: u16, buf: &mut [u16]) { - asm!("rep insw [edi], dx" :: "{ecx}"(buf.len()), "{dx}"(port), "{edi}"(buf.as_ptr()) : "ecx", "edi" : "intel"); -} - -#[inline(always)] -pub unsafe fn ins32(port: u16, buf: &mut [u32]) { - asm!("rep insd [edi], dx" :: "{ecx}"(buf.len()), "{dx}"(port), "{edi}"(buf.as_ptr()) : "ecx", "edi" : "intel"); -} |