Implement kernel processes

This commit is contained in:
disjtqz
2023-10-12 15:34:27 -04:00
committed by Radosław Gliński
parent ba7397952d
commit a7b047b2a2
15 changed files with 338 additions and 227 deletions

View File

@@ -111,20 +111,31 @@ uint32_t ExCreateThread(xe::be<uint32_t>* handle_ptr, uint32_t stack_size,
// LPVOID StartContext,
// DWORD CreationFlags // 0x80?
auto kernel_state_var = kernel_state();
// xenia_assert((creation_flags & 2) == 0); // creating system thread?
if (creation_flags & 2) {
XELOGE("Guest is creating a system thread!");
}
uint32_t thread_process = (creation_flags & 2)
? kernel_state_var->GetSystemProcess()
: kernel_state_var->GetTitleProcess();
X_KPROCESS* target_process =
kernel_state_var->memory()->TranslateVirtual<X_KPROCESS*>(thread_process);
// Inherit default stack size
uint32_t actual_stack_size = stack_size;
if (actual_stack_size == 0) {
actual_stack_size = kernel_state()->GetExecutableModule()->stack_size();
actual_stack_size = target_process->kernel_stack_size;
}
// Stack must be aligned to 16kb pages
actual_stack_size =
std::max((uint32_t)0x4000, ((actual_stack_size + 0xFFF) & 0xFFFFF000));
auto thread = object_ref<XThread>(
new XThread(kernel_state(), actual_stack_size, xapi_thread_startup,
start_address, start_context, creation_flags, true));
auto thread = object_ref<XThread>(new XThread(
kernel_state(), actual_stack_size, xapi_thread_startup, start_address,
start_context, creation_flags, true, false, thread_process));
X_STATUS result = thread->Create();
if (XFAILED(result)) {
@@ -345,29 +356,42 @@ dword_result_t KeSetBasePriorityThread_entry(lpvoid_t thread_ptr,
}
DECLARE_XBOXKRNL_EXPORT1(KeSetBasePriorityThread, kThreading, kImplemented);
dword_result_t KeSetDisableBoostThread_entry(lpvoid_t thread_ptr,
dword_result_t KeSetDisableBoostThread_entry(pointer_t<X_KTHREAD> thread_ptr,
dword_t disabled) {
auto thread = XObject::GetNativeObject<XThread>(kernel_state(), thread_ptr);
if (thread) {
// Uhm?
}
// supposed to acquire dispatcher lock + a prcb lock, all just to exchange
// this char there is no other special behavior going on in this function,
// just acquiring locks to do this exchange
auto old_boost_disabled =
reinterpret_cast<std::atomic_uint8_t*>(&thread_ptr->boost_disabled)
->exchange(static_cast<uint8_t>(disabled));
return 0;
return old_boost_disabled;
}
DECLARE_XBOXKRNL_EXPORT1(KeSetDisableBoostThread, kThreading, kImplemented);
dword_result_t KeGetCurrentProcessType_entry() {
return kernel_state()->process_type();
uint32_t xeKeGetCurrentProcessType(cpu::ppc::PPCContext* context) {
auto pcr = context->TranslateVirtualGPR<X_KPCR*>(context->r[13]);
if (!pcr->prcb_data.dpc_active)
return context->TranslateVirtual(pcr->prcb_data.current_thread)
->process_type;
return pcr->processtype_value_in_dpc;
}
void xeKeSetCurrentProcessType(uint32_t type, cpu::ppc::PPCContext* context) {
auto pcr = context->TranslateVirtualGPR<X_KPCR*>(context->r[13]);
if (pcr->prcb_data.dpc_active) {
pcr->processtype_value_in_dpc = type;
}
}
dword_result_t KeGetCurrentProcessType_entry(const ppc_context_t& context) {
return xeKeGetCurrentProcessType(context);
}
DECLARE_XBOXKRNL_EXPORT2(KeGetCurrentProcessType, kThreading, kImplemented,
kHighFrequency);
void KeSetCurrentProcessType_entry(dword_t type) {
// One of X_PROCTYPE_?
assert_true(type <= 2);
kernel_state()->set_process_type(type);
void KeSetCurrentProcessType_entry(dword_t type, const ppc_context_t& context) {
xeKeSetCurrentProcessType(type, context);
}
DECLARE_XBOXKRNL_EXPORT1(KeSetCurrentProcessType, kThreading, kImplemented);
@@ -1108,7 +1132,7 @@ dword_result_t KfAcquireSpinLock_entry(pointer_t<X_KSPINLOCK> lock_ptr,
DECLARE_XBOXKRNL_EXPORT3(KfAcquireSpinLock, kThreading, kImplemented, kBlocking,
kHighFrequency);
void xeKeKfReleaseSpinLock(PPCContext* ctx, X_KSPINLOCK* lock, dword_t old_irql,
void xeKeKfReleaseSpinLock(PPCContext* ctx, X_KSPINLOCK* lock, uint32_t old_irql,
bool change_irql) {
assert_true(lock->prcb_of_owner == static_cast<uint32_t>(ctx->r[13]));
// Unlock.
@@ -1385,7 +1409,7 @@ static void YankApcList(PPCContext* ctx, X_KTHREAD* current_thread, unsigned apc
}
}
void xeRundownApcs(PPCContext* ctx) {
void xeRundownApcs(cpu::ppc::PPCContext* ctx) {
auto kpcr = ctx->TranslateVirtualGPR<X_KPCR*>(ctx->r[13]);
auto current_thread = ctx->TranslateVirtual(kpcr->prcb_data.current_thread);
@@ -1429,7 +1453,7 @@ uint32_t xeKeInsertQueueApc(XAPC* apc, uint32_t arg1, uint32_t arg2,
auto target_thread = context->TranslateVirtual<X_KTHREAD*>(apc->thread_ptr);
auto old_irql = xeKeKfAcquireSpinLock(context, &target_thread->apc_lock);
uint32_t result;
if (!target_thread->apc_related || apc->enqueued) {
if (!target_thread->may_queue_apcs || apc->enqueued) {
result = 0;
} else {
apc->arg1 = arg1;
@@ -1470,9 +1494,7 @@ uint32_t xeKeInsertQueueApc(XAPC* apc, uint32_t arg1, uint32_t arg2,
dword_result_t KeInsertQueueApc_entry(pointer_t<XAPC> apc, lpvoid_t arg1,
lpvoid_t arg2, dword_t priority_increment,
const ppc_context_t& context) {
return xeKeInsertQueueApc(apc, arg1, arg2, priority_increment, context);
}
DECLARE_XBOXKRNL_EXPORT1(KeInsertQueueApc, kThreading, kImplemented);
@@ -1480,7 +1502,6 @@ dword_result_t KeRemoveQueueApc_entry(pointer_t<XAPC> apc,
const ppc_context_t& context) {
bool result = false;
uint32_t thread_guest_pointer = apc->thread_ptr;
if (!thread_guest_pointer) {
return 0;

View File

@@ -63,13 +63,15 @@ uint32_t xeNtQueueApcThread(uint32_t thread_handle, uint32_t apc_routine,
void xeKfLowerIrql(PPCContext* ctx, unsigned char new_irql);
unsigned char xeKfRaiseIrql(PPCContext* ctx, unsigned char new_irql);
void xeKeKfReleaseSpinLock(PPCContext* ctx, X_KSPINLOCK* lock, dword_t old_irql, bool change_irql=true);
uint32_t xeKeKfAcquireSpinLock(PPCContext* ctx, X_KSPINLOCK* lock, bool change_irql=true);
void xeKeKfReleaseSpinLock(PPCContext* ctx, X_KSPINLOCK* lock, uint32_t old_irql, bool change_irql=true);
uint32_t xeKeKfAcquireSpinLock(PPCContext* ctx, X_KSPINLOCK* lock,
bool change_irql = true);
X_STATUS xeProcessUserApcs(PPCContext* ctx);
void xeRundownApcs(PPCContext* ctx);
uint32_t xeKeGetCurrentProcessType(PPCContext* context);
void xeKeSetCurrentProcessType(uint32_t type, PPCContext* context);
} // namespace xboxkrnl
} // namespace kernel
} // namespace xe