1 /*---------------------------------------------------------------------------* 2 3 Copyright 2010-2012 Nintendo. All rights reserved. 4 5 These coded instructions, statements, and computer programs contain 6 proprietary information of Nintendo of America Inc. and/or Nintendo 7 Company Ltd., and are protected by Federal copyright law. They may 8 not be disclosed to third parties or copied or duplicated in any form, 9 in whole or in part, without the prior written consent of Nintendo. 10 11 *---------------------------------------------------------------------------*/ 12 using System; 13 using System.Text; 14 using System.Collections; 15 using System.Collections.Generic; 16 using System.Diagnostics; 17 using System.IO; 18 using System.Threading; 19 using System.Runtime.InteropServices; 20 using System.Text.RegularExpressions; 21 using System.Reflection; 22 using System.ComponentModel; 23 24 25 namespace CafeX 26 { 27 partial class Program 28 { 29 #region environment variables 30 31 internal static EnvVar CAFE_ROOT = new EnvVar("CAFE_ROOT"); 32 internal static EnvVar SDIO_BRIDGE_TOOLS = new EnvVar("SDIO_BRIDGE_TOOLS"); 33 internal static EnvVar MION_BRIDGE_TOOLS = new EnvVar("MION_BRIDGE_TOOLS"); 34 internal static EnvVar BRIDGE_CURRENT_NAME = new EnvVar("BRIDGE_CURRENT_NAME"); 35 internal static EnvVar BRIDGE_CURRENT_IP_ADDRESS = new EnvVar("BRIDGE_CURRENT_IP_ADDRESS"); 36 37 internal static EnvVar PLATFORM = new EnvVar("PLATFORM"); 38 internal static EnvVar CAFESTOP_STATUS = new EnvVar("CAFESTOP_STATUS"); 39 internal static EnvVar CAFERUN_OPTION_SOFT_LAUNCH = new EnvVar("CAFERUN_OPTION_SOFT_LAUNCH"); 40 internal static EnvVar CAFERUN_OPTION_FAST_RELAUNCH = new EnvVar("CAFERUN_OPTION_FAST_RELAUNCH"); 41 internal static EnvVar HOSTSTOP_RVAL = new EnvVar("HOSTSTOP_RVAL"); 42 internal static EnvVar HOSTSTOP_RETRIES = new EnvVar("HOSTSTOP_RETRIES"); 43 internal static EnvVar HOSTSTOP_RESET_OPTION = new EnvVar("HOSTSTOP_RESET_OPTION"); 44 internal static EnvVar CAFE_HARDWARE = new EnvVar("CAFE_HARDWARE"); 45 internal static EnvVar MION_PWR_SEQ = new EnvVar("MION_PWR_SEQ"); 46 internal static EnvVar BRIDGE_TYPE = new EnvVar("BRIDGE_TYPE"); 47 internal static EnvVar TMP = new EnvVar("TMP"); 48 49 internal static EnvVar SESSION_MANAGER = new EnvVar("SESSION_MANAGER"); 50 internal static EnvVar SESSION_NAME = new EnvVar("SESSION_NAME"); 51 internal static EnvVar SESSION_DEBUG_OUT_PORT = new EnvVar("SESSION_DEBUG_OUT_PORT"); 52 internal static EnvVar SESSION_DEBUG_CONTROL_PORT = new EnvVar("SESSION_DEBUG_CONTROL_PORT"); 53 internal static EnvVar SESSION_HIO_OUT_PORT = new EnvVar("SESSION_HIO_OUT_PORT"); 54 internal static EnvVar SESSION_LAUNCH_CTRL_PORT = new EnvVar("SESSION_LAUNCH_CTRL_PORT"); 55 internal static EnvVar SESSION_NET_MANAGE_PORT = new EnvVar("SESSION_NET_MANAGE_PORT"); 56 internal static EnvVar SESSION_PCFS_SATA_PORT = new EnvVar("SESSION_PCFS_SATA_PORT"); 57 internal static EnvVar SESSION_PATH_PREFIX = new EnvVar("SESSION_PATH_PREFIX"); 58 59 internal static EnvVar CAFE_DATA_DIR = new EnvVar("CAFE_DATA_DIR"); 60 internal static EnvVar CAFE_CONTENT_DIR = new EnvVar("CAFE_CONTENT_DIR"); 61 internal static EnvVar CAFE_META_DIR = new EnvVar("CAFE_META_DIR"); 62 internal static EnvVar CAFE_SAVE_DIR = new EnvVar("CAFE_SAVE_DIR"); 63 internal static EnvVar CAFE_SLC_DIR = new EnvVar("CAFE_SLC_DIR"); 64 internal static EnvVar CAFE_MLC_DIR = new EnvVar("CAFE_MLC_DIR"); 65 internal static EnvVar CAFE_DATA_TMP = new EnvVar("CAFE_DATA_TMP"); 66 67 internal static EnvVar LANG = new EnvVar("LANG"); 68 internal static EnvVar QUIET = new EnvVar("QUIET"); 69 internal static EnvVar NO_CONSOLE = new EnvVar("NO_CONSOLE"); 70 internal static EnvVar CAFESTOP_ONLY_IF_FSEMUL = new EnvVar("CAFESTOP_ONLY_IF_FSEMUL"); 71 internal static EnvVar PPC_OS_FLAGS = new EnvVar("PPC_OS_FLAGS"); 72 internal static EnvVar PPC_APP_FLAGS = new EnvVar("PPC_APP_FLAGS"); 73 internal static EnvVar PCFS_SYNC_DATE = new EnvVar("PCFS_SYNC_DATE"); 74 internal static EnvVar MCP_LAUNCH_HINT = new EnvVar("MCP_LAUNCH_HINT"); 75 internal static EnvVar MCP_INFO_OPTION = new EnvVar("MCP_INFO_OPTION"); 76 internal static EnvVar IGNORE_VERSION = new EnvVar("IGNORE_VERSION"); 77 internal static EnvVar DEBUGGER = new EnvVar("DEBUGGER"); 78 internal static EnvVar CAFE_CONSOLE = new EnvVar("CAFE_CONSOLE"); 79 internal static EnvVar CONSOLE = new EnvVar("CONSOLE"); 80 internal static EnvVar CAFE_DEBUG_PORT = new EnvVar("CAFE_DEBUG_PORT"); 81 internal static EnvVar DEBUG_ELF_FILE = new EnvVar("DEBUG_ELF_FILE"); 82 internal static EnvVar CAFERUN_OPTION_SOFT_RESTART = new EnvVar("CAFERUN_OPTION_SOFT_RESTART"); 83 internal static EnvVar CAFE_TEST_SELF_REFRESH = new EnvVar("CAFE_TEST_SELF_REFRESH"); 84 internal static EnvVar CAFERUN_OPTION_MLC_EMU_LAUNCH = new EnvVar("CAFERUN_OPTION_MLC_EMU_LAUNCH"); 85 internal static EnvVar CAFERUN_OPTION_MLC_EMU_TITLEID = new EnvVar("CAFERUN_OPTION_MLC_EMU_TITLEID"); 86 internal static EnvVar CAFERUN_OS_MAJOR_VERSION_LO = new EnvVar("CAFERUN_OS_MAJOR_VERSION_LO"); 87 internal static EnvVar CAFERUN_OS_MAJOR_VERSION = new EnvVar("CAFERUN_OS_MAJOR_VERSION"); 88 internal static EnvVar CAFERUN_COLDBOOT_OS_VERSION = new EnvVar("CAFERUN_COLDBOOT_OS_VERSION"); 89 internal static EnvVar HEARTBEAT_DISABLE = new EnvVar("HEARTBEAT_DISABLE"); 90 internal static EnvVar PCFS_DIR_MAPPING = new EnvVar("PCFS_DIR_MAPPING"); 91 internal static EnvVar MAPDIR_MLC = new EnvVar("MAPDIR_MLC"); 92 internal static EnvVar MAPDIR_SLC = new EnvVar("MAPDIR_SLC"); 93 internal static EnvVar MAPDIR_CODE = new EnvVar("MAPDIR_CODE"); 94 internal static EnvVar MAPDIR_META = new EnvVar("MAPDIR_META"); 95 internal static EnvVar MAPDIR_CONTENT = new EnvVar("MAPDIR_CONTENT"); 96 internal static EnvVar MAPDIR_SAVE = new EnvVar("MAPDIR_SAVE"); 97 internal static EnvVar PCFS_LOG_TIMESTAMP = new EnvVar("PCFS_LOG_TIMESTAMP"); 98 internal static EnvVar PCFS_SRV_LOG_OUTPUT = new EnvVar("PCFS_SRV_LOG_OUTPUT"); 99 internal static EnvVar RUN_FROM_HDD_BANK = new EnvVar("RUN_FROM_HDD_BANK"); 100 internal static EnvVar EJECT_STATE = new EnvVar("EJECT_STATE"); 101 internal static EnvVar BRIDGE_PARAMETERS = new EnvVar("BRIDGE_PARAMETERS"); 102 internal static EnvVar BRIDGE_PARAMETERS_WITH_E = new EnvVar("BRIDGE_PARAMETERS_WITH_E"); 103 internal static EnvVar PCFSSERVER_PARAMETERS = new EnvVar("PCFSSERVER_PARAMETERS"); 104 internal static EnvVar PCFS_OVER_SATA_PORT = new EnvVar("PCFS_OVER_SATA_PORT"); 105 internal static EnvVar PREPHDD_STAT = new EnvVar("PREPHDD_STAT"); 106 internal static EnvVar DISC_EMU_TID = new EnvVar("DISC_EMU_TID"); 107 internal static EnvVar SYSTEM_MODE = new EnvVar("SYSTEM_MODE"); 108 internal static EnvVar RPL_DIRS = new EnvVar("RPL_DIRS"); 109 internal static EnvVar RPL_FILES = new EnvVar("RPL_FILES"); 110 internal static EnvVar CAFERUN_OPTION_NO_DATA_SYNC = new EnvVar("CAFERUN_OPTION_NO_DATA_SYNC"); 111 internal static EnvVar CAFE_BOOT_MODE = new EnvVar("CAFE_BOOT_MODE"); 112 internal static EnvVar CAFERUN_HOSTBRIDGE_VERSION = new EnvVar("CAFERUN_HOSTBRIDGE_VERSION"); 113 internal static EnvVar CAFERUN_FW_VERSION = new EnvVar("CAFERUN_FW_VERSION"); 114 internal static EnvVar CAFE_DEBUG_INIT = new EnvVar("CAFE_DEBUG_INIT"); 115 internal static EnvVar CAFE_DEBUG_PREINIT = new EnvVar("CAFE_DEBUG_PREINIT"); 116 internal static EnvVar CAFE_DEBUG_DONTSTOP = new EnvVar("CAFE_DEBUG_DONTSTOP"); 117 internal static EnvVar CAFE_LAUNCH_DEBUG = new EnvVar("CAFE_LAUNCH_DEBUG"); 118 internal static EnvVar CAFE_SYSLOG_LEVEL = new EnvVar("CAFE_SYSLOG_LEVEL"); 119 internal static EnvVar CAFE_RUN_FORCERESTART = new EnvVar("CAFE_RUN_FORCERESTART"); 120 internal static EnvVar DEBUG_PROC_ID = new EnvVar("DEBUG_PROC_ID"); 121 internal static EnvVar DEBUG_FLAGS = new EnvVar("DEBUG_FLAGS"); 122 internal static EnvVar CATOUTPUT = new EnvVar("CATOUTPUT"); 123 internal static EnvVar CMDOUTPUT = new EnvVar("CMDOUTPUT"); 124 internal static EnvVar CAFE_AUTOTEST = new EnvVar("CAFE_AUTOTEST"); 125 internal static EnvVar YOSHIS_COOKIE = new EnvVar("YOSHIS_COOKIE"); 126 internal static EnvVar CAFERUN_APP_TYPE = new EnvVar("CAFERUN_APP_TYPE"); 127 128 internal static EnvVar DASH_A_ARGS = new EnvVar("DASH_A_ARGS"); 129 internal static EnvVar ARGS_WITH_BARS = new EnvVar("ARGS_WITH_BARS"); 130 internal static EnvVar DISC_EMU_TYPE = new EnvVar("DISC_EMU_TYPE"); 131 internal static EnvVar APP_XML_FILE = new EnvVar("APP_XML_FILE"); 132 133 internal static EnvVar USE_PCFS_OVER_SATA = new EnvVar("USE_PCFS_OVER_SATA"); 134 internal static EnvVar CAFERUN_OPTION_CALLED_FROM_CAFEDISCRUN = new EnvVar("CAFERUN_OPTION_CALLED_FROM_CAFEDISCRUN"); 135 internal static EnvVar SYSTEM_XML = new EnvVar("SYSTEM_XML"); 136 //internal static EnvVar TEMP = new EnvVar("TEMP"); 137 internal static EnvVar CAFE_TEMP = new EnvVar("CAFE_TEMP"); 138 internal static EnvVar CAFERUN_WORK_DIR = new EnvVar("CAFERUN_WORK_DIR"); 139 140 internal static EnvVar SYNCTOOL_SRC = new EnvVar("SYNCTOOL_SRC"); 141 internal static EnvVar SYNCTOOL_DEST = new EnvVar("SYNCTOOL_DEST"); 142 internal static EnvVar SYNCTOOL_CFG = new EnvVar("SYNCTOOL_CFG"); 143 internal static EnvVar SYNCTOOL_LOG = new EnvVar("SYNCTOOL_LOG"); 144 145 internal static EnvVar CAFE_ELF = new EnvVar("CAFE_ELF"); 146 internal static EnvVar CAFE_ELF_SRC_DIR = new EnvVar("CAFE_ELF_SRC_DIR"); 147 internal static EnvVar CAFE_ELF_DIR = new EnvVar("CAFE_ELF_DIR"); 148 internal static EnvVar CAFE_CODE_DIR = new EnvVar("CAFE_CODE_DIR"); 149 internal static EnvVar COS_XML_FILE = new EnvVar("COS_XML_FILE"); 150 internal static EnvVar META_XML_FILE = new EnvVar("META_XML_FILE"); 151 152 internal static EnvVar PREV_CAFE_ARGSTR = new EnvVar("PREV_CAFE_ARGSTR"); 153 internal static EnvVar CAFERUN_OS_VERSION_PARTIAL_UNIQUE_ID = new EnvVar("CAFERUN_OS_VERSION_PARTIAL_UNIQUE_ID"); 154 internal static EnvVar PCFS_SRV_LOG_DIR = new EnvVar("PCFS_SRV_LOG_DIR"); 155 internal static EnvVar CMD_RESULT = new EnvVar("CMD_RESULT"); 156 157 internal static EnvVar CAFERUN_COLDBOOT_OS_VERSION_HI = new EnvVar("CAFERUN_COLDBOOT_OS_VERSION_HI"); 158 internal static EnvVar CAFERUN_COLDBOOT_OS_VERSION_LO = new EnvVar("CAFERUN_COLDBOOT_OS_VERSION_LO"); 159 internal static EnvVar BOOTRUN_WORK_DIR = new EnvVar("BOOTRUN_WORK_DIR"); 160 internal static EnvVar BOOTRUN_USE_RECOVERY_IMAGE = new EnvVar("BOOTRUN_USE_RECOVERY_IMAGE"); 161 internal static EnvVar WUMAD_WORK_DIR = new EnvVar("WUMAD_WORK_DIR"); 162 internal static EnvVar FIRMWARE_FILE = new EnvVar("FIRMWARE_FILE"); 163 internal static EnvVar TOOLCHAIN = new EnvVar("TOOLCHAIN"); 164 internal static EnvVar CAFE_SECURITY = new EnvVar("CAFE_SECURITY"); 165 internal static EnvVar BOOT_DLF_FILE = new EnvVar("BOOT_DLF_FILE"); 166 internal static EnvVar CAFE_WUMAD = new EnvVar("CAFE_WUMAD"); 167 168 internal static EnvVar CAFEMAKEDLF = new EnvVar("CAFEMAKEDLF"); 169 internal static EnvVar APP_TITLE_ID = new EnvVar("APP_TITLE_ID"); 170 internal static EnvVar APP_GROUP_ID = new EnvVar("APP_GROUP_ID"); 171 internal static EnvVar APP_TITLE_VERSION = new EnvVar("APP_TITLE_VERSION"); 172 internal static EnvVar CAFEDEVRUN_FILE = new EnvVar("CAFEDEVRUN_FILE"); 173 internal static EnvVar CAFEDEVRUN_EXT = new EnvVar("CAFEDEVRUN_EXT"); 174 internal static EnvVar CAFEDEVRUN_NAME = new EnvVar("CAFEDEVRUN_NAME"); 175 internal static EnvVar CAFEDEVRUN_FILENAME = new EnvVar("CAFEDEVRUN_FILENAME"); 176 internal static EnvVar CAFEDEVRUN_DIR = new EnvVar("CAFEDEVRUN_DIR"); 177 internal static EnvVar CAFEDEVRUN_WORK_DIR = new EnvVar("CAFEDEVRUN_WORK_DIR"); 178 internal static EnvVar INCLUDE_SYSTEM_DIR = new EnvVar("INCLUDE_SYSTEM_DIR"); 179 internal static EnvVar CAFE_BASEFILE_PATH = new EnvVar("CAFE_BASEFILE_PATH"); 180 internal static EnvVar DEFAULT_DDF = new EnvVar("DEFAULT_DDF"); 181 internal static EnvVar COMMON_DDF_FILE = new EnvVar("COMMON_DDF_FILE"); 182 internal static EnvVar INDIVIDUAL_DDF_FILE = new EnvVar("INDIVIDUAL_DDF_FILE"); 183 184 internal static EnvVar FSEMUL_PARAMS = new EnvVar("FSEMUL_PARAMS"); 185 internal static EnvVar BRIDGE_INSTALL_PATH = new EnvVar("BRIDGE_INSTALL_PATH"); 186 internal static EnvVar CAFE_DETACH_FSEMUL = new EnvVar("CAFE_DETACH_FSEMUL"); 187 188 internal static EnvVar MULTIELF = new EnvVar("MULTIELF"); 189 internal static EnvVar CATTOUCAN_STATUS = new EnvVar("CATTOUCAN_STATUS"); 190 internal static EnvVar MULTI_CONNECT = new EnvVar("MULTI_CONNECT"); 191 internal static EnvVar CAFE_MULTI_INIT = new EnvVar("CAFE_MULTI_INIT"); 192 internal static EnvVar GHS_ROOT = new EnvVar("GHS_ROOT"); 193 194 internal static EnvVar CAFEON_DISABLE_BGD = new EnvVar("CAFEON_DISABLE_BGD"); 195 internal static EnvVar CAFEON_NOBGD_META = new EnvVar("CAFEON_NOBGD_META"); 196 internal static EnvVar CAFEON_OPTION_NO_DATA_SYNC = new EnvVar("CAFEON_OPTION_NO_DATA_SYNC"); 197 internal static EnvVar AUTOTEST_RUNNING = new EnvVar("AUTOTEST_RUNNING"); 198 internal static EnvVar CAFE_RUN_RUNNING = new EnvVar("CAFE_RUN_RUNNING"); 199 internal static EnvVar CAFERUN_INS = new EnvVar("CAFERUN_INS"); 200 internal static EnvVar CATTOUCAN_TERM = new EnvVar("CATTOUCAN_TERM"); 201 internal static EnvVar OS_VERSION_LO = new EnvVar("OS_VERSION_LO"); 202 203 internal static EnvVar SDK_VER = new EnvVar("SDK_VER"); 204 internal static EnvVar SDK_MAJ_VER = new EnvVar("SDK_MAJ_VER"); 205 internal static EnvVar SDK_MIN_VER = new EnvVar("SDK_MIN_VER"); 206 internal static EnvVar SDK_MIC_VER = new EnvVar("SDK_MIC_VER"); 207 208 internal static EnvVar CAFEUPDATE_USE_SYSTEM_UPDATER = new EnvVar("CAFEUPDATE_USE_SYSTEM_UPDATER"); 209 internal static EnvVar CAFEUPDATE_TITLE = new EnvVar("CAFEUPDATE_TITLE"); 210 internal static EnvVar CAFEUPDATE_PACKAGE = new EnvVar("CAFEUPDATE_PACKAGE"); 211 internal static EnvVar CAFEUPDATE_PACKAGE_DEFAULT = new EnvVar("CAFEUPDATE_PACKAGE_DEFAULT"); 212 213 internal static EnvVar SCRIPT_EXE_TIMESTAMP = new EnvVar("SCRIPT_EXE_TIMESTAMP"); 214 internal static EnvVar LOGDIR = new EnvVar("LOGDIR"); 215 internal static EnvVar _CCRSYSCFG1 = new EnvVar("_CCRSYSCFG1"); 216 internal static EnvVar MONITOR_DEFAULT_TIMEOUT = new EnvVar("MONITOR_DEFAULT_TIMEOUT"); 217 internal static EnvVar COMPORTS_SUPPORT = new EnvVar("COMPORTS_SUPPORT"); 218 internal static EnvVar INITIALIZED_COMPORTS = new EnvVar("INITIALIZED_COMPORTS"); 219 internal static EnvVar MONITOR_FOR_OUTPUT_CALLS = new EnvVar("MONITOR_FOR_OUTPUT_CALLS"); 220 221 internal static EnvVar MON_RESULT_PASS = new EnvVar("MON_RESULT_PASS"); 222 internal static EnvVar MON_RESULT_TIMEOUT = new EnvVar("MON_RESULT_TIMEOUT"); 223 internal static EnvVar MON_RESULT_UNDEF = new EnvVar("MON_RESULT_UNDEF"); 224 internal static EnvVar MON_RESULT_MANUAL = new EnvVar("MON_RESULT_MANUAL"); 225 internal static EnvVar MON_RESULT_NOLOG = new EnvVar("MON_RESULT_NOLOG"); 226 internal static EnvVar MON_RESULT_FAIL = new EnvVar("MON_RESULT_FAIL"); 227 internal static EnvVar MON_RESULT_EXPECTED_TERM = new EnvVar("MON_RESULT_EXPECTED_TERM"); 228 internal static EnvVar MON_RESULT_EXEC_WIN_APP = new EnvVar("MON_RESULT_EXEC_WIN_APP"); 229 internal static EnvVar MON_RESULT_NOPPC = new EnvVar("MON_RESULT_NOPPC"); 230 internal static EnvVar MON_RESULT_BOOT1 = new EnvVar("MON_RESULT_BOOT1"); 231 internal static EnvVar MON_RESULT_RESTART = new EnvVar("MON_RESULT_RESTART"); 232 internal static EnvVar MON_RESULT_TEST_AS_RPL = new EnvVar("MON_RESULT_TEST_AS_RPL"); 233 internal static EnvVar MON_RESULT_END_OF_RPL_LOADER = new EnvVar("MON_RESULT_END_OF_RPL_LOADER"); 234 internal static EnvVar MON_RESULT_BRIDGE_COLLISION = new EnvVar("MON_RESULT_BRIDGE_COLLISION"); 235 internal static EnvVar MON_RESULT_TEST_DBG_OUT = new EnvVar("MON_RESULT_TEST_DBG_OUT"); 236 internal static EnvVar MON_RESULT_BRIDGE_OFF = new EnvVar("MON_RESULT_BRIDGE_OFF"); 237 internal static EnvVar MON_RESULT_ERROR = new EnvVar("MON_RESULT_ERROR"); 238 internal static EnvVar MON_RESULT_SKIP = new EnvVar("MON_RESULT_SKIP"); 239 internal static EnvVar MON_RESULT_FATAL_ERROR = new EnvVar("MON_RESULT_FATA_ERROR"); 240 internal static EnvVar MON_RESULT_MISSING = new EnvVar("MON_RESULT_MISSING"); 241 internal static EnvVar MON_RESULT_ABORTED = new EnvVar("MON_RESULT_ABORTED"); 242 internal static EnvVar MON_RESULT_KILL_AUTOTEST = new EnvVar("MON_RESULT_KILL_AUTOTEST"); 243 internal static EnvVar SYNCTOOL_RVAL = new EnvVar("SYNCTOOL_RVAL"); 244 245 internal static EnvVar PATH = new EnvVar("PATH"); 246 247 internal static EnvVar PCFS_HEADLESS_EMUL = new EnvVar("PCFS_HEADLESS_EMUL"); 248 internal static EnvVar TMP_SUB_DIR = new EnvVar("TMP_SUB_DIR"); 249 internal static EnvVar PCFSSERVERSYNC_RVAL = new EnvVar("PCFSSERVERSYNC_RVAL"); 250 251 internal static EnvVar CAFE_RUN_DEBUG = new EnvVar("CAFE_RUN_DEBUG"); 252 253 internal static EnvVar CYGWIN_PATH = new EnvVar("CYGWIN_PATH"); 254 255 internal static EnvVar CAFEX_STDIN_ENCODING = new EnvVar("CAFEX_STDIN_ENCODING"); 256 internal static EnvVar CAFEX_STDOUT_ENCODING = new EnvVar("CAFEX_STDOUT_ENCODING"); 257 internal static EnvVar CAFE_OUTPUT_ENCODING = new EnvVar("CAFE_OUTPUT_ENCODING"); 258 259 //disrun in NAND mode 260 internal static EnvVar ALLOW_DISCRUN_IN_SOFTLAUNCH = new EnvVar("ALLOW_DISCRUN_IN_SOFTLAUNCH"); 261 internal static EnvVar BOOTRUN_ELF_OPT = new EnvVar("BOOTRUN_ELF_OPT"); 262 internal static EnvVar BOOTRUN_ELF_VALUE = new EnvVar("BOOTRUN_ELF_VALUE"); 263 internal static EnvVar ELF_NEST_OPT = new EnvVar("ELF_NEST_OPT"); 264 internal static EnvVar ELF_NEST_VALUE = new EnvVar("ELF_NEST_VALUE"); 265 internal static EnvVar SOFT_LAUNCH_CAFE_ELF = new EnvVar("SOFT_LAUNCH_CAFE_ELF"); 266 internal static EnvVar CAFERUN_WUMAD_TITLE_ID = new EnvVar("CAFERUN_WUMAD_TITLE_ID"); 267 268 // Discrun OS mismatch checking 269 internal static EnvVar SKIP_OS_CHECK = new EnvVar("SKIP_OS_CHECK"); 270 271 // EXI debug 272 internal static EnvVar USE_EXI_AS_DEBUG_CHANNEL = new EnvVar("USE_EXI_AS_DEBUG_CHANNEL"); 273 274 // Fast launch 275 internal static EnvVar CAFERUN_OPTION_FASTLAUNCH_RETRIES = new EnvVar("CAFERUN_OPTION_FASTLAUNCH_RETRIES"); 276 internal static EnvVar CAFERUN_OPTION_FASTLAUNCH_TIMEOUT = new EnvVar("CAFERUN_OPTION_FASTLAUNCH_TIMEOUT"); 277 internal static EnvVar CAFERUN_OPTION_FASTLAUNCH_DELAY = new EnvVar("CAFERUN_OPTION_FASTLAUNCH_DELAY"); 278 279 // KILL RESTART 280 internal static EnvVar CAFERUN_DISABLE_KILL_RESTART = new EnvVar("CAFERUN_DISABLE_KILL_RESTART"); 281 internal static EnvVar CAFERUN_OPTION_KILL_RESTART = new EnvVar("CAFERUN_OPTION_KILL_RESTART"); 282 internal static int g_gArgValue = 0; 283 internal static bool g_KOptionSet = false; 284 285 //Cafe profiler 286 internal static EnvVar CAFE_PROFILE = new EnvVar("CAFE_PROFILE"); 287 internal static EnvVar USE_SINGLE_CGI = new EnvVar("USE_SINGLE_CGI"); 288 289 // Mion version checking 290 internal static string MIN_MION_FW_VER = "0.0.14.74"; 291 internal static string MIN_MION_SW_VER = "3.2.6.1"; 292 293 //For launch command 294 internal static string LAUNCH_DLF_FILE = string.Empty; 295 internal static bool execLaunchCmd = false; 296 297 //For ECO mode debugging 298 internal static EnvVar ECO_MODE = new EnvVar("ECO_MODE"); 299 300 //For update/recover testing 301 internal static EnvVar CAFEX_RECOVER_TEST = new EnvVar("CAFEX_RECOVER_TEST"); 302 internal static UInt64 recover_flags = 0x230; 303 304 //For default caferun / cafediscrun options 305 internal static EnvVar CAFERUN_DEFAULT_OPTIONS = new EnvVar("CAFERUN_DEFAULT_OPTIONS"); 306 307 //For MIONPS arguments 308 internal const int MIONPS_BOOT_BYTE = 2; 309 internal const int MIONPS_SDK_MAJ_BYTE = 3; 310 internal const int MIONPS_SDK_MIN_BYTE = 4; 311 internal const int MIONPS_SDK_MIC_BYTE = 5; 312 313 internal const int MIONPS_BOOT_NAND = 1; 314 internal const int MIONPS_BOOT_PCFS = 2; 315 internal const int MIONPS_IMGUPLOAD_BASE_BYTE = 100; 316 317 #endregion 318 319 #region GLOBAL INTIALIZATION 320 internal static bool IsBooting = false; 321 322 internal const int CAFERUN_RETRY_COUNT = 5; 323 internal const int CAFERUN_LAST_RETRY = (CAFERUN_RETRY_COUNT - 1); 324 325 internal static char DEFAULT_DELIMITER = '\t'; 326 internal static string SYSCONFIGTOOL_TITLE_ID = "000500101f700500"; 327 328 internal static bool fAppTypeDefined = false; 329 const int CAFE_ARGSTR_MAX_LENGTH = 4096; 330 331 const string IOS_CRASHDUMP_TOKEN = "IOS_CRASH_START_PROCESS:"; 332 InitialEnvVarSetup()333 internal static CAFEX_ERROR InitialEnvVarSetup() 334 { 335 #if DEBUG 336 Log.WriteLine("InitialEnvVarSetup started."); 337 #endif 338 339 #region encoding setup 340 341 //check to see if we are in a cygwin window. 342 // if (CAFE_ROOT.value.Contains("cygdrive") || !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("CYGWIN"))) 343 // CALLED_FROM_CYGWIN = true; 344 345 //determine the encoding that Cafe is outputting 346 if (!String.IsNullOrEmpty(LANG.value)) 347 { 348 //cygwin uses the format (language)_(territory).(charset)[@modifier] 349 //and we're only interested in the charset 350 int langLoc = LANG.value.IndexOf(".", 0); 351 string lang = null; 352 353 if (langLoc > -1) 354 { 355 //handle case where LANG may have @ in it (legal in cygwin) 356 int atSignLoc = LANG.value.IndexOf("@", 0); 357 358 if (langLoc > atSignLoc) 359 lang = LANG.value.Substring(langLoc + 1); 360 else 361 lang = LANG.value.Substring(langLoc + 1, atSignLoc - langLoc); 362 363 switch (lang) 364 { 365 case "UTF-8": 366 case "utf8": 367 lang = "utf-8"; 368 break; 369 case "SJIS": 370 case "CP932": 371 lang = "shift_jis"; 372 break; 373 case "ASCII": 374 lang = "us-ascii"; 375 break; 376 case "CP1252": 377 lang = "windows-1252"; 378 break; 379 case "CP437": 380 lang = "IBM437"; 381 break; 382 case "CP720": 383 lang = "DOS-270"; 384 break; 385 case "CP737": 386 lang = "ibm737"; 387 break; 388 case "CP775": 389 lang = "ibm775"; 390 break; 391 case "CP850": 392 lang = "ibm850"; 393 break; 394 case "CP852": 395 lang = "ibm852"; 396 break; 397 case "CP855": 398 lang = "IBM855"; 399 break; 400 case "CP857": 401 lang = "ibm857"; 402 break; 403 case "CP858": 404 lang = "IBM00858"; 405 break; 406 case "CP860": 407 lang = "IBM860"; 408 break; 409 case "CP861": 410 lang = "ibm861"; 411 break; 412 case "CP862": 413 lang = "DOS-862"; 414 break; 415 case "CP863": 416 lang = "IBM863"; 417 break; 418 case "CP864": 419 lang = "IBM864"; 420 break; 421 case "CP865": 422 lang = "IBM865"; 423 break; 424 case "CP866": 425 lang = "cp866"; 426 break; 427 case "CP869": 428 lang = "ibm869"; 429 break; 430 case "CP870": 431 lang = "IBM870"; 432 break; 433 case "CP874": 434 case "TIS-620": 435 case "TIS620": 436 lang = "windows-874"; 437 break; 438 case "CP1250": 439 lang = "windows-1250"; 440 break; 441 case "CP1251": 442 lang = "windows-1251"; 443 break; 444 case "CP1253": 445 lang = "windows-1253"; 446 break; 447 case "CP1254": 448 lang = "windows-1254"; 449 break; 450 case "CP1255": 451 lang = "windows-1255"; 452 break; 453 case "CP1256": 454 lang = "windows-1256"; 455 break; 456 case "CP1257": 457 lang = "windows-1257"; 458 break; 459 case "CP1258": 460 lang = "windows-1258"; 461 break; 462 case "ISO-8859-1": 463 lang = "iso-8859-1"; 464 break; 465 case "ISO-8859-2": 466 lang = "iso-8859-2"; 467 break; 468 case "ISO-8859-3": 469 lang = "iso-8859-3"; 470 break; 471 case "ISO-8859-4": 472 lang = "iso-8859-4"; 473 break; 474 case "ISO-8859-5": 475 lang = "iso-8859-5"; 476 break; 477 case "ISO-8859-6": 478 lang = "iso-8859-6"; 479 break; 480 case "ISO-8859-7": 481 lang = "iso-8859-7"; 482 break; 483 case "ISO-8859-8": 484 lang = "iso-8859-8"; 485 break; 486 case "ISO-8859-9": 487 lang = "iso-8859-9"; 488 break; 489 case "ISO-8859-10": 490 lang = "iso-8859-10"; 491 break; 492 case "ISO-8859-11": 493 lang = "iso-8859-11"; 494 break; 495 case "ISO-8859-13": 496 lang = "iso-8859-13"; 497 break; 498 case "ISO-8859-14": 499 lang = "iso-8859-14"; 500 break; 501 case "ISO-8859-15": 502 lang = "iso-8859-15"; 503 break; 504 case "ISO-8859-16": 505 lang = "iso-8859-16"; 506 break; 507 case "Big5": 508 lang = "big5"; 509 break; 510 case "EUCCN": 511 case "euc-CN": 512 case "GB2312": 513 case "GBK": 514 lang = "gb2312"; 515 break; 516 case "EUCJP": 517 case "euc-JP": 518 lang = "EUC-JP"; 519 break; 520 case "EUCKR": 521 case "euc-KR": 522 lang = "ks_c_5601-1987"; 523 break; 524 case "KOI8-R": 525 lang = "koi8-r"; 526 break; 527 case "KOI8-U": 528 lang = "koi8-u"; 529 break; 530 default: 531 Console.WriteLine("cafex: Unknown LANG specified; using UTF-8 encoding for incoming Cafe messages"); 532 lang = null; 533 break; 534 } 535 } 536 else 537 { 538 Console.WriteLine("cafex: Invalid LANG specified; using UTF-8 encoding for incoming Cafe messages"); 539 } 540 CAFE_OUTPUT_ENCODING.value = lang; 541 } 542 543 544 #endregion 545 546 // THESE NEED TO BE SET IN CAFEX_ENV.BAT, BUT FOR NOW ARE HERE 547 CAFE_ROOT.value = PathConverter.Windowsify(CAFE_ROOT.value); 548 if (string.IsNullOrEmpty(CAFE_TEMP.value)) 549 { 550 CAFE_TEMP.value = Path.Combine (CAFE_ROOT.value, "temp"); 551 } 552 CAFE_TEMP.value = PathConverter.Windowsify(CAFE_TEMP.value); 553 GHS_ROOT.value = PathConverter.Windowsify(GHS_ROOT.value); 554 if (string.IsNullOrEmpty(CAFE_HARDWARE.value)) 555 { 556 CAFE_HARDWARE.value = "catdevmp"; 557 } 558 else if (!CAFE_HARDWARE.value.Equals("catdevmp")) 559 { 560 Console.WriteLine("User has already defined CAFE_HARDWARE to '{0}'!", CAFE_HARDWARE.value); 561 Console.WriteLine("Please be aware that anything but 'catdevmp' is not guaranteed to work."); 562 } 563 //CAFE_BOOT_MODE.value = "PCFS"; 564 //CAFE_CONTENT_DIR.value = CAFE_ROOT.value + "\\data\\disc\\content"; 565 //CAFE_SAVE_DIR.value = CAFE_ROOT.value + "\\data\\save"; 566 //CAFE_SLC_DIR.value = CAFE_ROOT.value + "\\data\\slc"; 567 //CAFE_MLC_DIR.value = CAFE_ROOT.value + "\\data\\mlc"; 568 //CAFE_META_DIR.value = CAFE_ROOT.value + "\\data\\disc\\meta"; 569 CAFE_CONTENT_DIR.value = PathConverter.Windowsify(CAFE_CONTENT_DIR.value); 570 CAFE_SAVE_DIR.value = PathConverter.Windowsify(CAFE_SAVE_DIR.value); 571 CAFE_SLC_DIR.value = PathConverter.Windowsify(CAFE_SLC_DIR.value); 572 CAFE_MLC_DIR.value = PathConverter.Windowsify(CAFE_MLC_DIR.value); 573 CAFE_META_DIR.value = PathConverter.Windowsify(CAFE_META_DIR.value); 574 TOOLCHAIN.value = "ghs"; 575 MONITOR_DEFAULT_TIMEOUT.value = "60"; 576 // carlosk - don't override this setting from environment 577 //CAFE_CONSOLE.value = "cattoucan"; 578 if (string.IsNullOrEmpty(CAFE_CONSOLE.value)) 579 { 580 CAFE_CONSOLE.value = "cattoucan"; 581 } 582 // carlosk - need to remove this or it will always do pcfs over sata 583 //USE_PCFS_OVER_SATA.value = "1"; 584 585 if (string.IsNullOrEmpty(CAFE_TEST_SELF_REFRESH.value)) 586 { 587 CAFE_TEST_SELF_REFRESH.value = "0"; 588 } 589 590 MON_RESULT_UNDEF.value = "-1"; 591 MON_RESULT_TIMEOUT.value = "0"; 592 MON_RESULT_PASS.value = "1"; 593 MON_RESULT_MANUAL.value = "2"; 594 MON_RESULT_NOLOG.value = "3"; 595 MON_RESULT_FAIL.value = "4"; 596 MON_RESULT_EXPECTED_TERM.value = "5"; 597 MON_RESULT_EXEC_WIN_APP.value = "6"; 598 MON_RESULT_NOPPC.value = "7"; 599 MON_RESULT_BOOT1.value = "8"; 600 MON_RESULT_RESTART.value = "9"; 601 MON_RESULT_TEST_AS_RPL.value = "10"; 602 MON_RESULT_END_OF_RPL_LOADER.value = "11"; 603 MON_RESULT_BRIDGE_COLLISION.value = "12"; 604 MON_RESULT_TEST_DBG_OUT.value = "13"; 605 MON_RESULT_BRIDGE_OFF.value = "14"; 606 MON_RESULT_KILL_AUTOTEST.value = "15"; 607 MON_RESULT_ERROR.value = "128"; 608 MON_RESULT_SKIP.value = "129"; 609 MON_RESULT_FATAL_ERROR.value = "255"; 610 MON_RESULT_MISSING.value = "131"; 611 MON_RESULT_ABORTED.value = "132"; 612 613 ALLOW_DISCRUN_IN_SOFTLAUNCH.value = "0"; 614 SKIP_OS_CHECK.value = "0"; 615 616 PATH.AddToVar("C:\\cygwin\\bin\\;", ';'); 617 618 CAFEX_ERROR ret = readSDKFromCafeRoot(null); 619 if (ret != CAFEX_ERROR.OK) 620 { 621 return ret; 622 } 623 624 #region session setup 625 626 if (SESSION_MANAGER.value == "1") 627 { 628 if (!File.Exists(MION_BRIDGE_TOOLS.value + "\\SessionManager.dll")) 629 { 630 Console.WriteLine("ERROR: SessionManager.dll not found and multi-CATDEV is enabled!"); 631 Console.WriteLine(" Please install HostBridge version 3.2.2.3+ or disable multi-CATDEV feature."); 632 return CAFEX_ERROR.NO_SESSIONMANAGER_DLL; 633 } 634 635 string output = string.Empty; 636 SessionManagerUtil.GetSessionInfo(out output); 637 638 string[] output_array = output.Split(' '); 639 640 SESSION_NAME.value = output_array[0]; 641 SESSION_DEBUG_OUT_PORT.value = output_array[1]; 642 SESSION_DEBUG_CONTROL_PORT.value = output_array[2]; 643 SESSION_HIO_OUT_PORT.value = output_array[3]; 644 SESSION_LAUNCH_CTRL_PORT.value = output_array[4]; 645 SESSION_NET_MANAGE_PORT.value = output_array[5]; 646 SESSION_PCFS_SATA_PORT.value = output_array[6]; 647 648 SESSION_PATH_PREFIX.value = SESSION_NAME.value + "_"; 649 650 CAFE_DATA_DIR.value = CAFE_ROOT.value + "\\" + SESSION_PATH_PREFIX.value + "data"; 651 652 // If the content or meta location has been changed from the default, we should not touch and use it. 653 // Otherwise, should modify by appending the CAFE_DATA_DIR. 654 string defaultContentDir = Path.Combine(CAFE_ROOT.value,"data\\disc\\content"); 655 string defaultMetaDir = Path.Combine(CAFE_ROOT.value,"data\\disc\\meta"); 656 string defaultSaveDir = Path.Combine(CAFE_DATA_DIR.value, "save"); 657 string defaultSlcDir = Path.Combine(CAFE_DATA_DIR.value, "slc"); 658 string defaultMlcDir = Path.Combine(CAFE_DATA_DIR.value, "mlc"); 659 660 // typical directories for users to change to something custom 661 if (string.Equals(CAFE_CONTENT_DIR.value,defaultContentDir)) 662 { 663 CAFE_CONTENT_DIR.value = Path.Combine(CAFE_DATA_DIR.value, "disc\\content"); 664 } 665 if (string.Equals(CAFE_META_DIR.value, defaultMetaDir)) 666 { 667 CAFE_META_DIR.value = Path.Combine(CAFE_DATA_DIR.value, "disc\\meta"); 668 } 669 if (string.Equals(CAFE_SAVE_DIR.value, defaultSaveDir)) 670 { 671 CAFE_SAVE_DIR.value = Path.Combine(CAFE_DATA_DIR.value, "save"); 672 } 673 674 // No idea why users would ever change these next two paths, but we need to support it 675 if (string.Equals(CAFE_SLC_DIR.value, defaultSlcDir)) 676 { 677 CAFE_SLC_DIR.value = Path.Combine(CAFE_DATA_DIR.value, "slc"); 678 } 679 else 680 { 681 Console.WriteLine("WARNING: CAFE_SLC_DIR is set to a non-default path! Cafe may encounter errors!"); 682 Console.WriteLine("default:{0}", defaultSlcDir); 683 Console.WriteLine(" actual:{0}", CAFE_SLC_DIR.value); 684 } 685 if (string.Equals(CAFE_MLC_DIR.value, defaultMlcDir)) 686 { 687 CAFE_MLC_DIR.value = Path.Combine(CAFE_DATA_DIR.value, "mlc"); 688 } 689 else 690 { 691 Console.WriteLine("WARNING: CAFE_MLC_DIR is set to a non-default path! Cafe may encounter errors!"); 692 Console.WriteLine("default:{0}", defaultMlcDir); 693 Console.WriteLine(" actual:{0}", CAFE_MLC_DIR.value); 694 } 695 696 CAFE_DATA_TMP.value = CAFE_DATA_DIR.value + "\\tmp"; 697 } 698 else 699 { 700 SESSION_NAME.value = ""; 701 SESSION_DEBUG_OUT_PORT.value = "6001"; 702 SESSION_DEBUG_CONTROL_PORT.value = "6002"; 703 SESSION_HIO_OUT_PORT.value = "6003"; 704 SESSION_LAUNCH_CTRL_PORT.value = "6006"; 705 SESSION_NET_MANAGE_PORT.value = "6008"; 706 SESSION_PCFS_SATA_PORT.value = "7500"; 707 708 SESSION_PATH_PREFIX.value = ""; 709 CAFE_DATA_DIR.value = CAFE_ROOT.value + "\\data"; 710 } 711 712 #if DEBUG 713 Log.WriteLine("SESSION_NAME = " + SESSION_NAME.value); 714 Log.WriteLine("SESSION_DEBUG_OUT_PORT = " + SESSION_DEBUG_OUT_PORT.value); 715 Log.WriteLine("SESSION_DEBUG_CONTROL_PORT = " + SESSION_DEBUG_CONTROL_PORT.value); 716 Log.WriteLine("SESSION_HIO_OUT_PORT = " + SESSION_HIO_OUT_PORT.value); 717 Log.WriteLine("SESSION_LAUNCH_CTRL_PORT = " + SESSION_LAUNCH_CTRL_PORT.value); 718 Log.WriteLine("SESSION_NET_MANAGE_PORT = " + SESSION_NET_MANAGE_PORT.value); 719 Log.WriteLine("SESSION_PCFS_SATA_PORT = " + SESSION_PCFS_SATA_PORT.value); 720 Log.WriteLine("SESSION_PATH_PREFIX = " + SESSION_PATH_PREFIX.value); 721 Log.WriteLine("CAFE_DATA_DIR = " + CAFE_DATA_DIR.value); 722 Log.WriteLine("CAFE_CONTENT_DIR = " + CAFE_CONTENT_DIR.value); 723 Log.WriteLine("CAFEON_OPTION_NO_DATA_SYNC = " + CAFEON_OPTION_NO_DATA_SYNC.value); 724 Log.WriteLine("CAFERUN_OPTION_NO_DATA_SYNC= " + CAFERUN_OPTION_NO_DATA_SYNC.value); 725 #endif 726 727 #endregion 728 729 return CAFEX_ERROR.OK; 730 } 731 732 #endregion 733 MCP_MAKE_APP_TYPE(Int64 flags, Int64 id)734 internal static Int64 MCP_MAKE_APP_TYPE(Int64 flags, Int64 id) 735 { 736 return ((flags) | ((id) & ((1<<24) - 1))); 737 } 738 739 #region SCRIPT FUNCTIONS 740 741 // Helper function: FindAppType() FindAppType( Int64 iTitleID )742 static string FindAppType( Int64 iTitleID ) 743 { 744 string app_type; 745 746 // Determine the correct app_type based on the title_id 747 if ((iTitleID == 0x0005001010001000) || (iTitleID == 0x0005001010001100) || 748 (iTitleID == 0x0005001010001200) || (iTitleID == 0x0005001010001300) || 749 (iTitleID == 0x0005001010001400) || (iTitleID == 0x0005001010001500) || 750 (iTitleID == 0x0005001010001600) || (iTitleID == 0x0005001010001700) || 751 (iTitleID == 0x0005001010001800) || (iTitleID == 0x0005001010001900) || 752 (iTitleID == 0x0005001010001A00) || (iTitleID == 0x0005001010001B00) || 753 (iTitleID == 0x0005001010001C00) || (iTitleID == 0x0005001010047000) || 754 (iTitleID == 0x0005001010047100) || (iTitleID == 0x0005001010047200)) // MCP_APP_TYPE_SYSTEM 755 { 756 app_type = Convert.ToString(MCP_MAKE_APP_TYPE(((1 << 31) | (1 << 28)), 32), 16); 757 } 758 else if ((iTitleID == 0x0005001010004005) || (iTitleID == 0x0005001010004006) || 759 (iTitleID == 0x0005001010004007) || (iTitleID == 0x0005001010004008) || 760 (iTitleID == 0x00050010100040FF) || (iTitleID == 0x0005001010008005) || 761 (iTitleID == 0x0005001010008006) || (iTitleID == 0x0005001010008007) || 762 (iTitleID == 0x0005001010008008) || (iTitleID == 0x000500101000C005) || 763 (iTitleID == 0x000500101000C006) || (iTitleID == 0x000500101000C007) || 764 (iTitleID == 0x000500101000C008) || (iTitleID == 0x000500101000C009)) // MCP_APP_TYPE_OS 765 { 766 app_type = Convert.ToString(MCP_MAKE_APP_TYPE((1 << 28), 10), 16); 767 } 768 else if ((iTitleID == 0x0005001010000100)) // MCP_APP_TYPE_BOOT1 769 { 770 app_type = Convert.ToString(MCP_MAKE_APP_TYPE((1 << 28), 9), 16); 771 } 772 else if ((iTitleID == 0x0005001010000200) || (iTitleID == 0x0005001010000300)) // MCP_APP_TYPE_DRH 773 { 774 app_type = Convert.ToString(MCP_MAKE_APP_TYPE((1 << 28), 20), 16); 775 } 776 else if ((iTitleID == 0x0005001010000400)) // MCP_APP_TYPE_BT 777 { 778 app_type = Convert.ToString(MCP_MAKE_APP_TYPE((1 << 28), 18), 16); 779 } 780 else if ((iTitleID == 0x0005001010004000)) // MCP_APP_TYPE_COMPAT_SYSTEM 781 { 782 app_type = Convert.ToString(MCP_MAKE_APP_TYPE((1 << 28), 17), 16); 783 } 784 else if ((iTitleID == 0x0005003010010000) || (iTitleID == 0x0005003010010100) || 785 (iTitleID == 0x0005003010010200) || (iTitleID == 0x0005003010020000) || 786 (iTitleID == 0x0005003010020100) || (iTitleID == 0x0005003010020200)) // MCP_APP_TYPE_HOMEBUTTON 787 { 788 app_type = Convert.ToString(MCP_MAKE_APP_TYPE(((1 << 31) | (1 << 28) | (1 << 30)), 4), 16); 789 } 790 else if ((iTitleID == 0x0005003010011000) || (iTitleID == 0x0005003010011100) || 791 (iTitleID == 0x0005003010011200) || (iTitleID == 0x0005003010021000) || 792 (iTitleID == 0x0005003010021100) || (iTitleID == 0x0005003010021200)) // MCP_APP_TYPE_ERRORDISPLAY 793 { 794 app_type = Convert.ToString(MCP_MAKE_APP_TYPE(((1 << 31) | (1 << 28) | (1 << 30)), 5), 16); 795 } 796 else if ((iTitleID == 0x0005003010019000) || (iTitleID == 0x0005003010019100) || 797 (iTitleID == 0x0005003010019200) || (iTitleID == 0x0005003010029000) || 798 (iTitleID == 0x0005003010029100) || (iTitleID == 0x0005003010029200)) // MCP_APP_TYPE_MINIMIIVERSE 799 { 800 app_type = Convert.ToString(MCP_MAKE_APP_TYPE(((1 << 31) | (1 << 28) | (1 << 30)), 13), 16); 801 } 802 else if ((iTitleID == 0x0005001010040000) || (iTitleID == 0x0005001010040100) || 803 (iTitleID == 0x0005001010040200) || (iTitleID == 0x000500101f700500)) // MCP_APP_TYPE_CAFEMENU 804 { 805 app_type = Convert.ToString(MCP_MAKE_APP_TYPE(((1 << 31) | (1 << 28)), 1), 16); 806 } 807 else if ((iTitleID == 0x0005001010041000) || (iTitleID == 0x0005001010041100) || 808 (iTitleID == 0x0005001010041200)) // MCP_APP_TYPE_SYSTEM_VERSION 809 { 810 app_type = Convert.ToString(MCP_MAKE_APP_TYPE((1 << 28), 21), 16); 811 } 812 else if ((iTitleID == 0x0005001010043000) || (iTitleID == 0x0005001010043100) || 813 (iTitleID == 0x0005001010043200)) // MCP_APP_TYPE_DRC 814 { 815 app_type = Convert.ToString(MCP_MAKE_APP_TYPE((1 << 28), 19), 16); 816 } 817 else if ((iTitleID == 0x0005001010044000) || (iTitleID == 0x0005001010044100) || 818 (iTitleID == 0x0005001010044200)) // MCP_APP_TYPE_DRC_LANG 819 { 820 app_type = Convert.ToString(MCP_MAKE_APP_TYPE((1 << 28), 26), 16); 821 } 822 else if ((iTitleID == 0x0005001010045000) || (iTitleID == 0x0005001010045100) || 823 (iTitleID == 0x0005001010045200)) // MCP_APP_TYPE_UPDATER 824 { 825 app_type = Convert.ToString(MCP_MAKE_APP_TYPE(((1 << 31) | (1 << 28)), 11), 16); 826 } 827 else if ((iTitleID == 0x0005001010046000) || (iTitleID == 0x0005001010046100) || 828 (iTitleID == 0x0005001010046200)) // MCP_APP_TYPE_UPDATE_SYSTEM 829 { 830 app_type = Convert.ToString(MCP_MAKE_APP_TYPE(((1 << 29) | (1 << 28)), 8), 16); 831 } 832 else if ((iTitleID == 0x000500101004B000) || (iTitleID == 0x000500101004B100) || 833 (iTitleID == 0x000500101004B200)) // MCP_APP_TYPE_NETSERV 834 { 835 app_type = Convert.ToString(MCP_MAKE_APP_TYPE(((1 << 31) | (1 << 28) | (1 << 30)), 22), 16); 836 } 837 else if ((iTitleID == 0x0005001B10059000) || (iTitleID == 0x0005001B10059100) || 838 (iTitleID == 0x0005001B10059200)) // MCP_APP_TYPE_EMANUAL 839 { 840 app_type = Convert.ToString(MCP_MAKE_APP_TYPE(((1 << 31) | (1 << 28) | (1 << 30)), 3), 16); 841 } 842 else if ((iTitleID == 0x0005001B1005F000)) // MCP_APP_TYPE_DATA_PATCH_MAP 843 { 844 app_type = Convert.ToString(MCP_MAKE_APP_TYPE(((1 << 27) | (1 << 28)), 35), 16); 845 } 846 else if ((iTitleID == 0x0005001010062000) || (iTitleID == 0x0005001010062100) || 847 (iTitleID == 0x0005001010062200) || (iTitleID == 0x0005001B10063000)) // MCP_APP_TYPE_DATA_WAGONU 848 { 849 app_type = Convert.ToString(MCP_MAKE_APP_TYPE(((1 << 27) | (1 << 28)), 41), 16); 850 } 851 else // If the title ID isn't internal or we don't know the app_type of the title then it gets set as MCP_APP_TYPE_GAME 852 { 853 app_type = Convert.ToString(MCP_MAKE_APP_TYPE((1 << 31), 0), 16); 854 }; 855 856 app_type = app_type.TrimStart('f'); 857 858 return app_type; 859 } 860 861 // Helper function: StartProcessOnCrashdump() StartProcessOnCrashdump(string input)862 static bool StartProcessOnCrashdump(string input) 863 { 864 if (input == null) 865 { 866 throw new ArgumentNullException("input"); 867 } 868 int pos = input.IndexOf(IOS_CRASHDUMP_TOKEN); 869 if (pos >= 0) 870 { 871 #if DEBUG 872 Log.WriteLine(String.Format("Found crash token in '{0}'!", input)); 873 #endif 874 string line = input.Substring(pos + IOS_CRASHDUMP_TOKEN.Length).Trim(); 875 //line = Environment.ExpandEnvironmentVariables(line); 876 877 string shell; 878 879 if (FileUtil.RunningFromCygwin) 880 { 881 shell = "cmd.exe"; 882 line = string.Format("/c start bash -c \"{0}\"", Regex.Replace(line, "%([A-Za-z_]\\w+)%", "${$1}")); 883 } 884 else 885 { 886 shell = "cmd.exe"; 887 line = "/c start " + Regex.Replace(line, "\\${?([A-Za-z_]\\w+)}?", "%$1%"); 888 } 889 #if DEBUG 890 Log.WriteLine(String.Format("Starting '{0} {1}'...", shell, line)); 891 #endif 892 ProcessExecutor.DoProcess_DontWait(shell, line); 893 } 894 895 return true; // don't exit CafeX 896 } 897 898 //Script function: cafestop stop(string[] args, bool checkMionVersion)899 static void stop(string[] args, bool checkMionVersion) 900 { 901 #if DEBUG 902 Log.WriteLine("stop started."); 903 string argString = null; 904 if (args != null) 905 { 906 foreach (string arg in args) 907 { 908 argString += arg + " "; 909 } 910 } 911 Log.WriteLine("Arguments=" + argString); 912 913 #endif 914 915 bool HARD_STOP = false; 916 917 if (args != null && args.Length > 0) 918 { 919 // Check for -h and display help 920 if (args[0].ToLowerInvariant() == "-h") 921 { 922 // Display help and return; 923 stop_usage(); 924 return; 925 } 926 // Check for -hostonly setting on first argument 927 if (args[0].ToLowerInvariant() == "-hostonly") 928 { 929 // CafeX doesn't let you execute any function if bridge vars are not set, so there is no 930 // reason to check them here again like in BASH. 931 // ----------------------------------------------------------------------------------------- 932 // We want to kill any running processes, but don't want to talk to a (non-existent?) device 933 ToucanReset.Stop(); 934 PCFSServer.Shutdown(); 935 return; 936 } 937 if (args[0].ToLowerInvariant() == "-hard") 938 { 939 // Force hard stop 940 HARD_STOP = true; 941 } 942 } 943 944 PLATFORM.value = "cafe"; 945 946 if ((CAFERUN_OPTION_SOFT_LAUNCH.value == "1" || CAFERUN_OPTION_KILL_RESTART.value == "1") && !HARD_STOP) 947 { 948 #if DEBUG 949 Log.WriteLine("(CAFERUN_OPTION_SOFT_LAUNCH.value == 1 || CAFERUN_OPTION_KILL_RESTART.value == 1) && !HARD_STOP -> Doing nothing"); 950 #endif 951 // In autotest or in caferun with CAFERUN_OPTION_SOFTLAUNCH set, cafestop is a no-op 952 CAFESTOP_STATUS.value = "0"; 953 954 if (USE_SINGLE_CGI.value != "1") 955 { 956 // Explicitly clear the hint if not set to 1 957 USE_SINGLE_CGI.value = null; 958 } 959 else 960 { 961 Console.WriteLine("cafex {0}: Enabling single pass CGI", command); 962 } 963 } 964 else 965 { 966 #if DEBUG 967 Log.WriteLine("CAFERUN_OPTION_SOFT_LAUNCH.value != 1 -> calling hoststop()"); 968 #endif 969 #if TIMER 970 Log.WriteLine("Hoststop start"); 971 CafeXSetupTime.Report(); 972 #endif 973 hoststop(args, checkMionVersion); 974 #if TIMER 975 Log.WriteLine("Hoststop end"); 976 CafeXSetupTime.Report(); 977 #endif 978 int ret = PCFSServer.Shutdown(); 979 CAFESTOP_STATUS.value = ret.ToString(); 980 } 981 982 if (CAFESTOP_STATUS.value != "0") 983 { 984 Console.WriteLine("cafex stop error: CAFESTOP_STATUS=" + CAFESTOP_STATUS.value); 985 } 986 } 987 stop(string[] args)988 static void stop(string[] args) 989 { 990 stop(args, false); 991 } 992 readSDKFromCafeRoot(string sdk_root)993 static CAFEX_ERROR readSDKFromCafeRoot(string sdk_root) 994 { 995 if (string.IsNullOrEmpty(sdk_root)) 996 { 997 sdk_root = CAFE_ROOT.value; 998 } 999 1000 string sdk_ver_file = Path.Combine(sdk_root, "system\\include\\sdk_ver.h"); 1001 if (!File.Exists(sdk_ver_file)) 1002 { 1003 Console.WriteLine("cafex: Unable to find {0}, using OS header file.", sdk_ver_file); 1004 sdk_ver_file = Path.Combine(CAFE_ROOT.value, "system\\src\\build\\make\\os_version.mk"); 1005 if (!File.Exists(sdk_ver_file)) 1006 { 1007 Console.WriteLine("cafex: Unable to find OS header file {0}!", sdk_ver_file); 1008 return CAFEX_ERROR.RUN_COULDNT_PARSE_SDK_VERSION_HEADER; 1009 } 1010 else 1011 { 1012 #if DEBUG 1013 Console.WriteLine("cafex: SDK version from {0}.", sdk_ver_file); 1014 #endif 1015 FileStream fs = new FileStream(sdk_ver_file, FileMode.Open, FileAccess.Read); 1016 StreamReader sr = new StreamReader(fs); 1017 bool found_line = false; 1018 while (!sr.EndOfStream) 1019 { 1020 string line = sr.ReadLine(); 1021 if (line.Contains("SM := ")) 1022 SDK_VER.value = line.Substring(25, 1); 1023 if (line.Contains("Sm := ")) 1024 SDK_VER.value = SDK_VER.value + "." + line.Substring(25, 2); 1025 if (line.Contains("Sc := ")) 1026 { 1027 SDK_VER.value = SDK_VER.value + "." + line.Substring(25, 2); 1028 found_line = true; 1029 break; 1030 } 1031 } 1032 sr.Close(); 1033 if (!found_line) 1034 { 1035 Console.WriteLine("cafex Error: couldn't determine SDK version!"); 1036 return CAFEX_ERROR.RUN_COULDNT_PARSE_SDK_VERSION_HEADER; 1037 } 1038 } 1039 } 1040 else 1041 { 1042 #if DEBUG 1043 Console.WriteLine("cafex: SDK version from {0}.", sdk_ver_file); 1044 #endif 1045 FileStream fs = new FileStream(sdk_ver_file, FileMode.Open, FileAccess.Read); 1046 StreamReader sr = new StreamReader(fs); 1047 bool found_line = false; 1048 while (!sr.EndOfStream) 1049 { 1050 string line = sr.ReadLine(); 1051 if (line.Contains("#define CAFE_OS_SDK_VERSION") && !line.Contains("CAFE_OS_SDK_VERSION_STRING")) 1052 { 1053 UInt32 maj, min, mic, version; 1054 string[] subs = line.Split((string[])null, StringSplitOptions.RemoveEmptyEntries); 1055 1056 if (subs.Length < 3) 1057 { 1058 Console.WriteLine("cafex Error: CAFE_OS_SDK_VERSION not defined in {0}!", sdk_ver_file); 1059 break; 1060 } 1061 1062 if (!UInt32.TryParse(subs[2], out version)) 1063 { 1064 Console.WriteLine("cafex Error: TryParse on CAFE_OS_SDK_VERSION '{0}' failed!", subs[2]); 1065 break; 1066 } 1067 1068 maj = version / 10000; 1069 min = (version % 10000) / 100; 1070 mic = version % 100; 1071 1072 SDK_VER.value = String.Format("{0}.{1:D2}.{2:D2}", maj, min, mic); 1073 1074 found_line = true; 1075 break; 1076 } 1077 } 1078 sr.Close(); 1079 if (!found_line) 1080 { 1081 Console.WriteLine("cafex Error: couldn't determine SDK version!"); 1082 return CAFEX_ERROR.RUN_COULDNT_PARSE_SDK_VERSION_HEADER; 1083 } 1084 } 1085 1086 return CAFEX_ERROR.OK; 1087 } 1088 readSDKFromMion()1089 static void readSDKFromMion() 1090 { 1091 string retVal = mionps.Run(BRIDGE_CURRENT_IP_ADDRESS.value + " 3 4 5").Trim(); 1092 char[] delims = {' '}; 1093 string[] splitString = retVal.Split(delims); 1094 SDK_MAJ_VER.value = splitString[0]; 1095 SDK_MIN_VER.value = String.Format("{0:D2}",Convert.ToInt32(splitString[1])); 1096 SDK_MIC_VER.value = String.Format("{0:D2}",Convert.ToInt32(splitString[2])); 1097 } 1098 setMionSDKVersion()1099 static void setMionSDKVersion() 1100 { 1101 char[] delims = { '.', ' ' }; 1102 string[] splitString = SDK_VER.value.Split(delims); 1103 1104 int sdkmaj = Convert.ToInt32(splitString[0]); 1105 int sdkmin = Convert.ToInt32(splitString[1]); 1106 int sdkmic = Convert.ToInt32(splitString[2]); 1107 1108 string parameters = string.Format("{0} 3 -s {1} 4 -s {2} 5 -s {3}", BRIDGE_CURRENT_IP_ADDRESS.value, 1109 sdkmaj, 1110 sdkmin, 1111 sdkmic); 1112 1113 string retVal = mionps.Run(parameters).Trim(); 1114 string[] result = retVal.Split(delims); 1115 try 1116 { 1117 int newcatmaj = Convert.ToInt32(result[0]); 1118 int newcatmin = Convert.ToInt32(result[1]); 1119 int newcatmic = Convert.ToInt32(result[2]); 1120 1121 if (sdkmaj != newcatmaj) 1122 Console.WriteLine("cafex unable to set the SDK Major version. Mionps returned " + result[0]); 1123 if (sdkmin != newcatmin) 1124 Console.WriteLine("cafex unable to set the SDK Minor version. Mionps returned " + result[1]); 1125 if (sdkmic != newcatmic) 1126 Console.WriteLine("cafex unable to set the SDK Micro version. Mionps returned " + result[2]); 1127 } 1128 catch (Exception) 1129 { 1130 Console.WriteLine("An error occurred when trying to set the SDK version on the catdev."); 1131 Console.WriteLine("Mionps returned: " + retVal); 1132 } 1133 } 1134 checkNameFail()1135 static CAFEX_ERROR checkNameFail() 1136 { 1137 HOSTSTOP_RVAL.value = "1"; 1138 return CAFEX_ERROR.CHECKNAME_FAILED; 1139 } 1140 parseVersions(string output, bool checkMionVersion, bool checkSdk)1141 static CAFEX_ERROR parseVersions(string output, bool checkMionVersion, bool checkSdk) 1142 { 1143 int res; 1144 int end; 1145 string sw_ver_str = null; 1146 string fw_ver_str = null; 1147 1148 // Parse the software version (if not already checked) 1149 if (checkMionVersion || sw_ver_flat == 0) 1150 { 1151 res = output.IndexOf("software:"); 1152 if (res < 0) 1153 { 1154 return checkNameFail(); 1155 } 1156 end = output.IndexOf('\n', res += 9); 1157 if (end < 0) 1158 { 1159 return checkNameFail(); 1160 } 1161 sw_ver_str = output.Substring(res, end - res); 1162 if (sw_ver_flat == 0) 1163 { 1164 sw_ver_flat = compute_flat_version(sw_ver_str); 1165 } 1166 } 1167 1168 // Parse the firmware version (if not already checked) 1169 if (checkMionVersion || fw_ver_flat == 0) 1170 { 1171 res = output.IndexOf("firmware:"); 1172 if (res < 0) 1173 { 1174 return checkNameFail(); 1175 } 1176 end = output.IndexOf('\n', res += 9); 1177 if (end < 0) 1178 { 1179 return checkNameFail(); 1180 } 1181 fw_ver_str = output.Substring(res, end - res); 1182 if (fw_ver_flat == 0) 1183 { 1184 fw_ver_flat = compute_flat_version(fw_ver_str); 1185 } 1186 } 1187 1188 // Check versions 1189 if (checkMionVersion) 1190 { 1191 int min_fw_ver = compute_flat_version(MIN_MION_FW_VER); 1192 int min_sw_ver = compute_flat_version(MIN_MION_SW_VER); 1193 1194 if (sw_ver_flat < min_sw_ver || fw_ver_flat < min_fw_ver) 1195 { 1196 Console.WriteLine("cafex failed: Please install at least HostBridgeSetup_{0}.exe and restart cafex_env.bat", MIN_MION_SW_VER); 1197 Console.WriteLine(" Current software version is {0} (need {1})", sw_ver_str, MIN_MION_SW_VER); 1198 Console.WriteLine(" Current firmware version is {0} (need {1})", fw_ver_str, MIN_MION_FW_VER); 1199 return checkNameFail(); 1200 } 1201 } 1202 1203 // Set SDK versions (if not set) 1204 if (checkSdk && 1205 (string.IsNullOrEmpty(SDK_MAJ_VER.value) || 1206 string.IsNullOrEmpty(SDK_MIN_VER.value) || 1207 string.IsNullOrEmpty(SDK_MIC_VER.value))) 1208 { 1209 res = output.IndexOf("sdk:"); 1210 if (res < 0) 1211 { 1212 return checkNameFail(); 1213 } 1214 end = output.IndexOf('\n', res += 4); 1215 if (end < 0) 1216 { 1217 return checkNameFail(); 1218 } 1219 char[] delims = { '.' }; 1220 string[] sdk = output.Substring(res, end - res).Split(delims); 1221 SDK_MAJ_VER.value = sdk[0]; 1222 SDK_MIN_VER.value = sdk[1]; 1223 SDK_MIC_VER.value = sdk[2]; 1224 } 1225 return CAFEX_ERROR.OK; 1226 } 1227 1228 //Script function: hoststop hoststop(string[] args, bool checkMionVersion)1229 static CAFEX_ERROR hoststop(string[] args, bool checkMionVersion) 1230 { 1231 bool bAttemptedSoftwareShutdown = false; 1232 bool HARD_STOP = false; 1233 1234 if (args != null && args.Length > 0) 1235 { 1236 if (args[0].ToLowerInvariant() == "-hard") 1237 { 1238 // Force hard stop 1239 HARD_STOP = true; 1240 } 1241 } 1242 1243 #if DEBUG 1244 Log.WriteLine("hoststop started."); 1245 string argString = null; 1246 if (args != null) 1247 { 1248 foreach (string arg in args) 1249 { 1250 argString += arg + " "; 1251 } 1252 } 1253 Log.WriteLine("Arguments=" + argString); 1254 1255 #endif 1256 1257 if (SDIO_BRIDGE_TOOLS.value == null) 1258 { 1259 if (MION_BRIDGE_TOOLS.value == null) 1260 { 1261 Console.WriteLine("cafex hoststop failed: Please install the HostBridge and reopen the build environment!"); 1262 return CAFEX_ERROR.CHECKNAME_FAILED; 1263 } 1264 } 1265 1266 HOSTSTOP_RVAL.value = "0"; 1267 HOSTSTOP_RETRIES.value = "0"; 1268 1269 getbridgetype(); 1270 1271 HOSTSTOP_RESET_OPTION.value = "-SMCResetHold"; 1272 1273 if (BRIDGE_TYPE.value == "Mion") 1274 { 1275 int res = 0; 1276 bool makemine = false; 1277 string output = string.Empty; 1278 bool singleCGI = USE_SINGLE_CGI.value == "1"; 1279 if (!singleCGI) 1280 { 1281 Environment.SetEnvironmentVariable("CHECK_NAME_STOP", null); 1282 } 1283 1284 // Set the proper USE_SINGLE_CGI hint 1285 if (args != null && args.Length > 0 && args[0] == "-makemine") 1286 { 1287 ToucanReset.Stop(); 1288 makemine = true; 1289 if (singleCGI) 1290 { 1291 Environment.SetEnvironmentVariable("CHECK_NAME_STOP", "2"); 1292 } 1293 } 1294 else if (singleCGI) 1295 { 1296 Environment.SetEnvironmentVariable("CHECK_NAME_STOP", "1"); 1297 } 1298 1299 // Check the bridge name 1300 res = checkbridgename.CheckName(ref output); 1301 if (res != 0) 1302 { 1303 // Check if error string 1304 res = output.IndexOf("ERROR :"); 1305 if (res < 0) 1306 { 1307 output = string.Format("Bridge with the name '{0}' was not found", BRIDGE_CURRENT_NAME.value); 1308 } 1309 else 1310 { 1311 // Report error string 1312 int end = output.IndexOf('\n', res); 1313 if (end < 0) 1314 { 1315 output = output.Substring(res); 1316 } 1317 else 1318 { 1319 output = output.Substring(res, end - res); 1320 } 1321 } 1322 Console.WriteLine("CheckBridgeName: {0}", output); 1323 return checkNameFail(); 1324 } 1325 1326 if (singleCGI) 1327 { 1328 if (output.Contains("INFO: CGI Reset")) 1329 { 1330 // Single pass supported firmware 1331 if (command != "stop") 1332 { 1333 Console.WriteLine("cafex {0}: Single pass CGI enabled", command); 1334 } 1335 if (makemine) 1336 { 1337 res = output.IndexOf("oldhost:"); 1338 if (res < 0) 1339 { 1340 return checkNameFail(); 1341 } 1342 int end = output.IndexOf("\n", res += 8); 1343 if (end < 0) 1344 { 1345 return checkNameFail(); 1346 } 1347 string old = output.Substring(res, (end - 1) - res); 1348 res = output.IndexOf("curhost:"); 1349 if (res < 0) 1350 { 1351 return checkNameFail(); 1352 } 1353 end = output.IndexOf("\n", res += 8); 1354 if (end < 0) 1355 { 1356 return checkNameFail(); 1357 } 1358 string host = output.Substring(res, (end - 1) - res); 1359 Console.WriteLine("cafex {0}: Bridge old owner: [{1}] new owner: [{2}]", command, old, host); 1360 } 1361 else 1362 { 1363 ToucanReset.Stop(); 1364 } 1365 1366 return parseVersions(output, checkMionVersion, true); 1367 } 1368 1369 // Not supported, clear hint 1370 USE_SINGLE_CGI.value = null; 1371 1372 // Are we at least using single pass supported hostbridge? 1373 res = output.IndexOf("INFO: Display info "); 1374 if (res >= 0) 1375 { 1376 // Check the bridge query version 1377 if (output[res + 19] != '(') 1378 { 1379 return checkNameFail(); 1380 } 1381 int end = output.IndexOf(')', res += 20); 1382 if (end < 0) 1383 { 1384 return checkNameFail(); 1385 } 1386 1387 // Parse the versions 1388 CAFEX_ERROR err = parseVersions(output, checkMionVersion, int.Parse(output.Substring(res, end - res)) > 1); 1389 if (err != CAFEX_ERROR.OK) 1390 { 1391 return err; 1392 } 1393 1394 // Only display warning if firmware is out of sync 1395 Console.WriteLine("cafex {0}: Disabling single pass CGI, not supported", command); 1396 } 1397 } 1398 1399 /* 1400 * Old stop functionality 1401 */ 1402 if (makemine) 1403 { 1404 FSEmul.makemine(); 1405 } 1406 1407 if ((MION_PWR_SEQ.value == "smcreset") && !HARD_STOP) 1408 { 1409 int mionbutton_ret = MionButton.rsthold(args); 1410 HOSTSTOP_RVAL.value = mionbutton_ret.ToString(); 1411 } 1412 else if ((MION_PWR_SEQ.value == "FOFF1") && !HARD_STOP) 1413 { 1414 int mionbutton_ret = MionButton.forceOff1(args); 1415 HOSTSTOP_RVAL.value = mionbutton_ret.ToString(); 1416 } 1417 else 1418 { 1419 string boot_mode_file = Path.Combine(CAFE_TEMP.value, BRIDGE_CURRENT_IP_ADDRESS.value.Replace('.', 'x') + "_" + BRIDGE_CURRENT_NAME.value + "_CAFE_BOOT_MODE"); 1420 string OLD_BOOT_MODE = string.Empty; 1421 if (File.Exists(boot_mode_file)) 1422 { 1423 OLD_BOOT_MODE = File.ReadAllText(boot_mode_file); 1424 } 1425 1426 if (MION_PWR_SEQ.value == "G_SHUTDOWN" && !HARD_STOP && (OLD_BOOT_MODE == CAFE_BOOT_MODE.value)) 1427 { 1428 int mionbutton_ret = MionButton.init_shutdown_w_FOFF2(args); 1429 bAttemptedSoftwareShutdown = true; 1430 HOSTSTOP_RVAL.value = mionbutton_ret.ToString(); 1431 } 1432 else 1433 { 1434 HOSTSTOP_RVAL.value = "1"; 1435 HOSTSTOP_RETRIES.value = "0"; 1436 while (HOSTSTOP_RVAL.value != "0" && HexHandler.GetNumberFromString(HOSTSTOP_RETRIES.value) < 4) 1437 { 1438 if (HexHandler.GetNumberFromString(HOSTSTOP_RETRIES.value) > 0) 1439 { 1440 Console.WriteLine("WARNING: MionButton powerdown failed with err={0}, will retry shortly, count={1}", HOSTSTOP_RVAL.value, HOSTSTOP_RETRIES.value); 1441 Thread.Sleep(new TimeSpan(0, 0, 30)); 1442 } 1443 1444 int mionbutton_ret = MionButton.forceOff2_off_single_cgi(args); 1445 HOSTSTOP_RVAL.value = mionbutton_ret.ToString(); 1446 HOSTSTOP_RETRIES.value = (HexHandler.GetNumberFromString(HOSTSTOP_RETRIES.value) + 1).ToString(); 1447 } 1448 } 1449 } 1450 1451 if (HOSTSTOP_RVAL.value != "0") 1452 { 1453 Console.WriteLine("Gathering MION logs via telnet for the mionbutton return of " + HOSTSTOP_RVAL.value + "."); 1454 string logfile = TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log"; 1455 FileStream fs = new FileStream(logfile, FileMode.Create); 1456 StreamWriter sw = new StreamWriter(fs); 1457 sw.WriteLine("----------------------------------------------------------------"); 1458 sw.WriteLine("----- MION telnet debug log @ " + DateTime.Now.ToLocalTime().ToString() + " -----"); 1459 sw.WriteLine("----------------------------------------------------------------"); 1460 output = string.Empty; 1461 int miontelnet_ret = miontelnet.Run(out output); 1462 sw.Write(output); 1463 sw.Flush(); 1464 sw.Close(); 1465 Console.WriteLine(" See " + logfile + " for details."); 1466 } 1467 } 1468 else 1469 { 1470 int toucanreset_ret = ToucanReset.Reset(); 1471 HOSTSTOP_RVAL.value = toucanreset_ret.ToString(); 1472 } 1473 1474 ToucanReset.Stop(); 1475 1476 if (HOSTSTOP_RVAL.value == "0") 1477 { 1478 return CAFEX_ERROR.OK; 1479 } 1480 1481 if (BRIDGE_TYPE.value == "Mion") 1482 { 1483 if (bAttemptedSoftwareShutdown && HOSTSTOP_RVAL.value == "1") 1484 { 1485 Console.WriteLine("cafex hoststop warning: Software shutdown failed."); 1486 HOSTSTOP_RVAL.value = "0"; 1487 } 1488 else 1489 { 1490 Console.WriteLine("cafex hoststop failed: Could not stop cafe through " + BRIDGE_CURRENT_NAME.value); 1491 checkbridgename.CheckName_IPOnly(); 1492 } 1493 } 1494 else 1495 { 1496 Console.WriteLine("cafex hoststop failed: Could not stop cafe through Toucan."); 1497 } 1498 return CAFEX_ERROR.CHECKNAME_FAILED; 1499 } 1500 hoststop(string[] args)1501 static CAFEX_ERROR hoststop(string[] args) 1502 { 1503 return hoststop(args, false); 1504 } 1505 1506 //Script function: getbridgetype getbridgetype()1507 static void getbridgetype() 1508 { 1509 #if DEBUG 1510 Log.WriteLine("getbridgetype started."); 1511 #endif 1512 1513 BRIDGE_TYPE.value = "Mion"; 1514 if (CAFE_HARDWARE.value.Length > 6) 1515 { 1516 if (CAFE_HARDWARE.value.Substring(6).StartsWith("mp")) 1517 { 1518 BRIDGE_TYPE.value = "Mion"; 1519 } 1520 else if (CAFE_HARDWARE.value.Substring(6) == "1" || CAFE_HARDWARE.value.Substring(6) == "2") 1521 { 1522 BRIDGE_TYPE.value = "Toucan"; 1523 } 1524 } 1525 1526 #if DEBUG 1527 Log.WriteLine("BRIDGE_TYPE set to = " + BRIDGE_TYPE.value); 1528 #endif 1529 } 1530 1531 internal enum CafeBootStage 1532 { 1533 Off, 1534 ServerSync, 1535 SendingSync1, 1536 WaitingForSync1, 1537 SendingFlags, 1538 SendingSync2, 1539 WaitingForSync2, 1540 Booted, 1541 } 1542 trySyncRequest()1543 static bool trySyncRequest() 1544 { 1545 if (cattoucan.SendSyncRequest(DEVKIT_HELP_REQUEST_TIMEOUT)) 1546 { 1547 CMD_RESULT.value = "0"; 1548 return true; 1549 } 1550 1551 CMD_RESULT.value = "1"; 1552 return false; 1553 } 1554 1555 private class CafeBootProgress 1556 { 1557 public CafeBootStage stage = CafeBootStage.Off; 1558 public bool waitForTitle = false; 1559 public bool checkPower = true; 1560 public int tries = 0; 1561 checkVDD2()1562 public void checkVDD2() 1563 { 1564 if (checkPower && mionsig.getVDD2() == 0) 1565 { 1566 stage = CafeBootStage.Off; 1567 } 1568 } 1569 checkKillRestartSoftlaunch()1570 public bool checkKillRestartSoftlaunch() 1571 { 1572 waitForTitle = Environment.GetEnvironmentVariable("USE_KILL_RESTART_SOFTLAUNCH") == "1"; 1573 return waitForTitle; 1574 } 1575 1576 public bool Active 1577 { 1578 get 1579 { 1580 return stage != CafeBootStage.Off; 1581 } 1582 } 1583 } 1584 bootCatDev()1585 static CafeBootStage bootCatDev() 1586 { 1587 cattoucan.FinishSync(true); 1588 1589 List<string> onArguments = new List<string>(); 1590 onArguments.Add("-noprompt"); 1591 if (!string.IsNullOrEmpty(BRIDGE_PARAMETERS_WITH_E.value)) 1592 { 1593 onArguments.AddRange(BRIDGE_PARAMETERS_WITH_E.value.Split(' ')); 1594 } 1595 1596 // discrun support variables 1597 onArguments.Add(ELF_NEST_OPT.value); 1598 onArguments.Add(ELF_NEST_VALUE.value); 1599 1600 string[] noprompt_args = onArguments.ToArray(); 1601 EnvVar.BackUpCurrentEnvironment(); 1602 // Save and check user input 1603 string userProvidedTitleId = CAFERUN_OPTION_MLC_EMU_TITLEID.value; 1604 if (!string.IsNullOrEmpty(userProvidedTitleId)) 1605 { 1606 userProvidedTitleId = userProvidedTitleId.StartsWith("0x") ? userProvidedTitleId.Substring(2).ToLowerInvariant() : userProvidedTitleId.ToLowerInvariant(); 1607 1608 // Then assigns to the variable that will be passed in for verification 1609 CAFERUN_WUMAD_TITLE_ID.value = userProvidedTitleId; 1610 } 1611 // Then assigns to the variable that will be passed in for verification 1612 CAFERUN_WUMAD_TITLE_ID.value = userProvidedTitleId; 1613 1614 IsBooting = true; 1615 CafeXReturn ret = on(noprompt_args, true, true); 1616 IsBooting = false; 1617 1618 if (ret.error != CAFEX_ERROR.OK) 1619 { 1620 if (CMD_RESULT.value == "0") 1621 { 1622 CMD_RESULT.value = "1"; 1623 } 1624 return CafeBootStage.Off; 1625 } 1626 1627 string wumadRetrievedTitleId = CAFERUN_WUMAD_TITLE_ID.value; 1628 EnvVar.RestoreSavedEnvironment(); 1629 // If a value returned and it's different, should take it. 1630 if (!string.IsNullOrEmpty(wumadRetrievedTitleId) && 1631 !wumadRetrievedTitleId.Equals(userProvidedTitleId)) 1632 { 1633 // This is the auto-discovery action. Reset the wumad title id. 1634 CAFERUN_WUMAD_TITLE_ID.value = wumadRetrievedTitleId; 1635 } 1636 1637 // We are cold booting, disable fast relaunch 1638 CAFERUN_OPTION_FAST_RELAUNCH.value = "0"; 1639 return CafeBootStage.ServerSync; 1640 } 1641 tryCafeReboot(bool launch, bool isWumadExecution, CafeBootProgress progress, out CAFEX_ERROR error)1642 static bool tryCafeReboot(bool launch, 1643 bool isWumadExecution, 1644 CafeBootProgress progress, 1645 out CAFEX_ERROR error) 1646 { 1647 bool coldBootIntoApp = progress.waitForTitle && 1648 CAFE_BOOT_MODE.value == "PCFS" && 1649 CAFERUN_OPTION_SOFT_LAUNCH.value != "1" && 1650 CAFERUN_OPTION_FAST_RELAUNCH.value != "1"; 1651 1652 /* Cold booting 1653 * don't wait for title to launch 1654 * or check power on sync 1655 */ 1656 progress.waitForTitle = false; 1657 progress.checkPower = false; 1658 1659 // Cold boot into app if PCFS and not trying to soft or fast launch 1660 if (coldBootIntoApp) 1661 { 1662 error = startBootRun(isWumadExecution, launch, true); 1663 if (error != CAFEX_ERROR.OK || !launch) 1664 { 1665 return false; 1666 } 1667 1668 progress.tries = CAFERUN_RETRY_COUNT; 1669 CMD_RESULT.value = "0"; 1670 } 1671 else 1672 { 1673 error = CAFEX_ERROR.OK; 1674 // Try to boot into sysconfig 1675 if (progress.tries < CAFERUN_LAST_RETRY) 1676 { 1677 progress.stage = bootCatDev(); 1678 if (!progress.Active) 1679 { 1680 progress.tries = CAFERUN_LAST_RETRY; 1681 } 1682 } 1683 } 1684 return true; 1685 } 1686 startBootRun(bool isWumadExecution, bool launch, bool reboot)1687 static CAFEX_ERROR startBootRun(bool isWumadExecution, bool launch, bool reboot) 1688 { 1689 if (reboot) 1690 { 1691 cattoucan.FinishSync(true); 1692 hoststop(null, false); 1693 } 1694 PCFS_SYNC_DATE.value = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-ffff"); 1695 string pcfsSync = string.Format("Starting PCFSServer.exe @ sync date [{0}]", PCFS_SYNC_DATE.value); 1696 Console.WriteLine(pcfsSync); 1697 #if DEBUG 1698 Log.WriteLine(pcfsSync); 1699 #endif 1700 pcfsSync = null; 1701 #if TIMER 1702 CafeXSetupTime.Report(); 1703 #endif 1704 CMD_RESULT.value = PCFSServer.Start(PCFSSERVER_PARAMETERS.value, PCFS_DIR_MAPPING.value, PCFS_SRV_LOG_OUTPUT.value).ToString(); 1705 1706 Console.WriteLine("PCFSServer has started"); 1707 #if DEBUG 1708 Log.WriteLine("PCFSServer has started"); 1709 #endif 1710 1711 #if TIMER 1712 CafeXSetupTime.Report(); 1713 #endif 1714 1715 if (PCFSSERVER_PARAMETERS.value != null) 1716 { 1717 Console.WriteLine("Waiting for PCFSServer initialization..."); 1718 PCFSSERVERSYNC_RVAL.value = PCFSServerSync.wait_sync(PCFS_SYNC_DATE.value).ToString(); 1719 if (PCFSSERVERSYNC_RVAL.value != "0") 1720 { 1721 Console.WriteLine("PCFSServerSync exited with value " + PCFSSERVERSYNC_RVAL.value); 1722 return CAFEX_ERROR.RUN_PCFSSERVER_SYNC_FAILED; 1723 } 1724 Console.WriteLine("PCFSServer initialization complete!"); 1725 } 1726 else 1727 { 1728 Console.WriteLine("PCFSServer started without synchronization"); 1729 } 1730 1731 BOOTRUN_ELF_OPT.value = ""; 1732 BOOTRUN_ELF_VALUE.value = ""; 1733 if (!string.IsNullOrEmpty(SOFT_LAUNCH_CAFE_ELF.value)) 1734 { 1735 BOOTRUN_ELF_OPT.value = "-usedlf"; 1736 BOOTRUN_ELF_VALUE.value = SOFT_LAUNCH_CAFE_ELF.value; 1737 } 1738 1739 // Check if this is a wumad execution, so that bootrun can correctly assign the title Id 1740 if (isWumadExecution) 1741 { 1742 if (!string.IsNullOrEmpty(CAFERUN_OPTION_MLC_EMU_TITLEID.value)) 1743 { 1744 // Saves user input 1745 string userProvidedTitleId = CAFERUN_OPTION_MLC_EMU_TITLEID.value.StartsWith("0x") ? CAFERUN_OPTION_MLC_EMU_TITLEID.value.Substring(2).ToLowerInvariant() : CAFERUN_OPTION_MLC_EMU_TITLEID.value.ToLowerInvariant(); 1746 // Then assigns to the variable that will be passed in for verification 1747 CAFERUN_WUMAD_TITLE_ID.value = userProvidedTitleId; 1748 } 1749 else 1750 { 1751 // Ensure there is no title, so autodiscovery can run 1752 CAFERUN_WUMAD_TITLE_ID.value = string.Empty; 1753 } 1754 } 1755 1756 if (launch == false) 1757 { 1758 return CAFEX_ERROR.OK; 1759 } 1760 1761 #if TIMER 1762 Log.WriteLine("Launching bootrun"); 1763 CafeXSetupTime.Report(); 1764 #endif 1765 CAFEX_ERROR bootrun_ret = bootrun(new List<string>() { BOOTRUN_ELF_OPT.value, BOOTRUN_ELF_VALUE.value }, fAppTypeDefined); 1766 if (bootrun_ret != CAFEX_ERROR.OK) 1767 { 1768 return bootrun_ret; 1769 } 1770 #if TIMER 1771 Log.WriteLine("Bootrun end"); 1772 CafeXSetupTime.Report(); 1773 #endif 1774 return CAFEX_ERROR.OK; 1775 } 1776 1777 //Script function: caferun run(string[] args, bool runSetup, bool launch)1778 static CafeXReturn run(string[] args, bool runSetup, bool launch) 1779 { 1780 CafeXReturn ret = new CafeXReturn(CAFEX_ERROR.UNEXPECTED); //TODO: Spread the love to the other return paths. 1781 1782 // Check to see if we have default options 1783 if (!String.IsNullOrEmpty(CAFERUN_DEFAULT_OPTIONS.value)) 1784 { 1785 // Warn the user that any default options will get overwritten if matching switches are specified on the command line. 1786 Log.WriteLine("*** CAFERUN_DEFAULT_OPTIONS *** Default options detected! Please be aware that any duplicate switches on the command line will overwrite the defaults specified!"); 1787 1788 // Split the string into array elements and then create the new args array 1789 string[] temp; 1790 temp = CAFERUN_DEFAULT_OPTIONS.value.Split(' '); 1791 1792 // We need to expand the args array so we can add the new args into it. 1793 int newLen = (temp.Length + args.Length); 1794 Array.Resize<string>(ref args, newLen); 1795 1796 string[] defaultArgs = new string[newLen]; 1797 Array.Copy(temp, defaultArgs, temp.Length); 1798 Array.Copy(args, 0, defaultArgs, temp.Length, (args.Length - temp.Length)); 1799 1800 args = defaultArgs; 1801 } 1802 1803 #if DEBUG 1804 Log.WriteLine("~~~~~~~~~~~~~~~~ START ENV VARIABLES~~~~~~~~~~~~~~~~~~"); 1805 IDictionary environmentVariables = Environment.GetEnvironmentVariables(); 1806 foreach (DictionaryEntry de in environmentVariables) 1807 { 1808 Log.WriteLine(string.Format(" {0} = {1}", de.Key, de.Value)); 1809 } 1810 Log.WriteLine("~~~~~~~~~~~~~~~~ END ENV VARIABLES~~~~~~~~~~~~~~~~~~"); 1811 1812 Log.WriteLine(string.Format("**** Current Working Directory = {0} ****", Directory.GetCurrentDirectory())); 1813 Log.WriteLine("run started."); 1814 string argString = null; 1815 if (args != null) 1816 { 1817 foreach (string arg in args) 1818 { 1819 argString += arg + " "; 1820 } 1821 } 1822 Log.WriteLine("Arguments=" + argString); 1823 1824 #endif 1825 #region setup 1826 bool isWumadExecution = false; 1827 if (runSetup == true) 1828 { 1829 if (CAFERUN_INS.value == null) 1830 { 1831 CAFERUN_INS.value = "0"; 1832 } 1833 1834 // This tells if the current call contains wumad parameters. 1835 PLATFORM.value = "cafe"; 1836 1837 QUIET.value = "-q"; 1838 CAFESTOP_ONLY_IF_FSEMUL.value = "0"; 1839 PPC_OS_FLAGS.value = "0"; 1840 PPC_APP_FLAGS.value = "0"; 1841 PCFS_SYNC_DATE.value = ""; 1842 MCP_LAUNCH_HINT.value = ""; 1843 MCP_INFO_OPTION.value = ""; 1844 if (DEBUGGER.value == null) 1845 { 1846 DEBUGGER.value = "none"; 1847 } 1848 1849 if (CAFE_CONSOLE.value == null) 1850 { 1851 CONSOLE.value = "cattoucan"; 1852 } 1853 else 1854 { 1855 CONSOLE.value = CAFE_CONSOLE.value; 1856 } 1857 1858 if (CAFE_DEBUG_PORT.value == null) 1859 { 1860 CAFE_DEBUG_PORT.value = "toucan"; 1861 } 1862 1863 if (DEBUG_ELF_FILE.value == null) 1864 { 1865 DEBUG_ELF_FILE.value = ""; 1866 } 1867 1868 CAFERUN_OPTION_SOFT_RESTART.value = "0"; 1869 CAFERUN_OPTION_FAST_RELAUNCH.value = "0"; 1870 CAFERUN_OPTION_MLC_EMU_LAUNCH.value = "0"; 1871 CAFERUN_OPTION_MLC_EMU_TITLEID.value = "0xFFFFFFFFFFFFFFFF"; 1872 string sdk_ver_file = CAFE_ROOT.value + "\\system\\include\\sdk_ver.h"; 1873 if (!File.Exists(sdk_ver_file)) 1874 { 1875 Console.WriteLine("cafex run error: sdk_ver.h does not exist: " + sdk_ver_file); 1876 return new CafeXReturn(CAFEX_ERROR.RUN_NO_SDK_VERSION_HEADER); 1877 } 1878 1879 FileStream fs = new FileStream(CAFE_ROOT.value + "\\system\\include\\sdk_ver.h", FileMode.Open, FileAccess.Read); 1880 StreamReader sr = new StreamReader(fs); 1881 bool found_line = false; 1882 while (!sr.EndOfStream) 1883 { 1884 string line = sr.ReadLine(); 1885 if (line.Contains("00050010")) 1886 { 1887 int index = line.IndexOf("00050010"); 1888 string version = line.Substring(index, 16); 1889 CAFERUN_OS_MAJOR_VERSION_LO.value = version.Substring(8, 8); 1890 CAFERUN_OS_MAJOR_VERSION.value = version.Substring(14, 2); 1891 if (CAFERUN_COLDBOOT_OS_VERSION.value == null) 1892 CAFERUN_COLDBOOT_OS_VERSION.value = "0x00050010100040" + CAFERUN_OS_MAJOR_VERSION.value; 1893 else 1894 CAFERUN_COLDBOOT_OS_VERSION.value = "0x" + CAFERUN_COLDBOOT_OS_VERSION.value; 1895 found_line = true; 1896 break; 1897 } 1898 } 1899 sr.Close(); 1900 if (!found_line) 1901 { 1902 Console.WriteLine("cafex run error: couldn't find sdk version in sdk_ver.h"); 1903 return new CafeXReturn(CAFEX_ERROR.RUN_COULDNT_PARSE_SDK_VERSION_HEADER); 1904 } 1905 #if DEBUG 1906 Log.WriteLine("CAFERUN_COLDBOOT_OS_VERSION set to '" + CAFERUN_COLDBOOT_OS_VERSION.value + "' from file " + CAFE_ROOT.value + "\\system\\include\\sdk_ver.h"); 1907 #endif 1908 HEARTBEAT_DISABLE.value = "0"; 1909 PCFS_DIR_MAPPING.value = ""; 1910 MAPDIR_MLC.value = ""; 1911 MAPDIR_SLC.value = ""; 1912 MAPDIR_CODE.value = ""; 1913 MAPDIR_META.value = ""; 1914 MAPDIR_CONTENT.value = ""; 1915 MAPDIR_SAVE.value = ""; 1916 PCFS_LOG_TIMESTAMP.value = ""; 1917 PCFS_SRV_LOG_OUTPUT.value = ""; 1918 RUN_FROM_HDD_BANK.value = ""; 1919 BRIDGE_PARAMETERS.value = ""; 1920 BRIDGE_PARAMETERS_WITH_E.value = ""; 1921 PCFSSERVER_PARAMETERS.value = ""; 1922 PCFS_OVER_SATA_PORT.value = ""; 1923 if (PCFS_HEADLESS_EMUL.value == null) 1924 { 1925 PCFS_HEADLESS_EMUL.value = "-pcfsenable"; 1926 } 1927 1928 PREPHDD_STAT.value = ""; 1929 DISC_EMU_TID.value = ""; 1930 SYSTEM_MODE.value = ""; 1931 RPL_DIRS.value = ""; 1932 RPL_FILES.value = ""; 1933 1934 if (CAFERUN_OPTION_NO_DATA_SYNC.value == null) 1935 { 1936 CAFERUN_OPTION_NO_DATA_SYNC.value = "0"; 1937 } 1938 1939 if (command != "on" && command != "setbootmode" && CAFE_BOOT_MODE.value == "NAND") 1940 { 1941 CAFERUN_OPTION_SOFT_LAUNCH.value = "1"; 1942 } 1943 else 1944 { 1945 CAFERUN_OPTION_SOFT_LAUNCH.value = "0"; 1946 } 1947 #if DEBUG 1948 Log.WriteLine("CAFERUN_OPTION_SOFT_LAUNCH set to " + CAFERUN_OPTION_SOFT_LAUNCH.value); 1949 #endif 1950 1951 CAFERUN_HOSTBRIDGE_VERSION.value = "unknown"; 1952 CAFERUN_FW_VERSION.value = "unknown"; 1953 1954 if (CAFE_DEBUG_INIT.value == null) 1955 { 1956 CAFE_DEBUG_INIT.value = "0"; 1957 } 1958 1959 if (CAFE_DEBUG_PREINIT.value == null) 1960 { 1961 CAFE_DEBUG_PREINIT.value = "0"; 1962 } 1963 1964 if (CAFE_DEBUG_DONTSTOP.value == null) 1965 { 1966 CAFE_DEBUG_DONTSTOP.value = "0"; 1967 } 1968 1969 if (CAFE_LAUNCH_DEBUG.value == null) 1970 { 1971 CAFE_LAUNCH_DEBUG.value = "1"; 1972 } 1973 1974 if (CAFE_SYSLOG_LEVEL.value == null) 1975 { 1976 CAFE_SYSLOG_LEVEL.value = "1"; 1977 } 1978 1979 if (CAFE_RUN_FORCERESTART.value == null) 1980 { 1981 CAFE_RUN_FORCERESTART.value = "0"; 1982 } 1983 1984 if (DEBUG_PROC_ID.value == null) 1985 { 1986 DEBUG_PROC_ID.value = "15"; 1987 } 1988 if (CAFERUN_OPTION_KILL_RESTART.value == null) 1989 { 1990 CAFERUN_OPTION_KILL_RESTART.value = "0"; 1991 } 1992 1993 DEBUG_FLAGS.value = "0"; 1994 1995 if (CAFE_DEBUG_INIT.value != "0") 1996 { 1997 DEBUG_FLAGS.value = "16"; 1998 } 1999 2000 if (CAFE_DEBUG_DONTSTOP.value != "0") 2001 { 2002 DEBUG_FLAGS.value = "32"; 2003 } 2004 2005 if (CAFE_DEBUG_PREINIT.value != "0") 2006 { 2007 DEBUG_FLAGS.value = "64"; 2008 } 2009 2010 if (USE_EXI_AS_DEBUG_CHANNEL.value == null || USE_EXI_AS_DEBUG_CHANNEL.value.Equals("0")) 2011 { 2012 UInt32 dbgFlags = HexHandler.GetNumberFromString(DEBUG_FLAGS.value) | 256; 2013 DEBUG_FLAGS.value = dbgFlags.ToString(); 2014 } 2015 2016 CATOUTPUT.value = "0"; 2017 CMDOUTPUT.value = "0"; 2018 2019 switch (CONSOLE.value) 2020 { 2021 case "sdio": 2022 { 2023 CONSOLE.value = "toucan"; 2024 break; 2025 } 2026 case "cattoucan": 2027 { 2028 CONSOLE.value = "toucan"; 2029 DEBUGGER.value = "cattoucan"; 2030 CATOUTPUT.value = "1"; 2031 break; 2032 } 2033 case "cmdtoucan": 2034 { 2035 CONSOLE.value = "toucan"; 2036 DEBUGGER.value = "cattoucan"; 2037 CMDOUTPUT.value = "1"; 2038 break; 2039 } 2040 } 2041 2042 if (CAFE_AUTOTEST.value == "1") 2043 { 2044 DEBUGGER.value = "none"; 2045 } 2046 2047 #if DEBUG 2048 Log.WriteLine("CONSOLE = " + CONSOLE.value); 2049 Log.WriteLine("DEBUGGER = " + DEBUGGER.value); 2050 Log.WriteLine("CATOUTPUT= " + CATOUTPUT.value); 2051 Log.WriteLine("CMDOUTPUT= " + CMDOUTPUT.value); 2052 #endif 2053 } 2054 //if (launch == false) 2055 //{ 2056 // return new CafeXReturn(CAFEX_ERROR.OK); 2057 //} 2058 #endregion 2059 2060 int rpx_index = args.Length; 2061 for (int i = 0; i < args.Length; ++i) 2062 { 2063 if (args[i].ToLowerInvariant().Contains(".rpx") || args[i].ToLowerInvariant().Contains(".elf")) 2064 { 2065 // Ensure the RPX is not the argument of an option 2066 if ( i > 0 && 2067 ( args[i - 1].Trim().Equals("-k") || 2068 args[i - 1].Trim().Equals("-l") || 2069 args[i - 1].ToLowerInvariant().Trim().Equals("-e"))) 2070 { 2071 // Exceptions: If ELF/RPX is argument of "-k" or "-l". 2072 continue; 2073 } 2074 else 2075 { 2076 // Default: ELF/RPX found is the one to run. 2077 rpx_index = i; 2078 break; 2079 } 2080 } 2081 } 2082 2083 #if DEBUG 2084 Log.WriteLine("Search for RPX index returned index = " + rpx_index.ToString()); 2085 #endif 2086 2087 #region arguments 2088 2089 for (int i = 0; i < rpx_index; ++i) 2090 { 2091 switch (args[i]) 2092 { 2093 case "-m": 2094 { 2095 Console.WriteLine("cafex run failed: memmap not supported"); 2096 run_usage(); 2097 return new CafeXReturn(CAFEX_ERROR.RUN_MEMMAP_NOT_SUPPORTED); 2098 } 2099 2100 case "-g": 2101 { 2102 if (!ArgumentChecks.IsArgumentValidSetting(args, i + 1)) 2103 { 2104 run_usage(); 2105 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2106 } 2107 2108 uint prev_value = HexHandler.GetNumberFromString(PPC_OS_FLAGS.value); 2109 uint arg_value; 2110 if (String.IsNullOrEmpty(args[i + 1])) 2111 { 2112 Console.WriteLine("WARNING: Value after -g is null or empty. Option is ignored."); 2113 arg_value = 0; 2114 } 2115 else 2116 { 2117 arg_value = HexHandler.GetNumberFromString(args[i + 1]); 2118 } 2119 2120 uint new_value = prev_value | arg_value; 2121 PPC_OS_FLAGS.value = new_value.ToString(); 2122 //MULTI sends -g 1 to PPC_OS_FLAGS telling it that debugger is attached 2123 //equivalent to ==> -d multi 2124 if ((arg_value & 0x1) == 1) 2125 { 2126 g_gArgValue = 1; 2127 } 2128 ++i; 2129 break; 2130 } 2131 2132 case "-p": 2133 { 2134 if (!ArgumentChecks.IsArgumentValidSetting(args, i + 1)) 2135 { 2136 run_usage(); 2137 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2138 } 2139 2140 if (String.IsNullOrEmpty(args[i + 1])) 2141 { 2142 //DEBUG_PROC_ID has a default value of 15, or whatever the user may have set in the env 2143 //This is why it's not set here. 2144 Console.WriteLine("WARNING: Value for -p is null or empty. Debugger will break in the default process ({0}).", DEBUG_PROC_ID.value); 2145 } 2146 else 2147 { 2148 DEBUG_PROC_ID.value = args[i + 1]; 2149 } 2150 uint debug_flags = HexHandler.GetNumberFromString(DEBUG_FLAGS.value); 2151 uint debug_proc_id = HexHandler.GetNumberFromString(DEBUG_PROC_ID.value); 2152 if ((debug_flags & 0xf) != 0) 2153 { 2154 uint new_value = (uint)(debug_flags & ~0xf) | (debug_proc_id & 0xf); 2155 DEBUG_FLAGS.value = new_value.ToString(); 2156 } 2157 ++i; 2158 break; 2159 } 2160 2161 case "-d": 2162 { 2163 if (!ArgumentChecks.IsArgumentValidSetting(args, i + 1)) 2164 { 2165 run_usage(); 2166 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2167 } 2168 2169 DEBUGGER.value = args[i + 1]; 2170 uint debug_flags = HexHandler.GetNumberFromString(DEBUG_FLAGS.value); 2171 uint debug_proc_id = HexHandler.GetNumberFromString(DEBUG_PROC_ID.value); 2172 uint new_value = debug_flags | (debug_proc_id & 0xf); 2173 DEBUG_FLAGS.value = new_value.ToString(); 2174 //CAFE_RUN_FORCERESTART.value = "1"; 2175 ++i; 2176 break; 2177 } 2178 2179 case "-k": 2180 { 2181 if (!ArgumentChecks.IsArgumentValidSetting(args, i + 1)) 2182 { 2183 run_usage(); 2184 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2185 } 2186 2187 DEBUG_ELF_FILE.value = args[i + 1]; 2188 ++i; 2189 break; 2190 } 2191 2192 case "-w": 2193 { 2194 if (!ArgumentChecks.IsArgumentValidSetting(args, i + 1)) 2195 { 2196 run_usage(); 2197 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2198 } 2199 2200 uint prev_value = HexHandler.GetNumberFromString(PPC_OS_FLAGS.value); 2201 uint arg_value = 0; 2202 try 2203 { 2204 arg_value = HexHandler.GetNumberFromString(args[i + 1]); 2205 } 2206 catch (FormatException) 2207 { 2208 Console.WriteLine("cafex : argument for -w option is not a valid number and will be ignored."); 2209 } 2210 2211 uint new_value = prev_value | arg_value; 2212 PPC_OS_FLAGS.value = new_value.ToString(); 2213 ++i; 2214 break; 2215 } 2216 2217 case "-a": 2218 { 2219 if (!ArgumentChecks.ArgumentExists(args, i + 1)) 2220 { 2221 run_usage(); 2222 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2223 } 2224 2225 DASH_A_ARGS.value = args[i + 1]; 2226 ++i; 2227 break; 2228 } 2229 2230 case "-o": 2231 { 2232 if (!ArgumentChecks.IsArgumentValidSetting(args, i + 1)) 2233 { 2234 run_usage(); 2235 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2236 } 2237 if (String.IsNullOrEmpty(args[i + 1])) 2238 { 2239 Console.WriteLine("WARNING: value for -o was null or empty, so it will be treated as 0."); 2240 CAFERUN_COLDBOOT_OS_VERSION.value = "0x0000000000000000"; 2241 } 2242 else 2243 { 2244 CAFERUN_COLDBOOT_OS_VERSION.value = args[i + 1]; 2245 } 2246 ++i; 2247 break; 2248 } 2249 2250 case "-b": 2251 { 2252 CAFERUN_COLDBOOT_OS_VERSION.value = "0x00050010100080" + CAFERUN_OS_MAJOR_VERSION.value; 2253 break; 2254 } 2255 2256 case "-C": 2257 { 2258 CAFERUN_COLDBOOT_OS_VERSION.value = "0x00050010100040FE"; 2259 break; 2260 } 2261 2262 case "-u": 2263 { 2264 CAFERUN_COLDBOOT_OS_VERSION.value = "0x000500101000C0" + CAFERUN_OS_MAJOR_VERSION.value; 2265 break; 2266 } 2267 2268 case "-n": 2269 { 2270 uint prev_value = HexHandler.GetNumberFromString(PPC_OS_FLAGS.value); 2271 uint new_value = prev_value | 0x02000; 2272 PPC_OS_FLAGS.value = new_value.ToString(); 2273 break; 2274 } 2275 2276 case "-i": 2277 { 2278 uint prev_value = HexHandler.GetNumberFromString(DEBUG_FLAGS.value); 2279 uint new_value = prev_value | 16; 2280 DEBUG_FLAGS.value = new_value.ToString(); 2281 break; 2282 } 2283 2284 case "-R": 2285 { 2286 uint prev_value = HexHandler.GetNumberFromString(DEBUG_FLAGS.value); 2287 uint new_value = prev_value | 32; 2288 DEBUG_FLAGS.value = new_value.ToString(); 2289 break; 2290 } 2291 2292 case "-j": 2293 { 2294 uint prev_value = HexHandler.GetNumberFromString(DEBUG_FLAGS.value); 2295 uint new_value = prev_value | 64; 2296 DEBUG_FLAGS.value = new_value.ToString(); 2297 break; 2298 } 2299 2300 case "-q": 2301 { 2302 CAFE_SYSLOG_LEVEL.value = "0"; 2303 break; 2304 } 2305 2306 case "-v": 2307 { 2308 if (!ArgumentChecks.IsArgumentValidSetting(args, i + 1)) 2309 { 2310 run_usage(); 2311 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2312 } 2313 CAFE_SYSLOG_LEVEL.value = args[i + 1]; 2314 2315 int sysloglvl = 0; 2316 if (int.TryParse(CAFE_SYSLOG_LEVEL.value, out sysloglvl)) 2317 { 2318 sysloglvl &= 7; 2319 CAFE_SYSLOG_LEVEL.value = sysloglvl.ToString(); 2320 } 2321 else 2322 { 2323 Console.WriteLine("Unable to convert CAFE_SYSLOG_LEVEL to integer."); 2324 return new CafeXReturn(CAFEX_ERROR.SYSLOG_LEVEL_SET_FAILED); 2325 } 2326 2327 ++i; 2328 break; 2329 } 2330 2331 case "-e": 2332 { 2333 if (!ArgumentChecks.ArgumentExists(args, i + 1)) 2334 { 2335 run_usage(); 2336 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2337 } 2338 2339 if (args[i + 1].StartsWith("mcp")) 2340 { 2341 if (args[i + 1].Length < 4) 2342 { 2343 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2344 } 2345 2346 string new_val = args[i + 1].Substring(4); 2347 MCP_INFO_OPTION.value = new_val; 2348 if (new_val.StartsWith("launch_hint")) 2349 { 2350 if (new_val.Length < 12) 2351 { 2352 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2353 } 2354 2355 MCP_LAUNCH_HINT.value = new_val.Substring(12); 2356 2357 // Check if user wants to launch from somewhere else than the wumad 2358 if (isWumadExecution && command != "on" && string.Compare(MCP_LAUNCH_HINT.value, "odd", true) != 0) 2359 { 2360 Console.WriteLine("WARNING: overriding launch hint for wumad with " + MCP_LAUNCH_HINT.value); 2361 } 2362 } 2363 } 2364 else if (args[i + 1] == "nopcfs") 2365 { 2366 Console.WriteLine("cafex run: Emulating PCFS Headless Mode."); 2367 PCFS_HEADLESS_EMUL.value = "-pcfsdisable"; 2368 } 2369 else if (args[i + 1] == "noFFIO") 2370 { 2371 // This is the designation for PCFSServer to disable Fast File IO 2372 Console.WriteLine("cafex run: Disabling PCFS Fast File IO."); 2373 PCFSSERVER_PARAMETERS.AddToVar("-noFFIO", ' '); 2374 } 2375 else if (args[i + 1] == "noCSR") 2376 { 2377 // This is the designation for PCFSServer to disable cafe from using the combined send+recv in MION 2378 Console.WriteLine("cafex run: Disabling MION send/recv support."); 2379 PCFSSERVER_PARAMETERS.AddToVar("-noCSR", ' '); 2380 } 2381 else if (args[i + 1] == "sdioasdbgr") 2382 { 2383 // make sure to change the port for SDIO from 7977 to 6002 2384 USE_EXI_AS_DEBUG_CHANNEL.value = "0"; 2385 } 2386 else if (args[i + 1].ToLowerInvariant().StartsWith("ejectstate")) 2387 { 2388 // Set the MION eject state (in or out) before launching 2389 if (args[i + 1].Length < 11) 2390 { 2391 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2392 } 2393 2394 EJECT_STATE.value = args[i + 1].Substring(11); 2395 if (EJECT_STATE.value != "in" && EJECT_STATE.value != "out") 2396 { 2397 Console.WriteLine("cafex: Invalid eject state parameter '{0}'! Please specify 'in' or 'out'.", EJECT_STATE.value); 2398 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2399 } 2400 } 2401 else if (args[i + 1].ToLowerInvariant().StartsWith("wumad")) 2402 { 2403 if (args[i + 1].Length < 6) 2404 { 2405 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2406 } 2407 2408 CAFE_WUMAD.value = PathConverter.Windowsify(args[i + 1].Substring(6)); 2409 2410 // Check to make sure CAFE_WUMAD.value isn't empty 2411 // 2412 if(String.IsNullOrEmpty(CAFE_WUMAD.value)) 2413 { 2414 Console.WriteLine("Invalid WUMAD argument!"); 2415 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2416 } 2417 2418 BRIDGE_PARAMETERS.AddToVar("-sata", ' '); 2419 BRIDGE_PARAMETERS_WITH_E.AddToVar("-e sata", ' '); 2420 CAFE_RUN_FORCERESTART.value = "1"; 2421 isWumadExecution = true; 2422 2423 // Force launching the wumad from ODD (if user didn't specify a launch hint, or cafex on) 2424 if (command != "on") 2425 { 2426 if (string.IsNullOrEmpty(MCP_LAUNCH_HINT.value)) 2427 { 2428 MCP_LAUNCH_HINT.value = "odd"; 2429 } 2430 else if (string.Compare(MCP_LAUNCH_HINT.value, "odd", true) != 0) 2431 { 2432 Console.WriteLine("WARNING: overriding launch hint for wumad with " + MCP_LAUNCH_HINT.value); 2433 } 2434 } 2435 } 2436 else if (args[i + 1].ToLowerInvariant().StartsWith("soft_launch_cafe_elf")) 2437 { 2438 // This is the CAFE_ELF of the top level execution 2439 // that invoked this run to power on. This is ued 2440 // to create the disk image. 2441 CAFERUN_OPTION_CALLED_FROM_CAFEDISCRUN.value = "yes"; 2442 SOFT_LAUNCH_CAFE_ELF.value = args[i + 1].Substring(21); 2443 } 2444 else if (args[i + 1].ToLowerInvariant().StartsWith("eco")) 2445 { 2446 // eco mode debugging case 2447 ECO_MODE.value = "1"; 2448 _CCRSYSCFG1.value = "0x20000000"; 2449 } 2450 else 2451 { 2452 BRIDGE_PARAMETERS.AddToVar("-" + args[i + 1], ' '); 2453 BRIDGE_PARAMETERS_WITH_E.AddToVar("-e " + args[i + 1], ' '); 2454 2455 if (args[i + 1].StartsWith("h")) 2456 { 2457 if (args[i + 1].Length < 2) 2458 { 2459 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2460 } 2461 2462 RUN_FROM_HDD_BANK.value = args[i + 1].Substring(2); 2463 2464 // Check the value of RUN_FROM_HDD_BANK to be sure that it 2465 // is a number in the range of 0 - 60 (inclusive) 2466 // 2467 int hdd_bank = -1; 2468 bool result = int.TryParse(RUN_FROM_HDD_BANK.value, out hdd_bank); 2469 if (!result) 2470 { 2471 Console.WriteLine("CafeX: Invalid HDD bank value!"); 2472 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2473 } 2474 else 2475 { 2476 // Make sure the number is in range 2477 // 2478 int MinHDDBankNo = 0; 2479 int MaxHDDBankNo = 60; 2480 if ( (hdd_bank < MinHDDBankNo) || (hdd_bank > MaxHDDBankNo) ) 2481 { 2482 Console.WriteLine("CafeX: Invalid HDD bank value!"); 2483 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2484 } 2485 } 2486 } 2487 if (args[i + 1].StartsWith("pcfsport")) 2488 { 2489 if (args[i + 1].Length < 9) 2490 { 2491 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2492 } 2493 2494 PCFS_OVER_SATA_PORT.value = args[i + 1].Substring(9); 2495 USE_PCFS_OVER_SATA.value = "1"; 2496 } 2497 if (args[i + 1].StartsWith("sdio")) 2498 { 2499 // If the Host Bridge does not support this option, remove it 2500 // This option was implemented with HB 3.2.4.4 2501 2502 CAFEX_ERROR hostcheckversion_ret = hostcheckversion(); 2503 if(hostcheckversion_ret != CAFEX_ERROR.OK) 2504 return new CafeXReturn(hostcheckversion_ret); 2505 2506 if (sw_ver_flat < compute_flat_version("3.2.4.4")) 2507 { 2508 BRIDGE_PARAMETERS.RemoveFromVar("-sdio", ' '); 2509 BRIDGE_PARAMETERS_WITH_E.RemoveFromVar("-sdio", ' '); 2510 } 2511 } 2512 } 2513 2514 ++i; 2515 break; 2516 } 2517 2518 case "-c": 2519 { 2520 DEBUGGER.value = "cattoucan"; 2521 break; 2522 } 2523 2524 case "-f": 2525 { 2526 CAFESTOP_ONLY_IF_FSEMUL.value = "1"; 2527 break; 2528 } 2529 2530 case "-s": 2531 { 2532 CAFERUN_OPTION_SOFT_LAUNCH.value = "1"; 2533 break; 2534 } 2535 2536 case "-y": 2537 { 2538 CAFERUN_OPTION_FAST_RELAUNCH.value = "1"; 2539 if (string.IsNullOrEmpty(CAFERUN_OPTION_FASTLAUNCH_RETRIES.value)) 2540 { 2541 CAFERUN_OPTION_FASTLAUNCH_RETRIES.value = COSDEBUG_FASTLAUNCH_RETRIES.ToString(); 2542 } 2543 if (string.IsNullOrEmpty(CAFERUN_OPTION_FASTLAUNCH_TIMEOUT.value)) 2544 { 2545 CAFERUN_OPTION_FASTLAUNCH_TIMEOUT.value = COSDEBUG_FASTLAUNCH_TIMEOUT.ToString(); 2546 } 2547 if (string.IsNullOrEmpty(CAFERUN_OPTION_FASTLAUNCH_DELAY.value)) 2548 { 2549 CAFERUN_OPTION_FASTLAUNCH_DELAY.value = COSDEBUG_FASTLAUNCH_DELAY.ToString(); 2550 } 2551 break; 2552 } 2553 2554 case "-r": 2555 { 2556 CAFERUN_OPTION_SOFT_RESTART.value = "1"; 2557 break; 2558 } 2559 2560 case "-F": 2561 { 2562 CAFE_RUN_FORCERESTART.value = "1"; 2563 break; 2564 } 2565 2566 case "-K": //Option to execute kill restart 2567 { 2568 // Set the restart option as a backup 2569 CAFERUN_OPTION_SOFT_RESTART.value = "1"; 2570 g_KOptionSet = true; 2571 break; 2572 } 2573 2574 case "-L": 2575 { 2576 IGNORE_VERSION.value = "1"; 2577 break; 2578 } 2579 2580 case "-t": 2581 { 2582 if (!ArgumentChecks.IsArgumentValidSetting(args, i + 1)) 2583 { 2584 run_usage(); 2585 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2586 } 2587 2588 if ((args[i + 1].Length == 18 && args[i + 1].StartsWith("0x")) || args[i + 1].Length == 16) 2589 { 2590 Int64 titleid; 2591 bool isNumber = false; 2592 2593 if (args[i + 1].StartsWith("0x")) 2594 { 2595 //strip the 0x 2596 isNumber = Int64.TryParse(args[i + 1].Remove(0, 2), System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out titleid); 2597 } 2598 else 2599 { 2600 isNumber = Int64.TryParse(args[i + 1], System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out titleid); 2601 } 2602 2603 if (isNumber) 2604 { 2605 CAFERUN_OPTION_MLC_EMU_LAUNCH.value = "1"; 2606 CAFERUN_OPTION_MLC_EMU_TITLEID.value = (args[i + 1].Length == 16) ? "0x" + args[i + 1] : args[i + 1]; 2607 } 2608 else 2609 { 2610 Console.WriteLine("Invalid title ID detected!"); 2611 Console.WriteLine("Please ensure that all characters in the -t argument are hexadecimal."); 2612 return new CafeXReturn(CAFEX_ERROR.RUN_BAD_TITLE_ID); 2613 } 2614 } 2615 else 2616 { 2617 Console.WriteLine("Title ID has incorrect length."); 2618 Console.WriteLine("A correct ID is 18 characters plus 0x in the beginning or 16 without 0x."); 2619 Console.WriteLine("Ex: 0x1234567812345678 or 1234567812345678"); 2620 Console.WriteLine("Found: {0}", args[i + 1]); 2621 return new CafeXReturn(CAFEX_ERROR.RUN_BAD_TITLE_ID); 2622 } 2623 ++i; 2624 break; 2625 } 2626 2627 case "-l": 2628 { 2629 if (!ArgumentChecks.IsArgumentValidSetting(args, i + 1)) 2630 { 2631 run_usage(); 2632 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2633 } 2634 2635 if (!args[i + 1].EndsWith(".rpl")) 2636 { 2637 // CafeX addToVar does not use space as delimiter for the list, so there is no need to replace spaces with "|". 2638 RPL_DIRS.AddToVar(args[i + 1], DEFAULT_DELIMITER); 2639 } 2640 else 2641 { 2642 // CafeX addToVar does not use space as delimiter for the list, so there is no need to replace spaces with "|". 2643 RPL_FILES.AddToVar(args[i + 1], DEFAULT_DELIMITER); 2644 } 2645 ++i; 2646 break; 2647 } 2648 2649 case "-h": 2650 { 2651 run_usage(); 2652 return new CafeXReturn(CAFEX_ERROR.OK); 2653 } 2654 2655 case "-H": 2656 { 2657 if (!ArgumentChecks.IsArgumentValidSetting(args, i + 1)) 2658 { 2659 run_usage(); 2660 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2661 } 2662 2663 if (args[i + 1] == "disable") 2664 { 2665 HEARTBEAT_DISABLE.value = "0x00020000"; 2666 } 2667 else if (args[i + 1] == "enable") 2668 { 2669 HEARTBEAT_DISABLE.value = "0"; 2670 } 2671 else 2672 { 2673 run_usage(); 2674 return new CafeXReturn(CAFEX_ERROR.RUN_BAD_H_ARGUMENT); 2675 } 2676 ++i; 2677 break; 2678 } 2679 2680 case "-x": 2681 { 2682 BRIDGE_PARAMETERS.AddToVar("-sata", ' '); 2683 break; 2684 } 2685 2686 case "-z": 2687 { 2688 if (!Directory.Exists(CAFE_DATA_DIR.value)) 2689 { 2690 Console.WriteLine("Session data directory is missing and needs to be sync'd!"); 2691 Console.WriteLine(" Please re-run without the '-z' option."); 2692 return new CafeXReturn(CAFEX_ERROR.RUN_NO_CAFE_DATA_DIR); 2693 } 2694 2695 CAFERUN_OPTION_NO_DATA_SYNC.value = "1"; 2696 break; 2697 } 2698 2699 case "-A": 2700 { 2701 Console.WriteLine("*** -A option is deprecated and has no effect. ATFS is now the default file system. ***"); 2702 break; 2703 } 2704 2705 case "-D": 2706 { 2707 Console.WriteLine("cafex run failed: -D option is deprecated. DVDFS is now unsupported."); 2708 run_usage(); 2709 return new CafeXReturn(CAFEX_ERROR.RUN_D_OPTION_USED); 2710 } 2711 2712 case "-M": 2713 { 2714 if (!ArgumentChecks.IsArgumentValidSetting(args, i + 1)) 2715 { 2716 run_usage(); 2717 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2718 } 2719 2720 SYSTEM_MODE.value = args[i + 1]; 2721 ++i; 2722 break; 2723 } 2724 2725 case "-T": 2726 { 2727 // Check the apptype to make sure it is valid 2728 if (!ArgumentChecks.IsArgumentValidSetting(args, i + 1)) 2729 { 2730 run_usage(); 2731 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2732 } 2733 2734 CAFERUN_APP_TYPE.value = args[i + 1]; 2735 2736 // Make sure the value is valid. 2737 if (CAFERUN_APP_TYPE.value.StartsWith("0x") || CAFERUN_APP_TYPE.value.StartsWith("0X")) // Check to see if the value is preceded by "0x" 2738 { 2739 CAFERUN_APP_TYPE.value.Remove(0, 2); // Strip off the "0x" or "0X" because we won't need it 2740 } 2741 2742 // Now check the length of the value. We will only accept values that are 8 digits in length. 2743 if (CAFERUN_APP_TYPE.value.Length != 8) 2744 { 2745 Console.WriteLine("-T value needs to be an 8 digit hex value"); 2746 run_usage(); 2747 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 2748 } 2749 2750 // We know that there is no "0x" prefix and that the value is the correct length. 2751 // Now we need to check to make sure that it is a hex value between 00000000 - FFFFFFFF 2752 try 2753 { 2754 Convert.ToUInt32(CAFERUN_APP_TYPE.value, 16); 2755 } 2756 catch ( Exception ) 2757 { 2758 Console.WriteLine("AppType is not in Hex format"); 2759 } 2760 2761 fAppTypeDefined = true; 2762 ++i; 2763 2764 break; 2765 } 2766 2767 case "-N": 2768 { 2769 SKIP_OS_CHECK.value = "1"; 2770 break; 2771 } 2772 2773 default: 2774 { 2775 Console.WriteLine("cafex run failed: invalid option: " + args[i]); 2776 run_usage(); 2777 return new CafeXReturn(CAFEX_ERROR.RUN_INVALID_OPTION); 2778 } 2779 } 2780 } 2781 2782 #endregion 2783 #if TIMER 2784 CafeXSetupTime.Report(); 2785 Log.WriteLine("End of arguments"); 2786 #endif 2787 // Check if we need to display the HBM warning. See bugzilla 11537 for more details. 2788 if (CAFE_BOOT_MODE.value == "PCFS") 2789 { 2790 // These paths are where HBM is located. 2791 if (!File.Exists(Path.Combine(CAFE_MLC_DIR.value, @"sys\title\00050030\1001000A\code\app.xml")) || 2792 !File.Exists(Path.Combine(CAFE_MLC_DIR.value, @"sys\title\00050030\1001010A\code\app.xml")) || 2793 !File.Exists(Path.Combine(CAFE_MLC_DIR.value, @"sys\title\00050030\1001020A\code\app.xml"))) 2794 { 2795 Console.WriteLine(string.Concat("WARNING: Some system applications on the system might be missing. ", 2796 "If the system fails to boot, please reinstall the SDK to restore the missing system applications and run cafeupdate.")); 2797 } 2798 } 2799 2800 if (!(SKIP_OS_CHECK.value == "1") && Convert.ToInt32(RUN_FROM_HDD_BANK.value) > -1 && 2801 command == "discrun" && CAFERUN_OPTION_MLC_EMU_LAUNCH.value == "1") 2802 { 2803 //Check the value on MION to see if we have an OS mismatch when booting from the HDD 2804 int mion_os_ver = Convert.ToInt32(mionps.Run(BRIDGE_CURRENT_IP_ADDRESS.value + " " + (Convert.ToInt32(RUN_FROM_HDD_BANK.value) + 100))); 2805 2806 // 2 is the DEBUG OS on MION, 1 is NDEBUG 2807 if (CAFERUN_COLDBOOT_OS_VERSION.value == "0x000500101000800A" && mion_os_ver != 2) 2808 { 2809 Console.WriteLine("ERROR: Uploaded title's OS version does not match command line arguments!"); 2810 Console.WriteLine("ERROR: Please omit \"-b\" on the command line."); 2811 Console.WriteLine("If you uploaded the title using a HostBridge prior to 3.2.6.0, please install HostBridge 3.2.6.0 or later, re-upload the image, and try again."); 2812 Console.WriteLine("If you want to skip this check, specify \"-N\" on the command line, but be warned that Cafe may return an error!"); 2813 return new CafeXReturn(CAFEX_ERROR.UPLOADED_IMAGE_OS_MISMATCH); 2814 } 2815 else if (CAFERUN_COLDBOOT_OS_VERSION.value == "0x000500101000400A" && mion_os_ver != 1) 2816 { 2817 Console.WriteLine("ERROR: Uploaded title's OS version does not match command line arguments!"); 2818 Console.WriteLine("ERROR: Please specify \"-b\" on the command line."); 2819 Console.WriteLine("If you uploaded the title using a HostBridge prior to 3.2.6.0, please install HostBridge 3.2.6.0 or later, re-upload the image, and try again."); 2820 Console.WriteLine("If you want to skip this check, specify \"-N\" on the command line, but be warned that Cafe may return an error!"); 2821 return new CafeXReturn(CAFEX_ERROR.UPLOADED_IMAGE_OS_MISMATCH); 2822 } 2823 } 2824 //If MULTI is running make sure KILL_RESTART is enabled 2825 if (DEBUGGER.value == "multi" && CAFE_LAUNCH_DEBUG.value == "0" 2826 && ((CAFERUN_DISABLE_KILL_RESTART.value == null) || (CAFERUN_DISABLE_KILL_RESTART.value == "0")) 2827 && ((g_gArgValue == 1) || (CAFERUN_OPTION_SOFT_RESTART.value == "1"))) 2828 { 2829 CAFERUN_OPTION_KILL_RESTART.value = "1"; 2830 } 2831 else 2832 { 2833 CAFERUN_OPTION_KILL_RESTART.value = "0"; 2834 } 2835 2836 //This is a hack to make sure that killrestart happens from the console instead of multi 2837 if (g_KOptionSet) 2838 { 2839 CAFERUN_OPTION_KILL_RESTART.value = "1"; 2840 g_gArgValue = 1; 2841 } 2842 2843 // Wumad override: if "-e sata" was not provided and "-e wumad" was, sata bridge parameters should be added. 2844 if (!string.IsNullOrEmpty(CAFE_WUMAD.value) && 2845 (string.IsNullOrEmpty(BRIDGE_PARAMETERS.value) || !BRIDGE_PARAMETERS.value.Contains("-sata")) && 2846 (string.IsNullOrEmpty(BRIDGE_PARAMETERS_WITH_E.value) || !BRIDGE_PARAMETERS_WITH_E.value.Contains("-e sata"))) 2847 { 2848 BRIDGE_PARAMETERS.AddToVar("-sata", ' '); 2849 BRIDGE_PARAMETERS_WITH_E.AddToVar("-e sata", ' '); 2850 } 2851 2852 // Remove arguments before the .rpx 2853 string[] new_args = new string[args.Length - rpx_index]; 2854 Array.Copy(args, rpx_index, new_args, 0, new_args.Length); 2855 args = new_args; 2856 2857 //if (args.Length == 0) 2858 //{ 2859 // Console.WriteLine("cafex run failed: No arguments specified."); 2860 // run_usage(); 2861 // return new CafeXReturn(CAFEX_ERROR.RUN_NO_ARGUMENTS); 2862 //} 2863 2864 readSDKFromMion(); 2865 string catdev_sdk_ver = SDK_MAJ_VER.value + "." + SDK_MIN_VER.value + "." + SDK_MIC_VER.value; 2866 string sdk_ver = SDK_VER.value; 2867 if (catdev_sdk_ver != SDK_VER.value) 2868 { 2869 Console.WriteLine("The CAT-DEV SDK version is not the same as the SDK you are running."); 2870 Console.WriteLine("SDK Version: " + sdk_ver + " CAT-DEV SDK Version: " + catdev_sdk_ver); 2871 Console.WriteLine("Please run cafeupdate to get in sync."); 2872 } 2873 if (PCFS_OVER_SATA_PORT.value == null) 2874 { 2875 if (USE_PCFS_OVER_SATA.value == "1") 2876 { 2877 PCFS_OVER_SATA_PORT.value = SESSION_PCFS_SATA_PORT.value; 2878 BRIDGE_PARAMETERS.AddToVar("-pcfsport:" + SESSION_PCFS_SATA_PORT.value, ' '); 2879 2880 Console.WriteLine("cafex run: using PCFS over SATA on port " + PCFS_OVER_SATA_PORT.value); 2881 } 2882 else 2883 { 2884 Console.WriteLine("cafex run: not using PCFS over SATA"); 2885 } 2886 } 2887 2888 if (PCFS_OVER_SATA_PORT.value != null) 2889 { 2890 PCFSSERVER_PARAMETERS.AddToVar("-c " + PCFS_OVER_SATA_PORT.value, ' '); 2891 } 2892 else 2893 { 2894 Console.WriteLine("cafex run: PCFS_OVER_SATA_PORT is not set."); 2895 } 2896 2897 if (PCFSSERVER_PARAMETERS.value != null) 2898 { 2899 Console.WriteLine("cafex run: PCFSServer parameters " + PCFSSERVER_PARAMETERS.value); 2900 } 2901 2902 if (BRIDGE_PARAMETERS.value == null || !BRIDGE_PARAMETERS.value.Contains("-h")) 2903 { 2904 if (BRIDGE_PARAMETERS.value == null || !BRIDGE_PARAMETERS.value.Contains("-em")) 2905 { 2906 BRIDGE_PARAMETERS.AddToVar("-em", ' '); 2907 } 2908 } 2909 2910 DISC_EMU_TYPE.value = "hfio"; 2911 if (CAFERUN_OPTION_CALLED_FROM_CAFEDISCRUN.value == "yes") 2912 { 2913 if (RUN_FROM_HDD_BANK.value != null) 2914 { 2915 DISC_EMU_TYPE.value = "hdd"; 2916 Console.WriteLine("cafex run: Will launch HDD bank " + RUN_FROM_HDD_BANK.value); 2917 } 2918 else if (!string.IsNullOrEmpty(CAFE_WUMAD.value)) 2919 { 2920 // wumad emulation started from cafediscrun 2921 DISC_EMU_TYPE.value = "hdd"; 2922 } 2923 else if (CAFERUN_OPTION_SOFT_LAUNCH.value == "1") 2924 { 2925 ALLOW_DISCRUN_IN_SOFTLAUNCH.value = "1"; 2926 DISC_EMU_TYPE.value = "blockemu"; 2927 BRIDGE_PARAMETERS.AddToVar("-em", ' '); //Tell FSEmul to use block emulation explicitly 2928 } 2929 else 2930 { 2931 DISC_EMU_TYPE.value = "blockemu"; 2932 2933 if (BRIDGE_PARAMETERS.value == null || !BRIDGE_PARAMETERS.value.Contains("-em")) 2934 { 2935 BRIDGE_PARAMETERS.AddToVar("-em", ' '); 2936 } 2937 } 2938 } 2939 else if (!string.IsNullOrEmpty(CAFE_WUMAD.value)) 2940 { 2941 // wumad emulation started from caferun 2942 DISC_EMU_TYPE.value = "hdd"; 2943 } 2944 else 2945 { 2946 // default 2947 DISC_EMU_TYPE.value = "hfio"; 2948 if (CAFE_BOOT_MODE.value == "NAND") 2949 { 2950 if (SYSTEM_MODE.value == "test") 2951 { 2952 Console.WriteLine("cafex run failed: Test mode not supported on NAND."); 2953 return new CafeXReturn(CAFEX_ERROR.RUN_TEST_MODE_WITH_NAND_BOOT); 2954 } 2955 Console.WriteLine("cafex run: Will use NAND file system"); 2956 } 2957 else 2958 { 2959 Console.WriteLine("cafex run: Will use PCFS file system emulation"); 2960 } 2961 if (RUN_FROM_HDD_BANK.value != null) 2962 { 2963 Console.WriteLine("cafex run: HDD bank " + RUN_FROM_HDD_BANK.value + " will be attached to odd"); 2964 } 2965 } 2966 Console.WriteLine("cafex run: bridge parameters: " + BRIDGE_PARAMETERS.value); 2967 // Console.WriteLine("cafex run: bridge parameters with -e: " + BRIDGE_PARAMETERS_WITH_E.value); 2968 2969 long os_version = HexHandler.GetLongNumberFromString(CAFERUN_COLDBOOT_OS_VERSION.value); 2970 CAFERUN_COLDBOOT_OS_VERSION.value = os_version.ToString("X").PadLeft(16, '0'); 2971 2972 if (DEBUGGER.value == "multi" && CAFE_LAUNCH_DEBUG.value == "0" 2973 && ((CAFERUN_DISABLE_KILL_RESTART.value == null) || (CAFERUN_DISABLE_KILL_RESTART.value == "0")) 2974 && ((g_gArgValue == 1) || (CAFERUN_OPTION_SOFT_RESTART.value == "1"))) 2975 { 2976 CAFERUN_OPTION_KILL_RESTART.value = "1"; 2977 } 2978 else 2979 { 2980 CAFERUN_OPTION_KILL_RESTART.value = "0"; 2981 } 2982 2983 if(g_KOptionSet) 2984 { 2985 CAFERUN_OPTION_KILL_RESTART.value = "1"; 2986 g_gArgValue = 1; 2987 } 2988 2989 HOSTSTOP_RVAL.value = "0"; 2990 Process[] fsEmulProcesses = Process.GetProcessesByName("FSEmul"); 2991 if ((CAFESTOP_ONLY_IF_FSEMUL.value == "0" || (fsEmulProcesses != null && fsEmulProcesses.Length > 0)) && 2992 CAFERUN_OPTION_KILL_RESTART.value == "0") 2993 { 2994 stop(null, true); 2995 if (HOSTSTOP_RVAL.value != "0") 2996 { 2997 Console.WriteLine("cafex run failed: Please check the device is connected, powered on, and not in use by another host PC."); 2998 return new CafeXReturn(CAFEX_ERROR.RUN_HOSTSTOP_RVAL_NON_ZERO); 2999 } 3000 } 3001 #if TIMER 3002 Log.WriteLine("Hostcheckversion start"); 3003 CafeXSetupTime.Report(); 3004 #endif 3005 ret.error = hostcheckversion(); 3006 #if TIMER 3007 Log.WriteLine("Hostcheckversion end"); 3008 CafeXSetupTime.Report(); 3009 #endif 3010 if (ret.error != CAFEX_ERROR.OK) 3011 { 3012 return ret; 3013 } 3014 3015 if (USE_EXI_AS_DEBUG_CHANNEL.value == null || USE_EXI_AS_DEBUG_CHANNEL.value.Equals("0")) 3016 { 3017 // use SDIO as debugger. Default is EXI 3018 DEBUG_FLAGS.value = (HexHandler.GetLongNumberFromString(DEBUG_FLAGS.value) | 256).ToString(); 3019 } 3020 3021 uint syslog_level = HexHandler.GetNumberFromString(CAFE_SYSLOG_LEVEL.value); 3022 CAFE_SYSLOG_LEVEL.value = (syslog_level & 7).ToString(); 3023 PPC_OS_FLAGS.value = (HexHandler.GetNumberFromString(PPC_OS_FLAGS.value) | HexHandler.GetNumberFromString(HEARTBEAT_DISABLE.value) | HexHandler.GetNumberFromString(DEBUG_FLAGS.value) | (syslog_level << 9)).ToString(); 3024 PPC_APP_FLAGS.value = ((HexHandler.GetNumberFromString(PPC_OS_FLAGS.value) & 0x00000e70) | ((HexHandler.GetNumberFromString(PPC_OS_FLAGS.value) >> 1) & 0x80) | ((HexHandler.GetNumberFromString(PPC_OS_FLAGS.value) >> 6) & 0x02) | Convert.ToUInt32(((HexHandler.GetNumberFromString(PPC_OS_FLAGS.value) & 0xf) != 0))).ToString(); 3025 3026 SYSTEM_XML.value = CAFE_SLC_DIR.value + "\\sys\\config\\system.xml"; 3027 3028 if (CAFE_TEMP.value == null) 3029 { 3030 Console.WriteLine("cafex run failed: CAFE_TEMP environment variable is not set."); 3031 return new CafeXReturn(CAFEX_ERROR.RUN_NO_TEMP_VAR); 3032 } 3033 else 3034 { 3035 CAFERUN_WORK_DIR.value = CAFE_TEMP.value + "\\" + SESSION_PATH_PREFIX.value + "caferun"; 3036 } 3037 create_directory_if_noexist(CAFERUN_WORK_DIR.value); 3038 3039 if (SESSION_MANAGER.value == "1") 3040 { 3041 Console.WriteLine("cafex run: Using CAFE_CONTENT_DIR = " + CAFE_CONTENT_DIR.value); 3042 if (CAFERUN_OPTION_NO_DATA_SYNC.value == "0" && CAFERUN_OPTION_SOFT_RESTART.value == "0") 3043 { 3044 ret.error = syncsession (null); 3045 if (CAFEX_ERROR.OK != ret.error) 3046 { 3047 return ret; 3048 } 3049 CAFERUN_OPTION_NO_DATA_SYNC.value = "1"; 3050 } 3051 } 3052 if (CAFERUN_OPTION_SOFT_RESTART.value == "0") 3053 { 3054 create_directory_if_noexist(CAFE_SLC_DIR.value + "\\sys"); 3055 create_directory_if_noexist(CAFE_MLC_DIR.value); 3056 3057 if (args.Length != 0 && args[0] != null) 3058 { 3059 if (DISC_EMU_TYPE.value == "hdd") 3060 { 3061 Console.WriteLine("cafex run: Specified rpx/elf file is used for setting title id from app.xml only"); 3062 } 3063 3064 CAFE_ELF.value = PathConverter.Windowsify(args[0]); 3065 CAFE_ELF.value = PathConverter.Root(CAFE_ELF.value); 3066 3067 if (SESSION_MANAGER.value == "1") 3068 { 3069 if (!File.Exists(CAFE_ELF.value)) 3070 { 3071 Console.WriteLine("cafex run failed: Cannot find rpx application in " + CAFE_ELF.value); 3072 return new CafeXReturn(CAFEX_ERROR.RUN_RPX_DOESNT_EXIST); 3073 } 3074 3075 TMP_SUB_DIR.value = Path.GetFileNameWithoutExtension(args[0]); 3076 string CAFE_DATA_TMP_DOS = CAFE_DATA_TMP.value + "\\" + TMP_SUB_DIR.value; 3077 create_directory_if_noexist(CAFE_DATA_TMP_DOS); 3078 3079 CAFE_ELF_SRC_DIR.value = Path.GetDirectoryName(CAFE_ELF.value); 3080 3081 if (!string.Equals(CAFE_ELF_SRC_DIR.value, CAFE_DATA_TMP_DOS, StringComparison.InvariantCultureIgnoreCase)) 3082 { 3083 // Don't sync if we are running from the data/tmp folder as this is most-likely 3084 // a restart from the Multi debugger. If not, the files are still ok as they were 3085 // from a previous sync. 3086 // 3087 SYNCTOOL_CFG.value = CAFE_ROOT.value + "\\system\\bin\\tool\\synctool.code.xml"; 3088 SYNCTOOL_LOG.value = CAFE_DATA_TMP.value + "\\synctool.log"; 3089 int SYNCTOOL_RVAL = synctool.sync(SYNCTOOL_CFG.value, CAFE_ELF_SRC_DIR.value, CAFE_DATA_TMP_DOS, SYNCTOOL_LOG.value); 3090 if (SYNCTOOL_RVAL != 0) 3091 { 3092 Console.WriteLine(" : Session data sync FAILED with exit code {0}!", SYNCTOOL_RVAL); 3093 Console.WriteLine(" : See {0} for details.", SYNCTOOL_LOG.value); 3094 return new CafeXReturn(CAFEX_ERROR.SYNCTOOL_FAILED); 3095 } 3096 } 3097 CAFE_ELF.value = CAFE_DATA_TMP.value + "\\" + TMP_SUB_DIR.value + "\\" + Path.GetFileName(args[0]); 3098 } 3099 3100 switch (Path.GetExtension(CAFE_ELF.value)) 3101 { 3102 case ".elf": 3103 { 3104 DEBUG_ELF_FILE.value = CAFE_ELF.value; 3105 string rpx = Path.ChangeExtension(CAFE_ELF.value, "rpx"); 3106 if (File.Exists(rpx)) 3107 { 3108 CAFE_ELF.value = rpx; 3109 } 3110 break; 3111 } 3112 3113 case ".rpx": 3114 { 3115 if (DEBUG_ELF_FILE.value == null) 3116 { 3117 string elf = Path.ChangeExtension(CAFE_ELF.value, "elf"); 3118 if (File.Exists(elf)) 3119 { 3120 DEBUG_ELF_FILE.value = elf; 3121 } 3122 } 3123 break; 3124 } 3125 } 3126 3127 if (!CAFE_ELF.value.EndsWith(".rpx")) 3128 { 3129 Console.WriteLine("cafex run failed: Please provide rpx application as first argument after run_options"); 3130 run_usage(); 3131 return new CafeXReturn(CAFEX_ERROR.RUN_NO_RPX_SPECIFIED); 3132 } 3133 3134 if (!File.Exists(CAFE_ELF.value)) 3135 { 3136 Console.WriteLine("cafex run failed: Cannot find rpx application in " + CAFE_ELF.value); 3137 return new CafeXReturn(CAFEX_ERROR.RUN_RPX_DOESNT_EXIST); 3138 } 3139 3140 CAFE_ELF_DIR.value = Path.GetDirectoryName(CAFE_ELF.value); 3141 3142 create_directory_if_noexist(CAFE_CONTENT_DIR.value); 3143 create_directory_if_noexist(CAFE_META_DIR.value); 3144 create_directory_if_noexist(CAFE_SAVE_DIR.value); 3145 3146 CAFE_CODE_DIR.value = CAFE_ELF_DIR.value; 3147 3148 APP_XML_FILE.value = CAFE_CODE_DIR.value + "\\app.xml"; 3149 if (!update_app_xml(APP_XML_FILE.value)) 3150 { 3151 return new CafeXReturn(CAFEX_ERROR.RUN_UPDATE_APP_XML_FAILED); 3152 } 3153 3154 COS_XML_FILE.value = CAFE_CODE_DIR.value + "\\cos.xml"; 3155 3156 if (!update_cos_xml(COS_XML_FILE.value, PPC_APP_FLAGS.value)) 3157 { 3158 return new CafeXReturn(CAFEX_ERROR.RUN_UPDATE_COS_XML_FAILED); 3159 } 3160 3161 META_XML_FILE.value = CAFE_META_DIR.value + "\\meta.xml"; 3162 CAFEX_ERROR update_meta_ret = update_meta_xml(META_XML_FILE.value); 3163 3164 if (update_meta_ret != CAFEX_ERROR.OK) 3165 { 3166 return new CafeXReturn(update_meta_ret); 3167 } 3168 3169 if (!update_arglist(COS_XML_FILE.value, CAFE_ELF.value, args)) 3170 { 3171 return new CafeXReturn(CAFEX_ERROR.RUN_UPDATE_ARGLIST_FAILED); 3172 } 3173 3174 update_boot_logos(CAFE_META_DIR.value); 3175 3176 if (RPL_DIRS.value != null) 3177 { 3178 string[] rpl_dirs = RPL_DIRS.value.Split(DEFAULT_DELIMITER); 3179 3180 foreach (string s in rpl_dirs) 3181 { 3182 string dir = PathConverter.Windowsify(s); 3183 string[] contained_files = Directory.GetFiles(dir, "*.rpl"); 3184 if (contained_files.Length == 0) 3185 { 3186 Console.WriteLine("cafex run : WARNING - No files found in directory {0}.", dir); 3187 } 3188 else 3189 { 3190 foreach (string origin in contained_files) 3191 { 3192 string destination = CAFE_CODE_DIR.value + "\\" + Path.GetFileName(origin); 3193 Console.WriteLine("cafex run: copy {0} to {1}", origin, destination); 3194 File.Copy(origin, destination, true); 3195 } 3196 } 3197 } 3198 } 3199 if (RPL_FILES.value != null) 3200 { 3201 string[] rpl_files = RPL_FILES.value.Split(DEFAULT_DELIMITER); 3202 foreach (string s in rpl_files) 3203 { 3204 string file = PathConverter.Windowsify(s); 3205 if (File.Exists(file)) 3206 { 3207 string destination = CAFE_CODE_DIR.value + "\\" + Path.GetFileName(s); 3208 Console.WriteLine("cafex run: copy {0} to {1}", file, destination); 3209 File.Copy(file, destination, true); 3210 } 3211 } 3212 } 3213 } 3214 3215 if (CAFERUN_INS.value == "0") 3216 { 3217 #if DEBUG 3218 Log.WriteLine("CAFEX: Writing data to {0}\\previous_launch_info.xml", CAFERUN_WORK_DIR.value); 3219 #endif 3220 FileStream previous_info_file = new FileStream(CAFERUN_WORK_DIR.value + "\\" + "previous_launch_info.xml", FileMode.Create); 3221 StreamWriter writer = new StreamWriter(previous_info_file); 3222 writer.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); 3223 writer.WriteLine("<prev type=\"complex\" access=\"777\">"); 3224 3225 if (!string.IsNullOrEmpty(CAFERUN_OPTION_MLC_EMU_LAUNCH.value) && CAFERUN_OPTION_MLC_EMU_LAUNCH.value == "1") 3226 { 3227 writer.WriteLine(" <emu_tid type=\"string\" length=\"512\">" + CAFERUN_OPTION_MLC_EMU_TITLEID.value + "</emu_tid>"); 3228 } 3229 else 3230 { 3231 writer.WriteLine(" <code_dir type=\"string\" length=\"512\">" + CAFE_CODE_DIR.value + "</code_dir>"); 3232 writer.WriteLine(" <disc_emu type=\"string\" length=\"8\">" + DISC_EMU_TYPE.value + "</disc_emu>"); 3233 writer.WriteLine(" <hdd_bank type=\"string\" length=\"8\">" + RUN_FROM_HDD_BANK.value + "</hdd_bank>"); 3234 writer.WriteLine(" <disc_emu_tid type=\"string\" length=\"8\">" + DISC_EMU_TID.value + "</disc_emu_tid>"); 3235 } 3236 writer.WriteLine(" <coldboot_os type=\"string\" length=\"8\">" + CAFERUN_COLDBOOT_OS_VERSION.value + "</coldboot_os>"); 3237 writer.WriteLine(" <fast_relaunch type=\"string\" length=\"8\">" + CAFERUN_OPTION_FAST_RELAUNCH.value + "</fast_relaunch>"); 3238 writer.WriteLine("</prev>"); 3239 writer.Flush(); 3240 writer.Close(); 3241 } 3242 CAFEX_ERROR updateResult = update_system_xml(SYSTEM_XML.value, PPC_OS_FLAGS.value, SYSTEM_MODE.value, MCP_LAUNCH_HINT.value); 3243 if (updateResult != CAFEX_ERROR.OK) 3244 { 3245 return new CafeXReturn(updateResult); 3246 } 3247 } 3248 else 3249 { 3250 if (!File.Exists(SYSTEM_XML.value)) 3251 { 3252 Console.WriteLine("cafex run failed: Please cafex run an rpx application first"); 3253 return new CafeXReturn(CAFEX_ERROR.RUN_DASH_R_WITH_NO_PREVIOUS_LAUNCH_INFO); 3254 } 3255 3256 string prev_info_file = CAFERUN_WORK_DIR.value + "\\" + "previous_launch_info.xml"; 3257 3258 CAFERUN_OPTION_FAST_RELAUNCH.value = XmlHandler.GetNodeValue(prev_info_file, "fast_relaunch"); 3259 CAFERUN_OPTION_MLC_EMU_TITLEID.value = XmlHandler.GetNodeValue(prev_info_file, "emu_tid"); 3260 3261 if (!string.IsNullOrEmpty(CAFERUN_OPTION_MLC_EMU_TITLEID.value)) 3262 { 3263 CAFERUN_OPTION_MLC_EMU_LAUNCH.value = "1"; 3264 CAFERUN_COLDBOOT_OS_VERSION.value = XmlHandler.GetNodeValue(SYSTEM_XML.value, "default_os_id"); 3265 } 3266 else 3267 { 3268 CAFE_CODE_DIR.value = XmlHandler.GetNodeValue(prev_info_file, "code_dir"); 3269 DISC_EMU_TYPE.value = XmlHandler.GetNodeValue(prev_info_file, "disc_emu"); 3270 RUN_FROM_HDD_BANK.value = XmlHandler.GetNodeValue(prev_info_file, "hdd_bank"); 3271 DISC_EMU_TID.value = XmlHandler.GetNodeValue(prev_info_file, "disc_emu_tid"); 3272 PREV_CAFE_ARGSTR.value = XmlHandler.GetNodeValue(CAFE_CODE_DIR.value + "\\cos.xml", "argstr"); 3273 3274 // Check "argstr" length to make sure it is less than 4096. 3275 if (!string.IsNullOrEmpty(PREV_CAFE_ARGSTR.value) && PREV_CAFE_ARGSTR.value.Length > CAFE_ARGSTR_MAX_LENGTH) 3276 { 3277 Console.WriteLine("cafex run failed: argstr value in cos.xml is longer than 4096 characters. Please shorten the argstr and retry."); 3278 return new CafeXReturn(CAFEX_ERROR.RUN_UPDATE_ARGLIST_FAILED); 3279 } 3280 3281 CAFE_ELF.value = CAFE_CODE_DIR.value + "\\" + PREV_CAFE_ARGSTR.value.Split(' ')[0]; 3282 3283 CAFERUN_COLDBOOT_OS_VERSION.value = XmlHandler.GetNodeValue(prev_info_file, "coldboot_os"); 3284 3285 if (string.IsNullOrEmpty(CAFERUN_COLDBOOT_OS_VERSION.value)) 3286 { 3287 CAFERUN_COLDBOOT_OS_VERSION.value = XmlHandler.GetNodeValue(SYSTEM_XML.value, "default_os_id"); 3288 } 3289 if (DISC_EMU_TYPE.value != "hdd") 3290 { 3291 if (!File.Exists(CAFE_ELF.value)) 3292 { 3293 Console.WriteLine("cafex run failed: Could not find " + CAFE_ELF.value); 3294 return new CafeXReturn(CAFEX_ERROR.RUN_DASH_R_CANT_FIND_APPLICATION); 3295 } 3296 3297 Console.WriteLine("cafex run: Restarting " + CAFE_ELF.value); 3298 } 3299 } 3300 } 3301 3302 // Set up the title to be run in Eco mode. If we are not in ECO mode make sure to remove the node from system.xml 3303 if (ECO_MODE.value == "1") 3304 { 3305 string default_title_id; 3306 3307 default_title_id = XmlHandler.GetNodeValue(SYSTEM_XML.value, "default_title_id"); 3308 if (XmlHandler.NodeExists(SYSTEM_XML.value, "default_eco_title_id")) 3309 { 3310 XmlHandler.UpdateNodeValue(SYSTEM_XML.value, "default_eco_title_id", default_title_id); 3311 } 3312 else 3313 { 3314 XmlHandler.AddNode(SYSTEM_XML.value, "default_eco_title_id", default_title_id, new string[4] { "type", "hexBinary", "length", "8" }); 3315 } 3316 } 3317 else 3318 { 3319 if (XmlHandler.NodeExists(SYSTEM_XML.value, "default_eco_title_id")) 3320 { 3321 XmlHandler.RemoveNode(SYSTEM_XML.value, "default_eco_title_id"); 3322 } 3323 } 3324 3325 if (CAFE_BOOT_MODE.value == "PCFS") 3326 { 3327 string os_directory = CAFE_SLC_DIR.value + "\\sys\\title\\" + CAFERUN_COLDBOOT_OS_VERSION.value.Substring(0,8) + "\\" + CAFERUN_COLDBOOT_OS_VERSION.value.Substring(8,8) + "\\code"; 3328 if (!Directory.Exists(os_directory)) 3329 { 3330 Console.WriteLine("cafex run failed: Cannot find OS in " + os_directory); 3331 return new CafeXReturn(CAFEX_ERROR.RUN_CANT_FIND_OS_DIRECTORY); 3332 } 3333 3334 string[] files = Directory.GetFiles(os_directory); 3335 bool found_rpl = false; 3336 foreach (string s in files) 3337 { 3338 if (s.EndsWith(".rpl")) 3339 { 3340 found_rpl = true; 3341 break; 3342 } 3343 } 3344 3345 if (!found_rpl) 3346 { 3347 CAFERUN_OS_VERSION_PARTIAL_UNIQUE_ID.value = (HexHandler.GetLongNumberFromString("0x" + CAFERUN_COLDBOOT_OS_VERSION.value) >> 8 & 0xff).ToString(); 3348 3349 uint value = HexHandler.GetNumberFromString(CAFERUN_OS_VERSION_PARTIAL_UNIQUE_ID.value); 3350 if (value >= 192) 3351 { 3352 Console.WriteLine("cafex run failed: Please build FDEBUG os version " + CAFERUN_COLDBOOT_OS_VERSION.value); 3353 } 3354 else if (value >= 128) 3355 { 3356 Console.WriteLine("cafex run failed: Please build DEBUG os version " + CAFERUN_COLDBOOT_OS_VERSION.value); 3357 Console.WriteLine(" or do not use \"cafex run -b\" to use NDEBUG version"); 3358 } 3359 else if (value >= 64) 3360 { 3361 Console.WriteLine("cafex run failed: Please build NDEBUG os version " + CAFERUN_COLDBOOT_OS_VERSION.value); 3362 Console.WriteLine(" or use \"cafex run -b\" to use the DEBUG version"); 3363 } 3364 else if ((HexHandler.GetLongNumberFromString("0x" + CAFERUN_COLDBOOT_OS_VERSION.value) & 0xFF) == 0xFE) 3365 { 3366 Console.WriteLine("cafex run failed: Please build OS_SECURITY_LEVEL os version " + CAFERUN_COLDBOOT_OS_VERSION.value); 3367 } 3368 else 3369 { 3370 Console.WriteLine("cafex run failed: Non-standard titleId for os version " + CAFERUN_COLDBOOT_OS_VERSION.value); 3371 } 3372 3373 return new CafeXReturn(CAFEX_ERROR.RUN_OS_NOT_PRESENT); 3374 } 3375 } 3376 3377 if (!string.IsNullOrEmpty(EJECT_STATE.value)) 3378 { 3379 int returnVal = mionurl.Run(BRIDGE_CURRENT_IP_ADDRESS.value + " /mion/status.cgi operation=eject disc=" + EJECT_STATE.value); 3380 if (returnVal != 0) 3381 { 3382 Console.WriteLine("cafex run: Set disc eject state:'{0}' failed={1}!", EJECT_STATE.value, returnVal); 3383 Console.WriteLine(" Continuing execution, Ignoring ejectstate"); 3384 } 3385 else 3386 { 3387 Console.WriteLine("cafex run: Set disc eject state: '{0}' succeeded.", EJECT_STATE.value); 3388 } 3389 } 3390 3391 if (PCFS_SRV_LOG_DIR.value == null) 3392 { 3393 PCFS_SRV_LOG_OUTPUT.value = "/dev/null"; 3394 } 3395 else 3396 { 3397 PCFS_LOG_TIMESTAMP.value = DateTime.Now.ToString("HHmmss"); 3398 PCFS_SRV_LOG_OUTPUT.value = PCFS_SRV_LOG_DIR.value + "\\" + SESSION_PATH_PREFIX.value + "pcfs_" + PCFS_LOG_TIMESTAMP.value + ".txt"; 3399 PCFS_SRV_LOG_OUTPUT.value = PathConverter.Windowsify(PCFS_SRV_LOG_OUTPUT.value); 3400 Console.WriteLine("PCFS output logged to " + PCFS_SRV_LOG_OUTPUT.value); 3401 } 3402 3403 if (DISC_EMU_TYPE.value == "hdd" || 3404 ((!string.IsNullOrEmpty(CAFE_ELF.value)) && CAFE_ELF.value.EndsWith(".rpx"))) 3405 { 3406 if (DISC_EMU_TYPE.value == "hfio") 3407 { 3408 MAPDIR_MLC.value = CAFE_MLC_DIR.value + "/"; 3409 MAPDIR_SLC.value = CAFE_SLC_DIR.value + "/"; 3410 MAPDIR_CODE.value = CAFE_CODE_DIR.value + "/"; 3411 MAPDIR_META.value = CAFE_META_DIR.value + "/"; 3412 MAPDIR_CONTENT.value = CAFE_CONTENT_DIR.value + "/"; 3413 MAPDIR_SAVE.value = CAFE_SAVE_DIR.value + "/"; 3414 3415 PCFS_DIR_MAPPING.value = "-m /%MLC_EMU_DIR/ \"" + MAPDIR_MLC.value + "\"" + 3416 " -m /%SLC_EMU_DIR/ \"" + MAPDIR_SLC.value + "\"" + 3417 " -m /%DISC_EMU_DIR/code/ \"" + MAPDIR_CODE.value + "\"" + 3418 " -m /%DISC_EMU_DIR/meta/ \"" + MAPDIR_META.value + "\"" + 3419 " -m /%DISC_EMU_DIR/content/ \"" + MAPDIR_CONTENT.value + "\"" + 3420 " -m /%DISC_EMU_DIR/save/ \"" + MAPDIR_SAVE.value + "\""; 3421 } 3422 else 3423 { 3424 MAPDIR_MLC.value = CAFE_MLC_DIR.value + "/"; 3425 MAPDIR_SLC.value = CAFE_SLC_DIR.value + "/"; 3426 MAPDIR_SAVE.value = CAFE_SAVE_DIR.value + "/"; 3427 3428 PCFS_DIR_MAPPING.value = "-m /%MLC_EMU_DIR/ \"" + MAPDIR_MLC.value + "\"" + 3429 " -m /%SLC_EMU_DIR/ \"" + MAPDIR_SLC.value + "\"" + 3430 " -m /%SAVE_EMU_DIR/ \"" + MAPDIR_SAVE.value + "\""; 3431 } 3432 } 3433 else if (CAFERUN_OPTION_MLC_EMU_LAUNCH.value == "1") 3434 { 3435 MAPDIR_MLC.value = CAFE_MLC_DIR.value + "/"; 3436 MAPDIR_SLC.value = CAFE_SLC_DIR.value + "/"; 3437 3438 PCFS_DIR_MAPPING.value = "-m /%MLC_EMU_DIR/ \"" + MAPDIR_MLC.value + "\"" + 3439 " -m /%SLC_EMU_DIR/ \"" + MAPDIR_SLC.value + "\""; 3440 } 3441 else 3442 { 3443 MAPDIR_MLC.value = CAFE_MLC_DIR.value + "/"; 3444 MAPDIR_SLC.value = CAFE_SLC_DIR.value + "/"; 3445 3446 PCFS_DIR_MAPPING.value = "-m /%MLC_EMU_DIR/ \"" + MAPDIR_MLC.value + "\"" + 3447 " -m /%SLC_EMU_DIR/ \"" + MAPDIR_SLC.value + "\""; 3448 } 3449 3450 ELF_NEST_OPT.value=""; 3451 ELF_NEST_VALUE.value = ""; 3452 if (ALLOW_DISCRUN_IN_SOFTLAUNCH.value == "1") 3453 { 3454 // the DLF will not be used now - but it has to be made now, 3455 // as this is the point where all input environment variables are set correctly 3456 // for cafedevrun.sh to run 3457 bootrun(new List<string>() {"-makedlf"} , fAppTypeDefined); 3458 if (string.IsNullOrEmpty(BRIDGE_PARAMETERS_WITH_E.value) || 3459 !BRIDGE_PARAMETERS_WITH_E.value.Contains("soft_launch_cafe_elf")) 3460 { 3461 if (!string.IsNullOrEmpty(CAFE_ELF.value)) 3462 { 3463 // we didn't get the ELF name from above. So we must to decide what it is. 3464 ELF_NEST_OPT.value = "-e"; 3465 ELF_NEST_VALUE.value = "soft_launch_cafe_elf:" + CAFE_ELF.value; 3466 3467 // Since there is no way to communicate new DLF contents into an existing FSEmul, 3468 // we need a forceful restart for this case - even though it is softlaunch 3469 CAFE_RUN_FORCERESTART.value = "1"; 3470 } 3471 } 3472 } 3473 3474 // Bug 9826: Watch for magic token from IOS signifying crash 3475 if (Environment.GetEnvironmentVariable("CAFERUN_OPTION_IGNORE_CRASH_TOKEN") == null 3476 || Environment.GetEnvironmentVariable("CAFERUN_OPTION_IGNORE_CRASH_TOKEN").Trim() != "0") 3477 { 3478 { 3479 Func<string, bool> callback = StartProcessOnCrashdump; 3480 cattoucan.AddNotification(IOS_CRASHDUMP_TOKEN, callback); 3481 } 3482 } 3483 3484 CAFERUN_INS.value = "1"; 3485 CMD_RESULT.value = "0"; 3486 if (CAFERUN_OPTION_SOFT_LAUNCH.value == "1" 3487 || (CAFERUN_OPTION_KILL_RESTART.value == "1" && ((CAFERUN_DISABLE_KILL_RESTART.value == null) || (CAFERUN_DISABLE_KILL_RESTART.value == "0")))) 3488 { 3489 CafeBootProgress progress = new CafeBootProgress(); 3490 if (CAFE_RUN_FORCERESTART.value == "1") 3491 { 3492 Console.WriteLine("**** FORCE REBOOT ****"); 3493 g_KOptionSet = false; 3494 g_gArgValue = 0; 3495 CAFERUN_OPTION_KILL_RESTART.value = "0"; 3496 progress.stage = bootCatDev(); 3497 CAFERUN_OPTION_SOFT_LAUNCH.value = "1"; 3498 } 3499 else if (CAFERUN_OPTION_KILL_RESTART.value == "1" 3500 && ((CAFERUN_DISABLE_KILL_RESTART.value == null) || (CAFERUN_DISABLE_KILL_RESTART.value == "0")) 3501 && ((g_gArgValue == 1) || (CAFERUN_OPTION_SOFT_RESTART.value == "1"))) 3502 { 3503 //Try executing kill restart operation. 3504 //COS restarts the current running application/title 3505 if (Program.CAFE_PROFILE.value != null && Program.CAFE_PROFILE.value == "1") 3506 { 3507 CafeXEventtLog.Instance.WriteToEventLog(562, DateTime.Now, EventStatus.BEGIN, EventProcess.CAFEX, "System is doing KILL RESTART"); 3508 } 3509 #if TIMER 3510 Log.WriteLine("SendKillRestartAndResponse start"); 3511 CafeXSetupTime.Report(); 3512 #endif 3513 g_KOptionSet = cosdebug.SendKillRestartAndResponse(Convert.ToInt32(SESSION_NET_MANAGE_PORT.value), 3514 COSDEBUG_KILLRESTART_RETRIES, 3515 COSDEBUG_KILLRESTART_TIMEOUT, 3516 COSDEBUG_KILLRESTART_DELAY); 3517 #if TIMER 3518 Log.WriteLine("SendKillRestartAndResponse end"); 3519 CafeXSetupTime.Report(); 3520 #endif 3521 // We're going to cold boot if g_KOptionSet was 3522 // set to false, clear these values regardless 3523 CAFERUN_OPTION_KILL_RESTART.value = "0"; 3524 g_gArgValue = 0; 3525 3526 // Check if we don't want to use softlaunch 3527 if (!g_KOptionSet && !progress.checkKillRestartSoftlaunch()) 3528 { 3529 // Boot run if PCFS 3530 if (CAFE_BOOT_MODE.value == "PCFS" && CAFERUN_OPTION_SOFT_LAUNCH.value != "1") 3531 { 3532 ret.error = startBootRun(isWumadExecution, launch, true); 3533 if (ret.error != CAFEX_ERROR.OK || !launch) 3534 { 3535 return ret; 3536 } 3537 3538 // Causes execution to jump to output 3539 g_KOptionSet = true; 3540 } 3541 else 3542 { 3543 // Cold boot to sysconfig when in NAND 3544 progress.stage = bootCatDev(); 3545 progress.waitForTitle = true; 3546 } 3547 } 3548 } 3549 else 3550 { 3551 // Ensure that the K flag is cleared 3552 g_KOptionSet = false; 3553 CAFERUN_OPTION_KILL_RESTART.value = "0"; 3554 } 3555 3556 if (CMD_RESULT.value == "0" && !g_KOptionSet) 3557 { 3558 for (progress.tries = 0; progress.tries < CAFERUN_RETRY_COUNT; ++progress.tries) 3559 { 3560 switch (progress.stage) 3561 { 3562 case CafeBootStage.Off: 3563 case CafeBootStage.ServerSync: 3564 #if DEBUG 3565 Log.WriteLine("Iteration #{0} of {1}", progress.tries + 1, CAFERUN_RETRY_COUNT); 3566 #endif 3567 PCFS_SYNC_DATE.value = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-ffff"); 3568 Console.WriteLine("Launching {0} @ sync date [{1}]", Path.GetFileName(CAFE_ELF.value), PCFS_SYNC_DATE.value); 3569 #if TIMER 3570 CafeXSetupTime.Report(); 3571 #endif 3572 CMD_RESULT.value = PCFSServerSync.sync(PCFS_SYNC_DATE.value, CAFE_ELF.value, PCFS_DIR_MAPPING.value).ToString(); 3573 #if DEBUG 3574 Log.WriteLine("PCFSServerSync process returned '{0}' from execution.", CMD_RESULT.value); 3575 #endif 3576 #if TIMER 3577 Log.WriteLine("PCFSServerSync end"); 3578 CafeXSetupTime.Report(); 3579 #endif 3580 if (CMD_RESULT.value != "0") 3581 { 3582 // Return error if we already booted 3583 if (progress.Active) 3584 { 3585 ret.error = CAFEX_ERROR.RUN_PCFSSERVER_SYNC_FAILED; 3586 } 3587 else if (tryCafeReboot(launch, 3588 isWumadExecution, 3589 progress, 3590 out ret.error)) 3591 { 3592 continue; 3593 } 3594 3595 return ret; 3596 } 3597 3598 if (CAFERUN_OPTION_FAST_RELAUNCH.value == "1") 3599 { 3600 progress.checkPower = false; 3601 progress.stage = CafeBootStage.SendingFlags; 3602 goto case CafeBootStage.SendingFlags; 3603 } 3604 3605 cattoucan.BeginBootSync(); 3606 progress.stage = CafeBootStage.SendingSync1; 3607 goto case CafeBootStage.SendingSync1; 3608 3609 case CafeBootStage.SendingSync1: 3610 // Try an initial sync request 3611 if (!trySyncRequest()) 3612 { 3613 /* Sending the request failed 3614 * Check the power if we did not cold boot 3615 */ 3616 progress.checkVDD2(); 3617 3618 // If we are running, try sending requests 3619 if (progress.Active) 3620 { 3621 int i = 1; 3622 for (; i < CAFERUN_RETRY_COUNT; ++i) 3623 { 3624 if (trySyncRequest()) 3625 { 3626 // Sending the sync was successful 3627 break; 3628 } 3629 } 3630 3631 // Check if not successful 3632 if (i > CAFERUN_LAST_RETRY) 3633 { 3634 // Check if this is the initial check 3635 if (!progress.checkPower) 3636 { 3637 /* This is in a reboot process 3638 * break loop and report error 3639 */ 3640 progress.tries = CAFERUN_RETRY_COUNT; 3641 continue; 3642 } 3643 3644 // Reboot CAT-DEV 3645 progress.stage = CafeBootStage.Off; 3646 } 3647 } 3648 3649 // Check if we need to reboot CAT-DEV 3650 if (!progress.Active) 3651 { 3652 if (tryCafeReboot(launch, 3653 isWumadExecution, 3654 progress, 3655 out ret.error)) 3656 { 3657 continue; 3658 } 3659 3660 return ret; 3661 } 3662 } 3663 3664 // Sync success, go to next stage 3665 progress.checkPower = false; 3666 progress.stage = CafeBootStage.WaitingForSync1; 3667 goto case CafeBootStage.WaitingForSync1; 3668 3669 case CafeBootStage.SendingSync2: 3670 if (trySyncRequest()) 3671 { 3672 progress.stage = CafeBootStage.WaitingForSync2; 3673 goto case CafeBootStage.WaitingForSync2; 3674 } 3675 3676 continue; 3677 3678 case CafeBootStage.WaitingForSync1: 3679 case CafeBootStage.WaitingForSync2: 3680 // Wait for devkit message to respond 3681 if (!cattoucan.SyncWithBoot(DEVKIT_HELP_RESPONSE_TIMEOUT)) 3682 { 3683 CMD_RESULT.value = "1"; 3684 continue; 3685 } 3686 3687 CMD_RESULT.value = "0"; 3688 if (progress.stage == CafeBootStage.WaitingForSync2) 3689 { 3690 cattoucan.FinishSync(!progress.waitForTitle && quiet_mode); 3691 progress.stage = CafeBootStage.Booted; 3692 break; 3693 } 3694 3695 progress.stage = CafeBootStage.SendingFlags; 3696 goto case CafeBootStage.SendingFlags; 3697 3698 case CafeBootStage.SendingFlags: 3699 #if DEBUG 3700 Log.WriteLine("setting cosflags now."); 3701 #endif 3702 // Set the COS flags 3703 CMD_RESULT.value = set_system_xml_cos_flags(PPC_OS_FLAGS.value).ToString(); 3704 if (CMD_RESULT.value == "0") 3705 { 3706 if (CAFERUN_OPTION_FAST_RELAUNCH.value == "1") 3707 { 3708 progress.stage = CafeBootStage.Booted; 3709 break; 3710 } 3711 3712 progress.stage = CafeBootStage.SendingSync2; 3713 goto case CafeBootStage.SendingSync2; 3714 } 3715 3716 cattoucan.FinishSync(true); 3717 3718 // Return error if we already booted 3719 if (progress.Active) 3720 { 3721 ret.error = CAFEX_ERROR.RUN_UPDATE_SYSTEM_XML_FAILED; 3722 } 3723 else if (tryCafeReboot(launch, 3724 isWumadExecution, 3725 progress, 3726 out ret.error)) 3727 { 3728 continue; 3729 } 3730 3731 return ret; 3732 } 3733 #if DEBUG 3734 Log.WriteLine(command + " trying softlaunch now."); 3735 #endif 3736 // discrun support. 3737 // This is softlaunch, and there is no RPS specified. 3738 // try to see if we can get it from the user - in case it applies 3739 if (string.IsNullOrEmpty(DISC_EMU_TID.value)) 3740 { 3741 if (CAFERUN_OPTION_MLC_EMU_LAUNCH.value == "1") 3742 { 3743 DISC_EMU_TID.value = (!string.IsNullOrEmpty(CAFERUN_OPTION_MLC_EMU_TITLEID.value) && CAFERUN_OPTION_MLC_EMU_TITLEID.value.Length == 16) ? 3744 "0x" + CAFERUN_OPTION_MLC_EMU_TITLEID.value : 3745 CAFERUN_OPTION_MLC_EMU_TITLEID.value; 3746 3747 Console.WriteLine("HDD emulation: using command line TID {0}", DISC_EMU_TID.value); 3748 } 3749 else if (!string.IsNullOrEmpty(CAFE_WUMAD.value) && 3750 !string.IsNullOrEmpty(CAFERUN_WUMAD_TITLE_ID.value)) 3751 { 3752 // Check if a WUMAD was provided and see if title id is available 3753 DISC_EMU_TID.value = CAFERUN_WUMAD_TITLE_ID.value; 3754 Console.WriteLine("HDD WUMAD emulation: using command line TID {0}", DISC_EMU_TID.value); 3755 } 3756 } 3757 3758 // still not set despite our attempts? 3759 if (string.IsNullOrEmpty(DISC_EMU_TID.value)) 3760 { 3761 Console.WriteLine("cafex run failed: Unable to determine title ID, and it was not specified in the command line."); 3762 return new CafeXReturn(CAFEX_ERROR.RUN_DISCRUN_NAND_UNABLE_TO_FIND_APPLICATION); 3763 } 3764 3765 // this is to phase in adoption smoothly into autotest, 3766 // avoiding any changes to tests other than cafediscrun. 3767 // We may disable this check later. 3768 if (ALLOW_DISCRUN_IN_SOFTLAUNCH.value == "1") 3769 { 3770 CMD_RESULT.value = "0"; 3771 if (!string.IsNullOrEmpty(SYSTEM_MODE.value)) 3772 { 3773 if (SYSTEM_MODE.value.ToLowerInvariant().Equals("prod")) 3774 { 3775 Console.WriteLine("Setting mode to 0"); 3776 devkitmsg.sys_mode_prod(); 3777 } 3778 else if (SYSTEM_MODE.value.ToLowerInvariant().Equals("dev")) 3779 { 3780 Console.WriteLine("Setting mode to 1"); 3781 devkitmsg.sys_mode_dev(); 3782 } 3783 else if (SYSTEM_MODE.value.ToLowerInvariant().Equals("test")) 3784 { 3785 Console.WriteLine("Setting mode to 2"); 3786 devkitmsg.sys_mode_test(); 3787 } 3788 } 3789 } 3790 3791 if (CAFERUN_OPTION_FAST_RELAUNCH.value == "1") 3792 { 3793 #if false 3794 string COSDEBUG_TID_HI = CAFERUN_OPTION_MLC_EMU_TITLEID.value.Substring(2, 8); 3795 string COSDEBUG_TID_LO = CAFERUN_OPTION_MLC_EMU_TITLEID.value.Substring(10, 8); 3796 3797 cosdebug.launch_retry(Convert.ToInt32(SESSION_NET_MANAGE_PORT.value), 3798 COSDEBUG_TID_HI, COSDEBUG_TID_LO, 3799 Convert.ToInt32(CAFERUN_OPTION_FASTLAUNCH_RETRIES.value), 3800 Convert.ToInt32(CAFERUN_OPTION_FASTLAUNCH_TIMEOUT.value), 3801 Convert.ToInt32(CAFERUN_OPTION_FASTLAUNCH_DELAY.value)); 3802 if (Program.CAFE_PROFILE.value != null && Program.CAFE_PROFILE.value == "1") 3803 { 3804 CafeXEventtLog.Instance.WriteToEventLog(562, "[" + DateTime.Now.ToString("HH:mm:ss:fff") + "] [BEGIN] [CafeX]" + " System is doing FAST RELAUNCH"); 3805 } 3806 3807 if (quiet_mode) 3808 { 3809 // We need to start cattoucan to get our events and syncronize the launch 3810 CATTOUCAN_TERM.value = Nintendo.SDSG.CatToucan.Terms.KI_PIREPARE_TITLE_ASYNC; 3811 cattoucan.start(true, true, false); 3812 cosdebug.stop_retry(COSDEBUG_FASTLAUNCH_TIMEOUT); 3813 } 3814 #endif 3815 3816 if (cosdebug.try_launch(CAFERUN_OPTION_MLC_EMU_TITLEID.value, 2)) 3817 { 3818 break; 3819 } 3820 } 3821 else 3822 { 3823 if (Program.CAFE_PROFILE.value != null && Program.CAFE_PROFILE.value == "1") 3824 { 3825 CafeXEventtLog.Instance.WriteToEventLog(552, DateTime.Now, EventStatus.BEGIN, EventProcess.CAFEX, "System is doing title soft launch"); 3826 } 3827 3828 if (progress.waitForTitle) 3829 { 3830 cattoucan.BeginTitleSoftSync(); 3831 } 3832 3833 if (MCP_LAUNCH_HINT.value != null) 3834 { 3835 CMD_RESULT.value = devkitmsg.title_softlaunch_with_hint(CAFERUN_COLDBOOT_OS_VERSION.value, DISC_EMU_TID.value, MCP_LAUNCH_HINT.value, SESSION_LAUNCH_CTRL_PORT.value).ToString(); 3836 } 3837 else 3838 { 3839 CMD_RESULT.value = devkitmsg.title_softlaunch(CAFERUN_COLDBOOT_OS_VERSION.value, DISC_EMU_TID.value, SESSION_LAUNCH_CTRL_PORT.value).ToString(); 3840 } 3841 3842 if (CMD_RESULT.value == "0") 3843 { 3844 if (!progress.waitForTitle || cattoucan.SyncWithTitle(Program.KILLRESTART_SOFTLAUNCH_TIMEOUT, false)) 3845 { 3846 break; 3847 } 3848 3849 Console.WriteLine("cafex {0}: Timeout waiting for title launch", command); 3850 } 3851 } 3852 3853 if (!progress.waitForTitle) 3854 { 3855 CMD_RESULT.value = "1"; 3856 } 3857 else if (!tryCafeReboot(launch, 3858 isWumadExecution, 3859 progress, 3860 out ret.error)) 3861 { 3862 return ret; 3863 } 3864 } 3865 } 3866 3867 if (CMD_RESULT.value != "0") 3868 { 3869 cattoucan.FinishSync(true); 3870 Console.WriteLine("Failed to launch application"); 3871 ret.error = CAFEX_ERROR.RUN_LAUNCH_FAILED; 3872 return ret; 3873 } 3874 } 3875 else 3876 { 3877 if (IsBooting) 3878 { 3879 cattoucan.BeginMenuSync(); 3880 } 3881 3882 ret.error = startBootRun(isWumadExecution, launch, false); 3883 if (ret.error != CAFEX_ERROR.OK) 3884 { 3885 cattoucan.FinishSync(true); 3886 return ret; 3887 } 3888 3889 if (IsBooting) 3890 { 3891 // We need to make sure system boots successfully 3892 cattoucan.SyncWithMenu(); 3893 return ret; 3894 } 3895 } 3896 3897 ret = connect_serial_or_debugger(quiet_mode); 3898 return ret; 3899 } 3900 3901 private struct WumadInfo 3902 { 3903 public bool titleFound; 3904 public string titleId; 3905 public string appXml; 3906 public string cosXml; 3907 public string metaXml; 3908 } 3909 TryGetWumadInfo(string wumadTempDir, ref WumadInfo info)3910 private static CAFEX_ERROR TryGetWumadInfo(string wumadTempDir, ref WumadInfo info) 3911 { 3912 string[] metaFiles = Directory.GetFiles(wumadTempDir, "*metaxml.bin"); 3913 string[] appFiles = Directory.GetFiles(wumadTempDir, "*appxml.bin"); 3914 string[] cosFiles = Directory.GetFiles(wumadTempDir, "*cosxml.bin"); 3915 3916 // User provided title. 3917 string titleId = string.Empty; 3918 if (!string.IsNullOrEmpty(CAFERUN_WUMAD_TITLE_ID.value)) 3919 { 3920 titleId = CAFERUN_WUMAD_TITLE_ID.value.StartsWith("0x") ? CAFERUN_WUMAD_TITLE_ID.value.Substring(2).ToLowerInvariant() : CAFERUN_WUMAD_TITLE_ID.value.ToLowerInvariant(); 3921 } 3922 3923 info.titleFound = false; 3924 if (metaFiles.Length == 1) 3925 { 3926 // The wumad has only one title 3927 string singleTitleId = XmlHandler.GetNodeValue(appFiles[0], "title_id"); 3928 if (string.IsNullOrEmpty(titleId) || 3929 titleId.Equals("ffffffffffffffff") || 3930 titleId.Equals(singleTitleId) ) 3931 { 3932 // Empty-> auto discovery *OR* 3933 // Value-> matches user input 3934 info.titleFound = true; 3935 info.titleId = singleTitleId; 3936 info.metaXml = metaFiles[0]; 3937 info.appXml = appFiles[0]; 3938 info.cosXml = cosFiles[0]; 3939 } 3940 else 3941 { 3942 // We need to respect the title give by the user, 3943 // but provide a warning that it didn't match. 3944 if (!IsTitleIdReserved(titleId)) 3945 { 3946 3947 Console.WriteLine("cafex bootrun: WARNING: Unable to find title {0} in the wumad.", titleId); 3948 } 3949 3950 return CAFEX_ERROR.RUN_BAD_TITLE_ID; 3951 } 3952 } 3953 else 3954 { 3955 // The wumad has multiple files... need to know the title id 3956 if (string.IsNullOrEmpty(titleId) || 3957 titleId.Equals("ffffffffffffffff")) 3958 { 3959 Console.WriteLine("cafex bootrun failed: Multiple titles found in wumad. Either RPX or TitleId is required to select the title to run."); 3960 return CAFEX_ERROR.RUN_TITLE_ID_REQUIRED; 3961 } 3962 3963 // If in NAND/softlaunch mode, we shouldn't validate the title id, since 3964 // the user may really want to launch a title there is not inside the wumad. 3965 // However, we should alert the user that the title was not found, and also 3966 // not search for if we already know it is the sysconfigtool title id. 3967 if (!IsTitleIdReserved(titleId)) 3968 { 3969 // Only looking if it's not a system/reserved titleid. 3970 int targetIndex = 0; 3971 3972 for (targetIndex = 0; targetIndex < appFiles.Length; ++targetIndex) 3973 { 3974 string wumadTitle = XmlHandler.GetNodeValue(appFiles[targetIndex], "title_id").ToLowerInvariant(); 3975 Console.WriteLine("cafex run : wumad title {0} found and comparing to {1}.", wumadTitle, titleId); 3976 if (wumadTitle.Equals(titleId)) 3977 { 3978 info.titleId = titleId; 3979 info.titleFound = true; 3980 break; 3981 } 3982 } 3983 3984 if (!info.titleFound) 3985 { 3986 Console.WriteLine("cafex bootrun: WARNING: Unable to find title {0} in the wumad.", titleId); 3987 return CAFEX_ERROR.RUN_BAD_TITLE_ID; 3988 } 3989 3990 info.metaXml = metaFiles[targetIndex]; 3991 info.appXml = appFiles[targetIndex]; 3992 info.cosXml = cosFiles[targetIndex]; 3993 } 3994 } 3995 3996 return CAFEX_ERROR.OK; 3997 } 3998 IsTitleIdReserved(string fullTitleInHex)3999 private static bool IsTitleIdReserved(string fullTitleInHex) 4000 { 4001 // Reserved range: 4002 //0x00000 Through 0x000FF -> 0 <= TID <= 255 4003 //0xF7000 Through 0xF7FFF -> 1011712 <= TID <= 1015807 4004 uint badRangeMaxA = HexHandler.GetNumberFromString("0xff"); 4005 uint badRangeMinB = HexHandler.GetNumberFromString("0xf7000"); 4006 uint badRangeMaxB = HexHandler.GetNumberFromString("0xf7fff"); 4007 4008 if (string.IsNullOrEmpty(fullTitleInHex)) 4009 { 4010 // Empty title shouldn't be used, so it is reserved! 4011 return true; 4012 } 4013 4014 string titleId = fullTitleInHex.StartsWith("0x") ? fullTitleInHex.Substring(2).ToLowerInvariant() : fullTitleInHex.ToLowerInvariant(); 4015 // Need to get the following digits of the title: 000500001XXXXX00 The five "X" hex values represent the Unique Id. 4016 string uniqueId = "0x" + titleId.Substring(9, 5); 4017 uint uniqueIdValue = HexHandler.GetNumberFromString(uniqueId); 4018 4019 if (uniqueIdValue <= badRangeMaxA || 4020 (uniqueIdValue >= badRangeMinB && uniqueIdValue <= badRangeMaxB)) 4021 { 4022 // is reserved 4023 return true; 4024 } 4025 else 4026 { 4027 // is not reserved 4028 return false; 4029 } 4030 4031 } 4032 //Script function: bootrun bootrun(List<string> args, bool fAppTypeDefined)4033 static CAFEX_ERROR bootrun(List<string> args, bool fAppTypeDefined) 4034 { 4035 #if DEBUG 4036 Log.WriteLine("bootrun started."); 4037 #endif 4038 4039 int MAKE_DLF_ONLY = 0; 4040 int USE_DLF_ONLY = 0; 4041 string ELF_FILENAME = CAFE_ELF.value; 4042 4043 if (args != null && args.Count > 0) 4044 { 4045 // Check parameters 4046 while (args.Count != 0) 4047 { 4048 string OPT = args[0]; 4049 args.RemoveAt(0); 4050 switch(OPT) 4051 { 4052 case "-makedlf": 4053 // It will make the DLF, but won't use it 4054 MAKE_DLF_ONLY = 1; 4055 break; 4056 4057 case "-usedlf": 4058 USE_DLF_ONLY = 1; 4059 if (args.Count > 0) 4060 { 4061 ELF_FILENAME = args[0]; 4062 args.RemoveAt(0); 4063 } 4064 break; 4065 4066 } 4067 } 4068 } 4069 4070 CAFERUN_COLDBOOT_OS_VERSION_HI.value = CAFERUN_COLDBOOT_OS_VERSION.value.Substring(0, 8); 4071 CAFERUN_COLDBOOT_OS_VERSION_LO.value = CAFERUN_COLDBOOT_OS_VERSION.value.Substring(8, 8); 4072 4073 if (CAFERUN_OPTION_SOFT_LAUNCH.value == "1" && MAKE_DLF_ONLY == 0) 4074 { 4075 if (CAFERUN_OPTION_FAST_RELAUNCH.value == "1") 4076 { 4077 #if false 4078 string COSDEBUG_TID_HI = DISC_EMU_TID.value.Substring(0, 8); 4079 string COSDEBUG_TID_LO = DISC_EMU_TID.value.Substring(8, 8); 4080 4081 cosdebug.launch_retry(Convert.ToInt32(SESSION_NET_MANAGE_PORT.value), 4082 COSDEBUG_TID_HI, COSDEBUG_TID_LO, 4083 Convert.ToInt32(CAFERUN_OPTION_FASTLAUNCH_RETRIES.value), 4084 Convert.ToInt32(CAFERUN_OPTION_FASTLAUNCH_TIMEOUT.value), 4085 Convert.ToInt32(CAFERUN_OPTION_FASTLAUNCH_DELAY.value)); 4086 if (quiet_mode) 4087 { 4088 // We need to start cattoucan to get our events and syncronize the launch 4089 CATTOUCAN_TERM.value = Nintendo.SDSG.CatToucan.Terms.KI_PIREPARE_TITLE_ASYNC; 4090 cattoucan.start(false, false, false); 4091 cosdebug.stop_retry(COSDEBUG_FASTLAUNCH_TIMEOUT); 4092 } 4093 #endif 4094 4095 if (!cosdebug.try_launch(DISC_EMU_TID.value, 0)) 4096 { 4097 return CAFEX_ERROR.TITLE_SYNC_FAILED; 4098 } 4099 } 4100 else 4101 { 4102 devkitmsg.title_softlaunch(CAFERUN_COLDBOOT_OS_VERSION.value, DISC_EMU_TID.value, SESSION_LAUNCH_CTRL_PORT.value); 4103 } 4104 } 4105 else 4106 { 4107 if (CAFE_TEMP.value == null) 4108 { 4109 Console.WriteLine("cafex run failed: CAFE_TEMP environment variable is not set."); 4110 return CAFEX_ERROR.BOOTRUN_NO_TEMP_VAR; 4111 } 4112 else 4113 { 4114 BOOTRUN_WORK_DIR.value = CAFE_TEMP.value + "\\" + SESSION_PATH_PREFIX.value + "caferun"; 4115 WUMAD_WORK_DIR.value = CAFE_TEMP.value + "\\" + SESSION_PATH_PREFIX.value + "makewumaddlf"; 4116 } 4117 initialize_work_directory(BOOTRUN_WORK_DIR.value); 4118 4119 //FIRMWARE_FILE.value = CAFE_SLC_DIR.value + "\\sys\\title\\" + CAFERUN_COLDBOOT_OS_VERSION_HI.value + "\\" + CAFERUN_COLDBOOT_OS_VERSION_LO.value + "\\code\\fw.img"; 4120 4121 if (!string.IsNullOrEmpty(BOOTRUN_USE_RECOVERY_IMAGE.value) && BOOTRUN_USE_RECOVERY_IMAGE.value == "1") 4122 { 4123 FIRMWARE_FILE.value = string.Concat(CAFE_ROOT.value, "\\system\\bin\\", TOOLCHAIN.value, "\\", PLATFORM.value, "\\boot\\recovery.img"); 4124 } 4125 else if (CAFE_SECURITY.value == "off") 4126 { 4127 FIRMWARE_FILE.value = string.Concat(CAFE_SLC_DIR.value, "\\sys\\title\\", CAFERUN_COLDBOOT_OS_VERSION_HI.value, "\\", CAFERUN_COLDBOOT_OS_VERSION_LO.value, "\\code\\fw.bu.img"); 4128 } 4129 else 4130 { 4131 FIRMWARE_FILE.value = string.Concat(CAFE_SLC_DIR.value, "\\sys\\title\\", CAFERUN_COLDBOOT_OS_VERSION_HI.value, "\\", CAFERUN_COLDBOOT_OS_VERSION_LO.value, "\\code\\fw.img"); 4132 } 4133 4134 BOOT_DLF_FILE.value = BOOTRUN_WORK_DIR.value + "\\ppc_boot.dlf"; 4135 4136 CAFEX_ERROR boot1file_ret = make_boot1_system_file(BOOTRUN_WORK_DIR.value + "\\ppc.bsf"); 4137 if (boot1file_ret != CAFEX_ERROR.OK) 4138 { 4139 return boot1file_ret; 4140 } 4141 4142 string diskid = BOOTRUN_WORK_DIR.value + "\\diskid.bin"; 4143 File.Copy(CAFE_ROOT.value + "\\system\\bin\\" + TOOLCHAIN.value + "\\" + PLATFORM.value + "\\boot\\diskid.bin", diskid, true); 4144 File.SetAttributes(diskid, FileAttributes.Normal); 4145 4146 CAFEX_ERROR bootdlf_ret = make_boot_dlf(diskid + "," + BOOTRUN_WORK_DIR.value + "\\ppc.bsf," + FIRMWARE_FILE.value, BOOT_DLF_FILE.value); 4147 if (bootdlf_ret != CAFEX_ERROR.OK) 4148 { 4149 return bootdlf_ret; 4150 } 4151 4152 if (DISC_EMU_TYPE.value == "blockemu") 4153 { 4154 if (!string.IsNullOrEmpty(ELF_FILENAME) && 4155 ELF_FILENAME.EndsWith(".rpx")) 4156 { 4157 if (USE_DLF_ONLY == 0) 4158 { 4159 CAFEX_ERROR run_ret = devrun(ELF_FILENAME, null, null, null); 4160 if (run_ret != CAFEX_ERROR.OK) 4161 { 4162 return run_ret; 4163 } 4164 } 4165 4166 if (MAKE_DLF_ONLY == 0) 4167 { 4168 hostrun(BOOT_DLF_FILE.value + " " + Path.ChangeExtension(ELF_FILENAME, ".dlf")); 4169 } 4170 4171 } 4172 } 4173 else // HFIO case & HDD case & WUMAD case 4174 { 4175 if (!string.IsNullOrEmpty(CAFE_WUMAD.value)) 4176 { 4177 // WUMAD case 4178 // Create the DLF from a WUMAD file. 4179 string wumadTempName = null; 4180 string wumadTempDir = null; 4181 string wumadDlfName = null; 4182 4183 if (CAFE_WUMAD.value.ToLower().EndsWith("wumad")) 4184 { 4185 // A WUMAD file was passed instead of a directory. 4186 Console.WriteLine("Creating DLF from WUMAD file..."); 4187 wumadTempName = Path.GetFileNameWithoutExtension(CAFE_WUMAD.value); 4188 wumadTempDir = Path.Combine(WUMAD_WORK_DIR.value, wumadTempName); 4189 wumadDlfName = Path.Combine(wumadTempDir, wumadTempName + ".dlf"); 4190 } 4191 else 4192 { 4193 // A directory was passed in. 4194 wumadTempName = null; 4195 wumadTempDir = CAFE_WUMAD.value; 4196 wumadDlfName = Path.Combine(WUMAD_WORK_DIR.value, "extractedWumad.dlf"); 4197 4198 } 4199 4200 if (wumadTempName != null) 4201 { 4202 wumadTempName = CAFE_WUMAD.value; 4203 } 4204 4205 Console.WriteLine("wumadName = " + wumadTempName); 4206 Console.WriteLine("wumadDir = " + wumadTempDir); 4207 Console.WriteLine("wumadDlf = " + wumadDlfName); 4208 4209 CAFEX_ERROR wumad_dlf_ret = make_wumad_dlf(wumadTempName, wumadTempDir, wumadDlfName); 4210 if (wumad_dlf_ret != CAFEX_ERROR.OK) 4211 { 4212 return wumad_dlf_ret; 4213 } 4214 4215 WumadInfo info = new WumadInfo(); 4216 CAFEX_ERROR wumadInfoResult = TryGetWumadInfo(wumadTempDir, ref info); 4217 // If a title id is required because there are more than one in the wumad 4218 // and none was provided, should stop here. 4219 if (wumadInfoResult == CAFEX_ERROR.RUN_TITLE_ID_REQUIRED) 4220 { 4221 return wumadInfoResult; 4222 } 4223 4224 // We always need to set the titleId, if the function 4225 // returned one. This allows the data to be available upstream 4226 // in a sequence of calls involving softlaunch. 4227 if (info.titleFound) 4228 { 4229 CAFERUN_WUMAD_TITLE_ID.value = info.titleId; 4230 } 4231 else 4232 { 4233 CAFERUN_WUMAD_TITLE_ID.value = string.Empty; 4234 } 4235 4236 // If no RPX was provided, the xmls not been updated. 4237 // This is a valid assumption because the code in caferun 4238 // sets all the xmls besed on an RPX provide prior to call 4239 // bootrun 4240 if (string.IsNullOrEmpty(ELF_FILENAME) && 4241 info.titleFound) 4242 { 4243 string contentMetaXml = CAFE_META_DIR.value + "\\meta.xml"; 4244 file_copy_retry(info.metaXml, contentMetaXml, true, 3); 4245 4246 // Get the title-id, version, app_type, etc from the WUMAD files 4247 string title_id = XmlHandler.GetNodeValue(info.appXml, "title_id"); 4248 string title_version = XmlHandler.GetNodeValue(info.appXml, "title_version"); 4249 string os_version = XmlHandler.GetNodeValue(info.appXml, "os_version"); 4250 string app_type = XmlHandler.GetNodeValue(info.appXml, "app_type"); 4251 string app_group_id = XmlHandler.GetNodeValue(info.appXml, "group_id"); 4252 4253 // Save config to meta.xml 4254 XmlHandler.UpdateNodeValue(contentMetaXml, "title_id", title_id); 4255 XmlHandler.UpdateNodeValue(contentMetaXml, "group_id", app_group_id); 4256 XmlHandler.UpdateNodeValue(contentMetaXml, "title_version", title_version); 4257 4258 // Convert the title_id from a string to a number for lookup 4259 Int64 iTitleID = Convert.ToInt64(title_id, 16); 4260 4261 if (fAppTypeDefined) 4262 { 4263 app_type = CAFERUN_APP_TYPE.value; 4264 } 4265 else 4266 { 4267 //Look up the App Type using the Title ID 4268 string calculated_app_type = FindAppType(iTitleID); 4269 if (app_type.CompareTo(calculated_app_type) != 0) 4270 { 4271 Console.WriteLine("WARNING: Calculated AppType does not match what was in APP.XML"); 4272 Console.WriteLine("Overwriting with the calculated value for AppType"); 4273 } 4274 app_type = calculated_app_type; 4275 } 4276 4277 // Save config to system.xml 4278 XmlHandler.UpdateNodeValue(SYSTEM_XML.value, "default_title_id", title_id); 4279 XmlHandler.UpdateNodeValue(SYSTEM_XML.value, "default_app_type", app_type); 4280 XmlHandler.UpdateNodeValue(SYSTEM_XML.value, "default_os_id", os_version); 4281 } 4282 4283 // Starts the emulation 4284 if (MAKE_DLF_ONLY == 0) 4285 { 4286 hostrun(BOOT_DLF_FILE.value + " " + wumadDlfName); 4287 } 4288 } 4289 else 4290 { 4291 // HFIO and HDD cases 4292 if (MAKE_DLF_ONLY == 0) 4293 { 4294 hostrun(BOOT_DLF_FILE.value); 4295 } 4296 } 4297 } 4298 } 4299 4300 return CAFEX_ERROR.OK; 4301 } 4302 4303 //Script function: cafedevrun devrun(string elf, string MAKE_PATCH, string CAFEMAKEDLF_OPTION, string KIOSK_DEFAULT_DDF)4304 static CAFEX_ERROR devrun(string elf, string MAKE_PATCH, string CAFEMAKEDLF_OPTION, string KIOSK_DEFAULT_DDF) 4305 { 4306 #if DEBUG 4307 Log.WriteLine("devrun started."); 4308 #endif 4309 4310 APP_TITLE_ID.value = "0000000000000000"; 4311 APP_GROUP_ID.value = "00000000"; 4312 APP_TITLE_VERSION.value = "0000"; 4313 4314 if (elf == null) 4315 { 4316 Console.WriteLine("cafex cafedevrun failed: image file required!"); 4317 return CAFEX_ERROR.CAFEDEVRUN_NO_IMAGE_FILE; 4318 } 4319 4320 CAFEDEVRUN_FILE.value = elf; 4321 CAFEDEVRUN_EXT.value = Path.GetExtension(elf).Remove(0, 1); 4322 CAFEDEVRUN_NAME.value = Path.GetDirectoryName(elf) + "\\" + Path.GetFileNameWithoutExtension(elf); 4323 CAFEDEVRUN_FILENAME.value = Path.GetFileNameWithoutExtension(elf); 4324 CAFEDEVRUN_DIR.value = Path.GetDirectoryName(elf); 4325 4326 string GAME_TYPE = null; 4327 if (MAKE_PATCH != null && MAKE_PATCH == "1") 4328 { 4329 GAME_TYPE = "GP"; 4330 } 4331 else 4332 { 4333 GAME_TYPE = "GM"; 4334 } 4335 4336 // Check temporary directory 4337 CAFEDEVRUN_WORK_DIR.value = CAFEDEVRUN_NAME.value + "_tmp"; 4338 create_directory_if_noexist(CAFEDEVRUN_WORK_DIR.value); 4339 4340 if (INCLUDE_SYSTEM_DIR.value == null) 4341 { 4342 INCLUDE_SYSTEM_DIR.value = "0"; 4343 } 4344 4345 CAFE_BASEFILE_PATH.value = CAFE_ROOT.value + "\\system\\bin\\tool\\mastering\\resources"; 4346 if (string.IsNullOrEmpty(KIOSK_DEFAULT_DDF)) 4347 { 4348 DEFAULT_DDF.value = CAFE_BASEFILE_PATH.value + "\\default.ddf"; 4349 } 4350 else 4351 { 4352 Console.WriteLine("Change default ddf -> " + KIOSK_DEFAULT_DDF); 4353 DEFAULT_DDF.value = KIOSK_DEFAULT_DDF; 4354 } 4355 4356 COMMON_DDF_FILE.value = CAFEDEVRUN_WORK_DIR.value + "\\common.ddf"; 4357 4358 string custom_ddf = Path.ChangeExtension(elf, ".ddf"); 4359 // Use individual ddf file if exists 4360 if (File.Exists(custom_ddf)) 4361 { 4362 INDIVIDUAL_DDF_FILE.value = custom_ddf; 4363 // TODO: Need to replace the game type in the custo_ddf file and save it. 4364 } 4365 else 4366 { 4367 INDIVIDUAL_DDF_FILE.value = ""; 4368 } 4369 4370 APP_XML_FILE.value = CAFEDEVRUN_DIR.value + "\\app.xml"; 4371 if (!File.Exists(APP_XML_FILE.value)) 4372 { 4373 Console.WriteLine("cafex cafedevrun failed: Cannot find " + APP_XML_FILE.value); 4374 return CAFEX_ERROR.CAFEDEVRUN_CANT_FIND_APP_XML; 4375 } 4376 4377 extract_info_from_app_xml(APP_XML_FILE.value); 4378 4379 FileStream fs = new FileStream(COMMON_DDF_FILE.value, FileMode.Create); 4380 StreamWriter sw = new StreamWriter(fs); 4381 sw.WriteLine(";"); 4382 sw.WriteLine("; " + CAFEDEVRUN_NAME.value + "." + CAFEDEVRUN_EXT.value); 4383 sw.WriteLine(";"); 4384 sw.WriteLine("[Input]"); 4385 sw.WriteLine("DiscHeaderBaseFileName=\"" + CAFE_BASEFILE_PATH.value + "\\discheader_base.bin\""); 4386 sw.WriteLine("VolumeHeaderBaseFileName=\"" + CAFE_BASEFILE_PATH.value + "\\volheader_base.bin\""); 4387 sw.WriteLine("[Output]"); 4388 sw.WriteLine("LayoutFileName=\"" + CAFEDEVRUN_NAME.value + ".dlf\""); 4389 sw.WriteLine("OutputDirectory=\"" + CAFEDEVRUN_DIR.value + "\""); 4390 sw.WriteLine("AppName=\"" + CAFEDEVRUN_FILENAME.value + "\""); 4391 sw.WriteLine("Mode=WU"); 4392 sw.WriteLine("[DiscID]"); 4393 sw.WriteLine("GameType=" + GAME_TYPE); 4394 sw.WriteLine("TitleId=0x" + APP_TITLE_ID.value); 4395 sw.WriteLine("GroupId=0x" + APP_GROUP_ID.value); 4396 sw.WriteLine("DiskNumber=0"); 4397 sw.WriteLine("GameVersion=" + (HexHandler.GetNumberFromString("0x" + APP_TITLE_VERSION.value) / 16).ToString()); 4398 sw.WriteLine("[SectionParam]"); 4399 sw.WriteLine("\"CONTENT\"=0x" + APP_TITLE_ID.value + ",0x" + APP_GROUP_ID.value + ",0x02"); 4400 sw.WriteLine("[PathList]"); 4401 sw.WriteLine("CODE_DIR_RPX=\"code\", \"$(CAFE_CODE_DIR)\\" + CAFEDEVRUN_FILENAME.value + ".rpx\""); 4402 4403 if (INCLUDE_SYSTEM_DIR.value == "1") 4404 { 4405 sw.WriteLine("[PathList]"); 4406 sw.WriteLine("SYSTEM_DIR=\"sys\", \"$(CAFE_SYSTEM_DIR)\""); 4407 } 4408 4409 sw.Flush(); 4410 sw.Close(); 4411 4412 int cafemakedlf_ret = cafemakedlf.make(DEFAULT_DDF.value, COMMON_DDF_FILE.value, INDIVIDUAL_DDF_FILE.value, CAFEMAKEDLF_OPTION); 4413 4414 if (cafemakedlf_ret != 0) 4415 { 4416 return CAFEX_ERROR.CAFEDEVRUN_CAFEMAKEDLF_FAILED; 4417 } 4418 4419 fs = new FileStream(CAFEDEVRUN_NAME.value + ".dlf", FileMode.Append); 4420 sw = new StreamWriter(fs); 4421 sw.WriteLine("0x00000005D3A00000,\"\""); 4422 sw.Flush(); 4423 sw.Close(); 4424 4425 return CAFEX_ERROR.OK; 4426 } 4427 4428 //Script function: hostrun hostrun(string arguments)4429 static void hostrun(string arguments) 4430 { 4431 #if DEBUG 4432 Log.WriteLine("hostrun started. Arguments:" + arguments); 4433 #endif 4434 4435 getbridgetype(); 4436 4437 FSEMUL_PARAMS.value = null; 4438 if (BRIDGE_TYPE.value == "Toucan") 4439 { 4440 BRIDGE_INSTALL_PATH.value = SDIO_BRIDGE_TOOLS.value; 4441 } 4442 else 4443 { 4444 BRIDGE_INSTALL_PATH.value = MION_BRIDGE_TOOLS.value; 4445 } 4446 4447 if (BRIDGE_TYPE.value == "Mion") 4448 { 4449 if (BRIDGE_PARAMETERS.value == null) 4450 { 4451 FSEMUL_PARAMS.value = "-em -ip " + BRIDGE_CURRENT_IP_ADDRESS.value; 4452 } 4453 else 4454 { 4455 FSEMUL_PARAMS.value = BRIDGE_PARAMETERS.value + " -ip " + BRIDGE_CURRENT_IP_ADDRESS.value; 4456 } 4457 } 4458 4459 if (execLaunchCmd && !string.IsNullOrEmpty(LAUNCH_DLF_FILE)) 4460 { 4461 string[] splitStrings = arguments.Split(' '); 4462 int i = 0; 4463 arguments = splitStrings[i++] + " " + LAUNCH_DLF_FILE + " "; 4464 for (; i < splitStrings.Length; i++) 4465 { 4466 arguments += splitStrings[i] + " "; 4467 } 4468 } 4469 4470 // Need to figure out what the difference between these two options is in the scripts, and if it is possible to replicate here. 4471 if (CAFE_DETACH_FSEMUL.value == null || CAFE_DETACH_FSEMUL.value != "0") 4472 { 4473 FSEmul.start(arguments, FSEMUL_PARAMS.value); 4474 } 4475 else 4476 { 4477 FSEmul.start(arguments, FSEMUL_PARAMS.value); 4478 } 4479 4480 // Remeber what the boot mode was when we cold booted the DEVKIT 4481 string boot_mode_file = Path.Combine(CAFE_TEMP.value, string.Format("{0}_{1}_CAFE_BOOT_MODE", BRIDGE_CURRENT_IP_ADDRESS.value.Replace('.', 'x'), BRIDGE_CURRENT_NAME.value)); 4482 File.WriteAllText(boot_mode_file, CAFE_BOOT_MODE.value); 4483 4484 if (Program.CAFE_PROFILE.value != null && Program.CAFE_PROFILE.value == "1") 4485 { 4486 CafeXEventtLog.Instance.WriteToEventLog(572, DateTime.Now, EventStatus.DISCRETE, EventProcess.CAFEX, "System is going through cold boot"); 4487 } 4488 } 4489 4490 //Script function: cafediscrun discrun(string[] args, bool runSetup, bool launch)4491 static CafeXReturn discrun(string[] args, bool runSetup, bool launch) 4492 { 4493 #if DEBUG 4494 Log.WriteLine("discrun started."); 4495 string argString = null; 4496 if (args != null) 4497 { 4498 foreach (string arg in args) 4499 { 4500 argString += arg + " "; 4501 } 4502 } 4503 Log.WriteLine("Arguments=" + argString); 4504 4505 #endif 4506 4507 CAFERUN_OPTION_CALLED_FROM_CAFEDISCRUN.value = "yes"; 4508 return run(args, runSetup, launch); 4509 } 4510 4511 4512 //Script function: cafeheadlessrun headlessrun(string[] args)4513 static CafeXReturn headlessrun(string[] args) 4514 { 4515 #if DEBUG 4516 Log.WriteLine("headlessrun started."); 4517 string argString = null; 4518 if (args != null) 4519 { 4520 foreach (string arg in args) 4521 { 4522 argString += arg + " "; 4523 } 4524 } 4525 Log.WriteLine("Arguments=" + argString); 4526 #endif 4527 4528 string HLRUN_OUT = Path.Combine(CAFE_TEMP.value, SESSION_PATH_PREFIX.value + "headlessrun"); 4529 string HLRUN_TMP = Path.Combine(HLRUN_OUT, "tmp"); 4530 4531 bool RUN_DEVMENU = true; // Run Devmenu after upload 4532 bool BYPASS_SETUP = false; // Bypass mastering step 4533 int TITLE_WAIT = 15; // Time to wait for the title to boot (in seconds) 4534 bool DEBUG_FLAG = false; // Use the DEBUG version of the OS 4535 int UPLOAD_BANK = 10; // Bank to upload the mastered image to 4536 string RPX_PATH = string.Empty; // Path to the RPX file 4537 string[] RPX_ARGS = new string[0]; // Arguments to the RPX file 4538 4539 CafeXReturn ret = new CafeXReturn(CAFEX_ERROR.OK); 4540 4541 // 4542 // check_args 4543 // 4544 for (int i = 0; i < args.Length; ++i) 4545 { 4546 switch (args[i]) 4547 { 4548 case "-b": 4549 { 4550 DEBUG_FLAG = true; 4551 break; 4552 } 4553 4554 case "-h": 4555 { 4556 if (!ArgumentChecks.IsArgumentValidSetting(args, i + 1)) 4557 { 4558 headlessrun_usage(); 4559 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 4560 } 4561 4562 if (!int.TryParse(args[i + 1], out UPLOAD_BANK)) 4563 { 4564 Console.WriteLine("Error: '{0}' is not a valid number!", args[i + 1]); 4565 headlessrun_usage(); 4566 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 4567 } 4568 ++i; 4569 break; 4570 } 4571 4572 case "-n": 4573 { 4574 RUN_DEVMENU = false; 4575 break; 4576 } 4577 4578 case "-m": 4579 { 4580 BYPASS_SETUP = true; 4581 break; 4582 } 4583 4584 case "-w": 4585 { 4586 if (!ArgumentChecks.IsArgumentValidSetting(args, i + 1)) 4587 { 4588 headlessrun_usage(); 4589 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 4590 } 4591 4592 if (!int.TryParse(args[i + 1], out TITLE_WAIT)) 4593 { 4594 Console.WriteLine("Error: '{0}' is not a valid number!", args[i + 1]); 4595 headlessrun_usage(); 4596 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 4597 } 4598 4599 if (TITLE_WAIT < 0) 4600 { 4601 Console.WriteLine("Error: Wait time can't be less than zero!"); 4602 headlessrun_usage(); 4603 return new CafeXReturn(CAFEX_ERROR.BAD_ARGUMENT); 4604 } 4605 4606 ++i; 4607 break; 4608 } 4609 4610 case "-u": 4611 { 4612 headlessrun_usage(); 4613 return new CafeXReturn(CAFEX_ERROR.OK); 4614 } 4615 4616 default: 4617 { 4618 if (string.IsNullOrEmpty(RPX_PATH)) 4619 { 4620 RPX_PATH = args[i]; 4621 } 4622 else 4623 { 4624 if (i < args.Length) 4625 { 4626 int start = i; 4627 RPX_ARGS = new string[args.Length - 1]; 4628 while (i < args.Length) 4629 { 4630 RPX_ARGS[i - start] = args[i]; 4631 } 4632 } 4633 i = args.Length; 4634 } 4635 break; 4636 } 4637 } 4638 } 4639 4640 string makecfmaster = getPathToMakeCfMaster(); 4641 if (makecfmaster == null) 4642 { 4643 Console.WriteLine("headlessrun requires makecfmaster.exe but it's not found."); 4644 return new CafeXReturn(CAFEX_ERROR.MASTERING_ERROR); 4645 } 4646 4647 if (string.IsNullOrEmpty(RPX_PATH)) 4648 { 4649 Console.WriteLine("cafex headlessrun failed: RPX file is missing on command line!"); 4650 headlessrun_usage(); 4651 return new CafeXReturn(CAFEX_ERROR.RUN_NO_RPX_SPECIFIED); 4652 } 4653 4654 // 4655 // update_bootloader 4656 // 4657 ret.error = hostcheckversion(); 4658 if (ret.error != CAFEX_ERROR.OK) 4659 { 4660 Console.WriteLine("cafex headlessrun: failed running hostcheckversion."); 4661 return ret; 4662 } 4663 4664 string boot_mode = string.Empty; 4665 4666 int hb_ver_flat = compute_flat_version(CAFERUN_HOSTBRIDGE_VERSION.value); 4667 if (hb_ver_flat < compute_flat_version("3.2.4.8")) 4668 { 4669 Console.WriteLine("cafex headlessrun: Using BOOT mode " + CAFE_BOOT_MODE.value); 4670 } 4671 else 4672 { 4673 Console.WriteLine("cafex headlessrun: Checking for DUAL bootloader..."); 4674 4675 // hostbridge 3.2.5.1 has a problem in mode detection that requires some time after stop 4676 // in order to properly detect boot mode 4677 try 4678 { 4679 stop(new string[] { "-hard" }); 4680 } 4681 catch (Exception e) 4682 { 4683 Console.WriteLine("cafex recover[warning]: Failure to hard stop the DEVKIT prior to mode detection, error {0}", e.Message); 4684 } 4685 Thread.Sleep(1000); 4686 4687 int boot_mode_detect = FSEmul.boot_mode_detect(BRIDGE_CURRENT_IP_ADDRESS.value, out boot_mode); 4688 if (boot_mode_detect != 0) 4689 { 4690 Console.WriteLine("cafex headlessrun: Unable to determine boot mode!"); 4691 return new CafeXReturn(CAFEX_ERROR.BOOTMODEDETECT_FSEMUL_FAILED); 4692 } 4693 4694 Console.WriteLine("cafex headlessrun: Detected BOOT mode : {0}", boot_mode); 4695 } 4696 4697 if (boot_mode.Substring(0, 4) != "DUAL") 4698 { 4699 // Install the DUAL bootlooder 4700 ret.error = recover(null); 4701 if (ret.error != CAFEX_ERROR.OK) 4702 { 4703 return ret; 4704 } 4705 } 4706 4707 if (!BYPASS_SETUP) 4708 { 4709 // 4710 // prepare_rpx_for_mastering 4711 // 4712 CAFE_BOOT_MODE.value = "PCFS"; 4713 4714 // Disable the builtin capturing of output 4715 string OLD_CAFE_CONSOLE = CAFE_CONSOLE.value; 4716 CAFE_CONSOLE.value = "notoucan"; 4717 4718 // Run the RPX to create the dependent files needed for mastering 4719 string[] discrun_args = new string[5 + (DEBUG_FLAG ? 1 : 0) + RPX_ARGS.Length]; 4720 int discrun_idx = 0; 4721 4722 if (DEBUG_FLAG) 4723 { 4724 discrun_args[discrun_idx++] = "-b"; 4725 } 4726 discrun_args[discrun_idx++] = "-e"; 4727 discrun_args[discrun_idx++] = "em"; 4728 discrun_args[discrun_idx++] = "-e"; 4729 discrun_args[discrun_idx++] = "sata"; 4730 discrun_args[discrun_idx++] = RPX_PATH; 4731 RPX_ARGS.CopyTo(discrun_args, discrun_idx); 4732 4733 Console.WriteLine("cafex headlessrun: calling discrun {0}", string.Join(" ", discrun_args)); 4734 ret = discrun(discrun_args, true, true); 4735 4736 // Wait for MCP to come up 4737 int mon_ret = monitor_for_output("-k", "[+-* DK is ready for console input *-+]", "30", CAFE_TEMP.value, null, true); 4738 if (mon_ret == 0) // TODO: This should be from the MON_RESULT enumeration 4739 { 4740 Console.WriteLine("cafex headlessrun: Master image prep for '{0}' succeeded.", RPX_PATH); 4741 } 4742 else 4743 { 4744 Console.WriteLine("cafex headlessrun: Master image prep for '{0}' failed with code {1}!", RPX_PATH, mon_ret); 4745 return new CafeXReturn(CAFEX_ERROR.MASTERING_ERROR); 4746 } 4747 4748 // Give the title time to boot up in case it writes files needed for mastering 4749 Console.WriteLine("cafex headlessrun: waiting {0} seconds for title to boot...", TITLE_WAIT); 4750 Thread.Sleep(TITLE_WAIT * 1000); 4751 4752 CAFE_CONSOLE.value = OLD_CAFE_CONSOLE; 4753 4754 stop(null); 4755 Thread.Sleep(2000); 4756 } 4757 4758 // 4759 // master_image 4760 // 4761 4762 // Create the working and temp folders 4763 Directory.CreateDirectory(HLRUN_TMP); 4764 4765 // Create the master image for the last ran RPX 4766 ret.error = makeMaster(new string[] { "-r", RPX_PATH, "-o", Path.Combine(HLRUN_OUT, "title"), "-w", HLRUN_TMP }); 4767 if (ret.error == CAFEX_ERROR.OK) 4768 { 4769 Console.WriteLine("cafex headlessrun: Mastering image for {0} succeeded.", RPX_PATH); 4770 } 4771 else 4772 { 4773 Console.WriteLine("cafex headlessrun:Mastering image for $RPX_PATH failed with code {0}!", ret); 4774 return ret; 4775 } 4776 4777 // 4778 // upload_image 4779 // 4780 int imageuploader_ret = ImageUploader.upload(BRIDGE_CURRENT_IP_ADDRESS.value, UPLOAD_BANK, Path.Combine(HLRUN_OUT, "title.wumad")); 4781 if (imageuploader_ret == 0) 4782 { 4783 Console.WriteLine("cafex headlessrun: ImageUpload to bank {0} succeeded.", UPLOAD_BANK); 4784 } 4785 else 4786 { 4787 Console.WriteLine("cafex headlessrun: ImageUpload to bank {0} failed with code {0}!", UPLOAD_BANK, imageuploader_ret); 4788 return new CafeXReturn(CAFEX_ERROR.IMAGEUPLOADER_FAILED); 4789 } 4790 4791 // 4792 // set_hreader_mode 4793 // 4794 int mionurl_ret = mionurl.Run(string.Format("{0} /setup.cgi id_27={1} id_32=1 op=0", BRIDGE_CURRENT_IP_ADDRESS.value, UPLOAD_BANK)); 4795 if (mionurl_ret == 0) 4796 { 4797 Console.WriteLine("cafex headlessrun: mionurl succeeded to set HREADER mode."); 4798 } 4799 else 4800 { 4801 Console.WriteLine("cafex headlessrun: mionurl failed to set HREADER mode with code {0}!", mionurl_ret); 4802 return new CafeXReturn(CAFEX_ERROR.MIONURL_FAILED); 4803 } 4804 4805 // Reboot MION and wait for completion so Bank and HREADER mode can take effect 4806 string miontelnet_output; 4807 Console.WriteLine("cafex headlessrun: Rebooting MION..."); 4808 int miontelnet_ret = miontelnet.Reboot(out miontelnet_output); 4809 Console.WriteLine(miontelnet_output); 4810 4811 if (RUN_DEVMENU) 4812 { 4813 // 4814 // run_image 4815 // 4816 4817 // Change the boot mode TO NAND 4818 CAFE_BOOT_MODE.value = "NAND"; 4819 4820 string[] discrun_args = new string[DEBUG_FLAG ? 6 : 5]; 4821 int discrun_idx = 0; 4822 4823 if (DEBUG_FLAG) 4824 { 4825 discrun_args[discrun_idx++] = "-b"; 4826 } 4827 discrun_args[discrun_idx++] = "-e"; 4828 discrun_args[discrun_idx++] = string.Format("h:{0}", UPLOAD_BANK); 4829 discrun_args[discrun_idx++] = "-e"; 4830 discrun_args[discrun_idx++] = "nopcfs"; 4831 discrun_args[discrun_idx++] = RPX_PATH; 4832 4833 Console.WriteLine("cafex headlessrun: calling discrun {0}", string.Join(" ", discrun_args)); 4834 return discrun(discrun_args, true, true); 4835 } 4836 else 4837 { 4838 Console.WriteLine("cafex headlessrun: completed sucessfully."); 4839 } 4840 4841 return new CafeXReturn(CAFEX_ERROR.OK); 4842 } 4843 4844 //Script function: cafeon on(string[] args, bool runSetup, bool launch)4845 static CafeXReturn on(string[] args, bool runSetup, bool launch) 4846 { 4847 #if DEBUG 4848 Log.WriteLine("on started."); 4849 string argString = null; 4850 if (args != null) 4851 { 4852 foreach (string arg in args) 4853 { 4854 argString += arg + " "; 4855 } 4856 } 4857 Log.WriteLine("Arguments=" + argString); 4858 4859 #endif 4860 List<string> argList = new List<string>(); 4861 CafeXReturn ret = new CafeXReturn(CAFEX_ERROR.OK); 4862 4863 CAFEON_DISABLE_BGD.value = "0"; 4864 CAFEON_NOBGD_META.value = ""; 4865 BRIDGE_PARAMETERS_WITH_E.value = ""; 4866 CAFE_RUN_DEBUG.value = ""; 4867 BOOTRUN_USE_RECOVERY_IMAGE.value = ""; 4868 4869 CAFEON_OPTION_NO_DATA_SYNC.value = CAFERUN_OPTION_NO_DATA_SYNC.value; 4870 4871 if (CAFEON_OPTION_NO_DATA_SYNC.value == null) 4872 { 4873 CAFEON_OPTION_NO_DATA_SYNC.value = "0"; 4874 } 4875 4876 if (CAFE_RUN_RUNNING.value == null) 4877 { 4878 CAFE_RUN_RUNNING.value = "0"; 4879 } 4880 4881 if (CAFE_RUN_RUNNING.value != "0") 4882 { 4883 Console.WriteLine("****cafex on: RECURSIVE CALL TO cafex on EXITING***"); 4884 ret.error = CAFEX_ERROR.ON_RECURSIVE_CALL; 4885 return ret; 4886 } 4887 4888 CAFE_RUN_RUNNING.value = "1"; 4889 4890 if (args != null && args.Length > 0) 4891 { 4892 for (int i = 0; i < args.Length; ++i) 4893 { 4894 if (args[i] == "-noprompt") 4895 { 4896 CATTOUCAN_TERM.value = Nintendo.SDSG.CatToucan.Terms.MENU_SOURCE; 4897 } 4898 else if (args[i] == "-d") 4899 { 4900 CAFE_RUN_DEBUG.value = args[i] + " " + args[i + 1]; 4901 ++i; 4902 } 4903 else if (args[i] == "-e") 4904 { 4905 BRIDGE_PARAMETERS_WITH_E.AddToVar(args[i] + " " + args[i + 1], ' '); 4906 ++i; 4907 } 4908 else if (args[i] == "-nobgd") 4909 { 4910 CAFEON_DISABLE_BGD.value = "1"; 4911 } 4912 else if (args[i] == "-nosync") 4913 { 4914 if (string.IsNullOrEmpty(CAFE_DATA_DIR.value) || 4915 !Directory.Exists(CAFE_DATA_DIR.value)) 4916 { 4917 Console.WriteLine("Session data directory is missing and needs to be sync'd!"); 4918 Console.WriteLine(" Please re-run without the '-nosync' option."); 4919 ret.error = CAFEX_ERROR.ON_DATA_DIR_MISSING; 4920 return ret; 4921 } 4922 4923 CAFEON_OPTION_NO_DATA_SYNC.value = "1"; 4924 } 4925 else if (args[i] == "-recover") 4926 { 4927 _CCRSYSCFG1.value = "0x40000000"; 4928 BOOTRUN_USE_RECOVERY_IMAGE.value = "1"; 4929 } 4930 else if (args[i] == "-h") 4931 { 4932 on_usage(); 4933 ret.error = CAFEX_ERROR.OK; 4934 return ret; 4935 } 4936 else 4937 { 4938 // This is an argument that needs to be passed down 4939 argList.Add(args[i]); 4940 } 4941 } 4942 } 4943 4944 if (CAFEON_DISABLE_BGD.value == "1") 4945 { 4946 if (!string.IsNullOrEmpty(CAFE_META_DIR.value) && 4947 Directory.Exists(CAFE_META_DIR.value)) 4948 { 4949 CAFEON_NOBGD_META.value = CAFE_TEMP.value + "\\" + SESSION_PATH_PREFIX.value + "tmp_meta"; 4950 Console.WriteLine("Disabling background daemons in tmp dir " + CAFEON_NOBGD_META.value); 4951 DirectoryInfo originMetaDiretory = new DirectoryInfo(CAFE_META_DIR.value); 4952 FileSystemInfo[] filesToCopy = originMetaDiretory.GetFileSystemInfos(); 4953 if (filesToCopy.Length > 0) 4954 { 4955 create_directory_if_noexist(CAFEON_NOBGD_META.value); 4956 string[] meta_files = Directory.GetFiles(CAFE_META_DIR.value); 4957 foreach (FileSystemInfo file in filesToCopy) 4958 { 4959 string fileName = file.FullName; 4960 string destinationFileName = CAFEON_NOBGD_META.value + "\\" + Path.GetFileName(fileName); 4961 file_copy_retry(fileName, destinationFileName, true, 3); 4962 } 4963 4964 XmlHandler.UpdateNodeValue(CAFEON_NOBGD_META.value + "\\meta.xml", "bg_daemon_enable", "0"); 4965 4966 CAFE_META_DIR.value = CAFEON_NOBGD_META.value; 4967 } 4968 } 4969 } 4970 4971 OS_VERSION_LO.value = XmlHandler.GetNodeValue(CAFE_ROOT.value + "\\data\\mlc\\sys\\title\\00050010\\1f700500\\code\\app.xml", "os_version").Substring(8, 6); 4972 string total_arglist_with_qs = StringCombiner.MakeDelimitedString(argList.ToArray(), ' ').Replace(' ', '?').Replace("-c?", "-c ").Replace("?-c", " -c"); 4973 4974 if (OS_VERSION_LO.value == null) 4975 { 4976 Console.WriteLine("cafex on error: unable to locate System Config Tool app.xml or file is corrupt"); 4977 } 4978 else 4979 { 4980 if (CAFEON_OPTION_NO_DATA_SYNC.value == "0") 4981 { 4982 ret.error = syncsession(null); 4983 if (CAFEX_ERROR.OK != ret.error) 4984 { 4985 return ret; 4986 } 4987 } 4988 4989 XmlHandler.UpdateNodeValue(CAFE_DATA_DIR.value + "\\mlc\\sys\\title\\00050010\\1f700500\\code\\cos.xml", "argstr", "system_config_tool.rpx " + total_arglist_with_qs); 4990 4991 // Keep the current command stored, so when run is called it knows it has last been called by 'on' 4992 string currentCommand = command; 4993 command = "on"; 4994 string OS_string = string.Empty; 4995 if (OS_VERSION_LO.value == "100040") 4996 { 4997 // NDEBUG OS 4998 OS_string = CAFE_ROOT.value + "\\system\\bin\\ghs\\cafe\\app\\system_config_tool\\base\\NDEBUG\\system_config_tool.rpx"; 4999 } 5000 else if (OS_VERSION_LO.value == "100080") 5001 { 5002 // DEBUG OS 5003 OS_string = "-b" + DEFAULT_DELIMITER + CAFE_ROOT.value + "\\system\\bin\\ghs\\cafe\\app\\system_config_tool\\base\\DEBUG\\system_config_tool.rpx"; 5004 } 5005 5006 string run_args = (!string.IsNullOrEmpty(CAFE_RUN_DEBUG.value) ? CAFE_RUN_DEBUG.value.Replace(' ', DEFAULT_DELIMITER) : string.Empty) + 5007 DEFAULT_DELIMITER + (!string.IsNullOrEmpty(BRIDGE_PARAMETERS_WITH_E.value) ? BRIDGE_PARAMETERS_WITH_E.value.Replace(' ', DEFAULT_DELIMITER) : string.Empty) + 5008 DEFAULT_DELIMITER + "-e" + DEFAULT_DELIMITER + "mcp:launch_hint:hfiomlc" + DEFAULT_DELIMITER + "-z" + DEFAULT_DELIMITER + 5009 "-t" + DEFAULT_DELIMITER + "0x" + SYSCONFIGTOOL_TITLE_ID + DEFAULT_DELIMITER + OS_string; 5010 5011 if (argList != null) 5012 { 5013 run_args += DEFAULT_DELIMITER + StringCombiner.MakeDelimitedString(argList.ToArray(), DEFAULT_DELIMITER); 5014 } 5015 5016 if (fAppTypeDefined) 5017 { 5018 fAppTypeDefined = false; 5019 ret = run(run_args.Split(new char[] { DEFAULT_DELIMITER }, StringSplitOptions.RemoveEmptyEntries), runSetup, launch); 5020 fAppTypeDefined = true; 5021 } 5022 else 5023 { 5024 ret = run(run_args.Split(new char[] { DEFAULT_DELIMITER }, StringSplitOptions.RemoveEmptyEntries), runSetup, launch); 5025 } 5026 5027 // Return the current command 5028 command = currentCommand; 5029 XmlHandler.UpdateNodeValue(CAFE_DATA_DIR.value + "\\mlc\\sys\\title\\00050010\\1f700500\\code\\cos.xml", "argstr", "system_config_tool.rpx"); 5030 } 5031 5032 return ret; 5033 } 5034 5035 5036 // Helper function: DUAL bootloader availibility and requirement by SDK is_DUAL_bootloader_available()5037 static private bool is_DUAL_bootloader_available() 5038 { 5039 int flat_sdk_ver = compute_flat_version(SDK_VER.value); 5040 5041 if (flat_sdk_ver >= compute_flat_version("2.10.01")) 5042 { 5043 // DUAL bootloader is available starting in SDK 2.10.01 5044 if (Directory.Exists (Path.Combine(CAFE_MLC_DIR.value, "sys\\update\\mixed"))) 5045 { 5046 // Found the mixed content folder in the MLC 5047 return true; 5048 } 5049 } 5050 5051 return false; 5052 } 5053 is_DUAL_bootloader_required()5054 static private bool is_DUAL_bootloader_required() 5055 { 5056 int flat_sdk_ver = compute_flat_version(SDK_VER.value); 5057 5058 if (flat_sdk_ver >= compute_flat_version("2.10.11")) 5059 { 5060 // DUAL bootloader is required starting in SDK 2.10.11 5061 return true; 5062 } 5063 5064 return false; 5065 } 5066 5067 5068 // Helper function: Prepares the mixed content folder in the current SDK prepare_mlc_recover_content()5069 static private void prepare_mlc_recover_content () 5070 { 5071 const string sdio_boot1_folder = "zzz-boot1-sdio"; 5072 const string dual_boot1_folder = "aaa-boot1-dual"; 5073 string MIXED_DIR = Path.Combine(Program.CAFE_MLC_DIR.value, "sys\\update\\mixed"); 5074 string PCFS_DIR = Path.Combine(Program.CAFE_MLC_DIR.value, "sys\\update\\pcfs"); 5075 string NAND_DIR = Path.Combine(Program.CAFE_MLC_DIR.value, "sys\\update\\nand"); 5076 string BL_DIR = Path.Combine(Program.CAFE_MLC_DIR.value, "sys\\update\\bootloader"); 5077 5078 // Delete the standalone copy of the dual bootloader 5079 if (Directory.Exists(BL_DIR)) 5080 { 5081 FileUtil.DirectoryDelete(BL_DIR, true); 5082 } 5083 5084 if (!Directory.Exists(MIXED_DIR)) 5085 { 5086 // Make a standalone copy of the SDIO bootloader since DUAL does not exist 5087 FileUtil.DirectoryCopy(Path.Combine(PCFS_DIR, sdio_boot1_folder), Path.Combine(BL_DIR, sdio_boot1_folder), false); 5088 } 5089 else 5090 { 5091 // Make a standalone copy of the DUAL bootloader 5092 FileUtil.DirectoryCopy(Path.Combine(MIXED_DIR, dual_boot1_folder), Path.Combine(BL_DIR, dual_boot1_folder), false); 5093 5094 // Delete all of the folders except the bootloader in the MLC mixed folder 5095 Console.WriteLine("cafex: Cleaning content in '{0}'", MIXED_DIR); 5096 foreach (string srcEntry in Directory.GetDirectories(MIXED_DIR)) 5097 { 5098 string srcName = Path.GetFileName(srcEntry); 5099 if (!srcName.Equals(dual_boot1_folder, StringComparison.CurrentCultureIgnoreCase)) 5100 { 5101 string destEntry = Path.Combine(MIXED_DIR, srcName); 5102 FileUtil.DirectoryDelete(srcEntry, true); 5103 } 5104 } 5105 5106 // Delete all of the files in the MLC mixed folder 5107 foreach (string srcEntry in Directory.GetFiles(MIXED_DIR)) 5108 { 5109 #if DEBUG 5110 Console.WriteLine("Deleting file '{0}'", srcEntry); 5111 #endif 5112 File.Delete(srcEntry); 5113 } 5114 5115 // 5116 // Start building the mixed content in dest_dir 5117 // 5118 Console.WriteLine("cafex: Preparing content in '{0}'", MIXED_DIR); 5119 5120 // Copy all of the folders except the bootloader from the src to the dest 5121 foreach (string srcEntry in Directory.GetDirectories(NAND_DIR)) 5122 { 5123 string srcName = Path.GetFileName(srcEntry); 5124 if (!srcName.StartsWith("zzz-boot1-")) 5125 { 5126 string destEntry = Path.Combine(MIXED_DIR, srcName); 5127 FileUtil.DirectoryCopy(srcEntry, destEntry, true); 5128 } 5129 } 5130 5131 // Copy the files from NAND content in the mixed dir 5132 foreach (string srcEntry in Directory.GetFiles(NAND_DIR)) 5133 { 5134 string srcName = Path.GetFileName(srcEntry); 5135 string destEntry = Path.Combine(MIXED_DIR, srcName); 5136 5137 #if DEBUG 5138 Console.WriteLine("Copying file '{0}' => '{1}'", srcEntry, destEntry); 5139 #endif 5140 File.Copy(srcEntry, destEntry); 5141 } 5142 } 5143 } 5144 5145 // Helper function: Prepares a revert content folder in the current SDK from the reversion SDK. prepare_mlc_revert_content(string REVERT_DIR, string revert_cafe_root, bool use_mixed)5146 static private void prepare_mlc_revert_content(string REVERT_DIR, string revert_cafe_root, bool use_mixed) 5147 { 5148 const string sdio_boot1_folder = "zzz-boot1-sdio"; 5149 const string dual_boot1_folder = "aaa-boot1-dual"; 5150 string PCFS_DIR = Path.Combine(revert_cafe_root, "data\\mlc\\sys\\update\\pcfs"); 5151 string NAND_DIR = Path.Combine(revert_cafe_root, "data\\mlc\\sys\\update\\nand"); 5152 string MIXED_DIR = Path.Combine(revert_cafe_root, "data\\mlc\\sys\\update\\mixed"); 5153 5154 // Delete the standalone copy of the SDIO bootloader 5155 if (Directory.Exists(REVERT_DIR)) 5156 { 5157 FileUtil.DirectoryDelete(REVERT_DIR, true); 5158 } 5159 5160 if (is_DUAL_bootloader_required()) 5161 { 5162 use_mixed = true; 5163 } 5164 5165 Console.WriteLine("cafex: Preparing content in '{0}'", REVERT_DIR); 5166 5167 // Copy directories from the NAND content folder (except the bootloader) 5168 foreach (string srcEntry in Directory.GetDirectories(NAND_DIR)) 5169 { 5170 string srcName = Path.GetFileName(srcEntry); 5171 if (!srcName.StartsWith("zzz-boot1-")) 5172 { 5173 string destEntry = Path.Combine(REVERT_DIR, srcName); 5174 FileUtil.DirectoryCopy(srcEntry, destEntry, true); 5175 } 5176 } 5177 5178 // Copy files from the NAND content folder 5179 foreach (string srcEntry in Directory.GetFiles(NAND_DIR)) 5180 { 5181 string srcName = Path.GetFileName(srcEntry); 5182 string destEntry = Path.Combine(REVERT_DIR, srcName); 5183 File.Copy(srcEntry, destEntry); 5184 } 5185 5186 // Copy the bootloader depending of if we using the DUAL bootloader 5187 if (!is_DUAL_bootloader_available() || !use_mixed) 5188 { 5189 // This is reverting to an SDK that doesn't have the DUAL bootloader or 5190 // an optional one where we don't want to use it. 5191 FileUtil.DirectoryCopy(Path.Combine(PCFS_DIR, sdio_boot1_folder), Path.Combine(REVERT_DIR, sdio_boot1_folder), false); 5192 } 5193 else 5194 { 5195 // This is reverting to an SDK that requires the DUAL booloader or 5196 // an optional one where we do want to use it. 5197 FileUtil.DirectoryCopy(Path.Combine(MIXED_DIR, dual_boot1_folder), Path.Combine(REVERT_DIR, dual_boot1_folder), false); 5198 } 5199 } 5200 5201 //Script function: cafeupdate update(string[] args)5202 static CAFEX_ERROR update(string[] args) 5203 { 5204 #if DEBUG 5205 Log.WriteLine("update started."); 5206 string argString = null; 5207 if (args != null) 5208 { 5209 foreach (string arg in args) 5210 { 5211 argString += arg + " "; 5212 } 5213 } 5214 Log.WriteLine("Arguments=" + argString); 5215 5216 #endif 5217 5218 CAFEUPDATE_USE_SYSTEM_UPDATER.value = "0"; 5219 CAFEUPDATE_TITLE.value = ""; 5220 CAFEUPDATE_PACKAGE_DEFAULT.value = "/vol/storage_hfiomlc01/sys/update/pcfs"; 5221 CAFEUPDATE_PACKAGE.value = CAFEUPDATE_PACKAGE_DEFAULT.value; 5222 bool USE_MIXED_BOOTLOADER = false; 5223 bool prod = true; 5224 bool reflash = false; 5225 bool noreflash = false; 5226 bool updateDRC = true; 5227 CAFEX_ERROR ret = CAFEX_ERROR.UPDATE_FAILED; 5228 5229 if ((recover_flags & RECOVER_COMMAND_MASK) == RECOVER_COMMAND_INIT) 5230 { 5231 recover_flags = (recover_flags & ~RECOVER_COMMAND_MASK) | RECOVER_COMMAND_UPDATE; 5232 } 5233 5234 if (is_DUAL_bootloader_required()) 5235 { 5236 USE_MIXED_BOOTLOADER = true; 5237 prod = false; 5238 } 5239 else //the bootloader isn't available or not required 5240 { 5241 USE_MIXED_BOOTLOADER = false; 5242 prod = true; 5243 } 5244 5245 for (int i = 0; i < args.Length; ++i) 5246 { 5247 switch (args[i].ToLowerInvariant()) 5248 { 5249 case "-u": 5250 { 5251 if (!ArgumentChecks.IsArgumentValidSetting(args, i + 1)) 5252 { 5253 run_usage(); 5254 return CAFEX_ERROR.BAD_ARGUMENT; 5255 } 5256 5257 CAFEUPDATE_PACKAGE.value = args[i + 1]; 5258 ++i; 5259 break; 5260 } 5261 5262 case "-s": 5263 { 5264 CAFEUPDATE_USE_SYSTEM_UPDATER.value = "1"; 5265 break; 5266 } 5267 5268 case "-t": 5269 { 5270 if (!ArgumentChecks.IsArgumentValidSetting(args, i + 1)) 5271 { 5272 run_usage(); 5273 return CAFEX_ERROR.BAD_ARGUMENT; 5274 } 5275 5276 CAFEUPDATE_TITLE.value = args[i + 1]; 5277 ++i; 5278 break; 5279 } 5280 5281 case "-p": 5282 { 5283 recover_flags = (recover_flags & ~RECOPT_PROD_MASK) | RECOPT_PRODUCTION_DEF; 5284 if (!is_DUAL_bootloader_required()) 5285 { 5286 Console.WriteLine("-p argument not supported on this SDK."); 5287 return CAFEX_ERROR.UPDATE_INVALID_OPTION; 5288 } 5289 if (CAFE_BOOT_MODE.value != "NAND") 5290 { 5291 Console.WriteLine("Warning: Ignoring '{0}' switch because it is only valid in NAND mode.", args[i]); 5292 recover_flags = (recover_flags & ~RECOVER_ENV_BOOT_MASK) | RECOVER_ENV_BOOT_NAND; 5293 } 5294 else 5295 { 5296 USE_MIXED_BOOTLOADER = false; 5297 prod = true; 5298 recover_flags = (recover_flags & ~RECOVER_ENV_BOOT_MASK) | RECOVER_ENV_BOOT_PCFS; 5299 //if (!noreflash) 5300 //{ 5301 // // the -noreflash option was found before the -P 5302 // reflash = true; 5303 //} 5304 } 5305 break; 5306 } 5307 case "-noreflash": 5308 { 5309 reflash = false; 5310 noreflash = true; 5311 recover_flags = (recover_flags & ~RECOPT_NOREFLASH_MASK) | RECOPT_NOREFLASH_DEF; 5312 break; 5313 } 5314 5315 case "-reflash": 5316 { 5317 reflash = true; 5318 recover_flags = (recover_flags & ~RECOPT_REFLASH_MASK) | RECOPT_REFLASH_DEF; 5319 break; 5320 } 5321 5322 case "-m": 5323 { 5324 recover_flags = (recover_flags & ~RECOPT_MIXED_MASK) | RECOPT_MIXED_DEF; 5325 //This option was only valid on SDKs 2.10.01-2.10.09 5326 if (is_DUAL_bootloader_available() && !is_DUAL_bootloader_required()) 5327 { 5328 USE_MIXED_BOOTLOADER = true; 5329 prod = false; 5330 } 5331 else 5332 { 5333 Console.WriteLine("-M is not supported in this SDK."); 5334 return CAFEX_ERROR.UPDATE_INVALID_OPTION; 5335 } 5336 break; 5337 } 5338 5339 case "-l": 5340 { 5341 recover_flags = (recover_flags & ~RECOPT_LEGACY_MASK) | RECOPT_LEGACY_DEF; 5342 5343 //This option was only valid on SDKs 2.10.10 and above 5344 if (is_DUAL_bootloader_required()) 5345 { 5346 USE_MIXED_BOOTLOADER = false; 5347 prod = true; 5348 } 5349 else 5350 { 5351 Console.WriteLine("-L is not supported in this SDK."); 5352 return CAFEX_ERROR.UPDATE_INVALID_OPTION; 5353 } 5354 break; 5355 } 5356 case "-nodrc": 5357 { 5358 //don't update the DRC firmware 5359 updateDRC = false; 5360 break; 5361 } 5362 5363 case "-h": 5364 { 5365 update_usage(); 5366 return CAFEX_ERROR.OK; 5367 } 5368 5369 default: 5370 { 5371 Console.WriteLine("cafex update failed: Invalid argument"); 5372 return CAFEX_ERROR.UPDATE_INVALID_OPTION; 5373 } 5374 } 5375 } 5376 5377 //I'd really like to check for -M and -L at the same time here, but the old code didn't check that. 5378 //So to maintain backcompat, whatever is specified last between -M and -L is what gets used. 5379 if (CAFE_BOOT_MODE.value == "NAND") 5380 { 5381 recover_flags = (recover_flags & ~RECOVER_ENV_BOOT_MASK) | RECOVER_ENV_BOOT_NAND; 5382 5383 List<string> recover_args = new List<string>(); 5384 if (prod) 5385 { 5386 recover_args.Add("-production"); 5387 } 5388 else if (USE_MIXED_BOOTLOADER && !is_DUAL_bootloader_required()) 5389 { 5390 recover_args.Add("-mixed"); 5391 } 5392 5393 if (noreflash) 5394 { 5395 recover_args.Add("-noreflash"); 5396 } 5397 else if (reflash) 5398 { 5399 recover_args.Add("-reflash"); 5400 } 5401 5402 ret = recover(recover_args.ToArray()); 5403 } 5404 else 5405 { 5406 recover_flags = (recover_flags & ~RECOVER_ENV_BOOT_MASK) | RECOVER_ENV_BOOT_PCFS; 5407 if (CAFE_SECURITY.value == "off") 5408 { 5409 Console.WriteLine("Sorry, bringup boot1 update not supported yet"); 5410 return CAFEX_ERROR.UPDATE_BRINGUP_BOOT1_UPDATE; 5411 } 5412 5413 5414 if (CAFEUPDATE_TITLE.value != null) 5415 { 5416 Console.WriteLine("Installing title " + CAFEUPDATE_TITLE.value + " using System Config Tool..."); 5417 CAFEX_ERROR on_ret = on(new string[] { "-c", "install " + CAFEUPDATE_TITLE.value, "-c", "exit" }, true, true).error; 5418 if (on_ret != CAFEX_ERROR.OK) 5419 { 5420 return on_ret; 5421 } 5422 else 5423 { 5424 readSDKFromMion(); 5425 setMionSDKVersion(); 5426 } 5427 } 5428 else 5429 { 5430 if (CAFEUPDATE_PACKAGE.value == CAFEUPDATE_PACKAGE_DEFAULT.value) 5431 { 5432 Console.WriteLine("Performing system update using System Config Tool..."); 5433 } 5434 else 5435 { 5436 Console.WriteLine("Performing system update using System Config Tool from " + CAFEUPDATE_PACKAGE.value + "..."); 5437 } 5438 5439 if (CAFEUPDATE_USE_SYSTEM_UPDATER.value == "1") 5440 { 5441 Console.WriteLine("Using system updater..."); 5442 CAFEX_ERROR on_ret = on(new string[] { "-c", "update_launch " + CAFEUPDATE_PACKAGE.value }, true, true).error; 5443 if (on_ret != CAFEX_ERROR.OK) 5444 { 5445 return on_ret; 5446 } 5447 else 5448 { 5449 readSDKFromMion(); 5450 setMionSDKVersion(); 5451 } 5452 } 5453 else 5454 { 5455 List<string> setbootmode_args = new List<string>(); 5456 if (USE_MIXED_BOOTLOADER && !is_DUAL_bootloader_required()) 5457 { 5458 setbootmode_args.Add("-mixed"); 5459 } 5460 setbootmode_args.Add("PCFS"); 5461 if (noreflash) 5462 { 5463 setbootmode_args.Add("-noreflash"); 5464 } 5465 else if (reflash) 5466 { 5467 setbootmode_args.Add("-reflash"); 5468 } 5469 5470 ret = setbootmode(setbootmode_args.ToArray()); 5471 } 5472 } 5473 } 5474 5475 if (updateDRC && ret == CAFEX_ERROR.OK) 5476 { 5477 Console.WriteLine("Attempting to update DRC"); 5478 //reset some values that on -recover set 5479 CAFE_CONSOLE.value = "cattoucan"; 5480 CAFE_RUN_RUNNING.value = "0"; 5481 _CCRSYSCFG1.value = ""; 5482 BOOTRUN_USE_RECOVERY_IMAGE.value = ""; 5483 CATTOUCAN_TERM.value = "drc_update end"; 5484 ret = on(new string[] {"-c drc_update 1"}, true, true).error; 5485 stop(null, true); 5486 } 5487 5488 return ret; 5489 } 5490 revert(string[] args)5491 static CAFEX_ERROR revert(string[] args) 5492 { 5493 #if DEBUG 5494 Log.WriteLine("revert started."); 5495 string argString = null; 5496 if (args != null) 5497 { 5498 foreach (string arg in args) 5499 { 5500 argString += arg + " "; 5501 } 5502 } 5503 Log.WriteLine("Arguments=" + argString); 5504 #endif 5505 bool reflash = false; 5506 bool noreflash = false; 5507 string revert_cafe_root = string.Empty; 5508 bool use_mixed = false; 5509 CAFEX_ERROR ret = CAFEX_ERROR.OK; 5510 5511 for (int i = 0; i < args.Length; ++i) 5512 { 5513 switch (args[i].ToLowerInvariant()) 5514 { 5515 case "-noreflash": 5516 if (reflash) 5517 { 5518 Console.WriteLine("cafex revert: '-reflash' and '-noreflash' can't be used together!"); 5519 return CAFEX_ERROR.UPDATE_INVALID_OPTION; 5520 } 5521 noreflash = true; 5522 break; 5523 5524 case "-reflash": 5525 if (noreflash) 5526 { 5527 Console.WriteLine("cafex revert: '-reflash' and '-noreflash' can't be used together!"); 5528 return CAFEX_ERROR.UPDATE_INVALID_OPTION; 5529 } 5530 reflash = true; 5531 break; 5532 5533 case "-mixed": 5534 use_mixed = true; 5535 break; 5536 5537 case "-h": 5538 revert_usage(); 5539 return CAFEX_ERROR.OK; 5540 5541 default: 5542 if (args[i].StartsWith("-") || !string.IsNullOrEmpty(revert_cafe_root)) 5543 { 5544 Console.WriteLine("cafex revert failed: Invalid argument: '{0}'", args[i]); 5545 return CAFEX_ERROR.UPDATE_INVALID_OPTION; 5546 } 5547 5548 revert_cafe_root = PathConverter.Windowsify(args[i]); 5549 break; 5550 } 5551 } 5552 5553 if (string.IsNullOrEmpty(revert_cafe_root)) 5554 { 5555 Console.WriteLine("cafex revert failed: Missing SDK root to revert to on command line!"); 5556 return CAFEX_ERROR.UPDATE_INVALID_OPTION; 5557 } 5558 5559 if (!Directory.Exists(revert_cafe_root)) 5560 { 5561 Console.WriteLine("cafex revert failed: Target SDK root folder '{0}' does not exist!", revert_cafe_root); 5562 return CAFEX_ERROR.UPDATE_INVALID_OPTION; 5563 } 5564 5565 // Backup these as we and readSDKFromCafeRoot will modify them 5566 string OLD_SDK_VER = SDK_VER.value; 5567 5568 // Update the SDK version for teh reversion to that of the target SDK 5569 if (CAFEX_ERROR.OK != readSDKFromCafeRoot(revert_cafe_root)) 5570 { 5571 Console.WriteLine("cafex revert failed: Unable to get SDK version from folder '{0}'!", revert_cafe_root); 5572 return CAFEX_ERROR.UPDATE_FAILED; 5573 } 5574 5575 if (compute_flat_version(SDK_VER.value) >= compute_flat_version(OLD_SDK_VER)) 5576 { 5577 Console.WriteLine("cafex revert failed: Can't revert to an earlier SDK. Please update using the newer SDK."); 5578 return CAFEX_ERROR.UPDATE_FAILED; 5579 } 5580 5581 if (use_mixed && (is_DUAL_bootloader_required() || !is_DUAL_bootloader_available())) 5582 { 5583 Console.WriteLine("cafex recover failed: -mixed argument not supported by this version of the SDK."); 5584 return CAFEX_ERROR.UPDATE_INVALID_OPTION; 5585 } 5586 5587 if (SESSION_MANAGER.value == "1") 5588 { 5589 if (string.IsNullOrEmpty(CAFERUN_OPTION_NO_DATA_SYNC.value) || CAFERUN_OPTION_NO_DATA_SYNC.value == "0") 5590 { 5591 ret = syncsession(null); 5592 if (CAFEX_ERROR.OK != ret) 5593 { 5594 return ret; 5595 } 5596 CAFERUN_OPTION_NO_DATA_SYNC.value = "1"; 5597 } 5598 } 5599 5600 string REVERT_DIR = Path.Combine(Program.CAFE_MLC_DIR.value, "revert"); 5601 prepare_mlc_revert_content(REVERT_DIR, revert_cafe_root, use_mixed); 5602 5603 List<string> recover_opts = new List<string>(); 5604 if (reflash) 5605 { 5606 recover_opts.Add("-reflash"); 5607 } 5608 else if (noreflash) 5609 { 5610 recover_opts.Add("-noreflash"); 5611 } 5612 5613 recover_opts.Add("-source"); 5614 recover_opts.Add("/vol/storage_hfiomlc01/revert"); 5615 5616 ret = recover(recover_opts.ToArray()); 5617 if (ret == 0) 5618 { 5619 Console.WriteLine("cafex: DEVKIT reverted to SDK {0}", SDK_VER.value); 5620 } 5621 5622 // Restore the SDK version in case we are called internally 5623 SDK_VER.value = OLD_SDK_VER; 5624 5625 return ret; 5626 } 5627 5628 // remove a directory for clean-up, avoiding any errors from removal ForceRemoveDirectory(string dirName)5629 static void ForceRemoveDirectory(string dirName) 5630 { 5631 for (int retry = 0; retry < 3; ++retry) 5632 { 5633 if (retry > 0) 5634 { 5635 Thread.Sleep(1000); 5636 } 5637 try 5638 { 5639 Directory.Delete(dirName, true); 5640 break; // stop retrying 5641 } 5642 catch (Exception e) 5643 { 5644 Console.WriteLine("ForceRemoveDirecory: Warning: tried to remove [{0}], got exception [{1}], retry={2}", 5645 dirName, e.Message, retry); 5646 } 5647 } 5648 } 5649 5650 5651 //Script function: caferecover 5652 // 5653 //Recover_test number decomposition 5654 // Digit order: 0xBA9876543210 5655 // Digit 0: 5656 // Digit 1: 5657 // Digit 2: 5658 // Digit 3: 5659 // Digit 4: 5660 // Digit 5: 5661 // Digit 6: 5662 // 5663 // Default = 0x02223225 5664 internal static UInt64 RECOVER_SDK_MASK = 0x000000000000000F; 5665 internal static UInt64 RECOVER_COMMAND_MASK = 0x00000000000000F0; 5666 internal static UInt64 RECOVER_ENV_BOOT_MASK = 0x0000000000000F00; 5667 internal static UInt64 RECOPT_REFLASH_MASK = 0x000000000000F000; 5668 internal static UInt64 RECOPT_NOREFLASH_MASK = 0x00000000000F0000; 5669 internal static UInt64 RECOPT_PROD_MASK = 0x0000000000F00000; 5670 internal static UInt64 RECOPT_MIXED_MASK = 0x000000000F000000; 5671 internal static UInt64 RECOVER_DETECTED_BOOT_MASK = 0x00000000F0000000; 5672 internal static UInt64 RECOPT_QUICK_MASK = 0x0000000F00000000; 5673 internal static UInt64 RECOPT_DESIRED_BOOT_MASK = 0x000000F000000000; 5674 internal static UInt64 RECOPT_LEGACY_MASK = 0x00000F0000000000; 5675 internal static UInt64 RECOPT_BOOTLOADER_MASK = 0x0000F00000000000; 5676 5677 internal static uint RECOPT_SDK_NOMIXED = 0x00000000; 5678 internal static uint RECOPT_SDK_MIXEDNOTREQ = 0x00000001; 5679 internal static uint RECOPT_SDK_MIXEDREQ = 0x00000002; 5680 5681 internal static uint RECOVER_COMMAND_RECOVER = 0x00000000; 5682 internal static uint RECOVER_COMMAND_SBM = 0x00000010; 5683 internal static uint RECOVER_COMMAND_UPDATE = 0x00000020; 5684 internal static uint RECOVER_COMMAND_INIT = 0x000000030; 5685 5686 internal static uint RECOVER_ENV_BOOT_NAND = 0x00000000; 5687 internal static uint RECOVER_ENV_BOOT_PCFS = 0x00000100; 5688 internal static uint RECOVER_ENV_BOOT_UNKNOWN = 0x00000200; 5689 5690 internal static uint RECOPT_REFLASH_UNDEF = 0x00000000; 5691 internal static uint RECOPT_REFLASH_DEF = 0x00001000; 5692 5693 internal static uint RECOPT_NOREFLASH_UNDEF = 0x00000000; 5694 internal static uint RECOPT_NOREFLASH_DEF = 0x00010000; 5695 5696 internal static uint RECOPT_PRODUCTION_UNDEF = 0x00000000; 5697 internal static uint RECOPT_PRODUCTION_DEF = 0x00100000; 5698 5699 internal static uint RECOPT_MIXED_UNDEF = 0x00000000; 5700 internal static uint RECOPT_MIXED_DEF = 0x010000000; 5701 5702 internal static uint RECOVER_DETECT_BOOT_NAND = 0x00000000; 5703 internal static uint RECOVER_DETECT_BOOT_PCFS = 0x10000000; 5704 internal static uint RECOVER_DETECT_BOOT_DUAL = 0x20000000; 5705 internal static uint RECOVER_DETECT_BOOT_UNKNOWN = 0x30000000; 5706 5707 internal static uint RECOPT_QUICK_UNDEF = 0x00000000; 5708 internal static UInt64 RECOPT_QUICK_DEF = 0x0000000100000000; 5709 5710 internal static uint RECOPT_DESIRED_BOOT_UNDEF = 0x00000000; 5711 internal static UInt64 RECOPT_DESIRED_BOOT_PCFS = 0x0000001000000000; 5712 internal static UInt64 RECOPT_DESIRED_BOOT_NAND = 0x0000002000000000; 5713 5714 internal static uint RECOPT_LEGACY_UNDEF = 0x00000000; 5715 internal static UInt64 RECOPT_LEGACY_DEF = 0x0000010000000000; 5716 5717 internal static uint RECOPT_BOOTLOADER_UNDEF = 0x00000000; 5718 internal static UInt64 RECOPT_BOOTLOADER_DEF = 0x0000100000000000; 5719 recover(string[] args)5720 static CAFEX_ERROR recover(string[] args) 5721 { 5722 #if DEBUG 5723 Log.WriteLine("recover started."); 5724 string argString = null; 5725 if (args != null) 5726 { 5727 foreach (string arg in args) 5728 { 5729 argString += arg + " "; 5730 } 5731 } 5732 Log.WriteLine("Arguments=" + argString); 5733 Log.WriteLine(String.Format("Recover_flags={0:X12}",recover_flags)); 5734 #endif 5735 // 5736 // Command line processing 5737 // 5738 5739 bool production_bootloader = false; 5740 bool bootloader_only = false; 5741 bool mixed_arg = false; 5742 bool reflash_arg = false; 5743 bool noreflash_arg = false; 5744 bool reflash = false; // This sets the default behavior for the recover operation 5745 bool noreflash = false; 5746 string recover_source = "/vol/storage_hfiomlc01/sys/update/pcfs"; 5747 5748 if ((recover_flags & RECOVER_COMMAND_MASK) == RECOVER_COMMAND_INIT) 5749 { 5750 recover_flags = (recover_flags & ~RECOVER_COMMAND_MASK) | RECOVER_COMMAND_RECOVER; 5751 } 5752 5753 if (is_DUAL_bootloader_available()) 5754 { 5755 if (is_DUAL_bootloader_required()) 5756 recover_flags = (recover_flags & ~RECOVER_SDK_MASK) | RECOPT_SDK_MIXEDREQ; 5757 else 5758 recover_flags = (recover_flags & ~RECOVER_SDK_MASK) | RECOPT_SDK_MIXEDNOTREQ; 5759 } 5760 else 5761 recover_flags = (recover_flags & ~RECOVER_SDK_MASK) | RECOPT_SDK_NOMIXED; 5762 5763 if (is_DUAL_bootloader_required()) 5764 { 5765 if (!Directory.Exists(Path.Combine(CAFE_MLC_DIR.value, "sys\\update\\mixed"))) 5766 { 5767 Console.WriteLine("cafex recover failed: Required mixed content folder '{0}' is missing!"); 5768 return CAFEX_ERROR.UPDATE_FAILED; 5769 } 5770 recover_source = "/vol/storage_hfiomlc01/sys/update/mixed"; 5771 } 5772 5773 if (args != null) 5774 { 5775 for (int i = 0; i < args.Length; ++i) 5776 { 5777 switch (args[i].ToLowerInvariant()) 5778 { 5779 case "-production": 5780 recover_source = "/vol/storage_hfiomlc01/sys/update/nand"; 5781 production_bootloader = true; 5782 recover_flags = recover_flags & (~RECOPT_PROD_MASK) | RECOPT_PRODUCTION_DEF; 5783 //{ 5784 // // the -noreflash option was found before the -production 5785 // reflash = true; 5786 //} 5787 break; 5788 5789 case "-bootloader": 5790 recover_source = "/vol/storage_hfiomlc01/sys/update/bootloader"; 5791 bootloader_only = true; 5792 recover_flags = (recover_flags & ~RECOPT_BOOTLOADER_MASK) | RECOPT_BOOTLOADER_DEF; 5793 break; 5794 5795 case "-source": 5796 recover_source = args[++i]; 5797 break; 5798 5799 case "-noreflash": 5800 noreflash_arg = true; 5801 reflash = false; 5802 noreflash = true; 5803 recover_flags = (recover_flags & ~RECOPT_NOREFLASH_MASK) | RECOPT_NOREFLASH_DEF; 5804 break; 5805 5806 case "-reflash": 5807 reflash_arg = true; 5808 reflash = true; 5809 recover_flags = (recover_flags & ~RECOPT_REFLASH_MASK) | RECOPT_REFLASH_DEF; 5810 break; 5811 5812 case "-mixed": 5813 if (is_DUAL_bootloader_required() || !is_DUAL_bootloader_available()) 5814 { 5815 Console.WriteLine("cafex recover failed: -mixed argument not supported by this version of the SDK."); 5816 return CAFEX_ERROR.UPDATE_INVALID_OPTION; 5817 } 5818 mixed_arg = true; 5819 recover_source = "/vol/storage_hfiomlc01/sys/update/mixed"; 5820 recover_flags = recover_flags & ~(RECOPT_MIXED_MASK) | RECOPT_MIXED_DEF; 5821 break; 5822 5823 case "-h": 5824 recover_usage(); 5825 return CAFEX_ERROR.OK; 5826 5827 default: 5828 Console.WriteLine("cafex recover failed: Invalid argument"); 5829 return CAFEX_ERROR.UPDATE_INVALID_OPTION; 5830 } 5831 } 5832 } 5833 5834 if (production_bootloader && bootloader_only) 5835 { 5836 Console.WriteLine("cafex recover failed: Invalid arguments: Can't specify both -production and -bootloader options!"); 5837 return CAFEX_ERROR.UPDATE_INVALID_OPTION; 5838 } 5839 5840 if (production_bootloader && mixed_arg) 5841 { 5842 Console.WriteLine("cafex recover failed: Invalid arguments: Can't specify both -production and -mixed options!"); 5843 return CAFEX_ERROR.UPDATE_INVALID_OPTION; 5844 } 5845 5846 if (mixed_arg && bootloader_only) 5847 { 5848 Console.WriteLine("WARNING: Ignoring -bootloader option since -mixed was specified"); 5849 recover_source = "/vol/storage_hfiomlc01/sys/update/mixed"; 5850 } 5851 5852 if (reflash_arg && noreflash_arg) 5853 { 5854 Console.WriteLine("cafex recover failed: Can't specify both -reflash and -noreflash! Please remove one or the other."); 5855 return CAFEX_ERROR.UPDATE_INVALID_OPTION; 5856 } 5857 5858 // can't do -reflash -bootloader, but it seems like the intent is to update the bootloader. 5859 // Also, only do this if -mixed isn't specified, since -mixed implies -bootloader, and we could be coming 5860 // from production NAND, which would require a reflash. 5861 if (bootloader_only && reflash_arg && !mixed_arg) 5862 { 5863 Console.WriteLine("WARNING: Ignoring reflash/noreflash argument since only bootloader is being updated"); 5864 reflash = false; 5865 noreflash = true; 5866 } 5867 5868 // Covers the case where we try to specify reflash when targeting legacy PCFS mode 5869 // without breaking setbootmode 5870 if (recover_source.EndsWith("pcfs") && reflash_arg) 5871 { 5872 Console.WriteLine("cafex recover failed: Cannot specify -reflash option with legacy PCFS as target package!"); 5873 Console.WriteLine("This is the default package for SDKs 2.10.03 and 2.10.04. Please do not specify -reflash without specifying -mixed or -production"); 5874 return CAFEX_ERROR.UPDATE_INVALID_OPTION; 5875 } 5876 5877 // Production bootloader must always reflash unless specified 5878 if (production_bootloader && !noreflash_arg) 5879 { 5880 noreflash = false; 5881 reflash = true; 5882 } 5883 5884 if (production_bootloader && mixed_arg) 5885 { 5886 Console.WriteLine("cafex recover failed: Invalid arguments: Can't specify both -production and -mixed options!"); 5887 return CAFEX_ERROR.UPDATE_INVALID_OPTION; 5888 } 5889 5890 if (mixed_arg && bootloader_only) 5891 { 5892 Console.WriteLine("WARNING: Ignoring -bootloader option since -mixed was specified"); 5893 recover_source = "/vol/storage_hfiomlc01/sys/update/mixed"; 5894 } 5895 5896 if (reflash_arg && noreflash_arg) 5897 { 5898 Console.WriteLine("cafex recover failed: Can't specify both -reflash and -noreflash! Please remove one or the other."); 5899 return CAFEX_ERROR.UPDATE_INVALID_OPTION; 5900 } 5901 5902 // can't do -reflash -bootloader, but it seems like the intent is to update the bootloader. 5903 // Also, only do this if -mixed isn't specified, since -mixed implies -bootloader, and we could be coming 5904 // from production NAND, which would require a reflash. 5905 if (bootloader_only && reflash_arg && !mixed_arg) 5906 { 5907 Console.WriteLine("WARNING: Ignoring reflash/noreflash argument since only bootloader is being updated"); 5908 reflash = false; 5909 noreflash = true; 5910 } 5911 5912 // Covers the case where we try to specify reflash when targeting legacy PCFS mode 5913 // without breaking setbootmode 5914 if (recover_source.EndsWith("pcfs") && reflash_arg) 5915 { 5916 Console.WriteLine("cafex recover failed: Cannot specify -reflash option with legacy PCFS as target package!"); 5917 Console.WriteLine("This is the default package for SDKs 2.10.03 and 2.10.04. Please do not specify -reflash without specifying -mixed or -production"); 5918 return CAFEX_ERROR.UPDATE_INVALID_OPTION; 5919 } 5920 5921 // Production bootloader must always reflash unless specified 5922 if (production_bootloader && !noreflash_arg) 5923 { 5924 noreflash = false; 5925 reflash = true; 5926 } 5927 5928 // 5929 // Initialization 5930 // 5931 SCRIPT_EXE_TIMESTAMP.value = DateTime.Now.ToString("MMMdd_yyyy_HHmmss"); 5932 LOGDIR.value = CAFE_TEMP.value + "\\" + SESSION_PATH_PREFIX.value + "caferecover\\" + SCRIPT_EXE_TIMESTAMP.value; 5933 Console.WriteLine("cafex recover"); 5934 Console.WriteLine("log directory is " + LOGDIR.value); 5935 Console.WriteLine("recover source directory is " + recover_source); 5936 create_directory_if_noexist(LOGDIR.value); 5937 string old_boot_mode = CAFE_BOOT_MODE.value; 5938 bool skip_update = false; 5939 CAFE_CONSOLE.value = "toucan"; 5940 5941 FileStream fs = null; 5942 TextWriter old_out = null; 5943 TextWriter old_err = null; 5944 StreamWriter sw = null; 5945 5946 CAFEX_ERROR hostcheckversion_ret = hostcheckversion(); 5947 if (hostcheckversion_ret != CAFEX_ERROR.OK) 5948 { 5949 return hostcheckversion_ret; 5950 } 5951 5952 // Stop the DEVKIT to release any resources it may have locked 5953 try 5954 { 5955 stop(new string[] { "-hard" }); 5956 } 5957 catch (Exception e) 5958 { 5959 Console.WriteLine("cafex recover[warning]: Failure to hard stop the DEVKIT prior to mode detection, error {0}", e.Message); 5960 } 5961 Thread.Sleep(1000); 5962 5963 if (CAFEX_RECOVER_TEST.value != "1") 5964 { 5965 if (SESSION_MANAGER.value == "1") 5966 { 5967 if (string.IsNullOrEmpty(CAFERUN_OPTION_NO_DATA_SYNC.value) || CAFERUN_OPTION_NO_DATA_SYNC.value == "0") 5968 { 5969 CAFEX_ERROR ret = syncsession(null); 5970 if (CAFEX_ERROR.OK != ret) 5971 { 5972 return ret; 5973 } 5974 CAFERUN_OPTION_NO_DATA_SYNC.value = "1"; 5975 } 5976 } 5977 5978 // Prepare the mixed and bootloader MLC folders 5979 prepare_mlc_recover_content(); 5980 } 5981 // 5982 // Boot mode detection 5983 // 5984 string boot_mode; 5985 int boot_mode_detect = FSEmul.boot_mode_detect(BRIDGE_CURRENT_IP_ADDRESS.value, out boot_mode); 5986 if (boot_mode_detect != 0) 5987 { 5988 Console.WriteLine("Unable to determine boot mode!"); 5989 return CAFEX_ERROR.BOOTMODEDETECT_FSEMUL_FAILED; 5990 } 5991 5992 Console.WriteLine("Detected BOOT mode : {0}", boot_mode); 5993 5994 if( boot_mode.Contains("NAND")) 5995 { 5996 CAFE_BOOT_MODE.value = "NAND"; 5997 recover_flags = (recover_flags & ~RECOVER_DETECTED_BOOT_MASK) | RECOVER_DETECT_BOOT_NAND; 5998 if (!noreflash && (!recover_source.EndsWith("pcfs") || recover_source.EndsWith("nand"))) 5999 { 6000 // Reflash by default unless -noreflash was specified or the recover source 6001 // is the legacy PCFS boot 6002 reflash = true; 6003 } 6004 } 6005 else 6006 { 6007 CAFE_BOOT_MODE.value = "PCFS"; 6008 if (boot_mode.Contains("DUAL")) 6009 { 6010 recover_flags = (recover_flags & ~RECOVER_DETECTED_BOOT_MASK) | RECOVER_DETECT_BOOT_DUAL; 6011 } 6012 else 6013 { 6014 recover_flags = (recover_flags & ~RECOVER_DETECTED_BOOT_MASK) | RECOVER_DETECT_BOOT_PCFS; 6015 } 6016 } 6017 6018 Console.WriteLine("recover_flags={0:X12}", recover_flags); 6019 //if (CAFEX_RECOVER_TEST.value == "1") 6020 //{ 6021 // try 6022 // { 6023 // stop(new string[] { "-hard" }); 6024 // } 6025 // catch (Exception e) 6026 // { 6027 // Console.WriteLine("cafex recover[warning]: Failure to hard stop the DEVKIT prior to mode detection, error {0}", e.Message); 6028 // } 6029 // return CAFEX_ERROR.OK; 6030 //} 6031 6032 // 6033 // cafex on (using the recovery image if booting in PCFS mode) 6034 // 6035 if (CAFE_BOOT_MODE.value == "NAND") 6036 { 6037 Console.WriteLine("Executing cafex on..."); 6038 fs = new FileStream(LOGDIR.value + "\\cafeon.txt", FileMode.Create); 6039 old_out = Console.Out; 6040 old_err = Console.Error; 6041 sw = new StreamWriter(fs); 6042 Console.SetOut(sw); 6043 Console.SetError(sw); 6044 if (CAFEX_RECOVER_TEST.value != "1") 6045 { 6046 on(new string[] { "-e", "nomodecheck" }, true, true); 6047 } 6048 6049 Console.SetOut(old_out); 6050 Console.SetError(old_err); 6051 sw.Flush(); 6052 sw.Close(); 6053 6054 if (File.Exists(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log")) 6055 { 6056 File.Move(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log", LOGDIR.value + "\\cafeon_mion.log"); 6057 } 6058 if (CAFEX_RECOVER_TEST.value != "1") 6059 { 6060 if (monitor_for_output("-k", "source -p -q /vol/content/", MONITOR_DEFAULT_TIMEOUT.value, LOGDIR.value, null, true) != 0) 6061 { 6062 Console.WriteLine("cafex recover: monitor failed waiting for cafeon success message."); 6063 return CAFEX_ERROR.RECOVERY_FAILED; 6064 } 6065 } 6066 6067 Console.WriteLine("Executing devkitmsg recover -v..."); 6068 devkitmsg.recover(); 6069 if (CAFEX_RECOVER_TEST.value != "1") 6070 { 6071 if (monitor_for_output("-K", "WUD_BCMFWCheck", MONITOR_DEFAULT_TIMEOUT.value, LOGDIR.value, null, true) != 0) 6072 { 6073 Console.WriteLine("cafex recover: monitor failed waiting for devkitmsg recover success message."); 6074 return CAFEX_ERROR.RECOVERY_FAILED; 6075 } 6076 } 6077 6078 Console.WriteLine("Executing devkitmsg 'update /vol/storage_hfiomlc01/sys/update/bootloader' -v..."); 6079 devkitmsg.update("/vol/storage_hfiomlc01/sys/update/bootloader"); 6080 6081 if (CAFEX_RECOVER_TEST.value != "1") 6082 { 6083 if (monitor_for_output("-k", "Update Done, err 0", MONITOR_DEFAULT_TIMEOUT.value, LOGDIR.value, null, true) != 0) 6084 { 6085 Console.WriteLine("cafex recover: monitor failed waiting for devkitmsg 1st update success message."); 6086 return CAFEX_ERROR.RECOVERY_FAILED; 6087 } 6088 } 6089 6090 CAFE_BOOT_MODE.value = "PCFS"; // Change to PCFS for the rest of the update 6091 if (bootloader_only) 6092 { 6093 // We have already updated the bootloader and since we were only 6094 // going to update it, skip the rest of update. 6095 skip_update = true; 6096 } 6097 6098 // 6099 // cafestop 6100 // 6101 Console.WriteLine("Executing cafex stop..."); 6102 try 6103 { 6104 stop(new string[] { "-hard" }); 6105 } 6106 catch (Exception e) 6107 { 6108 Console.WriteLine("cafex recover[warning]: Failure to hard stop the DEVKIT after bootloader update, error {0}", e.Message); 6109 } 6110 CAFE_RUN_RUNNING.value = "0"; 6111 } 6112 6113 if (!skip_update) 6114 { 6115 Console.WriteLine("Executing cafex on -recover..."); 6116 fs = new FileStream(LOGDIR.value + "\\cafeon.txt", FileMode.Create); 6117 old_out = Console.Out; 6118 old_err = Console.Error; 6119 sw = new StreamWriter(fs); 6120 Console.SetOut(sw); 6121 Console.SetError(sw); 6122 6123 if(CAFEX_RECOVER_TEST.value != "1") 6124 on(new string[] { "-e", "nomodecheck", "-recover" }, true, true); 6125 6126 Console.SetOut(old_out); 6127 Console.SetError(old_err); 6128 sw.Flush(); 6129 sw.Close(); 6130 6131 if (File.Exists(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log")) 6132 { 6133 File.Move(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log", LOGDIR.value + "\\cafeon_mion.log"); 6134 } 6135 if (CAFEX_RECOVER_TEST.value != "1") 6136 { 6137 if (monitor_for_output("-K", "WUD_BCMFWCheck", MONITOR_DEFAULT_TIMEOUT.value, LOGDIR.value, null, true) != 0) 6138 { 6139 Console.WriteLine("cafex recover: monitor failed waiting for devkitmsg recover success message."); 6140 return CAFEX_ERROR.RECOVERY_FAILED; 6141 } 6142 } 6143 6144 // Make sure Cafe is ready for commands 6145 int syncTry = 0; 6146 cattoucan.BeginBootSync(); 6147 for (syncTry = 0; syncTry < CAFERUN_RETRY_COUNT; ++syncTry) 6148 { 6149 if (cattoucan.SendSyncRequest(DEVKIT_HELP_REQUEST_TIMEOUT)) 6150 { 6151 break; 6152 } 6153 } 6154 for (; syncTry < CAFERUN_RETRY_COUNT; ++syncTry) 6155 { 6156 if (cattoucan.SyncWithBoot(DEVKIT_HELP_RESPONSE_TIMEOUT)) 6157 { 6158 break; 6159 } 6160 } 6161 cattoucan.FinishSync(true); 6162 6163 if (syncTry >= CAFERUN_RETRY_COUNT) 6164 { 6165 Console.WriteLine("Failed to sync with device"); 6166 return CAFEX_ERROR.RECOVERY_FAILED; 6167 } 6168 6169 // 6170 // Install the bootloader and content 6171 // 6172 if (reflash) 6173 { 6174 Console.WriteLine("Executing devkitmsg 'reflash '{0}' -v...", recover_source); 6175 devkitmsg.reflash(recover_source); 6176 if (CAFEX_RECOVER_TEST.value != "1") 6177 { 6178 if (monitor_for_output("-k", "System update was successful", MONITOR_DEFAULT_TIMEOUT.value, LOGDIR.value, null, true) != 0) 6179 { 6180 Console.WriteLine("cafex recover: monitor failed waiting for devkitmsg 1st update success message."); 6181 return CAFEX_ERROR.RECOVERY_FAILED; 6182 } 6183 } 6184 else 6185 return CAFEX_ERROR.OK; 6186 } 6187 else 6188 { 6189 Console.WriteLine("Executing devkitmsg 'update {0}' -v...", recover_source); 6190 devkitmsg.update(recover_source); 6191 if (CAFEX_RECOVER_TEST.value != "1") 6192 { 6193 if (monitor_for_output("-k", "Update Done, err 0", MONITOR_DEFAULT_TIMEOUT.value, LOGDIR.value, null, true) != 0) 6194 { 6195 Console.WriteLine("cafex recover: monitor failed waiting for devkitmsg 1st update success message."); 6196 return CAFEX_ERROR.RECOVERY_FAILED; 6197 } 6198 } 6199 else 6200 return CAFEX_ERROR.OK; 6201 } 6202 6203 // 6204 // Enable self-refresh 6205 // 6206 if (CAFE_TEST_SELF_REFRESH.value == "1") 6207 { 6208 Console.WriteLine("Executing devkitmsg standby_en 1 -v..."); 6209 devkitmsg.standby_en(1); 6210 } 6211 6212 // Update the DEV-KIT SDK variables to current 6213 setMionSDKVersion(); 6214 readSDKFromMion(); 6215 6216 // 6217 // cafestop 6218 // 6219 Console.WriteLine("Executing cafex stop..."); 6220 fs = new FileStream(LOGDIR.value + "\\cafestop1.txt", FileMode.Create); 6221 old_out = Console.Out; 6222 old_err = Console.Error; 6223 sw = new StreamWriter(fs); 6224 Console.SetOut(sw); 6225 Console.SetError(sw); 6226 6227 stop(null); 6228 6229 Console.SetOut(old_out); 6230 Console.SetError(old_err); 6231 sw.Flush(); 6232 sw.Close(); 6233 6234 if (File.Exists(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log")) 6235 { 6236 File.Move(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log", LOGDIR.value + "\\cafestop1_mion.log"); 6237 } 6238 6239 if (CAFESTOP_STATUS.value != "0") 6240 { 6241 Console.WriteLine("cafex recover: cafestop failure."); 6242 return CAFEX_ERROR.RECOVERY_FAILED; 6243 } 6244 } 6245 6246 if (production_bootloader || old_boot_mode == "NAND") 6247 { 6248 // Update the MION parameter space for NAND boot mode 6249 if (mionps.Run(String.Format("{0} {1} -s {2}",BRIDGE_CURRENT_IP_ADDRESS.value,MIONPS_BOOT_BYTE,MIONPS_BOOT_NAND)) != "1") 6250 { 6251 Console.WriteLine("cafex recover: unable to set NAND boot mode using mionps."); 6252 return CAFEX_ERROR.RECOVERY_FAILED; 6253 } 6254 } 6255 else 6256 { 6257 // Update the MION parameter space for PCFS boot mode 6258 if (mionps.Run(String.Format("{0} {1} -s {2}",BRIDGE_CURRENT_IP_ADDRESS.value,MIONPS_BOOT_BYTE,MIONPS_BOOT_PCFS)) != "2") 6259 { 6260 Console.WriteLine("cafex recover: unable to set PCFS boot mode using mionps."); 6261 return CAFEX_ERROR.RECOVERY_FAILED; 6262 } 6263 } 6264 6265 // 6266 // Success! 6267 // 6268 Console.WriteLine("Removing log directory " + LOGDIR.value + "..."); 6269 ForceRemoveDirectory(LOGDIR.value); 6270 Console.WriteLine("cafex recover complete. Exiting with code 0"); 6271 6272 if (production_bootloader && old_boot_mode != "NAND") 6273 { 6274 Console.WriteLine(); 6275 Console.WriteLine("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); 6276 Console.WriteLine("!! !!"); 6277 Console.WriteLine("!! Boot Loader/Boot Mode mis-match detected! !!"); 6278 Console.WriteLine("!! !!"); 6279 Console.WriteLine("!! Please export CAFE_BOOT_MODE=NAND for proper operation! !!"); 6280 Console.WriteLine("!! !!"); 6281 Console.WriteLine("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); 6282 } 6283 6284 return CAFEX_ERROR.OK; 6285 } 6286 6287 //Script function: cafex cleardata cleardata(params string[] args)6288 static CAFEX_ERROR cleardata(params string[] args) 6289 { 6290 #if DEBUG 6291 Log.WriteLine("cleardata started."); 6292 string argString = null; 6293 if (args != null) 6294 { 6295 foreach (string arg in args) 6296 { 6297 argString += arg + " "; 6298 } 6299 } 6300 Log.WriteLine("Arguments=" + argString); 6301 #endif 6302 // 6303 // Initialization 6304 // 6305 SCRIPT_EXE_TIMESTAMP.value = DateTime.Now.ToString("MMMdd_yyyy_HHmmss"); 6306 LOGDIR.value = CAFE_TEMP.value + "\\" + SESSION_PATH_PREFIX.value + "cleardata\\" + SCRIPT_EXE_TIMESTAMP.value; 6307 Console.WriteLine("cafex cleardata"); 6308 Console.WriteLine("log directory is " + LOGDIR.value); 6309 create_directory_if_noexist(LOGDIR.value); 6310 CAFE_CONSOLE.value = "toucan"; 6311 6312 FileStream fs = null; 6313 TextWriter old_out = null; 6314 TextWriter old_err = null; 6315 StreamWriter sw = null; 6316 6317 // 6318 // Boot mode detection 6319 // 6320 CAFEX_ERROR hostcheckversion_ret = hostcheckversion(); 6321 if (hostcheckversion_ret != CAFEX_ERROR.OK) 6322 { 6323 Console.WriteLine("cafex cleardata: failed running hostcheckversion."); 6324 return hostcheckversion_ret; 6325 } 6326 6327 int hb_ver_flat = compute_flat_version(CAFERUN_HOSTBRIDGE_VERSION.value); 6328 if (hb_ver_flat < compute_flat_version("3.2.4.8")) 6329 { 6330 Console.WriteLine("Error: Clear user data not supported in this version of the HostBridge!"); 6331 Console.WriteLine(" Please update your HostBridge to at least version 3.2.4.8 (preferably the latest) and try again."); 6332 Console.WriteLine("cafex cleardata failed."); 6333 return CAFEX_ERROR.CLEARDATA_FAILED; 6334 } 6335 else 6336 { 6337 string boot_mode; 6338 6339 // hostbridge 3.2.5.1 has a problem in mode detection that requires some time after stop 6340 // in order to properly detect boot mode 6341 try 6342 { 6343 stop(new string[] { "-hard" }); 6344 } 6345 catch (Exception e) 6346 { 6347 Console.WriteLine("cafex recover[warning]: Failure to hard stop the DEVKIT prior to mode detection, error {0}", e.Message); 6348 } 6349 Thread.Sleep(1000); 6350 6351 int boot_mode_detect = FSEmul.boot_mode_detect(BRIDGE_CURRENT_IP_ADDRESS.value, out boot_mode); 6352 if (boot_mode_detect != 0) 6353 { 6354 Console.WriteLine("Unable to determine boot mode!"); 6355 return CAFEX_ERROR.BOOTMODEDETECT_FSEMUL_FAILED; 6356 } 6357 6358 Console.WriteLine("Detected BOOT mode : {0}", boot_mode); 6359 if (boot_mode == "NAND") 6360 { 6361 CAFE_BOOT_MODE.value = "NAND"; 6362 } 6363 else 6364 { 6365 CAFE_BOOT_MODE.value = "PCFS"; 6366 } 6367 } 6368 6369 if (CAFE_BOOT_MODE.value == "NAND") 6370 { 6371 stop(null); 6372 6373 Console.WriteLine("Error: Can't clear user data in NAND boot mode! Please switch to PCFS boot mode and try again."); 6374 Console.WriteLine("cafex cleardata failed."); 6375 return CAFEX_ERROR.CLEARDATA_FAILED; 6376 } 6377 6378 Console.WriteLine("Executing cafex on..."); 6379 fs = new FileStream(LOGDIR.value + "\\cafeon.txt", FileMode.Create); 6380 old_out = Console.Out; 6381 old_err = Console.Error; 6382 sw = new StreamWriter(fs); 6383 Console.SetOut(sw); 6384 Console.SetError(sw); 6385 6386 // cafeon 6387 if (hb_ver_flat < compute_flat_version("3.2.4.1")) 6388 { 6389 on(null, true, true); 6390 } 6391 else 6392 { 6393 on(new string[] { "-e", "nomodecheck" }, true, true); 6394 } 6395 6396 Console.SetOut(old_out); 6397 Console.SetError(old_err); 6398 sw.Flush(); 6399 sw.Close(); 6400 6401 if (File.Exists(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log")) 6402 { 6403 File.Move(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log", LOGDIR.value + "\\cafeon_mion.log"); 6404 } 6405 6406 if (monitor_for_output("-k", Nintendo.SDSG.CatToucan.Terms.MENU_SOURCE, MONITOR_DEFAULT_TIMEOUT.value, LOGDIR.value, null, true) != 0) 6407 { 6408 Console.WriteLine("cafex cleardata: monitor failed waiting for cafeon success message."); 6409 return CAFEX_ERROR.CLEARDATA_FAILED; 6410 } 6411 6412 Console.WriteLine("Executing devkitmsg recover -v..."); 6413 devkitmsg.recover(); 6414 6415 if (monitor_for_output("-K", "WUD_BCMFWCheck", MONITOR_DEFAULT_TIMEOUT.value, LOGDIR.value, null, true) != 0) 6416 { 6417 Console.WriteLine("cafex cleardata: monitor failed waiting for devkitmsg recover success message."); 6418 return CAFEX_ERROR.CLEARDATA_FAILED; 6419 } 6420 6421 //clr_usrdata command 6422 Console.WriteLine("Executing devkitmsg clr_usrdata -v..."); 6423 devkitmsg.clr_usrdata(); 6424 6425 if (monitor_for_output("-k", "Done, err 0", MONITOR_DEFAULT_TIMEOUT.value, LOGDIR.value, null, true) != 0) 6426 { 6427 Console.WriteLine("cafex cleardata: monitor failed waiting for devkitmsg clr_usrdata success message."); 6428 return CAFEX_ERROR.CLEARDATA_FAILED; 6429 } 6430 6431 //cafestop 6432 Console.WriteLine("Executing cafex stop..."); 6433 fs = new FileStream(LOGDIR.value + "\\cafestop1.txt", FileMode.Create); 6434 old_out = Console.Out; 6435 old_err = Console.Error; 6436 sw = new StreamWriter(fs); 6437 Console.SetOut(sw); 6438 Console.SetError(sw); 6439 6440 stop(null); 6441 6442 Console.SetOut(old_out); 6443 Console.SetError(old_err); 6444 sw.Flush(); 6445 sw.Close(); 6446 6447 if (File.Exists(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log")) 6448 { 6449 File.Move(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log", LOGDIR.value + "\\cafestop1_mion.log"); 6450 } 6451 6452 if (CAFESTOP_STATUS.value != "0") 6453 { 6454 Console.WriteLine("cafex cleardata: cafestop failure."); 6455 return CAFEX_ERROR.CLEARDATA_FAILED; 6456 } 6457 6458 //success! 6459 Console.WriteLine("Removing log directory " + LOGDIR.value + "..."); 6460 ForceRemoveDirectory(LOGDIR.value); 6461 Console.WriteLine("cafex cleardata complete. Exiting with code 0"); 6462 6463 return CAFEX_ERROR.OK; 6464 } 6465 6466 //Script function: setbootmode setbootmode(string[] args)6467 static CAFEX_ERROR setbootmode(string[] args) 6468 { 6469 #if DEBUG 6470 Log.WriteLine("setbootmode started."); 6471 string argString = null; 6472 if (args != null) 6473 { 6474 foreach (string arg in args) 6475 { 6476 argString += arg + " "; 6477 } 6478 } 6479 Log.WriteLine("Arguments=" + argString); 6480 6481 #endif 6482 6483 CAFEX_ERROR returnValue = CAFEX_ERROR.SETBOOTMODE_FAILED; 6484 bool reflash = false; 6485 bool noreflash = false; 6486 bool mixed = false; 6487 bool prod = true; //not having this will break "setbootmode PCFS" in SDKs 2.10.01-2.10.08 6488 bool prod_arg = false; //specifically for the -quick case conditional 6489 6490 if ((recover_flags & RECOVER_COMMAND_MASK) == RECOVER_COMMAND_INIT) 6491 { 6492 recover_flags = (recover_flags & ~RECOVER_COMMAND_MASK) | RECOVER_COMMAND_SBM; 6493 } 6494 6495 if (is_DUAL_bootloader_required()) 6496 { 6497 mixed = true; 6498 prod = false; 6499 } 6500 else //the bootloader isn't available or not required 6501 { 6502 mixed = false; 6503 prod = true; 6504 } 6505 6506 bool quick = false; 6507 bool reflash_arg = false; 6508 bool noreflash_arg = false; 6509 6510 int ret = 0; 6511 string target = string.Empty; 6512 for (int idx = 0; idx < args.Length; idx++) 6513 { 6514 if (args[idx] == "-noreflash") //uses the update command with devkitmsg 6515 { 6516 noreflash_arg = true; 6517 reflash = false; 6518 noreflash = true; 6519 recover_flags = (recover_flags & ~RECOPT_NOREFLASH_MASK) | RECOPT_NOREFLASH_DEF; 6520 } 6521 else if (args[idx] == "-reflash") //uses the reflash command with devkitmsg 6522 { 6523 reflash_arg = true; 6524 noreflash = false; 6525 reflash = true; 6526 recover_flags = (recover_flags & ~RECOPT_REFLASH_MASK) | RECOPT_REFLASH_DEF; 6527 } 6528 else if (args[idx] == "-production" || args[idx] == "-P") 6529 { 6530 mixed = false; 6531 prod = true; 6532 prod_arg = true; 6533 reflash = true; 6534 recover_flags = (recover_flags & ~RECOPT_PROD_MASK) | RECOPT_PRODUCTION_DEF; 6535 //if (!noreflash) 6536 //{ 6537 // // the -noreflash option was found before -production 6538 // reflash = true; 6539 //} 6540 } 6541 else if (args[idx] == "-quick" || args[idx] == "-Q") 6542 { 6543 quick = true; 6544 recover_flags = (recover_flags & ~RECOPT_QUICK_MASK) | RECOPT_QUICK_DEF; 6545 } 6546 else if (args[idx] == "-h") 6547 { 6548 setbootmode_usage(); 6549 return CAFEX_ERROR.OK; 6550 } 6551 //included for backward compatibility. If both mixed and prod are specified, prod will take precedence. 6552 else if (args[idx] == "-mixed") 6553 { 6554 recover_flags = (recover_flags & ~RECOPT_MIXED_MASK) | RECOPT_MIXED_DEF; 6555 //This option was only valid on SDKs 2.10.01-2.10.09 6556 if (is_DUAL_bootloader_available() && !is_DUAL_bootloader_required()) 6557 { 6558 mixed = true; 6559 prod = false; 6560 } 6561 else 6562 { 6563 Console.WriteLine("-mixed option is not supported on this SDK."); 6564 return CAFEX_ERROR.BAD_ARGUMENT; 6565 } 6566 } 6567 else 6568 { 6569 if (!string.IsNullOrEmpty(target)) 6570 { 6571 setbootmode_usage(); 6572 return CAFEX_ERROR.BAD_ARGUMENT; 6573 } 6574 if (!ArgumentChecks.IsArgumentValidSetting(args, idx)) 6575 { 6576 setbootmode_usage(); 6577 return CAFEX_ERROR.BAD_ARGUMENT; 6578 } 6579 target = args[idx]; 6580 } 6581 } 6582 6583 if (string.IsNullOrEmpty(target)) 6584 { 6585 setbootmode_usage(); 6586 return CAFEX_ERROR.BAD_ARGUMENT; 6587 } 6588 6589 if (reflash_arg && noreflash_arg) 6590 { 6591 Console.WriteLine("Can't specify both -reflash and -noreflash! Please remove one or the other."); 6592 return CAFEX_ERROR.UPDATE_INVALID_OPTION; 6593 } 6594 6595 string status_str = "FAIL"; 6596 6597 if (quick) 6598 { 6599 if (target != "NAND" && target != "PCFS") 6600 { 6601 Console.WriteLine("cafex setbootmode error: {0} is not a valid boot mode!", target); 6602 setbootmode_usage(); 6603 return CAFEX_ERROR.SETBOOTMODE_BAD_MODE; 6604 } 6605 6606 if (prod_arg) 6607 { 6608 Console.WriteLine("cafex setbootmode error: Can't specify both -quick and -production options!"); 6609 setbootmode_usage(); 6610 return CAFEX_ERROR.BAD_ARGUMENT; 6611 } 6612 6613 CAFEX_ERROR hostcheckversion_ret = hostcheckversion(); 6614 6615 if (hostcheckversion_ret != CAFEX_ERROR.OK) 6616 { 6617 Console.WriteLine("cafex setbootmode: failed running hostcheckversion."); 6618 return CAFEX_ERROR.SETBOOTMODE_FAILED; 6619 } 6620 6621 int hb_ver_flat = compute_flat_version(CAFERUN_HOSTBRIDGE_VERSION.value); 6622 6623 if (hb_ver_flat < compute_flat_version("3.2.4.8")) 6624 { 6625 Console.WriteLine("cafex setbootmode: This version of the HostBridge doesn't support boot mode detection!."); 6626 Console.WriteLine(" Please update to it at least version 3.2.4.8 and try again."); 6627 return CAFEX_ERROR.SETBOOTMODE_FAILED; 6628 } 6629 6630 string boot_mode; 6631 6632 // hostbridge 3.2.5.1 has a problem in mode detection that requires some time after stop 6633 // in order to properly detect boot mode 6634 stop(new string[] { "-hard" }); 6635 Thread.Sleep(1000); 6636 6637 int boot_mode_detect = FSEmul.boot_mode_detect(BRIDGE_CURRENT_IP_ADDRESS.value, out boot_mode); 6638 if (boot_mode_detect != 0) 6639 { 6640 Console.WriteLine("cafex setbootmode: Error: Unable to determine boot mode!"); 6641 return CAFEX_ERROR.BOOTMODEDETECT_FSEMUL_FAILED; 6642 } 6643 6644 stop(new string[] { "-hard" }); 6645 6646 Console.WriteLine("cafex setbootmode: Detected BOOT mode : {0}", boot_mode); 6647 if(boot_mode.Contains("PCFS")) 6648 { 6649 recover_flags = (recover_flags & ~RECOVER_DETECTED_BOOT_MASK) | RECOVER_DETECT_BOOT_PCFS; 6650 } 6651 else if (boot_mode.Contains("NAND")) 6652 { 6653 recover_flags = (recover_flags & ~RECOVER_DETECTED_BOOT_MASK) | RECOVER_DETECT_BOOT_NAND; 6654 } 6655 else if (boot_mode.Contains("DUAL")) 6656 { 6657 recover_flags = (recover_flags & ~RECOVER_DETECTED_BOOT_MASK) | RECOVER_DETECT_BOOT_DUAL; 6658 } 6659 6660 if (!boot_mode.StartsWith ("DUAL")) 6661 { 6662 Console.WriteLine("cafex setbootmode: Error: DUAL bootloader is not installed. Please re-run setbootmode without using the -quick option."); 6663 return CAFEX_ERROR.SETBOOTMODE_FAILED; 6664 } 6665 6666 if (target == "NAND") 6667 { 6668 recover_flags = (recover_flags & ~RECOPT_DESIRED_BOOT_MASK) | RECOPT_DESIRED_BOOT_NAND; 6669 if (mionps.Run(BRIDGE_CURRENT_IP_ADDRESS.value + " 2 -s 1") != "1") 6670 { 6671 Console.WriteLine("cafex unable to set NAND mode using mionps."); 6672 return CAFEX_ERROR.SETBOOTMODE_FAILED; 6673 } 6674 } 6675 else 6676 { 6677 recover_flags = (recover_flags & ~RECOPT_DESIRED_BOOT_MASK) | RECOPT_DESIRED_BOOT_PCFS; 6678 if (mionps.Run(BRIDGE_CURRENT_IP_ADDRESS.value + " 2 -s 2") != "2") 6679 { 6680 Console.WriteLine("cafex unable to set PCFS mode using mionps."); 6681 return CAFEX_ERROR.SETBOOTMODE_FAILED; 6682 } 6683 } 6684 6685 if (CAFEX_RECOVER_TEST.value == "1") 6686 { 6687 Console.WriteLine("recover_flags={0:X12}", recover_flags); 6688 Console.WriteLine("devkitmsg_cmd: NA"); 6689 } 6690 6691 returnValue = CAFEX_ERROR.OK; 6692 status_str = "PASS"; 6693 } 6694 else 6695 { 6696 switch (target) 6697 { 6698 case "PCFS": 6699 { 6700 recover_flags = (recover_flags & ~RECOPT_DESIRED_BOOT_MASK) | RECOPT_DESIRED_BOOT_PCFS; 6701 6702 if (prod_arg) 6703 { 6704 Console.WriteLine("cafex setbootmode: Can't specify -production with the PCFS boot mode!"); 6705 return CAFEX_ERROR.SETBOOTMODE_FAILED; 6706 } 6707 6708 List<string> recover_args = new List<string>(); 6709 6710 if (mixed) 6711 { 6712 Console.WriteLine("Executing cafex recover for mixed PCFS..."); 6713 if (!is_DUAL_bootloader_required()) 6714 recover_args.Add("-mixed"); 6715 } 6716 else 6717 { 6718 Console.WriteLine("Executing cafex recover for legacy PCFS..."); 6719 } 6720 6721 if (noreflash) 6722 { 6723 recover_args.Add("-noreflash"); 6724 } 6725 else if (reflash) 6726 { 6727 recover_args.Add("-reflash"); 6728 } 6729 6730 ret = (int)recover(recover_args.ToArray()); 6731 if (ret == 0) 6732 { 6733 // Set the CAT-DEV mode inside mion... 6734 if (mionps.Run(BRIDGE_CURRENT_IP_ADDRESS.value + " 2 -s 2") != "2") 6735 { 6736 Console.WriteLine("cafex unable to set mode using mionps."); 6737 return CAFEX_ERROR.SETBOOTMODE_FAILED; 6738 } 6739 6740 CAFE_BOOT_MODE.value = "PCFS"; 6741 Console.WriteLine("CAFE_BOOT_MODE=" + CAFE_BOOT_MODE.value); 6742 status_str = "PASS"; 6743 returnValue = CAFEX_ERROR.OK; 6744 } 6745 break; 6746 } 6747 6748 case "NAND": 6749 { 6750 recover_flags = (recover_flags & ~RECOPT_DESIRED_BOOT_MASK) | RECOPT_DESIRED_BOOT_NAND; 6751 6752 List<string> recover_args = new List<string>(); 6753 if (prod) 6754 { 6755 Console.WriteLine("Executing cafex recover for production NAND..."); 6756 recover_args.Add("-production"); 6757 } 6758 else 6759 { 6760 Console.WriteLine("Executing cafex recover for mixed NAND..."); 6761 if (!is_DUAL_bootloader_required()) // SDK 2.10.11+ will error if -mixed is specified 6762 recover_args.Add("-mixed"); 6763 } 6764 6765 if (noreflash) 6766 { 6767 recover_args.Add("-noreflash"); 6768 } 6769 else if (reflash) 6770 { 6771 recover_args.Add("-reflash"); 6772 } 6773 6774 ret = (int)recover(recover_args.ToArray()); 6775 if (ret == 0) 6776 { 6777 // Set the CAT-DEV mode inside mion... 6778 if (mionps.Run(BRIDGE_CURRENT_IP_ADDRESS.value + " 2 -s 1") != "1") 6779 { 6780 Console.WriteLine("cafex unable to set mode using mionps."); 6781 return CAFEX_ERROR.SETBOOTMODE_FAILED; 6782 } 6783 6784 CAFE_BOOT_MODE.value = "NAND"; 6785 Console.WriteLine("CAFE_BOOT_MODE=" + CAFE_BOOT_MODE.value); 6786 status_str = "PASS"; 6787 returnValue = CAFEX_ERROR.OK; 6788 } 6789 break; 6790 } 6791 6792 default: 6793 { 6794 Console.WriteLine("cafex setbootmode error: Invalid boot mode"); 6795 status_str = "BAD MODE"; 6796 setbootmode_usage(); 6797 returnValue = CAFEX_ERROR.SETBOOTMODE_BAD_MODE; 6798 break; 6799 } 6800 } 6801 } 6802 6803 Console.WriteLine("cafex setbootmode: " + status_str); 6804 if (returnValue == CAFEX_ERROR.OK) 6805 { 6806 readSDKFromMion(); 6807 setMionSDKVersion(); 6808 } 6809 6810 return returnValue; 6811 } 6812 6813 6814 #if false 6815 //Script function: cafe_nand2pcfs nand2pcfs(int call_mionps)6816 static int nand2pcfs(int call_mionps) 6817 { 6818 #if DEBUG 6819 Log.WriteLine("nand2pcfs started."); 6820 #endif 6821 6822 // Initialization 6823 SCRIPT_EXE_TIMESTAMP.value = DateTime.Now.ToString("MMMdd_yyyy_HHmmss"); 6824 LOGDIR.value = CAFE_ROOT.value + "\\" + SESSION_PATH_PREFIX.value + "cafe_nand2pcfs\\" + SCRIPT_EXE_TIMESTAMP.value; 6825 Console.WriteLine("cafe_nand2pcfs"); 6826 Console.WriteLine("log directory is " + LOGDIR.value); 6827 create_directory_if_noexist(LOGDIR.value); 6828 6829 File.Delete(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log"); 6830 6831 CAFESTOP_STATUS.value = "0"; 6832 _CCRSYSCFG1.value = ""; 6833 if (initialize_serial_port_and_directory("cafestop") != 0) 6834 return 1; 6835 6836 //cafestop 6837 Console.WriteLine("Executing cafex stop..."); 6838 FileStream fs = new FileStream(LOGDIR.value + "\\cafestop0.txt", FileMode.Create); 6839 TextWriter old_out = Console.Out; 6840 TextWriter old_err = Console.Error; 6841 StreamWriter sw = new StreamWriter(fs); 6842 Console.SetOut(sw); 6843 Console.SetError(sw); 6844 6845 stop(new string[] {"-hard"}); 6846 6847 Console.SetOut(old_out); 6848 Console.SetError(old_err); 6849 sw.Flush(); 6850 sw.Close(); 6851 6852 if (File.Exists(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log")) 6853 { 6854 File.Move(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log", LOGDIR.value + "\\cafestop0_mion.log"); 6855 } 6856 6857 if (CAFESTOP_STATUS.value != "0") 6858 { 6859 Console.WriteLine("cafex nand2pcfs: cafestop failure."); 6860 return 1; 6861 } 6862 6863 //cafeon 6864 CAFEX_ERROR hostcheckversion_ret = hostcheckversion(); 6865 6866 if (hostcheckversion_ret != CAFEX_ERROR.OK) 6867 { 6868 Console.WriteLine("cafex nand2pcfs: failed running hostcheckversion."); 6869 return 1; 6870 } 6871 6872 int hb_ver_flat = compute_flat_version(CAFERUN_HOSTBRIDGE_VERSION.value); 6873 6874 Console.WriteLine("Executing cafex on..."); 6875 fs = new FileStream(LOGDIR.value + "\\cafeon.txt", FileMode.Create); 6876 old_out = Console.Out; 6877 old_err = Console.Error; 6878 sw = new StreamWriter(fs); 6879 Console.SetOut(sw); 6880 Console.SetError(sw); 6881 6882 //quiet_mode = true; // This breaks setbootmode in NAND/softlaunch 6883 Console.WriteLine("at on command"); 6884 if (hb_ver_flat < compute_flat_version("3.2.4.1")) 6885 { 6886 on(null, true, true); 6887 } 6888 else 6889 { 6890 on(new string[] { "-e", "nomodecheck" }, true, true); 6891 } 6892 6893 Console.WriteLine("after on command"); 6894 6895 Console.SetOut(old_out); 6896 Console.SetError(old_err); 6897 sw.Flush(); 6898 sw.Close(); 6899 6900 if (File.Exists(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log")) 6901 { 6902 File.Move(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log", LOGDIR.value + "\\cafeon_mion.log"); 6903 } 6904 6905 if (monitor_for_output("-k", Nintendo.SDSG.CatToucan.Terms.MENU_SOURCE, MONITOR_DEFAULT_TIMEOUT.value, LOGDIR.value, null, true) != 0) 6906 { 6907 Console.WriteLine("cafex nand2pcfs: monitor failed waiting for cafeon success message."); 6908 return 1; 6909 } 6910 6911 //recover command 6912 Console.WriteLine("Executing devkitmsg recover -v..."); 6913 devkitmsg.recover(); 6914 6915 if (monitor_for_output("-K", "WUD_BCMFWCheck", MONITOR_DEFAULT_TIMEOUT.value, LOGDIR.value, null, true) != 0) 6916 { 6917 Console.WriteLine("cafex nand2pcfs: monitor failed waiting for devkitmsg recover success message."); 6918 return 1; 6919 } 6920 6921 //update to PCFS 6922 Console.WriteLine("Executing devkitmsg 'update /vol/storage_hfiomlc01/sys/update/pcfs' -v..."); 6923 devkitmsg.update_pcfs(); 6924 6925 if (monitor_for_output("-k", "Update Done, err 0", MONITOR_DEFAULT_TIMEOUT.value, LOGDIR.value, null, true) != 0) 6926 { 6927 Console.WriteLine("cafex nand2pcfs: monitor failed waiting for devkitmsg 1st update success message."); 6928 return 1; 6929 } 6930 6931 if (call_mionps == 1) 6932 { 6933 // Set the CAT-DEV mode inside mion... 6934 if (mionps.Run(BRIDGE_CURRENT_IP_ADDRESS.value + " 2 -s 2") != "2") 6935 { 6936 Console.WriteLine("cafex unable to set mode using mionps."); 6937 return 1; 6938 } 6939 } 6940 6941 //clr_usrdata command 6942 Console.WriteLine("Executing devkitmsg clr_usrdata -v..."); 6943 devkitmsg.clr_usrdata(); 6944 6945 if (monitor_for_output("-k", "Done, err 0", MONITOR_DEFAULT_TIMEOUT.value, LOGDIR.value, null, true) != 0) 6946 { 6947 Console.WriteLine("cafex nand2pcfs: monitor failed waiting for devkitmsg clr_usrdata success message."); 6948 return 1; 6949 } 6950 6951 //enable self-refresh 6952 if (CAFE_TEST_SELF_REFRESH.value == "1") 6953 { 6954 Console.WriteLine("Executing devkitmsg standyby_en 1 -v..."); 6955 devkitmsg.standby_en(1); 6956 } 6957 6958 //cafestop 6959 Console.WriteLine("Executing cafex stop..."); 6960 fs = new FileStream(LOGDIR.value + "\\cafestop1.txt", FileMode.Create); 6961 old_out = Console.Out; 6962 old_err = Console.Error; 6963 sw = new StreamWriter(fs); 6964 Console.SetOut(sw); 6965 Console.SetError(sw); 6966 6967 stop(null); 6968 6969 Console.SetOut(old_out); 6970 Console.SetError(old_err); 6971 sw.Flush(); 6972 sw.Close(); 6973 6974 if (File.Exists(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log")) 6975 { 6976 File.Move(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log", LOGDIR.value + "\\cafestop1_mion.log"); 6977 } 6978 6979 if (CAFESTOP_STATUS.value != "0") 6980 { 6981 Console.WriteLine("cafex nand2pcfs: cafestop failure."); 6982 return 1; 6983 } 6984 6985 //success! 6986 Console.WriteLine("Removing log directory " + LOGDIR.value + "..."); 6987 ForceRemoveDirectory(LOGDIR.value); 6988 Console.WriteLine("cafex nand2pcfs complete. Exiting with code 0"); 6989 6990 return 0; 6991 } 6992 #endif 6993 6994 #if false 6995 //Script function: cafe_pcfs2nand pcfs2nand(int reflash, int call_mionps)6996 static int pcfs2nand(int reflash, int call_mionps) 6997 { 6998 #if DEBUG 6999 Log.WriteLine("pcfs2nand started."); 7000 #endif 7001 7002 // Initialization 7003 SCRIPT_EXE_TIMESTAMP.value = DateTime.Now.ToString("MMMdd_yyyy_HHmmss"); 7004 LOGDIR.value = CAFE_ROOT.value + "\\" + SESSION_PATH_PREFIX.value + "cafe_pcfs2nand\\" + SCRIPT_EXE_TIMESTAMP.value; 7005 Console.WriteLine("cafe_pcfs2nand"); 7006 Console.WriteLine("log directory is " + LOGDIR.value); 7007 create_directory_if_noexist(LOGDIR.value); 7008 7009 File.Delete(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log"); 7010 7011 CAFESTOP_STATUS.value = "0"; 7012 _CCRSYSCFG1.value = ""; 7013 if (initialize_serial_port_and_directory("cafestop") != 0) 7014 return 1; 7015 7016 //cafestop 7017 Console.WriteLine("Executing cafex stop..."); 7018 FileStream fs = new FileStream(LOGDIR.value + "\\cafestop0.txt", FileMode.Create); 7019 TextWriter old_out = Console.Out; 7020 TextWriter old_err = Console.Error; 7021 StreamWriter sw = new StreamWriter(fs); 7022 Console.SetOut(sw); 7023 Console.SetError(sw); 7024 7025 stop(null); 7026 7027 Console.SetOut(old_out); 7028 Console.SetError(old_err); 7029 sw.Flush(); 7030 sw.Close(); 7031 7032 if (File.Exists(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log")) 7033 { 7034 File.Move(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log", LOGDIR.value + "\\cafestop0_mion.log"); 7035 } 7036 7037 if (CAFESTOP_STATUS.value != "0") 7038 { 7039 Console.WriteLine("cafex nand2pcfs: cafestop failure."); 7040 return 1; 7041 } 7042 7043 //cafeon 7044 CAFEX_ERROR hostcheckversion_ret = hostcheckversion(); 7045 if (hostcheckversion_ret != CAFEX_ERROR.OK) 7046 { 7047 Console.WriteLine("cafex nand2pcfs: failed running hostcheckversion."); 7048 return 1; 7049 } 7050 7051 int hb_ver_flat = compute_flat_version(CAFERUN_HOSTBRIDGE_VERSION.value); 7052 7053 Console.WriteLine("Executing cafex on..."); 7054 fs = new FileStream(LOGDIR.value + "\\cafeon.txt", FileMode.Create); 7055 old_out = Console.Out; 7056 old_err = Console.Error; 7057 sw = new StreamWriter(fs); 7058 Console.SetOut(sw); 7059 Console.SetError(sw); 7060 7061 //quiet_mode = true; // This breaks setbootmode in NAND/softlaunch 7062 Console.WriteLine("at on command"); 7063 if (hb_ver_flat < compute_flat_version("3.2.4.1")) 7064 { 7065 on(null, true, true); 7066 } 7067 else 7068 { 7069 on(new string[] { "-e", "nomodecheck" }, true, true); 7070 } 7071 7072 Console.WriteLine("after on command"); 7073 7074 Console.SetOut(old_out); 7075 Console.SetError(old_err); 7076 sw.Flush(); 7077 sw.Close(); 7078 7079 if (File.Exists(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log")) 7080 { 7081 File.Move(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log", LOGDIR.value + "\\cafeon_mion.log"); 7082 } 7083 7084 if (monitor_for_output("-k", "source -p -q /vol/content/", MONITOR_DEFAULT_TIMEOUT.value, LOGDIR.value, null, true) != 0) 7085 { 7086 Console.WriteLine("cafex nand2pcfs: monitor failed waiting for cafeon success message."); 7087 return 1; 7088 } 7089 7090 bool was_pcfs_boot = false; 7091 fs = new FileStream(LOGDIR.value + "\\monitor_1.txt", FileMode.Open, FileAccess.Read); 7092 StreamReader sr = new StreamReader(fs); 7093 string contents = sr.ReadToEnd(); 7094 sr.Close(); 7095 if (contents.Contains("BOOT1: Loaded firmware image from SDIO.")) 7096 { 7097 was_pcfs_boot = true; 7098 } 7099 7100 //recover command 7101 Console.WriteLine("Executing devkitmsg recover -v..."); 7102 devkitmsg.recover(); 7103 7104 if (monitor_for_output("-K", "WUD_BCMFWCheck", MONITOR_DEFAULT_TIMEOUT.value, LOGDIR.value, null, true) != 0) 7105 { 7106 Console.WriteLine("cafex nand2pcfs: monitor failed waiting for devkitmsg recover success message."); 7107 return 1; 7108 } 7109 7110 // if last boot was NAND, first update BOOT1 to PCFS 7111 if (was_pcfs_boot == false) 7112 { 7113 const string dual_boot1_folder = "aaa-boot1-dual"; 7114 string BL_DEST_DIR = Path.Combine(Program.CAFE_MLC_DIR.value, "sys\\update\\bootloader"); 7115 string MIXED_DEST_DIR = Path.Combine(Program.CAFE_MLC_DIR.value, "sys\\update\\mixed"); 7116 7117 Console.WriteLine("cafex pcfs2nand: NAND boot detected, BOOT1 will be updated before updating to NAND"); 7118 Console.WriteLine("Executing devkitmsg 'update /vol/storage_hfiomlc01/sys/update/mixed' -v..."); 7119 // here we ensure we start from a flexible, configurable system 7120 7121 Console.WriteLine("cafex: Checking content in '{0}'", BL_DEST_DIR); 7122 7123 // Create the DUAL boot loader only directory if ir does not exist 7124 create_directory_if_noexist(BL_DEST_DIR); 7125 7126 // Create a junction for the DUAL bootloader in the bootloader dest dir 7127 if (!Directory.Exists(Path.Combine(BL_DEST_DIR, dual_boot1_folder))) 7128 { 7129 #if DEBUG 7130 Console.WriteLine("Copying directory '{0}' => '{1}'", Path.Combine(MIXED_DEST_DIR, dual_boot1_folder), Path.Combine(BL_DEST_DIR, dual_boot1_folder)); 7131 #endif 7132 // 7133 // Symbolic links require NTFS which *should* not be a problem for most but 7134 // require elevated privledges, which is an issue if the user is not an admin or with UAC. 7135 // 7136 // We copy the folders instead of linking them as it is relatively fast and more compatible with UAC. 7137 // 7138 FileUtil.DirectoryCopy(Path.Combine(MIXED_DEST_DIR, dual_boot1_folder), Path.Combine(BL_DEST_DIR, dual_boot1_folder), false); 7139 } 7140 7141 7142 devkitmsg.update("/vol/storage_hfiomlc01/sys/update/bootloader"); 7143 7144 if (monitor_for_output("-k", "Update Done, err 0", MONITOR_DEFAULT_TIMEOUT.value, LOGDIR.value, null, true) != 0) 7145 { 7146 Console.WriteLine("cafex pcfs2nand: monitor failed waiting for devkitmsg 1st update success message."); 7147 return 1; 7148 } 7149 7150 } 7151 else 7152 { 7153 Console.WriteLine("cafe_pcfs2nand: PCFS boot detected, no BOOT1 update needed"); 7154 } 7155 7156 //update command 7157 if (reflash == 1) 7158 { 7159 Console.WriteLine("Executing devkitmsg 'reflash /vol/storage_hfiomlc01/sys/update/nand' -v..."); 7160 devkitmsg.update_reflash(); 7161 7162 7163 if (monitor_for_output("-k", "MCP: System update was successful", MONITOR_DEFAULT_TIMEOUT.value, LOGDIR.value, null, true) != 0) 7164 { 7165 Console.WriteLine("cafex pcfs2nand: monitor failed waiting for devkitmsg reflash success message."); 7166 return 1; 7167 } 7168 } 7169 else 7170 { 7171 Console.WriteLine("Executing devkitmsg 'update /vol/storage_hfiomlc01/sys/update/nand' -v..."); 7172 devkitmsg.update_nand(); 7173 7174 if (monitor_for_output("-k", "Update Done, err 0", MONITOR_DEFAULT_TIMEOUT.value, LOGDIR.value, null, true) != 0) 7175 { 7176 Console.WriteLine("cafex pcfs2nand: monitor failed waiting for devkitmsg update success message."); 7177 return 1; 7178 } 7179 } 7180 7181 if (call_mionps == 1) 7182 { 7183 // Set the CAT-DEV mode inside mion... 7184 if (mionps.Run(BRIDGE_CURRENT_IP_ADDRESS.value + " 2 -s 1") != "1") 7185 { 7186 Console.WriteLine("cafex unable to set mode using mionps."); 7187 return 1; 7188 } 7189 } 7190 7191 // set default boot mode to development 7192 devkitmsg.sys_mode_dev(); 7193 7194 //cafestop 7195 Console.WriteLine("Executing cafex stop..."); 7196 fs = new FileStream(LOGDIR.value + "\\cafestop1.txt", FileMode.Create); 7197 old_out = Console.Out; 7198 old_err = Console.Error; 7199 sw = new StreamWriter(fs); 7200 Console.SetOut(sw); 7201 Console.SetError(sw); 7202 7203 stop(null); 7204 7205 Console.SetOut(old_out); 7206 Console.SetError(old_err); 7207 sw.Flush(); 7208 sw.Close(); 7209 7210 if (File.Exists(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log")) 7211 { 7212 File.Move(TMP.value + "\\" + SESSION_PATH_PREFIX.value + "cafestop_mion.log", LOGDIR.value + "\\cafestop1_mion.log"); 7213 } 7214 7215 if (CAFESTOP_STATUS.value != "0") 7216 { 7217 Console.WriteLine("cafex pcfs2nand: cafestop failure."); 7218 return 1; 7219 } 7220 7221 //success! 7222 Console.WriteLine("Removing log directory " + LOGDIR.value + "..."); 7223 ForceRemoveDirectory(LOGDIR.value); 7224 Console.WriteLine("cafex pcfs2nand complete. Exiting with code 0"); 7225 7226 return 0; 7227 } 7228 #endif 7229 7230 //Script function: hostcheckversion hostcheckversion()7231 static CAFEX_ERROR hostcheckversion() 7232 { 7233 #if DEBUG 7234 Log.WriteLine("hostcheckversion started."); 7235 #endif 7236 7237 getbridgetype(); 7238 7239 string min_fw_ver = string.Empty; 7240 string min_sw_ver = string.Empty; 7241 7242 if (BRIDGE_TYPE.value == "Mion") 7243 { 7244 min_fw_ver = MIN_MION_FW_VER; 7245 min_sw_ver = MIN_MION_SW_VER; 7246 } 7247 else 7248 { 7249 min_sw_ver = "2.9.1.5"; 7250 min_fw_ver = "2.8.0.13"; 7251 } 7252 7253 if (SDIO_BRIDGE_TOOLS.value == null) 7254 { 7255 if (MION_BRIDGE_TOOLS.value == null) 7256 { 7257 Console.WriteLine("cafex run failed: Please install HostBridge (version >= " + min_sw_ver + ") and reopen the build environment!"); 7258 return CAFEX_ERROR.HOSTCHECKVERSION_NO_HOSTBRIDGE; 7259 } 7260 } 7261 7262 if (fw_ver_flat == 0 || sw_ver_flat == 0) 7263 { 7264 string fw_ver = string.Empty; 7265 string sw_ver = string.Empty; 7266 7267 if (BRIDGE_TYPE.value == "Mion") 7268 { 7269 FSEmul.FW_SW_Version(BRIDGE_CURRENT_IP_ADDRESS.value, out fw_ver, out sw_ver); 7270 } 7271 else 7272 { 7273 FSEmul.FW_SW_Version(null, out fw_ver, out sw_ver); 7274 } 7275 7276 if (fw_ver == string.Empty || sw_ver == string.Empty) 7277 { 7278 Console.WriteLine("cafex run failed: Cannot check HostBridge version. Please stop the DEVKIT and try again."); 7279 return CAFEX_ERROR.HOSTCHECKVERSION_FSEMUL_FAILED; 7280 } 7281 7282 fw_ver_flat = compute_flat_version(fw_ver); 7283 sw_ver_flat = compute_flat_version(sw_ver); 7284 7285 CAFERUN_HOSTBRIDGE_VERSION.value = sw_ver; 7286 CAFERUN_FW_VERSION.value = fw_ver; 7287 } 7288 else 7289 { 7290 CAFERUN_HOSTBRIDGE_VERSION.value = compute_ver_string(sw_ver_flat); 7291 CAFERUN_FW_VERSION.value = compute_ver_string(fw_ver_flat); 7292 } 7293 7294 int min_fw_flat = compute_flat_version(min_fw_ver); 7295 int min_sw_flat = compute_flat_version(min_sw_ver); 7296 7297 if (sw_ver_flat < min_sw_flat || fw_ver_flat < min_fw_flat) 7298 { 7299 Console.WriteLine("cafex run failed: Please upgrade the HostBridge to at least version " + min_sw_ver + " and reopen the build environment!"); 7300 Console.WriteLine(" Current software version is " + CAFERUN_HOSTBRIDGE_VERSION.value + " (need " + min_sw_ver + ")"); 7301 Console.WriteLine(" Current firmware version is " + CAFERUN_FW_VERSION.value + " (need " + min_fw_ver + ")"); 7302 return CAFEX_ERROR.HOSTCHECKVERSION_OLD_VERSIONS; 7303 } 7304 7305 return CAFEX_ERROR.OK; 7306 } 7307 7308 //Script function: syncsession syncsession(string[] args)7309 static CAFEX_ERROR syncsession(string[] args) 7310 { 7311 #if DEBUG 7312 Log.WriteLine("syncsession started."); 7313 string argString = null; 7314 if (args != null) 7315 { 7316 foreach (string arg in args) 7317 { 7318 argString += arg + " "; 7319 } 7320 } 7321 Log.WriteLine("Arguments=" + argString); 7322 7323 #endif 7324 7325 if (args != null && args.Length > 0) 7326 { 7327 if (args[0] == "-h") 7328 { 7329 syncsession_usage(); 7330 return CAFEX_ERROR.OK; 7331 } 7332 else 7333 { 7334 Console.WriteLine("cafex syncsession failed: Invalid argument"); 7335 return CAFEX_ERROR.UPDATE_INVALID_OPTION; 7336 } 7337 } 7338 7339 if (SESSION_MANAGER.value == "1") 7340 { 7341 stop(null); 7342 7343 SYNCTOOL_SRC.value = PathConverter.Windowsify(Path.Combine(CAFE_ROOT.value, "data")); 7344 SYNCTOOL_DEST.value = PathConverter.Windowsify(CAFE_DATA_DIR.value); 7345 SYNCTOOL_CFG.value = PathConverter.Windowsify(Path.Combine(CAFE_ROOT.value, "system/bin/tool/synctool.data.xml")); 7346 SYNCTOOL_LOG.value = PathConverter.Windowsify(Path.Combine(CAFE_ROOT.value, SESSION_PATH_PREFIX.value + "sync.log")); 7347 7348 Console.WriteLine("cafex syncsession: Syncronizing {0} ===> {1}...", SYNCTOOL_SRC.value, SYNCTOOL_DEST.value); 7349 7350 int SYNCTOOL_RVAL = synctool.sync(SYNCTOOL_CFG.value, SYNCTOOL_SRC.value, SYNCTOOL_DEST.value, SYNCTOOL_LOG.value); 7351 if (SYNCTOOL_RVAL != 0) 7352 { 7353 Console.WriteLine(" : Session data sync FAILED with exit code {0}!", SYNCTOOL_RVAL); 7354 Console.WriteLine(" : See {0} for details.", SYNCTOOL_LOG.value); 7355 return CAFEX_ERROR.SYNCTOOL_FAILED; 7356 } 7357 else 7358 { 7359 Console.WriteLine(" : Session data sync log at {0}", SYNCTOOL_LOG.value); 7360 } 7361 } 7362 7363 return CAFEX_ERROR.OK; 7364 } 7365 getPathToMakeCfMaster()7366 private static String getPathToMakeCfMaster() 7367 { 7368 Assembly assembly = Assembly.GetExecutingAssembly(); 7369 String path = assembly.Location; 7370 String directory = Path.GetDirectoryName(path); 7371 String filename = directory + @"\makecfmaster.exe"; 7372 7373 if (File.Exists(filename)) 7374 return filename; 7375 7376 directory = Environment.GetEnvironmentVariable("CAFE_MASTERING_TOOLS"); 7377 if (directory != null) 7378 { 7379 filename = directory + @"\makecfmaster.exe"; 7380 7381 if (File.Exists(filename)) 7382 { 7383 return filename; 7384 } 7385 } 7386 7387 directory = Environment.GetEnvironmentVariable("CAFE_ROOT"); 7388 if (directory != null) 7389 { 7390 filename = directory + @"\system\bin\tool\mastering\makecfmaster.exe"; 7391 7392 if (File.Exists(filename)) 7393 { 7394 return filename; 7395 } 7396 } 7397 7398 return null; 7399 } 7400 processDataReceived(object sender, DataReceivedEventArgs args)7401 private static void processDataReceived(object sender, DataReceivedEventArgs args) 7402 { 7403 Console.WriteLine(args.Data); 7404 } 7405 makeMaster(string[] args)7406 static CAFEX_ERROR makeMaster(string[] args) 7407 { 7408 7409 #if DEBUG 7410 Log.WriteLine("master started."); 7411 string argString = null; 7412 if (args != null) 7413 { 7414 foreach (string arg in args) 7415 { 7416 argString += arg + " "; 7417 } 7418 } 7419 Log.WriteLine("Arguments=" + argString); 7420 7421 #endif 7422 Process p = new Process(); 7423 7424 p.StartInfo.FileName = getPathToMakeCfMaster(); 7425 p.StartInfo.Arguments = "archive " + string.Join(" ", args); 7426 p.StartInfo.CreateNoWindow = true; 7427 p.StartInfo.UseShellExecute = false; 7428 p.StartInfo.RedirectStandardOutput = true; 7429 p.StartInfo.RedirectStandardError = true; 7430 7431 try 7432 { 7433 p.Start(); 7434 7435 p.OutputDataReceived += processDataReceived; 7436 p.ErrorDataReceived += processDataReceived; 7437 7438 p.BeginOutputReadLine(); 7439 p.BeginErrorReadLine(); 7440 p.WaitForExit(); 7441 } 7442 catch (Win32Exception e) 7443 { 7444 Console.Write(e.Message); 7445 return CAFEX_ERROR.MASTERING_ERROR; 7446 } 7447 7448 Int64 returnVal = p.ExitCode; 7449 if (returnVal != 0) 7450 { 7451 Console.WriteLine("MAKE DISC ERROR!!! CODE: {0}", returnVal); 7452 CAFEX_ERROR masteringError = (CAFEX_ERROR)returnVal; 7453 return masteringError; 7454 } 7455 7456 return CAFEX_ERROR.OK; 7457 } 7458 7459 //this function emulates cafediscrun upto creation of 7460 //.dlf file. Then it calls cafeon with -c option to launch 7461 //the title through system config tool. 7462 //Steps: 7463 //1. Create dlf file 7464 //2. Make sure to append the <title.dlf> file to arguments to 7465 // FSEmul.exe 7466 //3. Call on with -c "launch -p -l <titleid>. You can get the title 7467 // id from app.xml of the title launchTitle(string[] args)7468 static CAFEX_ERROR launchTitle(string[] args) 7469 { 7470 CAFEX_ERROR result = CAFEX_ERROR.OK; 7471 #if DEBUG 7472 Log.WriteLine("makeDownload started."); 7473 string argString = null; 7474 if (args != null) 7475 { 7476 foreach (string arg in args) 7477 { 7478 argString += arg + " "; 7479 } 7480 } 7481 Log.WriteLine("Arguments=" + argString); 7482 7483 #endif 7484 string rpxPath = string.Empty; 7485 StringBuilder launchArgs = null; 7486 bool gotRpx = false; 7487 7488 execLaunchCmd = true; 7489 7490 if (args.Length > 1) 7491 { 7492 launchArgs = new StringBuilder(); 7493 } 7494 for (int i = 0; i < args.Length; i++) 7495 { 7496 string s = args[i]; 7497 if (!string.IsNullOrEmpty(s)) 7498 { 7499 if (!gotRpx && (s.StartsWith("-") || s.CompareTo("help") == 0)) 7500 { 7501 switch (s) 7502 { 7503 case "-h": 7504 case "-?": 7505 case "help": 7506 launch_usage(); 7507 return CAFEX_ERROR.OK; 7508 default: 7509 Console.WriteLine("cafex: Invalid parameter."); 7510 launch_usage(); 7511 return CAFEX_ERROR.MASTERING_ERROR; 7512 } 7513 } 7514 else if (s.Contains(".rpx")) //Must be path to the rpx file 7515 { 7516 rpxPath = s; 7517 gotRpx = true; 7518 } 7519 else //must be arguments for the rpx 7520 { 7521 launchArgs.Append(" " + s); 7522 } 7523 } 7524 } 7525 7526 if (string.IsNullOrEmpty(rpxPath)) 7527 { 7528 Console.WriteLine("cafex: Invalid parameter."); 7529 launch_usage(); 7530 return CAFEX_ERROR.MASTERING_ERROR; 7531 } 7532 7533 string winrpxPath = PathConverter.Windowsify(rpxPath); 7534 winrpxPath = PathConverter.Root(winrpxPath); 7535 winrpxPath = Path.GetFullPath(winrpxPath); 7536 //string rpxDir = winrpxPath.Substring(0, winrpxPath.LastIndexOf('\\')); 7537 //string rpxName = winrpxPath.Substring(winrpxPath.LastIndexOf('\\') + 1); 7538 //string rpxDLF = Path.ChangeExtension(winrpxPath, ".dlf"); 7539 //string rpxELF = Path.ChangeExtension(winrpxPath, ".elf"); 7540 7541 string rpxDir = Path.GetDirectoryName(winrpxPath); 7542 string rpxName = Path.GetFileName(winrpxPath); 7543 string rpxDLF = Path.ChangeExtension(winrpxPath, ".dlf"); 7544 string rpxELF = Path.ChangeExtension(winrpxPath, ".elf"); 7545 7546 //Below parameter must be set before we even start anything 7547 if (string.IsNullOrEmpty(CAFE_CODE_DIR.value)) 7548 { 7549 if (string.IsNullOrEmpty(CAFE_ELF_DIR.value)) 7550 { 7551 CAFE_ELF_DIR.value = rpxDir; 7552 } 7553 CAFE_CODE_DIR.value = CAFE_ELF_DIR.value; 7554 } 7555 7556 7557 //Run discrun to enable all the required setup variables 7558 //Note that we are only doing initialization and not launching the 7559 //application. 7560 string[] runArgs = 7561 { 7562 "-b", 7563 winrpxPath 7564 }; 7565 result = discrun(runArgs, true, false).error; 7566 if (result != CAFEX_ERROR.OK) 7567 { 7568 return result; 7569 } 7570 7571 //Make sure to remove "0x" from CAFERUN_COLDBOOT_OS_VERSION.value 7572 if (CAFERUN_COLDBOOT_OS_VERSION.value.Contains("0x")) 7573 { 7574 CAFERUN_COLDBOOT_OS_VERSION.value = CAFERUN_COLDBOOT_OS_VERSION.value.Substring(2); 7575 } 7576 7577 //Make ppc_boot.dlf and fw.img file which is needed to run system config tool 7578 result = bootrun(new List<string> { "-makedlf" }, false); 7579 if (result != CAFEX_ERROR.OK) 7580 { 7581 Console.WriteLine("cafex: Failed to run bootrun."); 7582 return result; 7583 } 7584 7585 //Make dlf file and store it in the same directory as the rpx 7586 //The dlf generated here will be passed to FSEmul to mounting the title on ODD 7587 result = devrun(rpxELF, null, null, null); 7588 if (result != CAFEX_ERROR.OK) 7589 { 7590 Console.WriteLine("cafex: Failed to run devrun."); 7591 return result; 7592 } 7593 7594 if (string.IsNullOrEmpty(BOOT_DLF_FILE.value)) 7595 { 7596 BOOT_DLF_FILE.value = CAFE_TEMP.value + "\\" + SESSION_PATH_PREFIX.value + "caferun" + "\\ppc_boot.dlf"; 7597 } 7598 7599 //Make sure SOFT_LUANCH is disabled 7600 CAFERUN_OPTION_SOFT_LAUNCH.value = "0"; 7601 7602 7603 //call hostrun to launch FSEMUL 7604 hostrun(BOOT_DLF_FILE.value + " " + rpxDLF); 7605 7606 extract_info_from_app_xml(rpxDir + "\\app.xml"); 7607 7608 LAUNCH_DLF_FILE = rpxDLF; 7609 string[] onArgs = 7610 { 7611 "-c launch -p -l 0x" + APP_TITLE_ID.value + ((launchArgs != null) ? launchArgs.ToString():string.Empty) 7612 }; 7613 7614 on(onArgs, false, true); 7615 return CAFEX_ERROR.OK; 7616 } 7617 #endregion 7618 7619 #region SCRIPT HELPERS 7620 initialize_work_directory(string directory)7621 static void initialize_work_directory(string directory) 7622 { 7623 #if DEBUG 7624 Log.WriteLine("initialize_work_diretory started."); 7625 #endif 7626 7627 if (!Directory.Exists(directory)) 7628 { 7629 Directory.CreateDirectory(directory); 7630 } 7631 7632 File.Delete(directory + "\\diskid.bin"); 7633 File.Delete(directory + "\\ppc.bsf"); 7634 File.Delete(directory + "\\ppc_boot.dlf"); 7635 } 7636 make_boot1_system_file(string bsf_file)7637 static CAFEX_ERROR make_boot1_system_file(string bsf_file) 7638 { 7639 #if DEBUG 7640 Log.WriteLine("make_boot1_system_file started."); 7641 #endif 7642 7643 string flags = "0"; 7644 7645 string firmware_filename = Path.GetFileName(FIRMWARE_FILE.value); 7646 if (firmware_filename.StartsWith("fw")) 7647 { 7648 flags = "0x80000000"; 7649 } 7650 7651 if (makebsf.make(QUIET.value, bsf_file, flags) != 0) 7652 { 7653 Console.WriteLine("cafex bootrun failed: Cannot generate bsf file."); 7654 return CAFEX_ERROR.BOOTRUN_MAKEBSF_FAILED; 7655 } 7656 7657 return CAFEX_ERROR.OK; 7658 } 7659 make_boot_dlf(string file_list, string output_dlf_file)7660 static CAFEX_ERROR make_boot_dlf(string file_list, string output_dlf_file) 7661 { 7662 #if DEBUG 7663 Log.WriteLine("make_boot_dlf started."); 7664 #endif 7665 7666 string commandResult = string.Empty; 7667 if (makedlf.make(QUIET.value, file_list, output_dlf_file, out commandResult) != 0) 7668 { 7669 Console.WriteLine("cafex bootrun failed: Cannot generate dlf file."); 7670 Console.WriteLine("Command output: " + commandResult); 7671 return CAFEX_ERROR.BOOTRUN_MAKEDLF_FAILED; 7672 } 7673 7674 return CAFEX_ERROR.OK; 7675 } 7676 make_wumad_dlf(string wumadFile, string extractionFolder, string output_dlf_file)7677 static CAFEX_ERROR make_wumad_dlf(string wumadFile, string extractionFolder, string output_dlf_file) 7678 { 7679 #if DEBUG 7680 Log.WriteLine("make_wumad_dlf started. Arguments: wumadFile=" + wumadFile + ", extractionFolder=" + extractionFolder + ", output_dlf_file=" + output_dlf_file); 7681 #endif 7682 7683 if (makewumaddlf.make(wumadFile, extractionFolder, output_dlf_file) != 0) 7684 { 7685 Console.WriteLine("cafex bootrun failed: Cannot generate dlf file from WUMAD."); 7686 return CAFEX_ERROR.BOOTRUN_MAKEDLF_FAILED; 7687 } 7688 7689 return CAFEX_ERROR.OK; 7690 } 7691 extract_info_from_app_xml(string app_xml_file)7692 static void extract_info_from_app_xml(string app_xml_file) 7693 { 7694 #if DEBUG 7695 Log.WriteLine("extract_info_from_app_xml started."); 7696 #endif 7697 7698 APP_TITLE_ID.value = XmlHandler.GetNodeValue(app_xml_file, "title_id"); 7699 APP_GROUP_ID.value = XmlHandler.GetNodeValue(app_xml_file, "group_id"); 7700 APP_TITLE_VERSION.value = XmlHandler.GetNodeValue(app_xml_file, "title_version"); 7701 7702 Console.WriteLine("App Title ID : " + APP_TITLE_ID.value); 7703 Console.WriteLine("App Group ID : " + APP_GROUP_ID.value); 7704 Console.WriteLine("App Title Version : " + APP_TITLE_VERSION.value); 7705 } 7706 connect_serial_or_debugger(bool quiet_mode)7707 static CafeXReturn connect_serial_or_debugger(bool quiet_mode) 7708 { 7709 #if DEBUG 7710 Log.WriteLine("connect_serial_or_debugger started. quiet_mode=" + quiet_mode.ToString() + ", DEBUGGER=" + DEBUGGER.value); 7711 #endif 7712 7713 switch (DEBUGGER.value) 7714 { 7715 case "multi": 7716 { 7717 break; 7718 } 7719 7720 case "gdb": 7721 case "gdbtui": 7722 { 7723 cattoucan.FinishSync(true); 7724 if (FileUtil.RunningFromCygwin && DEBUGGER.value == "gdb") 7725 { 7726 Console.WriteLine("cafex run error: gdb debugger is not compatible with cafex."); 7727 Console.WriteLine("Please disable cafex with \"export USE_CAFEX=0\" and run the command with BASH caferun."); 7728 } 7729 else 7730 { 7731 Console.WriteLine("cafex run error: Only Multi debugger supported"); 7732 } 7733 7734 return new CafeXReturn(CAFEX_ERROR.RUN_NON_MULTI_DEBUGGER); 7735 } 7736 7737 case "cattoucan": 7738 { 7739 CafeXReturn ret = new CafeXReturn(CAFEX_ERROR.OK); 7740 ret.appExitCode = cattoucan.start(no_console, false); 7741 7742 return ret; 7743 } 7744 7745 case "none": 7746 { 7747 cattoucan.FinishSync(true); 7748 if (CONSOLE.value != "toucan") 7749 { 7750 CAFE_DEBUG_PORT.value = "toucan"; 7751 } 7752 return new CafeXReturn(CAFEX_ERROR.OK); 7753 } 7754 7755 default: 7756 { 7757 cattoucan.FinishSync(true); 7758 Console.WriteLine("cafex run failed: " + DEBUGGER.value + " unsupported debugger."); 7759 return new CafeXReturn(CAFEX_ERROR.RUN_BAD_DEBUGGER); 7760 } 7761 } 7762 7763 if (CAFE_DEBUG_PORT.value != "toucan") 7764 { 7765 cattoucan.FinishSync(true); 7766 Console.WriteLine("cafex run failed: Unknown debugger port " + CAFE_DEBUG_PORT.value); 7767 return new CafeXReturn(CAFEX_ERROR.RUN_BAD_DEBUGGER_PORT); 7768 } 7769 7770 #if DEBUG 7771 Log.WriteLine("DEBUGGER = multi"); 7772 #endif 7773 MULTIELF.value = ""; 7774 if (DEBUG_ELF_FILE.value != null) 7775 { 7776 // Make sure the MULTIELF has windows-style path 7777 MULTIELF.value = PathConverter.Windowsify(DEBUG_ELF_FILE.value); 7778 } 7779 7780 CATTOUCAN_STATUS.value = cattoucan.start(no_console, false).ToString(); 7781 7782 if (string.IsNullOrEmpty(MULTI_CONNECT.value)) 7783 { 7784 if (USE_EXI_AS_DEBUG_CHANNEL.value != null && USE_EXI_AS_DEBUG_CHANNEL.value.Equals("1")) 7785 { 7786 MULTI_CONNECT.value = "\"-connect=cafeserv -iphost " + BRIDGE_CURRENT_IP_ADDRESS.value + " -console_iphost localhost -ipport 7977 -console_ipport " + SESSION_DEBUG_OUT_PORT.value + " -auto_first\""; 7787 } 7788 else 7789 { 7790 MULTI_CONNECT.value = "\"-connect=cafeserv -iphost localhost -ipport " + SESSION_DEBUG_CONTROL_PORT.value + " -console_ipport " + SESSION_DEBUG_OUT_PORT.value + " -auto_first\""; 7791 } 7792 } 7793 7794 #if DEBUG 7795 Log.WriteLine("MULTI_CONNECT before calling multi = " + MULTI_CONNECT.value); 7796 Log.WriteLine("CATTOUCAN_STATUS.value = " + CATTOUCAN_STATUS.value); 7797 Log.WriteLine("CAFE_LAUNCH_DEBUG.value = " + CAFE_LAUNCH_DEBUG.value); 7798 #endif 7799 7800 if (CATTOUCAN_STATUS.value == "42") 7801 { 7802 if (CAFE_LAUNCH_DEBUG.value == "1") 7803 { 7804 multi.start(MULTI_CONNECT.value, CAFE_MULTI_INIT.value, MULTIELF.value); 7805 } 7806 else 7807 { 7808 Console.WriteLine("Ready to connect from multi"); 7809 Console.WriteLine(GHS_ROOT.value + "\\multi.exe -cmd prepare_target " + MULTI_CONNECT.value + " " + CAFE_MULTI_INIT.value + " " + MULTIELF.value); 7810 } 7811 7812 if (CMDOUTPUT.value == "1") 7813 { 7814 #if DEBUG 7815 Log.WriteLine("CMDOUTPUT = 1 -> calling cattoucan.start..."); 7816 #endif 7817 7818 cattoucan.start(no_console, false); 7819 } 7820 } 7821 #if DEBUG 7822 Log.WriteLine("connect_serial_or_debugger completed."); 7823 #endif 7824 return new CafeXReturn(CAFEX_ERROR.OK); 7825 7826 } 7827 initialize_serial_port_and_directory(string stop_cmd)7828 static int initialize_serial_port_and_directory(string stop_cmd) 7829 { 7830 #if DEBUG 7831 Log.WriteLine("initialize_serial_port_and_directory started."); 7832 #endif 7833 7834 if (stop_cmd == null) 7835 { 7836 Console.WriteLine("\"Usage: Initialize_serial_port_and_directory stop_cmd\", where stop_cmd is cafestop or a bash function call."); 7837 return 1; 7838 } 7839 7840 create_directory_if_noexist(LOGDIR.value); 7841 7842 if (stop_cmd == "cafestop") 7843 { 7844 stop(null); 7845 } 7846 7847 //trap 7848 7849 if (CAFE_CONSOLE.value == "cattoucan") 7850 { 7851 //trap 7852 CAFE_CONSOLE.value = "toucan"; 7853 } 7854 7855 if (CAFE_CONSOLE.value == "cmdtoucan") 7856 { 7857 //trap 7858 CAFE_CONSOLE.value = "toucan"; 7859 } 7860 7861 if (CAFE_CONSOLE.value == "catwaikiki") 7862 { 7863 //trap 7864 CAFE_CONSOLE.value = "waikiki"; 7865 } 7866 7867 #if DEBUG 7868 Log.WriteLine("CAFE_CONSOLE=" + CAFE_CONSOLE.value); 7869 #endif 7870 7871 if (COMPORTS_SUPPORT.value == "-c") 7872 { 7873 int init_flag = 0; 7874 INITIALIZED_COMPORTS.value = ""; 7875 7876 for (int COMPORT = 1; COMPORT <= 20; ++COMPORT) 7877 { 7878 if (cmd.mode(COMPORT) == 0) 7879 { 7880 Console.WriteLine("Initialized COM" + COMPORT); 7881 init_flag = 1; 7882 INITIALIZED_COMPORTS.AddToVar("COM" + COMPORT + " ", ' '); 7883 } 7884 } 7885 7886 if (init_flag == 0 && CAFE_CONSOLE.value != "toucan") 7887 { 7888 Console.WriteLine("ERROR: no serial port is available."); 7889 Console.WriteLine("Please close other softwares using serial port,"); 7890 Console.WriteLine("such as HyperTerminal."); 7891 Console.WriteLine(); 7892 Console.WriteLine("This automated test script cannot share the serial port"); 7893 Console.WriteLine("with other softwares."); 7894 return 1; 7895 } 7896 } 7897 7898 return 0; 7899 } 7900 monitor_for_output(string str_opt, string test_str, string timeout, string log_dir, string file_name, bool printToScreen)7901 static int monitor_for_output(string str_opt, string test_str, string timeout, string log_dir, string file_name, bool printToScreen) 7902 { 7903 #if DEBUG 7904 Log.WriteLine("monitor_for_output started."); 7905 #endif 7906 7907 create_directory_if_noexist(log_dir); 7908 7909 if (MONITOR_FOR_OUTPUT_CALLS.value == null) 7910 { 7911 MONITOR_FOR_OUTPUT_CALLS.value = "0"; 7912 } 7913 7914 MONITOR_FOR_OUTPUT_CALLS.value = (HexHandler.GetNumberFromString(MONITOR_FOR_OUTPUT_CALLS.value) + 1).ToString(); 7915 string call_no = MONITOR_FOR_OUTPUT_CALLS.value; 7916 string mon_rc_file = log_dir + "\\monitor_return_code" + call_no + ".txt"; 7917 7918 if (file_name == null) 7919 { 7920 file_name = "monitor_" + call_no + ".txt"; 7921 } 7922 7923 string log_file = log_dir + "\\" + file_name; 7924 7925 // Write to the log file all the output and print to the screen, if printToScreen is true. 7926 FileStream fs = new FileStream(log_file, FileMode.Create); 7927 StreamWriter sw = new StreamWriter(fs); 7928 DataReceivedEventHandler callback = (sender, e) => 7929 { 7930 if (e != null && e.Data != null && sw != null) 7931 { 7932 string outputData = e.Data; 7933 if (printToScreen) 7934 { 7935 Console.WriteLine(outputData); 7936 } 7937 try 7938 { 7939 sw.WriteLine(outputData); 7940 sw.Flush(); 7941 } 7942 catch (IOException) 7943 { } 7944 catch (ObjectDisposedException) 7945 { } 7946 } 7947 }; 7948 7949 int retVal = monitor_for_output_redirectionCallback(str_opt, test_str, timeout, callback); 7950 7951 sw.Close(); 7952 7953 fs = new FileStream(mon_rc_file, FileMode.Create); 7954 sw = new StreamWriter(fs); 7955 sw.WriteLine(retVal); 7956 sw.Flush(); 7957 sw.Close(); 7958 7959 return retVal; 7960 } 7961 monitor_for_output_redirectionCallback(string str_opt, string test_str, string timeout, DataReceivedEventHandler callback)7962 static int monitor_for_output_redirectionCallback(string str_opt, string test_str, string timeout, DataReceivedEventHandler callback) 7963 { 7964 #if DEBUG 7965 Log.WriteLine("monitor_for_output_redirectionCallback started."); 7966 #endif 7967 7968 string ret = monitor.start_redirectionCallback(str_opt, test_str, timeout, callback).ToString(); 7969 7970 int return_val = evaluate_monitor_return_value(ret); 7971 if (return_val == 0) 7972 { 7973 Console.WriteLine("monitor returned PASS"); 7974 } 7975 else 7976 { 7977 return return_val; 7978 } 7979 7980 return 0; 7981 } 7982 evaluate_monitor_return_value(string mon_rval)7983 static int evaluate_monitor_return_value(string mon_rval) 7984 { 7985 #if DEBUG 7986 Log.WriteLine("evaluate_monitor_return_value started."); 7987 #endif 7988 7989 int return_val = 1; 7990 string status_str = string.Empty; 7991 7992 if (mon_rval == MON_RESULT_PASS.value) 7993 { 7994 return_val = 0; 7995 } 7996 7997 else if (mon_rval == MON_RESULT_TIMEOUT.value) 7998 { 7999 status_str = "TIMEOUT"; 8000 } 8001 8002 else if (mon_rval == MON_RESULT_UNDEF.value) 8003 { 8004 status_str = "UNDEF"; 8005 } 8006 8007 else if (mon_rval == MON_RESULT_MANUAL.value) 8008 { 8009 status_str = "MANUAL"; 8010 } 8011 8012 else if (mon_rval == MON_RESULT_NOLOG.value) 8013 { 8014 status_str = "NOLOG"; 8015 } 8016 8017 else if (mon_rval == MON_RESULT_FAIL.value) 8018 { 8019 status_str = "FAIL"; 8020 } 8021 8022 else if (mon_rval == MON_RESULT_EXPECTED_TERM.value) 8023 { 8024 status_str = "EXPECTED_TERM"; 8025 } 8026 8027 else if (mon_rval == MON_RESULT_EXEC_WIN_APP.value) 8028 { 8029 status_str = "EXEC_WIN_APP"; 8030 } 8031 8032 else if (mon_rval == MON_RESULT_NOPPC.value) 8033 { 8034 status_str = "NOPPC"; 8035 } 8036 8037 else if (mon_rval == MON_RESULT_BOOT1.value) 8038 { 8039 status_str = "BOOT1"; 8040 } 8041 8042 else if (mon_rval == MON_RESULT_RESTART.value) 8043 { 8044 status_str = "RESTART"; 8045 } 8046 8047 else if (mon_rval == MON_RESULT_TEST_AS_RPL.value) 8048 { 8049 status_str = "TEST_AS_RPL"; 8050 } 8051 8052 else if (mon_rval == MON_RESULT_END_OF_RPL_LOADER.value) 8053 { 8054 status_str = "END_OF_RPL_LOADER"; 8055 } 8056 8057 else if (mon_rval == MON_RESULT_BRIDGE_COLLISION.value) 8058 { 8059 status_str = "BRIDGE_COLLISION"; 8060 } 8061 8062 else if (mon_rval == MON_RESULT_TEST_DBG_OUT.value) 8063 { 8064 status_str = "TEST_DBG_OUT"; 8065 } 8066 8067 else if (mon_rval == MON_RESULT_BRIDGE_OFF.value) 8068 { 8069 status_str = "BRIDGE_OFF"; 8070 } 8071 8072 else if (mon_rval == MON_RESULT_ERROR.value) 8073 { 8074 status_str = "ERROR"; 8075 } 8076 8077 else if (mon_rval == MON_RESULT_FATAL_ERROR.value) 8078 { 8079 status_str = "FATAL_ERROR"; 8080 } 8081 8082 else if (mon_rval == MON_RESULT_MISSING.value) 8083 { 8084 status_str = "MISSING"; 8085 } 8086 8087 else if (mon_rval == MON_RESULT_ABORTED.value) 8088 { 8089 status_str = "ABORTED"; 8090 } 8091 8092 else 8093 { 8094 status_str = mon_rval.ToString(); 8095 } 8096 8097 if (return_val != 0) 8098 { 8099 Console.WriteLine("monitor returned " + status_str); 8100 return return_val; 8101 } 8102 8103 return 0; 8104 } 8105 check_xml_version(string file_dest, string file_default, string file_option)8106 static bool check_xml_version(string file_dest, string file_default, string file_option) 8107 { 8108 #if DEBUG 8109 Log.WriteLine("check_xml_version started."); 8110 #endif 8111 8112 if (!File.Exists(file_dest)) 8113 { 8114 Console.WriteLine("cafex run: Copying default config file to " + file_dest); 8115 if (!File.Exists(file_default)) 8116 { 8117 Console.WriteLine("cafex run failed: Cannot find default config file " + file_default); 8118 return false; 8119 } 8120 8121 create_directory_if_noexist(Path.GetDirectoryName(file_dest)); 8122 8123 File.Copy(file_default, file_dest, true); 8124 File.SetAttributes(file_dest, FileAttributes.Normal); 8125 } 8126 else 8127 { 8128 string ver_default = XmlHandler.GetNodeValue(file_default, "version"); 8129 string ver_dest = XmlHandler.GetNodeValue(file_dest, "version"); 8130 #if DEBUG 8131 Log.WriteLine("file_dest: " + file_dest + ", ver_default: " + ver_default + " - ver_dest: " + ver_dest); 8132 #endif 8133 if (ver_dest == null || ver_default == null) 8134 { 8135 Console.WriteLine("cafex run failed: Cannot get xml version numbers"); 8136 return false; 8137 } 8138 8139 if (IGNORE_VERSION.value == null) 8140 { 8141 if (ver_dest != ver_default) 8142 { 8143 if (file_option == "copy_default_if_mismatch") 8144 { 8145 Console.WriteLine("cafex run: Config file version mismatch detected: " + ver_dest + " vs. required " + ver_default); 8146 Console.WriteLine(" Copying default config file to " + file_dest); 8147 if (!File.Exists(file_default)) 8148 { 8149 Console.WriteLine("cafex run failed: Cannot find default config file " + file_default); 8150 return false; 8151 } 8152 8153 create_directory_if_noexist(Path.GetDirectoryName(file_dest)); 8154 8155 File.Copy(file_default, file_dest, true); 8156 File.SetAttributes(file_dest, FileAttributes.Normal); 8157 } 8158 else 8159 { 8160 Console.WriteLine("cafex run failed: Please update or delete config file: " + file_dest); 8161 Console.WriteLine(" Version number mismatch: " + ver_dest + " vs. required " + ver_default); 8162 return false; 8163 } 8164 } 8165 } 8166 } 8167 8168 return true; 8169 } 8170 args_to_bar_sep_list(string[] input)8171 static string args_to_bar_sep_list(string[] input) 8172 { 8173 return StringCombiner.MakeDelimitedString(input, '|'); 8174 } 8175 exit_if_specials(string[] arglist)8176 static bool exit_if_specials(string[] arglist) 8177 { 8178 #if DEBUG 8179 Log.WriteLine("exit_if_specials started."); 8180 #endif 8181 8182 foreach (string s in arglist) 8183 { 8184 if (s.Contains("?") || s.Contains("+") || s.Contains("<") || s.Contains(">") || s.Contains("|")) 8185 { 8186 Console.WriteLine("cafex run failed: Unable to parse special character (?+<>|) in arg list."); 8187 Console.WriteLine(" arglist: " + s); 8188 return false; 8189 } 8190 } 8191 return true; 8192 } 8193 update_arglist(string file_dest, string cafe_elf, string[] arglist)8194 static bool update_arglist(string file_dest, string cafe_elf, string[] arglist) 8195 { 8196 #if DEBUG 8197 Log.WriteLine("update_arglist started."); 8198 #endif 8199 8200 string[] arglist_without_rpx = new string[arglist.Length - 1]; 8201 Array.Copy(arglist, 1, arglist_without_rpx, 0, arglist_without_rpx.Length); 8202 8203 bool exit_if_specials_ret = exit_if_specials(arglist_without_rpx); 8204 if (!exit_if_specials_ret) 8205 { 8206 return false; 8207 } 8208 8209 string args_trailing_with_bars = args_to_bar_sep_list(arglist_without_rpx); 8210 8211 if (DASH_A_ARGS.value == null) 8212 { 8213 ARGS_WITH_BARS.value = args_trailing_with_bars; 8214 } 8215 else 8216 { 8217 ARGS_WITH_BARS.value = DASH_A_ARGS.value.Replace(',', '|'); 8218 if (args_trailing_with_bars != string.Empty) 8219 { 8220 ARGS_WITH_BARS.value = ARGS_WITH_BARS.value + "|" + args_trailing_with_bars; 8221 } 8222 } 8223 8224 string args_with_bars_no_quotes = string.Empty; 8225 //if (ARGS_WITH_BARS.value != null) 8226 //{ 8227 // args_with_bars_no_quotes = ARGS_WITH_BARS.value.Replace("\"", "\\\""); 8228 //} 8229 //else 8230 //{ 8231 // args_with_bars_no_quotes = ARGS_WITH_BARS.value; 8232 //} 8233 8234 args_with_bars_no_quotes = ARGS_WITH_BARS.value; 8235 8236 8237 string total_arglist = Path.GetFileName(cafe_elf); 8238 if (args_with_bars_no_quotes != string.Empty) 8239 { 8240 total_arglist += "|" + args_with_bars_no_quotes; 8241 } 8242 8243 string total_arglist_with_qs = total_arglist.Replace(' ', '?'); 8244 total_arglist_with_qs = total_arglist_with_qs.Replace('|', ' '); 8245 8246 // Check argument length to make sure it is less than 4096. 8247 if (!string.IsNullOrEmpty(total_arglist_with_qs) && total_arglist_with_qs.Length > CAFE_ARGSTR_MAX_LENGTH) 8248 { 8249 Console.WriteLine("cafex run failed: argument length is greater than 4096 characters. Please shorten and retry."); 8250 return false; 8251 } 8252 8253 XmlHandler.UpdateNodeValue(file_dest, "argstr", total_arglist_with_qs); 8254 8255 return true; 8256 } 8257 update_system_xml(string file_dest, string cmd_flags, string system_mode, string sys_xml_mcp_launch_hint)8258 static CAFEX_ERROR update_system_xml(string file_dest, string cmd_flags, string system_mode, string sys_xml_mcp_launch_hint) 8259 { 8260 #if DEBUG 8261 Log.WriteLine("update_system_xml started."); 8262 #endif 8263 8264 Int64 iTitleID = 0; 8265 string sys_default_xml = CAFE_ROOT.value + "\\system\\bin\\ghs\\cafe\\boot\\system_default.xml"; 8266 8267 if (!check_xml_version(file_dest, sys_default_xml, "copy_default_if_mismatch")) 8268 { 8269 return CAFEX_ERROR.UNEXPECTED; 8270 } 8271 8272 string old_system_mode_num = XmlHandler.GetNodeValue(file_dest, "dev_mode"); 8273 string[] system_mode_name_table = new string[4]; 8274 system_mode_name_table[0] = "PROD"; 8275 system_mode_name_table[1] = "DEV"; 8276 system_mode_name_table[2] = "TEST"; 8277 system_mode_name_table[3] = "Unknown"; 8278 8279 if (old_system_mode_num != "0" && old_system_mode_num != "1" && old_system_mode_num != "2") 8280 { 8281 old_system_mode_num = "3"; 8282 } 8283 8284 string new_system_mode_num = "3"; 8285 if (system_mode == "dev") 8286 { 8287 new_system_mode_num = "1"; 8288 } 8289 else if (system_mode == "test") 8290 { 8291 new_system_mode_num = "2"; 8292 } 8293 else 8294 { 8295 if (system_mode == "prod") 8296 { 8297 Console.WriteLine("cafex run Warning: Changing to PROD mode is not supported."); 8298 Console.WriteLine(" Please specify '-M dev' or '-M test'."); 8299 } 8300 else if (system_mode != null) 8301 { 8302 Console.WriteLine("cafex run Warning: Invalid system mode is specified."); 8303 } 8304 8305 if (old_system_mode_num != "3") 8306 { 8307 new_system_mode_num = old_system_mode_num; 8308 } 8309 else 8310 { 8311 new_system_mode_num = "1"; 8312 Console.WriteLine("cafex run: System mode is broken. Fixing it to DEV"); 8313 } 8314 } 8315 8316 if (CAFE_BOOT_MODE.value == "PCFS") 8317 { 8318 if (new_system_mode_num != old_system_mode_num) 8319 { 8320 Console.WriteLine("cafex run: Changing system mode " + system_mode_name_table[HexHandler.GetNumberFromString(old_system_mode_num)] + " to " + system_mode_name_table[HexHandler.GetNumberFromString(new_system_mode_num)]); 8321 XmlHandler.UpdateNodeValue(file_dest, "dev_mode", new_system_mode_num); 8322 } 8323 else 8324 { 8325 Console.WriteLine("cafex run: Current system mode is " + system_mode_name_table[HexHandler.GetNumberFromString(new_system_mode_num)]); 8326 } 8327 if (!String.IsNullOrEmpty(CAFE_TEST_SELF_REFRESH.value)) 8328 { 8329 XmlHandler.UpdateNodeValueByPath(file_dest, "//standby/enable", "1"); 8330 } 8331 } 8332 8333 if (CAFERUN_OPTION_MLC_EMU_LAUNCH.value == "1") 8334 { 8335 string mlc_emu_tid_hi = CAFERUN_OPTION_MLC_EMU_TITLEID.value.Substring(2, 8); 8336 string mlc_emu_tid_lo = CAFERUN_OPTION_MLC_EMU_TITLEID.value.Substring(10, 8); 8337 8338 string mlc_emu_title_dir = string.Empty; 8339 if (mlc_emu_tid_hi == "00050010") 8340 { 8341 mlc_emu_title_dir = CAFE_MLC_DIR.value + "\\sys\\title\\" + mlc_emu_tid_hi + "\\" + mlc_emu_tid_lo; 8342 } 8343 else 8344 { 8345 mlc_emu_title_dir = CAFE_MLC_DIR.value + "\\usr\\title\\" + mlc_emu_tid_hi + "\\" + mlc_emu_tid_lo; 8346 } 8347 8348 if (File.Exists(mlc_emu_title_dir + "\\code\\app.xml")) 8349 { 8350 string mlc_emu_os_version = XmlHandler.GetNodeValue(mlc_emu_title_dir + "\\code\\app.xml", "os_version"); 8351 CAFERUN_COLDBOOT_OS_VERSION.value = String.Format("{0:x16}", mlc_emu_os_version); 8352 } 8353 else 8354 { 8355 if (DISC_EMU_TYPE.value != "hdd" && ALLOW_DISCRUN_IN_SOFTLAUNCH.value == "0") 8356 { 8357 Console.WriteLine("cafex run failed: Cannot find title 0x" + mlc_emu_tid_hi + mlc_emu_tid_lo + " on MLC emulation"); 8358 Console.WriteLine(" Please cafeinstall before using -t option"); 8359 return CAFEX_ERROR.RUN_TITLE_ID_NOT_FOUND_IN_MLC; 8360 } 8361 } 8362 8363 // Convert the title_id from a string to a number for lookup later 8364 iTitleID = Convert.ToInt64(mlc_emu_tid_hi + mlc_emu_tid_lo, 16); 8365 8366 XmlHandler.UpdateNodeValue(file_dest, "default_title_id", mlc_emu_tid_hi + mlc_emu_tid_lo); 8367 } 8368 else 8369 { 8370 if (APP_XML_FILE.value != null) 8371 { 8372 DISC_EMU_TID.value = XmlHandler.GetNodeValue(APP_XML_FILE.value, "title_id"); 8373 8374 // Convert the title_id from a string to a number for lookup later 8375 iTitleID = Convert.ToInt64(DISC_EMU_TID.value, 16 ); 8376 8377 XmlHandler.UpdateNodeValue(file_dest, "default_title_id", DISC_EMU_TID.value); 8378 } 8379 else 8380 { 8381 if (DISC_EMU_TYPE.value == "hdd" && string.IsNullOrEmpty(CAFE_WUMAD.value)) 8382 { 8383 Console.WriteLine(); 8384 Console.WriteLine("-------"); 8385 Console.WriteLine("cafex run WARNING: Title ID is not specified."); 8386 Console.WriteLine(" Use -t option to specify Title ID of application on HDD."); 8387 Console.WriteLine(" Title ID of previously launched app will be used at this time,"); 8388 Console.WriteLine(" but launch may fail if it was different from that of application on HDD."); 8389 Console.WriteLine("-------"); 8390 Console.WriteLine(); 8391 } 8392 } 8393 } 8394 8395 if (APP_XML_FILE.value != null) 8396 { 8397 string disc_emu_app_type = XmlHandler.GetNodeValue(APP_XML_FILE.value, "app_type"); 8398 8399 if (fAppTypeDefined) 8400 { 8401 // AppType override was defined on the command line so use that instead of calculating based on TitleID 8402 disc_emu_app_type = CAFERUN_APP_TYPE.value; 8403 XmlHandler.UpdateNodeValue(file_dest, "default_app_type", disc_emu_app_type); 8404 } 8405 else 8406 { 8407 string calculated_disc_emu_app_type = FindAppType(iTitleID); // Find the app type based on the title ID 8408 if (disc_emu_app_type.CompareTo(calculated_disc_emu_app_type) != 0) 8409 { 8410 Console.WriteLine("WARNING: Calculated AppType does not match what was in APP.XML"); 8411 Console.WriteLine("Overwriting with the calculated value for AppType"); 8412 } 8413 disc_emu_app_type = calculated_disc_emu_app_type; 8414 XmlHandler.UpdateNodeValue(file_dest, "default_app_type", disc_emu_app_type); 8415 } 8416 } 8417 else 8418 { 8419 // There might not be an app.xml but we still want to change the default_app_type with what the user specified with -T 8420 if (fAppTypeDefined) 8421 { 8422 // AppType override was defined on the command line so use that instead of calculating based on TitleID 8423 XmlHandler.UpdateNodeValue(file_dest, "default_app_type", CAFERUN_APP_TYPE.value); 8424 } 8425 else 8426 { 8427 string calculated_disc_emu_app_type = FindAppType(iTitleID); // Find the app type based on the title ID 8428 XmlHandler.UpdateNodeValue(file_dest, "default_app_type", calculated_disc_emu_app_type); 8429 } 8430 } 8431 8432 if (CAFERUN_OPTION_SOFT_RESTART.value == "0") 8433 { 8434 XmlHandler.UpdateNodeValue(file_dest, "cmdFlags", cmd_flags); 8435 } 8436 8437 XmlHandler.UpdateNodeValue(file_dest, "default_os_id", CAFERUN_COLDBOOT_OS_VERSION.value); 8438 8439 if (sys_xml_mcp_launch_hint != null) 8440 { 8441 bool node_exists = XmlHandler.NodeExists(file_dest, "default_device_type"); 8442 if (!node_exists) 8443 { 8444 XmlHandler.AddNode(file_dest, "default_device_type", sys_xml_mcp_launch_hint, new string[4] { "type", "string", "length", "16" }); 8445 } 8446 else 8447 { 8448 XmlHandler.UpdateNodeValue(file_dest, "default_device_type", sys_xml_mcp_launch_hint); 8449 } 8450 } 8451 else 8452 { 8453 XmlHandler.RemoveNode(file_dest, "default_device_type"); 8454 } 8455 8456 return CAFEX_ERROR.OK; 8457 } 8458 set_system_xml_cos_flags(string ppc_os_flags)8459 static int set_system_xml_cos_flags(string ppc_os_flags) 8460 { 8461 #if DEBUG 8462 Log.WriteLine("setting cos_flags:" + ppc_os_flags); 8463 #endif 8464 string file_dest = CAFE_SLC_DIR.value + "\\sys\\config\\system.xml"; 8465 int ret = 0; 8466 XmlHandler.UpdateNodeValue(file_dest, "cmdFlags", ppc_os_flags); 8467 ret = devkitmsg.CosFlags(ppc_os_flags); 8468 if (ret != 0) 8469 { 8470 Console.WriteLine("devkitmsg \"cos_flags " + ppc_os_flags + "\" - failed result = " + ret); 8471 } 8472 return ret; 8473 } 8474 update_app_xml(string file_dest)8475 static bool update_app_xml(string file_dest) 8476 { 8477 #if DEBUG 8478 Log.WriteLine("update_app_xml started."); 8479 #endif 8480 8481 string app_default_xml = CAFE_ROOT.value + "\\system\\bin\\ghs\\cafe\\boot\\app_default.xml"; 8482 8483 if (!check_xml_version(file_dest, app_default_xml, "")) 8484 { 8485 return false; 8486 } 8487 8488 XmlHandler.UpdateNodeValue(file_dest, "os_version", CAFERUN_COLDBOOT_OS_VERSION.value); 8489 8490 return true; 8491 } 8492 update_cos_xml(string file_dest, string cmd_flags)8493 static bool update_cos_xml(string file_dest, string cmd_flags) 8494 { 8495 #if DEBUG 8496 Log.WriteLine("update_cos_xml started."); 8497 #endif 8498 Console.WriteLine("CAFEX: update_cos_xml started, cmd_flags = " + cmd_flags); 8499 string cos_default_xml = CAFE_ROOT.value + "\\system\\bin\\ghs\\cafe\\boot\\cos_default.xml"; 8500 8501 if (!check_xml_version(file_dest, cos_default_xml, "")) 8502 { 8503 return false; 8504 } 8505 8506 //Get original command flags from the xml file 8507 string orig_cmd_flags = XmlHandler.GetNodeValue(cos_default_xml, "cmdFlags"); 8508 8509 Console.WriteLine("CAFEX: HexHandler.GetNumberFromString(cmd_flags) = " + HexHandler.GetNumberFromString(cmd_flags).ToString()); 8510 8511 cmd_flags = (HexHandler.GetNumberFromString(cmd_flags) | (HexHandler.GetNumberFromString(orig_cmd_flags) & ~0xff)).ToString(); 8512 Console.WriteLine("CAFEX: change cos.xml cmdFlags to " + cmd_flags); 8513 8514 //Compare the command flags passed with the original one. 8515 //If the values are different then update the xml node for cmdFlags 8516 if (orig_cmd_flags != cmd_flags) 8517 { 8518 XmlHandler.UpdateNodeValue(file_dest, "cmdFlags", cmd_flags); 8519 } 8520 8521 return true; 8522 } 8523 update_meta_xml(string file_dest)8524 static CAFEX_ERROR update_meta_xml(string file_dest) 8525 { 8526 #if DEBUG 8527 Log.WriteLine("update_meta_xml started on file = " + file_dest); 8528 #endif 8529 8530 string meta_default_xml = CAFE_ROOT.value + "\\system\\bin\\ghs\\cafe\\boot\\meta_default.xml"; 8531 string own_meta_xml; 8532 8533 //Since CAFE_CODE_DIR will be modified due to the existence of the session manager, we need to look 8534 //at the location of the original rpx to find the custom meta.xml file. 8535 if (SESSION_MANAGER.value == "1") 8536 { 8537 own_meta_xml = Path.Combine(CAFE_ELF_SRC_DIR.value, "..\\meta\\meta.xml"); 8538 } 8539 else 8540 { 8541 own_meta_xml = CAFE_CODE_DIR.value + "\\..\\meta\\meta.xml"; 8542 } 8543 8544 if (CAFERUN_OPTION_MLC_EMU_LAUNCH.value == "0") 8545 { 8546 if (File.Exists(own_meta_xml)) 8547 { 8548 string abs_own_meta_xml = Path.GetFullPath(own_meta_xml); 8549 string abs_file_dest = Path.GetFullPath(file_dest); 8550 if (abs_own_meta_xml != abs_file_dest) 8551 { 8552 Console.Write("Copy " + own_meta_xml + " to " + file_dest); 8553 File.Copy(own_meta_xml, file_dest, true); 8554 File.SetAttributes(file_dest, FileAttributes.Normal); 8555 } 8556 } 8557 else 8558 { 8559 CAFEX_ERROR ret = check_title_id(file_dest, meta_default_xml, APP_XML_FILE.value); 8560 if (ret != CAFEX_ERROR.OK) 8561 { 8562 return ret; 8563 } 8564 } 8565 8566 if (!check_xml_version(file_dest, meta_default_xml, "")) 8567 { 8568 return CAFEX_ERROR.RUN_UPDATE_META_XML_FAILED; 8569 } 8570 8571 XmlHandler.UpdateNodeValue(file_dest, "os_version", CAFERUN_COLDBOOT_OS_VERSION.value); 8572 8573 Console.WriteLine("Updating title id, group id, title version and app type in " + file_dest + ", based on " + APP_XML_FILE.value + "..."); 8574 8575 // get titleId from disc emulation's app.xml 8576 DISC_EMU_TID.value = XmlHandler.GetNodeValue(APP_XML_FILE.value, "title_id"); 8577 XmlHandler.UpdateNodeValue(file_dest, "title_id", DISC_EMU_TID.value); 8578 8579 // get group Id from disc emulation's app.xml 8580 string disc_emu_gid = XmlHandler.GetNodeValue(APP_XML_FILE.value, "group_id"); 8581 XmlHandler.UpdateNodeValue(file_dest, "group_id", disc_emu_gid); 8582 8583 // get title version from disc emulation's app.xml 8584 string disc_emu_titlever_hex = XmlHandler.GetNodeValue(APP_XML_FILE.value, "title_version").Trim(); 8585 if (!disc_emu_titlever_hex.StartsWith("0x")) 8586 { 8587 disc_emu_titlever_hex = "0x" + disc_emu_titlever_hex; 8588 } 8589 8590 uint disc_emu_titlever_decimal = HexHandler.GetNumberFromString(disc_emu_titlever_hex); 8591 // insert system default_title_id 8592 XmlHandler.UpdateNodeValue(file_dest, "title_version", disc_emu_titlever_decimal.ToString("D5")); 8593 } 8594 8595 return CAFEX_ERROR.OK; 8596 } 8597 update_boot_logos(string file_dest)8598 static void update_boot_logos(string file_dest) 8599 { 8600 #if DEBUG 8601 Log.WriteLine("update_boot_logos started."); 8602 #endif 8603 8604 string boot_movie_h264 = CAFE_ROOT.value + "\\system\\bin\\ghs\\cafe\\meta\\bootMovie.h264"; 8605 string boot_logo_tex_tga = CAFE_ROOT.value + "\\system\\bin\\ghs\\cafe\\meta\\bootLogoTex.tga"; 8606 8607 string icon_tex_tga = CAFE_ROOT.value + "\\system\\bin\\ghs\\cafe\\meta\\iconTex.tga"; 8608 string boot_tv_tga = CAFE_ROOT.value + "\\system\\bin\\ghs\\cafe\\meta\\bootTvTex.tga"; 8609 string boot_drc_tga = CAFE_ROOT.value + "\\system\\bin\\ghs\\cafe\\meta\\bootDrcTex.tga"; 8610 8611 string dest_boot_movie_h264 = file_dest + "\\bootMovie.h264"; 8612 string dest_boot_logo_tex_tga = file_dest + "\\bootLogoTex.tga"; 8613 8614 string dest_icon_tex_tga = file_dest + "\\iconTex.tga"; 8615 string dest_boot_tv_tga = file_dest + "\\bootTvTex.tga"; 8616 string dest_boot_drc_tga = file_dest + "\\bootDrcTex.tga"; 8617 8618 // Copy boot_movie logo_text only if ghs\cafe\meta has a newer timestamp. 8619 // This replaces the "cp -u" from the BASH script. 8620 bool copyRequired = false; 8621 8622 if (!File.Exists(dest_boot_movie_h264)) 8623 { 8624 // Should copy because it does not exist 8625 copyRequired = true; 8626 } 8627 else 8628 { 8629 // Check the timestamps 8630 if (file_timestamp_compare(boot_movie_h264, dest_boot_movie_h264) > 0) 8631 { 8632 copyRequired = true; 8633 } 8634 } 8635 8636 if (copyRequired) 8637 { 8638 file_copy_retry(boot_movie_h264, dest_boot_movie_h264, true, 1); 8639 File.SetAttributes(dest_boot_movie_h264, FileAttributes.Normal); 8640 } 8641 8642 // Copy logo_text only if ghs\cafe\meta has a newer timestamp 8643 copyRequired = false; 8644 8645 if (!File.Exists(dest_boot_logo_tex_tga)) 8646 { 8647 // Should copy because it does not exist 8648 copyRequired = true; 8649 } 8650 else 8651 { 8652 // Check the timestamps 8653 if (file_timestamp_compare(boot_logo_tex_tga, dest_boot_logo_tex_tga) > 0) 8654 { 8655 copyRequired = true; 8656 } 8657 } 8658 8659 if (copyRequired) 8660 { 8661 file_copy_retry(boot_logo_tex_tga, dest_boot_logo_tex_tga, true, 1); 8662 File.SetAttributes(dest_boot_logo_tex_tga, FileAttributes.Normal); 8663 } 8664 8665 // Applicaion Boot Textures should be copy if files do not exist 8666 if (!File.Exists(dest_icon_tex_tga)) 8667 { 8668 file_copy_retry(icon_tex_tga, dest_icon_tex_tga, true, 1); 8669 File.SetAttributes(dest_icon_tex_tga, FileAttributes.Normal); 8670 } 8671 8672 if (!File.Exists(dest_boot_tv_tga)) 8673 { 8674 file_copy_retry(boot_tv_tga, dest_boot_tv_tga, true, 1); 8675 File.SetAttributes(dest_boot_tv_tga, FileAttributes.Normal); 8676 } 8677 8678 if (!File.Exists(dest_boot_drc_tga)) 8679 { 8680 file_copy_retry(boot_drc_tga, dest_boot_drc_tga, true, 1); 8681 File.SetAttributes(dest_boot_drc_tga, FileAttributes.Normal); 8682 } 8683 } 8684 create_directory_if_noexist(string directory)8685 static void create_directory_if_noexist(string directory) 8686 { 8687 #if DEBUG 8688 Log.WriteLine("create_directory_if_noexist started."); 8689 #endif 8690 8691 if (!Directory.Exists(directory)) 8692 { 8693 Directory.CreateDirectory(directory); 8694 } 8695 } 8696 compute_flat_version(string version)8697 static int compute_flat_version(string version) 8698 { 8699 #if DEBUG 8700 Log.WriteLine("compute_flat_version started."); 8701 #endif 8702 8703 string[] numbers = version.Split('.'); 8704 int ret = 0; 8705 if (numbers.Length > 0) 8706 { 8707 ret += Convert.ToInt32(numbers[0]) * 1000000; 8708 } 8709 if (numbers.Length > 1) 8710 { 8711 ret += Convert.ToInt32(numbers[1]) * 10000; 8712 } 8713 if (numbers.Length > 2) 8714 { 8715 ret += Convert.ToInt32(numbers[2]) * 100; 8716 } 8717 if (numbers.Length > 3) 8718 { 8719 ret += Convert.ToInt32(numbers[3]); 8720 } 8721 8722 #if DEBUG 8723 Log.WriteLine(string.Format("compute_flat_version: '{0}' => {1}.", version, ret.ToString())); 8724 #endif 8725 return ret; 8726 } 8727 compute_ver_string(int ver)8728 static string compute_ver_string(int ver) 8729 { 8730 string ver_str = (ver % 100).ToString(); 8731 8732 if (ver > 100) 8733 { 8734 ver_str = string.Format("{0}.{1}", (ver / 100) % 100, ver_str); 8735 8736 if (ver > 10000) 8737 { 8738 ver_str = string.Format("{0}.{1}", (ver / 10000) % 100, ver_str); 8739 8740 if (ver > 1000000) 8741 { 8742 ver_str = string.Format("{0}.{1}", (ver / 1000000) % 100, ver_str); 8743 } 8744 } 8745 } 8746 8747 return ver_str; 8748 } 8749 check_title_id(string file_dest, string file_default, string file_app)8750 static CAFEX_ERROR check_title_id(string file_dest, string file_default, string file_app) 8751 { 8752 #if DEBUG 8753 Log.WriteLine("check_title_id started. file_dest=" + file_dest + ",file_default=" + file_default + ",file_app=" + file_app); 8754 #endif 8755 if (!File.Exists(file_dest)) 8756 { 8757 Console.WriteLine("cafex run: Copying default config file to " + file_dest); 8758 if (!File.Exists(file_default)) 8759 { 8760 Console.WriteLine("cafex run failed: Cannot find default config file " + file_default); 8761 return CAFEX_ERROR.RUN_CHECKTITLEID_FAILED; 8762 } 8763 8764 File.Copy(file_default, file_dest, true); 8765 File.SetAttributes(file_dest, FileAttributes.Normal); 8766 } 8767 else 8768 { 8769 string titleid_dest = XmlHandler.GetNodeValue(file_dest, "title_id"); 8770 string titleid_app = XmlHandler.GetNodeValue(file_app, "title_id"); 8771 if (titleid_dest == string.Empty || titleid_app == string.Empty) 8772 { 8773 Console.WriteLine("cafex run failed: Cannot get title id"); 8774 return CAFEX_ERROR.RUN_CHECKTITLEID_FAILED; 8775 } 8776 8777 if (titleid_dest != titleid_app) 8778 { 8779 Console.WriteLine("cafex run: Config file title id mismatch detected: " + titleid_dest + " vs. required " + titleid_app); 8780 Console.WriteLine(" Copying default config file to " + file_dest); 8781 8782 if (!File.Exists(file_default)) 8783 { 8784 Console.WriteLine("cafex run failed: Cannot find default config file " + file_default); 8785 return CAFEX_ERROR.RUN_CHECKTITLEID_FAILED; 8786 } 8787 8788 File.Copy(file_default, file_dest, true); 8789 File.SetAttributes(file_dest, FileAttributes.Normal); 8790 } 8791 } 8792 8793 return CAFEX_ERROR.OK; 8794 } 8795 8796 /// <summary> 8797 /// Compares timestamsp between two files. 8798 /// </summary> 8799 /// <param name="file1">The first file for comparison.</param> 8800 /// <param name="file2">The second file for comparison.</param> 8801 /// <returns>0 if timestamps are the same, negative if first file is older than the second, and positive if first is newer than the second.</returns> file_timestamp_compare(string file1, string file2)8802 static int file_timestamp_compare(string file1, string file2) 8803 { 8804 if (!File.Exists(file1)) 8805 { 8806 throw new ArgumentException("file1 = " + file1); 8807 } 8808 8809 if (!File.Exists(file2)) 8810 { 8811 throw new ArgumentException("file2 = " + file2); 8812 } 8813 8814 DateTime file1Time = File.GetLastWriteTime(file1); 8815 DateTime file2Time = File.GetLastWriteTime(file2); 8816 8817 return DateTime.Compare(file1Time, file2Time); 8818 } 8819 8820 /// <summary> 8821 /// Tries to copy a file from source to destination, and if it fails and attempts is greater than one, 8822 /// it will wait for 1s and retry. 8823 /// </summary> 8824 /// <param name="sourceFileName">Source file.</param> 8825 /// <param name="destFileName">Destination file.</param> 8826 /// <param name="overwrite">Overwrite if destination exists.</param> 8827 /// <param name="attempts">Number of attempts</param> file_copy_retry(string sourceFileName, string destFileName, bool overwrite, uint attempts)8828 static void file_copy_retry(string sourceFileName, string destFileName, bool overwrite, uint attempts) 8829 { 8830 8831 try 8832 { 8833 if (overwrite && File.Exists(destFileName)) 8834 { 8835 // Force copy by stripping the read-only attribute 8836 File.SetAttributes(destFileName, File.GetAttributes(destFileName) & ~FileAttributes.ReadOnly); 8837 } 8838 8839 File.Copy(sourceFileName, destFileName, overwrite); 8840 } 8841 catch (IOException) 8842 { 8843 if (attempts > 1) 8844 { 8845 --attempts; 8846 // Wait a second 8847 Thread.Sleep(Program.RETRY_TIMESPAN); 8848 // Retry 8849 file_copy_retry(sourceFileName, destFileName, overwrite, attempts); 8850 } 8851 else 8852 { 8853 // Re-throw if no attempts 8854 throw; 8855 } 8856 } 8857 } 8858 8859 #endregion 8860 8861 #region HELP run_usage()8862 static void run_usage() 8863 { 8864 string caller; 8865 if (CAFERUN_OPTION_CALLED_FROM_CAFEDISCRUN.value == "yes") 8866 { 8867 caller = "discrun"; 8868 } 8869 else 8870 { 8871 caller = "run"; 8872 } 8873 8874 Console.WriteLine("Usage: cafex " + caller + " [options] <app>.rpx \"[arg1]\" \"[arg2]\" ... \"[argN]\""); 8875 Console.WriteLine(); 8876 Console.WriteLine("options:"); 8877 Console.WriteLine(" -a a,b... : arguments (comma delimited)"); 8878 Console.WriteLine(" -b : use DEBUG OS version"); 8879 Console.WriteLine(" -C : use OS_SECURITY_LEVEL OS version"); 8880 Console.WriteLine(" -u : use FDEBUG OS version"); 8881 Console.WriteLine(" -l <path> : user RPL directory or file to gather for RPX"); 8882 Console.WriteLine(); 8883 Console.WriteLine(" -d multi : launch multi (GHS UI) on elf file"); 8884 Console.WriteLine(" -L : run legacy application independent of xml versions"); 8885 Console.WriteLine(" -i : stop debugger in the initialization code"); 8886 Console.WriteLine(" -j : stop debugger in the pre-initialization code"); 8887 Console.WriteLine(" -R : do not stop in debugger until OSDebug or OSDebugStr call"); 8888 Console.WriteLine(" -p <n> : indicate process to debug (defaults to game process)"); 8889 Console.WriteLine(" -g <n> : 32-bit flag to pass along to PPC COS"); 8890 Console.WriteLine(" -w <n> : 32-bit flag to pass along to PPC COS."); 8891 Console.WriteLine(" -k <file> : path to elf file for debugger"); 8892 Console.WriteLine(" -x : Enable AHCI/SATA disk access. Deprecated - will soon become default."); 8893 Console.WriteLine(" -r : restart last application"); 8894 Console.WriteLine(" -s : use soft launch to run"); 8895 Console.WriteLine(" -F : force restart (stop and then boot hw)"); 8896 Console.WriteLine(" -t <tid> : title launch from mlc emulation (tid is hex that starts with 0x)"); 8897 Console.WriteLine(" -e <op> : pass op through to FSEmul or MCP (e.g.: -e sata -> FSEmul -sata)"); 8898 Console.WriteLine(" -e eco : Set the system to boot in ECO mode"); 8899 Console.WriteLine(); 8900 Console.WriteLine(" -v <n> : set COS verbose level (0=off 7 == MAX)"); 8901 Console.WriteLine(" -q : do not display OS warning or informational messages."); 8902 Console.WriteLine(" -z : suppress mirroring the data to the session data directory."); 8903 Console.WriteLine(" -K : Use kill restart to restart the application"); 8904 Console.WriteLine(" -T : apptype of the title being run (This will override the calculation of apptype)"); 8905 Console.WriteLine(); 8906 Console.WriteLine(" -h : (help) display options"); 8907 } 8908 headlessrun_usage()8909 static void headlessrun_usage() 8910 { 8911 Console.WriteLine("Usage: cafex headlessrun [options] <app>.rpx \"[arg1]\" ... \"[argN]\""); 8912 8913 Console.WriteLine(); 8914 Console.WriteLine("options:"); 8915 Console.WriteLine(" -b : Use DEBUG version of the OS"); 8916 Console.WriteLine(" -n : Don't start the title after upload."); 8917 Console.WriteLine(" -m : Bypass mastering setup."); 8918 Console.WriteLine(" -w <time> : Time (in seconds) to wait for title to boot during setup."); 8919 Console.WriteLine(" Default time is 15 seconds."); 8920 Console.WriteLine(" -h <bank> : Specify bank to run from. Default is bank 10."); 8921 Console.WriteLine(" -u : (help) display options"); 8922 } 8923 on_usage()8924 static void on_usage() 8925 { 8926 Console.WriteLine("Usage: cafex on [options]"); 8927 Console.WriteLine(); 8928 Console.WriteLine("options:"); 8929 Console.WriteLine(" -d multi : launch multi. (GHS UI)"); 8930 Console.WriteLine(" -e <op> : pass op through to FSEmul or MCP. (e.g.: -e sata -> FSEmul -sata)"); 8931 Console.WriteLine(" -p <n> : indicate process to debug. (defaults to game process)"); 8932 Console.WriteLine(" -nobgd : disables background daemons."); 8933 Console.WriteLine(" -noprompt : changes CATTOUCAN_TERM to \"source -p -q /vol/content\"."); 8934 Console.WriteLine(" -nosync : suppress mirroring the data to the session data directory."); 8935 Console.WriteLine(); 8936 Console.WriteLine(" -h : (help) display options."); 8937 } 8938 update_usage()8939 static void update_usage() 8940 { 8941 Console.WriteLine("Usage: cafex update [-h]"); 8942 Console.WriteLine(); 8943 Console.WriteLine("options:"); 8944 Console.WriteLine(" -u <package> : path to update package (from System Config Tool's perspective)"); 8945 Console.WriteLine(" -s : use system updater (update package should contain system updater)"); 8946 Console.WriteLine(" -t <dir> : patch to single title (from System Config Tool's perspective)"); 8947 if (is_DUAL_bootloader_available()) 8948 { 8949 if (is_DUAL_bootloader_required()) 8950 { 8951 Console.WriteLine(" -p : use the production bootloader (only applies when in NAND mode)"); 8952 } 8953 else 8954 Console.WriteLine(" -M : use the mixed bootloader."); 8955 } 8956 8957 Console.WriteLine(" -reflash : reflashes NAND during the update"); 8958 Console.WriteLine(" -noreflash : does not reflash NAND during the update(default)"); 8959 Console.WriteLine(" -nodrc : skip the firmware update for attached DRC"); 8960 Console.WriteLine(" -h : (help) display options"); 8961 } 8962 revert_usage()8963 static void revert_usage() 8964 { 8965 Console.WriteLine("Usage: cafex revert [-h] SDK_ROOT"); 8966 Console.WriteLine(); 8967 Console.WriteLine("options:"); 8968 Console.WriteLine(" -reflash : reflashes NAND during the update"); 8969 Console.WriteLine(" -noreflash : does not reflash NAND during the update (default)"); 8970 if (is_DUAL_bootloader_available() && !is_DUAL_bootloader_required()) 8971 { 8972 Console.WriteLine(" -mixed : use the DUAL instead of the PCFS bootloader"); 8973 } 8974 Console.WriteLine(" -h : (help) display options"); 8975 Console.WriteLine(" SDK_ROOT : root of the SDK to revert to"); 8976 } 8977 recover_usage()8978 static void recover_usage() 8979 { 8980 Console.WriteLine("Usage: cafex recover [-production|-bootloader][-h]"); 8981 Console.WriteLine(); 8982 Console.WriteLine("options:"); 8983 Console.WriteLine(" -production : use the production NAND bootloader"); 8984 if (is_DUAL_bootloader_available()) 8985 { 8986 Console.WriteLine(" -bootloader : update *only* the bootloader to the DUAL bootloader"); 8987 if (!is_DUAL_bootloader_required()) 8988 { 8989 Console.WriteLine(" -mixed : use the DUAL instead of the PCFS bootloader"); 8990 } 8991 } 8992 Console.WriteLine(" -noreflash : does not reflash NAND during the recovery"); 8993 Console.WriteLine(" -reflash : reflashes NAND during the recovery"); 8994 8995 Console.WriteLine(" -h : (help) display options"); 8996 } 8997 stop_usage()8998 static void stop_usage() 8999 { 9000 Console.WriteLine("Usage: cafex stop [-hostonly] [-makemine] [-h]"); 9001 Console.WriteLine(); 9002 Console.WriteLine("options:"); 9003 Console.WriteLine(" -h : (help) display options."); 9004 Console.WriteLine(" -hostonly : stops the host applications that control the bridge, keeping the bridge on."); 9005 Console.WriteLine(" -makemine : forces assigning the bridge to this host."); 9006 } 9007 setbootmode_usage()9008 static void setbootmode_usage() 9009 { 9010 Console.WriteLine("Usage: cafex setbootmode [-noreflash] [-quick|-production] [PCFS|NAND]"); 9011 Console.WriteLine(); 9012 Console.WriteLine("options:"); 9013 Console.WriteLine(" -h : (help) display options."); 9014 Console.WriteLine(" -quick|-Q : If the DUAL bootloader is installed, just change the boot"); 9015 Console.WriteLine(" mode environment variables."); 9016 if (is_DUAL_bootloader_available()) 9017 { 9018 if (is_DUAL_bootloader_required()) 9019 Console.WriteLine(" -production|-P : Applies only to NAND mode. Uses the production bootloader."); 9020 else 9021 Console.WriteLine(" -mixed : Install the mixed bootloader."); 9022 } 9023 Console.WriteLine(" -reflash : reflashes NAND during the operation"); 9024 Console.WriteLine(" -noreflash : does not reflash NAND during the operation(default)"); 9025 if (is_DUAL_bootloader_available()) 9026 { 9027 if (is_DUAL_bootloader_required()) 9028 Console.WriteLine(" PCFS : sets the Bridge to mixed boot using PCFS."); 9029 else 9030 Console.WriteLine(" PCFS : sets the Bridge to boot using PCFS."); 9031 } 9032 Console.WriteLine(" NAND : sets the Bridge to boot from internal NAND."); 9033 } 9034 syncsession_usage()9035 static void syncsession_usage() 9036 { 9037 Console.WriteLine("Usage: cafex syncsession [-h]"); 9038 Console.WriteLine(); 9039 Console.WriteLine("options:"); 9040 Console.WriteLine(" -h : (help) display options."); 9041 } 9042 launch_usage()9043 static void launch_usage() 9044 { 9045 Console.WriteLine("Usage: cafex launch <title path> [args]"); 9046 Console.WriteLine(); 9047 Console.WriteLine("options:"); 9048 Console.WriteLine(" -h : (help) display options"); 9049 Console.WriteLine(" <title path> : Full file path for the title rpx"); 9050 Console.WriteLine(" [args] : arguments to rpx"); 9051 Console.WriteLine(""); 9052 } 9053 #endregion 9054 } 9055 9056 public class getopts 9057 { 9058 private string[] args; 9059 private string optstring; 9060 private int optind; 9061 private string optarg; 9062 private string opt; 9063 private string next = null; 9064 int argc; 9065 getopts(string[] args, string optstring)9066 public getopts(string[] args, string optstring) 9067 { 9068 this.args = args; 9069 this.argc = args.Length; 9070 this.optstring = optstring; 9071 this.optind = 0; 9072 } 9073 9074 public int OPTIND 9075 { 9076 get 9077 { 9078 return this.optind; 9079 } 9080 } 9081 9082 public string OPT 9083 { 9084 get 9085 { 9086 return this.opt; 9087 } 9088 } 9089 9090 public string OPTARG 9091 { 9092 get 9093 { 9094 return this.optarg; 9095 } 9096 } 9097 getNext()9098 public bool getNext() 9099 { 9100 9101 optarg = null; 9102 9103 if (string.IsNullOrEmpty(next)) 9104 { 9105 // Check if that is the end of the args 9106 if (optind >= argc) 9107 { 9108 // Done 9109 optarg = null; 9110 return false; 9111 } 9112 9113 if (args[optind].Equals("-")) 9114 { 9115 // Invalid if only "-" 9116 this.optind++; 9117 optarg = null; 9118 if (optind < argc) 9119 { 9120 optarg = args[optind]; 9121 } 9122 9123 return false; 9124 } 9125 9126 if (optind >= argc || args[optind][0] != '-' || args[optind][1] == '\0') 9127 { 9128 optarg = null; 9129 if (optind < argc) 9130 { 9131 optarg = args[optind]; 9132 } 9133 9134 return false; 9135 } 9136 9137 if (args[optind].Equals("--")) 9138 { 9139 // Invalid if "--" 9140 optind++; 9141 optarg = null; 9142 if (optind < argc) 9143 { 9144 optarg = args[optind]; 9145 } 9146 9147 return false; 9148 } 9149 9150 // Set the current with the value calculated 9151 next = args[optind]; 9152 if (next.StartsWith("-")) 9153 { 9154 next = next.Remove(0, 1); 9155 } 9156 9157 optind++; 9158 } 9159 9160 // handle the current argument 9161 string configurationChar = next.Substring(0, 1); 9162 // remove configuration char from argument 9163 next = next.Substring(1); 9164 9165 int configurationCharPosition = optstring.IndexOf(configurationChar); 9166 if (-1 == configurationCharPosition) 9167 { 9168 this.opt = "?"; 9169 return true; 9170 } 9171 9172 configurationCharPosition++; 9173 // Check if configuration character should have an argument or not (yes, if there is ":" in the optstring). 9174 if (configurationCharPosition < optstring.Length 9175 && optstring[configurationCharPosition] == ':') 9176 { 9177 if (!string.IsNullOrEmpty(next)) 9178 { 9179 optarg = next; 9180 next = null; 9181 } 9182 else if (optind < argc) 9183 { 9184 // get the next argument from args and increase the index 9185 optarg = args[optind]; 9186 optind++; 9187 } 9188 else 9189 { 9190 // failure case 9191 this.opt = "?"; 9192 return true; 9193 } 9194 } 9195 9196 // Success 9197 this.opt = configurationChar; 9198 return true; 9199 } 9200 } 9201 } 9202