Proper misalignment for AllocatePool, add guest object table
This commit is contained in:
committed by
Radosław Gliński
parent
ee424ae14a
commit
6a08208dc8
@@ -14,9 +14,9 @@
|
||||
#include "xenia/base/math.h"
|
||||
#include "xenia/kernel/kernel_state.h"
|
||||
#include "xenia/kernel/util/shim_utils.h"
|
||||
#include "xenia/kernel/xboxkrnl/xboxkrnl_memory.h"
|
||||
#include "xenia/kernel/xboxkrnl/xboxkrnl_private.h"
|
||||
#include "xenia/xbox.h"
|
||||
#include "xenia/kernel/xboxkrnl/xboxkrnl_memory.h"
|
||||
DEFINE_bool(
|
||||
ignore_offset_for_ranged_allocations, false,
|
||||
"Allows to ignore 4k offset for physical allocations with provided range. "
|
||||
@@ -380,10 +380,10 @@ dword_result_t NtAllocateEncryptedMemory_entry(dword_t unk, dword_t region_size,
|
||||
DECLARE_XBOXKRNL_EXPORT1(NtAllocateEncryptedMemory, kMemory, kImplemented);
|
||||
|
||||
uint32_t xeMmAllocatePhysicalMemoryEx(uint32_t flags, uint32_t region_size,
|
||||
uint32_t protect_bits,
|
||||
uint32_t min_addr_range,
|
||||
uint32_t max_addr_range,
|
||||
uint32_t alignment) {
|
||||
uint32_t protect_bits,
|
||||
uint32_t min_addr_range,
|
||||
uint32_t max_addr_range,
|
||||
uint32_t alignment) {
|
||||
// Type will usually be 0 (user request?), where 1 and 2 are sometimes made
|
||||
// by D3D/etc.
|
||||
|
||||
@@ -463,7 +463,7 @@ dword_result_t MmAllocatePhysicalMemory_entry(dword_t flags,
|
||||
dword_t region_size,
|
||||
dword_t protect_bits) {
|
||||
return xeMmAllocatePhysicalMemoryEx(flags, region_size, protect_bits, 0,
|
||||
0xFFFFFFFFu, 0);
|
||||
0xFFFFFFFFu, 0);
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(MmAllocatePhysicalMemory, kMemory, kImplemented);
|
||||
|
||||
@@ -642,35 +642,64 @@ dword_result_t MmMapIoSpace_entry(dword_t unk0, lpvoid_t src_address,
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(MmMapIoSpace, kMemory, kImplemented);
|
||||
|
||||
dword_result_t ExAllocatePoolTypeWithTag_entry(dword_t size, dword_t tag,
|
||||
dword_t zero) {
|
||||
uint32_t alignment = 8;
|
||||
uint32_t adjusted_size = size;
|
||||
if (adjusted_size < 4 * 1024) {
|
||||
adjusted_size = xe::round_up(adjusted_size, 4 * 1024);
|
||||
struct X_POOL_ALLOC_HEADER {
|
||||
uint8_t unk_0;
|
||||
uint8_t unk_1;
|
||||
uint8_t unk_2; // set this to 170
|
||||
uint8_t unk_3;
|
||||
xe::be<uint32_t> tag;
|
||||
};
|
||||
|
||||
uint32_t xeAllocatePoolTypeWithTag(PPCContext* context, uint32_t size,
|
||||
uint32_t tag, uint32_t zero) {
|
||||
if (size <= 0xFD8) {
|
||||
uint32_t adjusted_size = size + sizeof(X_POOL_ALLOC_HEADER);
|
||||
|
||||
uint32_t addr =
|
||||
kernel_state()->memory()->SystemHeapAlloc(adjusted_size, 64);
|
||||
|
||||
auto result_ptr = context->TranslateVirtual<X_POOL_ALLOC_HEADER*>(addr);
|
||||
result_ptr->unk_2 = 170;
|
||||
result_ptr->tag = tag;
|
||||
|
||||
return addr + sizeof(X_POOL_ALLOC_HEADER);
|
||||
} else {
|
||||
alignment = 4 * 1024;
|
||||
return kernel_state()->memory()->SystemHeapAlloc(size, 4096);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t addr =
|
||||
kernel_state()->memory()->SystemHeapAlloc(adjusted_size, alignment);
|
||||
|
||||
return addr;
|
||||
dword_result_t ExAllocatePoolTypeWithTag_entry(dword_t size, dword_t tag,
|
||||
dword_t zero,
|
||||
const ppc_context_t& context) {
|
||||
return xeAllocatePoolTypeWithTag(context, size, tag, zero);
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(ExAllocatePoolTypeWithTag, kMemory, kImplemented);
|
||||
dword_result_t ExAllocatePoolWithTag_entry(dword_t numbytes, dword_t tag) {
|
||||
return ExAllocatePoolTypeWithTag_entry(numbytes, tag, 0);
|
||||
|
||||
dword_result_t ExAllocatePoolWithTag_entry(dword_t numbytes, dword_t tag,
|
||||
const ppc_context_t& context) {
|
||||
return xeAllocatePoolTypeWithTag(context, numbytes, tag, 0);
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(ExAllocatePoolWithTag, kMemory, kImplemented);
|
||||
|
||||
dword_result_t ExAllocatePool_entry(dword_t size) {
|
||||
dword_result_t ExAllocatePool_entry(dword_t size,
|
||||
const ppc_context_t& context) {
|
||||
const uint32_t none = 0x656E6F4E; // 'None'
|
||||
return ExAllocatePoolTypeWithTag_entry(size, none, 0);
|
||||
return xeAllocatePoolTypeWithTag(context, size, none, 0);
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(ExAllocatePool, kMemory, kImplemented);
|
||||
|
||||
void ExFreePool_entry(lpvoid_t base_address) {
|
||||
kernel_state()->memory()->SystemHeapFree(base_address);
|
||||
void xeFreePool(PPCContext* context, uint32_t base_address) {
|
||||
auto memory = context->kernel_state->memory();
|
||||
//if 4kb aligned, there is no pool header!
|
||||
if ((base_address & (4096 - 1)) == 0) {
|
||||
memory->SystemHeapFree(base_address);
|
||||
} else {
|
||||
memory->SystemHeapFree(base_address - sizeof(X_POOL_ALLOC_HEADER));
|
||||
}
|
||||
}
|
||||
|
||||
void ExFreePool_entry(lpvoid_t base_address, const ppc_context_t& context) {
|
||||
xeFreePool(context, base_address.guest_address());
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(ExFreePool, kMemory, kImplemented);
|
||||
|
||||
@@ -710,9 +739,7 @@ DECLARE_XBOXKRNL_EXPORT1(KeLockL2, kMemory, kStub);
|
||||
void KeUnlockL2_entry() {}
|
||||
DECLARE_XBOXKRNL_EXPORT1(KeUnlockL2, kMemory, kStub);
|
||||
|
||||
dword_result_t MmCreateKernelStack_entry(dword_t stack_size, dword_t r4) {
|
||||
assert_zero(r4); // Unknown argument.
|
||||
|
||||
uint32_t xeMmCreateKernelStack(uint32_t stack_size, uint32_t r4) {
|
||||
auto stack_size_aligned = (stack_size + 0xFFF) & 0xFFFFF000;
|
||||
uint32_t stack_alignment = (stack_size & 0xF000) ? 0x1000 : 0x10000;
|
||||
|
||||
@@ -725,6 +752,9 @@ dword_result_t MmCreateKernelStack_entry(dword_t stack_size, dword_t r4) {
|
||||
&stack_address);
|
||||
return stack_address + stack_size;
|
||||
}
|
||||
dword_result_t MmCreateKernelStack_entry(dword_t stack_size, dword_t r4) {
|
||||
return xeMmCreateKernelStack(stack_size, r4);
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(MmCreateKernelStack, kMemory, kImplemented);
|
||||
|
||||
dword_result_t MmDeleteKernelStack_entry(lpvoid_t stack_base,
|
||||
|
||||
@@ -24,7 +24,12 @@ uint32_t xeMmAllocatePhysicalMemoryEx(uint32_t flags, uint32_t region_size,
|
||||
uint32_t min_addr_range,
|
||||
uint32_t max_addr_range,
|
||||
uint32_t alignment);
|
||||
uint32_t xeAllocatePoolTypeWithTag(PPCContext* context, uint32_t size,
|
||||
uint32_t tag, uint32_t zero);
|
||||
|
||||
void xeFreePool(PPCContext* context, uint32_t base_address);
|
||||
|
||||
uint32_t xeMmCreateKernelStack(uint32_t size, uint32_t r4);
|
||||
} // namespace xboxkrnl
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
@@ -1132,8 +1132,8 @@ dword_result_t KfAcquireSpinLock_entry(pointer_t<X_KSPINLOCK> lock_ptr,
|
||||
DECLARE_XBOXKRNL_EXPORT3(KfAcquireSpinLock, kThreading, kImplemented, kBlocking,
|
||||
kHighFrequency);
|
||||
|
||||
void xeKeKfReleaseSpinLock(PPCContext* ctx, X_KSPINLOCK* lock, uint32_t old_irql,
|
||||
bool change_irql) {
|
||||
void xeKeKfReleaseSpinLock(PPCContext* ctx, X_KSPINLOCK* lock,
|
||||
uint32_t old_irql, bool change_irql) {
|
||||
assert_true(lock->prcb_of_owner == static_cast<uint32_t>(ctx->r[13]));
|
||||
// Unlock.
|
||||
lock->prcb_of_owner.value = 0;
|
||||
@@ -1170,8 +1170,9 @@ dword_result_t KeTryToAcquireSpinLockAtRaisedIrql_entry(
|
||||
auto lock = reinterpret_cast<uint32_t*>(lock_ptr.host_address());
|
||||
assert_true(lock_ptr->prcb_of_owner != static_cast<uint32_t>(ppc_ctx->r[13]));
|
||||
PrefetchForCAS(lock);
|
||||
if (!xe::atomic_cas(0, xe::byte_swap(static_cast<uint32_t>(ppc_ctx->r[13])),
|
||||
lock)) {
|
||||
if (!ppc_ctx->processor->GuestAtomicCAS32(
|
||||
ppc_ctx, 0, static_cast<uint32_t>(ppc_ctx->r[13]),
|
||||
lock_ptr.guest_address())) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -1361,8 +1362,8 @@ X_STATUS xeProcessUserApcs(PPCContext* ctx) {
|
||||
return alert_status;
|
||||
}
|
||||
|
||||
static void YankApcList(PPCContext* ctx, X_KTHREAD* current_thread, unsigned apc_mode,
|
||||
bool rundown) {
|
||||
static void YankApcList(PPCContext* ctx, X_KTHREAD* current_thread,
|
||||
unsigned apc_mode, bool rundown) {
|
||||
uint32_t unlocked_irql =
|
||||
xeKeKfAcquireSpinLock(ctx, ¤t_thread->apc_lock);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user