Best-guess process info block.
This commit is contained in:
parent
f9742cc3eb
commit
52060af847
|
@ -48,7 +48,8 @@ KernelState::KernelState(Emulator* emulator)
|
||||||
memory_(emulator->memory()),
|
memory_(emulator->memory()),
|
||||||
object_table_(nullptr),
|
object_table_(nullptr),
|
||||||
has_notified_startup_(false),
|
has_notified_startup_(false),
|
||||||
process_type_(X_PROCTYPE_USER) {
|
process_type_(X_PROCTYPE_USER),
|
||||||
|
process_info_block_address_(0) {
|
||||||
processor_ = emulator->processor();
|
processor_ = emulator->processor();
|
||||||
file_system_ = emulator->file_system();
|
file_system_ = emulator->file_system();
|
||||||
|
|
||||||
|
@ -66,12 +67,29 @@ KernelState::KernelState(Emulator* emulator)
|
||||||
assert_null(shared_kernel_state_);
|
assert_null(shared_kernel_state_);
|
||||||
shared_kernel_state_ = this;
|
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());
|
apps::RegisterApps(this, app_manager_.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
KernelState::~KernelState() {
|
KernelState::~KernelState() {
|
||||||
SetExecutableModule(nullptr);
|
SetExecutableModule(nullptr);
|
||||||
|
|
||||||
|
if (process_info_block_address_) {
|
||||||
|
memory_->SystemHeapFree(process_info_block_address_);
|
||||||
|
}
|
||||||
|
|
||||||
executable_module_.reset();
|
executable_module_.reset();
|
||||||
user_modules_.clear();
|
user_modules_.clear();
|
||||||
kernel_modules_.clear();
|
kernel_modules_.clear();
|
||||||
|
@ -95,6 +113,18 @@ uint32_t KernelState::title_id() const {
|
||||||
return executable_module_->xex_header()->execution_info.title_id;
|
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::RegisterModule(XModule* module) {}
|
||||||
|
|
||||||
void KernelState::UnregisterModule(XModule* module) {}
|
void KernelState::UnregisterModule(XModule* module) {}
|
||||||
|
@ -148,6 +178,15 @@ void KernelState::SetExecutableModule(object_ref<XUserModule> module) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
executable_module_ = std::move(module);
|
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) {
|
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) {
|
void KernelState::RegisterThread(XThread* thread) {
|
||||||
std::lock_guard<xe::recursive_mutex> lock(object_mutex_);
|
std::lock_guard<xe::recursive_mutex> lock(object_mutex_);
|
||||||
threads_by_id_[thread->thread_id()] = thread;
|
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) {
|
void KernelState::UnregisterThread(XThread* thread) {
|
||||||
|
@ -217,6 +260,10 @@ void KernelState::UnregisterThread(XThread* thread) {
|
||||||
if (it != threads_by_id_.end()) {
|
if (it != threads_by_id_.end()) {
|
||||||
threads_by_id_.erase(it);
|
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) {
|
void KernelState::OnThreadExecute(XThread* thread) {
|
||||||
|
|
|
@ -44,6 +44,31 @@ class XNotifyListener;
|
||||||
class XThread;
|
class XThread;
|
||||||
class XUserModule;
|
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 {
|
class KernelState {
|
||||||
public:
|
public:
|
||||||
KernelState(Emulator* emulator);
|
KernelState(Emulator* emulator);
|
||||||
|
@ -67,8 +92,11 @@ class KernelState {
|
||||||
ObjectTable* object_table() const { return object_table_; }
|
ObjectTable* object_table() const { return object_table_; }
|
||||||
xe::recursive_mutex& object_mutex() { return object_mutex_; }
|
xe::recursive_mutex& object_mutex() { return object_mutex_; }
|
||||||
|
|
||||||
uint32_t process_type() const { return process_type_; }
|
uint32_t process_type() const;
|
||||||
void set_process_type(uint32_t value) { process_type_ = value; }
|
void set_process_type(uint32_t value);
|
||||||
|
uint32_t process_info_block_address() const {
|
||||||
|
return process_info_block_address_;
|
||||||
|
}
|
||||||
|
|
||||||
void RegisterModule(XModule* module);
|
void RegisterModule(XModule* module);
|
||||||
void UnregisterModule(XModule* module);
|
void UnregisterModule(XModule* module);
|
||||||
|
@ -126,6 +154,8 @@ class KernelState {
|
||||||
std::vector<object_ref<XKernelModule>> kernel_modules_;
|
std::vector<object_ref<XKernelModule>> kernel_modules_;
|
||||||
std::vector<object_ref<XUserModule>> user_modules_;
|
std::vector<object_ref<XUserModule>> user_modules_;
|
||||||
|
|
||||||
|
uint32_t process_info_block_address_;
|
||||||
|
|
||||||
friend class XObject;
|
friend class XObject;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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 + 0x078, thread_state_address_ + 0x074);
|
||||||
xe::store_and_swap<uint32_t>(p + 0x07C, thread_state_address_ + 0x07C);
|
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 + 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);
|
xe::store_and_swap<uint8_t>(p + 0x08B, 1);
|
||||||
// D4 = APC
|
// D4 = APC
|
||||||
// FC = semaphore (ptr, 0, 2)
|
// FC = semaphore (ptr, 0, 2)
|
||||||
|
|
Loading…
Reference in New Issue