Starting to properly attribute virtual vs. physical memory accesses.

This commit is contained in:
Ben Vanik 2015-03-29 11:11:35 -07:00
parent ab90e0932b
commit ec84a688e9
42 changed files with 346 additions and 372 deletions

View File

@ -25,6 +25,10 @@ class AudioDriver {
virtual void SubmitFrame(uint32_t samples_ptr) = 0;
protected:
inline uint8_t* TranslatePhysical(uint32_t guest_address) const {
return memory_->TranslatePhysical(guest_address);
}
Emulator* emulator_;
Memory* memory_;
cpu::Processor* processor_;

View File

@ -182,7 +182,7 @@ uint32_t AudioSystem::AllocateXmaContext() {
auto guest_ptr = xma_context_free_list_.back();
xma_context_free_list_.pop_back();
auto context_ptr = memory()->Translate(guest_ptr);
auto context_ptr = memory()->TranslateVirtual(guest_ptr);
// Initialize?
@ -192,7 +192,7 @@ uint32_t AudioSystem::AllocateXmaContext() {
void AudioSystem::ReleaseXmaContext(uint32_t guest_ptr) {
std::lock_guard<std::mutex> lock(lock_);
auto context_ptr = memory()->Translate(guest_ptr);
auto context_ptr = memory()->TranslateVirtual(guest_ptr);
std::memset(context_ptr, 0, kXmaContextSize);
xma_context_free_list_.push_back(guest_ptr);
@ -217,8 +217,7 @@ X_STATUS AudioSystem::RegisterClient(uint32_t callback, uint32_t callback_arg,
unused_clients_.pop();
uint32_t ptr = memory()->SystemHeapAlloc(0x4);
auto mem = memory()->membase();
poly::store_and_swap<uint32_t>(mem + ptr, callback_arg);
poly::store_and_swap<uint32_t>(memory()->TranslateVirtual(ptr), callback_arg);
clients_[index] = {driver, callback, callback_arg, ptr};
@ -301,7 +300,7 @@ void AudioSystem::WriteRegister(uint64_t addr, uint64_t value) {
// feeding data.
uint32_t guest_ptr =
registers_.xma_context_array_ptr + context_id * kXmaContextSize;
auto context_ptr = memory()->Translate(guest_ptr);
auto context_ptr = memory()->TranslateVirtual(guest_ptr);
uint32_t dword0 = poly::load_and_swap<uint32_t>(context_ptr + 0);
bool has_valid_input = (dword0 & 0x00300000) != 0;
if (has_valid_input) {

View File

@ -122,7 +122,7 @@ void XAudio2AudioDriver::SubmitFrame(uint32_t frame_ptr) {
// Process samples! They are big-endian floats.
HRESULT hr;
auto input_frame = reinterpret_cast<float*>(emulator_->memory()->membase() + frame_ptr);
auto input_frame = memory_->TranslatePhysical<float*>(frame_ptr);
auto output_frame = reinterpret_cast<float*>(frame_);
auto interleave_channels = frame_channels_;

View File

@ -368,8 +368,7 @@ uint64_t TrapDebugPrint(void* raw_context, uint64_t address) {
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
uint32_t str_ptr = uint32_t(thread_state->context()->r[3]);
uint16_t str_len = uint16_t(thread_state->context()->r[4]);
const char* str =
reinterpret_cast<const char*>(thread_state->memory()->Translate(str_ptr));
auto str = thread_state->memory()->TranslateVirtual<const char*>(str_ptr);
// TODO(benvanik): truncate to length?
PLOGD("(DebugPrint) %s", str);
return 0;

View File

@ -37,7 +37,7 @@ int X64Function::RemoveBreakpointImpl(Breakpoint* breakpoint) { return 0; }
int X64Function::CallImpl(ThreadState* thread_state, uint32_t return_address) {
auto backend = (X64Backend*)thread_state->runtime()->backend();
auto thunk = backend->host_to_guest_thunk();
thunk(machine_code_, thread_state->raw_context(),
thunk(machine_code_, thread_state->context(),
reinterpret_cast<void*>(uintptr_t(return_address)));
return 0;
}

View File

@ -44,7 +44,7 @@ typedef struct alignas(64) PPCContext_s {
// TODO(benvanik): find a nice way to describe this to the JIT.
ThreadState* thread_state;
// TODO(benvanik): this is getting nasty. Must be here.
uint8_t* membase;
uint8_t* virtual_membase;
// Most frequently used registers first.
uint64_t r[32]; // General purpose registers
@ -210,6 +210,8 @@ typedef struct alignas(64) PPCContext_s {
// current runtime and its data.
Runtime* runtime;
uint8_t* physical_membase;
void SetRegFromString(const char* name, const char* value);
bool CompareRegWithString(const char* name, const char* value,
char* out_value, size_t out_value_size);

View File

@ -46,7 +46,6 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) {
SCOPE_profile_cpu_f("cpu");
Memory* memory = frontend_->memory();
const uint8_t* p = memory->membase();
symbol_info_ = symbol_info;
start_address_ = symbol_info->address();
@ -80,7 +79,7 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) {
for (uint32_t address = start_address, offset = 0; address <= end_address;
address += 4, offset++) {
i.address = address;
i.code = poly::load_and_swap<uint32_t>(p + address);
i.code = poly::load_and_swap<uint32_t>(memory->TranslateVirtual(address));
// TODO(benvanik): find a way to avoid using the opcode tables.
i.type = GetInstrType(i.code);
trace_info_.dest_count = 0;

View File

@ -50,7 +50,6 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
// split up and the second half is treated as another function.
Memory* memory = frontend_->memory();
const uint8_t* p = memory->membase();
LOGPPC("Analyzing function %.8X...", symbol_info->address());
@ -64,7 +63,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
InstrData i;
while (true) {
i.address = address;
i.code = poly::load_and_swap<uint32_t>(p + address);
i.code = poly::load_and_swap<uint32_t>(memory->TranslateVirtual(address));
// If we fetched 0 assume that we somehow hit one of the awesome
// 'no really we meant to end after that bl' functions.
@ -281,7 +280,6 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
std::vector<BlockInfo> PPCScanner::FindBlocks(FunctionInfo* symbol_info) {
Memory* memory = frontend_->memory();
const uint8_t* p = memory->membase();
std::map<uint32_t, BlockInfo> block_map;
@ -292,7 +290,7 @@ std::vector<BlockInfo> PPCScanner::FindBlocks(FunctionInfo* symbol_info) {
InstrData i;
for (uint32_t address = start_address; address <= end_address; address += 4) {
i.address = address;
i.code = poly::load_and_swap<uint32_t>(p + address);
i.code = poly::load_and_swap<uint32_t>(memory->TranslateVirtual(address));
if (!i.code) {
continue;
}

View File

@ -175,7 +175,6 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info,
void PPCTranslator::DumpSource(FunctionInfo* symbol_info,
poly::StringBuffer* string_buffer) {
Memory* memory = frontend_->memory();
const uint8_t* p = memory->membase();
string_buffer->Append("%s fn %.8X-%.8X %s\n",
symbol_info->module()->name().c_str(),
@ -184,14 +183,14 @@ void PPCTranslator::DumpSource(FunctionInfo* symbol_info,
auto blocks = scanner_->FindBlocks(symbol_info);
uint64_t start_address = symbol_info->address();
uint64_t end_address = symbol_info->end_address();
uint32_t start_address = symbol_info->address();
uint32_t end_address = symbol_info->end_address();
InstrData i;
auto block_it = blocks.begin();
for (uint64_t address = start_address, offset = 0; address <= end_address;
for (uint32_t address = start_address, offset = 0; address <= end_address;
address += 4, offset++) {
i.address = address;
i.code = poly::load_and_swap<uint32_t>(p + address);
i.code = poly::load_and_swap<uint32_t>(memory->TranslateVirtual(address));
// TODO(benvanik): find a way to avoid using the opcode tables.
i.type = GetInstrType(i.code);

View File

@ -241,7 +241,7 @@ class TestRunner {
auto address_str = it.second.substr(0, space_pos);
auto bytes_str = it.second.substr(space_pos + 1);
uint32_t address = std::strtoul(address_str.c_str(), nullptr, 16);
auto p = memory->Translate(address);
auto p = memory->TranslateVirtual(address);
const char* c = bytes_str.c_str();
while (*c) {
while (*c == ' ') ++c;
@ -283,7 +283,7 @@ class TestRunner {
auto address_str = it.second.substr(0, space_pos);
auto bytes_str = it.second.substr(space_pos + 1);
uint32_t address = std::strtoul(address_str.c_str(), nullptr, 16);
auto base_address = memory->Translate(address);
auto base_address = memory->TranslateVirtual(address);
auto p = base_address;
const char* c = bytes_str.c_str();
while (*c) {

View File

@ -88,7 +88,7 @@ int Function::Call(ThreadState* thread_state, uint32_t return_address) {
}
if (handler) {
handler(thread_state->raw_context(), symbol_info_->extern_arg0(),
handler(thread_state->context(), symbol_info_->extern_arg0(),
symbol_info_->extern_arg1());
} else {
PLOGW("undefined extern call to %.8llX %s", symbol_info_->address(),

View File

@ -163,8 +163,8 @@ uint64_t Processor::ExecuteInterrupt(uint32_t cpu, uint32_t address,
std::lock_guard<std::mutex> lock(interrupt_thread_lock_);
// Set 0x10C(r13) to the current CPU ID.
uint8_t* p = memory_->membase();
poly::store_and_swap<uint8_t>(p + interrupt_thread_block_ + 0x10C, cpu);
poly::store_and_swap<uint8_t>(
memory_->TranslateVirtual(interrupt_thread_block_ + 0x10C), cpu);
// Execute interrupt.
uint64_t result = Execute(interrupt_thread_state_, address, args, arg_count);

View File

@ -30,8 +30,8 @@ int RawModule::LoadFile(uint32_t base_address, const std::wstring& path) {
// Allocate memory.
// Since we have no real heap just load it wherever.
base_address_ = base_address;
uint8_t* p = memory_->Translate(base_address_);
memset(p, 0, file_length);
uint8_t* p = memory_->TranslateVirtual(base_address_);
std::memset(p, 0, file_length);
// Read into memory.
fread(p, file_length, 1, file);

View File

@ -29,7 +29,6 @@ ThreadState::ThreadState(Runtime* runtime, uint32_t thread_id,
thread_id_(thread_id),
name_(""),
backend_data_(0),
raw_context_(0),
stack_size_(stack_size),
thread_state_address_(thread_state_address) {
if (thread_id_ == UINT_MAX) {
@ -50,13 +49,16 @@ ThreadState::ThreadState(Runtime* runtime, uint32_t thread_id,
assert_not_zero(stack_address_);
// Allocate with 64b alignment.
context_ = (PPCContext*)calloc(1, sizeof(PPCContext));
assert_true(((uint64_t)context_ & 0xF) == 0);
context_ =
reinterpret_cast<PPCContext*>(_aligned_malloc(sizeof(PPCContext), 64));
assert_true(((uint64_t)context_ & 0x3F) == 0);
std::memset(context_, 0, sizeof(PPCContext));
// Stash pointers to common structures that callbacks may need.
context_->reserve_address = memory_->reserve_address();
context_->reserve_value = memory_->reserve_value();
context_->membase = memory_->membase();
context_->virtual_membase = memory_->virtual_membase();
context_->physical_membase = memory_->physical_membase();
context_->runtime = runtime;
context_->thread_state = this;
context_->thread_id = thread_id_;
@ -69,8 +71,6 @@ ThreadState::ThreadState(Runtime* runtime, uint32_t thread_id,
// 16 to 32b.
context_->r[1] -= 64;
raw_context_ = context_;
runtime_->debugger()->OnThreadCreated(this);
}
@ -84,7 +84,7 @@ ThreadState::~ThreadState() {
thread_state_ = nullptr;
}
free(context_);
_aligned_free(context_);
if (stack_allocated_) {
memory()->SystemHeapFree(stack_address_);
}

View File

@ -38,7 +38,6 @@ class ThreadState {
const std::string& name() const { return name_; }
void set_name(const std::string& value) { name_ = value; }
void* backend_data() const { return backend_data_; }
void* raw_context() const { return raw_context_; }
uint32_t stack_address() const { return stack_address_; }
size_t stack_size() const { return stack_size_; }
uint32_t thread_state_address() const { return thread_state_address_; }
@ -60,7 +59,6 @@ class ThreadState {
uint32_t thread_id_;
std::string name_;
void* backend_data_;
void* raw_context_;
uint32_t stack_address_;
bool stack_allocated_;
uint32_t stack_size_;

View File

@ -99,8 +99,6 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) {
return 1;
}
uint8_t* membase = memory_->membase();
char name[128];
for (size_t n = 0; n < import_info_count; n++) {
const xe_xex2_import_info_t* info = &import_infos[n];
@ -129,7 +127,7 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) {
// Grab, if available.
if (kernel_export) {
uint32_t* slot = (uint32_t*)(membase + info->value_address);
auto slot = memory_->TranslateVirtual<uint32_t*>(info->value_address);
if (kernel_export->type == KernelExport::Function) {
// Not exactly sure what this should be...
if (info->thunk_address) {
@ -176,7 +174,7 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) {
// blr
// nop
// nop
uint8_t* p = memory()->Translate(info->thunk_address);
uint8_t* p = memory()->TranslateVirtual(info->thunk_address);
poly::store_and_swap<uint32_t>(p + 0x0, 0x44000002);
poly::store_and_swap<uint32_t>(p + 0x4, 0x4E800020);
poly::store_and_swap<uint32_t>(p + 0x8, 0x60000000);

View File

@ -202,7 +202,7 @@ X_STATUS Emulator::CompleteLaunch(const std::wstring& path,
auto ev = xdb::protocol::ProcessStartEvent::Append(memory()->trace_base());
if (ev) {
ev->type = xdb::protocol::EventType::PROCESS_START;
ev->membase = reinterpret_cast<uint64_t>(memory()->membase());
ev->membase = reinterpret_cast<uint64_t>(memory()->virtual_membase());
auto path_length = poly::to_string(path)
.copy(ev->launch_path, sizeof(ev->launch_path) - 1);
ev->launch_path[path_length] = 0;

View File

@ -51,10 +51,9 @@ CommandProcessor::CachedPipeline::~CachedPipeline() {
CommandProcessor::CommandProcessor(GL4GraphicsSystem* graphics_system)
: memory_(graphics_system->memory()),
membase_(graphics_system->memory()->membase()),
graphics_system_(graphics_system),
register_file_(graphics_system_->register_file()),
trace_writer_(graphics_system->memory()->membase()),
trace_writer_(graphics_system->memory()->physical_membase()),
trace_state_(TraceState::kDisabled),
worker_running_(true),
swap_mode_(SwapMode::kNormal),
@ -212,8 +211,8 @@ void CommandProcessor::WorkerMain() {
// TODO(benvanik): use reader->Read_update_freq_ and only issue after moving
// that many indices.
if (read_ptr_writeback_ptr_) {
poly::store_and_swap<uint32_t>(membase_ + read_ptr_writeback_ptr_,
read_ptr_index_);
poly::store_and_swap<uint32_t>(
memory_->TranslatePhysical(read_ptr_writeback_ptr_), read_ptr_index_);
}
}
@ -488,7 +487,7 @@ void CommandProcessor::WriteRegister(uint32_t index, uint32_t value) {
// Enabled - write to address.
uint32_t scratch_addr = regs->values[XE_GPU_REG_SCRATCH_ADDR].u32;
uint32_t mem_addr = scratch_addr + (scratch_reg * 4);
poly::store_and_swap<uint32_t>(membase_ + xenos::GpuToCpu(mem_addr),
poly::store_and_swap<uint32_t>(memory_->TranslatePhysical(mem_addr),
value);
}
}
@ -651,8 +650,8 @@ void CommandProcessor::ExecutePrimaryBuffer(uint32_t start_index,
// Execute commands!
uint32_t ptr_mask = (primary_buffer_size_ / sizeof(uint32_t)) - 1;
RingbufferReader reader(membase_, primary_buffer_ptr_, ptr_mask, start_ptr,
end_ptr);
RingbufferReader reader(memory_->physical_membase(), primary_buffer_ptr_,
ptr_mask, start_ptr, end_ptr);
while (reader.can_read()) {
ExecutePacket(&reader);
}
@ -670,8 +669,8 @@ void CommandProcessor::ExecuteIndirectBuffer(uint32_t ptr, uint32_t length) {
// Execute commands!
uint32_t ptr_mask = 0;
RingbufferReader reader(membase_, primary_buffer_ptr_, ptr_mask, ptr,
ptr + length * sizeof(uint32_t));
RingbufferReader reader(memory_->physical_membase(), primary_buffer_ptr_,
ptr_mask, ptr, ptr + length * sizeof(uint32_t));
while (reader.can_read()) {
ExecutePacket(&reader);
}
@ -681,8 +680,8 @@ void CommandProcessor::ExecuteIndirectBuffer(uint32_t ptr, uint32_t length) {
void CommandProcessor::ExecutePacket(uint32_t ptr, uint32_t count) {
uint32_t ptr_mask = 0;
RingbufferReader reader(membase_, primary_buffer_ptr_, ptr_mask, ptr,
ptr + count * sizeof(uint32_t));
RingbufferReader reader(memory_->physical_membase(), primary_buffer_ptr_,
ptr_mask, ptr, ptr + count * sizeof(uint32_t));
while (reader.can_read()) {
ExecutePacket(&reader);
}
@ -992,7 +991,7 @@ bool CommandProcessor::ExecutePacketType3_WAIT_REG_MEM(RingbufferReader* reader,
// Memory.
auto endianness = static_cast<Endian>(poll_reg_addr & 0x3);
poll_reg_addr &= ~0x3;
value = poly::load<uint32_t>(membase_ + GpuToCpu(poll_reg_addr));
value = poly::load<uint32_t>(memory_->TranslatePhysical(poll_reg_addr));
value = GpuSwap(value, endianness);
trace_writer_.WriteMemoryRead(poll_reg_addr, 4);
} else {
@ -1095,7 +1094,7 @@ bool CommandProcessor::ExecutePacketType3_COND_WRITE(RingbufferReader* reader,
auto endianness = static_cast<Endian>(poll_reg_addr & 0x3);
poll_reg_addr &= ~0x3;
trace_writer_.WriteMemoryRead(poll_reg_addr, 4);
value = poly::load<uint32_t>(membase_ + GpuToCpu(poll_reg_addr));
value = poly::load<uint32_t>(memory_->TranslatePhysical(poll_reg_addr));
value = GpuSwap(value, endianness);
} else {
// Register.
@ -1136,7 +1135,7 @@ bool CommandProcessor::ExecutePacketType3_COND_WRITE(RingbufferReader* reader,
auto endianness = static_cast<Endian>(write_reg_addr & 0x3);
write_reg_addr &= ~0x3;
write_data = GpuSwap(write_data, endianness);
poly::store(membase_ + GpuToCpu(write_reg_addr), write_data);
poly::store(memory_->TranslatePhysical(write_reg_addr), write_data);
trace_writer_.WriteMemoryWrite(write_reg_addr, 4);
} else {
// Register.
@ -1182,7 +1181,7 @@ bool CommandProcessor::ExecutePacketType3_EVENT_WRITE_SHD(
auto endianness = static_cast<Endian>(address & 0x3);
address &= ~0x3;
data_value = GpuSwap(data_value, endianness);
poly::store(membase_ + GpuToCpu(address), data_value);
poly::store(memory_->TranslatePhysical(address), data_value);
trace_writer_.WriteMemoryWrite(address, 4);
return true;
}
@ -1207,7 +1206,7 @@ bool CommandProcessor::ExecutePacketType3_EVENT_WRITE_EXT(
};
assert_true(endianness == xenos::Endian::k8in16);
poly::copy_and_swap_16_aligned(
reinterpret_cast<uint16_t*>(membase_ + GpuToCpu(address)), extents,
reinterpret_cast<uint16_t*>(memory_->TranslatePhysical(address)), extents,
poly::countof(extents));
trace_writer_.WriteMemoryWrite(address, sizeof(extents));
return true;
@ -1367,8 +1366,8 @@ bool CommandProcessor::ExecutePacketType3_LOAD_ALU_CONSTANT(
}
trace_writer_.WriteMemoryRead(address, size_dwords * 4);
for (uint32_t n = 0; n < size_dwords; n++, index++) {
uint32_t data =
poly::load_and_swap<uint32_t>(membase_ + GpuToCpu(address + n * 4));
uint32_t data = poly::load_and_swap<uint32_t>(
memory_->TranslatePhysical(address + n * 4));
WriteRegister(index, data);
}
return true;
@ -1397,8 +1396,7 @@ bool CommandProcessor::ExecutePacketType3_IM_LOAD(RingbufferReader* reader,
uint32_t size_dwords = start_size & 0xFFFF; // dwords
assert_true(start == 0);
trace_writer_.WriteMemoryRead(addr, size_dwords * 4);
LoadShader(shader_type,
reinterpret_cast<uint32_t*>(membase_ + GpuToCpu(addr)),
LoadShader(shader_type, addr, memory_->TranslatePhysical<uint32_t*>(addr),
size_dwords);
return true;
}
@ -1414,8 +1412,8 @@ bool CommandProcessor::ExecutePacketType3_IM_LOAD_IMMEDIATE(
uint32_t size_dwords = start_size & 0xFFFF; // dwords
assert_true(start == 0);
reader->CheckRead(size_dwords);
LoadShader(shader_type, reinterpret_cast<uint32_t*>(membase_ + reader->ptr()),
size_dwords);
LoadShader(shader_type, reader->ptr(),
memory_->TranslatePhysical<uint32_t*>(reader->ptr()), size_dwords);
reader->Advance(size_dwords);
return true;
}
@ -1429,11 +1427,12 @@ bool CommandProcessor::ExecutePacketType3_INVALIDATE_STATE(
}
bool CommandProcessor::LoadShader(ShaderType shader_type,
const uint32_t* address,
uint32_t guest_address,
const uint32_t* host_address,
uint32_t dword_count) {
// Hash the input memory and lookup the shader.
GL4Shader* shader_ptr = nullptr;
uint64_t hash = XXH64(address, dword_count * sizeof(uint32_t), 0);
uint64_t hash = XXH64(host_address, dword_count * sizeof(uint32_t), 0);
auto it = shader_cache_.find(hash);
if (it != shader_cache_.end()) {
// Found in the cache.
@ -1442,17 +1441,16 @@ bool CommandProcessor::LoadShader(ShaderType shader_type,
} else {
// Not found in cache.
// No translation is performed here, as it depends on program_cntl.
auto shader =
std::make_unique<GL4Shader>(shader_type, hash, address, dword_count);
auto shader = std::make_unique<GL4Shader>(shader_type, hash, host_address,
dword_count);
shader_ptr = shader.get();
shader_cache_.insert({hash, shader_ptr});
all_shaders_.emplace_back(std::move(shader));
XELOGGPU("Set %s shader at %0.8X (%db):\n%s",
shader_type == ShaderType::kVertex ? "vertex" : "pixel",
uint32_t(reinterpret_cast<uintptr_t>(address) -
reinterpret_cast<uintptr_t>(membase_)),
dword_count * 4, shader_ptr->ucode_disassembly().c_str());
guest_address, dword_count * 4,
shader_ptr->ucode_disassembly().c_str());
}
switch (shader_type) {
case ShaderType::kVertex:
@ -2299,11 +2297,11 @@ CommandProcessor::UpdateStatus CommandProcessor::PopulateIndexBuffer() {
&allocation)) {
if (info.format == IndexFormat::kInt32) {
auto dest = reinterpret_cast<uint32_t*>(allocation.host_ptr);
auto src = reinterpret_cast<const uint32_t*>(membase_ + info.guest_base);
auto src = memory_->TranslatePhysical<const uint32_t*>(info.guest_base);
poly::copy_and_swap_32_aligned(dest, src, info.count);
} else {
auto dest = reinterpret_cast<uint16_t*>(allocation.host_ptr);
auto src = reinterpret_cast<const uint16_t*>(membase_ + info.guest_base);
auto src = memory_->TranslatePhysical<const uint16_t*>(info.guest_base);
poly::copy_and_swap_16_aligned(dest, src, info.count);
}
draw_batcher_.set_index_buffer(allocation);
@ -2357,7 +2355,7 @@ CommandProcessor::UpdateStatus CommandProcessor::PopulateVertexBuffers() {
// it (and if it matches just discard and reuse).
poly::copy_and_swap_32_aligned(
reinterpret_cast<uint32_t*>(allocation.host_ptr),
reinterpret_cast<const uint32_t*>(membase_ + (fetch->address << 2)),
memory_->TranslatePhysical<const uint32_t*>(fetch->address << 2),
valid_range / 4);
if (!has_bindless_vbos_) {
@ -2697,7 +2695,7 @@ bool CommandProcessor::IssueCopy() {
assert_true(fetch->type == 3);
assert_true(fetch->endian == 2);
assert_true(fetch->size == 6);
const uint8_t* vertex_addr = membase_ + (fetch->address << 2);
const uint8_t* vertex_addr = memory_->TranslatePhysical(fetch->address << 2);
trace_writer_.WriteMemoryRead(fetch->address << 2, fetch->size * 4);
int32_t dest_min_x = int32_t((std::min(
std::min(
@ -2734,7 +2732,7 @@ bool CommandProcessor::IssueCopy() {
// Destination pointer in guest memory.
// We have GL throw bytes directly into it.
// TODO(benvanik): copy to staging texture then PBO back?
void* ptr = membase_ + GpuToCpu(copy_dest_base);
void* ptr = memory_->TranslatePhysical(copy_dest_base);
// Make active so glReadPixels reads from us.
switch (copy_command) {

View File

@ -193,8 +193,8 @@ class CommandProcessor {
bool ExecutePacketType3_INVALIDATE_STATE(RingbufferReader* reader,
uint32_t packet, uint32_t count);
bool LoadShader(ShaderType shader_type, const uint32_t* address,
uint32_t dword_count);
bool LoadShader(ShaderType shader_type, uint32_t guest_address,
const uint32_t* host_address, uint32_t dword_count);
bool IssueDraw();
UpdateStatus UpdateShaders(PrimitiveType prim_type);
@ -214,7 +214,6 @@ class CommandProcessor {
GLuint depth_target);
Memory* memory_;
uint8_t* membase_;
GL4GraphicsSystem* graphics_system_;
RegisterFile* register_file_;

View File

@ -181,7 +181,7 @@ void GL4GraphicsSystem::PlayTrace(const uint8_t* trace_data, size_t trace_size,
case TraceCommandType::kPacketStart: {
auto cmd = reinterpret_cast<const PacketStartCommand*>(trace_ptr);
trace_ptr += sizeof(*cmd);
std::memcpy(memory()->Translate(cmd->base_ptr), trace_ptr,
std::memcpy(memory()->TranslatePhysical(cmd->base_ptr), trace_ptr,
cmd->count * 4);
trace_ptr += cmd->count * 4;
pending_packet = cmd;
@ -203,7 +203,7 @@ void GL4GraphicsSystem::PlayTrace(const uint8_t* trace_data, size_t trace_size,
case TraceCommandType::kMemoryRead: {
auto cmd = reinterpret_cast<const MemoryReadCommand*>(trace_ptr);
trace_ptr += sizeof(*cmd);
std::memcpy(memory()->Translate(cmd->base_ptr), trace_ptr,
std::memcpy(memory()->TranslatePhysical(cmd->base_ptr), trace_ptr,
cmd->length);
trace_ptr += cmd->length;
break;

View File

@ -676,7 +676,8 @@ void TextureSwap(Endian endianness, void* dest, const void* src,
bool TextureCache::UploadTexture2D(GLuint texture,
const TextureInfo& texture_info) {
const auto host_address = memory_->Translate(texture_info.guest_address);
const auto host_address =
memory_->TranslatePhysical(texture_info.guest_address);
const auto& config =
texture_configs[uint32_t(texture_info.format_info->format)];
@ -778,7 +779,8 @@ bool TextureCache::UploadTexture2D(GLuint texture,
bool TextureCache::UploadTextureCube(GLuint texture,
const TextureInfo& texture_info) {
const auto host_address = memory_->Translate(texture_info.guest_address);
const auto host_address =
memory_->TranslatePhysical(texture_info.guest_address);
const auto& config =
texture_configs[uint32_t(texture_info.format_info->format)];

View File

@ -832,7 +832,7 @@ class TracePlayer : public TraceReader {
};
void DrawControllerUI(xe::ui::MainWindow* window, TracePlayer& player,
uint8_t* membase) {
Memory* memory) {
ImGui::SetNextWindowPos(ImVec2(5, 5), ImGuiSetCondition_FirstUseEver);
if (!ImGui::Begin("Controller", nullptr, ImVec2(340, 60))) {
ImGui::End();
@ -871,7 +871,7 @@ void DrawControllerUI(xe::ui::MainWindow* window, TracePlayer& player,
}
void DrawCommandListUI(xe::ui::MainWindow* window, TracePlayer& player,
uint8_t* membase) {
Memory* memory) {
ImGui::SetNextWindowPos(ImVec2(5, 70), ImGuiSetCondition_FirstUseEver);
if (!ImGui::Begin("Command List", nullptr, ImVec2(200, 640))) {
ImGui::End();
@ -1013,7 +1013,7 @@ ShaderDisplayType DrawShaderTypeUI() {
}
void DrawShaderUI(xe::ui::MainWindow* window, TracePlayer& player,
uint8_t* membase, gl4::GL4Shader* shader,
Memory* memory, gl4::GL4Shader* shader,
ShaderDisplayType display_type) {
// Must be prepared for advanced display modes.
if (display_type != ShaderDisplayType::kUcode) {
@ -1166,10 +1166,10 @@ void DrawTextureInfo(TracePlayer& player, const Shader::SamplerDesc& desc) {
ImGui::Columns(1);
}
void DrawVertexFetcher(const uint8_t* membase, gl4::GL4Shader* shader,
void DrawVertexFetcher(const Memory* memory, gl4::GL4Shader* shader,
const Shader::BufferDesc& desc,
const xe_gpu_vertex_fetch_t* fetch) {
const uint8_t* addr = membase + (fetch->address << 2);
const uint8_t* addr = memory->TranslatePhysical(fetch->address << 2);
uint32_t vertex_count = (fetch->size * 4) / desc.stride_words;
int column_count = 0;
for (uint32_t el_index = 0; el_index < desc.element_count; ++el_index) {
@ -1379,7 +1379,7 @@ static const char* kEndiannessNames[] = {
};
void DrawStateUI(xe::ui::MainWindow* window, TracePlayer& player,
uint8_t* membase) {
Memory* memory) {
auto gs = static_cast<gl4::GL4GraphicsSystem*>(player.graphics_system());
auto cp = gs->command_processor();
auto& regs = *gs->register_file();
@ -1809,7 +1809,7 @@ void DrawStateUI(xe::ui::MainWindow* window, TracePlayer& player,
ImGui::BeginChild("#vertex_shader_text", ImVec2(0, 400));
auto shader = cp->active_vertex_shader();
if (shader) {
DrawShaderUI(window, player, membase, shader, shader_display_type);
DrawShaderUI(window, player, memory, shader, shader_display_type);
} else {
ImGui::TextColored(kColorError, "ERROR: no vertex shader set");
}
@ -1820,7 +1820,7 @@ void DrawStateUI(xe::ui::MainWindow* window, TracePlayer& player,
ImGui::BeginChild("#pixel_shader_text", ImVec2(0, 400));
auto shader = cp->active_pixel_shader();
if (shader) {
DrawShaderUI(window, player, membase, shader, shader_display_type);
DrawShaderUI(window, player, memory, shader, shader_display_type);
} else {
ImGui::TextColored(kColorError, "ERROR: no pixel shader set");
}
@ -1864,10 +1864,10 @@ void DrawStateUI(xe::ui::MainWindow* window, TracePlayer& player,
ImGui::NextColumn();
ImGui::Separator();
}
size_t element_size =
uint32_t element_size =
draw_info.index_format == IndexFormat::kInt32 ? 4 : 2;
const uint8_t* data_ptr =
membase + draw_info.index_buffer_ptr + (display_start * element_size);
const uint8_t* data_ptr = memory->TranslatePhysical(
draw_info.index_buffer_ptr + (display_start * element_size));
for (int i = display_start; i < display_end;
++i, data_ptr += element_size) {
if (i < 10) {
@ -1927,7 +1927,7 @@ void DrawStateUI(xe::ui::MainWindow* window, TracePlayer& player,
fetch->size * 4,
kEndiannessNames[int(fetch->endian)])) {
ImGui::BeginChild("#vertices", ImVec2(0, 300));
DrawVertexFetcher(membase, shader, desc, fetch);
DrawVertexFetcher(memory, shader, desc, fetch);
ImGui::EndChild();
ImGui::TreePop();
}
@ -2019,7 +2019,7 @@ void DrawStateUI(xe::ui::MainWindow* window, TracePlayer& player,
}
void DrawPacketDisassemblerUI(xe::ui::MainWindow* window, TracePlayer& player,
uint8_t* membase) {
Memory* memory) {
ImGui::SetNextWindowCollapsed(true, ImGuiSetCondition_FirstUseEver);
ImGui::SetNextWindowPos(ImVec2(float(window->width()) - 500 - 5, 5),
ImGuiSetCondition_FirstUseEver);
@ -2160,13 +2160,13 @@ void DrawPacketDisassemblerUI(xe::ui::MainWindow* window, TracePlayer& player,
ImGui::End();
}
void DrawUI(xe::ui::MainWindow* window, TracePlayer& player, uint8_t* membase) {
void DrawUI(xe::ui::MainWindow* window, TracePlayer& player, Memory* memory) {
ImGui::ShowTestWindow();
DrawControllerUI(window, player, membase);
DrawCommandListUI(window, player, membase);
DrawStateUI(window, player, membase);
DrawPacketDisassemblerUI(window, player, membase);
DrawControllerUI(window, player, memory);
DrawCommandListUI(window, player, memory);
DrawStateUI(window, player, memory);
DrawPacketDisassemblerUI(window, player, memory);
}
void ImImpl_Setup();
@ -2276,7 +2276,7 @@ int trace_viewer_main(std::vector<std::wstring>& args) {
ImGui::NewFrame();
DrawUI(window, player, emulator->memory()->membase());
DrawUI(window, player, emulator->memory());
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
ImGui::Render();

View File

@ -16,8 +16,8 @@ namespace kernel {
XApp::XApp(KernelState* kernel_state, uint32_t app_id)
: kernel_state_(kernel_state),
app_id_(app_id),
membase_(kernel_state->memory()->membase()) {}
memory_(kernel_state->memory()),
app_id_(app_id) {}
void XAppManager::RegisterApp(std::unique_ptr<XApp> app) {
assert_zero(app_lookup_.count(app->app_id()));

View File

@ -33,8 +33,8 @@ class XApp {
XApp(KernelState* kernel_state, uint32_t app_id);
KernelState* kernel_state_;
Memory* memory_;
uint32_t app_id_;
uint8_t* membase_;
};
class XAppManager {

View File

@ -22,6 +22,7 @@ XXGIApp::XXGIApp(KernelState* kernel_state) : XApp(kernel_state, 0xFB) {}
X_RESULT XXGIApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
uint32_t buffer_length) {
// NOTE: buffer_length may be zero or valid.
auto buffer = memory_->TranslateVirtual(buffer_ptr);
switch (message) {
case 0x000B0006: {
assert_true(!buffer_length || buffer_length == 24);
@ -30,35 +31,26 @@ X_RESULT XXGIApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
// qword 0
// dword r4 context enum
// dword r5 value
uint32_t user_index =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t context_id =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 16);
uint32_t context_value =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 20);
uint32_t user_index = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t context_id = poly::load_and_swap<uint32_t>(buffer + 16);
uint32_t context_value = poly::load_and_swap<uint32_t>(buffer + 20);
XELOGD("XUserSetContextEx(%.8X, %.8X, %.8X)", user_index, context_id,
context_value);
return X_ERROR_SUCCESS;
}
case 0x000B0007: {
uint32_t user_index =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t property_id =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 16);
uint32_t value_size =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 20);
uint32_t value_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 24);
uint32_t user_index = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t property_id = poly::load_and_swap<uint32_t>(buffer + 16);
uint32_t value_size = poly::load_and_swap<uint32_t>(buffer + 20);
uint32_t value_ptr = poly::load_and_swap<uint32_t>(buffer + 24);
XELOGD("XUserSetPropertyEx(%.8X, %.8X, %d, %.8X)", user_index,
property_id, value_size, value_ptr);
return X_ERROR_SUCCESS;
}
case 0x000B0008: {
assert_true(!buffer_length || buffer_length == 8);
uint32_t achievement_count =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t achievements_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 4);
uint32_t achievement_count = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t achievements_ptr = poly::load_and_swap<uint32_t>(buffer + 4);
XELOGD("XUserWriteAchievements(%.8X, %.8X)", achievement_count,
achievements_ptr);
return X_ERROR_SUCCESS;
@ -76,16 +68,14 @@ X_RESULT XXGIApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
case 0x000B0041: {
assert_true(!buffer_length || buffer_length == 32);
// 00000000 2789fecc 00000000 00000000 200491e0 00000000 200491f0 20049340
uint32_t user_index =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t context_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 16);
uint32_t context_id =
poly::load_and_swap<uint32_t>(membase_ + context_ptr + 0);
uint32_t user_index = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t context_ptr = poly::load_and_swap<uint32_t>(buffer + 16);
auto context = memory_->TranslateVirtual(context_ptr);
uint32_t context_id = poly::load_and_swap<uint32_t>(context + 0);
XELOGD("XUserGetContext(%.8X, %.8X(%.8X))", user_index, context_ptr,
context_id);
uint32_t value = 0;
poly::store_and_swap<uint32_t>(membase_ + context_ptr + 4, value);
poly::store_and_swap<uint32_t>(context + 4, value);
return X_ERROR_SUCCESS;
}
case 0x000B0071: {

View File

@ -24,12 +24,13 @@ X_RESULT XXLiveBaseApp::DispatchMessageSync(uint32_t message,
uint32_t buffer_ptr,
uint32_t buffer_length) {
// NOTE: buffer_length may be zero or valid.
auto buffer = memory_->TranslateVirtual(buffer_ptr);
switch (message) {
case 0x00058004: {
// Called on startup, seems to just return a bool in the buffer.
assert_true(!buffer_length || buffer_length == 4);
XELOGD("XLiveBaseGetLogonId(%.8X)", buffer_ptr);
poly::store_and_swap<uint32_t>(membase_ + buffer_ptr + 0, 1); // ?
poly::store_and_swap<uint32_t>(buffer + 0, 1); // ?
return X_ERROR_SUCCESS;
}
case 0x00058020: {

View File

@ -34,7 +34,7 @@ X_RESULT XXMPApp::XMPGetStatus(uint32_t state_ptr) {
Sleep(1);
XELOGD("XMPGetStatus(%.8X)", state_ptr);
poly::store_and_swap<uint32_t>(membase_ + state_ptr,
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(state_ptr),
static_cast<uint32_t>(state_));
return X_ERROR_SUCCESS;
}
@ -54,30 +54,32 @@ X_RESULT XXMPApp::XMPCreateTitlePlaylist(
for (uint32_t i = 0; i < song_count; ++i) {
auto song = std::make_unique<Song>();
song->handle = ++next_song_handle_;
uint8_t* song_base = membase_ + songs_ptr + (i * 36);
song->file_path = poly::load_and_swap<std::wstring>(
membase_ + poly::load_and_swap<uint32_t>(song_base + 0));
song->name = poly::load_and_swap<std::wstring>(
membase_ + poly::load_and_swap<uint32_t>(song_base + 4));
song->artist = poly::load_and_swap<std::wstring>(
membase_ + poly::load_and_swap<uint32_t>(song_base + 8));
song->album = poly::load_and_swap<std::wstring>(
membase_ + poly::load_and_swap<uint32_t>(song_base + 12));
song->album_artist = poly::load_and_swap<std::wstring>(
membase_ + poly::load_and_swap<uint32_t>(song_base + 16));
song->genre = poly::load_and_swap<std::wstring>(
membase_ + poly::load_and_swap<uint32_t>(song_base + 20));
uint8_t* song_base = memory_->TranslateVirtual(songs_ptr + (i * 36));
song->file_path =
poly::load_and_swap<std::wstring>(memory_->TranslateVirtual(
poly::load_and_swap<uint32_t>(song_base + 0)));
song->name = poly::load_and_swap<std::wstring>(memory_->TranslateVirtual(
poly::load_and_swap<uint32_t>(song_base + 4)));
song->artist = poly::load_and_swap<std::wstring>(memory_->TranslateVirtual(
poly::load_and_swap<uint32_t>(song_base + 8)));
song->album = poly::load_and_swap<std::wstring>(memory_->TranslateVirtual(
poly::load_and_swap<uint32_t>(song_base + 12)));
song->album_artist =
poly::load_and_swap<std::wstring>(memory_->TranslateVirtual(
poly::load_and_swap<uint32_t>(song_base + 16)));
song->genre = poly::load_and_swap<std::wstring>(memory_->TranslateVirtual(
poly::load_and_swap<uint32_t>(song_base + 20)));
song->track_number = poly::load_and_swap<uint32_t>(song_base + 24);
song->duration_ms = poly::load_and_swap<uint32_t>(song_base + 28);
song->format = static_cast<Song::Format>(
poly::load_and_swap<uint32_t>(song_base + 32));
if (out_song_handles) {
poly::store_and_swap<uint32_t>(membase_ + out_song_handles + (i * 4),
song->handle);
poly::store_and_swap<uint32_t>(
memory_->TranslateVirtual(out_song_handles + (i * 4)), song->handle);
}
playlist->songs.emplace_back(std::move(song));
}
poly::store_and_swap<uint32_t>(membase_ + out_playlist_handle,
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(out_playlist_handle),
playlist->handle);
std::lock_guard<std::mutex> lock(mutex_);
@ -195,64 +197,53 @@ void XXMPApp::OnStateChanged() {
X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
uint32_t buffer_length) {
// NOTE: buffer_length may be zero or valid.
auto buffer = memory_->TranslateVirtual(buffer_ptr);
switch (message) {
case 0x00070002: {
assert_true(!buffer_length || buffer_length == 12);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t playlist_handle =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 4);
uint32_t song_handle =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 8); // 0?
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t playlist_handle = poly::load_and_swap<uint32_t>(buffer + 4);
uint32_t song_handle = poly::load_and_swap<uint32_t>(buffer + 8); // 0?
assert_true(xmp_client == 0x00000002);
return XMPPlayTitlePlaylist(playlist_handle, song_handle);
}
case 0x00070003: {
assert_true(!buffer_length || buffer_length == 4);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
assert_true(xmp_client == 0x00000002);
return XMPContinue();
}
case 0x00070004: {
assert_true(!buffer_length || buffer_length == 8);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t unk = poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 4);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t unk = poly::load_and_swap<uint32_t>(buffer + 4);
assert_true(xmp_client == 0x00000002);
return XMPStop(unk);
}
case 0x00070005: {
assert_true(!buffer_length || buffer_length == 4);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
assert_true(xmp_client == 0x00000002);
return XMPPause();
}
case 0x00070006: {
assert_true(!buffer_length || buffer_length == 4);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
assert_true(xmp_client == 0x00000002);
return XMPNext();
}
case 0x00070007: {
assert_true(!buffer_length || buffer_length == 4);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
assert_true(xmp_client == 0x00000002);
return XMPPrevious();
}
case 0x00070008: {
assert_true(!buffer_length || buffer_length == 16);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t playback_mode =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 4);
uint32_t repeat_mode =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 8);
uint32_t flags =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 12);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t playback_mode = poly::load_and_swap<uint32_t>(buffer + 4);
uint32_t repeat_mode = poly::load_and_swap<uint32_t>(buffer + 8);
uint32_t flags = poly::load_and_swap<uint32_t>(buffer + 12);
assert_true(xmp_client == 0x00000002);
XELOGD("XMPSetPlaybackBehavior(%.8X, %.8X, %.8X)", playback_mode,
repeat_mode, flags);
@ -264,29 +255,27 @@ X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
}
case 0x00070009: {
assert_true(!buffer_length || buffer_length == 8);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t state_ptr = poly::load_and_swap<uint32_t>(
membase_ + buffer_ptr + 4); // out ptr to 4b - expect 0
buffer + 4); // out ptr to 4b - expect 0
assert_true(xmp_client == 0x00000002);
return XMPGetStatus(state_ptr);
}
case 0x0007000B: {
assert_true(!buffer_length || buffer_length == 8);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t float_ptr = poly::load_and_swap<uint32_t>(
membase_ + buffer_ptr + 4); // out ptr to 4b - floating point
buffer + 4); // out ptr to 4b - floating point
assert_true(xmp_client == 0x00000002);
XELOGD("XMPGetVolume(%.8X)", float_ptr);
poly::store_and_swap<float>(membase_ + float_ptr, volume_);
poly::store_and_swap<float>(memory_->TranslateVirtual(float_ptr),
volume_);
return X_ERROR_SUCCESS;
}
case 0x0007000C: {
assert_true(!buffer_length || buffer_length == 8);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
float float_value = poly::load_and_swap<float>(membase_ + buffer_ptr + 4);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
float float_value = poly::load_and_swap<float>(buffer + 4);
assert_true(xmp_client == 0x00000002);
XELOGD("XMPSetVolume(%g)", float_value);
volume_ = float_value;
@ -294,27 +283,19 @@ X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
}
case 0x0007000D: {
assert_true(!buffer_length || buffer_length == 36);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t dummy_alloc_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 4);
uint32_t dummy_alloc_size =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 8);
uint32_t songs_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 12);
uint32_t song_count =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 16);
uint32_t playlist_name_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 20);
uint32_t flags =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 24);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t dummy_alloc_ptr = poly::load_and_swap<uint32_t>(buffer + 4);
uint32_t dummy_alloc_size = poly::load_and_swap<uint32_t>(buffer + 8);
uint32_t songs_ptr = poly::load_and_swap<uint32_t>(buffer + 12);
uint32_t song_count = poly::load_and_swap<uint32_t>(buffer + 16);
uint32_t playlist_name_ptr = poly::load_and_swap<uint32_t>(buffer + 20);
uint32_t flags = poly::load_and_swap<uint32_t>(buffer + 24);
uint32_t song_handles_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 28); // 0?
uint32_t playlist_handle_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 32);
poly::load_and_swap<uint32_t>(buffer + 28); // 0?
uint32_t playlist_handle_ptr = poly::load_and_swap<uint32_t>(buffer + 32);
assert_true(xmp_client == 0x00000002);
auto playlist_name =
poly::load_and_swap<std::wstring>(membase_ + playlist_name_ptr);
auto playlist_name = poly::load_and_swap<std::wstring>(
memory_->TranslateVirtual(playlist_name_ptr));
// dummy_alloc_ptr is the result of a XamAlloc of dummy_alloc_size.
assert_true(dummy_alloc_size == song_count * 128);
return XMPCreateTitlePlaylist(songs_ptr, song_count, playlist_name_ptr,
@ -323,12 +304,10 @@ X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
}
case 0x0007000E: {
assert_true(!buffer_length || buffer_length == 12);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t unk_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 4); // 0
uint32_t info_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 8);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t unk_ptr = poly::load_and_swap<uint32_t>(buffer + 4); // 0
uint32_t info_ptr = poly::load_and_swap<uint32_t>(buffer + 8);
auto info = memory_->TranslateVirtual(info_ptr);
assert_true(xmp_client == 0x00000002);
assert_zero(unk_ptr);
XELOGE("XMPGetInfo?(%.8X, %.8X)", unk_ptr, info_ptr);
@ -336,41 +315,31 @@ X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
return X_ERROR_NOT_FOUND;
}
auto& song = active_playlist_->songs[active_song_index_];
poly::store_and_swap<uint32_t>(membase_ + info_ptr + 0, song->handle);
poly::store_and_swap<std::wstring>(membase_ + info_ptr + 4 + 572 + 0,
song->name);
poly::store_and_swap<std::wstring>(membase_ + info_ptr + 4 + 572 + 40,
song->artist);
poly::store_and_swap<std::wstring>(membase_ + info_ptr + 4 + 572 + 80,
song->album);
poly::store_and_swap<std::wstring>(membase_ + info_ptr + 4 + 572 + 120,
poly::store_and_swap<uint32_t>(info + 0, song->handle);
poly::store_and_swap<std::wstring>(info + 4 + 572 + 0, song->name);
poly::store_and_swap<std::wstring>(info + 4 + 572 + 40, song->artist);
poly::store_and_swap<std::wstring>(info + 4 + 572 + 80, song->album);
poly::store_and_swap<std::wstring>(info + 4 + 572 + 120,
song->album_artist);
poly::store_and_swap<std::wstring>(membase_ + info_ptr + 4 + 572 + 160,
song->genre);
poly::store_and_swap<uint32_t>(membase_ + info_ptr + 4 + 572 + 200,
song->track_number);
poly::store_and_swap<uint32_t>(membase_ + info_ptr + 4 + 572 + 204,
song->duration_ms);
poly::store_and_swap<uint32_t>(membase_ + info_ptr + 4 + 572 + 208,
poly::store_and_swap<std::wstring>(info + 4 + 572 + 160, song->genre);
poly::store_and_swap<uint32_t>(info + 4 + 572 + 200, song->track_number);
poly::store_and_swap<uint32_t>(info + 4 + 572 + 204, song->duration_ms);
poly::store_and_swap<uint32_t>(info + 4 + 572 + 208,
static_cast<uint32_t>(song->format));
return X_ERROR_SUCCESS;
}
case 0x00070013: {
assert_true(!buffer_length || buffer_length == 8);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t playlist_handle =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 4);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t playlist_handle = poly::load_and_swap<uint32_t>(buffer + 4);
assert_true(xmp_client == 0x00000002);
return XMPDeleteTitlePlaylist(playlist_handle);
}
case 0x0007001A: {
assert_true(!buffer_length || buffer_length == 12);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t unk1 = poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 4);
uint32_t enabled =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 8);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t unk1 = poly::load_and_swap<uint32_t>(buffer + 4);
uint32_t enabled = poly::load_and_swap<uint32_t>(buffer + 8);
assert_true(xmp_client == 0x00000002);
assert_zero(unk1);
XELOGD("XMPSetEnabled(%.8X, %.8X)", unk1, enabled);
@ -383,53 +352,49 @@ X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
}
case 0x0007001B: {
assert_true(!buffer_length || buffer_length == 12);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t unk_ptr = poly::load_and_swap<uint32_t>(
membase_ + buffer_ptr + 4); // out ptr to 4b - expect 0
buffer + 4); // out ptr to 4b - expect 0
uint32_t disabled_ptr = poly::load_and_swap<uint32_t>(
membase_ + buffer_ptr + 8); // out ptr to 4b - expect 1 (to skip)
buffer + 8); // out ptr to 4b - expect 1 (to skip)
assert_true(xmp_client == 0x00000002);
XELOGD("XMPGetEnabled(%.8X, %.8X)", unk_ptr, disabled_ptr);
poly::store_and_swap<uint32_t>(membase_ + unk_ptr, 0);
poly::store_and_swap<uint32_t>(membase_ + disabled_ptr, disabled_);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(unk_ptr), 0);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(disabled_ptr),
disabled_);
// Atrain spawns a thread 82437FD0 to call this in a tight loop forever.
poly::threading::Sleep(std::chrono::milliseconds(10));
return X_ERROR_SUCCESS;
}
case 0x00070029: {
assert_true(!buffer_length || buffer_length == 16);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t playback_mode_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 4);
uint32_t repeat_mode_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 8);
uint32_t unk3_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 12);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t playback_mode_ptr = poly::load_and_swap<uint32_t>(buffer + 4);
uint32_t repeat_mode_ptr = poly::load_and_swap<uint32_t>(buffer + 8);
uint32_t unk3_ptr = poly::load_and_swap<uint32_t>(buffer + 12);
assert_true(xmp_client == 0x00000002);
XELOGD("XMPGetPlaybackBehavior(%.8X, %.8X, %.8X)", playback_mode_ptr,
repeat_mode_ptr, unk3_ptr);
poly::store_and_swap<uint32_t>(membase_ + playback_mode_ptr,
static_cast<uint32_t>(playback_mode_));
poly::store_and_swap<uint32_t>(membase_ + repeat_mode_ptr,
poly::store_and_swap<uint32_t>(
memory_->TranslateVirtual(playback_mode_ptr),
static_cast<uint32_t>(playback_mode_));
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(repeat_mode_ptr),
static_cast<uint32_t>(repeat_mode_));
poly::store_and_swap<uint32_t>(membase_ + unk3_ptr, unknown_flags_);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(unk3_ptr),
unknown_flags_);
return X_ERROR_SUCCESS;
}
case 0x0007002E: {
assert_true(!buffer_length || buffer_length == 12);
// Query of size for XamAlloc - the result of the alloc is passed to
// 0x0007000D.
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t song_count =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 4);
uint32_t size_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 8);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t song_count = poly::load_and_swap<uint32_t>(buffer + 4);
uint32_t size_ptr = poly::load_and_swap<uint32_t>(buffer + 8);
assert_true(xmp_client == 0x00000002);
// We don't use the storage, so just fudge the number.
poly::store_and_swap<uint32_t>(membase_ + size_ptr, song_count * 128);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(size_ptr),
song_count * 128);
return X_ERROR_SUCCESS;
}
case 0x0007003D: {

View File

@ -204,7 +204,7 @@ void KernelState::BroadcastNotification(XNotificationID id, uint32_t data) {
void KernelState::CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result,
uint32_t length) {
auto ptr = memory()->membase() + overlapped_ptr;
auto ptr = memory()->TranslateVirtual(overlapped_ptr);
XOverlappedSetResult(ptr, result);
XOverlappedSetLength(ptr, length);
XOverlappedSetExtendedError(ptr, result);
@ -233,7 +233,7 @@ void KernelState::CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result,
void KernelState::CompleteOverlappedImmediate(uint32_t overlapped_ptr,
X_RESULT result,
uint32_t length) {
auto ptr = memory()->membase() + overlapped_ptr;
auto ptr = memory()->TranslateVirtual(overlapped_ptr);
XOverlappedSetContext(ptr, XThread::GetCurrentThreadHandle());
CompleteOverlapped(overlapped_ptr, result, length);
}

View File

@ -16,41 +16,44 @@ NativeList::NativeList(Memory* memory)
: memory_(memory), head_(kInvalidPointer) {}
void NativeList::Insert(uint32_t ptr) {
uint8_t* mem = memory_->membase();
poly::store_and_swap<uint32_t>(mem + ptr + 0, head_);
poly::store_and_swap<uint32_t>(mem + ptr + 4, 0);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(ptr + 0), head_);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(ptr + 4), 0);
if (head_) {
poly::store_and_swap<uint32_t>(mem + head_ + 4, ptr);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(head_ + 4), ptr);
}
head_ = ptr;
}
bool NativeList::IsQueued(uint32_t ptr) {
uint8_t* mem = memory_->membase();
uint32_t flink = poly::load_and_swap<uint32_t>(mem + ptr + 0);
uint32_t blink = poly::load_and_swap<uint32_t>(mem + ptr + 4);
uint32_t flink =
poly::load_and_swap<uint32_t>(memory_->TranslateVirtual(ptr + 0));
uint32_t blink =
poly::load_and_swap<uint32_t>(memory_->TranslateVirtual(ptr + 4));
return head_ == ptr || flink || blink;
}
void NativeList::Remove(uint32_t ptr) {
uint8_t* mem = memory_->membase();
uint32_t flink = poly::load_and_swap<uint32_t>(mem + ptr + 0);
uint32_t blink = poly::load_and_swap<uint32_t>(mem + ptr + 4);
uint32_t flink =
poly::load_and_swap<uint32_t>(memory_->TranslateVirtual(ptr + 0));
uint32_t blink =
poly::load_and_swap<uint32_t>(memory_->TranslateVirtual(ptr + 4));
if (ptr == head_) {
head_ = flink;
if (flink) {
poly::store_and_swap<uint32_t>(mem + flink + 4, 0);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(flink + 4), 0);
}
} else {
if (blink) {
poly::store_and_swap<uint32_t>(mem + blink + 0, flink);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(blink + 0),
flink);
}
if (flink) {
poly::store_and_swap<uint32_t>(mem + flink + 4, blink);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(flink + 4),
blink);
}
}
poly::store_and_swap<uint32_t>(mem + ptr + 0, 0);
poly::store_and_swap<uint32_t>(mem + ptr + 4, 0);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(ptr + 0), 0);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(ptr + 4), 0);
}
uint32_t NativeList::Shift() {

View File

@ -118,12 +118,12 @@ uint32_t XThread::thread_state() { return thread_state_address_; }
uint32_t XThread::thread_id() { return thread_id_; }
uint32_t XThread::last_error() {
uint8_t* p = memory()->Translate(thread_state_address_);
uint8_t* p = memory()->TranslateVirtual(thread_state_address_);
return poly::load_and_swap<uint32_t>(p + 0x160);
}
void XThread::set_last_error(uint32_t error_code) {
uint8_t* p = memory()->Translate(thread_state_address_);
uint8_t* p = memory()->TranslateVirtual(thread_state_address_);
poly::store_and_swap<uint32_t>(p + 0x160, error_code);
}
@ -176,7 +176,7 @@ X_STATUS XThread::Create() {
memory()->Copy(tls_address_, header->tls_info.raw_data_address, tls_size);
// Setup the thread state block (last error/etc).
uint8_t* p = memory()->Translate(thread_state_address_);
uint8_t* p = memory()->TranslateVirtual(thread_state_address_);
poly::store_and_swap<uint32_t>(p + 0x000, tls_address_);
poly::store_and_swap<uint32_t>(p + 0x100, thread_state_address_);
poly::store_and_swap<uint32_t>(p + 0x14C, thread_id_);
@ -382,7 +382,7 @@ void XThread::DeliverAPCs(void* data) {
// http://www.drdobbs.com/inside-nts-asynchronous-procedure-call/184416590?pgno=1
// http://www.drdobbs.com/inside-nts-asynchronous-procedure-call/184416590?pgno=7
XThread* thread = reinterpret_cast<XThread*>(data);
auto membase = thread->memory()->membase();
auto memory = thread->memory();
auto processor = thread->kernel_state()->processor();
auto apc_list = thread->apc_list();
thread->LockApc();
@ -390,7 +390,7 @@ void XThread::DeliverAPCs(void* data) {
// Get APC entry (offset for LIST_ENTRY offset) and cache what we need.
// Calling the routine may delete the memory/overwrite it.
uint32_t apc_address = apc_list->Shift() - 8;
uint8_t* apc_ptr = membase + apc_address;
uint8_t* apc_ptr = memory->TranslateVirtual(apc_address);
uint32_t kernel_routine = poly::load_and_swap<uint32_t>(apc_ptr + 16);
uint32_t normal_routine = poly::load_and_swap<uint32_t>(apc_ptr + 24);
uint32_t normal_context = poly::load_and_swap<uint32_t>(apc_ptr + 28);
@ -405,7 +405,7 @@ void XThread::DeliverAPCs(void* data) {
// The routine can modify all of its arguments before passing it on.
// Since we need to give guest accessible pointers over, we copy things
// into and out of scratch.
uint8_t* scratch_ptr = membase + thread->scratch_address_;
uint8_t* scratch_ptr = memory->TranslateVirtual(thread->scratch_address_);
poly::store_and_swap<uint32_t>(scratch_ptr + 0, normal_routine);
poly::store_and_swap<uint32_t>(scratch_ptr + 4, normal_context);
poly::store_and_swap<uint32_t>(scratch_ptr + 8, system_arg1);
@ -438,13 +438,12 @@ void XThread::DeliverAPCs(void* data) {
}
void XThread::RundownAPCs() {
auto membase = memory()->membase();
LockApc();
while (apc_list_->HasPending()) {
// Get APC entry (offset for LIST_ENTRY offset) and cache what we need.
// Calling the routine may delete the memory/overwrite it.
uint32_t apc_address = apc_list_->Shift() - 8;
uint8_t* apc_ptr = membase + apc_address;
uint8_t* apc_ptr = memory()->TranslateVirtual(apc_address);
uint32_t rundown_routine = poly::load_and_swap<uint32_t>(apc_ptr + 20);
// Mark as uninserted so that it can be reinserted again by the routine.

View File

@ -107,15 +107,15 @@ X_STATUS XUserModule::LoadFromMemory(const void* addr, const size_t length) {
// Load the XEX into memory and decrypt.
xe_xex2_options_t xex_options = {0};
xex_ = xe_xex2_load(kernel_state()->memory(), addr, length, xex_options);
xex_ = xe_xex2_load(memory(), addr, length, xex_options);
if (!xex_) {
return X_STATUS_UNSUCCESSFUL;
}
// Store execution info for later use.
// TODO(benvanik): just put entire xex header in memory somewhere?
execution_info_ptr_ = kernel_state()->memory()->SystemHeapAlloc(24);
auto eip = kernel_state()->memory()->membase() + execution_info_ptr_;
execution_info_ptr_ = memory()->SystemHeapAlloc(24);
auto eip = memory()->TranslateVirtual(execution_info_ptr_);
const auto& ex = xe_xex2_get_header(xex_)->execution_info;
poly::store_and_swap<uint32_t>(eip + 0x00, ex.media_id);
poly::store_and_swap<uint32_t>(eip + 0x04, ex.version.value);

View File

@ -26,8 +26,8 @@ using PPCContext = xe::cpu::frontend::PPCContext;
shim_data, \
(xe_kernel_export_shim_fn)export_name##_shim);
#define SHIM_MEM_BASE ppc_state->membase
#define SHIM_MEM_ADDR(a) (a ? (ppc_state->membase + a) : nullptr)
#define SHIM_MEM_BASE ppc_state->virtual_membase
#define SHIM_MEM_ADDR(a) (a ? (ppc_state->virtual_membase + a) : nullptr)
#define SHIM_MEM_8(a) poly::load_and_swap<uint8_t>(SHIM_MEM_ADDR(a))
#define SHIM_MEM_16(a) poly::load_and_swap<uint16_t>(SHIM_MEM_ADDR(a))

View File

@ -538,7 +538,7 @@ int xe_xex2_read_image_uncompressed(const xe_xex2_header_t *header,
uncompressed_size);
return 2;
}
uint8_t *buffer = memory->Translate(header->exe_address);
uint8_t *buffer = memory->TranslateVirtual(header->exe_address);
std::memset(buffer, 0, uncompressed_size);
const uint8_t *p = (const uint8_t *)xex_addr + header->exe_offset;
@ -588,7 +588,7 @@ int xe_xex2_read_image_basic_compressed(const xe_xex2_header_t *header,
uncompressed_size);
return 1;
}
uint8_t *buffer = memory->Translate(header->exe_address);
uint8_t *buffer = memory->TranslateVirtual(header->exe_address);
uint8_t *d = buffer;
std::memset(buffer, 0, uncompressed_size);
@ -726,7 +726,7 @@ int xe_xex2_read_image_compressed(const xe_xex2_header_t *header,
result_code = 2;
goto XECLEANUP;
}
uint8_t *buffer = memory->Translate(header->exe_address);
uint8_t *buffer = memory->TranslateVirtual(header->exe_address);
std::memset(buffer, 0, uncompressed_size);
// Setup decompressor and decompress.
@ -792,7 +792,7 @@ int xe_xex2_read_image(xe_xex2_ref xex, const uint8_t *xex_addr,
int xe_xex2_load_pe(xe_xex2_ref xex) {
const xe_xex2_header_t *header = &xex->header;
const uint8_t *p = xex->memory->Translate(header->exe_address);
const uint8_t *p = xex->memory->TranslateVirtual(header->exe_address);
// Verify DOS signature (MZ).
const IMAGE_DOS_HEADER *doshdr = (const IMAGE_DOS_HEADER *)p;
@ -886,7 +886,6 @@ const PESection *xe_xex2_get_pe_section(xe_xex2_ref xex, const char *name) {
int xe_xex2_find_import_infos(xe_xex2_ref xex,
const xe_xex2_import_library_t *library) {
uint8_t *mem = xex->memory->membase();
auto header = xe_xex2_get_header(xex);
// Find library index for verification.
@ -910,7 +909,8 @@ int xe_xex2_find_import_infos(xe_xex2_ref xex,
size_t info_count = 0;
for (size_t n = 0; n < library->record_count; n++) {
const uint32_t record = library->records[n];
const uint32_t value = poly::load_and_swap<uint32_t>(mem + record);
const uint32_t value =
poly::load_and_swap<uint32_t>(xex->memory->TranslateVirtual(record));
if (value & 0xFF000000) {
// Thunk for previous record - ignore.
} else {
@ -929,7 +929,8 @@ int xe_xex2_find_import_infos(xe_xex2_ref xex,
// Construct infos.
for (size_t n = 0, i = 0; n < library->record_count; n++) {
const uint32_t record = library->records[n];
const uint32_t value = poly::load_and_swap<uint32_t>(mem + record);
const uint32_t value =
poly::load_and_swap<uint32_t>(xex->memory->TranslateVirtual(record));
const uint32_t type = (value & 0xFF000000) >> 24;
// Verify library index matches given library.

View File

@ -151,10 +151,6 @@ struct XMAContextData {
};
static_assert(sizeof(XMAContextData) == 4 * 10, "Must be packed");
void StoreXmaRegister(uint8_t* membase, uint32_t num, uint32_t value) {
poly::store<uint32_t>(membase + (0x7FEA0000 + num), value);
}
void StoreXmaContextIndexedRegister(KernelState* state, uint32_t base_reg,
uint32_t context_ptr) {
auto audio_system = state->emulator()->audio_system();
@ -162,7 +158,8 @@ void StoreXmaContextIndexedRegister(KernelState* state, uint32_t base_reg,
XMAContextData::kSize;
uint32_t reg_num = base_reg + (hw_index >> 5) * 4;
uint32_t reg_value = 1 << (hw_index & 0x1F);
StoreXmaRegister(state->memory()->membase(), reg_num, reg_value);
poly::store<uint32_t>(state->memory()->TranslateVirtual(0x7FEA0000 + reg_num),
reg_value);
}
SHIM_CALL XMAInitializeContext_shim(PPCContext* ppc_state, KernelState* state) {

View File

@ -44,23 +44,23 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
xboxkrnl::RegisterUsbcamExports(export_resolver_, kernel_state_);
xboxkrnl::RegisterVideoExports(export_resolver_, kernel_state_);
uint8_t* mem = memory_->membase();
// KeDebugMonitorData (?*)
// Set to a valid value when a remote debugger is attached.
// Offset 0x18 is a 4b pointer to a handler function that seems to take two
// arguments. If we wanted to see what would happen we could fake that.
uint32_t pKeDebugMonitorData = memory_->SystemHeapAlloc(256);
auto lpKeDebugMonitorData = memory_->TranslateVirtual(pKeDebugMonitorData);
export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::KeDebugMonitorData, pKeDebugMonitorData);
poly::store_and_swap<uint32_t>(mem + pKeDebugMonitorData, 0);
poly::store_and_swap<uint32_t>(lpKeDebugMonitorData, 0);
// KeCertMonitorData (?*)
// Always set to zero, ignored.
uint32_t pKeCertMonitorData = memory_->SystemHeapAlloc(4);
auto lpKeCertMonitorData = memory_->TranslateVirtual(pKeCertMonitorData);
export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::KeCertMonitorData, pKeCertMonitorData);
poly::store_and_swap<uint32_t>(mem + pKeCertMonitorData, 0);
poly::store_and_swap<uint32_t>(lpKeCertMonitorData, 0);
// XboxHardwareInfo (XboxHardwareInfo_t, 16b)
// flags cpu# ? ? ? ? ? ?
@ -71,11 +71,11 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
// aomega08 says the value is 0x02000817, bit 27: debug mode on.
// When that is set, though, allocs crash in weird ways.
uint32_t pXboxHardwareInfo = memory_->SystemHeapAlloc(16);
auto lpXboxHardwareInfo = memory_->TranslateVirtual(pXboxHardwareInfo);
export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::XboxHardwareInfo, pXboxHardwareInfo);
poly::store_and_swap<uint32_t>(mem + pXboxHardwareInfo + 0, 0); // flags
poly::store_and_swap<uint8_t>(mem + pXboxHardwareInfo + 4,
0x06); // cpu count
poly::store_and_swap<uint32_t>(lpXboxHardwareInfo + 0, 0); // flags
poly::store_and_swap<uint8_t>(lpXboxHardwareInfo + 4, 0x06); // cpu count
// Remaining 11b are zeroes?
// XexExecutableModuleHandle (?**)
@ -88,13 +88,17 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
// 0x80101058 <- pointer to xex header
// 0x80101100 <- xex header base
uint32_t ppXexExecutableModuleHandle = memory_->SystemHeapAlloc(4);
auto lppXexExecutableModuleHandle =
memory_->TranslateVirtual(ppXexExecutableModuleHandle);
export_resolver_->SetVariableMapping("xboxkrnl.exe",
ordinals::XexExecutableModuleHandle,
ppXexExecutableModuleHandle);
uint32_t pXexExecutableModuleHandle = memory_->SystemHeapAlloc(256);
poly::store_and_swap<uint32_t>(mem + ppXexExecutableModuleHandle,
auto lpXexExecutableModuleHandle =
memory_->TranslateVirtual(pXexExecutableModuleHandle);
poly::store_and_swap<uint32_t>(lppXexExecutableModuleHandle,
pXexExecutableModuleHandle);
poly::store_and_swap<uint32_t>(mem + pXexExecutableModuleHandle + 0x58,
poly::store_and_swap<uint32_t>(lpXexExecutableModuleHandle + 0x58,
0x80101100);
// ExLoadedCommandLine (char*)
@ -102,41 +106,44 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
// Perhaps it's how swap disc/etc data is sent?
// Always set to "default.xex" (with quotes) for now.
uint32_t pExLoadedCommandLine = memory_->SystemHeapAlloc(1024);
auto lpExLoadedCommandLine = memory_->TranslateVirtual(pExLoadedCommandLine);
export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::ExLoadedCommandLine, pExLoadedCommandLine);
char command_line[] = "\"default.xex\"";
memcpy(mem + pExLoadedCommandLine, command_line,
poly::countof(command_line) + 1);
std::memcpy(lpExLoadedCommandLine, command_line,
poly::countof(command_line) + 1);
// XboxKrnlVersion (8b)
// Kernel version, looks like 2b.2b.2b.2b.
// I've only seen games check >=, so we just fake something here.
uint32_t pXboxKrnlVersion = memory_->SystemHeapAlloc(8);
auto lpXboxKrnlVersion = memory_->TranslateVirtual(pXboxKrnlVersion);
export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::XboxKrnlVersion, pXboxKrnlVersion);
poly::store_and_swap<uint16_t>(mem + pXboxKrnlVersion + 0, 2);
poly::store_and_swap<uint16_t>(mem + pXboxKrnlVersion + 2, 0xFFFF);
poly::store_and_swap<uint16_t>(mem + pXboxKrnlVersion + 4, 0xFFFF);
poly::store_and_swap<uint8_t>(mem + pXboxKrnlVersion + 6, 0x80);
poly::store_and_swap<uint8_t>(mem + pXboxKrnlVersion + 7, 0x00);
poly::store_and_swap<uint16_t>(lpXboxKrnlVersion + 0, 2);
poly::store_and_swap<uint16_t>(lpXboxKrnlVersion + 2, 0xFFFF);
poly::store_and_swap<uint16_t>(lpXboxKrnlVersion + 4, 0xFFFF);
poly::store_and_swap<uint8_t>(lpXboxKrnlVersion + 6, 0x80);
poly::store_and_swap<uint8_t>(lpXboxKrnlVersion + 7, 0x00);
// KeTimeStampBundle (ad)
// This must be updated during execution, at 1ms intevals.
// We setup a system timer here to do that.
uint32_t pKeTimeStampBundle = memory_->SystemHeapAlloc(24);
auto lpKeTimeStampBundle = memory_->TranslateVirtual(pKeTimeStampBundle);
export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::KeTimeStampBundle, pKeTimeStampBundle);
poly::store_and_swap<uint64_t>(mem + pKeTimeStampBundle + 0, 0);
poly::store_and_swap<uint64_t>(mem + pKeTimeStampBundle + 8, 0);
poly::store_and_swap<uint32_t>(mem + pKeTimeStampBundle + 16, GetTickCount());
poly::store_and_swap<uint32_t>(mem + pKeTimeStampBundle + 20, 0);
poly::store_and_swap<uint64_t>(lpKeTimeStampBundle + 0, 0);
poly::store_and_swap<uint64_t>(lpKeTimeStampBundle + 8, 0);
poly::store_and_swap<uint32_t>(lpKeTimeStampBundle + 16, GetTickCount());
poly::store_and_swap<uint32_t>(lpKeTimeStampBundle + 20, 0);
CreateTimerQueueTimer(
&timestamp_timer_, nullptr,
[](PVOID param, BOOLEAN timer_or_wait_fired) {
auto timestamp_bundle = reinterpret_cast<uint8_t*>(param);
poly::store_and_swap<uint32_t>(timestamp_bundle + 16, GetTickCount());
},
mem + pKeTimeStampBundle, 0,
lpKeTimeStampBundle, 0,
1, // 1ms
WT_EXECUTEINTIMERTHREAD);
}

View File

@ -541,7 +541,7 @@ SHIM_CALL RtlEnterCriticalSection_shim(PPCContext* ppc_state,
// XELOGD("RtlEnterCriticalSection(%.8X)", cs_ptr);
const uint8_t* thread_state_block = ppc_state->membase + ppc_state->r[13];
const uint8_t* thread_state_block = SHIM_MEM_ADDR(ppc_state->r[13]);
uint32_t thread_id = XThread::GetCurrentThreadId(thread_state_block);
auto cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr);
@ -583,7 +583,7 @@ SHIM_CALL RtlTryEnterCriticalSection_shim(PPCContext* ppc_state,
// XELOGD("RtlTryEnterCriticalSection(%.8X)", cs_ptr);
const uint8_t* thread_state_block = ppc_state->membase + ppc_state->r[13];
const uint8_t* thread_state_block = SHIM_MEM_ADDR(ppc_state->r[13]);
uint32_t thread_id = XThread::GetCurrentThreadId(thread_state_block);
auto cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr);

View File

@ -62,11 +62,10 @@ void AssertNoNameCollision(KernelState* state, uint32_t obj_attributes_ptr) {
// with a success of NAME_EXISTS.
// If the name exists and its type doesn't match, we do NAME_COLLISION.
// Otherwise, we add like normal.
auto membase = state->memory()->membase();
uint32_t name_str_ptr =
poly::load_and_swap<uint32_t>(membase + obj_attributes_ptr + 4);
uint32_t name_str_ptr = poly::load_and_swap<uint32_t>(
state->memory()->TranslateVirtual(obj_attributes_ptr + 4));
if (name_str_ptr) {
X_ANSI_STRING name_str(membase, name_str_ptr);
X_ANSI_STRING name_str(state->memory()->virtual_membase(), name_str_ptr);
auto name = name_str.to_string();
X_HANDLE handle = X_INVALID_HANDLE_VALUE;
X_RESULT result = state->object_table()->GetObjectByName(name, &handle);

View File

@ -447,7 +447,6 @@ void xe::kernel::xboxkrnl::RegisterVideoExports(ExportResolver* export_resolver,
SHIM_SET_MAPPING("xboxkrnl.exe", VdSwap, state);
Memory* memory = state->memory();
uint8_t* mem = memory->membase();
// VdGlobalDevice (4b)
// Pointer to a global D3D device. Games only seem to set this, so we don't
@ -456,7 +455,7 @@ void xe::kernel::xboxkrnl::RegisterVideoExports(ExportResolver* export_resolver,
memory->SystemHeapAlloc(4, 32, kSystemHeapPhysical);
export_resolver->SetVariableMapping("xboxkrnl.exe", ordinals::VdGlobalDevice,
pVdGlobalDevice);
poly::store_and_swap<uint32_t>(mem + pVdGlobalDevice, 0);
poly::store_and_swap<uint32_t>(memory->TranslateVirtual(pVdGlobalDevice), 0);
// VdGlobalXamDevice (4b)
// Pointer to the XAM D3D device, which we don't have.
@ -464,7 +463,8 @@ void xe::kernel::xboxkrnl::RegisterVideoExports(ExportResolver* export_resolver,
memory->SystemHeapAlloc(4, 32, kSystemHeapPhysical);
export_resolver->SetVariableMapping(
"xboxkrnl.exe", ordinals::VdGlobalXamDevice, pVdGlobalXamDevice);
poly::store_and_swap<uint32_t>(mem + pVdGlobalXamDevice, 0);
poly::store_and_swap<uint32_t>(memory->TranslateVirtual(pVdGlobalXamDevice),
0);
// VdGpuClockInMHz (4b)
// GPU clock. Xenos is 500MHz. Hope nothing is relying on this timing...
@ -472,7 +472,8 @@ void xe::kernel::xboxkrnl::RegisterVideoExports(ExportResolver* export_resolver,
memory->SystemHeapAlloc(4, 32, kSystemHeapPhysical);
export_resolver->SetVariableMapping("xboxkrnl.exe", ordinals::VdGpuClockInMHz,
pVdGpuClockInMHz);
poly::store_and_swap<uint32_t>(mem + pVdGpuClockInMHz, 500);
poly::store_and_swap<uint32_t>(memory->TranslateVirtual(pVdGpuClockInMHz),
500);
// VdHSIOCalibrationLock (28b)
// CriticalSection.
@ -481,7 +482,7 @@ void xe::kernel::xboxkrnl::RegisterVideoExports(ExportResolver* export_resolver,
export_resolver->SetVariableMapping(
"xboxkrnl.exe", ordinals::VdHSIOCalibrationLock, pVdHSIOCalibrationLock);
auto hsio_lock =
reinterpret_cast<X_RTL_CRITICAL_SECTION*>(mem + pVdHSIOCalibrationLock);
memory->TranslateVirtual<X_RTL_CRITICAL_SECTION*>(pVdHSIOCalibrationLock);
xeRtlInitializeCriticalSectionAndSpinCount(hsio_lock, pVdHSIOCalibrationLock,
10000);
}

View File

@ -23,9 +23,8 @@ XObject::XObject(KernelState* kernel_state, Type type)
pointer_ref_count_(1),
type_(type),
handle_(X_INVALID_HANDLE_VALUE) {
// Added pointer check to support usage without a kernel_state
if (kernel_state != nullptr){
if (kernel_state != nullptr) {
kernel_state->object_table()->AddHandle(this, &handle_);
}
}
@ -35,8 +34,6 @@ XObject::~XObject() {
assert_zero(pointer_ref_count_);
}
Memory* XObject::memory() const { return kernel_state_->memory(); }
XObject::Type XObject::type() { return type_; }
X_HANDLE XObject::handle() const { return handle_; }
@ -78,7 +75,7 @@ void XObject::SetAttributes(const uint8_t* obj_attrs_ptr) {
uint32_t name_str_ptr = poly::load_and_swap<uint32_t>(obj_attrs_ptr + 4);
if (name_str_ptr) {
X_ANSI_STRING name_str(membase(), name_str_ptr);
X_ANSI_STRING name_str(memory()->virtual_membase(), name_str_ptr);
name_ = name_str.to_string();
kernel_state_->object_table()->AddNameMapping(name_, handle_);
}
@ -157,8 +154,8 @@ X_STATUS XObject::WaitMultiple(uint32_t count, XObject** objects,
void XObject::SetNativePointer(uint32_t native_ptr) {
std::lock_guard<std::mutex> lock(kernel_state_->object_mutex());
DISPATCH_HEADER* header_be =
(DISPATCH_HEADER*)kernel_state_->memory()->Translate(native_ptr);
auto header_be =
kernel_state_->memory()->TranslateVirtual<DISPATCH_HEADER*>(native_ptr);
DISPATCH_HEADER header;
header.type_flags = poly::byte_swap(header_be->type_flags);
header.signal_state = poly::byte_swap(header_be->signal_state);

View File

@ -13,7 +13,6 @@
#include <atomic>
#include "xenia/kernel/kernel_state.h"
#include "xenia/xbox.h"
namespace xe {
@ -46,7 +45,7 @@ class XObject {
Emulator* emulator() const { return kernel_state_->emulator_; }
KernelState* kernel_state() const { return kernel_state_; }
uint8_t* membase() const { return kernel_state_->memory()->membase(); }
Memory* memory() const { return kernel_state_->memory(); }
Type type();
X_HANDLE handle() const;
@ -79,7 +78,6 @@ class XObject {
virtual void* GetWaitHandle() { return 0; }
protected:
Memory* memory() const;
void SetNativePointer(uint32_t native_ptr);
static uint32_t TimeoutTicksToMs(int64_t timeout_ticks);

View File

@ -116,7 +116,8 @@ class xe::MemoryHeap {
uint32_t MemoryHeap::next_heap_id_ = 1;
Memory::Memory()
: membase_(nullptr),
: virtual_membase_(nullptr),
physical_membase_(nullptr),
reserve_address_(0),
reserve_value_(0),
trace_base_(0),
@ -134,7 +135,7 @@ Memory::~Memory() {
if (mapping_base_) {
// GPU writeback.
VirtualFree(Translate(0xC0000000), 0x00100000, MEM_DECOMMIT);
VirtualFree(TranslateVirtual(0xC0000000), 0x00100000, MEM_DECOMMIT);
}
delete physical_heap_;
@ -147,6 +148,9 @@ Memory::~Memory() {
mapping_base_ = 0;
mapping_ = 0;
}
virtual_membase_ = nullptr;
physical_membase_ = nullptr;
}
int Memory::Initialize() {
@ -184,7 +188,8 @@ int Memory::Initialize() {
assert_always();
return 1;
}
membase_ = mapping_base_;
virtual_membase_ = mapping_base_;
physical_membase_ = virtual_membase_;
// Prepare heaps.
virtual_heap_->Initialize(kMemoryVirtualHeapLow, kMemoryVirtualHeapHigh);
@ -193,7 +198,8 @@ int Memory::Initialize() {
// GPU writeback.
// 0xC... is physical, 0x7F... is virtual. We may need to overlay these.
VirtualAlloc(Translate(0x00000000), 0x00100000, MEM_COMMIT, PAGE_READWRITE);
VirtualAlloc(TranslatePhysical(0x00000000), 0x00100000, MEM_COMMIT,
PAGE_READWRITE);
// Add handlers for MMIO.
mmio_handler_ = cpu::MMIOHandler::Install(mapping_base_);
@ -204,9 +210,10 @@ int Memory::Initialize() {
}
// I have no idea what this is, but games try to read/write there.
VirtualAlloc(Translate(0x40000000), 0x00010000, MEM_COMMIT, PAGE_READWRITE);
poly::store_and_swap<uint32_t>(Translate(0x40000000), 0x00C40000);
poly::store_and_swap<uint32_t>(Translate(0x40000004), 0x00010000);
VirtualAlloc(TranslateVirtual(0x40000000), 0x00010000, MEM_COMMIT,
PAGE_READWRITE);
poly::store_and_swap<uint32_t>(TranslateVirtual(0x40000000), 0x00C40000);
poly::store_and_swap<uint32_t>(TranslateVirtual(0x40000004), 0x00010000);
return 0;
}
@ -266,26 +273,24 @@ void Memory::UnmapViews() {
}
void Memory::Zero(uint32_t address, uint32_t size) {
uint8_t* p = membase_ + address;
std::memset(p, 0, size);
std::memset(TranslateVirtual(address), 0, size);
}
void Memory::Fill(uint32_t address, uint32_t size, uint8_t value) {
uint8_t* p = membase_ + address;
std::memset(p, value, size);
std::memset(TranslateVirtual(address), value, size);
}
void Memory::Copy(uint32_t dest, uint32_t src, uint32_t size) {
uint8_t* pdest = membase_ + dest;
const uint8_t* psrc = membase_ + src;
uint8_t* pdest = TranslateVirtual(dest);
const uint8_t* psrc = TranslateVirtual(src);
std::memcpy(pdest, psrc, size);
}
uint32_t Memory::SearchAligned(uint32_t start, uint32_t end,
const uint32_t* values, size_t value_count) {
assert_true(start <= end);
const uint32_t* p = reinterpret_cast<const uint32_t*>(membase_ + start);
const uint32_t* pe = reinterpret_cast<const uint32_t*>(membase_ + end);
auto p = TranslateVirtual<const uint32_t*>(start);
auto pe = TranslateVirtual<const uint32_t*>(end);
while (p != pe) {
if (*p == values[0]) {
const uint32_t* pc = p + 1;
@ -297,7 +302,7 @@ uint32_t Memory::SearchAligned(uint32_t start, uint32_t end,
matched++;
}
if (matched == value_count) {
return uint32_t(reinterpret_cast<const uint8_t*>(p) - membase_);
return uint32_t(reinterpret_cast<const uint8_t*>(p) - virtual_membase_);
}
}
p++;
@ -309,7 +314,7 @@ bool Memory::AddMappedRange(uint32_t address, uint32_t mask, uint32_t size,
void* context, cpu::MMIOReadCallback read_callback,
cpu::MMIOWriteCallback write_callback) {
DWORD protect = PAGE_NOACCESS;
if (!VirtualAlloc(Translate(address), size, MEM_COMMIT, protect)) {
if (!VirtualAlloc(TranslateVirtual(address), size, MEM_COMMIT, protect)) {
XELOGE("Unable to map range; commit/protect failed");
return false;
}
@ -361,7 +366,7 @@ uint32_t Memory::HeapAlloc(uint32_t base_address, uint32_t size, uint32_t flags,
}
if (result) {
if (flags & MEMORY_FLAG_ZERO) {
memset(Translate(result), 0, size);
memset(TranslateVirtual(result), 0, size);
}
}
return result;
@ -379,7 +384,7 @@ uint32_t Memory::HeapAlloc(uint32_t base_address, uint32_t size, uint32_t flags,
return 0;
}
uint8_t* p = Translate(base_address);
uint8_t* p = TranslateVirtual(base_address);
// TODO(benvanik): check if address range is in use with a query.
void* pv = VirtualAlloc(p, size, MEM_COMMIT, PAGE_READWRITE);
@ -405,20 +410,20 @@ int Memory::HeapFree(uint32_t address, uint32_t size) {
return physical_heap_->Free(address, size) ? 0 : 1;
} else {
// A placed address. Decommit.
uint8_t* p = Translate(address);
uint8_t* p = TranslateVirtual(address);
return VirtualFree(p, size, MEM_DECOMMIT) ? 0 : 1;
}
}
bool Memory::QueryInformation(uint32_t base_address, AllocationInfo* mem_info) {
uint8_t* p = Translate(base_address);
uint8_t* p = TranslateVirtual(base_address);
MEMORY_BASIC_INFORMATION mbi;
if (!VirtualQuery(p, &mbi, sizeof(mbi))) {
return false;
}
mem_info->base_address = base_address;
mem_info->allocation_base = static_cast<uint32_t>(
reinterpret_cast<uint8_t*>(mbi.AllocationBase) - membase_);
reinterpret_cast<uint8_t*>(mbi.AllocationBase) - virtual_membase_);
mem_info->allocation_protect = mbi.AllocationProtect;
mem_info->region_size = mbi.RegionSize;
mem_info->state = mbi.State;
@ -436,7 +441,7 @@ uint32_t Memory::QuerySize(uint32_t base_address) {
return physical_heap_->QuerySize(base_address);
} else {
// A placed address.
uint8_t* p = Translate(base_address);
uint8_t* p = TranslateVirtual(base_address);
MEMORY_BASIC_INFORMATION mem_info;
if (VirtualQuery(p, &mem_info, sizeof(mem_info))) {
return uint32_t(mem_info.RegionSize);
@ -448,7 +453,7 @@ uint32_t Memory::QuerySize(uint32_t base_address) {
}
int Memory::Protect(uint32_t address, uint32_t size, uint32_t access) {
uint8_t* p = Translate(address);
uint8_t* p = TranslateVirtual(address);
size_t heap_guard_size = FLAGS_heap_guard_pages * 4096;
p += heap_guard_size;
@ -464,7 +469,7 @@ int Memory::Protect(uint32_t address, uint32_t size, uint32_t access) {
}
uint32_t Memory::QueryProtect(uint32_t address) {
uint8_t* p = Translate(address);
uint8_t* p = TranslateVirtual(address);
MEMORY_BASIC_INFORMATION info;
size_t info_size = VirtualQuery((void*)p, &info, sizeof(info));
if (!info_size) {
@ -563,7 +568,7 @@ uint32_t MemoryHeap::Alloc(uint32_t base_address, uint32_t size, uint32_t flags,
}
uint32_t MemoryHeap::Free(uint32_t address, uint32_t size) {
uint8_t* p = memory_->Translate(address);
uint8_t* p = memory_->TranslateVirtual(address);
// Heap allocated address.
size_t heap_guard_size = FLAGS_heap_guard_pages * 4096;
@ -606,7 +611,7 @@ uint32_t MemoryHeap::Free(uint32_t address, uint32_t size) {
}
uint32_t MemoryHeap::QuerySize(uint32_t base_address) {
uint8_t* p = memory_->Translate(base_address);
uint8_t* p = memory_->TranslateVirtual(base_address);
// Heap allocated address.
uint32_t heap_guard_size = uint32_t(FLAGS_heap_guard_pages * 4096);

View File

@ -55,10 +55,25 @@ class Memory {
int Initialize();
inline uint8_t* membase() const { return membase_; }
inline uint8_t* Translate(uint64_t guest_address) const {
return membase_ + guest_address;
inline uint8_t* virtual_membase() const { return virtual_membase_; }
inline uint8_t* TranslateVirtual(uint32_t guest_address) const {
return virtual_membase_ + guest_address;
};
template <typename T>
inline T TranslateVirtual(uint32_t guest_address) const {
return reinterpret_cast<T>(virtual_membase_ + guest_address);
};
inline uint8_t* physical_membase() const { return physical_membase_; }
inline uint8_t* TranslatePhysical(uint32_t guest_address) const {
return physical_membase_ + (guest_address & 0x1FFFFFFF);
}
template <typename T>
inline T TranslatePhysical(uint32_t guest_address) const {
return reinterpret_cast<T>(physical_membase_ +
(guest_address & 0x1FFFFFFF));
}
inline uint64_t* reserve_address() { return &reserve_address_; }
inline uint64_t* reserve_value() { return &reserve_value_; }
@ -100,7 +115,8 @@ class Memory {
private:
uint32_t system_page_size_;
uint8_t* membase_;
uint8_t* virtual_membase_;
uint8_t* physical_membase_;
uint64_t reserve_address_;
uint64_t reserve_value_;
uint64_t trace_base_;