1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - OS
3   File:     os_application_jump.c
4 
5   Copyright 2007-2009 Nintendo. All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law. They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date:: 2009-06-04#$
14   $Rev: 10698 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 
18 #include <twl/os.h>
19 #include <application_jump_private.h>
20 #include <twl/spi.h>
21 #include <twl/code32.h>
22 #include <twl/mcu.h>
23 #include <twl/hw/common/mmap_shared.h>
24 #include <twl/hw/common/mmap_parameter.h>
25 
26 // Define data-------------------------------------------------------
27 #define OSi_LAUNCHER_PARAM_MAGIC_CODE           "TLNC"
28 #define OSi_LAUNCHER_PARAM_MAGIC_CODE_LEN       4
29 #define OSi_TITLE_ID_MEDIA_FLAG_MASK            ( 0x0001ULL << 34 )
30 #define OSi_TITLE_ID_DATA_ONLY_FLAG_MASK        ( 0x0001ULL << 35 )
31 #define OSi_TMP_APP_SIZE_MAX                    ( 16 * 1024 * 1024 )
32 
33 #define OSi_TMP_APP_PATH_RAW                    "nand:/tmp/jump.app"
34 #define OSi_TMP_APP_PATH_RAW_LENGTH             18
35 
36 typedef struct NandFirmResetParameter {
37     u8      isHotStart :1;
38     u8      isResetSW :1;
39     u8      rsv :5;
40     u8      isValid :1;
41 }NandFirmResetParameter;
42 
43 // NAND firmware parameter address
44 #define OSi_GetNandFirmResetParam()         ( (NandFirmResetParameter *)HW_NAND_FIRM_HOTSTART_FLAG )
45 
46 // Launcher parameter address
47 #define OSi_GetLauncherParam()              ( (LauncherParam *)HW_PARAM_LAUNCH_PARAM )
48 
49 
50 // Extern data-------------------------------------------------------
51 
52 // Function's prototype----------------------------------------------
53 static void OSi_DoHardwareReset( void );
54 static BOOL OSi_IsNandApp( OSTitleId id );
55 static BOOL OSi_IsSameMakerCode(OSTitleId id);
56 static OSTitleId OSi_SearchTitleIdFromList(OSTitleId id, u64 mask);
57 
58 // Global variables--------------------------------------------------
59 
60 // Static variables--------------------------------------------------
61 #include  <twl/ltdmain_begin.h>
62 static OSTitleId s_prevTitleId = 0;
63 #include  <twl/ltdmain_end.h>
64 // Const data--------------------------------------------------------
65 
66 #include <twl/ltdmain_begin.h>
OSi_IsNandApp(OSTitleId id)67 static BOOL OSi_IsNandApp( OSTitleId id )
68 {
69     if( id & OSi_TITLE_ID_MEDIA_FLAG_MASK )
70     {
71         return TRUE;
72     }
73     return FALSE;
74 }
75 
OSi_IsSameMakerCode(OSTitleId id)76 static BOOL OSi_IsSameMakerCode(OSTitleId id)
77 {
78     const OSTitleIDList *list = (const OSTitleIDList *)HW_OS_TITLE_ID_LIST;
79     const int   total = MATH_MIN( list->num, OS_TITLEIDLIST_MAX );
80     int i;
81     for (i = 0; i < total; ++i)
82     {
83         if (list->TitleID[i] == id)
84         {
85             int pos = (i >> 3);
86             int bit = (0x01 << (i & 7));
87             if (( list->sameMakerFlag[pos] & bit) != 0)
88             {
89                 /* The maker code is the same */
90                 return TRUE;
91             }
92             else
93             {
94                 /* The maker code is different */
95                 return FALSE;
96             }
97         }
98     }
99     /* The target TitleID is not in the list */
100     return FALSE;
101 }
102 
OSi_SearchTitleIdFromList(OSTitleId id,u64 mask)103 static OSTitleId OSi_SearchTitleIdFromList( OSTitleId id, u64 mask )
104 {
105     const OSTitleIDList *list = (const OSTitleIDList *)HW_OS_TITLE_ID_LIST;
106     const int OS_TITLE_ID_LIST_MAX = sizeof(list->TitleID) / sizeof(*list->TitleID);
107     const int num = MATH_MIN(list->num, OS_TITLE_ID_LIST_MAX);
108     int i;
109 
110     /* Under the assumption that game codes are unique, extract the relevant TitleID from the list */
111     for (i = 0; i < num; ++i)
112     {
113         if ( (id & mask) == (list->TitleID[i] & mask)                       /* Do the game codes match? */
114             && !(list->TitleID[i] & OSi_TITLE_ID_DATA_ONLY_FLAG_MASK) )     /* Is this not a data-only title? */
115         {
116             return list->TitleID[i];
117         }
118     }
119     return 0;
120 }
121 
122 #include  <twl/ltdmain_end.h>
123 
124 #ifdef SDK_ARM9
125 
OSi_InitPrevTitleId(void)126 void OSi_InitPrevTitleId( void )
127 {
128     OSDeliverArgInfo deliverArgInfo;
129     OS_InitDeliverArgInfo( &deliverArgInfo, 0 );
130     if ( OS_DELIVER_ARG_SUCCESS == OS_DecodeDeliverArg() )
131     {
132         s_prevTitleId = OS_GetTitleIdFromDeliverArg();
133     }
134     if ( (s_prevTitleId != 0 && !OSi_SearchTitleIdFromList(s_prevTitleId, 0xffffffffffffffff)) ||
135           (char)(s_prevTitleId >>24) == '0' ||
136           (char)(s_prevTitleId >>24) == '1' ||
137           (char)(s_prevTitleId >>24) == '2' ||
138           (char)(s_prevTitleId >>24) == '3' ||
139           (char)(s_prevTitleId >>24) == '4'  )
140     {
141         /* Make it look like this was started from the launcher and delete DeliverArg as well */
142         s_prevTitleId = 0;
143         OS_InitDeliverArgInfo( &deliverArgInfo, 0 );
144         (void)OS_EncodeDeliverArg();
145     }
146     else
147     {
148         OS_SetDeliverArgStateInvalid();
149     }
150 }
151 
152 // For safety purposes, locate this function in itcm
153 #include <twl/itcm_begin.h>
OSi_DoHardwareReset(void)154 static void OSi_DoHardwareReset( void )
155 {
156     // [TODO:] Lastly, change to HW reset via a microcomputer
157     // Issue reset command
158     PM_ForceToResetHardware();
159     OS_Terminate();
160 }
161 
162 #include <twl/itcm_end.h>
163 
164 /* The following code is located in the TWL extended memory region */
165 #ifdef    SDK_TWL
166 #include  <twl/ltdmain_begin.h>
167 #endif
168 // Hardware reset by specifying LauncherParam
OS_SetLauncherParamAndResetHardware(OSTitleId id,LauncherBootFlags * flag)169 void OS_SetLauncherParamAndResetHardware( OSTitleId id, LauncherBootFlags *flag )
170 {
171     // Copy the manufacturer and game codes
172     u32 *maker_code_dest_addr = (u32 *)((u32)(OSi_GetLauncherParam()) + HW_PARAM_DELIVER_ARG_MAKERCODE_OFS);
173     u32 *game_code_dest_addr = (u32 *)((u32)(OSi_GetLauncherParam()) + HW_PARAM_DELIVER_ARG_GAMECODE_OFS);
174     u16 *maker_code_src_addr = (u16 *)(HW_TWL_ROM_HEADER_BUF + 0x10);
175     u32 *game_code_src_addr = (u32 *)(HW_TWL_ROM_HEADER_BUF + 0xc);
176     *maker_code_dest_addr = (u32)*maker_code_src_addr;
177     *game_code_dest_addr = *game_code_src_addr;
178 
179     // Set the launcher parameter
180     OSi_GetLauncherParam()->body.v1.prevTitleID = *(OSTitleId *)(HW_TWL_ROM_HEADER_BUF + 0x230);
181     OSi_GetLauncherParam()->body.v1.bootTitleID = id;
182     OSi_GetLauncherParam()->body.v1.flags = *flag;
183     MI_CpuCopyFast( OSi_LAUNCHER_PARAM_MAGIC_CODE, (char *)&OSi_GetLauncherParam()->header.magicCode, OSi_LAUNCHER_PARAM_MAGIC_CODE_LEN);
184     OSi_GetLauncherParam()->header.bodyLength = sizeof(LauncherParamBody);
185     OSi_GetLauncherParam()->header.crc16 = SVC_GetCRC16( 65535, &OSi_GetLauncherParam()->body, OSi_GetLauncherParam()->header.bodyLength );
186     OSi_GetLauncherParam()->header.version = 1;
187 
188     if( id == 0 || OS_IsDeliverArgEncoded() != TRUE || OS_GetTitleIdLastEncoded() != OSi_GetLauncherParam()->body.v1.prevTitleID )
189     {
190         // If the DeliverArg is not encoded with the current application, force initialization of DeliverArg and encode
191         OSDeliverArgInfo deliverArgInfo;
192         OS_InitDeliverArgInfo( &deliverArgInfo, 0 );
193         (void)OS_EncodeDeliverArg();
194     }
195 
196     DC_FlushRange((const void *)HW_PARAM_DELIVER_ARG, HW_PARAM_DELIVER_ARG_SIZE + HW_PARAM_LAUNCH_PARAM_SIZE );
197     DC_WaitWriteBufferEmpty();
198 
199     OSi_DoHardwareReset();
200 }
201 
202 // Function that returns from the application after the application jump to the original application
203 // If there is no original application, FALSE
OS_ReturnToPrevApplication(void)204 BOOL OS_ReturnToPrevApplication( void )
205 {
206     if( s_prevTitleId != 0)
207     {
208         return OS_DoApplicationJump( s_prevTitleId, OS_APP_JUMP_NORMAL ); //Never return
209     }
210     return FALSE;
211 }
212 
IsSameTitleID(OSTitleId titleID,OSTitleId listedTitleID)213 static inline BOOL IsSameTitleID( OSTitleId titleID, OSTitleId listedTitleID )
214 {
215     if ((char)titleID == 'A')
216     {
217         // Corresponding to language code A option
218         return (listedTitleID >> 8) == (titleID >> 8);
219     }
220     else
221     {
222         return listedTitleID == titleID;
223     }
224 }
225 
226 // Get the ID that can actually be started for the given title ID
227 // If a startable ID exists, set that ID to the *bootableTitleID and return TRUE
228 // If a startable ID does not exist, return FALSE
OS_GetBootableTitleID(OSTitleId titleID,OSTitleId * bootableTitleID)229 static BOOL OS_GetBootableTitleID( OSTitleId titleID, OSTitleId *bootableTitleID )
230 {
231     const OSTitleIDList *list = (const OSTitleIDList *)HW_OS_TITLE_ID_LIST;
232     const int OS_TITLE_ID_LIST_MAX = sizeof(list->TitleID) / sizeof(*list->TitleID);
233     const int num = MATH_MIN(list->num, OS_TITLE_ID_LIST_MAX);
234     int i;
235     for (i = 0; i < num; ++i)
236     {
237         if (IsSameTitleID(titleID, list->TitleID[i]) && (list->appJumpFlag[i / 8] & (u8)(0x1 << (i % 8))))
238         {
239             *bootableTitleID = list->TitleID[i];
240             return TRUE;
241         }
242     }
243     return FALSE;
244 }
245 
246 // Whether an application has been installed that corresponds to that TitleID
OSi_CanApplicationJumpTo(OSTitleId titleID)247 BOOL OSi_CanApplicationJumpTo( OSTitleId titleID )
248 {
249     return OS_GetBootableTitleID(titleID, &titleID);
250 }
251 
252 // Wrapper for OS_SetLauncherParamAndResetHardware
OS_DoApplicationJump(OSTitleId id,OSAppJumpType jumpType)253 BOOL OS_DoApplicationJump( OSTitleId id, OSAppJumpType jumpType )
254 {
255     FSFile  file[1];
256     LauncherBootFlags flag;
257     u8 platform_code;
258     u8 bit_field;
259 
260     switch( jumpType )
261     {
262         case OS_APP_JUMP_NORMAL:
263             if( id & OSi_TITLE_ID_DATA_ONLY_FLAG_MASK )
264             {
265                 // Set so that it is not possible to jump to DataOnly items
266                 return FALSE;
267             }
268             if( id != 0 )
269             {
270                 if (!OS_GetBootableTitleID(id, &id))
271                 {
272                     return FALSE;
273                 }
274             }
275             // Set the bootType and jump
276             if( id & OSi_TITLE_ID_MEDIA_FLAG_MASK )
277             {
278                 flag.bootType = LAUNCHER_BOOTTYPE_NAND;
279             }else
280             {
281                 flag.bootType = LAUNCHER_BOOTTYPE_ROM;
282             }
283             break;
284         case OS_APP_JUMP_TMP:
285             // When you yourself are a TMP application, TMP jump is not possible
286             if( OS_IsTemporaryApplication() )
287             {
288                 OS_TPrintf("OS_DoApplicationJump error : tmp app can't jump to tmp app!\n");
289                 return FALSE;
290             }
291             // Get the TitleID from the file of OS_TMP_APP_PATH and check the allowed TMP jump bits
292             FS_InitFile( file );
293             if( !FS_OpenFileEx(file, OS_TMP_APP_PATH, FS_FILEMODE_R) )
294             {
295                 OS_TPrintf("OS_DoApplicationJump error : tmp app open error!\n");
296                 return FALSE;
297             }
298             // File size check
299             if( FS_GetFileLength( file ) > OSi_TMP_APP_SIZE_MAX )
300             {
301                 OS_TPrintf("OS_DoApplicationJump error : too large tmp app size!\n");
302                 return FALSE;
303             }
304 
305             if( !FS_SeekFile( file, 0x12, FS_SEEK_SET ) ||
306                 ( sizeof(platform_code) != FS_ReadFile( file, &platform_code, sizeof(platform_code) ) ) ||
307                 !FS_SeekFile( file, 0x1d, FS_SEEK_SET ) ||
308                 ( sizeof(bit_field) != FS_ReadFile( file, &bit_field, sizeof(bit_field) ) )
309             )
310             {
311                 OS_TPrintf("OS_DoApplicationJump error : tmp app read error!\n");
312                 (void)FS_CloseFile(file);
313                 return FALSE;
314             }
315 
316             if( !( bit_field & 0x2 ) )
317             {
318                 OS_TPrintf("OS_DoApplicationJump error : tmp jump bit is not enabled!\n");
319                 (void)FS_CloseFile(file);
320                 return FALSE;
321             }
322             flag.bootType = LAUNCHER_BOOTTYPE_TEMP;
323             // The TWL application gets the title ID from the header and enters it. For NTR applications, for the time being enter TitleIDs other than 0
324             if( platform_code & 0x2 )
325             {
326                 if( !FS_SeekFile( file, 0x0230, FS_SEEK_SET ) ||
327                     ( sizeof(id) != FS_ReadFile( file, &id, sizeof(id) ) )
328                 )
329                 {
330                     OS_TPrintf("OS_DoApplicationJump error : tmp app read error!\n");
331                     (void)FS_CloseFile(file);
332                     return FALSE;
333                 }
334             }else
335             {
336                 id = 0x1;
337             }
338             (void)FS_CloseFile(file);
339             break;
340         default:
341             return FALSE;
342     }
343 
344     if ( PMi_TryLockForReset() == FALSE )
345     {
346         return FALSE;
347     }
348 
349     // Shared configurations
350     flag.isValid = TRUE;
351     flag.isLogoSkip = TRUE;
352     flag.isInitialShortcutSkip = FALSE;
353     flag.isAppLoadCompleted = FALSE;
354     flag.isAppRelocate = FALSE;
355     flag.rsv = 0;
356 
357     OS_SetLauncherParamAndResetHardware( id, &flag ); // never return.
358     return TRUE;
359 }
360 
361 /* The code above is located in the TWL extended memory region */
362 #ifdef    SDK_TWL
363 #include  <twl/ltdmain_end.h>
364 #endif
365 
366 /*---------------------------------------------------------------------------*
367   Name:         OS_JumpToSystemMenu
368 
369   Description:  Runs a hardware reset and jumps to the system menu.
370 
371   Arguments:    None.
372 
373   Returns:      FALSE: Application jump failed for some reason.
374                 * If the process was successful, a reset occurred during this function, so TRUE is not returned.
375 
376  *---------------------------------------------------------------------------*/
OS_JumpToSystemMenu(void)377 BOOL OS_JumpToSystemMenu( void )
378 {
379     BOOL result = FALSE;
380 #ifdef SDK_TWL
381     if( OS_IsRunOnTwl() )
382     {
383         // ---- Application Jump with id==0
384         //      means to jump to system menu
385         result = OS_DoApplicationJump( 0, OS_APP_JUMP_NORMAL );
386     }
387     else
388 #endif
389     {
390         OS_Warning("This Hardware don't support this funciton");
391     }
392     return result;
393 }
394 
395 /*---------------------------------------------------------------------------*
396   Name:         OS_RebootSystem
397 
398   Description:  Runs a hardware reset and restarts itself.
399 
400   Arguments:    None.
401 
402   Returns:      FALSE: Run on NITRO, or failure in restarting.
403                 * If the process was successful, a reset occurred during this function, so TRUE is not returned.
404 
405  *---------------------------------------------------------------------------*/
OS_RebootSystem(void)406 BOOL OS_RebootSystem( void )
407 {
408 #ifdef SDK_TWL
409     if( OS_IsRunOnTwl() )
410     {
411         if( OS_IsTemporaryApplication() )
412         {
413             OS_TPrintf("OS_RebootSystem error : tmp app can't execute this function\n");
414             return FALSE;
415         }
416         // Application jump to self
417         return OS_DoApplicationJump( OS_GetTitleId(), OS_APP_JUMP_NORMAL );
418     }
419     else
420 #endif
421     {
422         OS_Warning("This Hardware don't support this funciton");
423         return FALSE;
424     }
425 }
426 
427 /*---------------------------------------------------------------------------*
428   Name:         OS_IsRebooted
429 
430   Description:  Checks whether a restart was applied using OS_RebootSystem.
431 
432   Arguments:    None.
433 
434   Returns:      TRUE: Restart was applied more than one time.
435                 FALSE: First startup.
436  *---------------------------------------------------------------------------*/
OS_IsRebooted(void)437 BOOL OS_IsRebooted( void )
438 {
439     BOOL result = FALSE;
440 #ifdef SDK_TWL
441     if( OS_IsRunOnTwl() )
442     {
443         if( OS_GetTitleId() == s_prevTitleId )
444         {
445             result = TRUE;
446         }
447     }
448 #endif
449     return result;
450 }
451 
452 /*---------------------------------------------------------------------------*
453   Name:         OSi_CanArbitraryJumpTo
454 
455   Description:  Checks whether a jump to the specified (arbitrary) application is possible.
456 
457   Arguments:    Game code of the application to jump to
458 
459   Returns:      TRUE: Execution can jump to the target application.
460                 FALSE: Execution cannot jump to the target application.
461  *---------------------------------------------------------------------------*/
462 
OSi_CanArbitraryJumpTo(u32 initialCode)463 BOOL OSi_CanArbitraryJumpTo(u32 initialCode)
464 {
465 #ifdef SDK_TWL
466     if( OS_IsRunOnTwl() )
467     {
468         OSTitleId id = OSi_SearchTitleIdFromList( (OSTitleId)initialCode, 0x00000000ffffffff );
469         /* Non-NAND application are exceptions */
470         if( OSi_IsNandApp(id) )
471         {
472             return OSi_CanApplicationJumpTo( id ) && OSi_IsSameMakerCode( id );
473         }
474     }
475 #endif
476     return FALSE;
477 }
478 
479 /*---------------------------------------------------------------------------*
480   Name:         OSi_JumpToArbitraryApplication
481 
482   Description:  Jumps to the specified (arbitrary) application.
483 
484   Arguments:    Game code of the application to jump to
485 
486   Returns:      FALSE: Application jump failed for some reason.
487                 * If the process was successful, a reset occurred during this function, so TRUE is not returned.
488 
489  *---------------------------------------------------------------------------*/
OSi_JumpToArbitraryApplication(u32 initialCode)490 BOOL OSi_JumpToArbitraryApplication(u32 initialCode)
491 {
492 #ifdef SDK_TWL
493     if( OS_IsRunOnTwl() )
494     {
495         OSTitleId id = OSi_SearchTitleIdFromList( (OSTitleId)initialCode, 0x00000000ffffffff );
496         if( OSi_CanArbitraryJumpTo( initialCode ) )
497         {
498             return OS_DoApplicationJump( id, OS_APP_JUMP_NORMAL );
499         }
500     }
501 #endif
502     return FALSE;
503 }
504 
505 /*---------------------------------------------------------------------------*
506   Name:         OSi_GetPrevTitleId
507 
508   Description:  Gets the Title ID of the application that used the OS_JumpToArbitraryApplication function to jump here.
509 
510 
511   Arguments:    None.
512 
513   Returns:      The Title ID of the application that used the OS_JumpToArbitraryApplication function to jump here.
514                 Returns 0 if this application was started from the System Menu or debugger, or if it was run on NITRO.
515 
516 
517  *---------------------------------------------------------------------------*/
OSi_GetPrevTitleId(void)518 OSTitleId OSi_GetPrevTitleId(void)
519 {
520 #ifdef SDK_TWL
521     if( OS_IsRunOnTwl() )
522     {
523         const OSTitleIDList *list = (const OSTitleIDList *)HW_OS_TITLE_ID_LIST;
524         const int   total = MATH_MIN( list->num, OS_TITLEIDLIST_MAX );
525         int i;
526         for (i = 0; i < total; ++i)
527         {
528             if (list->TitleID[i] == s_prevTitleId )
529             {
530                 return s_prevTitleId;
531             }
532         }
533     }
534 #endif
535     return 0;
536 }
537 
538 /*---------------------------------------------------------------------------*
539   Name:         OS_IsBootFromSystemMenu
540 
541   Description:  Determines whether this application was started from the System Menu.
542 
543   Arguments:    None.
544 
545   Returns:      TRUE: This application was started from the System Menu.
546                 FALSE: This application was started from another application.
547  *---------------------------------------------------------------------------*/
OS_IsBootFromSystemMenu(void)548 BOOL OS_IsBootFromSystemMenu( void )
549 {
550 #ifdef SDK_TWL
551     if( OS_IsRunOnTwl() )
552     {
553         if( OSi_GetPrevTitleId() == 0 )
554         {
555             return TRUE;
556         }
557         else
558         {
559             return FALSE;
560         }
561     }
562 #endif
563     return TRUE;
564 }
565 
566 /*---------------------------------------------------------------------------*
567   Name:         OSi_IsJumpFromSameMaker
568 
569   Description:  Determines whether this application was started from an application with the same maker code.
570 
571   Arguments:    None.
572 
573   Returns:      TRUE: This application was started from an application with the same maker code.
574                 FALSE: This application was started from another application or the System Menu.
575  *---------------------------------------------------------------------------*/
OSi_IsJumpFromSameMaker(void)576 BOOL OSi_IsJumpFromSameMaker( void )
577 {
578 #ifdef SDK_TWL
579     if( OS_IsRunOnTwl() )
580     {
581         if( OS_IsBootFromSystemMenu() )
582         {
583             /* Exclude this application in advance if it was started from the System Menu */
584             return FALSE;
585         }
586     return OSi_IsSameMakerCode( s_prevTitleId );
587     }
588 #endif
589     return FALSE;
590 }
591 
592 /*---------------------------------------------------------------------------*
593   Name:         OSi_GetInitialCode
594 
595   Description:  Gets the game code of the running application.
596 
597   Arguments:    None.
598 
599   Returns:      The game code.
600                 This cannot be obtained when run on NITRO, so 0 will be returned.
601  *---------------------------------------------------------------------------*/
OSi_GetInitialCode(void)602 u32 OSi_GetInitialCode(void)
603 {
604 #ifdef SDK_TWL
605     if( OS_IsRunOnTwl() )
606     {
607         return (u32)( OS_GetTitleId() );
608     }
609 #endif
610     return 0;
611 }
612 
613 /*---------------------------------------------------------------------------*
614   Name:         OSi_GetPrevInitialCode
615 
616   Description:  Gets the game code of the application that used the OS_JumpToArbitraryApplication function to jump here.
617 
618 
619   Arguments:    None.
620 
621   Returns:      The game code.
622                 Returns 0 if this application was started from the System Menu or debugger, or if it was run on NITRO because the value cannot be obtained.
623 
624  *---------------------------------------------------------------------------*/
OSi_GetPrevInitialCode(void)625 u32 OSi_GetPrevInitialCode(void)
626 {
627 #ifdef SDK_TWL
628     if( OS_IsRunOnTwl() )
629     {
630         return (u32)( OSi_GetPrevTitleId() );
631     }
632 #endif
633     return 0;
634 }
635 
636 /*---------------------------------------------------------------------------*
637   Name:         OS_IsTemporaryApplication
638 
639   Description:  Checks whether self is a TMP application.
640 
641   Arguments:    None.
642 
643   Returns:      TRUE: TMP application.
644                 FALSE: Other than TMP applications.
645  *---------------------------------------------------------------------------*/
OS_IsTemporaryApplication(void)646 BOOL OS_IsTemporaryApplication(void)
647 {
648 #ifdef SDK_TWL
649     static BOOL isChecked = FALSE, isTmpApp = FALSE;
650     if( OS_IsRunOnTwl() )
651     {
652         if( isChecked == FALSE ) /* If already checked, flow previous results */
653         {
654             if( 0 == STD_CompareNString( OS_GetBootSRLPath(), OSi_TMP_APP_PATH_RAW, OSi_TMP_APP_PATH_RAW_LENGTH ) )
655             {
656                 isTmpApp = TRUE;
657             }
658             else
659             {
660                 isTmpApp = FALSE;
661             }
662             isChecked = TRUE;
663         }
664         return isTmpApp;
665     }
666 #endif
667     return FALSE;
668 }
669 
670 #else // SDK_ARM9
671     //----------------------------------------------------------------
672     // For ARM7
673 
OSi_IsValidLauncherParam(void)674 static BOOL OSi_IsValidLauncherParam( void )
675 {
676     return ( STD_StrNCmp( (const char *)&OSi_GetLauncherParam()->header.magicCode,
677                              OSi_LAUNCHER_PARAM_MAGIC_CODE,
678                              OSi_LAUNCHER_PARAM_MAGIC_CODE_LEN ) == 0 ) &&
679     ( OSi_GetLauncherParam()->header.bodyLength > 0 ) &&
680     ( OSi_GetLauncherParam()->header.crc16 == SVC_GetCRC16( 65535, &OSi_GetLauncherParam()->body, OSi_GetLauncherParam()->header.bodyLength ) );
681 }
682 
OSi_IsEnableJTAG(void)683 static BOOL OSi_IsEnableJTAG( void )
684 {
685     // If SCFG register is invalid, the SCFG register value becomes "0". Check the value retracted to WRAM.
686     u8 value = (u8)(( reg_SCFG_EXT & REG_SCFG_EXT_CFG_MASK ) ?
687                     ( reg_SCFG_JTAG & REG_SCFG_JTAG_CPUJE_MASK ) :
688                     ( *(u8 *)HWi_WSYS09_ADDR & HWi_WSYS09_JTAG_CPUJE_MASK ));
689     return value ? TRUE : FALSE;
690 }
691 
692 // Launcher parameter lead and determine hot/cold boot
693 // Return TRUE if launcher parameter is valid; FALSE if invalid
694 // If the launcher parameter in LauncherParam is valid, that launcher parameter is stored
695 // TRUE if hot boot in isHotstart; False is stored if a cold boot.
OS_ReadLauncherParameter(LauncherParam * buf,BOOL * isHotstart)696 BOOL OS_ReadLauncherParameter( LauncherParam *buf, BOOL *isHotstart )
697 {
698     if( !OSi_GetNandFirmResetParam()->isValid ) {
699         *(u8 *)OSi_GetNandFirmResetParam() = (u8)MCU_GetFreeRegister( OS_MCU_RESET_VALUE_OFS );
700         OSi_GetNandFirmResetParam()->isValid = 1;
701     }
702 
703     // Hot/cold boot determination
704     // If "HOTBT flag of a microcomputer free register = 0," cold boot
705     if( !OSi_GetNandFirmResetParam()->isHotStart ) {
706         *isHotstart = FALSE;
707     }else {
708         *isHotstart = TRUE;
709         // Determine launcher parameter validity
710         if(  OSi_IsValidLauncherParam() &&
711             !OSi_GetNandFirmResetParam()->isResetSW
712         ) {
713             // If launcher parameter is valid, copy to buf
714             MI_CpuCopy32 ( OSi_GetLauncherParam(), buf, sizeof(LauncherParam) );
715             return TRUE;
716         }else {
717             // Else clear the transfer destination buffer
718             MI_CpuClear32 ( buf, sizeof(LauncherParam) );
719         }
720     }
721     return FALSE;
722 }
723 
724 #endif // SDK_ARM9
725