1 /*-------------------------------------------------------------
3 system.c -- OS functions and initialization
6 Michael Wiedenbauer (shagkur)
7 Dave Murphy (WinterMute)
9 This software is provided 'as-is', without any express or implied
10 warranty. In no event will the authors be held liable for any
11 damages arising from the use of this software.
13 Permission is granted to anyone to use this software for any
14 purpose, including commercial applications, and to alter it and
15 redistribute it freely, subject to the following restrictions:
17 1. The origin of this software must not be misrepresented; you
18 must not claim that you wrote the original software. If you use
19 this software in a product, an acknowledgment in the product
20 documentation would be appreciated but is not required.
22 2. Altered source versions must be plainly marked as such, and
23 must not be misrepresented as being the original software.
25 3. This notice may not be removed or altered from any source
28 -------------------------------------------------------------*/
30 //#define DEBUG_SYSTEM
36 #include <sys/iosupport.h>
47 #include "wiilaunch.h"
52 #include "sys_state.h"
53 #include "lwp_threads.h"
54 #include "lwp_priority.h"
55 #include "lwp_watchdog.h"
56 #include "lwp_wkspace.h"
57 #include "lwp_objmgr.h"
58 #include "lwp_config.h"
59 #include "libversion.h"
61 #define SYSMEM1_SIZE 0x01800000
63 #define SYSMEM2_SIZE 0x04000000
65 #define KERNEL_HEAP (1*1024*1024)
68 #define DSPCR_DSPRESET 0x0800 // Reset DSP
69 #define DSPCR_DSPDMA 0x0200 // ARAM dma in progress, if set
70 #define DSPCR_DSPINTMSK 0x0100 // * interrupt mask (RW)
71 #define DSPCR_DSPINT 0x0080 // * interrupt active (RWC)
72 #define DSPCR_ARINTMSK 0x0040
73 #define DSPCR_ARINT 0x0020
74 #define DSPCR_AIINTMSK 0x0010
75 #define DSPCR_AIINT 0x0008
76 #define DSPCR_HALT 0x0004 // halt DSP
77 #define DSPCR_PIINT 0x0002 // assert DSP PI interrupt
78 #define DSPCR_RES 0x0001 // reset DSP
80 #define LWP_OBJTYPE_SYSWD 7
82 #define LWP_CHECK_SYSWD(hndl) \
84 if(((hndl)==SYS_WD_NULL) || (LWP_OBJTYPE(hndl)!=LWP_OBJTYPE_SYSWD)) \
88 #define _SHIFTL(v, s, w) \
89 ((u32) (((u32)(v) & ((0x01 << (w)) - 1)) << (s)))
90 #define _SHIFTR(v, s, w) \
91 ((u32)(((u32)(v) >> (s)) & ((0x01 << (w)) - 1)))
99 } sramcntrl
ATTRIBUTE_ALIGN(32);
101 typedef struct _alarm_st
108 alarmcallback alarmhandler
;
112 typedef struct _yay0header
{
113 unsigned int id ATTRIBUTE_PACKED
;
114 unsigned int dec_size ATTRIBUTE_PACKED
;
115 unsigned int links_offset ATTRIBUTE_PACKED
;
116 unsigned int chunks_offset ATTRIBUTE_PACKED
;
119 static u16 sys_fontenc
= 0xffff;
120 static u32 sys_fontcharsinsheet
= 0;
121 static u8
*sys_fontwidthtab
= NULL
;
122 static u8
*sys_fontimage
= NULL
;
123 static sys_fontheader
*sys_fontdata
= NULL
;
125 static lwp_queue sys_reset_func_queue
;
126 static u32 system_initialized
= 0;
127 static lwp_objinfo sys_alarm_objects
;
129 static void *__sysarena1lo
= NULL
;
130 static void *__sysarena1hi
= NULL
;
133 static void *__sysarena2lo
= NULL
;
134 static void *__sysarena2hi
= NULL
;
135 static void *__ipcbufferlo
= NULL
;
136 static void *__ipcbufferhi
= NULL
;
139 static void __RSWDefaultHandler();
140 static resetcallback __RSWCallback
= NULL
;
142 static void __POWDefaultHandler();
143 static powercallback __POWCallback
= NULL
;
145 static u32 __sys_resetdown
= 0;
148 static vu16
* const _viReg
= (u16
*)0xCC002000;
149 static vu32
* const _piReg
= (u32
*)0xCC003000;
150 static vu16
* const _memReg
= (u16
*)0xCC004000;
151 static vu16
* const _dspReg
= (u16
*)0xCC005000;
153 void __SYS_ReadROM(void *buf
,u32 len
,u32 offset
);
154 void* SYS_AllocArena1MemLo(u32 size
,u32 align
);
156 static s32
__sram_sync(void);
157 static s32
__sram_writecallback(s32 chn
,s32 dev
);
158 static s32
__mem_onreset(s32 final
);
160 extern void __lwp_thread_coreinit(void);
161 extern void __lwp_sysinit(void);
162 extern void __heap_init(void);
163 extern void __exception_init(void);
164 extern void __exception_closeall(void);
165 extern void __systemcall_init(void);
166 extern void __decrementer_init(void);
167 extern void __lwp_mutex_init(void);
168 extern void __lwp_cond_init(void);
169 extern void __lwp_mqbox_init(void);
170 extern void __lwp_sema_init(void);
171 extern void __exi_init(void);
172 extern void __si_init(void);
173 extern void __irq_init(void);
174 extern void __lwp_start_multitasking(void);
175 extern void __timesystem_init(void);
176 extern void __memlock_init(void);
177 extern void __libc_init(int);
179 extern void __libogc_malloc_lock( struct _reent
*ptr
);
180 extern void __libogc_malloc_unlock( struct _reent
*ptr
);
182 extern void __exception_console(void);
183 extern void __exception_printf(const char *str
, ...);
185 extern void __realmode(void*);
186 extern void __configMEM1_24Mb(void);
187 extern void __configMEM1_48Mb(void);
188 extern void __configMEM2_64Mb(void);
189 extern void __configMEM2_128Mb(void);
190 extern void __reset(u32 reset_code
);
192 extern u32
__IPC_ClntInit(void);
193 extern u32
__PADDisableRecalibration(s32 disable
);
195 extern void __console_init_ex(void *conbuffer
,int tgt_xstart
,int tgt_ystart
,int tgt_stride
,int con_xres
,int con_yres
,int con_stride
);
197 extern int clock_gettime(struct timespec
*tp
);
198 extern void timespec_subtract(const struct timespec
*tp_start
,const struct timespec
*tp_end
,struct timespec
*result
);
201 extern int __libogc_lock_init(int *lock
,int recursive
);
202 extern int __libogc_lock_close(int *lock
);
203 extern int __libogc_lock_release(int *lock
);
204 extern int __libogc_lock_acquire(int *lock
);
205 extern void __libogc_exit(int status
);
206 extern void * __libogc_sbrk_r(struct _reent
*ptr
, ptrdiff_t incr
);
207 extern int __libogc_gettod_r(struct _reent
*ptr
, struct timeval
*tp
, struct timezone
*tz
);
209 extern u8 __gxregs
[];
210 extern u8 __text_start
[];
212 extern u8 __Arena1Lo
[], __Arena1Hi
[];
214 extern u8 __Arena2Lo
[], __Arena2Hi
[];
215 extern u8 __ipcbufferLo
[], __ipcbufferHi
[];
218 u8
*__argvArena1Lo
= (u8
*)0xdeadbeef;
220 static u32 __sys_inIPL
= (u32
)__isIPL
;
222 static u32 _dsp_initcode
[] =
224 0x029F0010,0x029F0033,0x029F0034,0x029F0035,
225 0x029F0036,0x029F0037,0x029F0038,0x029F0039,
226 0x12061203,0x12041205,0x00808000,0x0088FFFF,
227 0x00841000,0x0064001D,0x02180000,0x81001C1E,
228 0x00441B1E,0x00840800,0x00640027,0x191E0000,
229 0x00DEFFFC,0x02A08000,0x029C0028,0x16FC0054,
230 0x16FD4348,0x002102FF,0x02FF02FF,0x02FF02FF,
231 0x02FF02FF,0x00000000,0x00000000,0x00000000
234 static sys_resetinfo mem_resetinfo
= {
240 static const char *__sys_versiondate
;
241 static const char *__sys_versionbuild
;
243 static __inline__ alarm_st
* __lwp_syswd_open(syswd_t wd
)
246 return (alarm_st
*)__lwp_objmgr_get(&sys_alarm_objects
,LWP_OBJMASKID(wd
));
249 static __inline__
void __lwp_syswd_free(alarm_st
*alarm
)
251 __lwp_objmgr_close(&sys_alarm_objects
,&alarm
->object
);
252 __lwp_objmgr_free(&sys_alarm_objects
,&alarm
->object
);
256 #define SOFTRESET_ADR *((vu32*)0xCC003024)
257 void __reload() { SOFTRESET_ADR
=0; }
259 void __libogc_exit(int status
)
261 SYS_ResetSystem(SYS_SHUTDOWN
,0,0);
262 __lwp_thread_stopmultitasking(__reload
);
265 static void (*reload
)() = (void(*)())0x80001800;
267 static bool __stub_found()
269 u64 sig
= ((u64
)(*(u32
*)0x80001804) << 32) + *(u32
*)0x80001808;
270 if (sig
== 0x5354554248415858ULL
) // 'STUBHAXX'
279 SYS_ResetSystem(SYS_RETURNTOMENU
, 0, 0);
282 void __libogc_exit(int status
)
285 SYS_ResetSystem(SYS_SHUTDOWN
,0,0);
286 __lwp_thread_stopmultitasking(reload
);
288 SYS_ResetSystem(SYS_RETURNTOMENU
, 0, 0);
292 static void __init_syscall_array() {
293 __syscalls
.sbrk_r
= __libogc_sbrk_r
;
294 __syscalls
.lock_init
= __libogc_lock_init
;
295 __syscalls
.lock_close
= __libogc_lock_close
;
296 __syscalls
.lock_release
= __libogc_lock_release
;
297 __syscalls
.lock_acquire
= __libogc_lock_acquire
;
298 __syscalls
.malloc_lock
= __libogc_malloc_lock
;
299 __syscalls
.malloc_unlock
= __libogc_malloc_unlock
;
300 __syscalls
.exit
= __libogc_exit
;
301 __syscalls
.gettod_r
= __libogc_gettod_r
;
305 static alarm_st
* __lwp_syswd_allocate()
309 __lwp_thread_dispatchdisable();
310 alarm
= (alarm_st
*)__lwp_objmgr_allocate(&sys_alarm_objects
);
312 __lwp_objmgr_open(&sys_alarm_objects
,&alarm
->object
);
315 __lwp_thread_dispatchenable();
319 static s32
__mem_onreset(s32 final
)
323 __UnmaskIrq(IM_MEM0
|IM_MEM1
|IM_MEM2
|IM_MEM3
);
328 static void __sys_alarmhandler(void *arg
)
331 syswd_t thealarm
= (syswd_t
)arg
;
333 if(thealarm
==SYS_WD_NULL
|| LWP_OBJTYPE(thealarm
)!=LWP_OBJTYPE_SYSWD
) return;
335 __lwp_thread_dispatchdisable();
336 alarm
= (alarm_st
*)__lwp_objmgr_getnoprotection(&sys_alarm_objects
,LWP_OBJMASKID(thealarm
));
338 if(alarm
->alarmhandler
) alarm
->alarmhandler(thealarm
,alarm
->cb_arg
);
339 if(alarm
->periodic
) __lwp_wd_insert_ticks(&alarm
->alarm
,alarm
->periodic
);
341 __lwp_thread_dispatchunnest();
345 static void __dohotreset(u32 resetcode
)
349 _CPU_ISR_Disable(level
);
352 __reset(resetcode
<<3);
356 static s32
__call_resetfuncs(s32 final
)
360 lwp_queue
*header
= &sys_reset_func_queue
;
363 info
= (sys_resetinfo
*)header
->first
;
364 while(info
!=(sys_resetinfo
*)__lwp_queue_tail(header
)) {
365 if(info
->func
&& info
->func(final
)==0) ret
|= (ret
<<1);
366 info
= (sys_resetinfo
*)info
->node
.next
;
368 if(__sram_sync()==0) ret
|= (ret
<<1);
370 if(ret
&~0x01) return 0;
375 static void __doreboot(u32 resetcode
,s32 force_menu
)
379 _CPU_ISR_Disable(level
);
381 *((u32
*)0x817ffffc) = 0;
382 *((u32
*)0x817ffff8) = 0;
383 *((u32
*)0x800030e2) = 1;
387 static void __MEMInterruptHandler()
392 static void __RSWDefaultHandler()
398 static void __POWDefaultHandler()
404 static void __RSWHandler()
408 static u32 last_state
= 0;
409 static s64 hold_down
= 0;
411 hold_down
= gettime();
414 if(diff_usec(hold_down
,now
)>=100) break;
415 } while(!(_piReg
[0]&0x10000));
417 if(_piReg
[0]&0x10000) {
420 __MaskIrq(IRQMASK(IRQ_PI_RSW
));
432 static void __STMEventHandler(u32 event
)
437 if(event
==STM_EVENT_RESET
) {
438 ret
= SYS_ResetButtonDown();
440 _CPU_ISR_Disable(level
);
443 _CPU_ISR_Restore(level
);
447 if(event
==STM_EVENT_POWER
) {
448 _CPU_ISR_Disable(level
);
450 _CPU_ISR_Restore(level
);
455 void * __attribute__ ((weak
)) __myArena1Lo
= 0;
456 void * __attribute__ ((weak
)) __myArena1Hi
= 0;
458 static void __lowmem_init()
460 u32
*_gx
= (u32
*)__gxregs
;
463 void *ram_start
= (void*)0x80000000;
464 void *ram_end
= (void*)(0x80000000|SYSMEM1_SIZE
);
465 void *arena_start
= (void*)0x80003000;
466 #elif defined(HW_RVL)
467 void *arena_start
= (void*)0x80003F00;
471 memset(arena_start
,0,0x100);
472 if ( __argvArena1Lo
== (u8
*)0xdeadbeef ) __argvArena1Lo
= __Arena1Lo
;
473 if (__myArena1Lo
== 0) __myArena1Lo
= __argvArena1Lo
;
474 if (__myArena1Hi
== 0) __myArena1Hi
= __Arena1Hi
;
477 memset(ram_start
,0,0x100);
478 *((u32
*)(ram_start
+0x20)) = 0x0d15ea5e; // magic word "disease"
479 *((u32
*)(ram_start
+0x24)) = 1; // version
480 *((u32
*)(ram_start
+0x28)) = SYSMEM1_SIZE
; // physical memory size
481 *((u32
*)(ram_start
+0x2C)) = 1 + ((*(u32
*)0xCC00302c)>>28);
483 *((u32
*)(ram_start
+0x30)) = (u32
)__myArena1Lo
;
484 *((u32
*)(ram_start
+0x34)) = (u32
)__myArena1Hi
;
486 *((u32
*)(ram_start
+0xEC)) = (u32
)ram_end
; // ram_end (??)
487 *((u32
*)(ram_start
+0xF0)) = SYSMEM1_SIZE
; // simulated memory size
488 *((u32
*)(ram_start
+0xF8)) = TB_BUS_CLOCK
; // bus speed: 162 MHz
489 *((u32
*)(ram_start
+0xFC)) = TB_CORE_CLOCK
; // cpu speed: 486 Mhz
491 *((u16
*)(arena_start
+0xE0)) = 6; // production pads
492 *((u32
*)(arena_start
+0xE4)) = 0xC0008000;
494 DCFlushRangeNoSync(ram_start
, 0x100);
497 DCFlushRangeNoSync(arena_start
, 0x100);
498 DCFlushRangeNoSync(_gx
, 2048);
501 SYS_SetArenaLo((void*)__myArena1Lo
);
502 SYS_SetArenaHi((void*)__myArena1Hi
);
504 SYS_SetArena2Lo((void*)__Arena2Lo
);
505 SYS_SetArena2Hi((void*)__Arena2Hi
);
510 static void __ipcbuffer_init()
512 __ipcbufferlo
= (void*)__ipcbufferLo
;
513 __ipcbufferhi
= (void*)__ipcbufferHi
;
517 static void __bat_config()
519 u32 realmem1
= SYSMEM1_SIZE
;
520 u32 simmem1
= SYSMEM1_SIZE
;
522 u32 simmem2
= SYSMEM2_SIZE
;
525 if(simmem1
<realmem1
&& !(simmem1
-0x1800000)) {
526 DCInvalidateRange((void*)0x81800000,0x01800000);
530 if(simmem1
<=0x01800000) __realmode(__configMEM1_24Mb
);
531 else if(simmem1
<=0x03000000) __realmode(__configMEM1_48Mb
);
534 if(simmem2
<=0x04000000) __realmode(__configMEM2_64Mb
);
535 else if(simmem2
<=0x08000000) __realmode(__configMEM2_128Mb
);
539 static void __memprotect_init()
543 _CPU_ISR_Disable(level
);
545 __MaskIrq((IM_MEM0
|IM_MEM1
|IM_MEM2
|IM_MEM3
));
550 IRQ_Request(IRQ_MEM0
,__MEMInterruptHandler
,NULL
);
551 IRQ_Request(IRQ_MEM1
,__MEMInterruptHandler
,NULL
);
552 IRQ_Request(IRQ_MEM2
,__MEMInterruptHandler
,NULL
);
553 IRQ_Request(IRQ_MEM3
,__MEMInterruptHandler
,NULL
);
554 IRQ_Request(IRQ_MEMADDRESS
,__MEMInterruptHandler
,NULL
);
556 SYS_RegisterResetFunc(&mem_resetinfo
);
558 __UnmaskIrq(IM_MEMADDRESS
); //only enable memaddress irq atm
560 _CPU_ISR_Restore(level
);
563 static __inline__ u32
__get_fontsize(void *buffer
)
565 u8
*ptr
= (u8
*)buffer
;
567 if(ptr
[0]=='Y' && ptr
[1]=='a' && ptr
[2]=='y') return (((u32
*)ptr
)[1]);
571 static u32
__read_rom(void *buf
,u32 len
,u32 offset
)
576 DCInvalidateRange(buf
,len
);
578 if(EXI_Lock(EXI_CHANNEL_0
,EXI_DEVICE_1
,NULL
)==0) return 0;
579 if(EXI_Select(EXI_CHANNEL_0
,EXI_DEVICE_1
,EXI_SPEED8MHZ
)==0) {
580 EXI_Unlock(EXI_CHANNEL_0
);
586 if(EXI_Imm(EXI_CHANNEL_0
,&loff
,4,EXI_WRITE
,NULL
)==0) ret
|= 0x0001;
587 if(EXI_Sync(EXI_CHANNEL_0
)==0) ret
|= 0x0002;
588 if(EXI_Dma(EXI_CHANNEL_0
,buf
,len
,EXI_READ
,NULL
)==0) ret
|= 0x0004;
589 if(EXI_Sync(EXI_CHANNEL_0
)==0) ret
|= 0x0008;
590 if(EXI_Deselect(EXI_CHANNEL_0
)==0) ret
|= 0x0010;
591 if(EXI_Unlock(EXI_CHANNEL_0
)==0) ret
|= 0x00020;
597 static u32
__getrtc(u32
*gctime
)
603 if(EXI_Lock(EXI_CHANNEL_0
,EXI_DEVICE_1
,NULL
)==0) return 0;
604 if(EXI_Select(EXI_CHANNEL_0
,EXI_DEVICE_1
,EXI_SPEED8MHZ
)==0) {
605 EXI_Unlock(EXI_CHANNEL_0
);
612 if(EXI_Imm(EXI_CHANNEL_0
,&cmd
,4,EXI_WRITE
,NULL
)==0) ret
|= 0x01;
613 if(EXI_Sync(EXI_CHANNEL_0
)==0) ret
|= 0x02;
614 if(EXI_Imm(EXI_CHANNEL_0
,&time
,4,EXI_READ
,NULL
)==0) ret
|= 0x04;
615 if(EXI_Sync(EXI_CHANNEL_0
)==0) ret
|= 0x08;
616 if(EXI_Deselect(EXI_CHANNEL_0
)==0) ret
|= 0x10;
618 EXI_Unlock(EXI_CHANNEL_0
);
625 static u32
__sram_read(void *buffer
)
629 DCInvalidateRange(buffer
,64);
631 if(EXI_Lock(EXI_CHANNEL_0
,EXI_DEVICE_1
,NULL
)==0) return 0;
632 if(EXI_Select(EXI_CHANNEL_0
,EXI_DEVICE_1
,EXI_SPEED8MHZ
)==0) {
633 EXI_Unlock(EXI_CHANNEL_0
);
638 command
= 0x20000100;
639 if(EXI_Imm(EXI_CHANNEL_0
,&command
,4,EXI_WRITE
,NULL
)==0) ret
|= 0x01;
640 if(EXI_Sync(EXI_CHANNEL_0
)==0) ret
|= 0x02;
641 if(EXI_Dma(EXI_CHANNEL_0
,buffer
,64,EXI_READ
,NULL
)==0) ret
|= 0x04;
642 if(EXI_Sync(EXI_CHANNEL_0
)==0) ret
|= 0x08;
643 if(EXI_Deselect(EXI_CHANNEL_0
)==0) ret
|= 0x10;
644 if(EXI_Unlock(EXI_CHANNEL_0
)==0) ret
|= 0x20;
650 static u32
__sram_write(void *buffer
,u32 loc
,u32 len
)
654 if(EXI_Lock(EXI_CHANNEL_0
,EXI_DEVICE_1
,__sram_writecallback
)==0) return 0;
655 if(EXI_Select(EXI_CHANNEL_0
,EXI_DEVICE_1
,EXI_SPEED8MHZ
)==0) {
656 EXI_Unlock(EXI_CHANNEL_0
);
661 cmd
= 0xa0000100+(loc
<<6);
662 if(EXI_Imm(EXI_CHANNEL_0
,&cmd
,4,EXI_WRITE
,NULL
)==0) ret
|= 0x01;
663 if(EXI_Sync(EXI_CHANNEL_0
)==0) ret
|= 0x02;
664 if(EXI_ImmEx(EXI_CHANNEL_0
,buffer
,len
,EXI_WRITE
)==0) ret
|= 0x04;
665 if(EXI_Deselect(EXI_CHANNEL_0
)==0) ret
|= 0x08;
666 if(EXI_Unlock(EXI_CHANNEL_0
)==0) ret
|= 0x10;
672 static s32
__sram_writecallback(s32 chn
,s32 dev
)
674 sramcntrl
.sync
= __sram_write(sramcntrl
.srambuf
+sramcntrl
.offset
,sramcntrl
.offset
,(64-sramcntrl
.offset
));
675 if(sramcntrl
.sync
) sramcntrl
.offset
= 64;
680 static s32
__sram_sync()
682 return sramcntrl
.sync
;
687 sramcntrl
.enabled
= 0;
688 sramcntrl
.locked
= 0;
689 sramcntrl
.sync
= __sram_read(sramcntrl
.srambuf
);
691 sramcntrl
.offset
= 64;
694 static void DisableWriteGatherPipe()
696 mtspr(920,(mfspr(920)&~0x40000000));
699 static void __buildchecksum(u16
*buffer
,u16
*c1
,u16
*c2
)
707 *c2
+= buffer
[6+i
]^-1;
711 static void* __locksram(u32 loc
)
715 _CPU_ISR_Disable(level
);
716 if(!sramcntrl
.locked
) {
717 sramcntrl
.enabled
= level
;
718 sramcntrl
.locked
= 1;
719 return (void*)((u32
)sramcntrl
.srambuf
+loc
);
721 _CPU_ISR_Restore(level
);
725 static u32
__unlocksram(u32 write
,u32 loc
)
727 syssram
*sram
= (syssram
*)sramcntrl
.srambuf
;
731 if((sram
->flags
&0x03)>0x02) sram
->flags
= (sram
->flags
&~0x03);
732 __buildchecksum((u16
*)sramcntrl
.srambuf
,&sram
->checksum
,&sram
->checksum_inv
);
734 if(loc
<sramcntrl
.offset
) sramcntrl
.offset
= loc
;
736 sramcntrl
.sync
= __sram_write(sramcntrl
.srambuf
+sramcntrl
.offset
,sramcntrl
.offset
,(64-sramcntrl
.offset
));
737 if(sramcntrl
.sync
) sramcntrl
.offset
= 64;
739 sramcntrl
.locked
= 0;
740 _CPU_ISR_Restore(sramcntrl
.enabled
);
741 return sramcntrl
.sync
;
744 //returns the size of font
745 static u32
__read_font(void *buffer
)
747 if(SYS_GetFontEncoding()==1) __SYS_ReadROM(buffer
,315392,1769216);
748 else __SYS_ReadROM(buffer
,12288,2084608);
749 return __get_fontsize(buffer
);
752 static void __expand_font(const u8
*src
,u8
*dest
)
757 u8
*data
= (u8
*)sys_fontdata
+44;
759 if(sys_fontdata
->sheet_format
==0x0000) {
760 cnt
= (sys_fontdata
->sheet_fullsize
/2)-1;
763 idx
= _SHIFTR(src
[cnt
],6,2);
766 idx
= _SHIFTR(src
[cnt
],4,2);
769 dest
[(cnt
<<1)+0] =((val1
&0xf0)|(val2
&0x0f));
771 idx
= _SHIFTR(src
[cnt
],2,2);
774 idx
= _SHIFTR(src
[cnt
],0,2);
777 dest
[(cnt
<<1)+1] =((val1
&0xf0)|(val2
&0x0f));
782 DCStoreRange(dest
,sys_fontdata
->sheet_fullsize
);
785 static void __dsp_bootstrap()
790 memcpy(SYS_GetArenaHi()-128,(void*)0x81000000,128);
791 memcpy((void*)0x81000000,_dsp_initcode
,128);
792 DCFlushRange((void*)0x81000000,128);
795 _dspReg
[5] = (DSPCR_DSPRESET
|DSPCR_DSPINT
|DSPCR_ARINT
|DSPCR_AIINT
|DSPCR_HALT
);
796 _dspReg
[5] |= DSPCR_RES
;
797 while(_dspReg
[5]&DSPCR_RES
);
800 while((_SHIFTL(_dspReg
[2],16,16)|(_dspReg
[3]&0xffff))&0x80000000);
802 ((u32
*)_dspReg
)[8] = 0x01000000;
803 ((u32
*)_dspReg
)[9] = 0;
804 ((u32
*)_dspReg
)[10] = 32;
807 while(!(status
&DSPCR_ARINT
)) status
= _dspReg
[5];
811 while((gettick()-tick
)<2194);
813 ((u32
*)_dspReg
)[8] = 0x01000000;
814 ((u32
*)_dspReg
)[9] = 0;
815 ((u32
*)_dspReg
)[10] = 32;
818 while(!(status
&DSPCR_ARINT
)) status
= _dspReg
[5];
821 _dspReg
[5] &= ~DSPCR_DSPRESET
;
822 while(_dspReg
[5]&0x400);
824 _dspReg
[5] &= ~DSPCR_HALT
;
825 while(!(_dspReg
[2]&0x8000));
828 _dspReg
[5] |= DSPCR_HALT
;
829 _dspReg
[5] = (DSPCR_DSPRESET
|DSPCR_DSPINT
|DSPCR_ARINT
|DSPCR_AIINT
|DSPCR_HALT
);
830 _dspReg
[5] |= DSPCR_RES
;
831 while(_dspReg
[5]&DSPCR_RES
);
833 memcpy((void*)0x81000000,SYS_GetArenaHi()-128,128);
835 printf("__audiosystem_init(finish)\n");
839 static void __dsp_shutdown()
843 _dspReg
[5] = (DSPCR_DSPRESET
|DSPCR_HALT
);
844 _dspReg
[27] &= ~0x8000;
845 while(_dspReg
[5]&0x400);
846 while(_dspReg
[5]&0x200);
848 _dspReg
[5] = (DSPCR_DSPRESET
|DSPCR_DSPINT
|DSPCR_ARINT
|DSPCR_AIINT
|DSPCR_HALT
);
850 while((_SHIFTL(_dspReg
[2],16,16)|(_dspReg
[3]&0xffff))&0x80000000);
853 while((gettick()-tick
)<44);
855 _dspReg
[5] |= DSPCR_RES
;
856 while(_dspReg
[5]&DSPCR_RES
);
859 static void decode_szp(void *src
,void *dest
)
864 u32 size
,cnt
,cmask
,bcnt
;
868 header
= (yay0header
*)src
;
869 size
= header
->dec_size
;
870 loff
= header
->links_offset
;
871 coff
= header
->chunks_offset
;
873 roff
= sizeof(yay0header
);
880 cmask
= *(u32
*)(src
+roff
);
885 if(cmask
&0x80000000) {
886 dest8
[cnt
++] = *(u8
*)(src
+coff
);
889 link
= *(u16
*)(src
+loff
);
892 tmp
= dest8
+(cnt
-(link
&0x0fff)-1);
895 k
= (*(u8
*)(src
+coff
))+18;
900 dest8
[cnt
++] = tmp
[i
];
908 syssram
* __SYS_LockSram()
910 return (syssram
*)__locksram(0);
913 syssramex
* __SYS_LockSramEx()
915 return (syssramex
*)__locksram(sizeof(syssram
));
918 u32
__SYS_UnlockSram(u32 write
)
920 return __unlocksram(write
,0);
923 u32
__SYS_UnlockSramEx(u32 write
)
925 return __unlocksram(write
,sizeof(syssram
));
930 return __sram_sync();
933 void __SYS_ReadROM(void *buf
,u32 len
,u32 offset
)
938 cpy_cnt
= (len
>256)?256:len
;
939 while(__read_rom(buf
,cpy_cnt
,offset
)==0);
946 u32
__SYS_GetRTC(u32
*gctime
)
954 if(__getrtc(&time1
)==0) ret
|= 0x01;
955 if(__getrtc(&time2
)==0) ret
|= 0x02;
966 void __SYS_SetTime(s64 time
)
970 s64
*pBootTime
= (s64
*)0x800030d8;
972 _CPU_ISR_Disable(level
);
979 _CPU_ISR_Restore(level
);
982 s64
__SYS_GetSystemTime()
986 s64
*pBootTime
= (s64
*)0x800030d8;
988 _CPU_ISR_Disable(level
);
991 _CPU_ISR_Restore(level
);
995 void __SYS_SetBootTime()
1000 sram
= __SYS_LockSram();
1001 __SYS_GetRTC(&gctime
);
1002 __SYS_SetTime(secs_to_ticks(gctime
));
1003 __SYS_UnlockSram(0);
1006 u32
__SYS_LoadFont(void *src
,void *dest
)
1008 if(__read_font(src
)==0) return 0;
1010 decode_szp(src
,dest
);
1012 sys_fontdata
= (sys_fontheader
*)dest
;
1013 sys_fontwidthtab
= (u8
*)dest
+sys_fontdata
->width_table
;
1014 sys_fontcharsinsheet
= sys_fontdata
->sheet_column
*sys_fontdata
->sheet_row
;
1016 /* TODO: implement SJIS handling */
1021 void* __SYS_GetIPCBufferLo()
1023 return __ipcbufferlo
;
1026 void* __SYS_GetIPCBufferHi()
1028 return __ipcbufferhi
;
1033 void _V_EXPORTNAME(void)
1034 { __sys_versionbuild
= _V_STRING
; __sys_versiondate
= _V_DATE_
; }
1037 void __SYS_DoPowerCB(void)
1040 powercallback powcb
;
1042 _CPU_ISR_Disable(level
);
1043 powcb
= __POWCallback
;
1044 __POWCallback
= __POWDefaultHandler
;
1046 _CPU_ISR_Restore(level
);
1050 void __SYS_InitCallbacks()
1053 __POWCallback
= __POWDefaultHandler
;
1054 __sys_resetdown
= 0;
1056 __RSWCallback
= __RSWDefaultHandler
;
1059 void __attribute__((weak
)) __SYS_PreInit()
1070 _CPU_ISR_Disable(level
);
1072 if(system_initialized
) return;
1073 system_initialized
= 1;
1077 __init_syscall_array();
1082 __lwp_wkspace_init(KERNEL_HEAP
);
1083 __lwp_queue_init_empty(&sys_reset_func_queue
);
1084 __lwp_objmgr_initinfo(&sys_alarm_objects
,LWP_MAX_WATCHDOGS
,sizeof(alarm_st
));
1086 __lwp_priority_init();
1087 __lwp_watchdog_init();
1089 __systemcall_init();
1090 __decrementer_init();
1095 __lwp_thread_coreinit();
1102 __timesystem_init();
1106 __memprotect_init();
1109 __SYS_SetBootTime();
1111 DisableWriteGatherPipe();
1112 __SYS_InitCallbacks();
1115 #elif defined(HW_DOL)
1116 IRQ_Request(IRQ_PI_RSW
,__RSWHandler
,NULL
);
1117 __MaskIrq(IRQMASK(IRQ_PI_RSW
));
1120 __lwp_thread_startmultitasking();
1121 _CPU_ISR_Restore(level
);
1124 // This function gets called inside the main thread, prior to the application's main() function
1128 __IOS_LoadStartupIOS();
1129 __IOS_InitializeSubsystems();
1130 STM_RegisterEventHandler(__STMEventHandler
);
1136 u32
SYS_ResetButtonDown()
1138 return (!(_piReg
[0]&0x00010000));
1142 void SYS_ResetSystem(s32 reset
,u32 reset_code
,s32 force_menu
)
1149 if(reset
==SYS_SHUTDOWN
) {
1150 ret
= __PADDisableRecalibration(TRUE
);
1153 while(__call_resetfuncs(FALSE
)==0);
1155 if(reset
==SYS_HOTRESET
&& force_menu
==TRUE
) {
1156 sram
= __SYS_LockSram();
1157 sram
->flags
|= 0x40;
1158 __SYS_UnlockSram(TRUE
);
1159 while(!__SYS_SyncSram());
1162 _CPU_ISR_Disable(level
);
1163 __call_resetfuncs(TRUE
);
1167 __lwp_thread_dispatchdisable();
1168 if(reset
==SYS_HOTRESET
) {
1169 __dohotreset(reset_code
);
1170 } else if(reset
==SYS_RESTART
) {
1171 __lwp_thread_closeall();
1172 __lwp_thread_dispatchunnest();
1173 __doreboot(reset_code
,force_menu
);
1176 __lwp_thread_closeall();
1178 memset((void*)0x80000040,0,140);
1179 memset((void*)0x800000D4,0,20);
1180 memset((void*)0x800000F4,0,4);
1181 memset((void*)0x80003000,0,192);
1182 memset((void*)0x800030C8,0,12);
1183 memset((void*)0x800030E2,0,1);
1185 __PADDisableRecalibration(ret
);
1191 void SYS_ResetSystem(s32 reset
,u32 reset_code
,s32 force_menu
)
1197 if(reset
==SYS_SHUTDOWN
) {
1198 ret
= __PADDisableRecalibration(TRUE
);
1201 while(__call_resetfuncs(FALSE
)==0);
1208 if(CONF_GetShutdownMode() == CONF_SHUTDOWN_IDLE
) {
1209 ret
= CONF_GetIdleLedMode();
1210 if(ret
<= 2) STM_SetLedMode(ret
);
1211 STM_ShutdownToIdle();
1213 STM_ShutdownToStandby();
1216 case SYS_POWEROFF_STANDBY
:
1217 STM_ShutdownToStandby();
1219 case SYS_POWEROFF_IDLE
:
1220 ret
= CONF_GetIdleLedMode();
1221 if(ret
>= 0 && ret
<= 2) STM_SetLedMode(ret
);
1222 STM_ShutdownToIdle();
1224 case SYS_RETURNTOMENU
:
1229 //TODO: implement SYS_HOTRESET
1230 // either restart failed or this is SYS_SHUTDOWN
1232 __IOS_ShutdownSubsystems();
1234 _CPU_ISR_Disable(level
);
1235 __call_resetfuncs(TRUE
);
1239 __lwp_thread_dispatchdisable();
1240 __lwp_thread_closeall();
1242 memset((void*)0x80000040,0,140);
1243 memset((void*)0x800000D4,0,20);
1244 memset((void*)0x800000F4,0,4);
1245 memset((void*)0x80003000,0,192);
1246 memset((void*)0x800030C8,0,12);
1247 memset((void*)0x800030E2,0,1);
1249 __PADDisableRecalibration(ret
);
1253 void SYS_RegisterResetFunc(sys_resetinfo
*info
)
1256 sys_resetinfo
*after
;
1257 lwp_queue
*header
= &sys_reset_func_queue
;
1259 _CPU_ISR_Disable(level
);
1260 for(after
=(sys_resetinfo
*)header
->first
;after
->node
.next
!=NULL
&& info
->prio
>=after
->prio
;after
=(sys_resetinfo
*)after
->node
.next
);
1261 __lwp_queue_insertI(after
->node
.prev
,&info
->node
);
1262 _CPU_ISR_Restore(level
);
1265 void SYS_UnregisterResetFunc(sys_resetinfo
*info
) {
1269 _CPU_ISR_Disable(level
);
1270 for (n
= sys_reset_func_queue
.first
; n
->next
; n
= n
->next
) {
1271 if (n
== &info
->node
) {
1272 __lwp_queue_extractI(n
);
1276 _CPU_ISR_Restore(level
);
1279 void SYS_SetArena1Lo(void *newLo
)
1283 _CPU_ISR_Disable(level
);
1284 __sysarena1lo
= newLo
;
1285 _CPU_ISR_Restore(level
);
1288 void* SYS_GetArena1Lo()
1293 _CPU_ISR_Disable(level
);
1294 arenalo
= __sysarena1lo
;
1295 _CPU_ISR_Restore(level
);
1300 void SYS_SetArena1Hi(void *newHi
)
1304 _CPU_ISR_Disable(level
);
1305 __sysarena1hi
= newHi
;
1306 _CPU_ISR_Restore(level
);
1309 void* SYS_GetArena1Hi()
1314 _CPU_ISR_Disable(level
);
1315 arenahi
= __sysarena1hi
;
1316 _CPU_ISR_Restore(level
);
1321 u32
SYS_GetArena1Size()
1325 _CPU_ISR_Disable(level
);
1326 size
= ((u32
)__sysarena1hi
- (u32
)__sysarena1lo
);
1327 _CPU_ISR_Restore(level
);
1332 void* SYS_AllocArena1MemLo(u32 size
,u32 align
)
1337 mem1lo
= (u32
)SYS_GetArena1Lo();
1338 ptr
= (void*)((mem1lo
+(align
-1))&~(align
-1));
1339 mem1lo
= ((((u32
)ptr
+size
+align
)-1)&~(align
-1));
1340 SYS_SetArena1Lo((void*)mem1lo
);
1346 void SYS_SetArena2Lo(void *newLo
)
1350 _CPU_ISR_Disable(level
);
1351 __sysarena2lo
= newLo
;
1352 _CPU_ISR_Restore(level
);
1355 void* SYS_GetArena2Lo()
1360 _CPU_ISR_Disable(level
);
1361 arenalo
= __sysarena2lo
;
1362 _CPU_ISR_Restore(level
);
1367 void SYS_SetArena2Hi(void *newHi
)
1371 _CPU_ISR_Disable(level
);
1372 __sysarena2hi
= newHi
;
1373 _CPU_ISR_Restore(level
);
1376 void* SYS_GetArena2Hi()
1381 _CPU_ISR_Disable(level
);
1382 arenahi
= __sysarena2hi
;
1383 _CPU_ISR_Restore(level
);
1388 u32
SYS_GetArena2Size()
1392 _CPU_ISR_Disable(level
);
1393 size
= ((u32
)__sysarena2hi
- (u32
)__sysarena2lo
);
1394 _CPU_ISR_Restore(level
);
1399 void* SYS_AllocArena2MemLo(u32 size
,u32 align
)
1404 mem2lo
= (u32
)SYS_GetArena2Lo();
1405 ptr
= (void*)((mem2lo
+(align
-1))&~(align
-1));
1406 mem2lo
= ((((u32
)ptr
+size
+align
)-1)&~(align
-1));
1407 SYS_SetArena2Lo((void*)mem2lo
);
1413 void SYS_ProtectRange(u32 chan
,void *addr
,u32 bytes
,u32 cntrl
)
1416 u32 pstart
,pend
,level
;
1418 if(chan
<SYS_PROTECTCHANMAX
) {
1419 pstart
= ((u32
)addr
)&~0x3ff;
1420 pend
= ((((u32
)addr
)+bytes
)+1023)&~0x3ff;
1421 DCFlushRange((void*)pstart
,(pend
-pstart
));
1423 _CPU_ISR_Disable(level
);
1425 __UnmaskIrq(IRQMASK(chan
));
1426 _memReg
[chan
<<2] = _SHIFTR(pstart
,10,16);
1427 _memReg
[(chan
<<2)+1] = _SHIFTR(pend
,10,16);
1429 rcntrl
= _memReg
[8];
1430 rcntrl
= (rcntrl
&~(_SHIFTL(3,(chan
<<1),2)))|(_SHIFTL(cntrl
,(chan
<<1),2));
1431 _memReg
[8] = rcntrl
;
1433 if(cntrl
==SYS_PROTECTRDWR
)
1434 __MaskIrq(IRQMASK(chan
));
1437 _CPU_ISR_Restore(level
);
1441 void* SYS_AllocateFramebuffer(GXRModeObj
*rmode
)
1443 return memalign(32, VIDEO_GetFrameBufferSize(rmode
));
1446 u32
SYS_GetFontEncoding()
1450 if(sys_fontenc
<=0x0001) return sys_fontenc
;
1453 tv_mode
= VIDEO_GetCurrentTvMode();
1454 if(tv_mode
==VI_NTSC
&& _viReg
[55]&0x0002) ret
= 1;
1459 u32
SYS_InitFont(sys_fontheader
*font_data
)
1461 void *packed_data
= NULL
;
1463 if(!font_data
) return 0;
1465 if(SYS_GetFontEncoding()==1) {
1466 memset(font_data
,0,SYS_FONTSIZE_SJIS
);
1467 packed_data
= (void*)((u32
)font_data
+868096);
1469 memset(font_data
,0,SYS_FONTSIZE_ANSI
);
1470 packed_data
= (void*)((u32
)font_data
+119072);
1473 if(__SYS_LoadFont(packed_data
,font_data
)==1) {
1474 sys_fontimage
= (u8
*)((((u32
)font_data
+font_data
->sheet_image
)+31)&~31);
1475 __expand_font((u8
*)font_data
+font_data
->sheet_image
,sys_fontimage
);
1482 void SYS_GetFontTexture(s32 c
,void **image
,s32
*xpos
,s32
*ypos
,s32
*width
)
1489 if(!sys_fontwidthtab
|| ! sys_fontimage
) return;
1491 if(c
<sys_fontdata
->first_char
|| c
>sys_fontdata
->last_char
) c
= sys_fontdata
->inval_char
;
1492 else c
-= sys_fontdata
->first_char
;
1494 sheets
= c
/sys_fontcharsinsheet
;
1495 rem
= c
%sys_fontcharsinsheet
;
1496 *image
= sys_fontimage
+(sys_fontdata
->sheet_size
*sheets
);
1497 *xpos
= (rem
%sys_fontdata
->sheet_column
)*sys_fontdata
->cell_width
;
1498 *ypos
= (rem
/sys_fontdata
->sheet_column
)*sys_fontdata
->cell_height
;
1499 *width
= sys_fontwidthtab
[c
];
1502 void SYS_GetFontTexel(s32 c
,void *image
,s32 pos
,s32 stride
,s32
*width
)
1510 if(!sys_fontwidthtab
|| ! sys_fontimage
) return;
1512 if(c
<sys_fontdata
->first_char
|| c
>sys_fontdata
->last_char
) c
= sys_fontdata
->inval_char
;
1513 else c
-= sys_fontdata
->first_char
;
1515 sheets
= c
/sys_fontcharsinsheet
;
1516 rem
= c
%sys_fontcharsinsheet
;
1517 xoff
= (rem
%sys_fontdata
->sheet_column
)*sys_fontdata
->cell_width
;
1518 yoff
= (rem
/sys_fontdata
->sheet_column
)*sys_fontdata
->cell_height
;
1519 img_start
= sys_fontimage
+(sys_fontdata
->sheet_size
*sheets
);
1522 while(ypos
<sys_fontdata
->cell_height
) {
1524 while(xpos
<sys_fontdata
->cell_width
) {
1525 ptr1
= img_start
+(((sys_fontdata
->sheet_width
/8)<<5)*((ypos
+yoff
)/8));
1526 ptr1
= ptr1
+(((xpos
+xoff
)/8)<<5);
1527 ptr1
= ptr1
+(((ypos
+yoff
)%8)<<2);
1528 ptr1
= ptr1
+(((xpos
+xoff
)%8)/2);
1530 ptr2
= image
+((ypos
/8)*(((stride
<<1)/8)<<5));
1531 ptr2
= ptr2
+(((xpos
+pos
)/8)<<5);
1532 ptr2
= ptr2
+(((xpos
+pos
)%8)/2);
1533 ptr2
= ptr2
+((ypos
%8)<<2);
1541 *width
= sys_fontwidthtab
[c
];
1544 s32
SYS_CreateAlarm(syswd_t
*thealarm
)
1548 alarm
= __lwp_syswd_allocate();
1549 if(!alarm
) return -1;
1551 alarm
->alarmhandler
= NULL
;
1553 alarm
->start_per
= 0;
1554 alarm
->periodic
= 0;
1556 *thealarm
= (LWP_OBJMASKTYPE(LWP_OBJTYPE_SYSWD
)|LWP_OBJMASKID(alarm
->object
.id
));
1557 __lwp_thread_dispatchenable();
1561 s32
SYS_SetAlarm(syswd_t thealarm
,const struct timespec
*tp
,alarmcallback cb
,void *cbarg
)
1565 alarm
= __lwp_syswd_open(thealarm
);
1566 if(!alarm
) return -1;
1568 alarm
->cb_arg
= cbarg
;
1569 alarm
->alarmhandler
= cb
;
1570 alarm
->ticks
= __lwp_wd_calc_ticks(tp
);
1572 alarm
->periodic
= 0;
1573 alarm
->start_per
= 0;
1575 __lwp_wd_initialize(&alarm
->alarm
,__sys_alarmhandler
,alarm
->object
.id
,(void*)thealarm
);
1576 __lwp_wd_insert_ticks(&alarm
->alarm
,alarm
->ticks
);
1577 __lwp_thread_dispatchenable();
1581 s32
SYS_SetPeriodicAlarm(syswd_t thealarm
,const struct timespec
*tp_start
,const struct timespec
*tp_period
,alarmcallback cb
,void *cbarg
)
1585 alarm
= __lwp_syswd_open(thealarm
);
1586 if(!alarm
) return -1;
1588 alarm
->start_per
= __lwp_wd_calc_ticks(tp_start
);
1589 alarm
->periodic
= __lwp_wd_calc_ticks(tp_period
);
1590 alarm
->alarmhandler
= cb
;
1591 alarm
->cb_arg
= cbarg
;
1595 __lwp_wd_initialize(&alarm
->alarm
,__sys_alarmhandler
,alarm
->object
.id
,(void*)thealarm
);
1596 __lwp_wd_insert_ticks(&alarm
->alarm
,alarm
->start_per
);
1597 __lwp_thread_dispatchenable();
1601 s32
SYS_RemoveAlarm(syswd_t thealarm
)
1605 alarm
= __lwp_syswd_open(thealarm
);
1606 if(!alarm
) return -1;
1608 alarm
->alarmhandler
= NULL
;
1610 alarm
->periodic
= 0;
1611 alarm
->start_per
= 0;
1613 __lwp_wd_remove_ticks(&alarm
->alarm
);
1614 __lwp_syswd_free(alarm
);
1615 __lwp_thread_dispatchenable();
1619 s32
SYS_CancelAlarm(syswd_t thealarm
)
1623 alarm
= __lwp_syswd_open(thealarm
);
1624 if(!alarm
) return -1;
1626 alarm
->alarmhandler
= NULL
;
1628 alarm
->periodic
= 0;
1629 alarm
->start_per
= 0;
1631 __lwp_wd_remove_ticks(&alarm
->alarm
);
1632 __lwp_thread_dispatchenable();
1636 resetcallback
SYS_SetResetCallback(resetcallback cb
)
1641 _CPU_ISR_Disable(level
);
1642 old
= __RSWCallback
;
1647 __UnmaskIrq(IRQMASK(IRQ_PI_RSW
));
1649 __MaskIrq(IRQMASK(IRQ_PI_RSW
));
1651 _CPU_ISR_Restore(level
);
1656 powercallback
SYS_SetPowerCallback(powercallback cb
)
1661 _CPU_ISR_Disable(level
);
1662 old
= __POWCallback
;
1664 _CPU_ISR_Restore(level
);
1669 void SYS_StartPMC(u32 mcr0val
,u32 mcr1val
)
1691 printf("<%d load/stores / %d miss cycles / %d cycles / %d instructions>\n",mfpmc1(),mfpmc2(),mfpmc3(),mfpmc4());
1694 void SYS_SetWirelessID(u32 chan
,u32 id
)
1700 sram
= __SYS_LockSramEx();
1701 if(sram
->wirelessPad_id
[chan
]!=(u16
)id
) {
1702 sram
->wirelessPad_id
[chan
] = (u16
)id
;
1705 __SYS_UnlockSramEx(write
);
1708 u32
SYS_GetWirelessID(u32 chan
)
1714 sram
= __SYS_LockSramEx();
1715 id
= sram
->wirelessPad_id
[chan
];
1716 __SYS_UnlockSramEx(0);
1721 u32
SYS_GetHollywoodRevision()
1724 DCInvalidateRange((void*)0x80003138,8);
1725 rev
= *((u32
*)0x80003138);