Starting physical memory allocation routines.
These currently don't do anything special w.r.t. memory addresses/etc, but will in the future.
This commit is contained in:
parent
f78e7945d4
commit
16baef3591
|
@ -183,6 +183,138 @@ SHIM_CALL NtFreeVirtualMemory_shim(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t xeMmAllocatePhysicalMemoryEx(
|
||||||
|
uint32_t type, uint32_t region_size, uint32_t protect_bits,
|
||||||
|
uint32_t min_addr_range, uint32_t max_addr_range, uint32_t alignment) {
|
||||||
|
KernelState* state = shared_kernel_state_;
|
||||||
|
XEASSERTNOTNULL(state);
|
||||||
|
|
||||||
|
// Type will usually be 0 (user request?), where 1 and 2 are sometimes made
|
||||||
|
// by D3D/etc.
|
||||||
|
|
||||||
|
// Check protection bits.
|
||||||
|
if (!(protect_bits & (X_PAGE_READONLY | X_PAGE_READWRITE))) {
|
||||||
|
XELOGE("MmAllocatePhysicalMemoryEx: bad protection bits");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Either may be OR'ed into protect_bits:
|
||||||
|
// X_PAGE_NOCACHE
|
||||||
|
// X_PAGE_WRITECOMBINE
|
||||||
|
// We could use this to detect what's likely GPU-synchronized memory
|
||||||
|
// and let the GPU know we're messing with it (or even allocate from
|
||||||
|
// the GPU). At least the D3D command buffer is X_PAGE_WRITECOMBINE.
|
||||||
|
|
||||||
|
// Calculate page size.
|
||||||
|
// Default = 4KB
|
||||||
|
// X_MEM_LARGE_PAGES = 64KB
|
||||||
|
// X_MEM_16MB_PAGES = 16MB
|
||||||
|
uint32_t page_size = 4 * 1024;
|
||||||
|
if (protect_bits & X_MEM_LARGE_PAGES) {
|
||||||
|
page_size = 64 * 1024;
|
||||||
|
} else if (protect_bits & X_MEM_16MB_PAGES) {
|
||||||
|
page_size = 16 * 1024 * 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Round up the region size to the next page.
|
||||||
|
uint32_t adjusted_size = XEROUNDUP(region_size, page_size);
|
||||||
|
|
||||||
|
// Callers can pick an address to allocate with min_addr_range/max_addr_range
|
||||||
|
// and the memory must be allocated there. I haven't seen a game do this,
|
||||||
|
// and instead they all do min=0 / max=-1 to indicate the system should pick.
|
||||||
|
// If we have to suport arbitrary placement things will get nasty.
|
||||||
|
XEASSERT(min_addr_range == 0);
|
||||||
|
XEASSERT(max_addr_range == 0xFFFFFFFF);
|
||||||
|
|
||||||
|
// Allocate.
|
||||||
|
uint32_t flags = 0;
|
||||||
|
uint32_t base_address = xe_memory_heap_alloc(
|
||||||
|
state->memory(), 0, adjusted_size, flags);
|
||||||
|
if (!base_address) {
|
||||||
|
// Failed - assume no memory available.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHIM_CALL MmAllocatePhysicalMemoryEx_shim(
|
||||||
|
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||||
|
uint32_t type = SHIM_GET_ARG_32(0);
|
||||||
|
uint32_t region_size = SHIM_GET_ARG_32(1);
|
||||||
|
uint32_t protect_bits = SHIM_GET_ARG_32(2);
|
||||||
|
uint32_t min_addr_range = SHIM_GET_ARG_32(3);
|
||||||
|
uint32_t max_addr_range = SHIM_GET_ARG_32(4);
|
||||||
|
uint32_t alignment = SHIM_GET_ARG_32(5);
|
||||||
|
|
||||||
|
XELOGD(
|
||||||
|
"MmAllocatePhysicalMemoryEx(%d, %.8X, %.8X, %.8X, %.8X, %.8X)",
|
||||||
|
type, region_size, protect_bits,
|
||||||
|
min_addr_range, max_addr_range, alignment);
|
||||||
|
|
||||||
|
uint32_t base_address = xeMmAllocatePhysicalMemoryEx(
|
||||||
|
type, region_size, protect_bits,
|
||||||
|
min_addr_range, max_addr_range, alignment);
|
||||||
|
|
||||||
|
SHIM_SET_RETURN(base_address);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xeMmFreePhysicalMemory(uint32_t type, uint32_t base_address) {
|
||||||
|
KernelState* state = shared_kernel_state_;
|
||||||
|
XEASSERTNOTNULL(state);
|
||||||
|
|
||||||
|
// base_address = result of MmAllocatePhysicalMemory.
|
||||||
|
|
||||||
|
uint32_t flags = 0;
|
||||||
|
xe_memory_heap_free(
|
||||||
|
state->memory(), base_address, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHIM_CALL MmFreePhysicalMemory_shim(
|
||||||
|
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||||
|
uint32_t type = SHIM_GET_ARG_32(0);
|
||||||
|
uint32_t base_address = SHIM_GET_ARG_32(1);
|
||||||
|
|
||||||
|
XELOGD(
|
||||||
|
"MmFreePhysicalAddress(%d, %.8X)",
|
||||||
|
type, base_address);
|
||||||
|
|
||||||
|
xeMmFreePhysicalMemory(type, base_address);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// http://msdn.microsoft.com/en-us/library/windows/hardware/ff554547(v=vs.85).aspx
|
||||||
|
uint32_t xeMmGetPhysicalAddress(uint32_t base_address) {
|
||||||
|
// PHYSICAL_ADDRESS MmGetPhysicalAddress(
|
||||||
|
// _In_ PVOID BaseAddress
|
||||||
|
// );
|
||||||
|
// base_address = result of MmAllocatePhysicalMemory.
|
||||||
|
|
||||||
|
// We are always using virtual addresses, right now, since we don't need
|
||||||
|
// physical ones. We could munge up the address here to another mapped view
|
||||||
|
// of memory.
|
||||||
|
|
||||||
|
return base_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHIM_CALL MmGetPhysicalAddress_shim(
|
||||||
|
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||||
|
uint32_t base_address = SHIM_GET_ARG_32(0);
|
||||||
|
|
||||||
|
XELOGD(
|
||||||
|
"MmGetPhysicalAddress(%.8X)",
|
||||||
|
base_address);
|
||||||
|
|
||||||
|
uint32_t result = xeMmGetPhysicalAddress(base_address);
|
||||||
|
|
||||||
|
SHIM_SET_RETURN(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace xboxkrnl
|
} // namespace xboxkrnl
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
@ -192,4 +324,8 @@ void xe::kernel::xboxkrnl::RegisterMemoryExports(
|
||||||
ExportResolver* export_resolver, KernelState* state) {
|
ExportResolver* export_resolver, KernelState* state) {
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtAllocateVirtualMemory, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", NtAllocateVirtualMemory, state);
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtFreeVirtualMemory, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", NtFreeVirtualMemory, state);
|
||||||
|
//SHIM_SET_MAPPING("xboxkrnl.exe", MmAllocatePhysicalMemory, state);
|
||||||
|
SHIM_SET_MAPPING("xboxkrnl.exe", MmAllocatePhysicalMemoryEx, state);
|
||||||
|
SHIM_SET_MAPPING("xboxkrnl.exe", MmFreePhysicalMemory, state);
|
||||||
|
SHIM_SET_MAPPING("xboxkrnl.exe", MmGetPhysicalAddress, state);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,16 @@ X_STATUS xeNtAllocateVirtualMemory(
|
||||||
uint32_t* base_addr_ptr, uint32_t* region_size_ptr,
|
uint32_t* base_addr_ptr, uint32_t* region_size_ptr,
|
||||||
uint32_t allocation_type, uint32_t protect_bits,
|
uint32_t allocation_type, uint32_t protect_bits,
|
||||||
uint32_t unknown);
|
uint32_t unknown);
|
||||||
|
|
||||||
X_STATUS xeNtFreeVirtualMemory(
|
X_STATUS xeNtFreeVirtualMemory(
|
||||||
uint32_t* base_addr_ptr, uint32_t* region_size_ptr,
|
uint32_t* base_addr_ptr, uint32_t* region_size_ptr,
|
||||||
uint32_t free_type, uint32_t unknown);
|
uint32_t free_type, uint32_t unknown);
|
||||||
|
|
||||||
|
uint32_t xeMmAllocatePhysicalMemoryEx(
|
||||||
|
uint32_t type, uint32_t region_size, uint32_t protect_bits,
|
||||||
|
uint32_t min_addr_range, uint32_t max_addr_range, uint32_t alignment);
|
||||||
|
void xeMmFreePhysicalMemory(uint32_t type, uint32_t base_address);
|
||||||
|
uint32_t xeMmGetPhysicalAddress(uint32_t base_address);
|
||||||
|
|
||||||
|
|
||||||
} // namespace xboxkrnl
|
} // namespace xboxkrnl
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
|
|
|
@ -49,13 +49,26 @@ VOID xeVdQueryVideoMode(X_VIDEO_MODE *video_mode, bool swap) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SHIM_CALL VdQueryVideoMode_shim(
|
SHIM_CALL VdQueryVideoMode_shim(
|
||||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||||
X_VIDEO_MODE *video_mode = (X_VIDEO_MODE*)SHIM_MEM_ADDR(SHIM_GET_ARG_32(0));
|
uint32_t video_mode_ptr = SHIM_GET_ARG_32(0);
|
||||||
|
X_VIDEO_MODE *video_mode = (X_VIDEO_MODE*)SHIM_MEM_ADDR(video_mode_ptr);
|
||||||
|
|
||||||
|
XELOGD(
|
||||||
|
"VdQueryVideoMode(%.8X)",
|
||||||
|
video_mode_ptr);
|
||||||
|
|
||||||
xeVdQueryVideoMode(video_mode, true);
|
xeVdQueryVideoMode(video_mode, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// VdInitializeRingBuffer
|
||||||
|
// r3 = result of MmGetPhysicalAddress
|
||||||
|
// r4 = number of pages? page size?
|
||||||
|
// 0x8000 -> cntlzw=16 -> 0x1C - 16 = 12
|
||||||
|
|
||||||
|
|
||||||
} // namespace xboxkrnl
|
} // namespace xboxkrnl
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
Loading…
Reference in New Issue