1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - OS
3   File:     os_emulator.c
4 
5   Copyright 2003-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:: 2009-02-06#$
14   $Rev: 9988 $
15   $Author: ooshimay $
16  *---------------------------------------------------------------------------*/
17 #ifdef SDK_TWL
18 #include <twl.h>
19 #else
20 #include <nitro.h>
21 #endif
22 #ifdef SDK_ARM7
23 #include <twl/hw/common/mmap_wramEnv.h>
24 #endif
25 
26 //---- current processor lock flag
27 #ifdef SDK_ARM9
28 #define OSi_CURPROC_LOCKED_FLAG    OS_MAINP_LOCKED_FLAG
29 #else
30 #define OSi_CURPROC_LOCKED_FLAG    OS_SUBP_LOCKED_FLAG
31 #endif
32 
33 #define memorySize()   (*(u16*)HW_MMEMCHECKER_SUB & OS_CONSOLE_SIZE_MASK)
34 #define soundMixFlag() (*(u16*)OS_CHIPTYPE_SMX_ADDR & OS_CHIPTYPE_SMX_MASK)
35 
36 static u32 OSi_DetectDeviceType(void);
37 static u32 OSi_DetectPlatform(void);
38 
39 //================================================================================
40 // Detect ConsoleType
41 //================================================================================
42 /*---------------------------------------------------------------------------*
43   Name:         OS_GetConsoleType
44 
45   Description:  Get console type value
46                 This function returns a fixed value on FINALROM
47 
48   Arguments:    None
49 
50   Returns:		console type value. see include/nitro/os/common/emulator.h
51  *---------------------------------------------------------------------------*/
OS_GetConsoleType(void)52 u32 OS_GetConsoleType(void)
53 {
54 #if defined( SDK_FINALROM ) || defined( SDK_SMALL_BUILD )
55 	static u32 OSi_ConsoleTypeCache = OSi_CONSOLE_NOT_DETECT;
56 
57 	if (OSi_ConsoleTypeCache == OSi_CONSOLE_NOT_DETECT)
58 	{
59 		if ( OS_IsRunOnTwl() )
60 		{
61 			OSi_ConsoleTypeCache = OS_CONSOLE_TWL | OS_CONSOLE_TWLTYPE_RETAIL | OS_CONSOLE_SIZE_16MB;
62 		}
63 		else
64 		{
65 			OSi_ConsoleTypeCache = OS_CONSOLE_NITRO | OS_CONSOLE_SIZE_4MB;
66 		}
67 		OSi_ConsoleTypeCache |= OSi_DetectDeviceType();
68 	}
69 	return OSi_ConsoleTypeCache;
70 #else
71 	return OS_GetRunningConsoleType();
72 #endif
73 }
74 
75 /*---------------------------------------------------------------------------*
76   Name:         OS_GetRunningConsoleType
77 
78   Description:  Get console type value
79                 This function returns a true value in spite of on FINALROM
80 
81   Arguments:    None
82 
83   Returns:      console type value. see include/nitro/os/common/emulator.h
84  *---------------------------------------------------------------------------*/
85 static u32 OSi_RunningConsoleTypeCache = OSi_CONSOLE_NOT_DETECT;
OS_GetRunningConsoleType(void)86 u32 OS_GetRunningConsoleType(void)
87 {
88 #ifdef SDK_ARM9
89 	while( *(vu16*)HW_MMEMCHECKER_SUB == 0 )
90 	{
91 		SVC_WaitByLoop(0x100 / 4);
92 	}
93 #endif
94 
95     if (OSi_RunningConsoleTypeCache == OSi_CONSOLE_NOT_DETECT)
96 	{
97 		u32 emulator = OSi_DetectEmulator();
98 
99 		OSi_RunningConsoleTypeCache =
100 			( (emulator)? emulator: OSi_DetectPlatform() ) |
101 			OSi_DetectDeviceType() |
102 			memorySize();
103 	}
104 	return OSi_RunningConsoleTypeCache;
105 }
106 
107 //---- for debug
108 #ifndef SDK_FINALROM
OS_SetConsoleType(u32 type)109 void OS_SetConsoleType(u32 type)
110 {
111 	OSi_RunningConsoleTypeCache = type;
112 }
113 #endif
114 
115 /*---------------------------------------------------------------------------*
116   Name:         ( OSi_DetectDeviceType )
117 
118   Description:  get device type
119                 (subroutine of OS_GetConsoleType)
120 
121   Arguments:    None
122 
123   Returns:      decided by bus card data loaded
124                 OS_CONSOLE_DEV_CARTRIDGE : via cartridge bus
125                 OS_CONSOLE_DEV_CARD      : via card bus
126                 OS_CONSOLE_DEV_DOWNLOAD  : via download (multiboot)
127                 OS_CONSOLE_DEV_NAND      : via NAND
128                 OS_CONSOLE_DEV_MEMORY    : via memory
129                 OS_CONSOLE_DEV_SDCARD    : via SD card
130  *---------------------------------------------------------------------------*/
OSi_DetectDeviceType(void)131 static u32 OSi_DetectDeviceType(void)
132 {
133 	static const u32 table[]={
134 		0,						// for OS_BOOTTYPE_ILLEGAL
135 		OS_CONSOLE_DEV_CARD,	// for OS_BOOTTYPE_ROM
136 		OS_CONSOLE_DEV_DOWNLOAD,// for OS_BOOTTYPE_DOWNLOAD_MB
137 		OS_CONSOLE_DEV_NAND,	// for OS_BOOTTYPE_NAND
138 		OS_CONSOLE_DEV_MEMORY,	// for OS_BOOTTYPE_MEMORY
139 	};
140 
141 	return table[ OS_GetBootType() ];
142 }
143 
144 /*---------------------------------------------------------------------------*
145   Name:         ( OSi_DetectEmulator )
146 
147   Description:  Detect software emulator Ensata
148                 (subroutine of OS_GetConsoleType)
149 
150   Arguments:    None
151 
152   Returns:      OS_CONSOLE_ENSATA : if detect Ensata
153                 0                 : if not
154  *---------------------------------------------------------------------------*/
OSi_DetectEmulator(void)155 u32 OSi_DetectEmulator(void)
156 {
157 	static u32 OSi_IsDetectedEmulator = FALSE;
158 	static u32 OSi_Emulator;
159 
160 	if ( ! OSi_IsDetectedEmulator )
161 	{
162 #ifdef  SDK_ARM9
163 #ifndef SDK_FINALROM
164 
165 		u32 val;
166 		OSIntrMode intr = OS_DisableInterrupts();
167 
168 		// PING magic number to ensata
169 		(*(REGType32v *)REG_CLIPMTX_RESULT_0_ADDR) = 0x2468ace0;
170 
171 		// PONG magic number from ensata
172 		val = *(vu16 *)REG_VCOUNT_ADDR & 0x1ffU;
173 
174 		if (val == 270)
175 		{
176 			// Recognized as ensata, send back ACK signal to ensata
177 			*(vu32 *)0x4fff010 = 0x13579bdf;        // ACK Signal 1
178 			*(vu32 *)0x4fff010 = 0xfdb97531;        // ACK Signal 2
179 			OSi_Emulator = OS_CONSOLE_ENSATA;
180 		}
181 
182 		(void)OS_RestoreInterrupts(intr);
183 #else
184 		//---- ARM9 FINALROM
185 		OSi_Emulator = 0;
186 #endif
187 
188 #else
189 		//---- ARM7
190 		OSi_Emulator = 0;
191 #endif
192 
193 		OSi_IsDetectedEmulator = TRUE;
194 	}
195 	return OSi_Emulator;
196 }
197 
198 /*---------------------------------------------------------------------------*
199   Name:         ( OSi_DetectPlatform )
200 
201   Description:  Detect Debugger
202                 (subroutine of OS_GetConsoleType)
203 
204   Arguments:    None
205 
206   Returns:      OS_CONSOLE_NITRO
207                 OS_CONSOLE_TWL
208                 OS_CONSOLE_TWLDEBUGGER | OS_CONSOLE_BOARD_A9
209                 OS_CONSOLE_TWLDEBUGGER | OS_CONSOLE_BOARD_A9_A7
210                 0
211  *---------------------------------------------------------------------------*/
OSi_DetectPlatform(void)212 static u32 OSi_DetectPlatform(void)
213 {
214 	static u32 OSi_IsDetectedPlatform = FALSE;
215 	static u32 OSi_Platform;
216 
217 	if ( ! OSi_IsDetectedPlatform )
218 	{
219  		switch( *(u8*)(OS_CHIPTYPE_DEBUGGER_ADDR) & OS_CHIPTYPE_DEBUGGER_MASK )
220 		{
221 			case OS_CHIPTYPE_TWL: // equal to 0, also means running NITRO platform.
222 				{
223 					switch ( memorySize() )
224 					{
225 						case OS_CONSOLE_SIZE_4MB:
226 							OSi_Platform = OS_CONSOLE_NITRO;
227 							break;
228 						case OS_CONSOLE_SIZE_8MB:
229 							{
230 								int isDebuggerFlag = *(u16*)HW_CHECK_DEBUGGER_BUF2;
231 								if ( isDebuggerFlag == 1 )
232 								{
233 									OSi_Platform = OS_CONSOLE_ISDEBUGGER;
234 								}
235 								else
236 								{
237 								// bad status
238 									OSi_Platform = 0;
239 								}
240 							}
241 							break;
242 						case OS_CONSOLE_SIZE_16MB:
243 							OSi_Platform = OS_CONSOLE_TWL | OS_CONSOLE_TWLTYPE_RETAIL;
244 							break;
245 						case OS_CONSOLE_SIZE_32MB:
246 							// bad status
247 							OSi_Platform = 0;
248 							break;
249 						default:
250 							// bad status
251 							OSi_Platform = 0;
252 					}
253 				}
254 				break;
255 			case OS_CHIPTYPE_DEBUGGER_1:
256 				if ( *(u8*)(OS_CHIPTYPE_JTAG_ADDR) & OS_CHIPTYPE_JTAG_MASK)
257 				{
258 					OSi_Platform = OS_CONSOLE_TWLDEBUGGER | OS_CONSOLE_BOARD_A9_A7;
259 				}
260 				else
261 				{
262 					OSi_Platform = OS_CONSOLE_TWL | OS_CONSOLE_BOARD_A9_A7;
263 				}
264 				break;
265 			case OS_CHIPTYPE_DEBUGGER_2:
266 				if ( *(u8*)(OS_CHIPTYPE_JTAG_ADDR) & OS_CHIPTYPE_JTAG_MASK)
267 				{
268 					OSi_Platform = OS_CONSOLE_TWLDEBUGGER | OS_CONSOLE_BOARD_A9;
269 				}
270 				else
271 				{
272 					OSi_Platform = OS_CONSOLE_TWL | OS_CONSOLE_TWLTYPE_DEV;
273 				}
274 				break;
275 			case OS_CHIPTYPE_EVALUATE:
276 				OSi_Platform = OS_CONSOLE_TWL | OS_CONSOLE_TWLTYPE_DEV | OS_CONSOLE_EVALUATE;
277 				break;
278 		}
279 
280 		OSi_IsDetectedPlatform = TRUE;
281 	}
282 	return OSi_Platform;
283 }
284 
285 /*---------------------------------------------------------------------------*
286   Name:         OSi_DetectDebugger
287 
288   Description:  Detect Debugger.
289                 For internal quick check.
290 
291   Arguments:    None
292 
293   Returns:      same as OSi_DetectPlatform
294  *---------------------------------------------------------------------------*/
OSi_DetectDebugger(void)295 u32 OSi_DetectDebugger(void)
296 {
297 	return OSi_DetectPlatform();
298 }
299 
300 //================================================================================
301 // Get Info
302 //================================================================================
303 /*---------------------------------------------------------------------------*
304   Name:         OS_IsRunOnEmulator
305 
306   Description:  Detect software emulator Ensata
307 
308   Arguments:    None
309 
310   Returns:      TRUE  : running on Ensata
311                 FALSE : not running on Ensata
312  *---------------------------------------------------------------------------*/
OS_IsRunOnEmulator(void)313 BOOL OS_IsRunOnEmulator(void)
314 {
315 	return (OS_GetConsoleType() & OS_CONSOLE_ENSATA)? TRUE: FALSE;
316 }
317 
318 /*---------------------------------------------------------------------------*
319   Name:         OS_IsRunOnDebugger
320 
321   Description:  Detect running on debugger.
322 
323   Arguments:    None
324 
325   Returns:      TRUE  : running on debugger
326                 FALSE : not running on debugger
327  *---------------------------------------------------------------------------*/
OS_IsRunOnDebugger(void)328 BOOL OS_IsRunOnDebugger(void)
329 {
330 	return (OS_GetConsoleType() & (OS_CONSOLE_TWLDEBUGGER | OS_CONSOLE_ISDEBUGGER))? TRUE: FALSE;
331 }
332 
333 //================================================================================
334 // (only in TWL HYBRID)  detect platform, TWL or NITRO
335 //================================================================================
336 /*---------------------------------------------------------------------------*
337   Name:         OS_IsRunOnTwl
338 
339   Description:  check running platform
340 
341                 This function is used in only Nitro-TWL hybrid mode.
342                 (In Nitro mode and TWL limited mode, treated as constant)
343 
344   Arguments:    None
345 
346   Returns:      TRUE  : running on TWL
347                 FALSE : running on NITRO
348  *---------------------------------------------------------------------------*/
349 #ifdef SDK_TWLHYB
OS_IsRunOnTwl(void)350 BOOL OS_IsRunOnTwl(void)
351 {
352 	static BOOL OSi_IsDetectedTWL = FALSE;
353 	static BOOL OSi_IsRunOnTWL    = FALSE;
354 
355 	if ( ! OSi_IsDetectedTWL )
356 	{
357 #ifdef SDK_ARM9
358 		u8 rom9 = reg_SCFG_A9ROM;
359 #else // SDK_ARM7
360 		u8 rom9 = (u8)(*(u8*)(HW_PRV_WRAM_SYSRV + HWi_WSYS08_WRAMOFFSET) >> HWi_WSYS08_ROM_ARM9SEC_SHIFT);
361 #endif // SDK_ARM7
362 		OSi_IsRunOnTWL = ( rom9 & (REG_SCFG_A9ROM_SEC_MASK | REG_SCFG_A9ROM_RSEL_MASK) )
363  						 == REG_SCFG_A9ROM_SEC_MASK;
364 
365 		OSi_IsDetectedTWL = TRUE;
366 	}
367 
368 	return OSi_IsRunOnTWL;
369 }
370 #endif
371 
372 //================================================================================
373 // (used in all modes)  detect platform, TWL or NITRO
374 //================================================================================
375 /*---------------------------------------------------------------------------*
376   Name:         OSi_IsRunOnTwl
377 
378   Description:  same as OS_IsRunOnTwl
379 
380                 This function is used in all modes.
381 
382   Arguments:    None
383 
384   Returns:      TRUE  : running on TWL
385                 FALSE : running on NITRO
386  *---------------------------------------------------------------------------*/
387 extern BOOL OSi_IsRunOnTwl(void);
OSi_IsRunOnTwl(void)388 BOOL OSi_IsRunOnTwl(void)
389 {
390     return OS_IsRunOnTwl();
391 }
392 
393 //================================================================================
394 //  check platform on Nitro mode
395 //================================================================================
396 /*---------------------------------------------------------------------------*
397   Name:         OSi_IsNitroModeOnTwl
398 
399   Description:  check running platform
400 
401                 This function is used in Nitro ROM and Hybrid ROM.
402                 (In other mode, treated as constant)
403 
404   Arguments:    None
405 
406   Returns:      TRUE  : running on Nitro mode on TWL hardware.
407                 FALSE : other.
408  *---------------------------------------------------------------------------*/
409 #ifndef SDK_TWLLTD
OSi_IsNitroModeOnTwl(void)410 BOOL OSi_IsNitroModeOnTwl(void)
411 {
412 	static BOOL OSi_IsDetected = FALSE;
413 	static BOOL OSi_IsNitroModeOnTwl = FALSE;
414 
415 	if ( ! OSi_IsDetected )
416 	{
417 		if ( ! OS_IsRunOnTwl() && soundMixFlag() )
418 		{
419 			OSi_IsNitroModeOnTwl = TRUE;
420 		}
421 
422 		OSi_IsDetected = TRUE;
423 	}
424 
425 	return OSi_IsNitroModeOnTwl;
426 }
427 #endif // SDK_TWLLTD
428