1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - OS
3   File:     os_terminate_proc.c
4 
5   Copyright 2006-2008 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:: 2008-09-17#$
14   $Rev: 8556 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 #include <nitro/os/common/system.h>
18 #include <nitro/os/common/interrupt.h>
19 #include <nitro/os/common/emulator.h>
20 #include <nitro/os/common/pxi.h>
21 #include <nitro/os/common/reset.h>
22 
23 #ifdef SDK_TWL
24 #include <twl/fatfs.h>
25 #endif
26 
27 OSTerminateCallback OSi_TerminateCallback = NULL;
28 void* OSi_TerminateCallbackArg = NULL;
29 
30 //============================================================================
31 //          TERMINATE and HALT
32 //============================================================================
33 /*---------------------------------------------------------------------------*
34   Name:         OS_Terminate
35 
36   Description:  finalize and terminate
37 
38   Arguments:    None
39 
40   Returns:      --  (Never return)
41  *---------------------------------------------------------------------------*/
OS_Terminate(void)42 SDK_WEAK_SYMBOL void OS_Terminate(void)
43 {
44 #ifdef SDK_TWL
45     static BOOL terminated = FALSE;
46 #endif
47 
48 	//---- callback
49 	if ( OSi_TerminateCallback )
50 	{
51 		OSTerminateCallback callback = OSi_TerminateCallback;
52 		OSi_TerminateCallback = NULL;
53 		callback( OSi_TerminateCallbackArg );
54 	}
55 
56 #ifdef SDK_TWL
57     if ( ! terminated )
58     {
59         terminated = TRUE;
60 
61         if ( OS_GetProcMode() != OS_PROCMODE_IRQ )
62         {
63             (void)OS_EnableIrq();
64             (void)OS_EnableInterrupts();
65         }
66 
67         if ( OS_IsRunOnTwl() )
68         {
69             if ( FATFSi_IsInitialized() )
70             {
71                 (void)FATFS_UnmountAll();
72             }
73         }
74 
75         //---- send 'TERMINATE' command to ARM7, and terminate itself immediately
76         OSi_SendToPxi(OS_PXI_COMMAND_TERMINATE);
77     }
78 #endif
79 
80     OSi_TerminateCore();
81 }
82 
83 /*---------------------------------------------------------------------------*
84   Name:         OSi_TerminateCore
85 
86   Description:  Halt CPU and loop
87 
88   Arguments:    None
89 
90   Returns:      --  (Never return)
91  *---------------------------------------------------------------------------*/
OSi_TerminateCore(void)92 void OSi_TerminateCore(void)
93 {
94     (void)OS_DisableInterrupts();
95     while (1)
96     {
97         OS_Halt();
98     }
99 }
100 
101 /*---------------------------------------------------------------------------*
102   Name:         OSi_SetTerminateCallback
103 
104   Description:  set terminate callback
105                 (internal function. don't use)
106 
107   Arguments:    callback : callback
108 
109   Returns:      None
110  *---------------------------------------------------------------------------*/
OSi_SetTerminateCallback(OSTerminateCallback callback,void * arg)111 void OSi_SetTerminateCallback( OSTerminateCallback callback, void* arg )
112 {
113 	OSi_TerminateCallback = callback;
114 	OSi_TerminateCallbackArg = arg;
115 }
116 
117 /*---------------------------------------------------------------------------*
118   Name:         OS_Halt
119 
120   Description:  Halt CPU
121 
122   Arguments:    None
123 
124   Returns:      None
125  *---------------------------------------------------------------------------*/
126 #include <nitro/code32.h>
OS_Halt(void)127 SDK_WEAK_SYMBOL asm void OS_Halt( void )
128 {
129         mov     r0, #0
130         mcr     p15, 0, r0, c7, c0, 4
131         bx      lr
132 }
133 #include <nitro/codereset.h>
134 
135 /*---------------------------------------------------------------------------*
136   Name:         OS_Exit / OS_FExit
137 
138   Description:  Display exit string and Terminate.
139                 This is useful for 'loadrun' tool command.
140 
141   Arguments:    console : console to output string
142                 status  : exit status
143 
144   Returns:      --  (Never return)
145  *---------------------------------------------------------------------------*/
OS_Exit(int status)146 SDK_WEAK_SYMBOL void OS_Exit(int status)
147 {
148 	OS_FExit( OS_PRINT_OUTPUT_ERROR, status );
149 }
150 
OS_FExit(int console,int status)151 SDK_WEAK_SYMBOL void OS_FExit(int console, int status)
152 {
153 #ifdef SDK_FINALROM
154 #pragma unused( console, status )
155 #endif
156     (void)OS_DisableInterrupts();
157     OS_FPrintf( console, "\n" OS_EXIT_STRING, status);
158     OS_Terminate();
159 }
160