format shim conversion on some files
xam_info.cc, xam_msg.cc, xam_notify.cc, xboxkrnl_memory.cc, xboxkrnl_misc.cc
This commit is contained in:
parent
46504adcc0
commit
c38accbb76
|
@ -25,42 +25,35 @@ namespace xam {
|
||||||
constexpr uint32_t X_LANGUAGE_ENGLISH = 1;
|
constexpr uint32_t X_LANGUAGE_ENGLISH = 1;
|
||||||
constexpr uint32_t X_LANGUAGE_JAPANESE = 2;
|
constexpr uint32_t X_LANGUAGE_JAPANESE = 2;
|
||||||
|
|
||||||
SHIM_CALL XamGetSystemVersion_shim(PPCContext* ppc_context,
|
dword_result_t XamGetSystemVersion() {
|
||||||
KernelState* kernel_state) {
|
|
||||||
XELOGD("XamGetSystemVersion()");
|
|
||||||
// eh, just picking one. If we go too low we may break new games, but
|
// eh, just picking one. If we go too low we may break new games, but
|
||||||
// this value seems to be used for conditionally loading symbols and if
|
// this value seems to be used for conditionally loading symbols and if
|
||||||
// we pretend to be old we have less to worry with implementing.
|
// we pretend to be old we have less to worry with implementing.
|
||||||
// 0x200A3200
|
// 0x200A3200
|
||||||
// 0x20096B00
|
// 0x20096B00
|
||||||
SHIM_SET_RETURN_32(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
DECLARE_XAM_EXPORT(XamGetSystemVersion, ExportTag::kStub);
|
||||||
|
|
||||||
void XCustomRegisterDynamicActions() {
|
void XCustomRegisterDynamicActions() {
|
||||||
// ???
|
// ???
|
||||||
}
|
}
|
||||||
DECLARE_XAM_EXPORT(XCustomRegisterDynamicActions, ExportTag::kStub);
|
DECLARE_XAM_EXPORT(XCustomRegisterDynamicActions, ExportTag::kStub);
|
||||||
|
|
||||||
SHIM_CALL XGetAVPack_shim(PPCContext* ppc_context, KernelState* kernel_state) {
|
dword_result_t XGetAVPack() {
|
||||||
// DWORD
|
// DWORD
|
||||||
// Not sure what the values are for this, but 6 is VGA.
|
// Not sure what the values are for this, but 6 is VGA.
|
||||||
// Other likely values are 3/4/8 for HDMI or something.
|
// Other likely values are 3/4/8 for HDMI or something.
|
||||||
// Games seem to use this as a PAL check - if the result is not 3/4/6/8
|
// Games seem to use this as a PAL check - if the result is not 3/4/6/8
|
||||||
// they explode with errors if not in PAL mode.
|
// they explode with errors if not in PAL mode.
|
||||||
SHIM_SET_RETURN_32(6);
|
return 6;
|
||||||
}
|
}
|
||||||
|
DECLARE_XAM_EXPORT(XGetAVPack, ExportTag::kStub);
|
||||||
|
|
||||||
SHIM_CALL XGetGameRegion_shim(PPCContext* ppc_context,
|
dword_result_t XGetGameRegion() { return 0xFFFF; }
|
||||||
KernelState* kernel_state) {
|
DECLARE_XAM_EXPORT(XGetGameRegion, ExportTag::kStub);
|
||||||
XELOGD("XGetGameRegion()");
|
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(0xFFFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
SHIM_CALL XGetLanguage_shim(PPCContext* ppc_context,
|
|
||||||
KernelState* kernel_state) {
|
|
||||||
XELOGD("XGetLanguage()");
|
|
||||||
|
|
||||||
|
dword_result_t XGetLanguage() {
|
||||||
uint32_t desired_language = X_LANGUAGE_ENGLISH;
|
uint32_t desired_language = X_LANGUAGE_ENGLISH;
|
||||||
|
|
||||||
// Switch the language based on game region.
|
// Switch the language based on game region.
|
||||||
|
@ -73,16 +66,12 @@ SHIM_CALL XGetLanguage_shim(PPCContext* ppc_context,
|
||||||
}
|
}
|
||||||
// Add more overrides?
|
// Add more overrides?
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(desired_language);
|
return desired_language;
|
||||||
}
|
}
|
||||||
|
DECLARE_XAM_EXPORT(XGetLanguage, ExportTag::kImplemented);
|
||||||
|
|
||||||
SHIM_CALL XamGetExecutionId_shim(PPCContext* ppc_context,
|
dword_result_t XamGetExecutionId(lpdword_t info_ptr) {
|
||||||
KernelState* kernel_state) {
|
auto module = kernel_state()->GetExecutableModule();
|
||||||
uint32_t info_ptr = SHIM_GET_ARG_32(0);
|
|
||||||
|
|
||||||
XELOGD("XamGetExecutionId(%.8X)", info_ptr);
|
|
||||||
|
|
||||||
auto module = kernel_state->GetExecutableModule();
|
|
||||||
assert_not_null(module);
|
assert_not_null(module);
|
||||||
|
|
||||||
uint32_t guest_hdr_ptr;
|
uint32_t guest_hdr_ptr;
|
||||||
|
@ -90,13 +79,13 @@ SHIM_CALL XamGetExecutionId_shim(PPCContext* ppc_context,
|
||||||
module->GetOptHeader(XEX_HEADER_EXECUTION_INFO, &guest_hdr_ptr);
|
module->GetOptHeader(XEX_HEADER_EXECUTION_INFO, &guest_hdr_ptr);
|
||||||
|
|
||||||
if (XFAILED(result)) {
|
if (XFAILED(result)) {
|
||||||
SHIM_SET_RETURN_32(result);
|
return result;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SHIM_SET_MEM_32(info_ptr, guest_hdr_ptr);
|
*info_ptr = guest_hdr_ptr;
|
||||||
SHIM_SET_RETURN_32(X_STATUS_SUCCESS);
|
return X_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
DECLARE_XAM_EXPORT(XamGetExecutionId, ExportTag::kImplemented);
|
||||||
|
|
||||||
dword_result_t XamLoaderSetLaunchData(lpvoid_t data, dword_t size) {
|
dword_result_t XamLoaderSetLaunchData(lpvoid_t data, dword_t size) {
|
||||||
auto xam = kernel_state()->GetKernelModule<XamModule>("xam.xex");
|
auto xam = kernel_state()->GetKernelModule<XamModule>("xam.xex");
|
||||||
|
@ -173,32 +162,24 @@ void XamLoaderTerminateTitle() {
|
||||||
}
|
}
|
||||||
DECLARE_XAM_EXPORT(XamLoaderTerminateTitle, ExportTag::kSketchy);
|
DECLARE_XAM_EXPORT(XamLoaderTerminateTitle, ExportTag::kSketchy);
|
||||||
|
|
||||||
SHIM_CALL XamAlloc_shim(PPCContext* ppc_context, KernelState* kernel_state) {
|
dword_result_t XamAlloc(dword_t unk, dword_t size, lpword_t out_ptr) {
|
||||||
uint32_t unk = SHIM_GET_ARG_32(0);
|
|
||||||
uint32_t size = SHIM_GET_ARG_32(1);
|
|
||||||
uint32_t out_ptr = SHIM_GET_ARG_32(2);
|
|
||||||
|
|
||||||
XELOGD("XamAlloc(%d, %d, %.8X)", unk, size, out_ptr);
|
|
||||||
|
|
||||||
assert_true(unk == 0);
|
assert_true(unk == 0);
|
||||||
|
|
||||||
// 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?
|
||||||
uint32_t ptr = kernel_state->memory()->SystemHeapAlloc(size);
|
uint32_t ptr = kernel_state()->memory()->SystemHeapAlloc(size);
|
||||||
SHIM_SET_MEM_32(out_ptr, ptr);
|
*out_ptr = ptr;
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(X_ERROR_SUCCESS);
|
return X_ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
DECLARE_XAM_EXPORT(XamAlloc, ExportTag::kImplemented);
|
||||||
|
|
||||||
SHIM_CALL XamFree_shim(PPCContext* ppc_context, KernelState* kernel_state) {
|
dword_result_t XamFree(lpdword_t ptr) {
|
||||||
uint32_t ptr = SHIM_GET_ARG_32(0);
|
kernel_state()->memory()->SystemHeapFree(ptr);
|
||||||
|
|
||||||
XELOGD("XamFree(%.8X)", ptr);
|
return X_ERROR_SUCCESS;
|
||||||
|
|
||||||
kernel_state->memory()->SystemHeapFree(ptr);
|
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(X_ERROR_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
DECLARE_XAM_EXPORT(XamFree, ExportTag::kImplemented);
|
||||||
|
|
||||||
// https://github.com/LestaD/SourceEngine2007/blob/master/se2007/engine/xboxsystem.cpp#L518
|
// https://github.com/LestaD/SourceEngine2007/blob/master/se2007/engine/xboxsystem.cpp#L518
|
||||||
dword_result_t XamEnumerate(dword_t handle, dword_t flags, lpvoid_t buffer,
|
dword_result_t XamEnumerate(dword_t handle, dword_t flags, lpvoid_t buffer,
|
||||||
|
@ -244,17 +225,7 @@ dword_result_t XamEnumerate(dword_t handle, dword_t flags, lpvoid_t buffer,
|
||||||
DECLARE_XAM_EXPORT(XamEnumerate, ExportTag::kImplemented);
|
DECLARE_XAM_EXPORT(XamEnumerate, ExportTag::kImplemented);
|
||||||
|
|
||||||
void RegisterInfoExports(xe::cpu::ExportResolver* export_resolver,
|
void RegisterInfoExports(xe::cpu::ExportResolver* export_resolver,
|
||||||
KernelState* kernel_state) {
|
KernelState* kernel_state) {}
|
||||||
SHIM_SET_MAPPING("xam.xex", XamGetSystemVersion, state);
|
|
||||||
SHIM_SET_MAPPING("xam.xex", XGetAVPack, state);
|
|
||||||
SHIM_SET_MAPPING("xam.xex", XGetGameRegion, state);
|
|
||||||
SHIM_SET_MAPPING("xam.xex", XGetLanguage, state);
|
|
||||||
|
|
||||||
SHIM_SET_MAPPING("xam.xex", XamGetExecutionId, state);
|
|
||||||
|
|
||||||
SHIM_SET_MAPPING("xam.xex", XamAlloc, state);
|
|
||||||
SHIM_SET_MAPPING("xam.xex", XamFree, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace xam
|
} // namespace xam
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
|
|
|
@ -18,114 +18,78 @@ namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
namespace xam {
|
namespace xam {
|
||||||
|
|
||||||
SHIM_CALL XMsgInProcessCall_shim(PPCContext* ppc_context,
|
dword_result_t XMsgInProcessCall(dword_t app, dword_t message, dword_t arg1,
|
||||||
KernelState* kernel_state) {
|
dword_t arg2) {
|
||||||
uint32_t app = SHIM_GET_ARG_32(0);
|
auto result = kernel_state()->app_manager()->DispatchMessageSync(app, message,
|
||||||
uint32_t message = SHIM_GET_ARG_32(1);
|
|
||||||
uint32_t arg1 = SHIM_GET_ARG_32(2);
|
|
||||||
uint32_t arg2 = SHIM_GET_ARG_32(3);
|
|
||||||
|
|
||||||
XELOGD("XMsgInProcessCall(%.8X, %.8X, %.8X, %.8X)", app, message, arg1, arg2);
|
|
||||||
|
|
||||||
auto result = kernel_state->app_manager()->DispatchMessageSync(app, message,
|
|
||||||
arg1, arg2);
|
arg1, arg2);
|
||||||
if (result == X_ERROR_NOT_FOUND) {
|
if (result == X_ERROR_NOT_FOUND) {
|
||||||
XELOGE("XMsgInProcessCall: app %.8X undefined", app);
|
XELOGE("XMsgInProcessCall: app %.8X undefined", app);
|
||||||
}
|
}
|
||||||
SHIM_SET_RETURN_32(result);
|
return result;
|
||||||
}
|
}
|
||||||
|
DECLARE_XAM_EXPORT(XMsgInProcessCall, ExportTag::kImplemented);
|
||||||
|
|
||||||
SHIM_CALL XMsgSystemProcessCall_shim(PPCContext* ppc_context,
|
dword_result_t XMsgSystemProcessCall(dword_t app, dword_t message,
|
||||||
KernelState* kernel_state) {
|
dword_t buffer, dword_t buffer_length) {
|
||||||
uint32_t app = SHIM_GET_ARG_32(0);
|
auto result = kernel_state()->app_manager()->DispatchMessageAsync(
|
||||||
uint32_t message = SHIM_GET_ARG_32(1);
|
|
||||||
uint32_t buffer = SHIM_GET_ARG_32(2);
|
|
||||||
uint32_t buffer_length = SHIM_GET_ARG_32(3);
|
|
||||||
|
|
||||||
XELOGD("XMsgSystemProcessCall(%.8X, %.8X, %.8X, %.8X)", app, message, buffer,
|
|
||||||
buffer_length);
|
|
||||||
|
|
||||||
auto result = kernel_state->app_manager()->DispatchMessageAsync(
|
|
||||||
app, message, buffer, buffer_length);
|
app, message, buffer, buffer_length);
|
||||||
if (result == X_ERROR_NOT_FOUND) {
|
if (result == X_ERROR_NOT_FOUND) {
|
||||||
XELOGE("XMsgSystemProcessCall: app %.8X undefined", app);
|
XELOGE("XMsgSystemProcessCall: app %.8X undefined", app);
|
||||||
}
|
}
|
||||||
SHIM_SET_RETURN_32(result);
|
return result;
|
||||||
}
|
}
|
||||||
|
DECLARE_XAM_EXPORT(XMsgSystemProcessCall, ExportTag::kImplemented);
|
||||||
|
|
||||||
SHIM_CALL XMsgStartIORequest_shim(PPCContext* ppc_context,
|
dword_result_t XMsgStartIORequest(dword_t app, dword_t message,
|
||||||
KernelState* kernel_state) {
|
pointer_t<XAM_OVERLAPPED> overlapped_ptr,
|
||||||
uint32_t app = SHIM_GET_ARG_32(0);
|
dword_t buffer, dword_t buffer_length) {
|
||||||
uint32_t message = SHIM_GET_ARG_32(1);
|
auto result = kernel_state()->app_manager()->DispatchMessageAsync(
|
||||||
uint32_t overlapped_ptr = SHIM_GET_ARG_32(2);
|
|
||||||
uint32_t buffer = SHIM_GET_ARG_32(3);
|
|
||||||
uint32_t buffer_length = SHIM_GET_ARG_32(4);
|
|
||||||
|
|
||||||
XELOGD("XMsgStartIORequest(%.8X, %.8X, %.8X, %.8X, %d)", app, message,
|
|
||||||
overlapped_ptr, buffer, buffer_length);
|
|
||||||
|
|
||||||
auto result = kernel_state->app_manager()->DispatchMessageAsync(
|
|
||||||
app, message, buffer, buffer_length);
|
app, message, buffer, buffer_length);
|
||||||
if (result == X_ERROR_NOT_FOUND) {
|
if (result == X_ERROR_NOT_FOUND) {
|
||||||
XELOGE("XMsgStartIORequest: app %.8X undefined", app);
|
XELOGE("XMsgStartIORequest: app %.8X undefined", app);
|
||||||
}
|
}
|
||||||
if (overlapped_ptr) {
|
if (overlapped_ptr) {
|
||||||
kernel_state->CompleteOverlappedImmediate(overlapped_ptr, result);
|
kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, result);
|
||||||
result = X_ERROR_IO_PENDING;
|
result = X_ERROR_IO_PENDING;
|
||||||
}
|
}
|
||||||
SHIM_SET_RETURN_32(result);
|
return result;
|
||||||
}
|
}
|
||||||
|
DECLARE_XAM_EXPORT(XMsgStartIORequest, ExportTag::kImplemented);
|
||||||
|
|
||||||
SHIM_CALL XMsgStartIORequestEx_shim(PPCContext* ppc_context,
|
dword_result_t XMsgStartIORequestEx(dword_t app, dword_t message,
|
||||||
KernelState* kernel_state) {
|
pointer_t<XAM_OVERLAPPED> overlapped_ptr,
|
||||||
uint32_t app = SHIM_GET_ARG_32(0);
|
dword_t buffer, dword_t buffer_length,
|
||||||
uint32_t message = SHIM_GET_ARG_32(1);
|
lpdword_t unknown_ptr) {
|
||||||
uint32_t overlapped_ptr = SHIM_GET_ARG_32(2);
|
auto result = kernel_state()->app_manager()->DispatchMessageAsync(
|
||||||
uint32_t buffer = SHIM_GET_ARG_32(3);
|
|
||||||
uint32_t buffer_length = SHIM_GET_ARG_32(4);
|
|
||||||
uint32_t unknown_ptr = SHIM_GET_ARG_32(5);
|
|
||||||
|
|
||||||
XELOGD("XMsgStartIORequestEx(%.8X, %.8X, %.8X, %.8X, %d, %.8X)", app, message,
|
|
||||||
overlapped_ptr, buffer, buffer_length, unknown_ptr);
|
|
||||||
|
|
||||||
auto result = kernel_state->app_manager()->DispatchMessageAsync(
|
|
||||||
app, message, buffer, buffer_length);
|
app, message, buffer, buffer_length);
|
||||||
if (result == X_ERROR_NOT_FOUND) {
|
if (result == X_ERROR_NOT_FOUND) {
|
||||||
XELOGE("XMsgStartIORequestEx: app %.8X undefined", app);
|
XELOGE("XMsgStartIORequestEx: app %.8X undefined", app);
|
||||||
}
|
}
|
||||||
if (overlapped_ptr) {
|
if (overlapped_ptr) {
|
||||||
kernel_state->CompleteOverlappedImmediate(overlapped_ptr, result);
|
kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, result);
|
||||||
result = X_ERROR_IO_PENDING;
|
result = X_ERROR_IO_PENDING;
|
||||||
}
|
}
|
||||||
SHIM_SET_RETURN_32(result);
|
return result;
|
||||||
}
|
}
|
||||||
|
DECLARE_XAM_EXPORT(XMsgStartIORequestEx, ExportTag::kImplemented);
|
||||||
|
|
||||||
SHIM_CALL XMsgCancelIORequest_shim(PPCContext* ppc_context,
|
dword_result_t XMsgCancelIORequest(pointer_t<XAM_OVERLAPPED> overlapped_ptr,
|
||||||
KernelState* kernel_state) {
|
dword_t wait) {
|
||||||
uint32_t overlapped_ptr = SHIM_GET_ARG_32(0);
|
X_HANDLE event_handle = XOverlappedGetEvent(overlapped_ptr);
|
||||||
uint32_t wait = SHIM_GET_ARG_32(1);
|
|
||||||
|
|
||||||
XELOGD("XMsgCancelIORequest(%.8X, %d)", overlapped_ptr, wait);
|
|
||||||
|
|
||||||
X_HANDLE event_handle = XOverlappedGetEvent(SHIM_MEM_ADDR(overlapped_ptr));
|
|
||||||
if (event_handle && wait) {
|
if (event_handle && wait) {
|
||||||
auto ev = kernel_state->object_table()->LookupObject<XEvent>(event_handle);
|
auto ev =
|
||||||
|
kernel_state()->object_table()->LookupObject<XEvent>(event_handle);
|
||||||
if (ev) {
|
if (ev) {
|
||||||
ev->Wait(0, 0, true, nullptr);
|
ev->Wait(0, 0, true, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
DECLARE_XAM_EXPORT(XMsgCancelIORequest, ExportTag::kImplemented);
|
||||||
|
|
||||||
void RegisterMsgExports(xe::cpu::ExportResolver* export_resolver,
|
void RegisterMsgExports(xe::cpu::ExportResolver* export_resolver,
|
||||||
KernelState* kernel_state) {
|
KernelState* kernel_state) {}
|
||||||
SHIM_SET_MAPPING("xam.xex", XMsgInProcessCall, state);
|
|
||||||
SHIM_SET_MAPPING("xam.xex", XMsgSystemProcessCall, state);
|
|
||||||
SHIM_SET_MAPPING("xam.xex", XMsgStartIORequest, state);
|
|
||||||
SHIM_SET_MAPPING("xam.xex", XMsgStartIORequestEx, state);
|
|
||||||
SHIM_SET_MAPPING("xam.xex", XMsgCancelIORequest, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace xam
|
} // namespace xam
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
|
|
|
@ -18,46 +18,32 @@ namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
namespace xam {
|
namespace xam {
|
||||||
|
|
||||||
SHIM_CALL XamNotifyCreateListener_shim(PPCContext* ppc_context,
|
dword_result_t XamNotifyCreateListener(qword_t mask, dword_t one) {
|
||||||
KernelState* kernel_state) {
|
|
||||||
uint64_t mask = SHIM_GET_ARG_64(0);
|
|
||||||
uint32_t one = SHIM_GET_ARG_32(1);
|
|
||||||
|
|
||||||
XELOGD("XamNotifyCreateListener(%.8llX, %d)", mask, one);
|
|
||||||
|
|
||||||
// r4=1 may indicate user process?
|
// r4=1 may indicate user process?
|
||||||
|
|
||||||
auto listener = object_ref<NotifyListener>(new NotifyListener(kernel_state));
|
auto listener =
|
||||||
|
object_ref<NotifyListener>(new NotifyListener(kernel_state()));
|
||||||
listener->Initialize(mask);
|
listener->Initialize(mask);
|
||||||
|
|
||||||
// Handle ref is incremented, so return that.
|
// Handle ref is incremented, so return that.
|
||||||
uint32_t handle = listener->handle();
|
uint32_t handle = listener->handle();
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(handle);
|
return handle;
|
||||||
}
|
}
|
||||||
|
DECLARE_XAM_EXPORT(XamNotifyCreateListener, ExportTag::kImplemented);
|
||||||
|
|
||||||
// http://ffplay360.googlecode.com/svn/Test/Common/AtgSignIn.cpp
|
// http://ffplay360.googlecode.com/svn/Test/Common/AtgSignIn.cpp
|
||||||
SHIM_CALL XNotifyGetNext_shim(PPCContext* ppc_context,
|
dword_result_t XNotifyGetNext(dword_t handle, dword_t match_id,
|
||||||
KernelState* kernel_state) {
|
lpdword_t id_ptr, lpdword_t param_ptr) {
|
||||||
uint32_t handle = SHIM_GET_ARG_32(0);
|
|
||||||
uint32_t match_id = SHIM_GET_ARG_32(1);
|
|
||||||
uint32_t id_ptr = SHIM_GET_ARG_32(2);
|
|
||||||
uint32_t param_ptr = SHIM_GET_ARG_32(3);
|
|
||||||
|
|
||||||
XELOGD("XNotifyGetNext(%.8X, %.8X, %.8X, %.8X)", handle, match_id, id_ptr,
|
|
||||||
param_ptr);
|
|
||||||
|
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
SHIM_SET_RETURN_32(0);
|
return 0;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grab listener.
|
// Grab listener.
|
||||||
auto listener =
|
auto listener =
|
||||||
kernel_state->object_table()->LookupObject<NotifyListener>(handle);
|
kernel_state()->object_table()->LookupObject<NotifyListener>(handle);
|
||||||
if (!listener) {
|
if (!listener) {
|
||||||
SHIM_SET_RETURN_32(0);
|
return 0;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dequeued = false;
|
bool dequeued = false;
|
||||||
|
@ -73,42 +59,30 @@ SHIM_CALL XNotifyGetNext_shim(PPCContext* ppc_context,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dequeued) {
|
if (dequeued) {
|
||||||
SHIM_SET_MEM_32(id_ptr, id);
|
*id_ptr = id;
|
||||||
SHIM_SET_MEM_32(param_ptr, param);
|
*param_ptr = param;
|
||||||
} else {
|
} else {
|
||||||
SHIM_SET_MEM_32(id_ptr, 0);
|
*id_ptr = 0;
|
||||||
SHIM_SET_MEM_32(param_ptr, 0);
|
*param_ptr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(dequeued ? 1 : 0);
|
return dequeued ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
DECLARE_XAM_EXPORT(XNotifyGetNext, ExportTag::kImplemented);
|
||||||
|
|
||||||
SHIM_CALL XNotifyDelayUI_shim(PPCContext* ppc_context,
|
dword_result_t XNotifyDelayUI(dword_t delay_ms) {
|
||||||
KernelState* kernel_state) {
|
|
||||||
uint32_t delay_ms = SHIM_GET_ARG_32(0);
|
|
||||||
|
|
||||||
XELOGD("XNotifyDelayUI(%d)", delay_ms);
|
|
||||||
|
|
||||||
// Ignored.
|
// Ignored.
|
||||||
SHIM_SET_RETURN_32(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
DECLARE_XAM_EXPORT(XNotifyDelayUI, ExportTag::kStub);
|
||||||
|
|
||||||
SHIM_CALL XNotifyPositionUI_shim(PPCContext* ppc_context,
|
void XNotifyPositionUI(dword_t position) {
|
||||||
KernelState* kernel_state) {
|
|
||||||
uint32_t position = SHIM_GET_ARG_32(0);
|
|
||||||
|
|
||||||
XELOGD("XNotifyPositionUI(%.8X)", position);
|
|
||||||
|
|
||||||
// Ignored.
|
// Ignored.
|
||||||
}
|
}
|
||||||
|
DECLARE_XAM_EXPORT(XNotifyPositionUI, ExportTag::kStub);
|
||||||
|
|
||||||
void RegisterNotifyExports(xe::cpu::ExportResolver* export_resolver,
|
void RegisterNotifyExports(xe::cpu::ExportResolver* export_resolver,
|
||||||
KernelState* kernel_state) {
|
KernelState* kernel_state) {}
|
||||||
SHIM_SET_MAPPING("xam.xex", XamNotifyCreateListener, state);
|
|
||||||
SHIM_SET_MAPPING("xam.xex", XNotifyGetNext, state);
|
|
||||||
SHIM_SET_MAPPING("xam.xex", XNotifyDelayUI, state);
|
|
||||||
SHIM_SET_MAPPING("xam.xex", XNotifyPositionUI, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace xam
|
} // namespace xam
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
|
|
|
@ -164,19 +164,12 @@ dword_result_t NtAllocateVirtualMemory(lpdword_t base_addr_ptr,
|
||||||
DECLARE_XBOXKRNL_EXPORT(NtAllocateVirtualMemory,
|
DECLARE_XBOXKRNL_EXPORT(NtAllocateVirtualMemory,
|
||||||
ExportTag::kImplemented | ExportTag::kMemory);
|
ExportTag::kImplemented | ExportTag::kMemory);
|
||||||
|
|
||||||
SHIM_CALL NtFreeVirtualMemory_shim(PPCContext* ppc_context,
|
dword_result_t NtFreeVirtualMemory(lpdword_t base_addr_ptr,
|
||||||
KernelState* kernel_state) {
|
lpdword_t region_size_ptr, dword_t free_type,
|
||||||
uint32_t base_addr_ptr = SHIM_GET_ARG_32(0);
|
dword_t debug_memory) {
|
||||||
uint32_t base_addr_value = SHIM_MEM_32(base_addr_ptr);
|
uint32_t base_addr_value = *base_addr_ptr;
|
||||||
uint32_t region_size_ptr = SHIM_GET_ARG_32(1);
|
uint32_t region_size_value = *region_size_ptr;
|
||||||
uint32_t region_size_value = SHIM_MEM_32(region_size_ptr);
|
|
||||||
// X_MEM_DECOMMIT | X_MEM_RELEASE
|
// X_MEM_DECOMMIT | X_MEM_RELEASE
|
||||||
uint32_t free_type = SHIM_GET_ARG_32(2);
|
|
||||||
uint32_t debug_memory = SHIM_GET_ARG_32(3);
|
|
||||||
|
|
||||||
XELOGD("NtFreeVirtualMemory(%.8X(%.8X), %.8X(%.8X), %.8X, %.8X)",
|
|
||||||
base_addr_ptr, base_addr_value, region_size_ptr, region_size_value,
|
|
||||||
free_type, debug_memory);
|
|
||||||
|
|
||||||
// NTSTATUS
|
// NTSTATUS
|
||||||
// _Inout_ PVOID *BaseAddress,
|
// _Inout_ PVOID *BaseAddress,
|
||||||
|
@ -188,11 +181,10 @@ SHIM_CALL NtFreeVirtualMemory_shim(PPCContext* ppc_context,
|
||||||
assert_true(debug_memory == 0);
|
assert_true(debug_memory == 0);
|
||||||
|
|
||||||
if (!base_addr_value) {
|
if (!base_addr_value) {
|
||||||
SHIM_SET_RETURN_32(X_STATUS_MEMORY_NOT_ALLOCATED);
|
return X_STATUS_MEMORY_NOT_ALLOCATED;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto heap = kernel_state->memory()->LookupHeap(base_addr_value);
|
auto heap = kernel_state()->memory()->LookupHeap(base_addr_value);
|
||||||
bool result = false;
|
bool result = false;
|
||||||
if (free_type == X_MEM_DECOMMIT) {
|
if (free_type == X_MEM_DECOMMIT) {
|
||||||
// If zero, we may need to query size (free whole region).
|
// If zero, we may need to query size (free whole region).
|
||||||
|
@ -204,14 +196,14 @@ SHIM_CALL NtFreeVirtualMemory_shim(PPCContext* ppc_context,
|
||||||
result = heap->Release(base_addr_value, ®ion_size_value);
|
result = heap->Release(base_addr_value, ®ion_size_value);
|
||||||
}
|
}
|
||||||
if (!result) {
|
if (!result) {
|
||||||
SHIM_SET_RETURN_32(X_STATUS_UNSUCCESSFUL);
|
return X_STATUS_UNSUCCESSFUL;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SHIM_SET_MEM_32(base_addr_ptr, base_addr_value);
|
*base_addr_ptr = base_addr_value;
|
||||||
SHIM_SET_MEM_32(region_size_ptr, region_size_value);
|
*region_size_ptr = region_size_value;
|
||||||
SHIM_SET_RETURN_32(X_STATUS_SUCCESS);
|
return X_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(NtFreeVirtualMemory, ExportTag::kImplemented);
|
||||||
|
|
||||||
struct X_MEMORY_BASIC_INFORMATION {
|
struct X_MEMORY_BASIC_INFORMATION {
|
||||||
be<uint32_t> base_address;
|
be<uint32_t> base_address;
|
||||||
|
@ -223,30 +215,22 @@ struct X_MEMORY_BASIC_INFORMATION {
|
||||||
be<uint32_t> type;
|
be<uint32_t> type;
|
||||||
};
|
};
|
||||||
|
|
||||||
SHIM_CALL NtQueryVirtualMemory_shim(PPCContext* ppc_context,
|
dword_result_t NtQueryVirtualMemory(
|
||||||
KernelState* kernel_state) {
|
dword_t base_address,
|
||||||
uint32_t base_address = SHIM_GET_ARG_32(0);
|
pointer_t<X_MEMORY_BASIC_INFORMATION> memory_basic_information_ptr) {
|
||||||
uint32_t memory_basic_information_ptr = SHIM_GET_ARG_32(1);
|
auto heap = kernel_state()->memory()->LookupHeap(base_address);
|
||||||
auto memory_basic_information =
|
|
||||||
SHIM_STRUCT(X_MEMORY_BASIC_INFORMATION, memory_basic_information_ptr);
|
|
||||||
|
|
||||||
XELOGD("NtQueryVirtualMemory(%.8X, %.8X)", base_address,
|
|
||||||
memory_basic_information_ptr);
|
|
||||||
|
|
||||||
auto heap = kernel_state->memory()->LookupHeap(base_address);
|
|
||||||
HeapAllocationInfo alloc_info;
|
HeapAllocationInfo alloc_info;
|
||||||
if (heap == nullptr || !heap->QueryRegionInfo(base_address, &alloc_info)) {
|
if (heap == nullptr || !heap->QueryRegionInfo(base_address, &alloc_info)) {
|
||||||
SHIM_SET_RETURN_32(X_STATUS_INVALID_PARAMETER);
|
return X_STATUS_INVALID_PARAMETER;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memory_basic_information->base_address =
|
memory_basic_information_ptr->base_address =
|
||||||
static_cast<uint32_t>(alloc_info.base_address);
|
static_cast<uint32_t>(alloc_info.base_address);
|
||||||
memory_basic_information->allocation_base =
|
memory_basic_information_ptr->allocation_base =
|
||||||
static_cast<uint32_t>(alloc_info.allocation_base);
|
static_cast<uint32_t>(alloc_info.allocation_base);
|
||||||
memory_basic_information->allocation_protect =
|
memory_basic_information_ptr->allocation_protect =
|
||||||
ToXdkProtectFlags(alloc_info.allocation_protect);
|
ToXdkProtectFlags(alloc_info.allocation_protect);
|
||||||
memory_basic_information->region_size =
|
memory_basic_information_ptr->region_size =
|
||||||
static_cast<uint32_t>(alloc_info.region_size);
|
static_cast<uint32_t>(alloc_info.region_size);
|
||||||
uint32_t x_state = 0;
|
uint32_t x_state = 0;
|
||||||
if (alloc_info.state & kMemoryAllocationReserve) {
|
if (alloc_info.state & kMemoryAllocationReserve) {
|
||||||
|
@ -255,12 +239,13 @@ SHIM_CALL NtQueryVirtualMemory_shim(PPCContext* ppc_context,
|
||||||
if (alloc_info.state & kMemoryAllocationCommit) {
|
if (alloc_info.state & kMemoryAllocationCommit) {
|
||||||
x_state |= X_MEM_COMMIT;
|
x_state |= X_MEM_COMMIT;
|
||||||
}
|
}
|
||||||
memory_basic_information->state = x_state;
|
memory_basic_information_ptr->state = x_state;
|
||||||
memory_basic_information->protect = ToXdkProtectFlags(alloc_info.protect);
|
memory_basic_information_ptr->protect = ToXdkProtectFlags(alloc_info.protect);
|
||||||
memory_basic_information->type = alloc_info.type;
|
memory_basic_information_ptr->type = alloc_info.type;
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(X_STATUS_SUCCESS);
|
return X_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(NtQueryVirtualMemory, ExportTag::kImplemented);
|
||||||
|
|
||||||
dword_result_t MmAllocatePhysicalMemoryEx(dword_t flags, dword_t region_size,
|
dword_result_t MmAllocatePhysicalMemoryEx(dword_t flags, dword_t region_size,
|
||||||
dword_t protect_bits,
|
dword_t protect_bits,
|
||||||
|
@ -316,60 +301,53 @@ dword_result_t MmAllocatePhysicalMemoryEx(dword_t flags, dword_t region_size,
|
||||||
DECLARE_XBOXKRNL_EXPORT(MmAllocatePhysicalMemoryEx,
|
DECLARE_XBOXKRNL_EXPORT(MmAllocatePhysicalMemoryEx,
|
||||||
ExportTag::kImplemented | ExportTag::kMemory);
|
ExportTag::kImplemented | ExportTag::kMemory);
|
||||||
|
|
||||||
SHIM_CALL MmFreePhysicalMemory_shim(PPCContext* ppc_context,
|
dword_result_t MmFreePhysicalMemory(dword_t type, dword_t base_address) {
|
||||||
KernelState* kernel_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);
|
|
||||||
|
|
||||||
// base_address = result of MmAllocatePhysicalMemory.
|
// base_address = result of MmAllocatePhysicalMemory.
|
||||||
|
|
||||||
assert_true((base_address & 0x1F) == 0);
|
assert_true((base_address & 0x1F) == 0);
|
||||||
|
|
||||||
auto heap = kernel_state->memory()->LookupHeap(base_address);
|
auto heap = kernel_state()->memory()->LookupHeap(base_address);
|
||||||
heap->Release(base_address);
|
if (heap->Release(base_address)) {
|
||||||
|
return X_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
return X_STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(MmFreePhysicalMemory, ExportTag::kImplemented);
|
||||||
|
|
||||||
SHIM_CALL MmQueryAddressProtect_shim(PPCContext* ppc_context,
|
dword_result_t MmQueryAddressProtect(dword_t base_address) {
|
||||||
KernelState* kernel_state) {
|
auto heap = kernel_state()->memory()->LookupHeap(base_address);
|
||||||
uint32_t base_address = SHIM_GET_ARG_32(0);
|
|
||||||
|
|
||||||
XELOGD("MmQueryAddressProtect(%.8X)", base_address);
|
|
||||||
|
|
||||||
auto heap = kernel_state->memory()->LookupHeap(base_address);
|
|
||||||
uint32_t access;
|
uint32_t access;
|
||||||
if (!heap->QueryProtect(base_address, &access)) {
|
if (!heap->QueryProtect(base_address, &access)) {
|
||||||
access = 0;
|
access = 0;
|
||||||
}
|
}
|
||||||
access = ToXdkProtectFlags(access);
|
access = ToXdkProtectFlags(access);
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(access);
|
return access;
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(MmQueryAddressProtect, ExportTag::kImplemented);
|
||||||
|
|
||||||
void MmSetAddressProtect(lpvoid_t base_address, dword_t region_size,
|
dword_result_t MmSetAddressProtect(lpvoid_t base_address, dword_t region_size,
|
||||||
dword_t protect_bits) {
|
dword_t protect_bits) {
|
||||||
uint32_t protect = FromXdkProtectFlags(protect_bits);
|
uint32_t protect = FromXdkProtectFlags(protect_bits);
|
||||||
auto heap = kernel_memory()->LookupHeap(base_address);
|
auto heap = kernel_memory()->LookupHeap(base_address);
|
||||||
heap->Protect(base_address.guest_address(), region_size, protect);
|
if (heap->Protect(base_address.guest_address(), region_size, protect)) {
|
||||||
|
return X_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
return X_STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
DECLARE_XBOXKRNL_EXPORT(MmSetAddressProtect,
|
DECLARE_XBOXKRNL_EXPORT(MmSetAddressProtect,
|
||||||
ExportTag::kImplemented | ExportTag::kMemory);
|
ExportTag::kImplemented | ExportTag::kMemory);
|
||||||
|
|
||||||
SHIM_CALL MmQueryAllocationSize_shim(PPCContext* ppc_context,
|
dword_result_t MmQueryAllocationSize(lpvoid_t base_address) {
|
||||||
KernelState* kernel_state) {
|
auto heap = kernel_state()->memory()->LookupHeap(base_address);
|
||||||
uint32_t base_address = SHIM_GET_ARG_32(0);
|
|
||||||
|
|
||||||
XELOGD("MmQueryAllocationSize(%.8X)", base_address);
|
|
||||||
|
|
||||||
auto heap = kernel_state->memory()->LookupHeap(base_address);
|
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
if (!heap->QuerySize(base_address, &size)) {
|
if (!heap->QuerySize(base_address, &size)) {
|
||||||
size = 0;
|
size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(size);
|
return size;
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(MmQueryAllocationSize, ExportTag::kImplemented);
|
||||||
|
|
||||||
// https://code.google.com/p/vdash/source/browse/trunk/vdash/include/kernel.h
|
// https://code.google.com/p/vdash/source/browse/trunk/vdash/include/kernel.h
|
||||||
struct X_MM_QUERY_STATISTICS_SECTION {
|
struct X_MM_QUERY_STATISTICS_SECTION {
|
||||||
|
@ -396,37 +374,29 @@ struct X_MM_QUERY_STATISTICS_RESULT {
|
||||||
};
|
};
|
||||||
static_assert_size(X_MM_QUERY_STATISTICS_RESULT, 104);
|
static_assert_size(X_MM_QUERY_STATISTICS_RESULT, 104);
|
||||||
|
|
||||||
SHIM_CALL MmQueryStatistics_shim(PPCContext* ppc_context,
|
dword_result_t MmQueryStatistics(
|
||||||
KernelState* kernel_state) {
|
pointer_t<X_MM_QUERY_STATISTICS_RESULT> stats_ptr) {
|
||||||
uint32_t stats_ptr = SHIM_GET_ARG_32(0);
|
if (!stats_ptr) {
|
||||||
|
return X_STATUS_INVALID_PARAMETER;
|
||||||
XELOGD("MmQueryStatistics(%.8X)", stats_ptr);
|
|
||||||
|
|
||||||
if (stats_ptr == 0) {
|
|
||||||
SHIM_SET_RETURN_32(X_STATUS_INVALID_PARAMETER);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t size = sizeof(X_MM_QUERY_STATISTICS_RESULT);
|
const uint32_t size = sizeof(X_MM_QUERY_STATISTICS_RESULT);
|
||||||
|
|
||||||
auto stats =
|
if (stats_ptr->size != size) {
|
||||||
reinterpret_cast<X_MM_QUERY_STATISTICS_RESULT*>(SHIM_MEM_ADDR(stats_ptr));
|
return X_STATUS_BUFFER_TOO_SMALL;
|
||||||
if (stats->size != size) {
|
|
||||||
SHIM_SET_RETURN_32(X_STATUS_BUFFER_TOO_SMALL);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zero out the struct.
|
// Zero out the struct.
|
||||||
std::memset(stats, 0, size);
|
std::memset(stats_ptr, 0, size);
|
||||||
|
|
||||||
// Set the constants the game is likely asking for.
|
// Set the constants the game is likely asking for.
|
||||||
// These numbers are mostly guessed. If the game is just checking for
|
// These numbers are mostly guessed. If the game is just checking for
|
||||||
// memory, this should satisfy it. If it's actually verifying things
|
// memory, this should satisfy it. If it's actually verifying things
|
||||||
// this won't work :/
|
// this won't work :/
|
||||||
stats->size = size;
|
stats_ptr->size = size;
|
||||||
|
|
||||||
stats->total_physical_pages = 0x00020000; // 512mb / 4kb pages
|
stats_ptr->total_physical_pages = 0x00020000; // 512mb / 4kb pages
|
||||||
stats->kernel_pages = 0x00000300;
|
stats_ptr->kernel_pages = 0x00000300;
|
||||||
|
|
||||||
// TODO(gibbed): maybe use LookupHeapByType instead?
|
// TODO(gibbed): maybe use LookupHeapByType instead?
|
||||||
auto heap_a = kernel_memory()->LookupHeap(0xA0000000);
|
auto heap_a = kernel_memory()->LookupHeap(0xA0000000);
|
||||||
|
@ -447,45 +417,43 @@ SHIM_CALL MmQueryStatistics_shim(PPCContext* ppc_context,
|
||||||
#undef GET_USED_PAGE_SIZE
|
#undef GET_USED_PAGE_SIZE
|
||||||
#undef GET_USED_PAGE_COUNT
|
#undef GET_USED_PAGE_COUNT
|
||||||
|
|
||||||
assert_true(used_pages < stats->total_physical_pages);
|
assert_true(used_pages < stats_ptr->total_physical_pages);
|
||||||
|
|
||||||
stats->title.available_pages = stats->total_physical_pages - used_pages;
|
stats_ptr->title.available_pages =
|
||||||
stats->title.total_virtual_memory_bytes = 0x2FFF0000; // TODO(gibbed): FIXME
|
stats_ptr->total_physical_pages - used_pages;
|
||||||
stats->title.reserved_virtual_memory_bytes =
|
stats_ptr->title.total_virtual_memory_bytes =
|
||||||
|
0x2FFF0000; // TODO(gibbed): FIXME
|
||||||
|
stats_ptr->title.reserved_virtual_memory_bytes =
|
||||||
0x00160000; // TODO(gibbed): FIXME
|
0x00160000; // TODO(gibbed): FIXME
|
||||||
stats->title.physical_pages = 0x00001000; // TODO(gibbed): FIXME
|
stats_ptr->title.physical_pages = 0x00001000; // TODO(gibbed): FIXME
|
||||||
stats->title.pool_pages = 0x00000010;
|
stats_ptr->title.pool_pages = 0x00000010;
|
||||||
stats->title.stack_pages = 0x00000100;
|
stats_ptr->title.stack_pages = 0x00000100;
|
||||||
stats->title.image_pages = 0x00000100;
|
stats_ptr->title.image_pages = 0x00000100;
|
||||||
stats->title.heap_pages = 0x00000100;
|
stats_ptr->title.heap_pages = 0x00000100;
|
||||||
stats->title.virtual_pages = 0x00000100;
|
stats_ptr->title.virtual_pages = 0x00000100;
|
||||||
stats->title.page_table_pages = 0x00000100;
|
stats_ptr->title.page_table_pages = 0x00000100;
|
||||||
stats->title.cache_pages = 0x00000100;
|
stats_ptr->title.cache_pages = 0x00000100;
|
||||||
|
|
||||||
stats->system.available_pages = 0x00000000;
|
stats_ptr->system.available_pages = 0x00000000;
|
||||||
stats->system.total_virtual_memory_bytes = 0x00000000;
|
stats_ptr->system.total_virtual_memory_bytes = 0x00000000;
|
||||||
stats->system.reserved_virtual_memory_bytes = 0x00000000;
|
stats_ptr->system.reserved_virtual_memory_bytes = 0x00000000;
|
||||||
stats->system.physical_pages = 0x00000000;
|
stats_ptr->system.physical_pages = 0x00000000;
|
||||||
stats->system.pool_pages = 0x00000000;
|
stats_ptr->system.pool_pages = 0x00000000;
|
||||||
stats->system.stack_pages = 0x00000000;
|
stats_ptr->system.stack_pages = 0x00000000;
|
||||||
stats->system.image_pages = 0x00000000;
|
stats_ptr->system.image_pages = 0x00000000;
|
||||||
stats->system.heap_pages = 0x00000000;
|
stats_ptr->system.heap_pages = 0x00000000;
|
||||||
stats->system.virtual_pages = 0x00000000;
|
stats_ptr->system.virtual_pages = 0x00000000;
|
||||||
stats->system.page_table_pages = 0x00000000;
|
stats_ptr->system.page_table_pages = 0x00000000;
|
||||||
stats->system.cache_pages = 0x00000000;
|
stats_ptr->system.cache_pages = 0x00000000;
|
||||||
|
|
||||||
stats->highest_physical_page = 0x0001FFFF;
|
stats_ptr->highest_physical_page = 0x0001FFFF;
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(X_STATUS_SUCCESS);
|
return X_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(MmQueryStatistics, ExportTag::kImplemented);
|
||||||
|
|
||||||
// http://msdn.microsoft.com/en-us/library/windows/hardware/ff554547(v=vs.85).aspx
|
// http://msdn.microsoft.com/en-us/library/windows/hardware/ff554547(v=vs.85).aspx
|
||||||
SHIM_CALL MmGetPhysicalAddress_shim(PPCContext* ppc_context,
|
dword_result_t MmGetPhysicalAddress(dword_t base_address) {
|
||||||
KernelState* kernel_state) {
|
|
||||||
uint32_t base_address = SHIM_GET_ARG_32(0);
|
|
||||||
|
|
||||||
XELOGD("MmGetPhysicalAddress(%.8X)", base_address);
|
|
||||||
|
|
||||||
// PHYSICAL_ADDRESS MmGetPhysicalAddress(
|
// PHYSICAL_ADDRESS MmGetPhysicalAddress(
|
||||||
// _In_ PVOID BaseAddress
|
// _In_ PVOID BaseAddress
|
||||||
// );
|
// );
|
||||||
|
@ -497,18 +465,12 @@ SHIM_CALL MmGetPhysicalAddress_shim(PPCContext* ppc_context,
|
||||||
physical_address += 0x1000;
|
physical_address += 0x1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(physical_address);
|
return physical_address;
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(MmGetPhysicalAddress, ExportTag::kImplemented);
|
||||||
|
|
||||||
SHIM_CALL MmMapIoSpace_shim(PPCContext* ppc_context,
|
dword_result_t MmMapIoSpace(dword_t unk0, lpvoid_t src_address, dword_t size,
|
||||||
KernelState* kernel_state) {
|
dword_t flags) {
|
||||||
uint32_t unk0 = SHIM_GET_ARG_32(0);
|
|
||||||
uint32_t src_address = SHIM_GET_ARG_32(1); // from MmGetPhysicalAddress
|
|
||||||
uint32_t size = SHIM_GET_ARG_32(2);
|
|
||||||
uint32_t flags = SHIM_GET_ARG_32(3);
|
|
||||||
|
|
||||||
XELOGD("MmMapIoSpace(%.8X, %.8X, %d, %.8X)", unk0, src_address, size, flags);
|
|
||||||
|
|
||||||
// I've only seen this used to map XMA audio contexts.
|
// I've only seen this used to map XMA audio contexts.
|
||||||
// The code seems fine with taking the src address, so this just returns that.
|
// The code seems fine with taking the src address, so this just returns that.
|
||||||
// If others start using it there could be problems.
|
// If others start using it there could be problems.
|
||||||
|
@ -516,17 +478,12 @@ SHIM_CALL MmMapIoSpace_shim(PPCContext* ppc_context,
|
||||||
assert_true(size == 0x40);
|
assert_true(size == 0x40);
|
||||||
assert_true(flags == 0x404);
|
assert_true(flags == 0x404);
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(src_address);
|
return 0;
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(MmMapIoSpace, ExportTag::kImplemented);
|
||||||
|
|
||||||
SHIM_CALL ExAllocatePoolTypeWithTag_shim(PPCContext* ppc_context,
|
dword_result_t ExAllocatePoolTypeWithTag(dword_t size, dword_t tag,
|
||||||
KernelState* kernel_state) {
|
dword_t zero) {
|
||||||
uint32_t size = SHIM_GET_ARG_32(0);
|
|
||||||
uint32_t tag = SHIM_GET_ARG_32(1);
|
|
||||||
uint32_t zero = SHIM_GET_ARG_32(2);
|
|
||||||
|
|
||||||
XELOGD("ExAllocatePoolTypeWithTag(%d, %.4s, %d)", size, &tag, zero);
|
|
||||||
|
|
||||||
uint32_t alignment = 8;
|
uint32_t alignment = 8;
|
||||||
uint32_t adjusted_size = size;
|
uint32_t adjusted_size = size;
|
||||||
if (adjusted_size < 4 * 1024) {
|
if (adjusted_size < 4 * 1024) {
|
||||||
|
@ -536,18 +493,16 @@ SHIM_CALL ExAllocatePoolTypeWithTag_shim(PPCContext* ppc_context,
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t addr =
|
uint32_t addr =
|
||||||
kernel_state->memory()->SystemHeapAlloc(adjusted_size, alignment);
|
kernel_state()->memory()->SystemHeapAlloc(adjusted_size, alignment);
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(addr);
|
return addr;
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(ExAllocatePoolTypeWithTag, ExportTag::kImplemented);
|
||||||
|
|
||||||
SHIM_CALL ExFreePool_shim(PPCContext* ppc_context, KernelState* kernel_state) {
|
void ExFreePool(lpvoid_t base_address) {
|
||||||
uint32_t base_address = SHIM_GET_ARG_32(0);
|
kernel_state()->memory()->SystemHeapFree(base_address);
|
||||||
|
|
||||||
XELOGD("ExFreePool(%.8X)", base_address);
|
|
||||||
|
|
||||||
kernel_state->memory()->SystemHeapFree(base_address);
|
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(ExFreePool, ExportTag::kImplemented);
|
||||||
|
|
||||||
dword_result_t KeGetImagePageTableEntry(lpvoid_t address) {
|
dword_result_t KeGetImagePageTableEntry(lpvoid_t address) {
|
||||||
// Unknown
|
// Unknown
|
||||||
|
@ -555,18 +510,14 @@ dword_result_t KeGetImagePageTableEntry(lpvoid_t address) {
|
||||||
}
|
}
|
||||||
DECLARE_XBOXKRNL_EXPORT(KeGetImagePageTableEntry, ExportTag::kStub);
|
DECLARE_XBOXKRNL_EXPORT(KeGetImagePageTableEntry, ExportTag::kStub);
|
||||||
|
|
||||||
SHIM_CALL KeLockL2_shim(PPCContext* ppc_context, KernelState* kernel_state) {
|
dword_result_t KeLockL2() {
|
||||||
// Ignored for now. This is just a perf optimization, I think.
|
// TODO
|
||||||
// It may be useful as a hint for CPU-GPU transfer.
|
return 0;
|
||||||
|
|
||||||
XELOGD("KeLockL2(?)");
|
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(0);
|
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(KeLockL2, ExportTag::kStub);
|
||||||
|
|
||||||
SHIM_CALL KeUnlockL2_shim(PPCContext* ppc_context, KernelState* kernel_state) {
|
void KeUnlockL2() {}
|
||||||
XELOGD("KeUnlockL2(?)");
|
DECLARE_XBOXKRNL_EXPORT(KeUnlockL2, ExportTag::kStub);
|
||||||
}
|
|
||||||
|
|
||||||
dword_result_t MmCreateKernelStack(dword_t stack_size, dword_t r4) {
|
dword_result_t MmCreateKernelStack(dword_t stack_size, dword_t r4) {
|
||||||
assert_zero(r4); // Unknown argument.
|
assert_zero(r4); // Unknown argument.
|
||||||
|
@ -596,22 +547,7 @@ dword_result_t MmDeleteKernelStack(lpvoid_t stack_base, lpvoid_t stack_end) {
|
||||||
DECLARE_XBOXKRNL_EXPORT(MmDeleteKernelStack, ExportTag::kImplemented);
|
DECLARE_XBOXKRNL_EXPORT(MmDeleteKernelStack, ExportTag::kImplemented);
|
||||||
|
|
||||||
void RegisterMemoryExports(xe::cpu::ExportResolver* export_resolver,
|
void RegisterMemoryExports(xe::cpu::ExportResolver* export_resolver,
|
||||||
KernelState* kernel_state) {
|
KernelState* kernel_state) {}
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtFreeVirtualMemory, state);
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtQueryVirtualMemory, state);
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", MmFreePhysicalMemory, state);
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", MmQueryAddressProtect, state);
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", MmQueryAllocationSize, state);
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", MmQueryStatistics, state);
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", MmGetPhysicalAddress, state);
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", MmMapIoSpace, state);
|
|
||||||
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", ExAllocatePoolTypeWithTag, state);
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", ExFreePool, state);
|
|
||||||
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", KeLockL2, state);
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", KeUnlockL2, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace xboxkrnl
|
} // namespace xboxkrnl
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
|
|
|
@ -18,17 +18,13 @@ namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
namespace xboxkrnl {
|
namespace xboxkrnl {
|
||||||
|
|
||||||
SHIM_CALL KeEnableFpuExceptions_shim(PPCContext* ppc_context,
|
void KeEnableFpuExceptions(dword_t enabled) {
|
||||||
KernelState* kernel_state) {
|
|
||||||
uint32_t enabled = SHIM_GET_ARG_32(0);
|
|
||||||
XELOGD("KeEnableFpuExceptions(%d)", enabled);
|
|
||||||
// TODO(benvanik): can we do anything about exceptions?
|
// TODO(benvanik): can we do anything about exceptions?
|
||||||
}
|
}
|
||||||
|
DECLARE_XBOXKRNL_EXPORT(KeEnableFpuExceptions, ExportTag::kStub);
|
||||||
|
|
||||||
void RegisterMiscExports(xe::cpu::ExportResolver* export_resolver,
|
void RegisterMiscExports(xe::cpu::ExportResolver* export_resolver,
|
||||||
KernelState* kernel_state) {
|
KernelState* kernel_state) {}
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", KeEnableFpuExceptions, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace xboxkrnl
|
} // namespace xboxkrnl
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
|
|
Loading…
Reference in New Issue