Skip to content

Commit

Permalink
UserspaceEmulator: Add a SoftMMU::read<T> function
Browse files Browse the repository at this point in the history
...and implement SoftCPU::read_memory<T> with it.
This allows the MMU to read a typed object (using 1-byte reads), which
is significantly nicer to use than reading the struct fields manually.
  • Loading branch information
alimpfard authored and awesomekling committed Mar 4, 2022
1 parent 70b53b4 commit baf7038
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 12 deletions.
20 changes: 8 additions & 12 deletions Userland/DevTools/UserspaceEmulator/SoftCPU.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

#pragma once

#include "AK/Debug.h"
#include "Emulator.h"
#include "Region.h"
#include "SoftFPU.h"
#include "ValueWithShadow.h"
Expand Down Expand Up @@ -367,18 +369,12 @@ class SoftCPU final
template<typename T>
ValueWithShadow<T> read_memory(X86::LogicalAddress address)
{
if constexpr (sizeof(T) == 1)
return read_memory8(address);
if constexpr (sizeof(T) == 2)
return read_memory16(address);
if constexpr (sizeof(T) == 4)
return read_memory32(address);
if constexpr (sizeof(T) == 8)
return read_memory64(address);
if constexpr (sizeof(T) == 16)
return read_memory128(address);
if constexpr (sizeof(T) == 32)
return read_memory256(address);
auto value = m_emulator.mmu().read<T>(address);
if constexpr (AK::HasFormatter<T>)
outln_if(MEMORY_DEBUG, "\033[36;1mread_memory: @{:#04x}:{:p} -> {:#064x} ({:hex-dump})\033[0m", address.selector(), address.offset(), value.value(), value.shadow().span());
else
outln_if(MEMORY_DEBUG, "\033[36;1mread_memory: @{:#04x}:{:p} -> ??? ({:hex-dump})\033[0m", address.selector(), address.offset(), value.shadow().span());
return value;
}

void write_memory8(X86::LogicalAddress, ValueWithShadow<u8>);
Expand Down
5 changes: 5 additions & 0 deletions Userland/DevTools/UserspaceEmulator/SoftMMU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -376,4 +376,9 @@ bool SoftMMU::fast_fill_memory32(X86::LogicalAddress address, size_t count, Valu
return true;
}

void SoftMMU::dump_backtrace()
{
m_emulator.dump_backtrace();
}

}
34 changes: 34 additions & 0 deletions Userland/DevTools/UserspaceEmulator/SoftMMU.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#pragma once

#include "Region.h"
#include "Report.h"
#include "ValueWithShadow.h"
#include <AK/HashMap.h>
#include <AK/NonnullOwnPtrVector.h>
Expand All @@ -29,6 +30,39 @@ class SoftMMU {
ValueWithShadow<u128> read128(X86::LogicalAddress);
ValueWithShadow<u256> read256(X86::LogicalAddress);

void dump_backtrace();

template<typename T>
ValueWithShadow<T> read(X86::LogicalAddress address) requires(IsTriviallyConstructible<T>)
{
auto* region = find_region(address);
if (!region) {
reportln("SoftMMU::read256: No region for @ {:p}", address.offset());
dump_backtrace();
TODO();
}

if (!region->is_readable()) {
reportln("SoftMMU::read256: Non-readable region @ {:p}", address.offset());
dump_backtrace();
TODO();
}

alignas(alignof(T)) u8 data[sizeof(T)];
Array<u8, sizeof(T)> shadow;

for (auto i = 0u; i < sizeof(T); ++i) {
auto result = region->read8(address.offset() - region->base() + i);
data[i] = result.value();
shadow[i] = result.shadow()[0];
}

return {
*bit_cast<T*>(&data[0]),
shadow,
};
}

void write8(X86::LogicalAddress, ValueWithShadow<u8>);
void write16(X86::LogicalAddress, ValueWithShadow<u16>);
void write32(X86::LogicalAddress, ValueWithShadow<u32>);
Expand Down

0 comments on commit baf7038

Please sign in to comment.