From 32056e2cfdbc82eb03def02267e16078867b09f8 Mon Sep 17 00:00:00 2001 From: emoose Date: Mon, 22 Oct 2018 17:27:07 +0100 Subject: [PATCH 1/4] [Kernel] Add more XConfig settings & --xconfig_initial_setup flag This just adds some extra XConfig settings that the dashboard tries to retrieve. The XCONFIG_USER_RETAIL_FLAGS setting gets used to decide whether to show the initial setup/OOBE wizard or not. Since the OOBE currently isn't usable in Xenia (mostly due to missing XamProfile* exports, afaik), this setting is by default set to skip it. But if that isn't desired the --xconfig_initial_setup flag can be used to un-set it. --- src/xenia/kernel/xboxkrnl/xboxkrnl_modules.cc | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_modules.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_modules.cc index d647e2f8c..ff3307ccc 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_modules.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_modules.cc @@ -16,6 +16,9 @@ #include "xenia/kernel/xboxkrnl/xboxkrnl_private.h" #include "xenia/xbox.h" +DEFINE_bool(xconfig_initial_setup, false, + "Enable the dashboard initial setup/OOBE"); + namespace xe { namespace kernel { namespace xboxkrnl { @@ -33,6 +36,9 @@ X_STATUS xeExGetXConfigSetting(uint16_t category, uint16_t setting, case 0x0002: // XCONFIG_SECURED_CATEGORY switch (setting) { + case 0x0001: // XCONFIG_SECURED_MAC_ADDRESS (6 bytes) + return X_STATUS_SUCCESS; // Just return, easier than setting up code + // for different size configs case 0x0002: // XCONFIG_SECURED_AV_REGION setting_size = 4; value = 0x00001000; // USA/Canada @@ -67,13 +73,25 @@ X_STATUS xeExGetXConfigSetting(uint16_t category, uint16_t setting, case 0x000C: // XCONFIG_USER_RETAIL_FLAGS setting_size = 4; // TODO(benvanik): get this value. - value = 0; + + // 0x40 = dashboard initial setup complete + value = FLAGS_xconfig_initial_setup ? 0 : 0x40; break; case 0x000E: // XCONFIG_USER_COUNTRY setting_size = 4; // TODO(benvanik): get this value. value = 0; break; + case 0x000F: // XCONFIG_USER_PC_FLAGS (parental control?) + setting_size = 1; + value = 0; + break; + case 0x0010: // XCONFIG_USER_SMB_CONFIG (0x100 byte string) + // Just set the start of the buffer to 0 so that callers + // don't error from an un-inited buffer + setting_size = 4; + value = 0; + break; default: assert_unhandled_case(setting); return X_STATUS_INVALID_PARAMETER_2; From 0e59c12cec36dc36ff75af297907120399d018fe Mon Sep 17 00:00:00 2001 From: emoose Date: Mon, 22 Oct 2018 17:29:27 +0100 Subject: [PATCH 2/4] [CPU] Add PVR register to mfspr PVR stores the processor/motherboard revision, the latest I could find seems to be 0x710800 which is probably a Corona. XShell tries to retrieve this during launch to print it on the console (search "XSHELL: CPUPVR" on pastebin for some examples) Xenia crashes because it's unimplemented, so I just made it return 0x710800. It could be worth moving this to be a constant somewhere though. IIRC hypervisor/kernel uses this for some things too, but since we don't emulate those it's not much of a problem, but there could still be other XEXs which use it for something. --- src/xenia/cpu/ppc/ppc_emit_control.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/xenia/cpu/ppc/ppc_emit_control.cc b/src/xenia/cpu/ppc/ppc_emit_control.cc index bdc7dd552..087e1f129 100644 --- a/src/xenia/cpu/ppc/ppc_emit_control.cc +++ b/src/xenia/cpu/ppc/ppc_emit_control.cc @@ -609,6 +609,10 @@ int InstrEmit_mfspr(PPCHIRBuilder& f, const InstrData& i) { // TBU v = f.Shr(f.LoadClock(), 32); break; + case 287: + // PVR + v = f.LoadConstantUint64(0x710800); + break; default: XEINSTRNOTIMPLEMENTED(); return 1; From 9309e1ac20da7878be159bcfad605ea01564ff2d Mon Sep 17 00:00:00 2001 From: emoose Date: Mon, 22 Oct 2018 17:32:03 +0100 Subject: [PATCH 3/4] [Base] Add more mount paths for the local directory This adds more mount paths for the XEX's local directory to Emulator::LaunchXexFile, so any XEXs that try to use these mountpoints can load files from the XEX directory. Mount points added: - \Device\Harddisk0\Partition0 - original mountpoint used by Xenia - \Device\Harddisk0\Partition1 - some games/apps seem to use this to refer to HDD1: - \Device\Harddisk0\Partition1\DEVKIT Used by xshell.xex, gets linked as E: (aka "development drive") Even if a DEVKIT folder exists inside the local folder, it seems we still have to add this mount point explicitly. - \Device\LauncherData Also used by xshell.xex for various UI resources The xlaunch.fdf file is normally mounted via DmMountFdfxVolume to this path (xlaunch.fdf is a FATX formatted container) By mounting this xshell can retrieve extracted resources from the local dir. - \SystemRoot Normally refers to the NAND, used by dash.xex to retrieve XZP resources when they aren't inside xam.xex. Other apps also use this to refer to other system XEXs/resources By mounting it we can just place any needed resources in the local dir. --- src/xenia/emulator.cc | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/xenia/emulator.cc b/src/xenia/emulator.cc index 19a82a85e..88e2abed5 100644 --- a/src/xenia/emulator.cc +++ b/src/xenia/emulator.cc @@ -245,24 +245,32 @@ X_STATUS Emulator::LaunchXexFile(std::wstring path) { // and then get that symlinked to game:\, so // -> game:\foo.xex - auto mount_path = "\\Device\\Harddisk0\\Partition0"; + // Register local directory as some commonly used mount paths + std::string mount_paths[] = { + "\\Device\\Harddisk0\\Partition0", + "\\Device\\Harddisk0\\Partition1", + "\\Device\\Harddisk0\\Partition1\\DEVKIT", + "\\Device\\LauncherData", + "\\SystemRoot", + }; - // Register the local directory in the virtual filesystem. auto parent_path = xe::find_base_path(path); - auto device = - std::make_unique(mount_path, parent_path, true); - if (!device->Initialize()) { - XELOGE("Unable to scan host path"); - return X_STATUS_NO_SUCH_FILE; - } - if (!file_system_->RegisterDevice(std::move(device))) { - XELOGE("Unable to register host path"); - return X_STATUS_NO_SUCH_FILE; + for (auto path : mount_paths) { + auto device = + std::make_unique(path, parent_path, true); + if (!device->Initialize()) { + XELOGE("Unable to scan host path"); + return X_STATUS_NO_SUCH_FILE; + } + if (!file_system_->RegisterDevice(std::move(device))) { + XELOGE("Unable to register host path as %s", path.c_str()); + return X_STATUS_NO_SUCH_FILE; + } } // Create symlinks to the device. - file_system_->RegisterSymbolicLink("game:", mount_path); - file_system_->RegisterSymbolicLink("d:", mount_path); + file_system_->RegisterSymbolicLink("game:", mount_paths[0]); + file_system_->RegisterSymbolicLink("d:", mount_paths[0]); // Get just the filename (foo.xex). auto file_name = xe::find_name_from_path(path); From e4f58afc460774b926db7fa0522857a9906b5671 Mon Sep 17 00:00:00 2001 From: emoose Date: Wed, 24 Oct 2018 00:18:15 +0100 Subject: [PATCH 4/4] [Kernel] Formatting fix inside xeExGetXConfigSetting --- src/xenia/kernel/xboxkrnl/xboxkrnl_modules.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_modules.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_modules.cc index ff3307ccc..203c1d0d1 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_modules.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_modules.cc @@ -39,7 +39,7 @@ X_STATUS xeExGetXConfigSetting(uint16_t category, uint16_t setting, case 0x0001: // XCONFIG_SECURED_MAC_ADDRESS (6 bytes) return X_STATUS_SUCCESS; // Just return, easier than setting up code // for different size configs - case 0x0002: // XCONFIG_SECURED_AV_REGION + case 0x0002: // XCONFIG_SECURED_AV_REGION setting_size = 4; value = 0x00001000; // USA/Canada break;