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()
1068 _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
1130 for (i
= 0; i
< 32; ++i
)
1133 __IOS_LoadStartupIOS();
1134 __IOS_InitializeSubsystems();
1135 STM_RegisterEventHandler(__STMEventHandler
);
1141 u32
SYS_ResetButtonDown()
1143 return (!(_piReg
[0]&0x00010000));
1147 void SYS_ResetSystem(s32 reset
,u32 reset_code
,s32 force_menu
)
1154 if(reset
==SYS_SHUTDOWN
) {
1155 ret
= __PADDisableRecalibration(TRUE
);
1158 while(__call_resetfuncs(FALSE
)==0);
1160 if(reset
==SYS_HOTRESET
&& force_menu
==TRUE
) {
1161 sram
= __SYS_LockSram();
1162 sram
->flags
|= 0x40;
1163 __SYS_UnlockSram(TRUE
);
1164 while(!__SYS_SyncSram());
1167 _CPU_ISR_Disable(level
);
1168 __call_resetfuncs(TRUE
);
1172 __lwp_thread_dispatchdisable();
1173 if(reset
==SYS_HOTRESET
) {
1174 __dohotreset(reset_code
);
1175 } else if(reset
==SYS_RESTART
) {
1176 __lwp_thread_closeall();
1177 __lwp_thread_dispatchunnest();
1178 __doreboot(reset_code
,force_menu
);
1181 __lwp_thread_closeall();
1183 memset((void*)0x80000040,0,140);
1184 memset((void*)0x800000D4,0,20);
1185 memset((void*)0x800000F4,0,4);
1186 memset((void*)0x80003000,0,192);
1187 memset((void*)0x800030C8,0,12);
1188 memset((void*)0x800030E2,0,1);
1190 __PADDisableRecalibration(ret
);
1196 void SYS_ResetSystem(s32 reset
,u32 reset_code
,s32 force_menu
)
1202 if(reset
==SYS_SHUTDOWN
) {
1203 ret
= __PADDisableRecalibration(TRUE
);
1206 while(__call_resetfuncs(FALSE
)==0);
1213 if(CONF_GetShutdownMode() == CONF_SHUTDOWN_IDLE
) {
1214 ret
= CONF_GetIdleLedMode();
1215 if(ret
<= 2) STM_SetLedMode(ret
);
1216 STM_ShutdownToIdle();
1218 STM_ShutdownToStandby();
1221 case SYS_POWEROFF_STANDBY
:
1222 STM_ShutdownToStandby();
1224 case SYS_POWEROFF_IDLE
:
1225 ret
= CONF_GetIdleLedMode();
1226 if(ret
>= 0 && ret
<= 2) STM_SetLedMode(ret
);
1227 STM_ShutdownToIdle();
1229 case SYS_RETURNTOMENU
:
1234 //TODO: implement SYS_HOTRESET
1235 // either restart failed or this is SYS_SHUTDOWN
1237 __IOS_ShutdownSubsystems();
1239 _CPU_ISR_Disable(level
);
1240 __call_resetfuncs(TRUE
);
1244 __lwp_thread_dispatchdisable();
1245 __lwp_thread_closeall();
1247 memset((void*)0x80000040,0,140);
1248 memset((void*)0x800000D4,0,20);
1249 memset((void*)0x800000F4,0,4);
1250 memset((void*)0x80003000,0,192);
1251 memset((void*)0x800030C8,0,12);
1252 memset((void*)0x800030E2,0,1);
1254 __PADDisableRecalibration(ret
);
1258 void SYS_RegisterResetFunc(sys_resetinfo
*info
)
1261 sys_resetinfo
*after
;
1262 lwp_queue
*header
= &sys_reset_func_queue
;
1264 _CPU_ISR_Disable(level
);
1265 for(after
=(sys_resetinfo
*)header
->first
;after
->node
.next
!=NULL
&& info
->prio
>=after
->prio
;after
=(sys_resetinfo
*)after
->node
.next
);
1266 __lwp_queue_insertI(after
->node
.prev
,&info
->node
);
1267 _CPU_ISR_Restore(level
);
1270 void SYS_UnregisterResetFunc(sys_resetinfo
*info
) {
1274 _CPU_ISR_Disable(level
);
1275 for (n
= sys_reset_func_queue
.first
; n
->next
; n
= n
->next
) {
1276 if (n
== &info
->node
) {
1277 __lwp_queue_extractI(n
);
1281 _CPU_ISR_Restore(level
);
1284 void SYS_SetArena1Lo(void *newLo
)
1288 _CPU_ISR_Disable(level
);
1289 __sysarena1lo
= newLo
;
1290 _CPU_ISR_Restore(level
);
1293 void* SYS_GetArena1Lo()
1298 _CPU_ISR_Disable(level
);
1299 arenalo
= __sysarena1lo
;
1300 _CPU_ISR_Restore(level
);
1305 void SYS_SetArena1Hi(void *newHi
)
1309 _CPU_ISR_Disable(level
);
1310 __sysarena1hi
= newHi
;
1311 _CPU_ISR_Restore(level
);
1314 void* SYS_GetArena1Hi()
1319 _CPU_ISR_Disable(level
);
1320 arenahi
= __sysarena1hi
;
1321 _CPU_ISR_Restore(level
);
1326 u32
SYS_GetArena1Size()
1330 _CPU_ISR_Disable(level
);
1331 size
= ((u32
)__sysarena1hi
- (u32
)__sysarena1lo
);
1332 _CPU_ISR_Restore(level
);
1337 void* SYS_AllocArena1MemLo(u32 size
,u32 align
)
1342 mem1lo
= (u32
)SYS_GetArena1Lo();
1343 ptr
= (void*)((mem1lo
+(align
-1))&~(align
-1));
1344 mem1lo
= ((((u32
)ptr
+size
+align
)-1)&~(align
-1));
1345 SYS_SetArena1Lo((void*)mem1lo
);
1351 void SYS_SetArena2Lo(void *newLo
)
1355 _CPU_ISR_Disable(level
);
1356 __sysarena2lo
= newLo
;
1357 _CPU_ISR_Restore(level
);
1360 void* SYS_GetArena2Lo()
1365 _CPU_ISR_Disable(level
);
1366 arenalo
= __sysarena2lo
;
1367 _CPU_ISR_Restore(level
);
1372 void SYS_SetArena2Hi(void *newHi
)
1376 _CPU_ISR_Disable(level
);
1377 __sysarena2hi
= newHi
;
1378 _CPU_ISR_Restore(level
);
1381 void* SYS_GetArena2Hi()
1386 _CPU_ISR_Disable(level
);
1387 arenahi
= __sysarena2hi
;
1388 _CPU_ISR_Restore(level
);
1393 u32
SYS_GetArena2Size()
1397 _CPU_ISR_Disable(level
);
1398 size
= ((u32
)__sysarena2hi
- (u32
)__sysarena2lo
);
1399 _CPU_ISR_Restore(level
);
1404 void* SYS_AllocArena2MemLo(u32 size
,u32 align
)
1409 mem2lo
= (u32
)SYS_GetArena2Lo();
1410 ptr
= (void*)((mem2lo
+(align
-1))&~(align
-1));
1411 mem2lo
= ((((u32
)ptr
+size
+align
)-1)&~(align
-1));
1412 SYS_SetArena2Lo((void*)mem2lo
);
1418 void SYS_ProtectRange(u32 chan
,void *addr
,u32 bytes
,u32 cntrl
)
1421 u32 pstart
,pend
,level
;
1423 if(chan
<SYS_PROTECTCHANMAX
) {
1424 pstart
= ((u32
)addr
)&~0x3ff;
1425 pend
= ((((u32
)addr
)+bytes
)+1023)&~0x3ff;
1426 DCFlushRange((void*)pstart
,(pend
-pstart
));
1428 _CPU_ISR_Disable(level
);
1430 __UnmaskIrq(IRQMASK(chan
));
1431 _memReg
[chan
<<2] = _SHIFTR(pstart
,10,16);
1432 _memReg
[(chan
<<2)+1] = _SHIFTR(pend
,10,16);
1434 rcntrl
= _memReg
[8];
1435 rcntrl
= (rcntrl
&~(_SHIFTL(3,(chan
<<1),2)))|(_SHIFTL(cntrl
,(chan
<<1),2));
1436 _memReg
[8] = rcntrl
;
1438 if(cntrl
==SYS_PROTECTRDWR
)
1439 __MaskIrq(IRQMASK(chan
));
1442 _CPU_ISR_Restore(level
);
1446 void* SYS_AllocateFramebuffer(GXRModeObj
*rmode
)
1448 return memalign(32, VIDEO_GetFrameBufferSize(rmode
));
1451 u32
SYS_GetFontEncoding()
1455 if(sys_fontenc
<=0x0001) return sys_fontenc
;
1458 tv_mode
= VIDEO_GetCurrentTvMode();
1459 if(tv_mode
==VI_NTSC
&& _viReg
[55]&0x0002) ret
= 1;
1464 u32
SYS_InitFont(sys_fontheader
*font_data
)
1466 void *packed_data
= NULL
;
1468 if(!font_data
) return 0;
1470 if(SYS_GetFontEncoding()==1) {
1471 memset(font_data
,0,SYS_FONTSIZE_SJIS
);
1472 packed_data
= (void*)((u32
)font_data
+868096);
1474 memset(font_data
,0,SYS_FONTSIZE_ANSI
);
1475 packed_data
= (void*)((u32
)font_data
+119072);
1478 if(__SYS_LoadFont(packed_data
,font_data
)==1) {
1479 sys_fontimage
= (u8
*)((((u32
)font_data
+font_data
->sheet_image
)+31)&~31);
1480 __expand_font((u8
*)font_data
+font_data
->sheet_image
,sys_fontimage
);
1487 void SYS_GetFontTexture(s32 c
,void **image
,s32
*xpos
,s32
*ypos
,s32
*width
)
1494 if(!sys_fontwidthtab
|| ! sys_fontimage
) return;
1496 if(c
<sys_fontdata
->first_char
|| c
>sys_fontdata
->last_char
) c
= sys_fontdata
->inval_char
;
1497 else c
-= sys_fontdata
->first_char
;
1499 sheets
= c
/sys_fontcharsinsheet
;
1500 rem
= c
%sys_fontcharsinsheet
;
1501 *image
= sys_fontimage
+(sys_fontdata
->sheet_size
*sheets
);
1502 *xpos
= (rem
%sys_fontdata
->sheet_column
)*sys_fontdata
->cell_width
;
1503 *ypos
= (rem
/sys_fontdata
->sheet_column
)*sys_fontdata
->cell_height
;
1504 *width
= sys_fontwidthtab
[c
];
1507 void SYS_GetFontTexel(s32 c
,void *image
,s32 pos
,s32 stride
,s32
*width
)
1515 if(!sys_fontwidthtab
|| ! sys_fontimage
) return;
1517 if(c
<sys_fontdata
->first_char
|| c
>sys_fontdata
->last_char
) c
= sys_fontdata
->inval_char
;
1518 else c
-= sys_fontdata
->first_char
;
1520 sheets
= c
/sys_fontcharsinsheet
;
1521 rem
= c
%sys_fontcharsinsheet
;
1522 xoff
= (rem
%sys_fontdata
->sheet_column
)*sys_fontdata
->cell_width
;
1523 yoff
= (rem
/sys_fontdata
->sheet_column
)*sys_fontdata
->cell_height
;
1524 img_start
= sys_fontimage
+(sys_fontdata
->sheet_size
*sheets
);
1527 while(ypos
<sys_fontdata
->cell_height
) {
1529 while(xpos
<sys_fontdata
->cell_width
) {
1530 ptr1
= img_start
+(((sys_fontdata
->sheet_width
/8)<<5)*((ypos
+yoff
)/8));
1531 ptr1
= ptr1
+(((xpos
+xoff
)/8)<<5);
1532 ptr1
= ptr1
+(((ypos
+yoff
)%8)<<2);
1533 ptr1
= ptr1
+(((xpos
+xoff
)%8)/2);
1535 ptr2
= image
+((ypos
/8)*(((stride
<<1)/8)<<5));
1536 ptr2
= ptr2
+(((xpos
+pos
)/8)<<5);
1537 ptr2
= ptr2
+(((xpos
+pos
)%8)/2);
1538 ptr2
= ptr2
+((ypos
%8)<<2);
1546 *width
= sys_fontwidthtab
[c
];
1549 s32
SYS_CreateAlarm(syswd_t
*thealarm
)
1553 alarm
= __lwp_syswd_allocate();
1554 if(!alarm
) return -1;
1556 alarm
->alarmhandler
= NULL
;
1558 alarm
->start_per
= 0;
1559 alarm
->periodic
= 0;
1561 *thealarm
= (LWP_OBJMASKTYPE(LWP_OBJTYPE_SYSWD
)|LWP_OBJMASKID(alarm
->object
.id
));
1562 __lwp_thread_dispatchenable();
1566 s32
SYS_SetAlarm(syswd_t thealarm
,const struct timespec
*tp
,alarmcallback cb
,void *cbarg
)
1570 alarm
= __lwp_syswd_open(thealarm
);
1571 if(!alarm
) return -1;
1573 alarm
->cb_arg
= cbarg
;
1574 alarm
->alarmhandler
= cb
;
1575 alarm
->ticks
= __lwp_wd_calc_ticks(tp
);
1577 alarm
->periodic
= 0;
1578 alarm
->start_per
= 0;
1580 __lwp_wd_initialize(&alarm
->alarm
,__sys_alarmhandler
,alarm
->object
.id
,(void*)thealarm
);
1581 __lwp_wd_insert_ticks(&alarm
->alarm
,alarm
->ticks
);
1582 __lwp_thread_dispatchenable();
1586 s32
SYS_SetPeriodicAlarm(syswd_t thealarm
,const struct timespec
*tp_start
,const struct timespec
*tp_period
,alarmcallback cb
,void *cbarg
)
1590 alarm
= __lwp_syswd_open(thealarm
);
1591 if(!alarm
) return -1;
1593 alarm
->start_per
= __lwp_wd_calc_ticks(tp_start
);
1594 alarm
->periodic
= __lwp_wd_calc_ticks(tp_period
);
1595 alarm
->alarmhandler
= cb
;
1596 alarm
->cb_arg
= cbarg
;
1600 __lwp_wd_initialize(&alarm
->alarm
,__sys_alarmhandler
,alarm
->object
.id
,(void*)thealarm
);
1601 __lwp_wd_insert_ticks(&alarm
->alarm
,alarm
->start_per
);
1602 __lwp_thread_dispatchenable();
1606 s32
SYS_RemoveAlarm(syswd_t thealarm
)
1610 alarm
= __lwp_syswd_open(thealarm
);
1611 if(!alarm
) return -1;
1613 alarm
->alarmhandler
= NULL
;
1615 alarm
->periodic
= 0;
1616 alarm
->start_per
= 0;
1618 __lwp_wd_remove_ticks(&alarm
->alarm
);
1619 __lwp_syswd_free(alarm
);
1620 __lwp_thread_dispatchenable();
1624 s32
SYS_CancelAlarm(syswd_t thealarm
)
1628 alarm
= __lwp_syswd_open(thealarm
);
1629 if(!alarm
) return -1;
1631 alarm
->alarmhandler
= NULL
;
1633 alarm
->periodic
= 0;
1634 alarm
->start_per
= 0;
1636 __lwp_wd_remove_ticks(&alarm
->alarm
);
1637 __lwp_thread_dispatchenable();
1641 resetcallback
SYS_SetResetCallback(resetcallback cb
)
1646 _CPU_ISR_Disable(level
);
1647 old
= __RSWCallback
;
1652 __UnmaskIrq(IRQMASK(IRQ_PI_RSW
));
1654 __MaskIrq(IRQMASK(IRQ_PI_RSW
));
1656 _CPU_ISR_Restore(level
);
1661 powercallback
SYS_SetPowerCallback(powercallback cb
)
1666 _CPU_ISR_Disable(level
);
1667 old
= __POWCallback
;
1669 _CPU_ISR_Restore(level
);
1674 void SYS_StartPMC(u32 mcr0val
,u32 mcr1val
)
1696 printf("<%d load/stores / %d miss cycles / %d cycles / %d instructions>\n",mfpmc1(),mfpmc2(),mfpmc3(),mfpmc4());
1699 void SYS_SetWirelessID(u32 chan
,u32 id
)
1705 sram
= __SYS_LockSramEx();
1706 if(sram
->wirelessPad_id
[chan
]!=(u16
)id
) {
1707 sram
->wirelessPad_id
[chan
] = (u16
)id
;
1710 __SYS_UnlockSramEx(write
);
1713 u32
SYS_GetWirelessID(u32 chan
)
1719 sram
= __SYS_LockSramEx();
1720 id
= sram
->wirelessPad_id
[chan
];
1721 __SYS_UnlockSramEx(0);
1726 u32
SYS_GetHollywoodRevision()
1729 DCInvalidateRange((void*)0x80003138,8);
1730 rev
= *((u32
*)0x80003138);