Starting to properly attribute virtual vs. physical memory accesses.

This commit is contained in:
Ben Vanik
2015-03-29 11:11:35 -07:00
parent ab90e0932b
commit ec84a688e9
42 changed files with 346 additions and 372 deletions

View File

@@ -16,8 +16,8 @@ namespace kernel {
XApp::XApp(KernelState* kernel_state, uint32_t app_id)
: kernel_state_(kernel_state),
app_id_(app_id),
membase_(kernel_state->memory()->membase()) {}
memory_(kernel_state->memory()),
app_id_(app_id) {}
void XAppManager::RegisterApp(std::unique_ptr<XApp> app) {
assert_zero(app_lookup_.count(app->app_id()));

View File

@@ -33,8 +33,8 @@ class XApp {
XApp(KernelState* kernel_state, uint32_t app_id);
KernelState* kernel_state_;
Memory* memory_;
uint32_t app_id_;
uint8_t* membase_;
};
class XAppManager {

View File

@@ -22,6 +22,7 @@ XXGIApp::XXGIApp(KernelState* kernel_state) : XApp(kernel_state, 0xFB) {}
X_RESULT XXGIApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
uint32_t buffer_length) {
// NOTE: buffer_length may be zero or valid.
auto buffer = memory_->TranslateVirtual(buffer_ptr);
switch (message) {
case 0x000B0006: {
assert_true(!buffer_length || buffer_length == 24);
@@ -30,35 +31,26 @@ X_RESULT XXGIApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
// qword 0
// dword r4 context enum
// dword r5 value
uint32_t user_index =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t context_id =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 16);
uint32_t context_value =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 20);
uint32_t user_index = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t context_id = poly::load_and_swap<uint32_t>(buffer + 16);
uint32_t context_value = poly::load_and_swap<uint32_t>(buffer + 20);
XELOGD("XUserSetContextEx(%.8X, %.8X, %.8X)", user_index, context_id,
context_value);
return X_ERROR_SUCCESS;
}
case 0x000B0007: {
uint32_t user_index =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t property_id =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 16);
uint32_t value_size =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 20);
uint32_t value_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 24);
uint32_t user_index = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t property_id = poly::load_and_swap<uint32_t>(buffer + 16);
uint32_t value_size = poly::load_and_swap<uint32_t>(buffer + 20);
uint32_t value_ptr = poly::load_and_swap<uint32_t>(buffer + 24);
XELOGD("XUserSetPropertyEx(%.8X, %.8X, %d, %.8X)", user_index,
property_id, value_size, value_ptr);
return X_ERROR_SUCCESS;
}
case 0x000B0008: {
assert_true(!buffer_length || buffer_length == 8);
uint32_t achievement_count =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t achievements_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 4);
uint32_t achievement_count = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t achievements_ptr = poly::load_and_swap<uint32_t>(buffer + 4);
XELOGD("XUserWriteAchievements(%.8X, %.8X)", achievement_count,
achievements_ptr);
return X_ERROR_SUCCESS;
@@ -76,16 +68,14 @@ X_RESULT XXGIApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
case 0x000B0041: {
assert_true(!buffer_length || buffer_length == 32);
// 00000000 2789fecc 00000000 00000000 200491e0 00000000 200491f0 20049340
uint32_t user_index =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t context_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 16);
uint32_t context_id =
poly::load_and_swap<uint32_t>(membase_ + context_ptr + 0);
uint32_t user_index = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t context_ptr = poly::load_and_swap<uint32_t>(buffer + 16);
auto context = memory_->TranslateVirtual(context_ptr);
uint32_t context_id = poly::load_and_swap<uint32_t>(context + 0);
XELOGD("XUserGetContext(%.8X, %.8X(%.8X))", user_index, context_ptr,
context_id);
uint32_t value = 0;
poly::store_and_swap<uint32_t>(membase_ + context_ptr + 4, value);
poly::store_and_swap<uint32_t>(context + 4, value);
return X_ERROR_SUCCESS;
}
case 0x000B0071: {

View File

@@ -24,12 +24,13 @@ X_RESULT XXLiveBaseApp::DispatchMessageSync(uint32_t message,
uint32_t buffer_ptr,
uint32_t buffer_length) {
// NOTE: buffer_length may be zero or valid.
auto buffer = memory_->TranslateVirtual(buffer_ptr);
switch (message) {
case 0x00058004: {
// Called on startup, seems to just return a bool in the buffer.
assert_true(!buffer_length || buffer_length == 4);
XELOGD("XLiveBaseGetLogonId(%.8X)", buffer_ptr);
poly::store_and_swap<uint32_t>(membase_ + buffer_ptr + 0, 1); // ?
poly::store_and_swap<uint32_t>(buffer + 0, 1); // ?
return X_ERROR_SUCCESS;
}
case 0x00058020: {

View File

@@ -34,7 +34,7 @@ X_RESULT XXMPApp::XMPGetStatus(uint32_t state_ptr) {
Sleep(1);
XELOGD("XMPGetStatus(%.8X)", state_ptr);
poly::store_and_swap<uint32_t>(membase_ + state_ptr,
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(state_ptr),
static_cast<uint32_t>(state_));
return X_ERROR_SUCCESS;
}
@@ -54,30 +54,32 @@ X_RESULT XXMPApp::XMPCreateTitlePlaylist(
for (uint32_t i = 0; i < song_count; ++i) {
auto song = std::make_unique<Song>();
song->handle = ++next_song_handle_;
uint8_t* song_base = membase_ + songs_ptr + (i * 36);
song->file_path = poly::load_and_swap<std::wstring>(
membase_ + poly::load_and_swap<uint32_t>(song_base + 0));
song->name = poly::load_and_swap<std::wstring>(
membase_ + poly::load_and_swap<uint32_t>(song_base + 4));
song->artist = poly::load_and_swap<std::wstring>(
membase_ + poly::load_and_swap<uint32_t>(song_base + 8));
song->album = poly::load_and_swap<std::wstring>(
membase_ + poly::load_and_swap<uint32_t>(song_base + 12));
song->album_artist = poly::load_and_swap<std::wstring>(
membase_ + poly::load_and_swap<uint32_t>(song_base + 16));
song->genre = poly::load_and_swap<std::wstring>(
membase_ + poly::load_and_swap<uint32_t>(song_base + 20));
uint8_t* song_base = memory_->TranslateVirtual(songs_ptr + (i * 36));
song->file_path =
poly::load_and_swap<std::wstring>(memory_->TranslateVirtual(
poly::load_and_swap<uint32_t>(song_base + 0)));
song->name = poly::load_and_swap<std::wstring>(memory_->TranslateVirtual(
poly::load_and_swap<uint32_t>(song_base + 4)));
song->artist = poly::load_and_swap<std::wstring>(memory_->TranslateVirtual(
poly::load_and_swap<uint32_t>(song_base + 8)));
song->album = poly::load_and_swap<std::wstring>(memory_->TranslateVirtual(
poly::load_and_swap<uint32_t>(song_base + 12)));
song->album_artist =
poly::load_and_swap<std::wstring>(memory_->TranslateVirtual(
poly::load_and_swap<uint32_t>(song_base + 16)));
song->genre = poly::load_and_swap<std::wstring>(memory_->TranslateVirtual(
poly::load_and_swap<uint32_t>(song_base + 20)));
song->track_number = poly::load_and_swap<uint32_t>(song_base + 24);
song->duration_ms = poly::load_and_swap<uint32_t>(song_base + 28);
song->format = static_cast<Song::Format>(
poly::load_and_swap<uint32_t>(song_base + 32));
if (out_song_handles) {
poly::store_and_swap<uint32_t>(membase_ + out_song_handles + (i * 4),
song->handle);
poly::store_and_swap<uint32_t>(
memory_->TranslateVirtual(out_song_handles + (i * 4)), song->handle);
}
playlist->songs.emplace_back(std::move(song));
}
poly::store_and_swap<uint32_t>(membase_ + out_playlist_handle,
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(out_playlist_handle),
playlist->handle);
std::lock_guard<std::mutex> lock(mutex_);
@@ -195,64 +197,53 @@ void XXMPApp::OnStateChanged() {
X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
uint32_t buffer_length) {
// NOTE: buffer_length may be zero or valid.
auto buffer = memory_->TranslateVirtual(buffer_ptr);
switch (message) {
case 0x00070002: {
assert_true(!buffer_length || buffer_length == 12);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t playlist_handle =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 4);
uint32_t song_handle =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 8); // 0?
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t playlist_handle = poly::load_and_swap<uint32_t>(buffer + 4);
uint32_t song_handle = poly::load_and_swap<uint32_t>(buffer + 8); // 0?
assert_true(xmp_client == 0x00000002);
return XMPPlayTitlePlaylist(playlist_handle, song_handle);
}
case 0x00070003: {
assert_true(!buffer_length || buffer_length == 4);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
assert_true(xmp_client == 0x00000002);
return XMPContinue();
}
case 0x00070004: {
assert_true(!buffer_length || buffer_length == 8);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t unk = poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 4);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t unk = poly::load_and_swap<uint32_t>(buffer + 4);
assert_true(xmp_client == 0x00000002);
return XMPStop(unk);
}
case 0x00070005: {
assert_true(!buffer_length || buffer_length == 4);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
assert_true(xmp_client == 0x00000002);
return XMPPause();
}
case 0x00070006: {
assert_true(!buffer_length || buffer_length == 4);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
assert_true(xmp_client == 0x00000002);
return XMPNext();
}
case 0x00070007: {
assert_true(!buffer_length || buffer_length == 4);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
assert_true(xmp_client == 0x00000002);
return XMPPrevious();
}
case 0x00070008: {
assert_true(!buffer_length || buffer_length == 16);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t playback_mode =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 4);
uint32_t repeat_mode =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 8);
uint32_t flags =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 12);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t playback_mode = poly::load_and_swap<uint32_t>(buffer + 4);
uint32_t repeat_mode = poly::load_and_swap<uint32_t>(buffer + 8);
uint32_t flags = poly::load_and_swap<uint32_t>(buffer + 12);
assert_true(xmp_client == 0x00000002);
XELOGD("XMPSetPlaybackBehavior(%.8X, %.8X, %.8X)", playback_mode,
repeat_mode, flags);
@@ -264,29 +255,27 @@ X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
}
case 0x00070009: {
assert_true(!buffer_length || buffer_length == 8);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t state_ptr = poly::load_and_swap<uint32_t>(
membase_ + buffer_ptr + 4); // out ptr to 4b - expect 0
buffer + 4); // out ptr to 4b - expect 0
assert_true(xmp_client == 0x00000002);
return XMPGetStatus(state_ptr);
}
case 0x0007000B: {
assert_true(!buffer_length || buffer_length == 8);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t float_ptr = poly::load_and_swap<uint32_t>(
membase_ + buffer_ptr + 4); // out ptr to 4b - floating point
buffer + 4); // out ptr to 4b - floating point
assert_true(xmp_client == 0x00000002);
XELOGD("XMPGetVolume(%.8X)", float_ptr);
poly::store_and_swap<float>(membase_ + float_ptr, volume_);
poly::store_and_swap<float>(memory_->TranslateVirtual(float_ptr),
volume_);
return X_ERROR_SUCCESS;
}
case 0x0007000C: {
assert_true(!buffer_length || buffer_length == 8);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
float float_value = poly::load_and_swap<float>(membase_ + buffer_ptr + 4);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
float float_value = poly::load_and_swap<float>(buffer + 4);
assert_true(xmp_client == 0x00000002);
XELOGD("XMPSetVolume(%g)", float_value);
volume_ = float_value;
@@ -294,27 +283,19 @@ X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
}
case 0x0007000D: {
assert_true(!buffer_length || buffer_length == 36);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t dummy_alloc_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 4);
uint32_t dummy_alloc_size =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 8);
uint32_t songs_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 12);
uint32_t song_count =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 16);
uint32_t playlist_name_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 20);
uint32_t flags =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 24);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t dummy_alloc_ptr = poly::load_and_swap<uint32_t>(buffer + 4);
uint32_t dummy_alloc_size = poly::load_and_swap<uint32_t>(buffer + 8);
uint32_t songs_ptr = poly::load_and_swap<uint32_t>(buffer + 12);
uint32_t song_count = poly::load_and_swap<uint32_t>(buffer + 16);
uint32_t playlist_name_ptr = poly::load_and_swap<uint32_t>(buffer + 20);
uint32_t flags = poly::load_and_swap<uint32_t>(buffer + 24);
uint32_t song_handles_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 28); // 0?
uint32_t playlist_handle_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 32);
poly::load_and_swap<uint32_t>(buffer + 28); // 0?
uint32_t playlist_handle_ptr = poly::load_and_swap<uint32_t>(buffer + 32);
assert_true(xmp_client == 0x00000002);
auto playlist_name =
poly::load_and_swap<std::wstring>(membase_ + playlist_name_ptr);
auto playlist_name = poly::load_and_swap<std::wstring>(
memory_->TranslateVirtual(playlist_name_ptr));
// dummy_alloc_ptr is the result of a XamAlloc of dummy_alloc_size.
assert_true(dummy_alloc_size == song_count * 128);
return XMPCreateTitlePlaylist(songs_ptr, song_count, playlist_name_ptr,
@@ -323,12 +304,10 @@ X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
}
case 0x0007000E: {
assert_true(!buffer_length || buffer_length == 12);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t unk_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 4); // 0
uint32_t info_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 8);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t unk_ptr = poly::load_and_swap<uint32_t>(buffer + 4); // 0
uint32_t info_ptr = poly::load_and_swap<uint32_t>(buffer + 8);
auto info = memory_->TranslateVirtual(info_ptr);
assert_true(xmp_client == 0x00000002);
assert_zero(unk_ptr);
XELOGE("XMPGetInfo?(%.8X, %.8X)", unk_ptr, info_ptr);
@@ -336,41 +315,31 @@ X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
return X_ERROR_NOT_FOUND;
}
auto& song = active_playlist_->songs[active_song_index_];
poly::store_and_swap<uint32_t>(membase_ + info_ptr + 0, song->handle);
poly::store_and_swap<std::wstring>(membase_ + info_ptr + 4 + 572 + 0,
song->name);
poly::store_and_swap<std::wstring>(membase_ + info_ptr + 4 + 572 + 40,
song->artist);
poly::store_and_swap<std::wstring>(membase_ + info_ptr + 4 + 572 + 80,
song->album);
poly::store_and_swap<std::wstring>(membase_ + info_ptr + 4 + 572 + 120,
poly::store_and_swap<uint32_t>(info + 0, song->handle);
poly::store_and_swap<std::wstring>(info + 4 + 572 + 0, song->name);
poly::store_and_swap<std::wstring>(info + 4 + 572 + 40, song->artist);
poly::store_and_swap<std::wstring>(info + 4 + 572 + 80, song->album);
poly::store_and_swap<std::wstring>(info + 4 + 572 + 120,
song->album_artist);
poly::store_and_swap<std::wstring>(membase_ + info_ptr + 4 + 572 + 160,
song->genre);
poly::store_and_swap<uint32_t>(membase_ + info_ptr + 4 + 572 + 200,
song->track_number);
poly::store_and_swap<uint32_t>(membase_ + info_ptr + 4 + 572 + 204,
song->duration_ms);
poly::store_and_swap<uint32_t>(membase_ + info_ptr + 4 + 572 + 208,
poly::store_and_swap<std::wstring>(info + 4 + 572 + 160, song->genre);
poly::store_and_swap<uint32_t>(info + 4 + 572 + 200, song->track_number);
poly::store_and_swap<uint32_t>(info + 4 + 572 + 204, song->duration_ms);
poly::store_and_swap<uint32_t>(info + 4 + 572 + 208,
static_cast<uint32_t>(song->format));
return X_ERROR_SUCCESS;
}
case 0x00070013: {
assert_true(!buffer_length || buffer_length == 8);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t playlist_handle =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 4);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t playlist_handle = poly::load_and_swap<uint32_t>(buffer + 4);
assert_true(xmp_client == 0x00000002);
return XMPDeleteTitlePlaylist(playlist_handle);
}
case 0x0007001A: {
assert_true(!buffer_length || buffer_length == 12);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t unk1 = poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 4);
uint32_t enabled =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 8);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t unk1 = poly::load_and_swap<uint32_t>(buffer + 4);
uint32_t enabled = poly::load_and_swap<uint32_t>(buffer + 8);
assert_true(xmp_client == 0x00000002);
assert_zero(unk1);
XELOGD("XMPSetEnabled(%.8X, %.8X)", unk1, enabled);
@@ -383,53 +352,49 @@ X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
}
case 0x0007001B: {
assert_true(!buffer_length || buffer_length == 12);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t unk_ptr = poly::load_and_swap<uint32_t>(
membase_ + buffer_ptr + 4); // out ptr to 4b - expect 0
buffer + 4); // out ptr to 4b - expect 0
uint32_t disabled_ptr = poly::load_and_swap<uint32_t>(
membase_ + buffer_ptr + 8); // out ptr to 4b - expect 1 (to skip)
buffer + 8); // out ptr to 4b - expect 1 (to skip)
assert_true(xmp_client == 0x00000002);
XELOGD("XMPGetEnabled(%.8X, %.8X)", unk_ptr, disabled_ptr);
poly::store_and_swap<uint32_t>(membase_ + unk_ptr, 0);
poly::store_and_swap<uint32_t>(membase_ + disabled_ptr, disabled_);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(unk_ptr), 0);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(disabled_ptr),
disabled_);
// Atrain spawns a thread 82437FD0 to call this in a tight loop forever.
poly::threading::Sleep(std::chrono::milliseconds(10));
return X_ERROR_SUCCESS;
}
case 0x00070029: {
assert_true(!buffer_length || buffer_length == 16);
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t playback_mode_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 4);
uint32_t repeat_mode_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 8);
uint32_t unk3_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 12);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t playback_mode_ptr = poly::load_and_swap<uint32_t>(buffer + 4);
uint32_t repeat_mode_ptr = poly::load_and_swap<uint32_t>(buffer + 8);
uint32_t unk3_ptr = poly::load_and_swap<uint32_t>(buffer + 12);
assert_true(xmp_client == 0x00000002);
XELOGD("XMPGetPlaybackBehavior(%.8X, %.8X, %.8X)", playback_mode_ptr,
repeat_mode_ptr, unk3_ptr);
poly::store_and_swap<uint32_t>(membase_ + playback_mode_ptr,
static_cast<uint32_t>(playback_mode_));
poly::store_and_swap<uint32_t>(membase_ + repeat_mode_ptr,
poly::store_and_swap<uint32_t>(
memory_->TranslateVirtual(playback_mode_ptr),
static_cast<uint32_t>(playback_mode_));
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(repeat_mode_ptr),
static_cast<uint32_t>(repeat_mode_));
poly::store_and_swap<uint32_t>(membase_ + unk3_ptr, unknown_flags_);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(unk3_ptr),
unknown_flags_);
return X_ERROR_SUCCESS;
}
case 0x0007002E: {
assert_true(!buffer_length || buffer_length == 12);
// Query of size for XamAlloc - the result of the alloc is passed to
// 0x0007000D.
uint32_t xmp_client =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 0);
uint32_t song_count =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 4);
uint32_t size_ptr =
poly::load_and_swap<uint32_t>(membase_ + buffer_ptr + 8);
uint32_t xmp_client = poly::load_and_swap<uint32_t>(buffer + 0);
uint32_t song_count = poly::load_and_swap<uint32_t>(buffer + 4);
uint32_t size_ptr = poly::load_and_swap<uint32_t>(buffer + 8);
assert_true(xmp_client == 0x00000002);
// We don't use the storage, so just fudge the number.
poly::store_and_swap<uint32_t>(membase_ + size_ptr, song_count * 128);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(size_ptr),
song_count * 128);
return X_ERROR_SUCCESS;
}
case 0x0007003D: {

View File

@@ -204,7 +204,7 @@ void KernelState::BroadcastNotification(XNotificationID id, uint32_t data) {
void KernelState::CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result,
uint32_t length) {
auto ptr = memory()->membase() + overlapped_ptr;
auto ptr = memory()->TranslateVirtual(overlapped_ptr);
XOverlappedSetResult(ptr, result);
XOverlappedSetLength(ptr, length);
XOverlappedSetExtendedError(ptr, result);
@@ -233,7 +233,7 @@ void KernelState::CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result,
void KernelState::CompleteOverlappedImmediate(uint32_t overlapped_ptr,
X_RESULT result,
uint32_t length) {
auto ptr = memory()->membase() + overlapped_ptr;
auto ptr = memory()->TranslateVirtual(overlapped_ptr);
XOverlappedSetContext(ptr, XThread::GetCurrentThreadHandle());
CompleteOverlapped(overlapped_ptr, result, length);
}

View File

@@ -16,41 +16,44 @@ NativeList::NativeList(Memory* memory)
: memory_(memory), head_(kInvalidPointer) {}
void NativeList::Insert(uint32_t ptr) {
uint8_t* mem = memory_->membase();
poly::store_and_swap<uint32_t>(mem + ptr + 0, head_);
poly::store_and_swap<uint32_t>(mem + ptr + 4, 0);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(ptr + 0), head_);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(ptr + 4), 0);
if (head_) {
poly::store_and_swap<uint32_t>(mem + head_ + 4, ptr);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(head_ + 4), ptr);
}
head_ = ptr;
}
bool NativeList::IsQueued(uint32_t ptr) {
uint8_t* mem = memory_->membase();
uint32_t flink = poly::load_and_swap<uint32_t>(mem + ptr + 0);
uint32_t blink = poly::load_and_swap<uint32_t>(mem + ptr + 4);
uint32_t flink =
poly::load_and_swap<uint32_t>(memory_->TranslateVirtual(ptr + 0));
uint32_t blink =
poly::load_and_swap<uint32_t>(memory_->TranslateVirtual(ptr + 4));
return head_ == ptr || flink || blink;
}
void NativeList::Remove(uint32_t ptr) {
uint8_t* mem = memory_->membase();
uint32_t flink = poly::load_and_swap<uint32_t>(mem + ptr + 0);
uint32_t blink = poly::load_and_swap<uint32_t>(mem + ptr + 4);
uint32_t flink =
poly::load_and_swap<uint32_t>(memory_->TranslateVirtual(ptr + 0));
uint32_t blink =
poly::load_and_swap<uint32_t>(memory_->TranslateVirtual(ptr + 4));
if (ptr == head_) {
head_ = flink;
if (flink) {
poly::store_and_swap<uint32_t>(mem + flink + 4, 0);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(flink + 4), 0);
}
} else {
if (blink) {
poly::store_and_swap<uint32_t>(mem + blink + 0, flink);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(blink + 0),
flink);
}
if (flink) {
poly::store_and_swap<uint32_t>(mem + flink + 4, blink);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(flink + 4),
blink);
}
}
poly::store_and_swap<uint32_t>(mem + ptr + 0, 0);
poly::store_and_swap<uint32_t>(mem + ptr + 4, 0);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(ptr + 0), 0);
poly::store_and_swap<uint32_t>(memory_->TranslateVirtual(ptr + 4), 0);
}
uint32_t NativeList::Shift() {

View File

@@ -118,12 +118,12 @@ uint32_t XThread::thread_state() { return thread_state_address_; }
uint32_t XThread::thread_id() { return thread_id_; }
uint32_t XThread::last_error() {
uint8_t* p = memory()->Translate(thread_state_address_);
uint8_t* p = memory()->TranslateVirtual(thread_state_address_);
return poly::load_and_swap<uint32_t>(p + 0x160);
}
void XThread::set_last_error(uint32_t error_code) {
uint8_t* p = memory()->Translate(thread_state_address_);
uint8_t* p = memory()->TranslateVirtual(thread_state_address_);
poly::store_and_swap<uint32_t>(p + 0x160, error_code);
}
@@ -176,7 +176,7 @@ X_STATUS XThread::Create() {
memory()->Copy(tls_address_, header->tls_info.raw_data_address, tls_size);
// Setup the thread state block (last error/etc).
uint8_t* p = memory()->Translate(thread_state_address_);
uint8_t* p = memory()->TranslateVirtual(thread_state_address_);
poly::store_and_swap<uint32_t>(p + 0x000, tls_address_);
poly::store_and_swap<uint32_t>(p + 0x100, thread_state_address_);
poly::store_and_swap<uint32_t>(p + 0x14C, thread_id_);
@@ -382,7 +382,7 @@ void XThread::DeliverAPCs(void* data) {
// http://www.drdobbs.com/inside-nts-asynchronous-procedure-call/184416590?pgno=1
// http://www.drdobbs.com/inside-nts-asynchronous-procedure-call/184416590?pgno=7
XThread* thread = reinterpret_cast<XThread*>(data);
auto membase = thread->memory()->membase();
auto memory = thread->memory();
auto processor = thread->kernel_state()->processor();
auto apc_list = thread->apc_list();
thread->LockApc();
@@ -390,7 +390,7 @@ void XThread::DeliverAPCs(void* data) {
// Get APC entry (offset for LIST_ENTRY offset) and cache what we need.
// Calling the routine may delete the memory/overwrite it.
uint32_t apc_address = apc_list->Shift() - 8;
uint8_t* apc_ptr = membase + apc_address;
uint8_t* apc_ptr = memory->TranslateVirtual(apc_address);
uint32_t kernel_routine = poly::load_and_swap<uint32_t>(apc_ptr + 16);
uint32_t normal_routine = poly::load_and_swap<uint32_t>(apc_ptr + 24);
uint32_t normal_context = poly::load_and_swap<uint32_t>(apc_ptr + 28);
@@ -405,7 +405,7 @@ void XThread::DeliverAPCs(void* data) {
// The routine can modify all of its arguments before passing it on.
// Since we need to give guest accessible pointers over, we copy things
// into and out of scratch.
uint8_t* scratch_ptr = membase + thread->scratch_address_;
uint8_t* scratch_ptr = memory->TranslateVirtual(thread->scratch_address_);
poly::store_and_swap<uint32_t>(scratch_ptr + 0, normal_routine);
poly::store_and_swap<uint32_t>(scratch_ptr + 4, normal_context);
poly::store_and_swap<uint32_t>(scratch_ptr + 8, system_arg1);
@@ -438,13 +438,12 @@ void XThread::DeliverAPCs(void* data) {
}
void XThread::RundownAPCs() {
auto membase = memory()->membase();
LockApc();
while (apc_list_->HasPending()) {
// Get APC entry (offset for LIST_ENTRY offset) and cache what we need.
// Calling the routine may delete the memory/overwrite it.
uint32_t apc_address = apc_list_->Shift() - 8;
uint8_t* apc_ptr = membase + apc_address;
uint8_t* apc_ptr = memory()->TranslateVirtual(apc_address);
uint32_t rundown_routine = poly::load_and_swap<uint32_t>(apc_ptr + 20);
// Mark as uninserted so that it can be reinserted again by the routine.

View File

@@ -107,15 +107,15 @@ X_STATUS XUserModule::LoadFromMemory(const void* addr, const size_t length) {
// Load the XEX into memory and decrypt.
xe_xex2_options_t xex_options = {0};
xex_ = xe_xex2_load(kernel_state()->memory(), addr, length, xex_options);
xex_ = xe_xex2_load(memory(), addr, length, xex_options);
if (!xex_) {
return X_STATUS_UNSUCCESSFUL;
}
// Store execution info for later use.
// TODO(benvanik): just put entire xex header in memory somewhere?
execution_info_ptr_ = kernel_state()->memory()->SystemHeapAlloc(24);
auto eip = kernel_state()->memory()->membase() + execution_info_ptr_;
execution_info_ptr_ = memory()->SystemHeapAlloc(24);
auto eip = memory()->TranslateVirtual(execution_info_ptr_);
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 + 0x04, ex.version.value);

View File

@@ -26,8 +26,8 @@ using PPCContext = xe::cpu::frontend::PPCContext;
shim_data, \
(xe_kernel_export_shim_fn)export_name##_shim);
#define SHIM_MEM_BASE ppc_state->membase
#define SHIM_MEM_ADDR(a) (a ? (ppc_state->membase + a) : nullptr)
#define SHIM_MEM_BASE ppc_state->virtual_membase
#define SHIM_MEM_ADDR(a) (a ? (ppc_state->virtual_membase + a) : nullptr)
#define SHIM_MEM_8(a) poly::load_and_swap<uint8_t>(SHIM_MEM_ADDR(a))
#define SHIM_MEM_16(a) poly::load_and_swap<uint16_t>(SHIM_MEM_ADDR(a))

View File

@@ -538,7 +538,7 @@ int xe_xex2_read_image_uncompressed(const xe_xex2_header_t *header,
uncompressed_size);
return 2;
}
uint8_t *buffer = memory->Translate(header->exe_address);
uint8_t *buffer = memory->TranslateVirtual(header->exe_address);
std::memset(buffer, 0, uncompressed_size);
const uint8_t *p = (const uint8_t *)xex_addr + header->exe_offset;
@@ -588,7 +588,7 @@ int xe_xex2_read_image_basic_compressed(const xe_xex2_header_t *header,
uncompressed_size);
return 1;
}
uint8_t *buffer = memory->Translate(header->exe_address);
uint8_t *buffer = memory->TranslateVirtual(header->exe_address);
uint8_t *d = buffer;
std::memset(buffer, 0, uncompressed_size);
@@ -726,7 +726,7 @@ int xe_xex2_read_image_compressed(const xe_xex2_header_t *header,
result_code = 2;
goto XECLEANUP;
}
uint8_t *buffer = memory->Translate(header->exe_address);
uint8_t *buffer = memory->TranslateVirtual(header->exe_address);
std::memset(buffer, 0, uncompressed_size);
// Setup decompressor and decompress.
@@ -792,7 +792,7 @@ int xe_xex2_read_image(xe_xex2_ref xex, const uint8_t *xex_addr,
int xe_xex2_load_pe(xe_xex2_ref xex) {
const xe_xex2_header_t *header = &xex->header;
const uint8_t *p = xex->memory->Translate(header->exe_address);
const uint8_t *p = xex->memory->TranslateVirtual(header->exe_address);
// Verify DOS signature (MZ).
const IMAGE_DOS_HEADER *doshdr = (const IMAGE_DOS_HEADER *)p;
@@ -886,7 +886,6 @@ const PESection *xe_xex2_get_pe_section(xe_xex2_ref xex, const char *name) {
int xe_xex2_find_import_infos(xe_xex2_ref xex,
const xe_xex2_import_library_t *library) {
uint8_t *mem = xex->memory->membase();
auto header = xe_xex2_get_header(xex);
// Find library index for verification.
@@ -910,7 +909,8 @@ int xe_xex2_find_import_infos(xe_xex2_ref xex,
size_t info_count = 0;
for (size_t n = 0; n < library->record_count; n++) {
const uint32_t record = library->records[n];
const uint32_t value = poly::load_and_swap<uint32_t>(mem + record);
const uint32_t value =
poly::load_and_swap<uint32_t>(xex->memory->TranslateVirtual(record));
if (value & 0xFF000000) {
// Thunk for previous record - ignore.
} else {
@@ -929,7 +929,8 @@ int xe_xex2_find_import_infos(xe_xex2_ref xex,
// Construct infos.
for (size_t n = 0, i = 0; n < library->record_count; n++) {
const uint32_t record = library->records[n];
const uint32_t value = poly::load_and_swap<uint32_t>(mem + record);
const uint32_t value =
poly::load_and_swap<uint32_t>(xex->memory->TranslateVirtual(record));
const uint32_t type = (value & 0xFF000000) >> 24;
// Verify library index matches given library.

View File

@@ -151,10 +151,6 @@ struct XMAContextData {
};
static_assert(sizeof(XMAContextData) == 4 * 10, "Must be packed");
void StoreXmaRegister(uint8_t* membase, uint32_t num, uint32_t value) {
poly::store<uint32_t>(membase + (0x7FEA0000 + num), value);
}
void StoreXmaContextIndexedRegister(KernelState* state, uint32_t base_reg,
uint32_t context_ptr) {
auto audio_system = state->emulator()->audio_system();
@@ -162,7 +158,8 @@ void StoreXmaContextIndexedRegister(KernelState* state, uint32_t base_reg,
XMAContextData::kSize;
uint32_t reg_num = base_reg + (hw_index >> 5) * 4;
uint32_t reg_value = 1 << (hw_index & 0x1F);
StoreXmaRegister(state->memory()->membase(), reg_num, reg_value);
poly::store<uint32_t>(state->memory()->TranslateVirtual(0x7FEA0000 + reg_num),
reg_value);
}
SHIM_CALL XMAInitializeContext_shim(PPCContext* ppc_state, KernelState* state) {

View File

@@ -44,23 +44,23 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
xboxkrnl::RegisterUsbcamExports(export_resolver_, kernel_state_);
xboxkrnl::RegisterVideoExports(export_resolver_, kernel_state_);
uint8_t* mem = memory_->membase();
// KeDebugMonitorData (?*)
// 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
// arguments. If we wanted to see what would happen we could fake that.
uint32_t pKeDebugMonitorData = memory_->SystemHeapAlloc(256);
auto lpKeDebugMonitorData = memory_->TranslateVirtual(pKeDebugMonitorData);
export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::KeDebugMonitorData, pKeDebugMonitorData);
poly::store_and_swap<uint32_t>(mem + pKeDebugMonitorData, 0);
poly::store_and_swap<uint32_t>(lpKeDebugMonitorData, 0);
// KeCertMonitorData (?*)
// Always set to zero, ignored.
uint32_t pKeCertMonitorData = memory_->SystemHeapAlloc(4);
auto lpKeCertMonitorData = memory_->TranslateVirtual(pKeCertMonitorData);
export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::KeCertMonitorData, pKeCertMonitorData);
poly::store_and_swap<uint32_t>(mem + pKeCertMonitorData, 0);
poly::store_and_swap<uint32_t>(lpKeCertMonitorData, 0);
// XboxHardwareInfo (XboxHardwareInfo_t, 16b)
// flags cpu# ? ? ? ? ? ?
@@ -71,11 +71,11 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
// aomega08 says the value is 0x02000817, bit 27: debug mode on.
// When that is set, though, allocs crash in weird ways.
uint32_t pXboxHardwareInfo = memory_->SystemHeapAlloc(16);
auto lpXboxHardwareInfo = memory_->TranslateVirtual(pXboxHardwareInfo);
export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::XboxHardwareInfo, pXboxHardwareInfo);
poly::store_and_swap<uint32_t>(mem + pXboxHardwareInfo + 0, 0); // flags
poly::store_and_swap<uint8_t>(mem + pXboxHardwareInfo + 4,
0x06); // cpu count
poly::store_and_swap<uint32_t>(lpXboxHardwareInfo + 0, 0); // flags
poly::store_and_swap<uint8_t>(lpXboxHardwareInfo + 4, 0x06); // cpu count
// Remaining 11b are zeroes?
// XexExecutableModuleHandle (?**)
@@ -88,13 +88,17 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
// 0x80101058 <- pointer to xex header
// 0x80101100 <- xex header base
uint32_t ppXexExecutableModuleHandle = memory_->SystemHeapAlloc(4);
auto lppXexExecutableModuleHandle =
memory_->TranslateVirtual(ppXexExecutableModuleHandle);
export_resolver_->SetVariableMapping("xboxkrnl.exe",
ordinals::XexExecutableModuleHandle,
ppXexExecutableModuleHandle);
uint32_t pXexExecutableModuleHandle = memory_->SystemHeapAlloc(256);
poly::store_and_swap<uint32_t>(mem + ppXexExecutableModuleHandle,
auto lpXexExecutableModuleHandle =
memory_->TranslateVirtual(pXexExecutableModuleHandle);
poly::store_and_swap<uint32_t>(lppXexExecutableModuleHandle,
pXexExecutableModuleHandle);
poly::store_and_swap<uint32_t>(mem + pXexExecutableModuleHandle + 0x58,
poly::store_and_swap<uint32_t>(lpXexExecutableModuleHandle + 0x58,
0x80101100);
// ExLoadedCommandLine (char*)
@@ -102,41 +106,44 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
// Perhaps it's how swap disc/etc data is sent?
// Always set to "default.xex" (with quotes) for now.
uint32_t pExLoadedCommandLine = memory_->SystemHeapAlloc(1024);
auto lpExLoadedCommandLine = memory_->TranslateVirtual(pExLoadedCommandLine);
export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::ExLoadedCommandLine, pExLoadedCommandLine);
char command_line[] = "\"default.xex\"";
memcpy(mem + pExLoadedCommandLine, command_line,
poly::countof(command_line) + 1);
std::memcpy(lpExLoadedCommandLine, command_line,
poly::countof(command_line) + 1);
// XboxKrnlVersion (8b)
// Kernel version, looks like 2b.2b.2b.2b.
// I've only seen games check >=, so we just fake something here.
uint32_t pXboxKrnlVersion = memory_->SystemHeapAlloc(8);
auto lpXboxKrnlVersion = memory_->TranslateVirtual(pXboxKrnlVersion);
export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::XboxKrnlVersion, pXboxKrnlVersion);
poly::store_and_swap<uint16_t>(mem + pXboxKrnlVersion + 0, 2);
poly::store_and_swap<uint16_t>(mem + pXboxKrnlVersion + 2, 0xFFFF);
poly::store_and_swap<uint16_t>(mem + pXboxKrnlVersion + 4, 0xFFFF);
poly::store_and_swap<uint8_t>(mem + pXboxKrnlVersion + 6, 0x80);
poly::store_and_swap<uint8_t>(mem + pXboxKrnlVersion + 7, 0x00);
poly::store_and_swap<uint16_t>(lpXboxKrnlVersion + 0, 2);
poly::store_and_swap<uint16_t>(lpXboxKrnlVersion + 2, 0xFFFF);
poly::store_and_swap<uint16_t>(lpXboxKrnlVersion + 4, 0xFFFF);
poly::store_and_swap<uint8_t>(lpXboxKrnlVersion + 6, 0x80);
poly::store_and_swap<uint8_t>(lpXboxKrnlVersion + 7, 0x00);
// KeTimeStampBundle (ad)
// This must be updated during execution, at 1ms intevals.
// We setup a system timer here to do that.
uint32_t pKeTimeStampBundle = memory_->SystemHeapAlloc(24);
auto lpKeTimeStampBundle = memory_->TranslateVirtual(pKeTimeStampBundle);
export_resolver_->SetVariableMapping(
"xboxkrnl.exe", ordinals::KeTimeStampBundle, pKeTimeStampBundle);
poly::store_and_swap<uint64_t>(mem + pKeTimeStampBundle + 0, 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 + 20, 0);
poly::store_and_swap<uint64_t>(lpKeTimeStampBundle + 0, 0);
poly::store_and_swap<uint64_t>(lpKeTimeStampBundle + 8, 0);
poly::store_and_swap<uint32_t>(lpKeTimeStampBundle + 16, GetTickCount());
poly::store_and_swap<uint32_t>(lpKeTimeStampBundle + 20, 0);
CreateTimerQueueTimer(
&timestamp_timer_, nullptr,
[](PVOID param, BOOLEAN timer_or_wait_fired) {
auto timestamp_bundle = reinterpret_cast<uint8_t*>(param);
poly::store_and_swap<uint32_t>(timestamp_bundle + 16, GetTickCount());
},
mem + pKeTimeStampBundle, 0,
lpKeTimeStampBundle, 0,
1, // 1ms
WT_EXECUTEINTIMERTHREAD);
}

View File

@@ -541,7 +541,7 @@ SHIM_CALL RtlEnterCriticalSection_shim(PPCContext* ppc_state,
// XELOGD("RtlEnterCriticalSection(%.8X)", cs_ptr);
const uint8_t* thread_state_block = ppc_state->membase + ppc_state->r[13];
const uint8_t* thread_state_block = SHIM_MEM_ADDR(ppc_state->r[13]);
uint32_t thread_id = XThread::GetCurrentThreadId(thread_state_block);
auto cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr);
@@ -583,7 +583,7 @@ SHIM_CALL RtlTryEnterCriticalSection_shim(PPCContext* ppc_state,
// XELOGD("RtlTryEnterCriticalSection(%.8X)", cs_ptr);
const uint8_t* thread_state_block = ppc_state->membase + ppc_state->r[13];
const uint8_t* thread_state_block = SHIM_MEM_ADDR(ppc_state->r[13]);
uint32_t thread_id = XThread::GetCurrentThreadId(thread_state_block);
auto cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr);

View File

@@ -62,11 +62,10 @@ void AssertNoNameCollision(KernelState* state, uint32_t obj_attributes_ptr) {
// with a success of NAME_EXISTS.
// If the name exists and its type doesn't match, we do NAME_COLLISION.
// Otherwise, we add like normal.
auto membase = state->memory()->membase();
uint32_t name_str_ptr =
poly::load_and_swap<uint32_t>(membase + obj_attributes_ptr + 4);
uint32_t name_str_ptr = poly::load_and_swap<uint32_t>(
state->memory()->TranslateVirtual(obj_attributes_ptr + 4));
if (name_str_ptr) {
X_ANSI_STRING name_str(membase, name_str_ptr);
X_ANSI_STRING name_str(state->memory()->virtual_membase(), name_str_ptr);
auto name = name_str.to_string();
X_HANDLE handle = X_INVALID_HANDLE_VALUE;
X_RESULT result = state->object_table()->GetObjectByName(name, &handle);

View File

@@ -447,7 +447,6 @@ void xe::kernel::xboxkrnl::RegisterVideoExports(ExportResolver* export_resolver,
SHIM_SET_MAPPING("xboxkrnl.exe", VdSwap, state);
Memory* memory = state->memory();
uint8_t* mem = memory->membase();
// VdGlobalDevice (4b)
// Pointer to a global D3D device. Games only seem to set this, so we don't
@@ -456,7 +455,7 @@ void xe::kernel::xboxkrnl::RegisterVideoExports(ExportResolver* export_resolver,
memory->SystemHeapAlloc(4, 32, kSystemHeapPhysical);
export_resolver->SetVariableMapping("xboxkrnl.exe", ordinals::VdGlobalDevice,
pVdGlobalDevice);
poly::store_and_swap<uint32_t>(mem + pVdGlobalDevice, 0);
poly::store_and_swap<uint32_t>(memory->TranslateVirtual(pVdGlobalDevice), 0);
// VdGlobalXamDevice (4b)
// Pointer to the XAM D3D device, which we don't have.
@@ -464,7 +463,8 @@ void xe::kernel::xboxkrnl::RegisterVideoExports(ExportResolver* export_resolver,
memory->SystemHeapAlloc(4, 32, kSystemHeapPhysical);
export_resolver->SetVariableMapping(
"xboxkrnl.exe", ordinals::VdGlobalXamDevice, pVdGlobalXamDevice);
poly::store_and_swap<uint32_t>(mem + pVdGlobalXamDevice, 0);
poly::store_and_swap<uint32_t>(memory->TranslateVirtual(pVdGlobalXamDevice),
0);
// VdGpuClockInMHz (4b)
// GPU clock. Xenos is 500MHz. Hope nothing is relying on this timing...
@@ -472,7 +472,8 @@ void xe::kernel::xboxkrnl::RegisterVideoExports(ExportResolver* export_resolver,
memory->SystemHeapAlloc(4, 32, kSystemHeapPhysical);
export_resolver->SetVariableMapping("xboxkrnl.exe", ordinals::VdGpuClockInMHz,
pVdGpuClockInMHz);
poly::store_and_swap<uint32_t>(mem + pVdGpuClockInMHz, 500);
poly::store_and_swap<uint32_t>(memory->TranslateVirtual(pVdGpuClockInMHz),
500);
// VdHSIOCalibrationLock (28b)
// CriticalSection.
@@ -481,7 +482,7 @@ void xe::kernel::xboxkrnl::RegisterVideoExports(ExportResolver* export_resolver,
export_resolver->SetVariableMapping(
"xboxkrnl.exe", ordinals::VdHSIOCalibrationLock, pVdHSIOCalibrationLock);
auto hsio_lock =
reinterpret_cast<X_RTL_CRITICAL_SECTION*>(mem + pVdHSIOCalibrationLock);
memory->TranslateVirtual<X_RTL_CRITICAL_SECTION*>(pVdHSIOCalibrationLock);
xeRtlInitializeCriticalSectionAndSpinCount(hsio_lock, pVdHSIOCalibrationLock,
10000);
}

View File

@@ -23,9 +23,8 @@ XObject::XObject(KernelState* kernel_state, Type type)
pointer_ref_count_(1),
type_(type),
handle_(X_INVALID_HANDLE_VALUE) {
// Added pointer check to support usage without a kernel_state
if (kernel_state != nullptr){
if (kernel_state != nullptr) {
kernel_state->object_table()->AddHandle(this, &handle_);
}
}
@@ -35,8 +34,6 @@ XObject::~XObject() {
assert_zero(pointer_ref_count_);
}
Memory* XObject::memory() const { return kernel_state_->memory(); }
XObject::Type XObject::type() { return type_; }
X_HANDLE XObject::handle() const { return handle_; }
@@ -78,7 +75,7 @@ void XObject::SetAttributes(const uint8_t* obj_attrs_ptr) {
uint32_t name_str_ptr = poly::load_and_swap<uint32_t>(obj_attrs_ptr + 4);
if (name_str_ptr) {
X_ANSI_STRING name_str(membase(), name_str_ptr);
X_ANSI_STRING name_str(memory()->virtual_membase(), name_str_ptr);
name_ = name_str.to_string();
kernel_state_->object_table()->AddNameMapping(name_, handle_);
}
@@ -157,8 +154,8 @@ X_STATUS XObject::WaitMultiple(uint32_t count, XObject** objects,
void XObject::SetNativePointer(uint32_t native_ptr) {
std::lock_guard<std::mutex> lock(kernel_state_->object_mutex());
DISPATCH_HEADER* header_be =
(DISPATCH_HEADER*)kernel_state_->memory()->Translate(native_ptr);
auto header_be =
kernel_state_->memory()->TranslateVirtual<DISPATCH_HEADER*>(native_ptr);
DISPATCH_HEADER header;
header.type_flags = poly::byte_swap(header_be->type_flags);
header.signal_state = poly::byte_swap(header_be->signal_state);

View File

@@ -13,7 +13,6 @@
#include <atomic>
#include "xenia/kernel/kernel_state.h"
#include "xenia/xbox.h"
namespace xe {
@@ -46,7 +45,7 @@ class XObject {
Emulator* emulator() const { return kernel_state_->emulator_; }
KernelState* kernel_state() const { return kernel_state_; }
uint8_t* membase() const { return kernel_state_->memory()->membase(); }
Memory* memory() const { return kernel_state_->memory(); }
Type type();
X_HANDLE handle() const;
@@ -79,7 +78,6 @@ class XObject {
virtual void* GetWaitHandle() { return 0; }
protected:
Memory* memory() const;
void SetNativePointer(uint32_t native_ptr);
static uint32_t TimeoutTicksToMs(int64_t timeout_ticks);