Implement x86 debug registers
This commit is contained in:
@@ -240,6 +240,7 @@ exec386_2386(int32_t cycs)
|
||||
cycdiff = 0;
|
||||
oldcyc = cycles;
|
||||
while (cycdiff < cycle_period) {
|
||||
int ins_fetch_fault = 0;
|
||||
ins_cycles = cycles;
|
||||
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
@@ -259,6 +260,14 @@ exec386_2386(int32_t cycs)
|
||||
fetchdat = fastreadl_fetch(cs + cpu_state.pc);
|
||||
ol = opcode_length[fetchdat & 0xff];
|
||||
CHECK_READ_CS(MIN(ol, 4));
|
||||
ins_fetch_fault = cpu_386_check_instruction_fault();
|
||||
|
||||
if (!cpu_state.abrt && ins_fetch_fault) {
|
||||
x86gen();
|
||||
ins_fetch_fault = 0;
|
||||
/* No instructions executed at this point. */
|
||||
goto block_ended;
|
||||
}
|
||||
|
||||
if (!cpu_state.abrt) {
|
||||
#ifdef ENABLE_386_LOG
|
||||
@@ -287,6 +296,7 @@ exec386_2386(int32_t cycs)
|
||||
if (cpu_end_block_after_ins)
|
||||
cpu_end_block_after_ins--;
|
||||
|
||||
block_ended:
|
||||
if (cpu_state.abrt) {
|
||||
flags_rebuild();
|
||||
tempi = cpu_state.abrt & ABRT_MASK;
|
||||
@@ -309,9 +319,12 @@ exec386_2386(int32_t cycs)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (!x86_was_reset && ins_fetch_fault)
|
||||
x86gen(); /* This is supposed to be the first one serviced by the processor according to the manual. */
|
||||
} else if (trap) {
|
||||
flags_rebuild();
|
||||
dr[6] |= (trap == 2) ? 0x8000 : 0x4000;
|
||||
if (trap != 4)
|
||||
dr[6] |= (trap == 2) ? 0x8000 : 0x4000;
|
||||
trap = 0;
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
oldcs = CS;
|
||||
|
@@ -80,6 +80,7 @@ int smm_in_hlt = 0;
|
||||
int smi_block = 0;
|
||||
|
||||
int prefetch_prefixes = 0;
|
||||
int rf_flag_no_clear = 0;
|
||||
|
||||
int tempc;
|
||||
int oldcpl;
|
||||
@@ -1655,6 +1656,38 @@ cpu_386_flags_rebuild(void)
|
||||
flags_rebuild();
|
||||
}
|
||||
|
||||
int
|
||||
cpu_386_check_instruction_fault(void)
|
||||
{
|
||||
int i = 0;
|
||||
int fault = 0;
|
||||
/* Report no fault if RF is set. */
|
||||
if (cpu_state.eflags & RF_FLAG)
|
||||
return 0;
|
||||
|
||||
/* Make sure breakpoints are enabled. */
|
||||
if (!(dr[7] & 0xFF))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
int breakpoint_enabled = !!(dr[7] & (0x3 << (2 * i))) && !(dr[7] & (0x30000 << (4 * i)));
|
||||
uint64_t translated_addr = 0xffffffffffffffffULL;
|
||||
if (!breakpoint_enabled)
|
||||
continue;
|
||||
if (!(cr0 >> 31))
|
||||
translated_addr = dr[i];
|
||||
else
|
||||
translated_addr = mmutranslate_noabrt(dr[i], 0);
|
||||
|
||||
if ((cs + cpu_state.pc) == translated_addr) {
|
||||
dr[6] |= (1 << i);
|
||||
fault = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
|
||||
int
|
||||
sysenter(uint32_t fetchdat)
|
||||
{
|
||||
|
@@ -50,80 +50,80 @@
|
||||
# define do_mmut_ww(s, a, b) do_mmutranslate_2386((s) + (a), b, 2, 1)
|
||||
# define do_mmut_wl(s, a, b) do_mmutranslate_2386((s) + (a), b, 4, 1)
|
||||
#else
|
||||
# define readmemb_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl_no_mmut((s) + (a), b) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))))
|
||||
# define readmemw_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl_no_mmut((s) + (a), b) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a))))
|
||||
# define readmeml_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll_no_mmut((s) + (a), b) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a))))
|
||||
# define readmemb(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl((s) + (a)) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))))
|
||||
# define readmemw(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl((s) + (a)) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a))))
|
||||
# define readmeml(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll((s) + (a)) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a))))
|
||||
# define readmemq(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) ? readmemql((s) + (a)) : *(uint64_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))))
|
||||
# define readmemb_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) ? readmembl_no_mmut((s) + (a), b) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))))
|
||||
# define readmemw_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF) || (((s) + (a)) & 1)) ? readmemwl_no_mmut((s) + (a), b) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a))))
|
||||
# define readmeml_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF) || (((s) + (a)) & 3)) ? readmemll_no_mmut((s) + (a), b) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a))))
|
||||
# define readmemb(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) ? readmembl((s) + (a)) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))))
|
||||
# define readmemw(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF) || (((s) + (a)) & 1)) ? readmemwl((s) + (a)) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a))))
|
||||
# define readmeml(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF) || (((s) + (a)) & 3)) ? readmemll((s) + (a)) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a))))
|
||||
# define readmemq(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF) || (((s) + (a)) & 7)) ? readmemql((s) + (a)) : *(uint64_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))))
|
||||
|
||||
# define writememb_n(s, a, b, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \
|
||||
writemembl_no_mmut((s) + (a), b, v); \
|
||||
else \
|
||||
# define writememb_n(s, a, b, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) \
|
||||
writemembl_no_mmut((s) + (a), b, v); \
|
||||
else \
|
||||
*(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
# define writememw_n(s, a, b, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \
|
||||
writememwl_no_mmut((s) + (a), b, v); \
|
||||
else \
|
||||
# define writememw_n(s, a, b, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1) || (dr[7] & 0xFF)) \
|
||||
writememwl_no_mmut((s) + (a), b, v); \
|
||||
else \
|
||||
*(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
# define writememl_n(s, a, b, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \
|
||||
writememll_no_mmut((s) + (a), b, v); \
|
||||
else \
|
||||
# define writememl_n(s, a, b, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3) || (dr[7] & 0xFF)) \
|
||||
writememll_no_mmut((s) + (a), b, v); \
|
||||
else \
|
||||
*(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
# define writememb(s, a, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \
|
||||
writemembl((s) + (a), v); \
|
||||
else \
|
||||
# define writememb(s, a, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) \
|
||||
writemembl((s) + (a), v); \
|
||||
else \
|
||||
*(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
# define writememw(s, a, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \
|
||||
writememwl((s) + (a), v); \
|
||||
else \
|
||||
# define writememw(s, a, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1) || (dr[7] & 0xFF)) \
|
||||
writememwl((s) + (a), v); \
|
||||
else \
|
||||
*(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
# define writememl(s, a, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \
|
||||
writememll((s) + (a), v); \
|
||||
else \
|
||||
# define writememl(s, a, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3) || (dr[7] & 0xFF)) \
|
||||
writememll((s) + (a), v); \
|
||||
else \
|
||||
*(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
# define writememq(s, a, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) \
|
||||
writememql((s) + (a), v); \
|
||||
else \
|
||||
# define writememq(s, a, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7) || (dr[7] & 0xFF)) \
|
||||
writememql((s) + (a), v); \
|
||||
else \
|
||||
*(uint64_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
|
||||
# define do_mmut_rb(s, a, b) \
|
||||
if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \
|
||||
# define do_mmut_rb(s, a, b) \
|
||||
if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) \
|
||||
do_mmutranslate((s) + (a), b, 1, 0)
|
||||
# define do_mmut_rw(s, a, b) \
|
||||
if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \
|
||||
# define do_mmut_rw(s, a, b) \
|
||||
if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1) || (dr[7] & 0xFF)) \
|
||||
do_mmutranslate((s) + (a), b, 2, 0)
|
||||
# define do_mmut_rl(s, a, b) \
|
||||
if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \
|
||||
# define do_mmut_rl(s, a, b) \
|
||||
if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3) || (dr[7] & 0xFF)) \
|
||||
do_mmutranslate((s) + (a), b, 4, 0)
|
||||
# define do_mmut_rb2(s, a, b) \
|
||||
old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \
|
||||
if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \
|
||||
# define do_mmut_rb2(s, a, b) \
|
||||
old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \
|
||||
if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) \
|
||||
do_mmutranslate((s) + (a), b, 1, 0)
|
||||
# define do_mmut_rw2(s, a, b) \
|
||||
old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \
|
||||
if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \
|
||||
# define do_mmut_rw2(s, a, b) \
|
||||
old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \
|
||||
if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1) || (dr[7] & 0xFF)) \
|
||||
do_mmutranslate((s) + (a), b, 2, 0)
|
||||
# define do_mmut_rl2(s, a, b) \
|
||||
old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \
|
||||
if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \
|
||||
# define do_mmut_rl2(s, a, b) \
|
||||
old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \
|
||||
if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3) || (dr[7] & 0xFF)) \
|
||||
do_mmutranslate((s) + (a), b, 4, 0)
|
||||
|
||||
# define do_mmut_wb(s, a, b) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \
|
||||
# define do_mmut_wb(s, a, b) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (dr[7] & 0xFF)) \
|
||||
do_mmutranslate((s) + (a), b, 1, 1)
|
||||
# define do_mmut_ww(s, a, b) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \
|
||||
# define do_mmut_ww(s, a, b) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1) || (dr[7] & 0xFF)) \
|
||||
do_mmutranslate((s) + (a), b, 2, 1)
|
||||
# define do_mmut_wl(s, a, b) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \
|
||||
# define do_mmut_wl(s, a, b) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3) || (dr[7] & 0xFF)) \
|
||||
do_mmutranslate((s) + (a), b, 4, 1)
|
||||
#endif
|
||||
|
||||
@@ -674,3 +674,8 @@ seteaq(uint64_t v)
|
||||
cpu_state.pc += 2
|
||||
|
||||
#endif
|
||||
|
||||
/* Resume Flag handling. */
|
||||
extern int rf_flag_no_clear;
|
||||
|
||||
int cpu_386_check_instruction_fault(void);
|
@@ -223,7 +223,7 @@ fetch_ea_16_long(uint32_t rmdat)
|
||||
|
||||
#include "386_ops.h"
|
||||
|
||||
#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG))
|
||||
#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG) && !(dr[7] & 0xFF))
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
int32_t cycles_main = 0;
|
||||
@@ -285,6 +285,11 @@ exec386_dynarec_int(void)
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
cpu_state.ssegs = 0;
|
||||
|
||||
if (UNLIKELY(cpu_386_check_instruction_fault())) {
|
||||
x86gen();
|
||||
goto block_ended;
|
||||
}
|
||||
|
||||
fetchdat = fastreadl_fetch(cs + cpu_state.pc);
|
||||
# ifdef ENABLE_386_DYNAREC_LOG
|
||||
if (in_smm)
|
||||
@@ -306,6 +311,14 @@ exec386_dynarec_int(void)
|
||||
cpu_state.pc &= 0xffff;
|
||||
# endif
|
||||
|
||||
if (!cpu_state.abrt) {
|
||||
if (!rf_flag_no_clear) {
|
||||
cpu_state.eflags &= ~RF_FLAG;
|
||||
}
|
||||
|
||||
rf_flag_no_clear = 0;
|
||||
}
|
||||
|
||||
if (((cs + cpu_state.pc) >> 12) != pccache)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
@@ -329,7 +342,8 @@ exec386_dynarec_int(void)
|
||||
|
||||
block_ended:
|
||||
if (!cpu_state.abrt && trap) {
|
||||
dr[6] |= (trap == 2) ? 0x8000 : 0x4000;
|
||||
if (trap != 4)
|
||||
dr[6] |= (trap == 2) ? 0x8000 : 0x4000;
|
||||
trap = 0;
|
||||
# ifndef USE_NEW_DYNAREC
|
||||
oldcs = CS;
|
||||
|
@@ -178,6 +178,7 @@ opPOPF_186(uint32_t fetchdat)
|
||||
else
|
||||
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
flags_extract();
|
||||
rf_flag_no_clear = 1;
|
||||
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0);
|
||||
@@ -211,6 +212,7 @@ opPOPF_286(uint32_t fetchdat)
|
||||
else
|
||||
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
flags_extract();
|
||||
rf_flag_no_clear = 1;
|
||||
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0);
|
||||
@@ -264,6 +266,7 @@ opPOPF(uint32_t fetchdat)
|
||||
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
}
|
||||
flags_extract();
|
||||
rf_flag_no_clear = 1;
|
||||
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0);
|
||||
@@ -307,6 +310,7 @@ opPOPFD(uint32_t fetchdat)
|
||||
cpu_state.eflags = (templ >> 16) & 3;
|
||||
|
||||
flags_extract();
|
||||
rf_flag_no_clear = 1;
|
||||
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 0);
|
||||
|
@@ -87,6 +87,12 @@ opMOV_r_DRx_a16(uint32_t fetchdat)
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_reg == 4 || cpu_reg == 5) {
|
||||
if (cr4 & 0x8)
|
||||
x86illegal();
|
||||
else
|
||||
cpu_reg += 2;
|
||||
}
|
||||
cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0);
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
|
||||
@@ -100,6 +106,12 @@ opMOV_r_DRx_a32(uint32_t fetchdat)
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_reg == 4 || cpu_reg == 5) {
|
||||
if (cr4 & 0x8)
|
||||
x86illegal();
|
||||
else
|
||||
cpu_reg += 2;
|
||||
}
|
||||
cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0);
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
|
||||
@@ -228,10 +240,23 @@ opMOV_DRx_r_a16(uint32_t fetchdat)
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if ((dr[6] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) {
|
||||
dr[7] |= 0x2000;
|
||||
dr[6] &= ~0x2000;
|
||||
x86gen();
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_reg == 4 || cpu_reg == 5) {
|
||||
if (cr4 & 0x8)
|
||||
x86illegal();
|
||||
else
|
||||
cpu_reg += 2;
|
||||
}
|
||||
dr[cpu_reg] = cpu_state.regs[cpu_rm].l;
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
|
||||
CPU_BLOCK_END();
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
@@ -242,9 +267,16 @@ opMOV_DRx_r_a32(uint32_t fetchdat)
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_reg == 4 || cpu_reg == 5) {
|
||||
if (cr4 & 0x8)
|
||||
x86illegal();
|
||||
else
|
||||
cpu_reg += 2;
|
||||
}
|
||||
dr[cpu_reg] = cpu_state.regs[cpu_rm].l;
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
|
||||
CPU_BLOCK_END();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -135,6 +135,7 @@ opIRET_186(uint32_t fetchdat)
|
||||
}
|
||||
flags_extract();
|
||||
nmi_enable = 1;
|
||||
rf_flag_no_clear = 1;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0);
|
||||
@@ -175,6 +176,7 @@ opIRET_286(uint32_t fetchdat)
|
||||
}
|
||||
flags_extract();
|
||||
nmi_enable = 1;
|
||||
rf_flag_no_clear = 1;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0);
|
||||
@@ -243,6 +245,7 @@ opIRET(uint32_t fetchdat)
|
||||
}
|
||||
flags_extract();
|
||||
nmi_enable = 1;
|
||||
rf_flag_no_clear = 1;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0);
|
||||
@@ -285,6 +288,7 @@ opIRETD(uint32_t fetchdat)
|
||||
}
|
||||
flags_extract();
|
||||
nmi_enable = 1;
|
||||
rf_flag_no_clear = 1;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1);
|
||||
|
@@ -2286,6 +2286,8 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
op_loadseg(new_fs, &cpu_state.seg_fs);
|
||||
op_loadseg(new_gs, &cpu_state.seg_gs);
|
||||
|
||||
rf_flag_no_clear = 1;
|
||||
|
||||
if (t_bit) {
|
||||
trap = 2;
|
||||
#ifdef USE_DYNAREC
|
||||
|
@@ -87,6 +87,12 @@ x86de(UNUSED(char *s), UNUSED(uint16_t error))
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
x86gen(void)
|
||||
{
|
||||
x86_int(1);
|
||||
}
|
||||
|
||||
void
|
||||
x86gpf(UNUSED(char *s), uint16_t error)
|
||||
{
|
||||
|
@@ -41,6 +41,7 @@ extern int cgate32;
|
||||
extern int intgatesize;
|
||||
|
||||
extern void x86seg_reset(void);
|
||||
extern void x86gen(void);
|
||||
extern void x86de(char *s, uint16_t error);
|
||||
extern void x86gpf(char *s, uint16_t error);
|
||||
extern void x86gpf_expected(char *s, uint16_t error);
|
||||
|
@@ -439,6 +439,8 @@ extern void mem_reset_page_blocks(void);
|
||||
extern void flushmmucache(void);
|
||||
extern void flushmmucache_nopc(void);
|
||||
|
||||
extern void mem_debug_check_addr(uint32_t addr, int write);
|
||||
|
||||
extern void mem_a20_init(void);
|
||||
extern void mem_a20_recalc(void);
|
||||
|
||||
|
65
src/io.c
65
src/io.c
@@ -279,6 +279,59 @@ io_handler_interleaved(int set, uint16_t base, int size,
|
||||
io_handler_common(set, base, size, inb, inw, inl, outb, outw, outl, priv, 2);
|
||||
}
|
||||
|
||||
extern int trap;
|
||||
/* Set trap for I/O address breakpoints. */
|
||||
void
|
||||
io_debug_check_addr(uint16_t addr)
|
||||
{
|
||||
int i = 0;
|
||||
int set_trap = 0;
|
||||
|
||||
if (trap == 4)
|
||||
return; /* Debug trap already pending. */
|
||||
|
||||
if (!(dr[7] & 0xFF))
|
||||
return;
|
||||
|
||||
if (!(cr4 & 0x8))
|
||||
return; /* No I/O debug trap. */
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
uint16_t dr_addr = dr[i] & 0xFFFF;
|
||||
int breakpoint_enabled = !!(dr[7] & (0x3 << (2 * i)));
|
||||
int len_type_pair = ((dr[7] >> 16) & (0xF << (4 * i))) >> (4 * i);
|
||||
if (!breakpoint_enabled)
|
||||
continue;
|
||||
if ((len_type_pair & 3) != 2)
|
||||
continue;
|
||||
|
||||
switch ((len_type_pair >> 2) & 3)
|
||||
{
|
||||
case 0x00:
|
||||
if (dr_addr == addr) {
|
||||
set_trap = 1;
|
||||
dr[6] |= (1 << i);
|
||||
}
|
||||
break;
|
||||
case 0x01:
|
||||
if ((dr_addr & ~1) == addr || ((dr_addr & ~1) + 1) == (addr + 1)) {
|
||||
set_trap = 1;
|
||||
dr[6] |= (1 << i);
|
||||
}
|
||||
break;
|
||||
case 0x03:
|
||||
dr_addr &= ~3;
|
||||
if (addr >= dr_addr && addr < (dr_addr + 4)) {
|
||||
set_trap = 1;
|
||||
dr[6] |= (1 << i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (set_trap)
|
||||
trap = 4;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
inb(uint16_t port)
|
||||
{
|
||||
@@ -290,6 +343,8 @@ inb(uint16_t port)
|
||||
int qfound = 0;
|
||||
#endif
|
||||
|
||||
io_debug_check_addr(port);
|
||||
|
||||
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
ret = pci_read(port, NULL);
|
||||
found = 1;
|
||||
@@ -350,6 +405,8 @@ outb(uint16_t port, uint8_t val)
|
||||
int qfound = 0;
|
||||
#endif
|
||||
|
||||
io_debug_check_addr(port);
|
||||
|
||||
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
pci_write(port, val, NULL);
|
||||
found = 1;
|
||||
@@ -402,6 +459,8 @@ inw(uint16_t port)
|
||||
#endif
|
||||
uint8_t ret8[2];
|
||||
|
||||
io_debug_check_addr(port);
|
||||
|
||||
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
ret = pci_readw(port, NULL);
|
||||
found = 2;
|
||||
@@ -474,6 +533,8 @@ outw(uint16_t port, uint16_t val)
|
||||
int qfound = 0;
|
||||
#endif
|
||||
|
||||
io_debug_check_addr(port);
|
||||
|
||||
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
pci_writew(port, val, NULL);
|
||||
found = 2;
|
||||
@@ -542,6 +603,8 @@ inl(uint16_t port)
|
||||
int qfound = 0;
|
||||
#endif
|
||||
|
||||
io_debug_check_addr(port);
|
||||
|
||||
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
ret = pci_readl(port, NULL);
|
||||
found = 4;
|
||||
@@ -646,6 +709,8 @@ outl(uint16_t port, uint32_t val)
|
||||
#endif
|
||||
int i = 0;
|
||||
|
||||
io_debug_check_addr(port);
|
||||
|
||||
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
|
||||
pci_writel(port, val, NULL);
|
||||
found = 4;
|
||||
|
@@ -161,6 +161,57 @@ mem_log(const char *fmt, ...)
|
||||
# define mem_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
/* Set trap for data address breakpoints. */
|
||||
void
|
||||
mem_debug_check_addr(uint32_t addr, int write)
|
||||
{
|
||||
int i = 0;
|
||||
int set_trap = 0;
|
||||
|
||||
if (trap == 4)
|
||||
return; /* Debug trap already pending. */
|
||||
|
||||
if (!(dr[7] & 0xFF))
|
||||
return;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
uint32_t dr_addr = dr[i];
|
||||
int breakpoint_enabled = !!(dr[7] & (0x3 << (2 * i)));
|
||||
int len_type_pair = ((dr[7] >> 16) & (0xF << (4 * i))) >> (4 * i);
|
||||
if (!breakpoint_enabled)
|
||||
continue;
|
||||
if (!write && (len_type_pair & 3) != 3)
|
||||
continue;
|
||||
if ((len_type_pair & 3) != 1)
|
||||
continue;
|
||||
|
||||
switch ((len_type_pair >> 2) & 3)
|
||||
{
|
||||
case 0x00:
|
||||
if (dr_addr == addr) {
|
||||
set_trap = 1;
|
||||
dr[6] |= (1 << i);
|
||||
}
|
||||
break;
|
||||
case 0x01:
|
||||
if ((dr_addr & ~1) == addr || ((dr_addr & ~1) + 1) == (addr + 1)) {
|
||||
set_trap = 1;
|
||||
dr[6] |= (1 << i);
|
||||
}
|
||||
break;
|
||||
case 0x03:
|
||||
dr_addr &= ~3;
|
||||
if (addr >= dr_addr && addr < (dr_addr + 4)) {
|
||||
set_trap = 1;
|
||||
dr[6] |= (1 << i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (set_trap)
|
||||
trap = 4;
|
||||
}
|
||||
|
||||
int
|
||||
mem_addr_is_ram(uint32_t addr)
|
||||
{
|
||||
@@ -790,6 +841,7 @@ readmembl(uint32_t addr)
|
||||
uint64_t a;
|
||||
|
||||
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1);
|
||||
mem_debug_check_addr(addr, 0);
|
||||
|
||||
addr64 = (uint64_t) addr;
|
||||
mem_logical_addr = addr;
|
||||
@@ -819,6 +871,7 @@ writemembl(uint32_t addr, uint8_t val)
|
||||
uint64_t a;
|
||||
|
||||
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1);
|
||||
mem_debug_check_addr(addr, 1);
|
||||
|
||||
addr64 = (uint64_t) addr;
|
||||
mem_logical_addr = addr;
|
||||
@@ -905,6 +958,8 @@ readmemwl(uint32_t addr)
|
||||
|
||||
addr64a[0] = addr;
|
||||
addr64a[1] = addr + 1;
|
||||
mem_debug_check_addr(addr, 0);
|
||||
mem_debug_check_addr(addr + 1, 0);
|
||||
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 2);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
@@ -963,6 +1018,8 @@ writememwl(uint32_t addr, uint16_t val)
|
||||
|
||||
addr64a[0] = addr;
|
||||
addr64a[1] = addr + 1;
|
||||
mem_debug_check_addr(addr, 1);
|
||||
mem_debug_check_addr(addr + 1, 1);
|
||||
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 2);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
@@ -1139,8 +1196,10 @@ readmemll(uint32_t addr)
|
||||
int i;
|
||||
uint64_t a = 0x0000000000000000ULL;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
for (i = 0; i < 4; i++) {
|
||||
addr64a[i] = (uint64_t) (addr + i);
|
||||
mem_debug_check_addr(addr + i, 0);
|
||||
}
|
||||
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 4);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
@@ -1213,8 +1272,10 @@ writememll(uint32_t addr, uint32_t val)
|
||||
int i;
|
||||
uint64_t a = 0x0000000000000000ULL;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
for (i = 0; i < 4; i++) {
|
||||
addr64a[i] = (uint64_t) (addr + i);
|
||||
mem_debug_check_addr(addr + i, 1);
|
||||
}
|
||||
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 4);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
@@ -1417,8 +1478,10 @@ readmemql(uint32_t addr)
|
||||
int i;
|
||||
uint64_t a = 0x0000000000000000ULL;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
for (i = 0; i < 8; i++) {
|
||||
addr64a[i] = (uint64_t) (addr + i);
|
||||
mem_debug_check_addr(addr + i, 0);
|
||||
}
|
||||
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 8);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
@@ -1483,8 +1546,10 @@ writememql(uint32_t addr, uint64_t val)
|
||||
int i;
|
||||
uint64_t a = 0x0000000000000000ULL;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
for (i = 0; i < 8; i++) {
|
||||
addr64a[i] = (uint64_t) (addr + i);
|
||||
mem_debug_check_addr(addr + i, 1);
|
||||
}
|
||||
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 8);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
@@ -1582,8 +1647,10 @@ do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write)
|
||||
uint32_t last_addr = addr + (num - 1);
|
||||
uint64_t a = 0x0000000000000000ULL;
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
mem_debug_check_addr(addr, write);
|
||||
for (i = 0; i < num; i++) {
|
||||
a64[i] = (uint64_t) addr;
|
||||
}
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (cr0 >> 31) {
|
||||
|
@@ -243,6 +243,7 @@ readmembl_2386(uint32_t addr)
|
||||
|
||||
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1);
|
||||
|
||||
mem_debug_check_addr(addr, 0);
|
||||
addr64 = (uint64_t) addr;
|
||||
mem_logical_addr = addr;
|
||||
|
||||
@@ -270,6 +271,7 @@ writemembl_2386(uint32_t addr, uint8_t val)
|
||||
mem_mapping_t *map;
|
||||
uint64_t a;
|
||||
|
||||
mem_debug_check_addr(addr, 1);
|
||||
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1);
|
||||
|
||||
addr64 = (uint64_t) addr;
|
||||
@@ -347,6 +349,8 @@ readmemwl_2386(uint32_t addr)
|
||||
|
||||
addr64a[0] = addr;
|
||||
addr64a[1] = addr + 1;
|
||||
mem_debug_check_addr(addr, 0);
|
||||
mem_debug_check_addr(addr + 1, 0);
|
||||
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 2);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
@@ -402,6 +406,8 @@ writememwl_2386(uint32_t addr, uint16_t val)
|
||||
|
||||
addr64a[0] = addr;
|
||||
addr64a[1] = addr + 1;
|
||||
mem_debug_check_addr(addr, 1);
|
||||
mem_debug_check_addr(addr + 1, 1);
|
||||
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 2);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
@@ -555,8 +561,10 @@ readmemll_2386(uint32_t addr)
|
||||
int i;
|
||||
uint64_t a = 0x0000000000000000ULL;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
for (i = 0; i < 4; i++) {
|
||||
addr64a[i] = (uint64_t) (addr + i);
|
||||
mem_debug_check_addr(addr + i, 0);
|
||||
}
|
||||
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 4);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
@@ -626,8 +634,10 @@ writememll_2386(uint32_t addr, uint32_t val)
|
||||
int i;
|
||||
uint64_t a = 0x0000000000000000ULL;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
for (i = 0; i < 4; i++) {
|
||||
addr64a[i] = (uint64_t) (addr + i);
|
||||
mem_debug_check_addr(addr + i, 1);
|
||||
}
|
||||
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 4);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
@@ -807,8 +817,10 @@ readmemql_2386(uint32_t addr)
|
||||
int i;
|
||||
uint64_t a = 0x0000000000000000ULL;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
for (i = 0; i < 8; i++) {
|
||||
addr64a[i] = (uint64_t) (addr + i);
|
||||
mem_debug_check_addr(addr + i, 0);
|
||||
}
|
||||
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 8);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
@@ -870,8 +882,10 @@ writememql_2386(uint32_t addr, uint64_t val)
|
||||
int i;
|
||||
uint64_t a = 0x0000000000000000ULL;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
for (i = 0; i < 8; i++) {
|
||||
addr64a[i] = (uint64_t) (addr + i);
|
||||
mem_debug_check_addr(addr + i, 1);
|
||||
}
|
||||
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 8);
|
||||
|
||||
mem_logical_addr = addr;
|
||||
@@ -957,32 +971,35 @@ do_mmutranslate_2386(uint32_t addr, uint32_t *a64, int num, int write)
|
||||
uint32_t last_addr = addr + (num - 1);
|
||||
uint64_t a = 0x0000000000000000ULL;
|
||||
|
||||
mem_debug_check_addr(addr, write);
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
a64[i] = (uint64_t) addr;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (cr0 >> 31) {
|
||||
/* If we have encountered at least one page fault, mark all subsequent addresses as
|
||||
having page faulted, prevents false negatives in readmem*l_no_mmut. */
|
||||
if ((i > 0) && cpu_state.abrt && !high_page)
|
||||
a64[i] = a64[i - 1];
|
||||
/* If we are on the same page, there is no need to translate again, as we can just
|
||||
reuse the previous result. */
|
||||
else if (i == 0) {
|
||||
a = mmutranslatereal_2386(addr, write);
|
||||
a64[i] = (uint32_t) a;
|
||||
} else if (!(addr & 0xfff)) {
|
||||
a = mmutranslatereal_2386(last_addr, write);
|
||||
a64[i] = (uint32_t) a;
|
||||
if (!(cr0 >> 31))
|
||||
return;
|
||||
|
||||
if (!cpu_state.abrt) {
|
||||
a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff));
|
||||
a64[i] = (uint32_t) a;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < num; i++) {
|
||||
/* If we have encountered at least one page fault, mark all subsequent addresses as
|
||||
having page faulted, prevents false negatives in readmem*l_no_mmut. */
|
||||
if ((i > 0) && cpu_state.abrt && !high_page)
|
||||
a64[i] = a64[i - 1];
|
||||
/* If we are on the same page, there is no need to translate again, as we can just
|
||||
reuse the previous result. */
|
||||
else if (i == 0) {
|
||||
a = mmutranslatereal_2386(addr, write);
|
||||
a64[i] = (uint32_t) a;
|
||||
} else if (!(addr & 0xfff)) {
|
||||
a = mmutranslatereal_2386(last_addr, write);
|
||||
a64[i] = (uint32_t) a;
|
||||
|
||||
if (!cpu_state.abrt) {
|
||||
a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff));
|
||||
a64[i] = (uint32_t) a;
|
||||
}
|
||||
} else {
|
||||
a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff));
|
||||
a64[i] = (uint32_t) a;
|
||||
}
|
||||
|
||||
addr++;
|
||||
|
Reference in New Issue
Block a user