aboutsummaryrefslogtreecommitdiff
path: root/tobba/src
diff options
context:
space:
mode:
Diffstat (limited to 'tobba/src')
-rw-r--r--tobba/src/lib.rs21
-rw-r--r--tobba/src/x86.rs217
-rw-r--r--tobba/src/x86_64.rs19
-rw-r--r--tobba/src/x86_shared.rs409
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");
-}