diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index 94d0b94bd..60482e9a9 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -38,6 +38,9 @@ DEFINE_uint32(max_signed_profiles, 4, "Limits how many profiles can be assigned. Possible values: 1-4", "Kernel"); +DEFINE_uint32(kernel_build_version, 1888, "Define current kernel version", + "Kernel"); + namespace xe { namespace kernel { @@ -66,6 +69,7 @@ KernelState::KernelState(Emulator* emulator) user_profiles_.emplace(0, std::make_unique(0)); InitializeKernelGuestGlobals(); + kernel_version_ = KernelVersion(cvars::kernel_build_version); auto content_root = emulator_->content_root(); if (!content_root.empty()) { diff --git a/src/xenia/kernel/kernel_state.h b/src/xenia/kernel/kernel_state.h index 31939e816..370eae04d 100644 --- a/src/xenia/kernel/kernel_state.h +++ b/src/xenia/kernel/kernel_state.h @@ -48,6 +48,8 @@ namespace kernel { constexpr fourcc_t kKernelSaveSignature = make_fourcc("KRNL"); +static constexpr const uint16_t kBaseKernelBuildVersion = 1888; + // (?), used by KeGetCurrentProcessType constexpr uint32_t X_PROCTYPE_IDLE = 0; constexpr uint32_t X_PROCTYPE_TITLE = 1; @@ -145,6 +147,27 @@ struct KernelGuestGlobals { struct DPCImpersonationScope { uint8_t previous_irql_; }; + +struct KernelVersion { + union { + xe::be value; + + struct { + xe::be major; + xe::be minor; + xe::be build; + xe::be qfe; + }; + }; + + KernelVersion(uint16_t build_ver = kBaseKernelBuildVersion) { + major = 2; + minor = 0; + build = std::max(kBaseKernelBuildVersion, build_ver); + qfe = 0; + } +}; + class KernelState { public: explicit KernelState(Emulator* emulator); @@ -200,6 +223,8 @@ class KernelState { // Access must be guarded by the global critical region. util::ObjectTable* object_table() { return &object_table_; } + const KernelVersion* GetKernelVersion() const { return &kernel_version_; } + uint32_t GetSystemProcess() const { return kernel_guest_globals_ + offsetof(KernelGuestGlobals, system_process); } @@ -332,6 +357,8 @@ class KernelState { std::map> user_profiles_; std::unique_ptr achievement_manager_; + KernelVersion kernel_version_; + xe::global_critical_region global_critical_region_; // Must be guarded by the global critical region. diff --git a/src/xenia/kernel/xbdm/xbdm_misc.cc b/src/xenia/kernel/xbdm/xbdm_misc.cc index fa3bf857a..f972499c7 100644 --- a/src/xenia/kernel/xbdm/xbdm_misc.cc +++ b/src/xenia/kernel/xbdm/xbdm_misc.cc @@ -13,8 +13,10 @@ #include "xenia/kernel/xbdm/xbdm_private.h" #include "xenia/kernel/xthread.h" #include "xenia/xbox.h" + // chrispy: no idea what a real valid value is for this static constexpr const char DmXboxName[] = "Xbox360Name"; + namespace xe { namespace kernel { namespace xbdm { @@ -142,8 +144,8 @@ dword_result_t DmGetSystemInfo_entry(pointer_t info) { info->base_kernel_version.minor = info->kernel_version.minor = 0; info->base_kernel_version.qfe = info->kernel_version.qfe = 0; - info->base_kernel_version.build = 1888; - info->kernel_version.build = 13139; + info->base_kernel_version.build = kBaseKernelBuildVersion; + info->kernel_version.build = kernel_state()->GetKernelVersion()->build; return XBDM_SUCCESSFUL; } diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_module.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_module.cc index 78f82db06..be5e9ac75 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_module.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_module.cc @@ -205,15 +205,12 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) // 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); + uint32_t pXboxKrnlVersion = memory_->SystemHeapAlloc(sizeof(KernelVersion)); auto lpXboxKrnlVersion = memory_->TranslateVirtual(pXboxKrnlVersion); export_resolver_->SetVariableMapping( "xboxkrnl.exe", ordinals::XboxKrnlVersion, pXboxKrnlVersion); - xe::store_and_swap(lpXboxKrnlVersion + 0, 2); - xe::store_and_swap(lpXboxKrnlVersion + 2, 0xFFFF); - xe::store_and_swap(lpXboxKrnlVersion + 4, 0xFFFF); - xe::store_and_swap(lpXboxKrnlVersion + 6, 0x80); - xe::store_and_swap(lpXboxKrnlVersion + 7, 0x00); + std::memcpy(lpXboxKrnlVersion, kernel_state_->GetKernelVersion(), + sizeof(KernelVersion)); export_resolver_->SetVariableMapping("xboxkrnl.exe", ordinals::KeTimeStampBundle,