Special memory functions for system allocs.

This commit is contained in:
Ben Vanik 2015-03-28 15:54:44 -07:00
parent 71eabf7f2b
commit 3a197705bb
12 changed files with 87 additions and 70 deletions

View File

@ -78,9 +78,8 @@ X_STATUS AudioSystem::Setup() {
reinterpret_cast<MMIOWriteCallback>(MMIOWriteRegisterThunk)); reinterpret_cast<MMIOWriteCallback>(MMIOWriteRegisterThunk));
// Setup XMA contexts ptr. // Setup XMA contexts ptr.
registers_.xma_context_array_ptr = uint32_t( registers_.xma_context_array_ptr = memory()->SystemHeapAlloc(
memory()->HeapAlloc(0, kXmaContextSize * kXmaContextCount, kXmaContextSize * kXmaContextCount, 256, kSystemHeapPhysical);
MEMORY_FLAG_PHYSICAL | MEMORY_FLAG_ZERO, 256));
// Add all contexts to the free list. // Add all contexts to the free list.
for (int i = kXmaContextCount - 1; i >= 0; --i) { for (int i = kXmaContextCount - 1; i >= 0; --i) {
xma_context_free_list_.push_back(registers_.xma_context_array_ptr + xma_context_free_list_.push_back(registers_.xma_context_array_ptr +
@ -92,7 +91,7 @@ X_STATUS AudioSystem::Setup() {
thread_state_ = thread_state_ =
new ThreadState(emulator_->processor()->runtime(), 0, 0, 16 * 1024, 0); new ThreadState(emulator_->processor()->runtime(), 0, 0, 16 * 1024, 0);
thread_state_->set_name("Audio Worker"); thread_state_->set_name("Audio Worker");
thread_block_ = (uint32_t)memory()->HeapAlloc(0, 2048, MEMORY_FLAG_ZERO); thread_block_ = memory()->SystemHeapAlloc(2048);
thread_state_->context()->r[13] = thread_block_; thread_state_->context()->r[13] = thread_block_;
// Create worker thread. // Create worker thread.
@ -169,9 +168,9 @@ void AudioSystem::Shutdown() {
thread_.join(); thread_.join();
delete thread_state_; delete thread_state_;
memory()->HeapFree(thread_block_, 0); memory()->SystemHeapFree(thread_block_);
memory()->HeapFree(registers_.xma_context_array_ptr, 0); memory()->SystemHeapFree(registers_.xma_context_array_ptr);
} }
uint32_t AudioSystem::AllocateXmaContext() { uint32_t AudioSystem::AllocateXmaContext() {
@ -217,7 +216,7 @@ X_STATUS AudioSystem::RegisterClient(uint32_t callback, uint32_t callback_arg,
unused_clients_.pop(); unused_clients_.pop();
uint32_t ptr = (uint32_t)memory()->HeapAlloc(0, 0x4, 0); uint32_t ptr = memory()->SystemHeapAlloc(0x4);
auto mem = memory()->membase(); auto mem = memory()->membase();
poly::store_and_swap<uint32_t>(mem + ptr, callback_arg); poly::store_and_swap<uint32_t>(mem + ptr, callback_arg);

View File

@ -55,7 +55,7 @@ Processor::Processor(xe::Memory* memory, ExportResolver* export_resolver)
Processor::~Processor() { Processor::~Processor() {
if (interrupt_thread_block_) { if (interrupt_thread_block_) {
memory_->HeapFree(interrupt_thread_block_, 2048); memory_->SystemHeapFree(interrupt_thread_block_);
delete interrupt_thread_state_; delete interrupt_thread_state_;
} }
@ -98,7 +98,7 @@ int Processor::Setup() {
interrupt_thread_state_ = new ThreadState(runtime_, 0, 0, 16 * 1024, 0); interrupt_thread_state_ = new ThreadState(runtime_, 0, 0, 16 * 1024, 0);
interrupt_thread_state_->set_name("Interrupt"); interrupt_thread_state_->set_name("Interrupt");
interrupt_thread_block_ = memory_->HeapAlloc(0, 2048, MEMORY_FLAG_ZERO); interrupt_thread_block_ = memory_->SystemHeapAlloc(2048);
interrupt_thread_state_->context()->r[13] = interrupt_thread_block_; interrupt_thread_state_->context()->r[13] = interrupt_thread_block_;
return 0; return 0;

View File

@ -41,7 +41,7 @@ ThreadState::ThreadState(Runtime* runtime, uint32_t thread_id,
backend_data_ = runtime->backend()->AllocThreadData(); backend_data_ = runtime->backend()->AllocThreadData();
if (!stack_address) { if (!stack_address) {
stack_address_ = memory()->HeapAlloc(0, stack_size, MEMORY_FLAG_ZERO); stack_address_ = memory()->SystemHeapAlloc(stack_size);
stack_allocated_ = true; stack_allocated_ = true;
} else { } else {
stack_address_ = stack_address; stack_address_ = stack_address;
@ -86,7 +86,7 @@ ThreadState::~ThreadState() {
free(context_); free(context_);
if (stack_allocated_) { if (stack_allocated_) {
memory()->HeapFree(stack_address_, stack_size_); memory()->SystemHeapFree(stack_address_);
} }
} }

View File

@ -78,15 +78,9 @@ XThread::~XThread() {
if (thread_state_) { if (thread_state_) {
delete thread_state_; delete thread_state_;
} }
if (scratch_address_) { kernel_state()->memory()->SystemHeapFree(scratch_address_);
kernel_state()->memory()->HeapFree(scratch_address_, 0); kernel_state()->memory()->SystemHeapFree(tls_address_);
} kernel_state()->memory()->SystemHeapFree(thread_state_address_);
if (tls_address_) {
kernel_state()->memory()->HeapFree(tls_address_, 0);
}
if (thread_state_address_) {
kernel_state()->memory()->HeapFree(thread_state_address_, 0);
}
if (thread_handle_) { if (thread_handle_) {
// TODO(benvanik): platform kill // TODO(benvanik): platform kill
@ -151,8 +145,7 @@ X_STATUS XThread::Create() {
// 0x160: last error // 0x160: last error
// So, at offset 0x100 we have a 4b pointer to offset 200, then have the // So, at offset 0x100 we have a 4b pointer to offset 200, then have the
// structure. // structure.
thread_state_address_ = thread_state_address_ = memory()->SystemHeapAlloc(2048);
(uint32_t)memory()->HeapAlloc(0, 2048, MEMORY_FLAG_ZERO);
if (!thread_state_address_) { if (!thread_state_address_) {
XELOGW("Unable to allocate thread state block"); XELOGW("Unable to allocate thread state block");
return X_STATUS_NO_MEMORY; return X_STATUS_NO_MEMORY;
@ -166,13 +159,12 @@ X_STATUS XThread::Create() {
// Allocate thread scratch. // Allocate thread scratch.
// This is used by interrupts/APCs/etc so we can round-trip pointers through. // This is used by interrupts/APCs/etc so we can round-trip pointers through.
scratch_size_ = 4 * 16; scratch_size_ = 4 * 16;
scratch_address_ = scratch_address_ = memory()->SystemHeapAlloc(scratch_size_);
(uint32_t)memory()->HeapAlloc(0, scratch_size_, MEMORY_FLAG_ZERO);
// Allocate TLS block. // Allocate TLS block.
const xe_xex2_header_t* header = module->xex_header(); const xe_xex2_header_t* header = module->xex_header();
uint32_t tls_size = header->tls_info.slot_count * header->tls_info.data_size; uint32_t tls_size = header->tls_info.slot_count * header->tls_info.data_size;
tls_address_ = (uint32_t)memory()->HeapAlloc(0, tls_size, MEMORY_FLAG_ZERO); tls_address_ = memory()->SystemHeapAlloc(tls_size);
if (!tls_address_) { if (!tls_address_) {
XELOGW("Unable to allocate thread local storage block"); XELOGW("Unable to allocate thread local storage block");
module->Release(); module->Release();
@ -421,9 +413,8 @@ void XThread::DeliverAPCs(void* data) {
// kernel_routine(apc_address, &normal_routine, &normal_context, // kernel_routine(apc_address, &normal_routine, &normal_context,
// &system_arg1, &system_arg2) // &system_arg1, &system_arg2)
uint64_t kernel_args[] = { uint64_t kernel_args[] = {
apc_address, thread->scratch_address_ + 0, apc_address, thread->scratch_address_ + 0, thread->scratch_address_ + 4,
thread->scratch_address_ + 4, thread->scratch_address_ + 8, thread->scratch_address_ + 8, thread->scratch_address_ + 12,
thread->scratch_address_ + 12,
}; };
processor->ExecuteInterrupt(0, kernel_routine, kernel_args, processor->ExecuteInterrupt(0, kernel_routine, kernel_args,
poly::countof(kernel_args)); poly::countof(kernel_args));

View File

@ -23,9 +23,7 @@ XUserModule::XUserModule(KernelState* kernel_state, const char* path)
: XModule(kernel_state, path), xex_(nullptr), execution_info_ptr_(0) {} : XModule(kernel_state, path), xex_(nullptr), execution_info_ptr_(0) {}
XUserModule::~XUserModule() { XUserModule::~XUserModule() {
if (execution_info_ptr_) { kernel_state()->memory()->SystemHeapFree(execution_info_ptr_);
kernel_state()->memory()->HeapFree(execution_info_ptr_, 0);
}
xe_xex2_dealloc(xex_); xe_xex2_dealloc(xex_);
} }
@ -116,8 +114,7 @@ X_STATUS XUserModule::LoadFromMemory(const void* addr, const size_t length) {
// Store execution info for later use. // Store execution info for later use.
// TODO(benvanik): just put entire xex header in memory somewhere? // TODO(benvanik): just put entire xex header in memory somewhere?
execution_info_ptr_ = execution_info_ptr_ = kernel_state()->memory()->SystemHeapAlloc(24);
uint32_t(kernel_state()->memory()->HeapAlloc(0, 24, MEMORY_FLAG_ZERO, 0));
auto eip = kernel_state()->memory()->membase() + execution_info_ptr_; auto eip = kernel_state()->memory()->membase() + execution_info_ptr_;
const auto& ex = xe_xex2_get_header(xex_)->execution_info; 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 + 0x00, ex.media_id);

View File

@ -127,8 +127,8 @@ SHIM_CALL XamAlloc_shim(PPCContext* ppc_state, KernelState* state) {
// Allocate from the heap. Not sure why XAM does this specially, perhaps // Allocate from the heap. Not sure why XAM does this specially, perhaps
// it keeps stuff in a separate heap? // it keeps stuff in a separate heap?
uint64_t ptr = state->memory()->HeapAlloc(0, size, MEMORY_FLAG_ZERO); uint32_t ptr = state->memory()->SystemHeapAlloc(size);
SHIM_SET_MEM_32(out_ptr, uint32_t(ptr)); SHIM_SET_MEM_32(out_ptr, ptr);
SHIM_SET_RETURN_32(X_ERROR_SUCCESS); SHIM_SET_RETURN_32(X_ERROR_SUCCESS);
} }
@ -138,7 +138,7 @@ SHIM_CALL XamFree_shim(PPCContext* ppc_state, KernelState* state) {
XELOGD("XamFree(%.8X)", ptr); XELOGD("XamFree(%.8X)", ptr);
state->memory()->HeapFree(ptr, 0); state->memory()->SystemHeapFree(ptr);
SHIM_SET_RETURN_32(X_ERROR_SUCCESS); SHIM_SET_RETURN_32(X_ERROR_SUCCESS);
} }

View File

@ -418,8 +418,7 @@ SHIM_CALL ExAllocatePoolTypeWithTag_shim(PPCContext* ppc_state,
alignment = 4 * 1024; alignment = 4 * 1024;
} }
uint32_t addr = (uint32_t)state->memory()->HeapAlloc( uint32_t addr = state->memory()->SystemHeapAlloc(adjusted_size, alignment);
0, adjusted_size, MEMORY_FLAG_ZERO, alignment);
SHIM_SET_RETURN_32(addr); SHIM_SET_RETURN_32(addr);
} }
@ -429,7 +428,7 @@ SHIM_CALL ExFreePool_shim(PPCContext* ppc_state, KernelState* state) {
XELOGD("ExFreePool(%.8X)", base_address); XELOGD("ExFreePool(%.8X)", base_address);
state->memory()->HeapFree(base_address, 0); state->memory()->SystemHeapFree(base_address);
} }
SHIM_CALL KeLockL2_shim(PPCContext* ppc_state, KernelState* state) { SHIM_CALL KeLockL2_shim(PPCContext* ppc_state, KernelState* state) {

View File

@ -50,14 +50,14 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
// Set to a valid value when a remote debugger is attached. // 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 // 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. // arguments. If we wanted to see what would happen we could fake that.
uint32_t pKeDebugMonitorData = (uint32_t)memory_->HeapAlloc(0, 256, 0); uint32_t pKeDebugMonitorData = memory_->SystemHeapAlloc(256);
export_resolver_->SetVariableMapping( export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::KeDebugMonitorData, pKeDebugMonitorData); "xboxkrnl.exe", ordinals::KeDebugMonitorData, pKeDebugMonitorData);
poly::store_and_swap<uint32_t>(mem + pKeDebugMonitorData, 0); poly::store_and_swap<uint32_t>(mem + pKeDebugMonitorData, 0);
// KeCertMonitorData (?*) // KeCertMonitorData (?*)
// Always set to zero, ignored. // Always set to zero, ignored.
uint32_t pKeCertMonitorData = (uint32_t)memory_->HeapAlloc(0, 4, 0); uint32_t pKeCertMonitorData = memory_->SystemHeapAlloc(4);
export_resolver_->SetVariableMapping( export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::KeCertMonitorData, pKeCertMonitorData); "xboxkrnl.exe", ordinals::KeCertMonitorData, pKeCertMonitorData);
poly::store_and_swap<uint32_t>(mem + pKeCertMonitorData, 0); poly::store_and_swap<uint32_t>(mem + pKeCertMonitorData, 0);
@ -70,7 +70,7 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
// //
// aomega08 says the value is 0x02000817, bit 27: debug mode on. // aomega08 says the value is 0x02000817, bit 27: debug mode on.
// When that is set, though, allocs crash in weird ways. // When that is set, though, allocs crash in weird ways.
uint32_t pXboxHardwareInfo = (uint32_t)memory_->HeapAlloc(0, 16, 0); uint32_t pXboxHardwareInfo = memory_->SystemHeapAlloc(16);
export_resolver_->SetVariableMapping( export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::XboxHardwareInfo, pXboxHardwareInfo); "xboxkrnl.exe", ordinals::XboxHardwareInfo, pXboxHardwareInfo);
poly::store_and_swap<uint32_t>(mem + pXboxHardwareInfo + 0, 0); // flags poly::store_and_swap<uint32_t>(mem + pXboxHardwareInfo + 0, 0); // flags
@ -87,11 +87,11 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
// 0x80101000 <- our module structure // 0x80101000 <- our module structure
// 0x80101058 <- pointer to xex header // 0x80101058 <- pointer to xex header
// 0x80101100 <- xex header base // 0x80101100 <- xex header base
uint32_t ppXexExecutableModuleHandle = (uint32_t)memory_->HeapAlloc(0, 4, 0); uint32_t ppXexExecutableModuleHandle = memory_->SystemHeapAlloc(4);
export_resolver_->SetVariableMapping("xboxkrnl.exe", export_resolver_->SetVariableMapping("xboxkrnl.exe",
ordinals::XexExecutableModuleHandle, ordinals::XexExecutableModuleHandle,
ppXexExecutableModuleHandle); ppXexExecutableModuleHandle);
uint32_t pXexExecutableModuleHandle = (uint32_t)memory_->HeapAlloc(0, 256, 0); uint32_t pXexExecutableModuleHandle = memory_->SystemHeapAlloc(256);
poly::store_and_swap<uint32_t>(mem + ppXexExecutableModuleHandle, poly::store_and_swap<uint32_t>(mem + ppXexExecutableModuleHandle,
pXexExecutableModuleHandle); pXexExecutableModuleHandle);
poly::store_and_swap<uint32_t>(mem + pXexExecutableModuleHandle + 0x58, poly::store_and_swap<uint32_t>(mem + pXexExecutableModuleHandle + 0x58,
@ -101,7 +101,7 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
// The name of the xex. Not sure this is ever really used on real devices. // The name of the xex. Not sure this is ever really used on real devices.
// Perhaps it's how swap disc/etc data is sent? // Perhaps it's how swap disc/etc data is sent?
// Always set to "default.xex" (with quotes) for now. // Always set to "default.xex" (with quotes) for now.
uint32_t pExLoadedCommandLine = (uint32_t)memory_->HeapAlloc(0, 1024, 0); uint32_t pExLoadedCommandLine = memory_->SystemHeapAlloc(1024);
export_resolver_->SetVariableMapping( export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::ExLoadedCommandLine, pExLoadedCommandLine); "xboxkrnl.exe", ordinals::ExLoadedCommandLine, pExLoadedCommandLine);
char command_line[] = "\"default.xex\""; char command_line[] = "\"default.xex\"";
@ -111,7 +111,7 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
// XboxKrnlVersion (8b) // XboxKrnlVersion (8b)
// Kernel version, looks like 2b.2b.2b.2b. // Kernel version, looks like 2b.2b.2b.2b.
// I've only seen games check >=, so we just fake something here. // I've only seen games check >=, so we just fake something here.
uint32_t pXboxKrnlVersion = (uint32_t)memory_->HeapAlloc(0, 8, 0); uint32_t pXboxKrnlVersion = memory_->SystemHeapAlloc(8);
export_resolver_->SetVariableMapping( export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::XboxKrnlVersion, pXboxKrnlVersion); "xboxkrnl.exe", ordinals::XboxKrnlVersion, pXboxKrnlVersion);
poly::store_and_swap<uint16_t>(mem + pXboxKrnlVersion + 0, 2); poly::store_and_swap<uint16_t>(mem + pXboxKrnlVersion + 0, 2);
@ -123,23 +123,22 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
// KeTimeStampBundle (ad) // KeTimeStampBundle (ad)
// This must be updated during execution, at 1ms intevals. // This must be updated during execution, at 1ms intevals.
// We setup a system timer here to do that. // We setup a system timer here to do that.
uint32_t pKeTimeStampBundle = (uint32_t)memory_->HeapAlloc(0, 24, 0); uint32_t pKeTimeStampBundle = memory_->SystemHeapAlloc(24);
export_resolver_->SetVariableMapping( export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::KeTimeStampBundle, pKeTimeStampBundle); "xboxkrnl.exe", ordinals::KeTimeStampBundle, pKeTimeStampBundle);
poly::store_and_swap<uint64_t>(mem + pKeTimeStampBundle + 0, 0); poly::store_and_swap<uint64_t>(mem + pKeTimeStampBundle + 0, 0);
poly::store_and_swap<uint64_t>(mem + pKeTimeStampBundle + 8, 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 + 16, GetTickCount());
poly::store_and_swap<uint32_t>(mem + pKeTimeStampBundle + 20, 0); poly::store_and_swap<uint32_t>(mem + pKeTimeStampBundle + 20, 0);
CreateTimerQueueTimer(&timestamp_timer_, nullptr, CreateTimerQueueTimer(
[](PVOID param, BOOLEAN timer_or_wait_fired) { &timestamp_timer_, nullptr,
auto timestamp_bundle = [](PVOID param, BOOLEAN timer_or_wait_fired) {
reinterpret_cast<uint8_t*>(param); auto timestamp_bundle = reinterpret_cast<uint8_t*>(param);
poly::store_and_swap<uint32_t>(timestamp_bundle + 16, poly::store_and_swap<uint32_t>(timestamp_bundle + 16, GetTickCount());
GetTickCount()); },
}, mem + pKeTimeStampBundle, 0,
mem + pKeTimeStampBundle, 0, 1, // 1ms
1, // 1ms WT_EXECUTEINTIMERTHREAD);
WT_EXECUTEINTIMERTHREAD);
} }
void XboxkrnlModule::RegisterExportTable(ExportResolver* export_resolver) { void XboxkrnlModule::RegisterExportTable(ExportResolver* export_resolver) {
@ -149,14 +148,14 @@ void XboxkrnlModule::RegisterExportTable(ExportResolver* export_resolver) {
return; return;
} }
// Build the export table used for resolution. // Build the export table used for resolution.
#include "xenia/kernel/util/export_table_pre.inc" #include "xenia/kernel/util/export_table_pre.inc"
static KernelExport xboxkrnl_export_table[] = { static KernelExport xboxkrnl_export_table[] = {
#include "xenia/kernel/xboxkrnl_table.inc" #include "xenia/kernel/xboxkrnl_table.inc"
}; };
#include "xenia/kernel/util/export_table_post.inc" #include "xenia/kernel/util/export_table_post.inc"
export_resolver->RegisterTable("xboxkrnl.exe", xboxkrnl_export_table, export_resolver->RegisterTable("xboxkrnl.exe", xboxkrnl_export_table,
poly::countof(xboxkrnl_export_table)); poly::countof(xboxkrnl_export_table));
} }
XboxkrnlModule::~XboxkrnlModule() { XboxkrnlModule::~XboxkrnlModule() {

View File

@ -205,7 +205,7 @@ SHIM_CALL RtlFreeAnsiString_shim(PPCContext* ppc_state, KernelState* state) {
return; return;
} }
uint32_t length = SHIM_MEM_16(string_ptr + 2); uint32_t length = SHIM_MEM_16(string_ptr + 2);
state->memory()->HeapFree(buffer, length); state->memory()->SystemHeapFree(buffer);
SHIM_SET_MEM_16(string_ptr + 0, 0); SHIM_SET_MEM_16(string_ptr + 0, 0);
SHIM_SET_MEM_16(string_ptr + 2, 0); SHIM_SET_MEM_16(string_ptr + 2, 0);
@ -260,7 +260,7 @@ SHIM_CALL RtlFreeUnicodeString_shim(PPCContext* ppc_state, KernelState* state) {
return; return;
} }
uint32_t length = SHIM_MEM_16(string_ptr + 2); uint32_t length = SHIM_MEM_16(string_ptr + 2);
state->memory()->HeapFree(buffer, length); state->memory()->SystemHeapFree(buffer);
SHIM_SET_MEM_16(string_ptr + 0, 0); SHIM_SET_MEM_16(string_ptr + 0, 0);
SHIM_SET_MEM_16(string_ptr + 2, 0); SHIM_SET_MEM_16(string_ptr + 2, 0);
@ -292,8 +292,8 @@ SHIM_CALL RtlUnicodeStringToAnsiString_shim(PPCContext* ppc_state,
X_STATUS result = X_STATUS_SUCCESS; X_STATUS result = X_STATUS_SUCCESS;
if (alloc_dest) { if (alloc_dest) {
auto buffer_ptr = uint32_t buffer_ptr =
state->memory()->HeapAlloc(0, uint32_t(ansi_str.size() + 1), 0); state->memory()->SystemHeapAlloc(uint32_t(ansi_str.size() + 1));
memcpy(SHIM_MEM_ADDR(buffer_ptr), ansi_str.data(), ansi_str.size() + 1); memcpy(SHIM_MEM_ADDR(buffer_ptr), ansi_str.data(), ansi_str.size() + 1);
SHIM_SET_MEM_16(destination_ptr + 0, SHIM_SET_MEM_16(destination_ptr + 0,
static_cast<uint16_t>(ansi_str.size())); static_cast<uint16_t>(ansi_str.size()));

View File

@ -452,28 +452,32 @@ void xe::kernel::xboxkrnl::RegisterVideoExports(ExportResolver* export_resolver,
// VdGlobalDevice (4b) // VdGlobalDevice (4b)
// Pointer to a global D3D device. Games only seem to set this, so we don't // Pointer to a global D3D device. Games only seem to set this, so we don't
// have to do anything. We may want to read it back later, though. // have to do anything. We may want to read it back later, though.
uint32_t pVdGlobalDevice = (uint32_t)memory->HeapAlloc(0, 4, 0); uint32_t pVdGlobalDevice =
memory->SystemHeapAlloc(4, 32, kSystemHeapPhysical);
export_resolver->SetVariableMapping("xboxkrnl.exe", ordinals::VdGlobalDevice, export_resolver->SetVariableMapping("xboxkrnl.exe", ordinals::VdGlobalDevice,
pVdGlobalDevice); pVdGlobalDevice);
poly::store_and_swap<uint32_t>(mem + pVdGlobalDevice, 0); poly::store_and_swap<uint32_t>(mem + pVdGlobalDevice, 0);
// VdGlobalXamDevice (4b) // VdGlobalXamDevice (4b)
// Pointer to the XAM D3D device, which we don't have. // Pointer to the XAM D3D device, which we don't have.
uint32_t pVdGlobalXamDevice = (uint32_t)memory->HeapAlloc(0, 4, 0); uint32_t pVdGlobalXamDevice =
memory->SystemHeapAlloc(4, 32, kSystemHeapPhysical);
export_resolver->SetVariableMapping( export_resolver->SetVariableMapping(
"xboxkrnl.exe", ordinals::VdGlobalXamDevice, pVdGlobalXamDevice); "xboxkrnl.exe", ordinals::VdGlobalXamDevice, pVdGlobalXamDevice);
poly::store_and_swap<uint32_t>(mem + pVdGlobalXamDevice, 0); poly::store_and_swap<uint32_t>(mem + pVdGlobalXamDevice, 0);
// VdGpuClockInMHz (4b) // VdGpuClockInMHz (4b)
// GPU clock. Xenos is 500MHz. Hope nothing is relying on this timing... // GPU clock. Xenos is 500MHz. Hope nothing is relying on this timing...
uint32_t pVdGpuClockInMHz = (uint32_t)memory->HeapAlloc(0, 4, 0); uint32_t pVdGpuClockInMHz =
memory->SystemHeapAlloc(4, 32, kSystemHeapPhysical);
export_resolver->SetVariableMapping("xboxkrnl.exe", ordinals::VdGpuClockInMHz, export_resolver->SetVariableMapping("xboxkrnl.exe", ordinals::VdGpuClockInMHz,
pVdGpuClockInMHz); pVdGpuClockInMHz);
poly::store_and_swap<uint32_t>(mem + pVdGpuClockInMHz, 500); poly::store_and_swap<uint32_t>(mem + pVdGpuClockInMHz, 500);
// VdHSIOCalibrationLock (28b) // VdHSIOCalibrationLock (28b)
// CriticalSection. // CriticalSection.
uint32_t pVdHSIOCalibrationLock = (uint32_t)memory->HeapAlloc(0, 28, 0); uint32_t pVdHSIOCalibrationLock =
memory->SystemHeapAlloc(28, 32, kSystemHeapPhysical);
export_resolver->SetVariableMapping( export_resolver->SetVariableMapping(
"xboxkrnl.exe", ordinals::VdHSIOCalibrationLock, pVdHSIOCalibrationLock); "xboxkrnl.exe", ordinals::VdHSIOCalibrationLock, pVdHSIOCalibrationLock);
auto hsio_lock = auto hsio_lock =

View File

@ -267,18 +267,18 @@ void Memory::UnmapViews() {
void Memory::Zero(uint32_t address, uint32_t size) { void Memory::Zero(uint32_t address, uint32_t size) {
uint8_t* p = membase_ + address; uint8_t* p = membase_ + address;
memset(p, 0, size); std::memset(p, 0, size);
} }
void Memory::Fill(uint32_t address, uint32_t size, uint8_t value) { void Memory::Fill(uint32_t address, uint32_t size, uint8_t value) {
uint8_t* p = membase_ + address; uint8_t* p = membase_ + address;
memset(p, value, size); std::memset(p, value, size);
} }
void Memory::Copy(uint32_t dest, uint32_t src, uint32_t size) { void Memory::Copy(uint32_t dest, uint32_t src, uint32_t size) {
uint8_t* pdest = membase_ + dest; uint8_t* pdest = membase_ + dest;
const uint8_t* psrc = membase_ + src; const uint8_t* psrc = membase_ + src;
memcpy(pdest, psrc, size); std::memcpy(pdest, psrc, size);
} }
uint32_t Memory::SearchAligned(uint32_t start, uint32_t end, uint32_t Memory::SearchAligned(uint32_t start, uint32_t end,
@ -328,6 +328,25 @@ void Memory::CancelWriteWatch(uintptr_t watch_handle) {
mmio_handler_->CancelWriteWatch(watch_handle); mmio_handler_->CancelWriteWatch(watch_handle);
} }
uint32_t Memory::SystemHeapAlloc(uint32_t size, uint32_t alignment,
uint32_t system_heap_flags) {
// TODO(benvanik): lightweight pool.
bool is_physical = !!(system_heap_flags & kSystemHeapPhysical);
uint32_t flags = MEMORY_FLAG_ZERO;
if (is_physical) {
flags |= MEMORY_FLAG_PHYSICAL;
}
return HeapAlloc(0, size, flags, alignment);
}
void Memory::SystemHeapFree(uint32_t address) {
if (!address) {
return;
}
// TODO(benvanik): lightweight pool.
HeapFree(address, 0);
}
uint32_t Memory::HeapAlloc(uint32_t base_address, uint32_t size, uint32_t flags, uint32_t Memory::HeapAlloc(uint32_t base_address, uint32_t size, uint32_t flags,
uint32_t alignment) { uint32_t alignment) {
// If we were given a base address we are outside of the normal heap and // If we were given a base address we are outside of the normal heap and

View File

@ -21,6 +21,12 @@
namespace xe { namespace xe {
enum SystemHeapFlag : uint32_t {
kSystemHeapVirtual = 1 << 0,
kSystemHeapPhysical = 1 << 1,
kSystemHeapDefault = kSystemHeapVirtual,
};
class MemoryHeap; class MemoryHeap;
// TODO(benvanik): move to heap. // TODO(benvanik): move to heap.
@ -75,6 +81,9 @@ class Memory {
void* callback_context, void* callback_data); void* callback_context, void* callback_data);
void CancelWriteWatch(uintptr_t watch_handle); void CancelWriteWatch(uintptr_t watch_handle);
uint32_t SystemHeapAlloc(uint32_t size, uint32_t alignment = 0x20,
uint32_t system_heap_flags = kSystemHeapDefault);
void SystemHeapFree(uint32_t address);
uint32_t HeapAlloc(uint32_t base_address, uint32_t size, uint32_t flags, uint32_t HeapAlloc(uint32_t base_address, uint32_t size, uint32_t flags,
uint32_t alignment = 0x20); uint32_t alignment = 0x20);
int HeapFree(uint32_t address, uint32_t size); int HeapFree(uint32_t address, uint32_t size);