Debugger/Memory: Add support for address spaces

Different address spaces can be chosen in the memory view panel.
 * Effective (or virtual): Probably the view people mostly want. Address
   translation goes through MMU.
 * Auxiliary: ARAM address space. Does not display anything in Wii mode.
 * Physical: Physical address space. Only supports mem1 and mem2 (wii
   mode) so far.
This commit is contained in:
booto
2019-04-11 01:50:52 -04:00
parent 3b16d2261a
commit 2ff0486335
14 changed files with 668 additions and 105 deletions

View File

@ -16,9 +16,7 @@
#include "Core/Core.h"
#include "Core/PowerPC/BreakPoints.h"
#include "Core/PowerPC/MMU.h"
#include "Core/PowerPC/PowerPC.h"
#include "DolphinQt/Resources.h"
#include "DolphinQt/Settings.h"
@ -74,6 +72,8 @@ void MemoryViewWidget::Update()
setRowHeight(0, 24);
const AddressSpace::Accessors* accessors = AddressSpace::GetAccessors(m_address_space);
// Calculate (roughly) how many rows will fit in our table
int rows = std::round((height() / static_cast<float>(rowHeight(0))) - 0.25);
@ -101,7 +101,7 @@ void MemoryViewWidget::Update()
if (addr == m_address)
addr_item->setSelected(true);
if (Core::GetState() != Core::State::Paused || !PowerPC::HostIsRAMAddress(addr))
if (Core::GetState() != Core::State::Paused || !accessors->IsValidAddress(addr))
{
for (int c = 2; c < columnCount(); c++)
{
@ -115,14 +115,16 @@ void MemoryViewWidget::Update()
continue;
}
auto* description_item =
new QTableWidgetItem(QString::fromStdString(PowerPC::debug_interface.GetDescription(addr)));
if (m_address_space == AddressSpace::Type::Effective)
{
auto* description_item = new QTableWidgetItem(
QString::fromStdString(PowerPC::debug_interface.GetDescription(addr)));
description_item->setForeground(Qt::blue);
description_item->setFlags(Qt::ItemIsEnabled);
setItem(i, columnCount() - 1, description_item);
description_item->setForeground(Qt::blue);
description_item->setFlags(Qt::ItemIsEnabled);
setItem(i, columnCount() - 1, description_item);
}
bool row_breakpoint = true;
auto update_values = [&](auto value_to_string) {
@ -132,14 +134,18 @@ void MemoryViewWidget::Update()
hex_item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
const u32 address = addr + c * (16 / GetColumnCount(m_type));
if (PowerPC::memchecks.OverlapsMemcheck(address, 16 / GetColumnCount(m_type)))
if (m_address_space == AddressSpace::Type::Effective &&
PowerPC::memchecks.OverlapsMemcheck(address, 16 / GetColumnCount(m_type)))
{
hex_item->setBackground(Qt::red);
}
else
{
row_breakpoint = false;
}
setItem(i, 2 + c, hex_item);
if (PowerPC::HostIsRAMAddress(address))
if (accessors->IsValidAddress(address))
{
hex_item->setText(value_to_string(address));
hex_item->setData(Qt::UserRole, address);
@ -151,35 +157,35 @@ void MemoryViewWidget::Update()
}
}
};
switch (m_type)
{
case Type::U8:
update_values([](u32 address) {
const u8 value = PowerPC::HostRead_U8(address);
update_values([&accessors](u32 address) {
const u8 value = accessors->ReadU8(address);
return QStringLiteral("%1").arg(value, 2, 16, QLatin1Char('0'));
});
break;
case Type::ASCII:
update_values([](u32 address) {
const char value = PowerPC::HostRead_U8(address);
update_values([&accessors](u32 address) {
const char value = accessors->ReadU8(address);
return std::isprint(value) ? QString{QChar::fromLatin1(value)} : QStringLiteral(".");
});
break;
case Type::U16:
update_values([](u32 address) {
const u16 value = PowerPC::HostRead_U16(address);
update_values([&accessors](u32 address) {
const u16 value = accessors->ReadU16(address);
return QStringLiteral("%1").arg(value, 4, 16, QLatin1Char('0'));
});
break;
case Type::U32:
update_values([](u32 address) {
const u32 value = PowerPC::HostRead_U32(address);
update_values([&accessors](u32 address) {
const u32 value = accessors->ReadU32(address);
return QStringLiteral("%1").arg(value, 8, 16, QLatin1Char('0'));
});
break;
case Type::Float32:
update_values([](u32 address) { return QString::number(PowerPC::HostRead_F32(address)); });
update_values(
[&accessors](u32 address) { return QString::number(accessors->ReadF32(address)); });
break;
}
@ -202,6 +208,22 @@ void MemoryViewWidget::Update()
update();
}
void MemoryViewWidget::SetAddressSpace(AddressSpace::Type address_space)
{
if (m_address_space == address_space)
{
return;
}
m_address_space = address_space;
Update();
}
AddressSpace::Type MemoryViewWidget::GetAddressSpace() const
{
return m_address_space;
}
void MemoryViewWidget::SetType(Type type)
{
if (m_type == type)
@ -273,21 +295,24 @@ void MemoryViewWidget::ToggleRowBreakpoint(bool row)
const u32 addr = row ? GetContextAddress() & 0xFFFFFFF0 : GetContextAddress();
const auto length = row ? 16 : (16 / GetColumnCount(m_type));
if (!PowerPC::memchecks.OverlapsMemcheck(addr, length))
if (m_address_space == AddressSpace::Type::Effective)
{
check.start_address = addr;
check.end_address = check.start_address + length - 1;
check.is_ranged = length > 0;
check.is_break_on_read = (m_bp_type == BPType::ReadOnly || m_bp_type == BPType::ReadWrite);
check.is_break_on_write = (m_bp_type == BPType::WriteOnly || m_bp_type == BPType::ReadWrite);
check.log_on_hit = m_do_log;
check.break_on_hit = true;
if (!PowerPC::memchecks.OverlapsMemcheck(addr, length))
{
check.start_address = addr;
check.end_address = check.start_address + length - 1;
check.is_ranged = length > 0;
check.is_break_on_read = (m_bp_type == BPType::ReadOnly || m_bp_type == BPType::ReadWrite);
check.is_break_on_write = (m_bp_type == BPType::WriteOnly || m_bp_type == BPType::ReadWrite);
check.log_on_hit = m_do_log;
check.break_on_hit = true;
PowerPC::memchecks.Add(check);
}
else
{
PowerPC::memchecks.Remove(addr);
PowerPC::memchecks.Add(check);
}
else
{
PowerPC::memchecks.Remove(addr);
}
}
emit BreakpointsChanged();
@ -348,7 +373,8 @@ void MemoryViewWidget::OnCopyHex()
const auto length = 16 / GetColumnCount(m_type);
u64 value = PowerPC::HostRead_U64(addr);
const AddressSpace::Accessors* accessors = AddressSpace::GetAccessors(m_address_space);
u64 value = accessors->ReadU64(addr);
QApplication::clipboard()->setText(
QStringLiteral("%1").arg(value, length * 2, 16, QLatin1Char('0')).left(length * 2));
@ -362,8 +388,9 @@ void MemoryViewWidget::OnContextMenu()
auto* copy_hex = menu->addAction(tr("Copy Hex"), this, &MemoryViewWidget::OnCopyHex);
const AddressSpace::Accessors* accessors = AddressSpace::GetAccessors(m_address_space);
copy_hex->setEnabled(Core::GetState() != Core::State::Uninitialized &&
PowerPC::HostIsRAMAddress(GetContextAddress()));
accessors->IsValidAddress(GetContextAddress()));
menu->addSeparator();