diff --git a/src/xenia/kernel/util/shim_utils.h b/src/xenia/kernel/util/shim_utils.h index 57d5d1e98..91ee8efe0 100644 --- a/src/xenia/kernel/util/shim_utils.h +++ b/src/xenia/kernel/util/shim_utils.h @@ -33,8 +33,8 @@ using PPCContext = xe::cpu::ppc::PPCContext; library_name, ordinals::export_name, \ (xe::cpu::xe_kernel_export_shim_fn)export_name##_shim); -#define SHIM_MEM_BASE ppc_context->virtual_membase -#define SHIM_MEM_ADDR(a) (a ? (ppc_context->virtual_membase + a) : nullptr) +#define SHIM_MEM_ADDR(a) \ + ((a) ? ppc_context->kernel_state->memory()->TranslateVirtual(a) : nullptr) #define SHIM_MEM_8(a) xe::load_and_swap(SHIM_MEM_ADDR(a)) #define SHIM_MEM_16(a) xe::load_and_swap(SHIM_MEM_ADDR(a)) diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_modules.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_modules.cc index c1597fd4a..44483bcf3 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_modules.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_modules.cc @@ -243,8 +243,8 @@ dword_result_t XexGetProcedureAddress(lpvoid_t hmodule, dword_t ordinal, assert_not_zero(ordinal); bool is_string_name = (ordinal & 0xFFFF0000) != 0; - auto string_name = reinterpret_cast( - kernel_memory()->virtual_membase() + ordinal); + auto string_name = + reinterpret_cast(kernel_memory()->TranslateVirtual(ordinal)); X_STATUS result = X_STATUS_INVALID_HANDLE; diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_ob.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_ob.cc index 45bcb3355..18d518753 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_ob.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_ob.cc @@ -166,7 +166,7 @@ dword_result_t ObDereferenceObject(dword_t native_ptr) { } auto object = XObject::GetNativeObject( - kernel_state(), kernel_memory()->virtual_membase() + native_ptr); + kernel_state(), kernel_memory()->TranslateVirtual(native_ptr)); if (object) { object->Release(); } diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc index 71dcb5f7c..3182b510e 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc @@ -241,7 +241,7 @@ dword_result_t RtlUnicodeStringToAnsiString( uint32_t buffer_ptr = kernel_memory()->SystemHeapAlloc(uint32_t(ansi_str.size() + 1)); - memcpy(kernel_memory()->virtual_membase() + buffer_ptr, ansi_str.data(), + memcpy(kernel_memory()->TranslateVirtual(buffer_ptr), ansi_str.data(), ansi_str.size() + 1); destination_ptr->length = static_cast(ansi_str.size()); destination_ptr->maximum_length = @@ -250,7 +250,7 @@ dword_result_t RtlUnicodeStringToAnsiString( } else { uint32_t buffer_capacity = destination_ptr->maximum_length; auto buffer_ptr = - kernel_memory()->virtual_membase() + destination_ptr->pointer; + kernel_memory()->TranslateVirtual(destination_ptr->pointer); if (buffer_capacity < ansi_str.size() + 1) { // Too large - we just write what we can. result = X_STATUS_BUFFER_OVERFLOW; @@ -332,7 +332,7 @@ pointer_result_t RtlImageNtHeader(lpvoid_t module) { if (nt_magic != 0x4550) { // 'PE' return 0; } - return static_cast(nt_header - kernel_memory()->virtual_membase()); + return kernel_memory()->HostToGuestVirtual(nt_header); } DECLARE_XBOXKRNL_EXPORT1(RtlImageNtHeader, kNone, kImplemented); diff --git a/src/xenia/memory.cc b/src/xenia/memory.cc index 77f62d9d8..d4db87faf 100644 --- a/src/xenia/memory.cc +++ b/src/xenia/memory.cc @@ -430,7 +430,6 @@ bool Memory::AccessViolationCallback(void* host_address, bool is_write) { // TODO(Triang3l): Handle GPU readback. return false; } - // Access via physical_membase_ is special, when need to bypass everything, // so only watching virtual memory regions. if (reinterpret_cast(host_address) < @@ -439,29 +438,14 @@ bool Memory::AccessViolationCallback(void* host_address, bool is_write) { reinterpret_cast(physical_membase_)) { return false; } - - uint32_t virtual_address = - uint32_t(reinterpret_cast(host_address) - virtual_membase_); - // If the 4 KB page offset in 0xE0000000 cannot be applied via memory mapping, - // it will be added by CPU load/store implementations, so the host virtual - // addresses (relative to virtual_membase_) where access violations occur do - // not match guest virtual addresses. Revert what CPU memory accesses are - // doing. - // TODO(Triang3l): Move this to a host->guest address conversion function. - if (virtual_address >= 0xE0000000) { - uint32_t host_address_offset = heaps_.vE0000000.host_address_offset(); - if (virtual_address < 0xE0000000 + host_address_offset) { - return false; - } - virtual_address -= host_address_offset; - } - + uint32_t virtual_address = HostToGuestVirtual(host_address); BaseHeap* heap = LookupHeap(virtual_address); if (heap == &heaps_.vA0000000 || heap == &heaps_.vC0000000 || heap == &heaps_.vE0000000) { - return static_cast(heap)->TriggerWatches( - virtual_address / system_page_size_ * system_page_size_, - system_page_size_, is_write, false); + // Will be rounded to physical page boundaries internally, so just pass 1 as + // the length - guranteed not to cross page boundaries also. + return static_cast(heap)->TriggerWatches(virtual_address, 1, + is_write, false); } return false; diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index 4884c260e..3fb8fb452 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -344,17 +344,10 @@ struct X_VIDEO_MODE { }; static_assert_size(X_VIDEO_MODE, 48); +// https://docs.microsoft.com/en-us/windows/win32/api/ntdef/ns-ntdef-list_entry struct X_LIST_ENTRY { be flink_ptr; // next entry / head be blink_ptr; // previous entry / head - - // Assumes X_LIST_ENTRY is within guest memory! - void initialize(uint8_t* virtual_membase) { - flink_ptr = static_cast(reinterpret_cast(this) - - virtual_membase); - blink_ptr = static_cast(reinterpret_cast(this) - - virtual_membase); - } }; static_assert_size(X_LIST_ENTRY, 8);