mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 08:07:44 +00:00
UserspaceEmulator: Add a SoftMMU::read<T> function
...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.
This commit is contained in:
parent
70b53b44b2
commit
baf7038919
3 changed files with 47 additions and 12 deletions
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "AK/Debug.h"
|
||||||
|
#include "Emulator.h"
|
||||||
#include "Region.h"
|
#include "Region.h"
|
||||||
#include "SoftFPU.h"
|
#include "SoftFPU.h"
|
||||||
#include "ValueWithShadow.h"
|
#include "ValueWithShadow.h"
|
||||||
|
@ -367,18 +369,12 @@ public:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ValueWithShadow<T> read_memory(X86::LogicalAddress address)
|
ValueWithShadow<T> read_memory(X86::LogicalAddress address)
|
||||||
{
|
{
|
||||||
if constexpr (sizeof(T) == 1)
|
auto value = m_emulator.mmu().read<T>(address);
|
||||||
return read_memory8(address);
|
if constexpr (AK::HasFormatter<T>)
|
||||||
if constexpr (sizeof(T) == 2)
|
outln_if(MEMORY_DEBUG, "\033[36;1mread_memory: @{:#04x}:{:p} -> {:#064x} ({:hex-dump})\033[0m", address.selector(), address.offset(), value.value(), value.shadow().span());
|
||||||
return read_memory16(address);
|
else
|
||||||
if constexpr (sizeof(T) == 4)
|
outln_if(MEMORY_DEBUG, "\033[36;1mread_memory: @{:#04x}:{:p} -> ??? ({:hex-dump})\033[0m", address.selector(), address.offset(), value.shadow().span());
|
||||||
return read_memory32(address);
|
return value;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_memory8(X86::LogicalAddress, ValueWithShadow<u8>);
|
void write_memory8(X86::LogicalAddress, ValueWithShadow<u8>);
|
||||||
|
|
|
@ -376,4 +376,9 @@ bool SoftMMU::fast_fill_memory32(X86::LogicalAddress address, size_t count, Valu
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoftMMU::dump_backtrace()
|
||||||
|
{
|
||||||
|
m_emulator.dump_backtrace();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Region.h"
|
#include "Region.h"
|
||||||
|
#include "Report.h"
|
||||||
#include "ValueWithShadow.h"
|
#include "ValueWithShadow.h"
|
||||||
#include <AK/HashMap.h>
|
#include <AK/HashMap.h>
|
||||||
#include <AK/NonnullOwnPtrVector.h>
|
#include <AK/NonnullOwnPtrVector.h>
|
||||||
|
@ -29,6 +30,39 @@ public:
|
||||||
ValueWithShadow<u128> read128(X86::LogicalAddress);
|
ValueWithShadow<u128> read128(X86::LogicalAddress);
|
||||||
ValueWithShadow<u256> read256(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 write8(X86::LogicalAddress, ValueWithShadow<u8>);
|
||||||
void write16(X86::LogicalAddress, ValueWithShadow<u16>);
|
void write16(X86::LogicalAddress, ValueWithShadow<u16>);
|
||||||
void write32(X86::LogicalAddress, ValueWithShadow<u32>);
|
void write32(X86::LogicalAddress, ValueWithShadow<u32>);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue