Remove tlb_data from global pointers
This commit is contained in:
parent
6334e0965a
commit
7be85004c6
2
Makefile
2
Makefile
|
@ -70,7 +70,7 @@ CARGO_FLAGS=\
|
|||
--target wasm32-unknown-unknown \
|
||||
-- \
|
||||
-C linker=tools/rust-lld-wrapper \
|
||||
-C link-args="--import-table --global-base=8388608 $(STRIP_DEBUG_FLAG)" \
|
||||
-C link-args="--import-table --global-base=262144 $(STRIP_DEBUG_FLAG)" \
|
||||
--verbose
|
||||
|
||||
CORE_FILES=const.js config.js io.js main.js lib.js ide.js pci.js floppy.js \
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use cpu::cpu::{
|
||||
FLAG_CARRY, FLAG_OVERFLOW, FLAG_SIGN, FLAG_ZERO, TLB_GLOBAL, TLB_HAS_CODE, TLB_NO_USER,
|
||||
TLB_READONLY, TLB_VALID,
|
||||
tlb_data, FLAG_CARRY, FLAG_OVERFLOW, FLAG_SIGN, FLAG_ZERO, TLB_GLOBAL, TLB_HAS_CODE,
|
||||
TLB_NO_USER, TLB_READONLY, TLB_VALID,
|
||||
};
|
||||
use cpu::global_pointers;
|
||||
use cpu::imports::mem8;
|
||||
|
@ -508,7 +508,7 @@ fn gen_safe_read(
|
|||
ctx.builder.shl_i32();
|
||||
|
||||
ctx.builder
|
||||
.load_aligned_i32(global_pointers::tlb_data as u32);
|
||||
.load_aligned_i32(unsafe { &tlb_data[0] as *const i32 as u32 });
|
||||
let entry_local = ctx.builder.tee_new_local();
|
||||
|
||||
ctx.builder.const_i32(
|
||||
|
@ -651,7 +651,7 @@ fn gen_safe_write(
|
|||
ctx.builder.shl_i32();
|
||||
|
||||
ctx.builder
|
||||
.load_aligned_i32(global_pointers::tlb_data as u32);
|
||||
.load_aligned_i32(unsafe { &tlb_data[0] as *const i32 as u32 });
|
||||
let entry_local = ctx.builder.tee_new_local();
|
||||
|
||||
ctx.builder
|
||||
|
@ -802,7 +802,7 @@ pub fn gen_safe_read_write(
|
|||
ctx.builder.shl_i32();
|
||||
|
||||
ctx.builder
|
||||
.load_aligned_i32(global_pointers::tlb_data as u32);
|
||||
.load_aligned_i32(unsafe { &tlb_data[0] as *const i32 as u32 });
|
||||
let entry_local = ctx.builder.tee_new_local();
|
||||
|
||||
ctx.builder
|
||||
|
|
|
@ -262,6 +262,7 @@ pub static mut rdtsc_imprecision_offset: u64 = 0;
|
|||
pub static mut rdtsc_last_value: u64 = 0;
|
||||
pub static mut tsc_offset: u64 = 0;
|
||||
|
||||
pub static mut tlb_data: [i32; 0x400000] = [0; 0x400000];
|
||||
pub static mut valid_tlb_entries: [i32; 10000] = [0; 10000];
|
||||
pub static mut valid_tlb_entries_count: i32 = 0;
|
||||
|
||||
|
@ -1506,7 +1507,7 @@ pub unsafe fn get_eflags() -> i32 {
|
|||
pub unsafe fn get_eflags_no_arith() -> i32 { return *flags; }
|
||||
|
||||
pub unsafe fn translate_address_read(address: i32) -> OrPageFault<u32> {
|
||||
let entry = *tlb_data.offset((address as u32 >> 12) as isize);
|
||||
let entry = tlb_data[(address as u32 >> 12) as usize];
|
||||
let user = *cpl == 3;
|
||||
if entry & (TLB_VALID | if user { TLB_NO_USER } else { 0 }) == TLB_VALID {
|
||||
Ok((entry & !0xFFF ^ address) as u32)
|
||||
|
@ -1517,7 +1518,7 @@ pub unsafe fn translate_address_read(address: i32) -> OrPageFault<u32> {
|
|||
}
|
||||
|
||||
pub unsafe fn translate_address_read_jit(address: i32) -> OrPageFault<u32> {
|
||||
let entry = *tlb_data.offset((address as u32 >> 12) as isize);
|
||||
let entry = tlb_data[(address as u32 >> 12) as usize];
|
||||
let user = *cpl == 3;
|
||||
if entry & (TLB_VALID | if user { TLB_NO_USER } else { 0 }) == TLB_VALID {
|
||||
Ok((entry & !0xFFF ^ address) as u32)
|
||||
|
@ -1669,7 +1670,7 @@ pub unsafe fn do_page_walk(addr: i32, for_writing: bool, user: bool) -> Result<i
|
|||
global = page_table_entry & PAGE_TABLE_GLOBAL_MASK == PAGE_TABLE_GLOBAL_MASK
|
||||
}
|
||||
}
|
||||
if *tlb_data.offset(page as isize) == 0 {
|
||||
if tlb_data[page as usize] == 0 {
|
||||
if valid_tlb_entries_count == VALID_TLB_ENTRY_MAX {
|
||||
profiler::stat_increment(TLB_FULL);
|
||||
clear_tlb();
|
||||
|
@ -1705,7 +1706,7 @@ pub unsafe fn do_page_walk(addr: i32, for_writing: bool, user: bool) -> Result<i
|
|||
| if global && 0 != *cr.offset(4) & CR4_PGE { TLB_GLOBAL } else { 0 }
|
||||
| if has_code { TLB_HAS_CODE } else { 0 };
|
||||
dbg_assert!((high ^ page << 12) & 0xFFF == 0);
|
||||
*tlb_data.offset(page as isize) = high ^ page << 12 | info_bits;
|
||||
tlb_data[page as usize] = high ^ page << 12 | info_bits;
|
||||
return Ok(high);
|
||||
}
|
||||
|
||||
|
@ -1716,13 +1717,13 @@ pub unsafe fn full_clear_tlb() {
|
|||
*last_virt_eip = -1;
|
||||
for i in 0..valid_tlb_entries_count {
|
||||
let page = valid_tlb_entries[i as usize];
|
||||
*tlb_data.offset(page as isize) = 0;
|
||||
tlb_data[page as usize] = 0;
|
||||
}
|
||||
valid_tlb_entries_count = 0;
|
||||
|
||||
if CHECK_TLB_INVARIANTS {
|
||||
for i in 0..0x100000 {
|
||||
dbg_assert!(*tlb_data.offset(i) == 0);
|
||||
dbg_assert!(tlb_data[i] == 0);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1735,21 +1736,21 @@ pub unsafe fn clear_tlb() {
|
|||
let mut global_page_offset: i32 = 0;
|
||||
for i in 0..valid_tlb_entries_count {
|
||||
let page = valid_tlb_entries[i as usize];
|
||||
let entry = *tlb_data.offset(page as isize);
|
||||
let entry = tlb_data[page as usize];
|
||||
if 0 != entry & TLB_GLOBAL {
|
||||
// reinsert at the front
|
||||
valid_tlb_entries[global_page_offset as usize] = page;
|
||||
global_page_offset += 1;
|
||||
}
|
||||
else {
|
||||
*tlb_data.offset(page as isize) = 0
|
||||
tlb_data[page as usize] = 0
|
||||
}
|
||||
}
|
||||
valid_tlb_entries_count = global_page_offset;
|
||||
|
||||
if CHECK_TLB_INVARIANTS {
|
||||
for i in 0..0x100000 {
|
||||
dbg_assert!(*tlb_data.offset(i) == 0 || 0 != *tlb_data.offset(i) & TLB_GLOBAL);
|
||||
dbg_assert!(tlb_data[i] == 0 || 0 != tlb_data[i] & TLB_GLOBAL);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1792,7 +1793,7 @@ pub unsafe fn trigger_pagefault_jit(fault: PageFault) {
|
|||
*cr.offset(2) = addr;
|
||||
// invalidate tlb entry
|
||||
let page = ((addr as u32) >> 12) as i32;
|
||||
*tlb_data.offset(page as isize) = 0;
|
||||
tlb_data[page as usize] = 0;
|
||||
if DEBUG {
|
||||
if cpu_exception_hook(CPU_EXCEPTION_PF) {
|
||||
return;
|
||||
|
@ -1835,7 +1836,7 @@ pub unsafe fn trigger_pagefault(fault: PageFault) {
|
|||
*cr.offset(2) = addr;
|
||||
// invalidate tlb entry
|
||||
let page = ((addr as u32) >> 12) as i32;
|
||||
*tlb_data.offset(page as isize) = 0;
|
||||
tlb_data[page as usize] = 0;
|
||||
*instruction_pointer = *previous_ip;
|
||||
call_interrupt_vector(
|
||||
CPU_EXCEPTION_PF,
|
||||
|
@ -1845,7 +1846,7 @@ pub unsafe fn trigger_pagefault(fault: PageFault) {
|
|||
}
|
||||
|
||||
pub unsafe fn translate_address_write_and_can_skip_dirty(address: i32) -> OrPageFault<(u32, bool)> {
|
||||
let entry = *tlb_data.offset((address as u32 >> 12) as isize);
|
||||
let entry = tlb_data[(address as u32 >> 12) as usize];
|
||||
let user = *cpl == 3;
|
||||
if entry & (TLB_VALID | if user { TLB_NO_USER } else { 0 } | TLB_READONLY) == TLB_VALID {
|
||||
return Ok(((entry & !0xFFF ^ address) as u32, entry & TLB_HAS_CODE == 0));
|
||||
|
@ -1859,7 +1860,7 @@ pub unsafe fn translate_address_write_and_can_skip_dirty(address: i32) -> OrPage
|
|||
}
|
||||
|
||||
pub unsafe fn translate_address_write(address: i32) -> OrPageFault<u32> {
|
||||
let entry = *tlb_data.offset((address as u32 >> 12) as isize);
|
||||
let entry = tlb_data[(address as u32 >> 12) as usize];
|
||||
let user = *cpl == 3;
|
||||
if entry & (TLB_VALID | if user { TLB_NO_USER } else { 0 } | TLB_READONLY) == TLB_VALID {
|
||||
return Ok((entry & !0xFFF ^ address) as u32);
|
||||
|
@ -1870,7 +1871,7 @@ pub unsafe fn translate_address_write(address: i32) -> OrPageFault<u32> {
|
|||
}
|
||||
|
||||
pub unsafe fn translate_address_write_jit(address: i32) -> OrPageFault<u32> {
|
||||
let entry = *tlb_data.offset((address as u32 >> 12) as isize);
|
||||
let entry = tlb_data[(address as u32 >> 12) as usize];
|
||||
let user = *cpl == 3;
|
||||
if entry & (TLB_VALID | if user { TLB_NO_USER } else { 0 } | TLB_READONLY) == TLB_VALID {
|
||||
Ok((entry & !0xFFF ^ address) as u32)
|
||||
|
@ -1891,12 +1892,12 @@ pub fn tlb_set_has_code(physical_page: Page, has_code: bool) {
|
|||
let physical_page = physical_page.to_u32();
|
||||
for i in 0..unsafe { valid_tlb_entries_count } {
|
||||
let page = unsafe { valid_tlb_entries[i as usize] };
|
||||
let entry = unsafe { *tlb_data.offset(page as isize) };
|
||||
let entry = unsafe { tlb_data[page as usize] };
|
||||
if 0 != entry {
|
||||
let tlb_physical_page = entry as u32 >> 12 ^ page as u32;
|
||||
if physical_page == tlb_physical_page {
|
||||
unsafe {
|
||||
*tlb_data.offset(page as isize) =
|
||||
tlb_data[page as usize] =
|
||||
if has_code { entry | TLB_HAS_CODE } else { entry & !TLB_HAS_CODE }
|
||||
}
|
||||
}
|
||||
|
@ -1914,7 +1915,7 @@ pub fn check_tlb_invariants() {
|
|||
|
||||
for i in 0..unsafe { valid_tlb_entries_count } {
|
||||
let page = unsafe { valid_tlb_entries[i as usize] };
|
||||
let entry = unsafe { *tlb_data.offset(page as isize) };
|
||||
let entry = unsafe { tlb_data[page as usize] };
|
||||
|
||||
if 0 == entry || 0 != entry & TLB_IN_MAPPED_RANGE {
|
||||
// there's no code in mapped memory
|
||||
|
@ -1943,13 +1944,13 @@ pub unsafe fn readable_or_pagefault(addr: i32, size: i32) -> OrPageFault<()> {
|
|||
let mask = TLB_VALID | if user { TLB_NO_USER } else { 0 };
|
||||
let expect = TLB_VALID;
|
||||
let page = (addr as u32 >> 12) as i32;
|
||||
if *tlb_data.offset(page as isize) & mask != expect {
|
||||
if tlb_data[page as usize] & mask != expect {
|
||||
do_page_translation(addr, false, user)?;
|
||||
}
|
||||
let next_page = ((addr + size - 1) as u32 >> 12) as i32;
|
||||
if page != next_page {
|
||||
dbg_assert!(next_page == page + 1);
|
||||
if *tlb_data.offset(next_page as isize) & mask != expect {
|
||||
if tlb_data[next_page as usize] & mask != expect {
|
||||
do_page_translation(next_page << 12, false, user)?;
|
||||
}
|
||||
}
|
||||
|
@ -1967,13 +1968,13 @@ pub unsafe fn writable_or_pagefault(addr: i32, size: i32) -> OrPageFault<()> {
|
|||
let mask = TLB_READONLY | TLB_VALID | if user { TLB_NO_USER } else { 0 };
|
||||
let expect = TLB_VALID;
|
||||
let page = (addr as u32 >> 12) as i32;
|
||||
if *tlb_data.offset(page as isize) & mask != expect {
|
||||
if tlb_data[page as usize] & mask != expect {
|
||||
do_page_translation(addr, true, user)?;
|
||||
}
|
||||
let next_page = ((addr + size - 1) as u32 >> 12) as i32;
|
||||
if page != next_page {
|
||||
dbg_assert!(next_page == page + 1);
|
||||
if *tlb_data.offset(next_page as isize) & mask != expect {
|
||||
if tlb_data[next_page as usize] & mask != expect {
|
||||
do_page_translation(next_page << 12, true, user)?;
|
||||
}
|
||||
}
|
||||
|
@ -3381,7 +3382,7 @@ pub unsafe fn invlpg(addr: i32) {
|
|||
// necessary, because when valid_tlb_entries grows too large, it will be
|
||||
// empties by calling clear_tlb, which removes this entry as it isn't global.
|
||||
// This however means that valid_tlb_entries can contain some invalid entries
|
||||
*tlb_data.offset(page as isize) = 0;
|
||||
tlb_data[page as usize] = 0;
|
||||
*last_virt_eip = -1;
|
||||
}
|
||||
|
||||
|
@ -3428,7 +3429,7 @@ pub unsafe fn get_valid_tlb_entries_count() -> i32 {
|
|||
let mut result: i32 = 0;
|
||||
for i in 0..valid_tlb_entries_count {
|
||||
let page = valid_tlb_entries[i as usize];
|
||||
let entry = *tlb_data.offset(page as isize);
|
||||
let entry = tlb_data[page as usize];
|
||||
if 0 != entry {
|
||||
result += 1
|
||||
}
|
||||
|
@ -3444,7 +3445,7 @@ pub unsafe fn get_valid_global_tlb_entries_count() -> i32 {
|
|||
let mut result: i32 = 0;
|
||||
for i in 0..valid_tlb_entries_count {
|
||||
let page = valid_tlb_entries[i as usize];
|
||||
let entry = *tlb_data.offset(page as isize);
|
||||
let entry = tlb_data[page as usize];
|
||||
if 0 != entry & TLB_GLOBAL {
|
||||
result += 1
|
||||
}
|
||||
|
@ -3453,7 +3454,7 @@ pub unsafe fn get_valid_global_tlb_entries_count() -> i32 {
|
|||
}
|
||||
|
||||
pub unsafe fn translate_address_system_read(address: i32) -> OrPageFault<u32> {
|
||||
let entry = *tlb_data.offset((address as u32 >> 12) as isize);
|
||||
let entry = tlb_data[(address as u32 >> 12) as usize];
|
||||
if 0 != entry & TLB_VALID {
|
||||
return Ok((entry & !0xFFF ^ address) as u32);
|
||||
}
|
||||
|
@ -3463,7 +3464,7 @@ pub unsafe fn translate_address_system_read(address: i32) -> OrPageFault<u32> {
|
|||
}
|
||||
|
||||
pub unsafe fn translate_address_system_write(address: i32) -> OrPageFault<u32> {
|
||||
let entry = *tlb_data.offset((address as u32 >> 12) as isize);
|
||||
let entry = tlb_data[(address as u32 >> 12) as usize];
|
||||
if entry & (TLB_VALID | TLB_READONLY) == TLB_VALID {
|
||||
return Ok((entry & !0xFFF ^ address) as u32);
|
||||
}
|
||||
|
|
|
@ -70,7 +70,6 @@ pub const opstats_compiled_buffer: *mut u32 = 0x10000 as *mut u32;
|
|||
pub const opstats_jit_exit_buffer: *mut u32 = 0x18000 as *mut u32;
|
||||
pub const opstats_unguarded_register_buffer: *mut u32 = 0x20000 as *mut u32;
|
||||
pub const opstats_wasm_size: *mut u32 = 0x28000 as *mut u32;
|
||||
pub const tlb_data: *mut i32 = 0x400000 as *mut i32;
|
||||
|
||||
pub fn get_reg32_offset(r: u32) -> u32 {
|
||||
dbg_assert!(r < 8);
|
||||
|
|
Loading…
Reference in a new issue