From 5b4f79608229e01349740cc7b416bc0e04f5ab43 Mon Sep 17 00:00:00 2001 From: Ethin Probst Date: Fri, 23 Aug 2019 17:35:40 -0500 Subject: [PATCH 01/11] The bootloader now implements SSE and AVX support and enables AVX if found. --- src/avx.s | 17 +++++++++++++++++ src/main.rs | 5 +++++ src/sse.s | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/stage_2.s | 2 +- 4 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 src/avx.s create mode 100644 src/sse.s diff --git a/src/avx.s b/src/avx.s new file mode 100644 index 00000000..fab80889 --- /dev/null +++ b/src/avx.s @@ -0,0 +1,17 @@ +.section .boot, "awx" +.intel_syntax noprefix +.code64 + +# This asm file enables AVX support before the OS starts. +# AVX is not a requirement for an OS to boot. +# This file should be loaded after stage 3 and just before stage 4. +enable_avx: + push rax + push rcx + xor rcx, rcx + xgetbv + or eax, 7 + xsetbv + pop rcx + pop rax + ret diff --git a/src/main.rs b/src/main.rs index e8294172..debc13ee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,7 +36,9 @@ include!(concat!(env!("OUT_DIR"), "/bootloader_config.rs")); global_asm!(include_str!("stage_1.s")); global_asm!(include_str!("stage_2.s")); global_asm!(include_str!("e820.s")); +global_asm!(include_str!("sse.s")); global_asm!(include_str!("stage_3.s")); +global_asm!(include_str!("avx.s")); #[cfg(feature = "vga_320x200")] global_asm!(include_str!("video_mode/vga_320x200.s")); @@ -87,6 +89,9 @@ extern "C" { #[no_mangle] pub unsafe extern "C" fn stage_4() -> ! { +if is_x86_feature_detected!("avx") { +enable_avx(); +} // Set stack segment asm!("mov bx, 0x0 mov ss, bx" ::: "bx" : "intel"); diff --git a/src/sse.s b/src/sse.s new file mode 100644 index 00000000..be65d7de --- /dev/null +++ b/src/sse.s @@ -0,0 +1,53 @@ +.section .boot, "awx" +.intel_syntax noprefix +.code32 + +# Checks for SSE support and enables it. Should be loaded after stage 2. +no_sse_msg: .asciz "This system does not support SSE" +no_sse2_msg: .asciz "This system does not support SSE 2" +no_xsave_msg: .asciz "This system does not support XSAVE" + +# As a part of the implementation of x86-64, AMD demands a minimum amount of SSE support. +# This function will fail if SSE, SSE2 and XSAVE support are not found together. +enable_sse: + mov eax, 0x1 + cpuid + test edx, 1 << 25 + jz .no_sse + mov eax, 0x1 + cpuid + test edx, 1 << 26 + jz .no_sse2 + mov eax, 0x1 + cpuid + test ecx, 1 << 26 + jz .no_xsave + mov eax, cr0 + # clear coprocessor emulation CR0.EM + and ax, 0xFFFB + # set coprocessor monitoring CR0.MP + or ax, 0x2 + mov cr0, eax + mov eax, cr4 + # set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time + or ax, 3 << 9 + mov cr4, eax + ret + +.no_sse: + lea si, [no_sse_msg] + call real_mode_println +.no_sse_spin: +jmp .no_sse_spin + +.no_sse2: + lea si, [no_sse2_msg] + call real_mode_println +.no_sse2_spin: +jmp .no_sse2_spin + +.no_xsave: + lea si, [no_xsave_msg] + call real_mode_println +.no_xsave_spin: +jmp .no_xsave_spin diff --git a/src/stage_2.s b/src/stage_2.s index 5486439a..d9869474 100644 --- a/src/stage_2.s +++ b/src/stage_2.s @@ -95,7 +95,7 @@ enter_protected_mode_again: mov eax, cr0 or al, 1 # set protected mode bit mov cr0, eax - + call enable_sse push 0x8 lea eax, [stage_3] push eax From fa61c657f1ede5dac6cb6c655b383de449be8c57 Mon Sep 17 00:00:00 2001 From: Ethin Probst Date: Sat, 24 Aug 2019 17:53:00 -0500 Subject: [PATCH 02/11] Rewrote SSE code in rust using inline ASM and made SSE and AVX features. --- Cargo.toml | 2 ++ src/main.rs | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 98952880..433e0b7a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,8 @@ binary = ["xmas-elf", "x86_64", "usize_conversions", "fixedvec", "llvm-tools", " vga_320x200 = ["font8x8"] recursive_page_table = [] map_physical_memory = [] +sse = [] +avx = ["sse"] [profile.dev] panic = "abort" diff --git a/src/main.rs b/src/main.rs index debc13ee..9c862f49 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,6 +23,7 @@ use x86_64::structures::paging::{ }; use x86_64::ux::u9; use x86_64::{PhysAddr, VirtAddr}; +use x86_64::registers::Cr0; // The bootloader_config.rs file contains some configuration constants set by the build script: // PHYSICAL_MEMORY_OFFSET: The offset into the virtual address space where the physical memory @@ -89,6 +90,22 @@ extern "C" { #[no_mangle] pub unsafe extern "C" fn stage_4() -> ! { +#[cfg(feature = "sse")] +if is_x86_feature_detected!("sse") && is_x86_feature_detected!("sse2") { +let flags = ((Cr0::read_raw() & 0xFFFB) | 0x2); +Cr0::write_raw(flags); +// For now, we must use inline ASM here +let mut cr4: u64; +unsafe { +asm!("mov %cr4, $0" : "=r" (cr4)); +} +cr4 |= 3 << 9; +unsafe { +asm!("mov $0, %cr4" :: "r" (cr4) : "memory"); +} +} + +#[cfg(feature = "avx")] if is_x86_feature_detected!("avx") { enable_avx(); } From 3f84e5c14ce0c7ed686a6f0beaf31af1cdec0a2d Mon Sep 17 00:00:00 2001 From: Ethin Probst Date: Sat, 24 Aug 2019 17:55:16 -0500 Subject: [PATCH 03/11] Deleted SSE assembly and formatted code. --- src/main.rs | 45 ++++++++++++++++++++++++------------------- src/sse.s | 53 --------------------------------------------------- src/stage_2.s | 1 - 3 files changed, 25 insertions(+), 74 deletions(-) delete mode 100644 src/sse.s diff --git a/src/main.rs b/src/main.rs index 9c862f49..51355972 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,13 +17,13 @@ use core::{mem, slice}; use fixedvec::alloc_stack; use usize_conversions::usize_from; use x86_64::instructions::tlb; +use x86_64::registers::Cr0; use x86_64::structures::paging::{ frame::PhysFrameRange, page_table::PageTableEntry, Mapper, Page, PageTable, PageTableFlags, PhysFrame, RecursivePageTable, Size2MiB, Size4KiB, }; use x86_64::ux::u9; use x86_64::{PhysAddr, VirtAddr}; -use x86_64::registers::Cr0; // The bootloader_config.rs file contains some configuration constants set by the build script: // PHYSICAL_MEMORY_OFFSET: The offset into the virtual address space where the physical memory @@ -37,8 +37,8 @@ include!(concat!(env!("OUT_DIR"), "/bootloader_config.rs")); global_asm!(include_str!("stage_1.s")); global_asm!(include_str!("stage_2.s")); global_asm!(include_str!("e820.s")); -global_asm!(include_str!("sse.s")); global_asm!(include_str!("stage_3.s")); +#[cfg(feature = "avx")] global_asm!(include_str!("avx.s")); #[cfg(feature = "vga_320x200")] @@ -90,25 +90,30 @@ extern "C" { #[no_mangle] pub unsafe extern "C" fn stage_4() -> ! { -#[cfg(feature = "sse")] -if is_x86_feature_detected!("sse") && is_x86_feature_detected!("sse2") { -let flags = ((Cr0::read_raw() & 0xFFFB) | 0x2); -Cr0::write_raw(flags); -// For now, we must use inline ASM here -let mut cr4: u64; -unsafe { -asm!("mov %cr4, $0" : "=r" (cr4)); -} -cr4 |= 3 << 9; -unsafe { -asm!("mov $0, %cr4" :: "r" (cr4) : "memory"); -} -} + #[cfg(feature = "sse")] + { + if is_x86_feature_detected!("sse") && is_x86_feature_detected!("sse2") { + let flags = ((Cr0::read_raw() & 0xFFFB) | 0x2); + Cr0::write_raw(flags); + // For now, we must use inline ASM here + let mut cr4: u64; + unsafe { + asm!("mov %cr4, $0" : "=r" (cr4)); + } + cr4 |= 3 << 9; + unsafe { + asm!("mov $0, %cr4" :: "r" (cr4) : "memory"); + } + } + } + + #[cfg(feature = "avx")] + { + if is_x86_feature_detected!("avx") { + enable_avx(); + } + } -#[cfg(feature = "avx")] -if is_x86_feature_detected!("avx") { -enable_avx(); -} // Set stack segment asm!("mov bx, 0x0 mov ss, bx" ::: "bx" : "intel"); diff --git a/src/sse.s b/src/sse.s deleted file mode 100644 index be65d7de..00000000 --- a/src/sse.s +++ /dev/null @@ -1,53 +0,0 @@ -.section .boot, "awx" -.intel_syntax noprefix -.code32 - -# Checks for SSE support and enables it. Should be loaded after stage 2. -no_sse_msg: .asciz "This system does not support SSE" -no_sse2_msg: .asciz "This system does not support SSE 2" -no_xsave_msg: .asciz "This system does not support XSAVE" - -# As a part of the implementation of x86-64, AMD demands a minimum amount of SSE support. -# This function will fail if SSE, SSE2 and XSAVE support are not found together. -enable_sse: - mov eax, 0x1 - cpuid - test edx, 1 << 25 - jz .no_sse - mov eax, 0x1 - cpuid - test edx, 1 << 26 - jz .no_sse2 - mov eax, 0x1 - cpuid - test ecx, 1 << 26 - jz .no_xsave - mov eax, cr0 - # clear coprocessor emulation CR0.EM - and ax, 0xFFFB - # set coprocessor monitoring CR0.MP - or ax, 0x2 - mov cr0, eax - mov eax, cr4 - # set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time - or ax, 3 << 9 - mov cr4, eax - ret - -.no_sse: - lea si, [no_sse_msg] - call real_mode_println -.no_sse_spin: -jmp .no_sse_spin - -.no_sse2: - lea si, [no_sse2_msg] - call real_mode_println -.no_sse2_spin: -jmp .no_sse2_spin - -.no_xsave: - lea si, [no_xsave_msg] - call real_mode_println -.no_xsave_spin: -jmp .no_xsave_spin diff --git a/src/stage_2.s b/src/stage_2.s index d9869474..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 - call enable_sse push 0x8 lea eax, [stage_3] push eax From 61b6534f2443d756ba11ab07dfe169c926c6a251 Mon Sep 17 00:00:00 2001 From: Ethin Probst Date: Sat, 24 Aug 2019 18:41:06 -0500 Subject: [PATCH 04/11] Aded a use statement to fix a compile error. --- src/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.rs b/src/main.rs index 51355972..82c5a90f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,6 +24,7 @@ use x86_64::structures::paging::{ }; use x86_64::ux::u9; use x86_64::{PhysAddr, VirtAddr}; +use x86_64::registers::control::Cr0; // The bootloader_config.rs file contains some configuration constants set by the build script: // PHYSICAL_MEMORY_OFFSET: The offset into the virtual address space where the physical memory From 1b59b4d9528aa5d7f1426a1e22a34242c36e4fb0 Mon Sep 17 00:00:00 2001 From: Ethin Probst Date: Sat, 24 Aug 2019 18:51:09 -0500 Subject: [PATCH 05/11] Removed AVX support. --- Cargo.toml | 1 - src/avx.s | 17 ----------------- src/main.rs | 11 ----------- 3 files changed, 29 deletions(-) delete mode 100644 src/avx.s diff --git a/Cargo.toml b/Cargo.toml index 433e0b7a..28c1e58a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,6 @@ vga_320x200 = ["font8x8"] recursive_page_table = [] map_physical_memory = [] sse = [] -avx = ["sse"] [profile.dev] panic = "abort" diff --git a/src/avx.s b/src/avx.s deleted file mode 100644 index fab80889..00000000 --- a/src/avx.s +++ /dev/null @@ -1,17 +0,0 @@ -.section .boot, "awx" -.intel_syntax noprefix -.code64 - -# This asm file enables AVX support before the OS starts. -# AVX is not a requirement for an OS to boot. -# This file should be loaded after stage 3 and just before stage 4. -enable_avx: - push rax - push rcx - xor rcx, rcx - xgetbv - or eax, 7 - xsetbv - pop rcx - pop rax - ret diff --git a/src/main.rs b/src/main.rs index 82c5a90f..2a87db35 100644 --- a/src/main.rs +++ b/src/main.rs @@ -39,8 +39,6 @@ global_asm!(include_str!("stage_1.s")); global_asm!(include_str!("stage_2.s")); global_asm!(include_str!("e820.s")); global_asm!(include_str!("stage_3.s")); -#[cfg(feature = "avx")] -global_asm!(include_str!("avx.s")); #[cfg(feature = "vga_320x200")] global_asm!(include_str!("video_mode/vga_320x200.s")); @@ -93,7 +91,6 @@ extern "C" { pub unsafe extern "C" fn stage_4() -> ! { #[cfg(feature = "sse")] { - if is_x86_feature_detected!("sse") && is_x86_feature_detected!("sse2") { let flags = ((Cr0::read_raw() & 0xFFFB) | 0x2); Cr0::write_raw(flags); // For now, we must use inline ASM here @@ -105,14 +102,6 @@ pub unsafe extern "C" fn stage_4() -> ! { unsafe { asm!("mov $0, %cr4" :: "r" (cr4) : "memory"); } - } - } - - #[cfg(feature = "avx")] - { - if is_x86_feature_detected!("avx") { - enable_avx(); - } } // Set stack segment From 59e87f2bdd79c1d1b9009e5f69754edeccd59590 Mon Sep 17 00:00:00 2001 From: Ethin Probst Date: Sat, 24 Aug 2019 18:56:58 -0500 Subject: [PATCH 06/11] Tested SSE support and formatted code. --- src/main.rs | 24 ++++++++++++------------ test-kernel/Cargo.lock | 5 +++++ test-kernel/Cargo.toml | 1 + 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/main.rs b/src/main.rs index 2a87db35..9fe345d3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,6 +17,7 @@ use core::{mem, slice}; use fixedvec::alloc_stack; use usize_conversions::usize_from; use x86_64::instructions::tlb; +use x86_64::registers::control::Cr0; use x86_64::registers::Cr0; use x86_64::structures::paging::{ frame::PhysFrameRange, page_table::PageTableEntry, Mapper, Page, PageTable, PageTableFlags, @@ -24,7 +25,6 @@ use x86_64::structures::paging::{ }; use x86_64::ux::u9; use x86_64::{PhysAddr, VirtAddr}; -use x86_64::registers::control::Cr0; // The bootloader_config.rs file contains some configuration constants set by the build script: // PHYSICAL_MEMORY_OFFSET: The offset into the virtual address space where the physical memory @@ -91,17 +91,17 @@ extern "C" { pub unsafe extern "C" fn stage_4() -> ! { #[cfg(feature = "sse")] { - let flags = ((Cr0::read_raw() & 0xFFFB) | 0x2); - Cr0::write_raw(flags); - // For now, we must use inline ASM here - let mut cr4: u64; - unsafe { - asm!("mov %cr4, $0" : "=r" (cr4)); - } - cr4 |= 3 << 9; - unsafe { - asm!("mov $0, %cr4" :: "r" (cr4) : "memory"); - } + let flags = ((Cr0::read_raw() & 0xFFFB) | 0x2); + Cr0::write_raw(flags); + // For now, we must use inline ASM here + let mut cr4: u64; + unsafe { + asm!("mov %cr4, $0" : "=r" (cr4)); + } + cr4 |= 3 << 9; + unsafe { + asm!("mov $0, %cr4" :: "r" (cr4) : "memory"); + } } // Set stack segment 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)", ] diff --git a/test-kernel/Cargo.toml b/test-kernel/Cargo.toml index 85bcf7a9..dc1e990c 100644 --- a/test-kernel/Cargo.toml +++ b/test-kernel/Cargo.toml @@ -6,3 +6,4 @@ edition = "2018" [dependencies] x86_64 = "0.3.4" +bootloader = {path = "..", features=["sse"]} From a05b9cb6271f173de19c34800d5b83287bed1b3a Mon Sep 17 00:00:00 2001 From: Ethin Probst Date: Sat, 24 Aug 2019 19:15:34 -0500 Subject: [PATCH 07/11] Formatted code and ensured that the bootloader *actually* built. --- example-kernel/Cargo.lock | 5 +++++ example-kernel/src/main.rs | 2 +- src/main.rs | 7 ++++--- 3 files changed, 10 insertions(+), 4 deletions(-) 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 9fe345d3..3d6a62cf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,8 +17,6 @@ use core::{mem, slice}; use fixedvec::alloc_stack; use usize_conversions::usize_from; use x86_64::instructions::tlb; -use x86_64::registers::control::Cr0; -use x86_64::registers::Cr0; use x86_64::structures::paging::{ frame::PhysFrameRange, page_table::PageTableEntry, Mapper, Page, PageTable, PageTableFlags, PhysFrame, RecursivePageTable, Size2MiB, Size4KiB, @@ -91,13 +89,16 @@ extern "C" { pub unsafe extern "C" fn stage_4() -> ! { #[cfg(feature = "sse")] { - let flags = ((Cr0::read_raw() & 0xFFFB) | 0x2); + use x86_64::registers::control::Cr0; + // We now clear coprocessor emulation CR0.EM and set coprocessor monitoring CR0.MP + let flags = (Cr0::read_raw() & 0xFFFB | 0x2); Cr0::write_raw(flags); // For now, we must use inline ASM here let mut cr4: u64; unsafe { asm!("mov %cr4, $0" : "=r" (cr4)); } + // set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time cr4 |= 3 << 9; unsafe { asm!("mov $0, %cr4" :: "r" (cr4) : "memory"); From 81315b6440cae98b349796d8d36b0521e7ee8f70 Mon Sep 17 00:00:00 2001 From: Ethin Probst Date: Wed, 11 Sep 2019 21:18:38 -0500 Subject: [PATCH 08/11] Got SSE t ofinally work (haven't committed in a while because of lack of time) --- src/main.rs | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/main.rs b/src/main.rs index 3d6a62cf..5bb36e44 100644 --- a/src/main.rs +++ b/src/main.rs @@ -90,19 +90,24 @@ pub unsafe extern "C" fn stage_4() -> ! { #[cfg(feature = "sse")] { use x86_64::registers::control::Cr0; - // We now clear coprocessor emulation CR0.EM and set coprocessor monitoring CR0.MP - let flags = (Cr0::read_raw() & 0xFFFB | 0x2); - Cr0::write_raw(flags); - // For now, we must use inline ASM here - let mut cr4: u64; - unsafe { - asm!("mov %cr4, $0" : "=r" (cr4)); - } - // set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time - cr4 |= 3 << 9; - unsafe { - asm!("mov $0, %cr4" :: "r" (cr4) : "memory"); - } + 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"); + } } // Set stack segment From 12b3c8b1c7b3ced7f9cd45c7a2df4f6e65066b49 Mon Sep 17 00:00:00 2001 From: Ethin Probst Date: Wed, 11 Sep 2019 21:21:58 -0500 Subject: [PATCH 09/11] Aded bit_field dependency. Formatted code. --- Cargo.toml | 1 + src/main.rs | 37 +++++++++++++++++++------------------ 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 28c1e58a..bfa017ab 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 = "*" [dependencies.font8x8] version = "0.2.4" diff --git a/src/main.rs b/src/main.rs index 5bb36e44..ac726128 100644 --- a/src/main.rs +++ b/src/main.rs @@ -89,25 +89,26 @@ extern "C" { pub unsafe extern "C" fn stage_4() -> ! { #[cfg(feature = "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"); - } + 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"); + } } // Set stack segment From e8b3a3970ef3f2ebbe429388c15fe008a7b99704 Mon Sep 17 00:00:00 2001 From: Ethin Probst Date: Thu, 19 Sep 2019 16:42:27 -0500 Subject: [PATCH 10/11] Moved SSE into its own module. Made deps for SSE entirely optional. Removed botloader dep from test kernel. --- Cargo.lock | 7 +++++++ Cargo.toml | 4 ++-- src/main.rs | 26 ++------------------------ src/sse.rs | 24 ++++++++++++++++++++++++ test-kernel/Cargo.toml | 1 - 5 files changed, 35 insertions(+), 27 deletions(-) create mode 100644 src/sse.rs 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 bfa017ab..a128b9d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +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 = "*" +bit_field = { version = "0.10.0", optional = true } [dependencies.font8x8] version = "0.2.4" @@ -35,7 +35,7 @@ binary = ["xmas-elf", "x86_64", "usize_conversions", "fixedvec", "llvm-tools", " vga_320x200 = ["font8x8"] recursive_page_table = [] map_physical_memory = [] -sse = [] +sse = ["bit_field"] [profile.dev] panic = "abort" diff --git a/src/main.rs b/src/main.rs index ac726128..87781b3d 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); @@ -87,30 +89,6 @@ extern "C" { #[no_mangle] pub unsafe extern "C" fn stage_4() -> ! { - #[cfg(feature = "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"); - } - } - // Set stack segment asm!("mov bx, 0x0 mov ss, bx" ::: "bx" : "intel"); 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/test-kernel/Cargo.toml b/test-kernel/Cargo.toml index dc1e990c..85bcf7a9 100644 --- a/test-kernel/Cargo.toml +++ b/test-kernel/Cargo.toml @@ -6,4 +6,3 @@ edition = "2018" [dependencies] x86_64 = "0.3.4" -bootloader = {path = "..", features=["sse"]} From 837ea1c3377795f48422ceb7abba7535b14d7a7f Mon Sep 17 00:00:00 2001 From: Ethin Probst Date: Fri, 20 Sep 2019 07:53:43 -0500 Subject: [PATCH 11/11] Added function call to enable SSE if SSE feature is enabled --- src/main.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main.rs b/src/main.rs index 87781b3d..dc0f4bc4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -144,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;