Restore the debug register operation on 486+

But put it behind a compile-time option due to performance hits
Also add the DE flag to CPUID on supported CPUs
This commit is contained in:
Alexander Babikov
2024-01-15 06:22:38 +05:00
parent d182f4c553
commit a07ffdecab
12 changed files with 531 additions and 37 deletions

View File

@@ -137,6 +137,7 @@ option(MINITRACE "Enable Chrome tracing using the modified minitrace library"
option(GDBSTUB "Enable GDB stub server for debugging" OFF)
option(DEV_BRANCH "Development branch" OFF)
option(DISCORD "Discord Rich Presence support" ON)
option(DEBUGREGS486 "Enable debug register opeartion on 486+ CPUs" OFF)
if(WIN32)
set(QT ON)

View File

@@ -57,6 +57,10 @@ if(DISCORD)
target_sources(86Box PRIVATE discord.c)
endif()
if(DEBUGREGS486)
add_compile_definitions(USE_DEBUG_REGS_486)
endif()
if(VNC)
find_package(LibVNCServer)
if(LibVNCServer_FOUND)

View File

@@ -49,6 +49,82 @@
# define do_mmut_wb(s, a, b) do_mmutranslate_2386((s) + (a), b, 1, 1)
# 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)
#elif defined(USE_DEBUG_REGS_486)
# 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 || (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) || (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) || (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 || (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) || (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) || (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) || (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 || (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) || (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) || (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 || (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) || (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) || (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 || (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) || (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) || (dr[7] & 0xFF)) \
do_mmutranslate((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))))
@@ -263,6 +339,11 @@ fastreadb(uint32_t a)
{
uint8_t *t;
# ifdef USE_DEBUG_REGS_486
read_type = 1;
mem_debug_check_addr(a, read_type);
read_type = 4;
# endif
if ((a >> 12) == pccache)
# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
return *((uint8_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)));
@@ -286,6 +367,12 @@ fastreadw(uint32_t a)
{
uint8_t *t;
uint16_t val;
# ifdef USE_DEBUG_REGS_486
read_type = 1;
mem_debug_check_addr(a, read_type);
mem_debug_check_addr(a + 1, read_type);
read_type = 4;
# endif
if ((a & 0xFFF) > 0xFFE) {
val = fastreadb(a);
val |= (fastreadb(a + 1) << 8);
@@ -315,6 +402,14 @@ fastreadl(uint32_t a)
{
uint8_t *t;
uint32_t val;
# ifdef USE_DEBUG_REGS_486
int i;
read_type = 1;
for (i = 0; i < 4; i++) {
mem_debug_check_addr(a + i, read_type);
}
read_type = 4;
# endif
if ((a & 0xFFF) < 0xFFD) {
if ((a >> 12) != pccache) {
t = getpccache(a);
@@ -402,6 +497,12 @@ fastreadw_fetch(uint32_t a)
{
uint8_t *t;
uint16_t val;
# ifdef USE_DEBUG_REGS_486
read_type = 1;
mem_debug_check_addr(a, read_type);
mem_debug_check_addr(a + 1, read_type);
read_type = 4;
# endif
if ((a & 0xFFF) > 0xFFE) {
val = fastreadb(a);
if (opcode_length[val & 0xff] > 1)
@@ -432,6 +533,14 @@ fastreadl_fetch(uint32_t a)
{
uint8_t *t;
uint32_t val;
# ifdef USE_DEBUG_REGS_486
int i;
read_type = 1;
for (i = 0; i < 4; i++) {
mem_debug_check_addr(a + i, read_type);
}
read_type = 4;
# endif
if ((a & 0xFFF) < 0xFFD) {
if ((a >> 12) != pccache) {
t = getpccache(a);

View File

@@ -28,6 +28,7 @@
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/machine.h>
#include <86box/plat_fallthrough.h>
#include <86box/gdbstub.h>
#ifdef USE_DYNAREC
# include "codegen.h"
@@ -224,7 +225,11 @@ fetch_ea_16_long(uint32_t rmdat)
#include "386_ops.h"
#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG))
#ifdef USE_DEBUG_REGS_486
# define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG) && !(dr[7] & 0xFF))
#else
# define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG))
#endif
#ifdef USE_DYNAREC
int32_t cycles_main = 0;
@@ -269,7 +274,11 @@ exec386_dynarec_int(void)
cpu_block_end = 0;
x86_was_reset = 0;
# ifdef USE_DEBUG_REGS_486
if (trap & 2) {
# else
if (trap == 2) {
# endif
/* Handle the T bit in the new TSS first. */
CPU_BLOCK_END();
goto block_ended;
@@ -286,6 +295,13 @@ exec386_dynarec_int(void)
cpu_state.ea_seg = &cpu_state.seg_ds;
cpu_state.ssegs = 0;
# ifdef USE_DEBUG_REGS_486
if (UNLIKELY(cpu_386_check_instruction_fault())) {
x86gen();
goto block_ended;
}
# endif
fetchdat = fastreadl_fetch(cs + cpu_state.pc);
# ifdef ENABLE_386_DYNAREC_LOG
if (in_smm)
@@ -296,9 +312,16 @@ exec386_dynarec_int(void)
opcode = fetchdat & 0xFF;
fetchdat >>= 8;
# ifdef USE_DEBUG_REGS_486
trap |= !!(cpu_state.flags & T_FLAG);
# else
trap = cpu_state.flags & T_FLAG;
# endif
cpu_state.pc++;
# ifdef USE_DEBUG_REGS_486
cpu_state.eflags &= ~(RF_FLAG);
# endif
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
}
@@ -307,6 +330,16 @@ exec386_dynarec_int(void)
cpu_state.pc &= 0xffff;
# endif
# ifdef USE_DEBUG_REGS_486
if (!cpu_state.abrt) {
if (!rf_flag_no_clear) {
cpu_state.eflags &= ~RF_FLAG;
}
rf_flag_no_clear = 0;
}
# endif
if (((cs + cpu_state.pc) >> 12) != pccache)
CPU_BLOCK_END();
@@ -330,7 +363,14 @@ exec386_dynarec_int(void)
block_ended:
if (!cpu_state.abrt && trap) {
# ifdef USE_DEBUG_REGS_486
//pclog("Debug trap 0x%X\n", trap);
if (trap & 2) dr[6] |= 0x8000;
if (trap & 1) dr[6] |= 0x4000;
# else
dr[6] |= (trap == 2) ? 0x8000 : 0x4000;
# endif
trap = 0;
# ifndef USE_NEW_DYNAREC
oldcs = CS;
@@ -842,6 +882,13 @@ exec386(int32_t cycs)
cpu_state.ea_seg = &cpu_state.seg_ds;
cpu_state.ssegs = 0;
#ifdef USE_DEBUG_REGS_486
if (UNLIKELY(cpu_386_check_instruction_fault())) {
x86gen();
goto block_ended;
}
#endif
fetchdat = fastreadl_fetch(cs + cpu_state.pc);
if (!cpu_state.abrt) {
@@ -851,9 +898,16 @@ exec386(int32_t cycs)
#endif
opcode = fetchdat & 0xFF;
fetchdat >>= 8;
#ifdef USE_DEBUG_REGS_486
trap |= !!(cpu_state.flags & T_FLAG);
#else
trap = cpu_state.flags & T_FLAG;
#endif
cpu_state.pc++;
#ifdef USE_DEBUG_REGS_486
cpu_state.eflags &= ~(RF_FLAG);
#endif
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
if (x86_was_reset)
break;
@@ -871,6 +925,9 @@ exec386(int32_t cycs)
if (cpu_end_block_after_ins)
cpu_end_block_after_ins--;
#ifdef USE_DEBUG_REGS_486
block_ended:
#endif
if (cpu_state.abrt) {
flags_rebuild();
tempi = cpu_state.abrt & ABRT_MASK;
@@ -895,12 +952,21 @@ exec386(int32_t cycs)
}
} else if (trap) {
flags_rebuild();
#ifdef USE_DEBUG_REGS_486
if (trap & 1)
dr[6] |= 0x4000;
if (trap & 2)
dr[6] |= 0x8000;
#endif
trap = 0;
#ifndef USE_NEW_DYNAREC
oldcs = CS;
#endif
cpu_state.oldpc = cpu_state.pc;
#ifndef USE_DEBUG_REGS_486
dr[6] |= 0x4000;
#endif
x86_int(1);
}

View File

@@ -24,6 +24,7 @@
#include <86box/gdbstub.h>
#include "codegen.h"
#include <86box/plat_unused.h>
#include <86box/plat_fallthrough.h>
#define CPU_BLOCK_END() cpu_block_end = 1

View File

@@ -81,6 +81,12 @@ enum {
#define CPUID_3DNOWE (1UL << 30UL) /* Extended 3DNow! instructions */
#define CPUID_3DNOW (1UL << 31UL) /* 3DNow! instructions */
/* Remove the Debugging Extensions CPUID flag if not compiled
with debug register support for 486 and later CPUs. */
#ifndef USE_DEBUG_REGS_486
# define CPUID_DE 0
#endif
/* Make sure this is as low as possible. */
cpu_state_t cpu_state;
fpu_state_t fpu_state;
@@ -1973,7 +1979,7 @@ cpu_CPUID(void)
} else if (EAX == 1) {
EAX = ((msr.fcr2 & 0x0ff0) ? ((msr.fcr2 & 0x0ff0) | (CPUID & 0xf00f)) : CPUID);
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR;
EDX = CPUID_FPU | CPUID_DE | CPUID_TSC | CPUID_MSR;
if (cpu_has_feature(CPU_FEATURE_CX8))
EDX |= CPUID_CMPXCHG8B;
if (msr.fcr & (1 << 9))
@@ -1999,7 +2005,7 @@ cpu_CPUID(void)
case 1:
EAX = ((msr.fcr2 & 0x0ff0) ? ((msr.fcr2 & 0x0ff0) | (CPUID & 0xf00f)) : CPUID);
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR;
EDX = CPUID_FPU | CPUID_DE | CPUID_TSC | CPUID_MSR;
if (cpu_has_feature(CPU_FEATURE_CX8))
EDX |= CPUID_CMPXCHG8B;
if (msr.fcr & (1 << 9))
@@ -2010,7 +2016,7 @@ cpu_CPUID(void)
break;
case 0x80000001:
EAX = CPUID;
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR;
EDX = CPUID_FPU | CPUID_DE | CPUID_TSC | CPUID_MSR;
if (cpu_has_feature(CPU_FEATURE_CX8))
EDX |= CPUID_CMPXCHG8B;
if (msr.fcr & (1 << 9))
@@ -2048,7 +2054,7 @@ cpu_CPUID(void)
} else if (EAX == 1) {
EAX = CPUID;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B;
EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B;
if (cpu_s->cpu_type != CPU_P24T)
EDX |= CPUID_MCE;
} else
@@ -2065,7 +2071,7 @@ cpu_CPUID(void)
} else if (EAX == 1) {
EAX = CPUID;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDPGE;
EDX = CPUID_FPU | CPUID_DE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDPGE;
} else
EAX = EBX = ECX = EDX = 0;
break;
@@ -2081,7 +2087,7 @@ cpu_CPUID(void)
case 1:
EAX = CPUID;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE;
EDX = CPUID_FPU | CPUID_DE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE;
break;
case 0x80000000:
EAX = 0x80000005;
@@ -2090,7 +2096,7 @@ cpu_CPUID(void)
case 0x80000001:
EAX = CPUID;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE;
EDX = CPUID_FPU | CPUID_DE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE;
break;
case 0x80000002: /* Processor name string */
EAX = 0x2D444D41; /* AMD-K5(tm) Proce */
@@ -2126,7 +2132,7 @@ cpu_CPUID(void)
case 1:
EAX = CPUID;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX;
EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX;
break;
case 0x80000000:
EAX = 0x80000005;
@@ -2135,7 +2141,7 @@ cpu_CPUID(void)
case 0x80000001:
EAX = CPUID + 0x100;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX;
EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX;
break;
case 0x80000002: /* Processor name string */
EAX = 0x2D444D41; /* AMD-K6tm w/ mult */
@@ -2183,7 +2189,7 @@ cpu_CPUID(void)
case 1:
EAX = CPUID;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX;
EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX;
if (cpu_s->cpu_type == CPU_K6_2C)
EDX |= CPUID_PGE;
break;
@@ -2194,7 +2200,7 @@ cpu_CPUID(void)
case 0x80000001:
EAX = CPUID + 0x100;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_MMX | CPUID_3DNOW;
EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_MMX | CPUID_3DNOW;
if (cpu_s->cpu_type == CPU_K6_2C)
EDX |= CPUID_PGE;
break;
@@ -2233,7 +2239,7 @@ cpu_CPUID(void)
case 1:
EAX = CPUID;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE | CPUID_MMX;
EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE | CPUID_MMX;
break;
case 0x80000000:
EAX = 0x80000006;
@@ -2242,7 +2248,7 @@ cpu_CPUID(void)
case 0x80000001:
EAX = CPUID + 0x100;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_PGE | CPUID_MMX | CPUID_3DNOW;
EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_PGE | CPUID_MMX | CPUID_3DNOW;
break;
case 0x80000002: /* Processor name string */
EAX = 0x2d444d41; /* AMD-K6(tm) 3D+ P */
@@ -2284,7 +2290,7 @@ cpu_CPUID(void)
case 1:
EAX = CPUID;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE | CPUID_MMX;
EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_PGE | CPUID_MMX;
break;
case 0x80000000:
EAX = 0x80000007;
@@ -2293,7 +2299,7 @@ cpu_CPUID(void)
case 0x80000001:
EAX = CPUID + 0x100;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_MMX | CPUID_PGE | CPUID_3DNOW | CPUID_3DNOWE;
EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_MMX | CPUID_PGE | CPUID_3DNOW | CPUID_3DNOWE;
break;
case 0x80000002: /* Processor name string */
EAX = 0x2d444d41; /* AMD-K6(tm)-III P */
@@ -2339,7 +2345,7 @@ cpu_CPUID(void)
} else if (EAX == 1) {
EAX = CPUID;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX;
EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX;
} else
EAX = EBX = ECX = EDX = 0;
break;
@@ -2382,7 +2388,7 @@ cpu_CPUID(void)
} else if (EAX == 1) {
EAX = CPUID;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B;
EDX = CPUID_FPU | CPUID_DE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B;
} else
EAX = EBX = ECX = EDX = 0;
break;
@@ -2396,7 +2402,7 @@ cpu_CPUID(void)
} else if (EAX == 1) {
EAX = CPUID;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX;
EDX = CPUID_FPU | CPUID_DE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX;
} else
EAX = EBX = ECX = EDX = 0;
break;
@@ -2411,7 +2417,7 @@ cpu_CPUID(void)
} else if (EAX == 1) {
EAX = CPUID;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_CMOV;
EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_CMOV;
} else if (EAX == 2) {
EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries
Instruction TLB: 4 MB pages, fully associative, 2 entries
@@ -2434,7 +2440,7 @@ cpu_CPUID(void)
} else if (EAX == 1) {
EAX = CPUID;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_CMOV;
EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_CMOV;
} else if (EAX == 2) {
EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries
Instruction TLB: 4 MB pages, fully associative, 2 entries
@@ -2457,7 +2463,7 @@ cpu_CPUID(void)
} else if (EAX == 1) {
EAX = CPUID;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_FXSR | CPUID_CMOV;
EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_FXSR | CPUID_CMOV;
} else if (EAX == 2) {
EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries
Instruction TLB: 4 MB pages, fully associative, 2 entries
@@ -2496,7 +2502,7 @@ cpu_CPUID(void)
case 1:
EAX = ((msr.fcr2 & 0x0ff0) ? ((msr.fcr2 & 0x0ff0) | (CPUID & 0xf00f)) : CPUID);
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_MMX | CPUID_MTRR;
EDX = CPUID_FPU | CPUID_DE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_MMX | CPUID_MTRR;
if (cpu_has_feature(CPU_FEATURE_CX8))
EDX |= CPUID_CMPXCHG8B;
if (msr.fcr & (1 << 7))
@@ -2507,7 +2513,7 @@ cpu_CPUID(void)
break;
case 0x80000001:
EAX = CPUID;
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_MMX | CPUID_MTRR | CPUID_3DNOW;
EDX = CPUID_FPU | CPUID_DE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_MMX | CPUID_MTRR | CPUID_3DNOW;
if (cpu_has_feature(CPU_FEATURE_CX8))
EDX |= CPUID_CMPXCHG8B;
if (msr.fcr & (1 << 7))

View File

@@ -279,7 +279,11 @@ reset_common(int hard)
cr4 = 0;
cpu_state.eflags = 0;
cgate32 = 0;
#ifdef USE_DEBUG_REGS_486
if (is386) {
#else
if (is386 && !is486) {
#endif
for (uint8_t i = 0; i < 4; i++)
dr[i] = 0x00000000;
dr[6] = 0xffff1ff0;

View File

@@ -178,6 +178,9 @@ opPOPF_186(uint32_t fetchdat)
else
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
flags_extract();
#ifdef USE_DEBUG_REGS_486
rf_flag_no_clear = 1;
#endif
CLOCK_CYCLES(5);
PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0);
@@ -211,6 +214,9 @@ opPOPF_286(uint32_t fetchdat)
else
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
flags_extract();
#ifdef USE_DEBUG_REGS_486
rf_flag_no_clear = 1;
#endif
CLOCK_CYCLES(5);
PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0);
@@ -264,6 +270,9 @@ opPOPF(uint32_t fetchdat)
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
}
flags_extract();
#ifdef USE_DEBUG_REGS_486
rf_flag_no_clear = 1;
#endif
CLOCK_CYCLES(5);
PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0);
@@ -307,6 +316,9 @@ opPOPFD(uint32_t fetchdat)
cpu_state.eflags = (templ >> 16) & 3;
flags_extract();
#ifdef USE_DEBUG_REGS_486
rf_flag_no_clear = 1;
#endif
CLOCK_CYCLES(5);
PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 0);

View File

@@ -82,12 +82,43 @@ opMOV_r_CRx_a32(uint32_t fetchdat)
static int
opMOV_r_DRx_a16(uint32_t fetchdat)
{
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
if (((CPL > 0) || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
x86gpf(NULL, 0);
return 1;
}
#ifdef USE_DEBUG_REGS_486
if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) {
trap |= 1;
return 1;
}
#endif
fetch_ea_16(fetchdat);
cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0);
switch (cpu_reg) {
case 0 ... 3:
cpu_state.regs[cpu_rm].l = dr[cpu_reg];
break;
case 4:
if (cr4 & 0x8) {
x86illegal();
return 1;
}
fallthrough;
case 6:
cpu_state.regs[cpu_rm].l = dr[6];
break;
case 5:
if (cr4 & 0x8) {
x86illegal();
return 1;
}
fallthrough;
case 7:
cpu_state.regs[cpu_rm].l = dr[7];
break;
default:
x86illegal();
return 1;
}
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
return 0;
@@ -95,12 +126,43 @@ opMOV_r_DRx_a16(uint32_t fetchdat)
static int
opMOV_r_DRx_a32(uint32_t fetchdat)
{
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
if (((CPL > 0) || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
x86gpf(NULL, 0);
return 1;
}
#ifdef USE_DEBUG_REGS_486
if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) {
trap |= 1;
return 1;
}
#endif
fetch_ea_32(fetchdat);
cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0);
switch (cpu_reg) {
case 0 ... 3:
cpu_state.regs[cpu_rm].l = dr[cpu_reg];
break;
case 4:
if (cr4 & 0x8) {
x86illegal();
return 1;
}
fallthrough;
case 6:
cpu_state.regs[cpu_rm].l = dr[6];
break;
case 5:
if (cr4 & 0x8) {
x86illegal();
return 1;
}
fallthrough;
case 7:
cpu_state.regs[cpu_rm].l = dr[7];
break;
default:
x86illegal();
return 1;
}
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
return 0;
@@ -224,27 +286,96 @@ opMOV_CRx_r_a32(uint32_t fetchdat)
static int
opMOV_DRx_r_a16(uint32_t fetchdat)
{
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
if (((CPL > 0) || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
x86gpf(NULL, 0);
return 1;
}
#ifdef USE_DEBUG_REGS_486
if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) {
trap |= 1;
x86gen();
return 1;
}
#endif
fetch_ea_16(fetchdat);
dr[cpu_reg] = cpu_state.regs[cpu_rm].l;
switch (cpu_reg) {
case 0 ... 3:
dr[cpu_reg] = cpu_state.regs[cpu_rm].l;
break;
case 4:
if (cr4 & 0x8) {
x86illegal();
return 1;
}
fallthrough;
case 6:
dr[6] = (dr[6] & 0xffff0ff0) | (cpu_state.regs[cpu_rm].l & 0x0000f00f);
break;
case 5:
if (cr4 & 0x8) {
x86illegal();
return 1;
}
fallthrough;
case 7:
dr[7] = cpu_state.regs[cpu_rm].l | 0x00000400;
break;
default:
x86illegal();
return 1;
}
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
#ifdef USE_DEBUG_REGS_486
CPU_BLOCK_END();
#endif
return 0;
}
static int
opMOV_DRx_r_a32(uint32_t fetchdat)
{
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
if (((CPL > 0) || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
x86gpf(NULL, 0);
return 1;
}
#ifdef USE_DEBUG_REGS_486
if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) {
trap |= 1;
return 1;
}
#endif
fetch_ea_16(fetchdat);
dr[cpu_reg] = cpu_state.regs[cpu_rm].l;
switch (cpu_reg) {
case 0 ... 3:
dr[cpu_reg] = cpu_state.regs[cpu_rm].l;
break;
case 4:
if (cr4 & 0x8) {
x86illegal();
return 1;
}
fallthrough;
case 6:
dr[6] = (dr[6] & 0xffff0ff0) | (cpu_state.regs[cpu_rm].l & 0x0000f00f);
break;
case 5:
if (cr4 & 0x8) {
x86illegal();
return 1;
}
fallthrough;
case 7:
dr[7] = cpu_state.regs[cpu_rm].l | 0x00000400;
break;
default:
x86illegal();
return 1;
}
CLOCK_CYCLES(6);
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
#ifdef USE_DEBUG_REGS_486
CPU_BLOCK_END();
#endif
return 0;
}

View File

@@ -135,6 +135,9 @@ opIRET_186(uint32_t fetchdat)
}
flags_extract();
nmi_enable = 1;
#ifdef USE_DEBUG_REGS_486
rf_flag_no_clear = 1;
#endif
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0);
@@ -175,6 +178,9 @@ opIRET_286(uint32_t fetchdat)
}
flags_extract();
nmi_enable = 1;
#ifdef USE_DEBUG_REGS_486
rf_flag_no_clear = 1;
#endif
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0);
@@ -243,6 +249,9 @@ opIRET(uint32_t fetchdat)
}
flags_extract();
nmi_enable = 1;
#ifdef USE_DEBUG_REGS_486
rf_flag_no_clear = 1;
#endif
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0);
@@ -285,6 +294,9 @@ opIRETD(uint32_t fetchdat)
}
flags_extract();
nmi_enable = 1;
#ifdef USE_DEBUG_REGS_486
rf_flag_no_clear = 1;
#endif
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1);

View File

@@ -279,6 +279,58 @@ io_handler_interleaved(int set, uint16_t base, int size,
io_handler_common(set, base, size, inb, inw, inl, outb, outw, outl, priv, 2);
}
#ifdef USE_DEBUG_REGS_486
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 (!(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;
}
#endif
uint8_t
inb(uint16_t port)
{
@@ -290,6 +342,10 @@ inb(uint16_t port)
int qfound = 0;
#endif
#ifdef USE_DEBUG_REGS_486
io_debug_check_addr(port);
#endif
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
ret = pci_read(port, NULL);
found = 1;
@@ -350,6 +406,10 @@ outb(uint16_t port, uint8_t val)
int qfound = 0;
#endif
#ifdef USE_DEBUG_REGS_486
io_debug_check_addr(port);
#endif
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
pci_write(port, val, NULL);
found = 1;
@@ -402,6 +462,10 @@ inw(uint16_t port)
#endif
uint8_t ret8[2];
#ifdef USE_DEBUG_REGS_486
io_debug_check_addr(port);
#endif
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
ret = pci_readw(port, NULL);
found = 2;
@@ -474,6 +538,10 @@ outw(uint16_t port, uint16_t val)
int qfound = 0;
#endif
#ifdef USE_DEBUG_REGS_486
io_debug_check_addr(port);
#endif
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
pci_writew(port, val, NULL);
found = 2;
@@ -542,6 +610,10 @@ inl(uint16_t port)
int qfound = 0;
#endif
#ifdef USE_DEBUG_REGS_486
io_debug_check_addr(port);
#endif
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
ret = pci_readl(port, NULL);
found = 4;
@@ -646,6 +718,10 @@ outl(uint16_t port, uint32_t val)
#endif
int i = 0;
#ifdef USE_DEBUG_REGS_486
io_debug_check_addr(port);
#endif
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
pci_writel(port, val, NULL);
found = 4;

View File

@@ -164,6 +164,46 @@ mem_log(const char *fmt, ...)
# define mem_log(fmt, ...)
#endif
#ifdef USE_DEBUG_REGS_486
/* As below, 1 = exec, 4 = read. */
int read_type = 4;
/* Set trap for data address breakpoints - 1 = exec, 2 = write, 4 = read. */
void
mem_debug_check_addr(uint32_t addr, int flags)
{
uint32_t bp_addr;
uint32_t bp_mask;
uint32_t len_type_pair;
int bp_enabled;
uint8_t match_flags[4] = { 0, 2, 0, 6 };
if (cpu_state.abrt || ((flags == 1) && (cpu_state.eflags & RF_FLAG)))
return;
if (dr[7] & 0x000000ff) for (uint8_t i = 0; i < 4; i++) {
bp_addr = dr[i];
bp_enabled = (dr[7] >> (i << 1)) & 0x03;
len_type_pair = (dr[7] >> (16 + (i << 2))) & 0x0f;
bp_mask = ~((len_type_pair >> 2) & 0x03);
if ((flags & match_flags[len_type_pair & 0x03]) && ((bp_addr & bp_mask) == (addr & bp_mask))) {
/*
From the Intel i386 documemntation:
(Note that the processor sets Bn regardless of whether Gn or
Ln is set. If more than one breakpoint condition occurs at one time and if
the breakpoint trap occurs due to an enabled condition other than n, Bn may
be set, even though neither Gn nor Ln is set.)
*/
dr[6] |= (1 << i);
if (bp_enabled)
trap |= (read_type == 1) ? 8 : 4;
}
}
}
#endif
int
mem_addr_is_ram(uint32_t addr)
{
@@ -793,6 +833,9 @@ readmembl(uint32_t addr)
uint64_t a;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1);
#ifdef USE_DEBUG_REGS_486
mem_debug_check_addr(addr, read_type);
#endif
addr64 = (uint64_t) addr;
mem_logical_addr = addr;
@@ -822,6 +865,9 @@ writemembl(uint32_t addr, uint8_t val)
uint64_t a;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1);
#ifdef USE_DEBUG_REGS_486
mem_debug_check_addr(addr, 2);
#endif
addr64 = (uint64_t) addr;
mem_logical_addr = addr;
@@ -908,6 +954,10 @@ readmemwl(uint32_t addr)
addr64a[0] = addr;
addr64a[1] = addr + 1;
#ifdef USE_DEBUG_REGS_486
mem_debug_check_addr(addr, read_type);
mem_debug_check_addr(addr + 1, read_type);
#endif
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 2);
mem_logical_addr = addr;
@@ -966,6 +1016,10 @@ writememwl(uint32_t addr, uint16_t val)
addr64a[0] = addr;
addr64a[1] = addr + 1;
#ifdef USE_DEBUG_REGS_486
mem_debug_check_addr(addr, 2);
mem_debug_check_addr(addr + 1, 2);
#endif
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 2);
mem_logical_addr = addr;
@@ -1142,8 +1196,12 @@ 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);
#ifdef USE_DEBUG_REGS_486
mem_debug_check_addr(addr + i, read_type);
#endif
}
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 4);
mem_logical_addr = addr;
@@ -1216,8 +1274,12 @@ 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);
#ifdef USE_DEBUG_REGS_486
mem_debug_check_addr(addr + i, 2);
#endif
}
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 4);
mem_logical_addr = addr;
@@ -1420,8 +1482,12 @@ 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);
#ifdef USE_DEBUG_REGS_486
mem_debug_check_addr(addr + i, read_type);
#endif
}
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 8);
mem_logical_addr = addr;
@@ -1486,8 +1552,12 @@ 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);
#ifdef USE_DEBUG_REGS_486
mem_debug_check_addr(addr + i, 2);
#endif
}
GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 8);
mem_logical_addr = addr;
@@ -1584,7 +1654,9 @@ do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write)
int cond = 1;
uint32_t last_addr = addr + (num - 1);
uint64_t a = 0x0000000000000000ULL;
#ifdef USE_DEBUG_REGS_486
mem_debug_check_addr(addr, write ? 2 : read_type);
#endif
for (i = 0; i < num; i++)
a64[i] = (uint64_t) addr;