movs: fast copy into svga lfb

This commit is contained in:
Fabian 2022-11-10 16:15:19 -06:00
parent 70cf369d18
commit 685c39177f
2 changed files with 38 additions and 9 deletions

View file

@ -236,6 +236,16 @@ pub unsafe fn memcpy_no_mmap_or_dirty_check(src_addr: u32, dst_addr: u32, count:
) )
} }
pub unsafe fn memcpy_into_svga_lfb(src_addr: u32, dst_addr: u32, count: u32) {
dbg_assert!(src_addr < *memory_size);
dbg_assert!(in_svga_lfb(dst_addr));
ptr::copy_nonoverlapping(
mem8.offset(src_addr as isize),
vga_mem8.offset((dst_addr - VGA_LFB_ADDRESS) as isize),
count as usize,
)
}
pub unsafe fn mmap_write8(addr: u32, value: i32) { pub unsafe fn mmap_write8(addr: u32, value: i32) {
if in_svga_lfb(addr) { if in_svga_lfb(addr) {
vga::mark_dirty(addr); vga::mark_dirty(addr);

View file

@ -19,9 +19,9 @@ use cpu::cpu::{
}; };
use cpu::global_pointers::{flags, instruction_pointer, previous_ip}; use cpu::global_pointers::{flags, instruction_pointer, previous_ip};
use cpu::memory::{ use cpu::memory::{
in_mapped_range, memcpy_no_mmap_or_dirty_check, memset_no_mmap_or_dirty_check, in_mapped_range, in_svga_lfb, memcpy_into_svga_lfb, memcpy_no_mmap_or_dirty_check,
read8_no_mmap_check, read16_no_mmap_check, read32_no_mmap_check, write8_no_mmap_or_dirty_check, memset_no_mmap_or_dirty_check, read8_no_mmap_check, read16_no_mmap_check, read32_no_mmap_check,
write16_no_mmap_or_dirty_check, write32_no_mmap_or_dirty_check, write8_no_mmap_or_dirty_check, write16_no_mmap_or_dirty_check, write32_no_mmap_or_dirty_check,
}; };
use page::Page; use page::Page;
@ -145,10 +145,19 @@ unsafe fn string_instruction(
let mut phys_dst = 0; let mut phys_dst = 0;
let mut phys_src = 0; let mut phys_src = 0;
let mut skip_dirty_page = false; let mut skip_dirty_page = false;
let mut movs_into_svga_lfb = false;
if rep_fast { if rep_fast {
match instruction { match instruction {
Instruction::Movs | Instruction::Stos | Instruction::Ins => { Instruction::Movs => {
let (addr, skip) =
return_on_pagefault!(translate_address_write_and_can_skip_dirty(es + dst));
movs_into_svga_lfb = in_svga_lfb(addr);
rep_fast = rep_fast && (!in_mapped_range(addr) || movs_into_svga_lfb);
phys_dst = addr;
skip_dirty_page = skip;
},
Instruction::Stos | Instruction::Ins => {
let (addr, skip) = let (addr, skip) =
return_on_pagefault!(translate_address_write_and_can_skip_dirty(es + dst)); return_on_pagefault!(translate_address_write_and_can_skip_dirty(es + dst));
rep_fast = rep_fast && !in_mapped_range(addr); rep_fast = rep_fast && !in_mapped_range(addr);
@ -256,11 +265,21 @@ unsafe fn string_instruction(
phys_src -= (count_until_end_of_page - 1) * size_bytes as u32; phys_src -= (count_until_end_of_page - 1) * size_bytes as u32;
phys_dst -= (count_until_end_of_page - 1) * size_bytes as u32; phys_dst -= (count_until_end_of_page - 1) * size_bytes as u32;
} }
memcpy_no_mmap_or_dirty_check( if movs_into_svga_lfb {
phys_src, ::cpu::vga::mark_dirty(phys_dst);
phys_dst, memcpy_into_svga_lfb(
count_until_end_of_page * size_bytes as u32, phys_src,
); phys_dst,
count_until_end_of_page * size_bytes as u32,
);
}
else {
memcpy_no_mmap_or_dirty_check(
phys_src,
phys_dst,
count_until_end_of_page * size_bytes as u32,
);
}
i = count_until_end_of_page; i = count_until_end_of_page;
break; break;
}, },