From 817638b7aaa7f4adf9231a1c8fb7faedeb9a8edc Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 1 Sep 2016 16:14:42 -0600 Subject: [PATCH] Write combining is useable on real hardware, significantly improving scroll performance --- arch/x86_64/src/device/display.rs | 2 +- arch/x86_64/src/paging/mod.rs | 22 +++++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/arch/x86_64/src/device/display.rs b/arch/x86_64/src/device/display.rs index 25cc299..1329284 100644 --- a/arch/x86_64/src/device/display.rs +++ b/arch/x86_64/src/device/display.rs @@ -102,7 +102,7 @@ pub unsafe fn init(active_table: &mut ActivePageTable) { let start_frame = Frame::containing_address(PhysicalAddress::new(onscreen)); let end_frame = Frame::containing_address(PhysicalAddress::new(onscreen + size * 4 - 1)); for frame in Frame::range_inclusive(start_frame, end_frame) { - active_table.identity_map(frame, entry::PRESENT | entry::WRITABLE | entry::NO_EXECUTE); + active_table.identity_map(frame, entry::HUGE_PAGE /*actually sets PAT for write combining*/ | entry::PRESENT | entry::WRITABLE | entry::NO_EXECUTE); } } diff --git a/arch/x86_64/src/paging/mod.rs b/arch/x86_64/src/paging/mod.rs index f9c7d64..760bee5 100644 --- a/arch/x86_64/src/paging/mod.rs +++ b/arch/x86_64/src/paging/mod.rs @@ -2,7 +2,7 @@ //! Some code was borrowed from [Phil Opp's Blog](http://os.phil-opp.com/modifying-page-tables.html) use core::ops::{Deref, DerefMut}; -use x86::tlb; +use x86::{msr, tlb}; use memory::{allocate_frame, Frame}; @@ -89,6 +89,26 @@ pub unsafe fn init(stack_start: usize, stack_end: usize) -> ActivePageTable { } }); + let uncacheable = 0; + let write_combining = 1; + let write_through = 4; + let write_protected = 5; + let write_back = 6; + let uncached = 7; + + let pat0 = write_back; + let pat1 = write_through; + let pat2 = uncached; + let pat3 = uncacheable; + + let pat4 = write_combining; + let pat5 = pat1; + let pat6 = pat2; + let pat7 = pat3; + + msr::wrmsr(msr::IA32_PAT, pat7 << 56 | pat6 << 48 | pat5 << 40 | pat4 << 32 + | pat3 << 24 | pat2 << 16 | pat1 << 8 | pat0); + active_table.switch(new_table); // Map and copy TDATA