Best-guess process info block.

This commit is contained in:
Ben Vanik 2015-06-04 17:46:00 -07:00
parent f9742cc3eb
commit 52060af847
3 changed files with 82 additions and 3 deletions

View File

@ -48,7 +48,8 @@ KernelState::KernelState(Emulator* emulator)
memory_(emulator->memory()),
object_table_(nullptr),
has_notified_startup_(false),
process_type_(X_PROCTYPE_USER) {
process_type_(X_PROCTYPE_USER),
process_info_block_address_(0) {
processor_ = emulator->processor();
file_system_ = emulator->file_system();
@ -66,12 +67,29 @@ KernelState::KernelState(Emulator* emulator)
assert_null(shared_kernel_state_);
shared_kernel_state_ = this;
process_info_block_address_ = memory_->SystemHeapAlloc(0x60);
auto pib =
memory_->TranslateVirtual<ProcessInfoBlock*>(process_info_block_address_);
// TODO(benvanik): figure out what this list is.
pib->unk_04 = pib->unk_08 = 0;
pib->unk_0C = 0x0000007F;
pib->unk_10 = 0x001F0000;
pib->thread_count = 0;
pib->unk_1B = 0x06;
pib->kernel_stack_size = 16 * 1024;
// TODO(benvanik): figure out what this list is.
pib->unk_54 = pib->unk_58 = 0;
apps::RegisterApps(this, app_manager_.get());
}
KernelState::~KernelState() {
SetExecutableModule(nullptr);
if (process_info_block_address_) {
memory_->SystemHeapFree(process_info_block_address_);
}
executable_module_.reset();
user_modules_.clear();
kernel_modules_.clear();
@ -95,6 +113,18 @@ uint32_t KernelState::title_id() const {
return executable_module_->xex_header()->execution_info.title_id;
}
uint32_t KernelState::process_type() const {
auto pib =
memory_->TranslateVirtual<ProcessInfoBlock*>(process_info_block_address_);
return pib->process_type;
}
void KernelState::set_process_type(uint32_t value) {
auto pib =
memory_->TranslateVirtual<ProcessInfoBlock*>(process_info_block_address_);
pib->process_type = uint8_t(value);
}
void KernelState::RegisterModule(XModule* module) {}
void KernelState::UnregisterModule(XModule* module) {}
@ -148,6 +178,15 @@ void KernelState::SetExecutableModule(object_ref<XUserModule> module) {
return;
}
executable_module_ = std::move(module);
auto header = executable_module_->xex_header();
if (header) {
auto pib = memory_->TranslateVirtual<ProcessInfoBlock*>(
process_info_block_address_);
pib->tls_data_size = header->tls_info.data_size;
pib->tls_raw_data_size = header->tls_info.raw_data_size;
pib->tls_slot_size = header->tls_info.slot_count * 4;
}
}
void KernelState::LoadKernelModule(object_ref<XKernelModule> kernel_module) {
@ -209,6 +248,10 @@ object_ref<XUserModule> KernelState::LoadUserModule(const char* raw_name) {
void KernelState::RegisterThread(XThread* thread) {
std::lock_guard<xe::recursive_mutex> lock(object_mutex_);
threads_by_id_[thread->thread_id()] = thread;
auto pib =
memory_->TranslateVirtual<ProcessInfoBlock*>(process_info_block_address_);
pib->thread_count = pib->thread_count + 1;
}
void KernelState::UnregisterThread(XThread* thread) {
@ -217,6 +260,10 @@ void KernelState::UnregisterThread(XThread* thread) {
if (it != threads_by_id_.end()) {
threads_by_id_.erase(it);
}
auto pib =
memory_->TranslateVirtual<ProcessInfoBlock*>(process_info_block_address_);
pib->thread_count = pib->thread_count - 1;
}
void KernelState::OnThreadExecute(XThread* thread) {

View File

@ -44,6 +44,31 @@ class XNotifyListener;
class XThread;
class XUserModule;
struct ProcessInfoBlock {
xe::be<uint32_t> unk_00;
xe::be<uint32_t> unk_04; // blink
xe::be<uint32_t> unk_08; // flink
xe::be<uint32_t> unk_0C;
xe::be<uint32_t> unk_10;
xe::be<uint32_t> thread_count;
xe::be<uint8_t> unk_18;
xe::be<uint8_t> unk_19;
xe::be<uint8_t> unk_1A;
xe::be<uint8_t> unk_1B;
xe::be<uint32_t> kernel_stack_size;
xe::be<uint32_t> unk_20;
xe::be<uint32_t> tls_data_size;
xe::be<uint32_t> tls_raw_data_size;
xe::be<uint16_t> tls_slot_size;
xe::be<uint8_t> unk_2E;
xe::be<uint8_t> process_type;
xe::be<uint32_t> bitmap[0x20 / 4];
xe::be<uint32_t> unk_50;
xe::be<uint32_t> unk_54; // blink
xe::be<uint32_t> unk_58; // flink
xe::be<uint32_t> unk_5C;
};
class KernelState {
public:
KernelState(Emulator* emulator);
@ -67,8 +92,11 @@ class KernelState {
ObjectTable* object_table() const { return object_table_; }
xe::recursive_mutex& object_mutex() { return object_mutex_; }
uint32_t process_type() const { return process_type_; }
void set_process_type(uint32_t value) { process_type_ = value; }
uint32_t process_type() const;
void set_process_type(uint32_t value);
uint32_t process_info_block_address() const {
return process_info_block_address_;
}
void RegisterModule(XModule* module);
void UnregisterModule(XModule* module);
@ -126,6 +154,8 @@ class KernelState {
std::vector<object_ref<XKernelModule>> kernel_modules_;
std::vector<object_ref<XUserModule>> user_modules_;
uint32_t process_info_block_address_;
friend class XObject;
};

View File

@ -253,6 +253,8 @@ X_STATUS XThread::Create() {
xe::store_and_swap<uint32_t>(p + 0x078, thread_state_address_ + 0x074);
xe::store_and_swap<uint32_t>(p + 0x07C, thread_state_address_ + 0x07C);
xe::store_and_swap<uint32_t>(p + 0x080, thread_state_address_ + 0x07C);
xe::store_and_swap<uint32_t>(p + 0x084,
kernel_state_->process_info_block_address());
xe::store_and_swap<uint8_t>(p + 0x08B, 1);
// D4 = APC
// FC = semaphore (ptr, 0, 2)