diff --git a/Cargo.lock b/Cargo.lock index 2c4f0a5e..58f72e82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,6 +13,11 @@ name = "bit_field" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "bit_field" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "bitflags" version = "1.1.0" @@ -22,6 +27,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "bootloader" version = "0.8.0" dependencies = [ + "bit_field 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "fixedvec 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "font8x8 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "llvm-tools 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -106,6 +112,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum array-init 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "23589ecb866b460d3a0f1278834750268c607e8e28a1b982c907219f3178cd72" +"checksum bit_field 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a165d606cf084741d4ac3a28fb6e9b1eb0bd31f6cd999098cfddb0b2ab381dc0" "checksum bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed8765909f9009617974ab6b7d332625b320b33c326b1e9321382ef1999b5d56" "checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" "checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427" diff --git a/Cargo.toml b/Cargo.toml index 98952880..a128b9d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ xmas-elf = { version = "0.6.2", optional = true } x86_64 = { version = "0.7.2", optional = true } usize_conversions = { version = "0.2.0", optional = true } fixedvec = { version = "0.2.4", optional = true } +bit_field = { version = "0.10.0", optional = true } [dependencies.font8x8] version = "0.2.4" @@ -34,6 +35,7 @@ binary = ["xmas-elf", "x86_64", "usize_conversions", "fixedvec", "llvm-tools", " vga_320x200 = ["font8x8"] recursive_page_table = [] map_physical_memory = [] +sse = ["bit_field"] [profile.dev] panic = "abort" diff --git a/example-kernel/Cargo.lock b/example-kernel/Cargo.lock index be9487bc..5fecdd3d 100644 --- a/example-kernel/Cargo.lock +++ b/example-kernel/Cargo.lock @@ -18,10 +18,15 @@ name = "bitflags" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "bootloader" +version = "0.8.0" + [[package]] name = "example-kernel" version = "0.1.0" dependencies = [ + "bootloader 0.8.0", "x86_64 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/example-kernel/src/main.rs b/example-kernel/src/main.rs index 7f472954..a953f2e9 100644 --- a/example-kernel/src/main.rs +++ b/example-kernel/src/main.rs @@ -11,7 +11,7 @@ pub extern "C" fn _start() -> ! { // named `_start` by default let vga_buffer = 0xb8000 as *mut u8; - + // print `HELLO` to the screen (see // https://os.phil-opp.com/minimal-rust-kernel/#printing-to-screen) for (i, &byte) in HELLO.iter().enumerate() { diff --git a/src/main.rs b/src/main.rs index e8294172..dc0f4bc4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -54,6 +54,8 @@ mod frame_allocator; mod level4_entries; mod page_table; mod printer; +#[cfg(feature = "sse")] +mod sse; pub struct IdentityMappedAddr(PhysAddr); @@ -142,6 +144,10 @@ fn load_elf( // Extract required information from the ELF file. let mut preallocated_space = alloc_stack!([ProgramHeader64; 32]); let mut segments = FixedVec::new(&mut preallocated_space); + #[cfg(feature = "sse")] + { + sse::enable_sse(); + } let entry_point; { let kernel_start_ptr = usize_from(kernel_start.as_u64()) as *const u8; diff --git a/src/sse.rs b/src/sse.rs new file mode 100644 index 00000000..86d12bdf --- /dev/null +++ b/src/sse.rs @@ -0,0 +1,24 @@ +/// Enables Streaming SIMD Extensions (SSE) support for loaded kernels. +#[cfg(feature = "sse")] +pub fn enable_sse() { + use bit_field::BitField; + use x86_64::registers::control::Cr0; + let mut flags = Cr0::read_raw(); + flags.set_bit(2, false); + flags.set_bit(1, true); + flags.set_bit(9, true); + flags.set_bit(10, true); + unsafe { + Cr0::write_raw(flags); + } + // For now, we must use inline ASM here + let mut cr4: u64; + unsafe { + asm!("mov %cr4, $0" : "=r" (cr4)); + } + cr4.set_bit(9, true); + cr4.set_bit(10, true); + unsafe { + asm!("mov $0, %cr4" :: "r" (cr4) : "memory"); + } +} diff --git a/src/stage_2.s b/src/stage_2.s index 5486439a..9e8d0df6 100644 --- a/src/stage_2.s +++ b/src/stage_2.s @@ -95,7 +95,6 @@ enter_protected_mode_again: mov eax, cr0 or al, 1 # set protected mode bit mov cr0, eax - push 0x8 lea eax, [stage_3] push eax diff --git a/test-kernel/Cargo.lock b/test-kernel/Cargo.lock index e2a6a681..18967535 100644 --- a/test-kernel/Cargo.lock +++ b/test-kernel/Cargo.lock @@ -18,6 +18,10 @@ name = "bitflags" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "bootloader" +version = "0.8.0" + [[package]] name = "nodrop" version = "0.1.13" @@ -32,6 +36,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "test-kernel" version = "0.1.0" dependencies = [ + "bootloader 0.8.0", "x86_64 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ]