Files
dolphin/Source/Core/Core/Debugger/PPCDebugInterface.cpp
T
Fiora c2ed29fe0d MemmapFunctions: various MMU optimizations
Small TLB lookup optimizations: this is the hot path for MMU code, so try to
make it better.

Template the TLB lookup functions based on the lookup type (opcode, data,
no exception).

Clean up the Read/Write functions and make them more consistent.

Add an early-exit path for MMU accesses to ReadFromHardware/WriteToHardware.
2015-01-05 10:34:55 -08:00

227 lines
4.9 KiB
C++

// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2
// Refer to the license.txt file included.
#include <string>
#include "Common/GekkoDisassembler.h"
#include "Core/Core.h"
#include "Core/Host.h"
#include "Core/Debugger/Debugger_SymbolMap.h"
#include "Core/Debugger/PPCDebugInterface.h"
#include "Core/HW/CPU.h"
#include "Core/HW/DSP.h"
#include "Core/HW/Memmap.h"
#include "Core/PowerPC/PowerPC.h"
#include "Core/PowerPC/PPCSymbolDB.h"
#include "Core/PowerPC/JitCommon/JitBase.h"
std::string PPCDebugInterface::Disassemble(unsigned int address)
{
// Memory::ReadUnchecked_U32 seemed to crash on shutdown
if (PowerPC::GetState() == PowerPC::CPU_POWERDOWN)
return "";
if (Core::GetState() != Core::CORE_UNINITIALIZED)
{
if (!Memory::IsRAMAddress(address, true, true))
{
if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bMMU || !((address & JIT_ICACHE_VMEM_BIT) &&
Memory::TranslateAddress<Memory::FLAG_NO_EXCEPTION>(address)))
{
return "(No RAM here)";
}
}
u32 op = Memory::Read_Instruction(address);
std::string disasm = GekkoDisassembler::Disassemble(op, address);
UGeckoInstruction inst;
inst.hex = Memory::ReadUnchecked_U32(address);
if (inst.OPCD == 1)
{
disasm += " (hle)";
}
return disasm;
}
else
{
return "<unknown>";
}
}
void PPCDebugInterface::GetRawMemoryString(int memory, unsigned int address, char *dest, int max_size)
{
if (Core::GetState() != Core::CORE_UNINITIALIZED)
{
if (memory || Memory::IsRAMAddress(address, true, true))
{
snprintf(dest, max_size, "%08X%s", ReadExtraMemory(memory, address), memory ? " (ARAM)" : "");
}
else
{
strcpy(dest, memory ? "--ARAM--" : "--------");
}
}
else
{
strcpy(dest, "<unknwn>"); // bad spelling - 8 chars
}
}
unsigned int PPCDebugInterface::ReadMemory(unsigned int address)
{
return Memory::ReadUnchecked_U32(address);
}
unsigned int PPCDebugInterface::ReadExtraMemory(int memory, unsigned int address)
{
switch (memory)
{
case 0:
return Memory::ReadUnchecked_U32(address);
case 1:
return (DSP::ReadARAM(address) << 24) |
(DSP::ReadARAM(address + 1) << 16) |
(DSP::ReadARAM(address + 2) << 8) |
(DSP::ReadARAM(address + 3));
default:
return 0;
}
}
unsigned int PPCDebugInterface::ReadInstruction(unsigned int address)
{
return Memory::Read_Instruction(address);
}
bool PPCDebugInterface::IsAlive()
{
return Core::GetState() != Core::CORE_UNINITIALIZED;
}
bool PPCDebugInterface::IsBreakpoint(unsigned int address)
{
return PowerPC::breakpoints.IsAddressBreakPoint(address);
}
void PPCDebugInterface::SetBreakpoint(unsigned int address)
{
PowerPC::breakpoints.Add(address);
}
void PPCDebugInterface::ClearBreakpoint(unsigned int address)
{
PowerPC::breakpoints.Remove(address);
}
void PPCDebugInterface::ClearAllBreakpoints()
{
PowerPC::breakpoints.Clear();
}
void PPCDebugInterface::ToggleBreakpoint(unsigned int address)
{
if (PowerPC::breakpoints.IsAddressBreakPoint(address))
PowerPC::breakpoints.Remove(address);
else
PowerPC::breakpoints.Add(address);
}
void PPCDebugInterface::AddWatch(unsigned int address)
{
PowerPC::watches.Add(address);
}
void PPCDebugInterface::ClearAllMemChecks()
{
PowerPC::memchecks.Clear();
}
bool PPCDebugInterface::IsMemCheck(unsigned int address)
{
return (Memory::AreMemoryBreakpointsActivated() &&
PowerPC::memchecks.GetMemCheck(address));
}
void PPCDebugInterface::ToggleMemCheck(unsigned int address)
{
if (Memory::AreMemoryBreakpointsActivated() &&
!PowerPC::memchecks.GetMemCheck(address))
{
// Add Memory Check
TMemCheck MemCheck;
MemCheck.StartAddress = address;
MemCheck.EndAddress = address;
MemCheck.OnRead = true;
MemCheck.OnWrite = true;
MemCheck.Log = true;
MemCheck.Break = true;
PowerPC::memchecks.Add(MemCheck);
}
else
PowerPC::memchecks.Remove(address);
}
void PPCDebugInterface::InsertBLR(unsigned int address, unsigned int value)
{
Memory::Write_U32(value, address);
}
void PPCDebugInterface::BreakNow()
{
CCPU::Break();
}
// =======================================================
// Separate the blocks with colors.
// -------------
int PPCDebugInterface::GetColor(unsigned int address)
{
if (!Memory::IsRAMAddress(address, true, true))
return 0xeeeeee;
static const int colors[6] =
{
0xd0FFFF, // light cyan
0xFFd0d0, // light red
0xd8d8FF, // light blue
0xFFd0FF, // light purple
0xd0FFd0, // light green
0xFFFFd0, // light yellow
};
Symbol *symbol = g_symbolDB.GetSymbolFromAddr(address);
if (!symbol)
return 0xFFFFFF;
if (symbol->type != Symbol::SYMBOL_FUNCTION)
return 0xEEEEFF;
return colors[symbol->index % 6];
}
// =============
std::string PPCDebugInterface::GetDescription(unsigned int address)
{
return g_symbolDB.GetDescription(address);
}
unsigned int PPCDebugInterface::GetPC()
{
return PowerPC::ppcState.pc;
}
void PPCDebugInterface::SetPC(unsigned int address)
{
PowerPC::ppcState.pc = address;
}
void PPCDebugInterface::RunToBreakpoint()
{
}