mirror of
https://github.com/copy/v86.git
synced 2026-01-06 15:31:59 +00:00
Make tsc_offset 64-bit integer, save and restore it correctly
This commit is contained in:
parent
27b0ab71b1
commit
2b75cff787
5 changed files with 30 additions and 15 deletions
13
src/cpu.js
13
src/cpu.js
|
|
@ -148,7 +148,8 @@ function CPU(bus, wm, codegen, coverage_logger)
|
|||
this.mul32_result = new Int32Array(wm.memory.buffer, 544, 2);
|
||||
this.div32_result = new Float64Array(2);
|
||||
|
||||
this.tsc_offset = new Int32Array(wm.memory.buffer, 652, 1);
|
||||
this.tsc_offset = new Uint32Array(wm.memory.buffer, 544, 2); // 64 bit
|
||||
this.current_tsc = new Uint32Array(wm.memory.buffer, 956, 2); // 64 bit
|
||||
|
||||
this.phys_addr = new Int32Array(wm.memory.buffer, 656, 1);
|
||||
|
||||
|
|
@ -240,7 +241,7 @@ function CPU(bus, wm, codegen, coverage_logger)
|
|||
|
||||
this.update_operand_size();
|
||||
|
||||
this.tsc_offset[0] = v86.microtick();
|
||||
wm.exports["_set_tsc"](0, 0);
|
||||
|
||||
this.debug_init();
|
||||
|
||||
|
|
@ -369,6 +370,9 @@ CPU.prototype.get_state = function()
|
|||
state[41] = this.dreg;
|
||||
state[42] = this.mem8;
|
||||
|
||||
this.wm.exports["_store_current_tsc"]();
|
||||
state[43] = this.current_tsc;
|
||||
|
||||
state[45] = this.devices.virtio;
|
||||
state[46] = this.devices.apic;
|
||||
state[47] = this.devices.rtc;
|
||||
|
|
@ -453,6 +457,8 @@ CPU.prototype.set_state = function(state)
|
|||
this.dreg.set(state[41]);
|
||||
this.mem8.set(state[42]);
|
||||
|
||||
this.wm.exports["_set_tsc"](state[43][0], state[43][1]);
|
||||
|
||||
this.devices.virtio = state[45];
|
||||
this.devices.apic = state[46];
|
||||
this.devices.rtc = state[47];
|
||||
|
|
@ -491,7 +497,6 @@ CPU.prototype.set_state = function(state)
|
|||
this.fpu_opcode[0] = state[75];
|
||||
|
||||
this.full_clear_tlb();
|
||||
// tsc_offset?
|
||||
|
||||
this.update_operand_size();
|
||||
};
|
||||
|
|
@ -628,7 +633,7 @@ CPU.prototype.reset = function()
|
|||
this.last_op2.fill(0);
|
||||
this.last_op_size.fill(0);
|
||||
|
||||
this.tsc_offset[0] = v86.microtick();
|
||||
this.wm.exports["_set_tsc"](0, 0);
|
||||
|
||||
this.instruction_pointer[0] = 0xFFFF0;
|
||||
this.switch_cs_real_mode(0xF000);
|
||||
|
|
|
|||
|
|
@ -1241,9 +1241,20 @@ int32_t decr_ecx_asize()
|
|||
return is_asize_32() ? --reg32s[ECX] : --reg16[CX];
|
||||
}
|
||||
|
||||
void set_tsc(uint32_t low, uint32_t high)
|
||||
{
|
||||
uint64_t new_value = low | (uint64_t)high << 32;
|
||||
uint64_t current_value = read_tsc();
|
||||
*tsc_offset = current_value - new_value;
|
||||
}
|
||||
|
||||
uint64_t read_tsc()
|
||||
{
|
||||
double_t n = microtick() - tsc_offset[0]; // XXX: float
|
||||
n = n * TSC_RATE;
|
||||
return n;
|
||||
double_t n = microtick() * TSC_RATE;
|
||||
return (uint64_t)n - *tsc_offset;
|
||||
}
|
||||
|
||||
void store_current_tsc()
|
||||
{
|
||||
*current_tsc = read_tsc();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ int32_t get_reg_asize(int32_t reg);
|
|||
void set_ecx_asize(int32_t value);
|
||||
void add_reg_asize(int32_t reg, int32_t value);
|
||||
int32_t decr_ecx_asize(void);
|
||||
void set_tsc(uint32_t, uint32_t);
|
||||
uint64_t read_tsc(void);
|
||||
bool vm86_mode(void);
|
||||
int32_t getiopl(void);
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ static int32_t* const flags = (int32_t* const) 536;
|
|||
|
||||
static bool* const page_fault = (bool* const) 540;
|
||||
|
||||
// gap 12
|
||||
static uint64_t* const tsc_offset = (uint64_t* const) 544;
|
||||
|
||||
static bool* const a20_enabled = (bool* const) 552;
|
||||
static int32_t* const instruction_pointer = (int32_t* const) 556;
|
||||
|
|
@ -45,7 +45,7 @@ static int32_t* const sysenter_cs = (int32_t* const) 636;
|
|||
static int32_t* const sysenter_esp = (int32_t* const) 640;
|
||||
static int32_t* const sysenter_eip = (int32_t* const) 644;
|
||||
static uint8_t* const prefixes = (uint8_t* const) 648;
|
||||
static int32_t* const tsc_offset = (int32_t* const) 652;
|
||||
// gap
|
||||
static int32_t* const phys_addr = (int32_t* const) 656;
|
||||
static int32_t* const phys_addr_high = (int32_t* const) 660;
|
||||
static uint32_t* const timestamp_counter = (uint32_t* const) 664;
|
||||
|
|
@ -69,6 +69,8 @@ static int32_t* const mxcsr = (int32_t* const) 824;
|
|||
|
||||
static union reg128* const reg_xmm = (union reg128* const) 828; // length 128
|
||||
|
||||
static uint64_t* const current_tsc = (uint64_t* const) 956;
|
||||
|
||||
static uint8_t* const codegen_buffers = (uint8_t* const) 2048; // length 2048
|
||||
|
||||
static uint8_t* const tlb_info = (uint8_t* const) 4096; // length 0x100000
|
||||
|
|
|
|||
|
|
@ -736,10 +736,7 @@ void instr_0F30() {
|
|||
break;
|
||||
|
||||
case IA32_TIME_STAMP_COUNTER:
|
||||
{
|
||||
uint64_t new_tick = (low) + 0x100000000 * (high);
|
||||
tsc_offset[0] = microtick() - new_tick / TSC_RATE; // XXX: float
|
||||
}
|
||||
set_tsc(low, high);
|
||||
break;
|
||||
|
||||
case IA32_BIOS_SIGN_ID:
|
||||
|
|
@ -768,13 +765,12 @@ void instr_0F31() {
|
|||
|
||||
if(!cpl[0] || !(cr[4] & CR4_TSD))
|
||||
{
|
||||
//dbg_assert(isFinite(n), "non-finite tsc: " + n);
|
||||
uint64_t tsc = read_tsc();
|
||||
|
||||
reg32s[EAX] = tsc;
|
||||
reg32s[EDX] = tsc >> 32;
|
||||
|
||||
//dbg_log("rdtsc edx:eax=" + h(reg32[EDX], 8) + ":" + h(reg32[EAX], 8));
|
||||
//dbg_log("rdtsc edx:eax=%x:%x", reg32s[EDX], reg32s[EAX]);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue