commit
43bb29edc5
18 changed files with 1190 additions and 9 deletions
|
@ -23,6 +23,8 @@
|
|||
#include "core/arm/skyeye_common/armsupp.h"
|
||||
#include "core/arm/skyeye_common/vfp/vfp.h"
|
||||
|
||||
#include "core/gdbstub/gdbstub.h"
|
||||
|
||||
Common::Profiling::TimingCategory profile_execute("DynCom::Execute");
|
||||
Common::Profiling::TimingCategory profile_decode("DynCom::Decode");
|
||||
|
||||
|
@ -3548,6 +3550,7 @@ static int InterpreterTranslate(ARMul_State* cpu, int& bb_start, u32 addr) {
|
|||
CITRA_IGNORE_EXIT(-1);
|
||||
}
|
||||
inst_base = arm_instruction_trans[idx](inst, idx);
|
||||
|
||||
translated:
|
||||
phys_addr += inst_size;
|
||||
|
||||
|
@ -3580,6 +3583,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
|
|||
Common::Profiling::ScopeTimer timer_execute(profile_execute);
|
||||
MICROPROFILE_SCOPE(DynCom_Execute);
|
||||
|
||||
GDBStub::BreakpointAddress breakpoint_data;
|
||||
|
||||
#undef RM
|
||||
#undef RS
|
||||
|
||||
|
@ -3604,15 +3609,27 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
|
|||
#define INC_PC(l) ptr += sizeof(arm_inst) + l
|
||||
#define INC_PC_STUB ptr += sizeof(arm_inst)
|
||||
|
||||
#define GDB_BP_CHECK \
|
||||
cpu->Cpsr &= ~(1 << 5); \
|
||||
cpu->Cpsr |= cpu->TFlag << 5; \
|
||||
if (GDBStub::g_server_enabled) { \
|
||||
if (GDBStub::IsMemoryBreak() || (breakpoint_data.type != GDBStub::BreakpointType::None && PC == breakpoint_data.address)) { \
|
||||
GDBStub::Break(); \
|
||||
goto END; \
|
||||
} \
|
||||
}
|
||||
|
||||
// GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a
|
||||
// clunky switch statement.
|
||||
#if defined __GNUC__ || defined __clang__
|
||||
#define GOTO_NEXT_INST \
|
||||
GDB_BP_CHECK; \
|
||||
if (num_instrs >= cpu->NumInstrsToExecute) goto END; \
|
||||
num_instrs++; \
|
||||
goto *InstLabel[inst_base->idx]
|
||||
#else
|
||||
#define GOTO_NEXT_INST \
|
||||
GDB_BP_CHECK; \
|
||||
if (num_instrs >= cpu->NumInstrsToExecute) goto END; \
|
||||
num_instrs++; \
|
||||
switch(inst_base->idx) { \
|
||||
|
@ -3903,6 +3920,11 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
|
|||
goto END;
|
||||
}
|
||||
|
||||
// Find breakpoint if one exists within the block
|
||||
if (GDBStub::g_server_enabled && GDBStub::IsConnected()) {
|
||||
breakpoint_data = GDBStub::GetNextBreakpointFromAddress(cpu->Reg[15], GDBStub::BreakpointType::Execute);
|
||||
}
|
||||
|
||||
inst_base = (arm_inst *)&inst_buf[ptr];
|
||||
GOTO_NEXT_INST;
|
||||
}
|
||||
|
@ -4454,7 +4476,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
|
|||
ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
|
||||
inst_cream->get_addr(cpu, inst_cream->inst, addr);
|
||||
|
||||
cpu->Reg[BITS(inst_cream->inst, 12, 15)] = Memory::Read8(addr);
|
||||
cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory8(addr);
|
||||
|
||||
if (BITS(inst_cream->inst, 12, 15) == 15) {
|
||||
INC_PC(sizeof(ldst_inst));
|
||||
|
@ -4472,7 +4494,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
|
|||
ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
|
||||
inst_cream->get_addr(cpu, inst_cream->inst, addr);
|
||||
|
||||
cpu->Reg[BITS(inst_cream->inst, 12, 15)] = Memory::Read8(addr);
|
||||
cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory8(addr);
|
||||
|
||||
if (BITS(inst_cream->inst, 12, 15) == 15) {
|
||||
INC_PC(sizeof(ldst_inst));
|
||||
|
@ -4531,7 +4553,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
|
|||
|
||||
cpu->SetExclusiveMemoryAddress(read_addr);
|
||||
|
||||
RD = Memory::Read8(read_addr);
|
||||
RD = cpu->ReadMemory8(read_addr);
|
||||
if (inst_cream->Rd == 15) {
|
||||
INC_PC(sizeof(generic_arm_inst));
|
||||
goto DISPATCH;
|
||||
|
@ -4604,7 +4626,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
|
|||
if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
|
||||
ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
|
||||
inst_cream->get_addr(cpu, inst_cream->inst, addr);
|
||||
unsigned int value = Memory::Read8(addr);
|
||||
unsigned int value = cpu->ReadMemory8(addr);
|
||||
if (BIT(value, 7)) {
|
||||
value |= 0xffffff00;
|
||||
}
|
||||
|
@ -6027,7 +6049,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
|
|||
ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
|
||||
inst_cream->get_addr(cpu, inst_cream->inst, addr);
|
||||
unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
|
||||
Memory::Write8(addr, value);
|
||||
cpu->WriteMemory8(addr, value);
|
||||
}
|
||||
cpu->Reg[15] += cpu->GetInstructionSize();
|
||||
INC_PC(sizeof(ldst_inst));
|
||||
|
@ -6040,7 +6062,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
|
|||
ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
|
||||
inst_cream->get_addr(cpu, inst_cream->inst, addr);
|
||||
unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
|
||||
Memory::Write8(addr, value);
|
||||
cpu->WriteMemory8(addr, value);
|
||||
}
|
||||
cpu->Reg[15] += cpu->GetInstructionSize();
|
||||
INC_PC(sizeof(ldst_inst));
|
||||
|
@ -6091,7 +6113,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
|
|||
|
||||
if (cpu->IsExclusiveMemoryAccess(write_addr)) {
|
||||
cpu->UnsetExclusiveMemoryAddress();
|
||||
Memory::Write8(write_addr, cpu->Reg[inst_cream->Rm]);
|
||||
cpu->WriteMemory8(write_addr, cpu->Reg[inst_cream->Rm]);
|
||||
RD = 0;
|
||||
} else {
|
||||
// Failed to write due to mutex access
|
||||
|
@ -6250,8 +6272,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
|
|||
if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) {
|
||||
swp_inst* inst_cream = (swp_inst*)inst_base->component;
|
||||
addr = RN;
|
||||
unsigned int value = Memory::Read8(addr);
|
||||
Memory::Write8(addr, (RM & 0xFF));
|
||||
unsigned int value = cpu->ReadMemory8(addr);
|
||||
cpu->WriteMemory8(addr, (RM & 0xFF));
|
||||
RD = value;
|
||||
}
|
||||
cpu->Reg[15] += cpu->GetInstructionSize();
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "core/memory.h"
|
||||
#include "core/arm/skyeye_common/armstate.h"
|
||||
#include "core/arm/skyeye_common/vfp/vfp.h"
|
||||
#include "core/gdbstub/gdbstub.h"
|
||||
|
||||
ARMul_State::ARMul_State(PrivilegeMode initial_mode)
|
||||
{
|
||||
|
@ -185,8 +186,25 @@ void ARMul_State::ResetMPCoreCP15Registers()
|
|||
CP15[CP15_TLB_DEBUG_CONTROL] = 0x00000000;
|
||||
}
|
||||
|
||||
static void CheckMemoryBreakpoint(u32 address, GDBStub::BreakpointType type)
|
||||
{
|
||||
if (GDBStub::g_server_enabled && GDBStub::CheckBreakpoint(address, type)) {
|
||||
LOG_DEBUG(Debug, "Found memory breakpoint @ %08x", address);
|
||||
GDBStub::Break(true);
|
||||
}
|
||||
}
|
||||
|
||||
u8 ARMul_State::ReadMemory8(u32 address) const
|
||||
{
|
||||
CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read);
|
||||
|
||||
return Memory::Read8(address);
|
||||
}
|
||||
|
||||
u16 ARMul_State::ReadMemory16(u32 address) const
|
||||
{
|
||||
CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read);
|
||||
|
||||
u16 data = Memory::Read16(address);
|
||||
|
||||
if (InBigEndianMode())
|
||||
|
@ -197,6 +215,8 @@ u16 ARMul_State::ReadMemory16(u32 address) const
|
|||
|
||||
u32 ARMul_State::ReadMemory32(u32 address) const
|
||||
{
|
||||
CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read);
|
||||
|
||||
u32 data = Memory::Read32(address);
|
||||
|
||||
if (InBigEndianMode())
|
||||
|
@ -207,6 +227,8 @@ u32 ARMul_State::ReadMemory32(u32 address) const
|
|||
|
||||
u64 ARMul_State::ReadMemory64(u32 address) const
|
||||
{
|
||||
CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read);
|
||||
|
||||
u64 data = Memory::Read64(address);
|
||||
|
||||
if (InBigEndianMode())
|
||||
|
@ -215,8 +237,17 @@ u64 ARMul_State::ReadMemory64(u32 address) const
|
|||
return data;
|
||||
}
|
||||
|
||||
void ARMul_State::WriteMemory8(u32 address, u8 data)
|
||||
{
|
||||
CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Write);
|
||||
|
||||
Memory::Write8(address, data);
|
||||
}
|
||||
|
||||
void ARMul_State::WriteMemory16(u32 address, u16 data)
|
||||
{
|
||||
CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Write);
|
||||
|
||||
if (InBigEndianMode())
|
||||
data = Common::swap16(data);
|
||||
|
||||
|
@ -225,6 +256,8 @@ void ARMul_State::WriteMemory16(u32 address, u16 data)
|
|||
|
||||
void ARMul_State::WriteMemory32(u32 address, u32 data)
|
||||
{
|
||||
CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Write);
|
||||
|
||||
if (InBigEndianMode())
|
||||
data = Common::swap32(data);
|
||||
|
||||
|
@ -233,6 +266,8 @@ void ARMul_State::WriteMemory32(u32 address, u32 data)
|
|||
|
||||
void ARMul_State::WriteMemory64(u32 address, u64 data)
|
||||
{
|
||||
CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Write);
|
||||
|
||||
if (InBigEndianMode())
|
||||
data = Common::swap64(data);
|
||||
|
||||
|
|
|
@ -153,9 +153,11 @@ public:
|
|||
|
||||
// Reads/writes data in big/little endian format based on the
|
||||
// state of the E (endian) bit in the APSR.
|
||||
u8 ReadMemory8(u32 address) const;
|
||||
u16 ReadMemory16(u32 address) const;
|
||||
u32 ReadMemory32(u32 address) const;
|
||||
u64 ReadMemory64(u32 address) const;
|
||||
void WriteMemory8(u32 address, u8 data);
|
||||
void WriteMemory16(u32 address, u16 data);
|
||||
void WriteMemory32(u32 address, u32 data);
|
||||
void WriteMemory64(u32 address, u64 data);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue