cpu: Port get_tss_stack_addr to Rust

This commit is contained in:
Amaan Cheval 2018-09-25 13:12:00 +05:30 committed by Fabian
parent de8411f184
commit 0bf4e4faf6
4 changed files with 39 additions and 42 deletions

View file

@ -260,7 +260,6 @@ function V86Starter(options)
cpu.do_task_switch(selector, has_error_code, error_code);
},
// XXX: Port to Rust
"get_tss_stack_addr": (dpl) => cpu.get_tss_stack_addr(dpl),
"switch_cs_real_mode": (selector) => cpu.switch_cs_real_mode(selector),
};

View file

@ -306,6 +306,7 @@ CPU.prototype.wasm_patch = function(wm)
this.trigger_ss = get_import("trigger_ss");
this.call_interrupt_vector = get_import("call_interrupt_vector_js");
this.get_tss_stack_addr = get_import("get_tss_stack_addr_js");
this.do_many_cycles_native = get_import("do_many_cycles_native");
this.cycle_internal = get_import("cycle_internal");
@ -2281,42 +2282,6 @@ CPU.prototype.far_jump = function(eip, selector, is_call)
CPU_LOG_VERBOSE && this.debug.dump_state("far " + ["jump", "call"][+is_call] + " end");
};
CPU.prototype.get_tss_stack_addr = function(dpl)
{
if(this.tss_size_32[0])
{
var tss_stack_addr = (dpl << 3) + 4 | 0;
if((tss_stack_addr + 5 | 0) > this.segment_limits[reg_tr])
{
throw this.debug.unimpl("#TS handler");
}
tss_stack_addr = tss_stack_addr + this.segment_offsets[reg_tr] | 0;
dbg_assert((tss_stack_addr & 0xFFF) <= 0x1000 - 6);
}
else
{
var tss_stack_addr = (dpl << 2) + 2 | 0;
if((tss_stack_addr + 5 | 0) > this.segment_limits[reg_tr])
{
throw this.debug.unimpl("#TS handler");
}
tss_stack_addr = tss_stack_addr + this.segment_offsets[reg_tr] | 0;
dbg_assert((tss_stack_addr & 0xFFF) <= 0x1000 - 4);
}
if(this.cr[0] & CR0_PG)
{
tss_stack_addr = this.translate_address_system_read(tss_stack_addr);
}
return tss_stack_addr;
};
CPU.prototype.do_task_switch = function(selector, has_error_code, error_code)
{
dbg_assert(this.tss_size_32[0], "TODO");

View file

@ -6,8 +6,6 @@ extern "C" {
#[no_mangle]
fn do_task_switch(selector: i32, has_error_code: bool, error_code: i32);
#[no_mangle]
fn get_tss_stack_addr(dpl: u8) -> u32;
#[no_mangle]
fn switch_cs_real_mode(selector: i32);
#[no_mangle]
fn dbg_trace();
@ -385,6 +383,36 @@ pub unsafe fn call_interrupt_vector_js(
call_interrupt_vector(interrupt_nr, is_software_int, ec);
}
pub unsafe fn get_tss_stack_addr(dpl: u8) -> OrPageFault<u32> {
let mut tss_stack_addr: u32;
if *tss_size_32 {
tss_stack_addr = ((dpl << 3) + 4) as u32;
if tss_stack_addr + 5 > *segment_limits.offset(TR as isize) {
panic!("#TS handler");
}
tss_stack_addr = tss_stack_addr + *segment_offsets.offset(TR as isize) as u32;
dbg_assert!(tss_stack_addr & 0xFFF <= 0x1000 - 6);
}
else {
tss_stack_addr = ((dpl << 2) + 2) as u32;
if tss_stack_addr + 5 > *segment_limits.offset(TR as isize) {
panic!("#TS handler");
}
tss_stack_addr = tss_stack_addr + *segment_offsets.offset(TR as isize) as u32;
dbg_assert!(tss_stack_addr & 0xFFF <= 0x1000 - 4);
}
tss_stack_addr = translate_address_system_read(tss_stack_addr as i32)?;
Ok(tss_stack_addr)
}
pub unsafe fn call_interrupt_vector(
interrupt_nr: i32,
is_software_int: bool,
@ -505,7 +533,8 @@ pub unsafe fn call_interrupt_vector(
panic!("Unimplemented: #GP handler for non-0 cs segment dpl when in vm86 mode");
}
let tss_stack_addr = get_tss_stack_addr(cs_segment_descriptor.dpl());
let tss_stack_addr =
return_on_pagefault!(get_tss_stack_addr(cs_segment_descriptor.dpl()));
let new_esp = read32s(tss_stack_addr);
let new_ss = read16(tss_stack_addr + if *tss_size_32 { 4 } else { 2 });

View file

@ -1,6 +1,7 @@
use cpu2::cpu::{
safe_read16, safe_read32s, safe_write16, safe_write32, translate_address_read,
translate_address_system_read, translate_address_system_write, writable_or_pagefault,
get_tss_stack_addr, safe_read16, safe_read32s, safe_write16, safe_write32,
translate_address_read, translate_address_system_read, translate_address_system_write,
writable_or_pagefault,
};
use cpu2::misc_instr::{push16, push32};
@ -35,3 +36,6 @@ pub unsafe fn push16_js(value: i32) { push16(value).unwrap() }
#[no_mangle]
pub unsafe fn push32_js(value: i32) { push32(value).unwrap() }
#[no_mangle]
pub unsafe fn get_tss_stack_addr_js(dpl: u8) -> u32 { get_tss_stack_addr(dpl).unwrap() }