This commit is contained in:
Fabian 2022-01-14 14:21:55 -06:00
parent ff22df3f9c
commit 4e28e51d04
4 changed files with 15 additions and 26 deletions

View file

@ -11,7 +11,6 @@ list of emulated hardware:
- Single stepping (trap flag, debug registers) - Single stepping (trap flag, debug registers)
- Some exceptions, especially floating point and SSE - Some exceptions, especially floating point and SSE
- Multicore - Multicore
- PAE
- 64-bit extensions - 64-bit extensions
- A floating point unit (FPU). Calculations are done using the Berkeley - A floating point unit (FPU). Calculations are done using the Berkeley
SoftFloat library and therefore should be precise (but slow). Trigonometric SoftFloat library and therefore should be precise (but slow). Trigonometric

View file

@ -120,6 +120,7 @@ var
/** @const */ /** @const */
var CR0_PG = 1 << 31; var CR0_PG = 1 << 31;
/** @const */
var CR4_PAE = 1 << 5; var CR4_PAE = 1 << 5;

View file

@ -332,8 +332,6 @@ CPU.prototype.debug_init = function()
}; };
} }
var dbg_log = console.log.bind(console);
function dump_page_structures() { function dump_page_structures() {
var pae = !!(cpu.cr[4] & CR4_PAE); var pae = !!(cpu.cr[4] & CR4_PAE);
if (pae) if (pae)

View file

@ -20,8 +20,8 @@ use cpu::global_pointers::*;
use cpu::memory; use cpu::memory;
use cpu::memory::mem8; use cpu::memory::mem8;
use cpu::memory::{ use cpu::memory::{
in_mapped_range, read8, read16, read32s, read64s, read128, read_aligned32, in_mapped_range, read8, read16, read32s, read64s, read128, read_aligned32, read_aligned64,
read_aligned64, write8, write_aligned32, write8, write_aligned32,
}; };
use cpu::misc_instr::{ use cpu::misc_instr::{
adjust_stack_reg, get_stack_pointer, getaf, getcf, getof, getpf, getsf, getzf, pop16, pop32s, adjust_stack_reg, get_stack_pointer, getaf, getcf, getof, getpf, getsf, getzf, pop16, pop32s,
@ -1829,21 +1829,17 @@ pub unsafe fn do_page_walk(
let pae = *cr.offset(4) & CR4_PAE != 0; let pae = *cr.offset(4) & CR4_PAE != 0;
let (page_dir_addr, page_dir_entry) = let (page_dir_addr, page_dir_entry) = match walk_page_directory(pae, addr) {
match walk_page_directory(pae, addr) { Some((a, e)) => (a, e),
Some((a, e)) => (a, e), None => {
// to do at this place: return Err(PageFault {
//
// - set cr2 = addr (which caused the page fault)
// - call_interrupt_vector with id 14, error code 0-7 (requires information if read or write)
// - prevent execution of the function that triggered this call
None => return Err(PageFault {
addr, addr,
for_writing, for_writing,
user, user,
present: false, present: false,
}), });
}; },
};
if page_dir_entry & PAGE_TABLE_PRESENT_MASK == 0 { if page_dir_entry & PAGE_TABLE_PRESENT_MASK == 0 {
return Err(PageFault { return Err(PageFault {
@ -1854,7 +1850,6 @@ pub unsafe fn do_page_walk(
}); });
} }
// XXX
let kernel_write_override = !user && 0 == *cr & CR0_WP; let kernel_write_override = !user && 0 == *cr & CR0_WP;
if page_dir_entry & PAGE_TABLE_RW_MASK == 0 && !kernel_write_override { if page_dir_entry & PAGE_TABLE_RW_MASK == 0 && !kernel_write_override {
can_write = false; can_write = false;
@ -1893,14 +1888,14 @@ pub unsafe fn do_page_walk(
high = if pae { high = if pae {
(page_dir_entry as u32 & 0xFFE00000 | (addr & 0x1FF000) as u32) as i32 (page_dir_entry as u32 & 0xFFE00000 | (addr & 0x1FF000) as u32) as i32
} else { }
else {
(page_dir_entry as u32 & 0xFFC00000 | (addr & 0x3FF000) as u32) as i32 (page_dir_entry as u32 & 0xFFC00000 | (addr & 0x3FF000) as u32) as i32
}; };
global = page_dir_entry & PAGE_TABLE_GLOBAL_MASK == PAGE_TABLE_GLOBAL_MASK global = page_dir_entry & PAGE_TABLE_GLOBAL_MASK == PAGE_TABLE_GLOBAL_MASK
} }
else { else {
let (page_table_addr, page_table_entry) = let (page_table_addr, page_table_entry) = walk_page_table(pae, addr, page_dir_entry);
walk_page_table(pae, addr, page_dir_entry);
if page_table_entry & PAGE_TABLE_PRESENT_MASK == 0 { if page_table_entry & PAGE_TABLE_PRESENT_MASK == 0 {
return Err(PageFault { return Err(PageFault {
@ -2010,7 +2005,7 @@ unsafe fn walk_page_directory(pae: bool, addr: i32) -> Option<(i32, i32)> {
"Unsupported: PDPT entry larger than 32 bits" "Unsupported: PDPT entry larger than 32 bits"
); );
let page_dir_addr = ((pdpt_entry as u32 & 0xFFFFF000)>> 2).wrapping_add(page_dir_idx << 1); let page_dir_addr = ((pdpt_entry as u32 & 0xFFFFF000) >> 2).wrapping_add(page_dir_idx << 1);
let page_dir_entry = read_aligned64(page_dir_addr); let page_dir_entry = read_aligned64(page_dir_addr);
dbg_assert!( dbg_assert!(
page_dir_entry as u64 & 0x7FFF_FFFF_0000_0000 == 0, page_dir_entry as u64 & 0x7FFF_FFFF_0000_0000 == 0,
@ -2030,11 +2025,7 @@ unsafe fn walk_page_directory(pae: bool, addr: i32) -> Option<(i32, i32)> {
return Some((page_dir_addr as i32, page_dir_entry)); return Some((page_dir_addr as i32, page_dir_entry));
} }
unsafe fn walk_page_table( unsafe fn walk_page_table(pae: bool, addr: i32, page_dir_entry: i32) -> (i32, i32) {
pae: bool,
addr: i32,
page_dir_entry: i32
) -> (i32, i32) {
let page_table = (page_dir_entry as u32 & 0xFFFFF000) >> 2; let page_table = (page_dir_entry as u32 & 0xFFFFF000) >> 2;
if pae { if pae {
let page_table_idx = (addr as u32 >> 12) & 0x1FF; let page_table_idx = (addr as u32 >> 12) & 0x1FF;