change PAD_ScanPads()s behaviour. the return value now contains a bitmask of the...
[libogc.git] / libogc / system.c
blob1f2fc751d66364eee8800c5e760c765e2ff81aae
1 /*-------------------------------------------------------------
3 system.c -- OS functions and initialization
5 Copyright (C) 2004
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
26 distribution.
28 -------------------------------------------------------------*/
30 //#define DEBUG_SYSTEM
32 #include <stdlib.h>
33 #include <string.h>
34 #include <stdio.h>
35 #include <malloc.h>
36 #include <sys/iosupport.h>
38 #include "asm.h"
39 #include "irq.h"
40 #include "exi.h"
41 #if defined(HW_RVL)
42 #include "ipc.h"
43 #include "ios.h"
44 #include "stm.h"
45 #include "es.h"
46 #include "conf.h"
47 #include "wiilaunch.h"
48 #endif
49 #include "cache.h"
50 #include "video.h"
51 #include "system.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
62 #if defined(HW_RVL)
63 #define SYSMEM2_SIZE 0x04000000
64 #endif
65 #define KERNEL_HEAP (1*1024*1024)
67 // DSPCR bits
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) \
83 { \
84 if(((hndl)==SYS_WD_NULL) || (LWP_OBJTYPE(hndl)!=LWP_OBJTYPE_SYSWD)) \
85 return NULL; \
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)))
93 struct _sramcntrl {
94 u8 srambuf[64];
95 u32 offset;
96 s32 enabled;
97 s32 locked;
98 s32 sync;
99 } sramcntrl ATTRIBUTE_ALIGN(32);
101 typedef struct _alarm_st
103 lwp_obj object;
104 wd_cntrl alarm;
105 u64 ticks;
106 u64 periodic;
107 u64 start_per;
108 alarmcallback alarmhandler;
109 void *cb_arg;
110 } alarm_st;
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;
117 } yay0header;
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;
132 #if defined(HW_RVL)
133 static void *__sysarena2lo = NULL;
134 static void *__sysarena2hi = NULL;
135 static void *__ipcbufferlo = NULL;
136 static void *__ipcbufferhi = NULL;
137 #endif
139 static void __RSWDefaultHandler();
140 static resetcallback __RSWCallback = NULL;
141 #if defined(HW_RVL)
142 static void __POWDefaultHandler();
143 static powercallback __POWCallback = NULL;
145 static u32 __sys_resetdown = 0;
146 #endif
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[];
211 extern u8 __isIPL[];
212 extern u8 __Arena1Lo[], __Arena1Hi[];
213 #if defined(HW_RVL)
214 extern u8 __Arena2Lo[], __Arena2Hi[];
215 extern u8 __ipcbufferLo[], __ipcbufferHi[];
216 #endif
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 = {
236 __mem_onreset,
240 static const char *__sys_versiondate;
241 static const char *__sys_versionbuild;
243 static __inline__ alarm_st* __lwp_syswd_open(syswd_t wd)
245 LWP_CHECK_SYSWD(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);
255 #ifdef HW_DOL
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);
264 #else
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'
271 return true;
272 return false;
275 void __reload()
277 if(__stub_found()) {
278 __exception_closeall();
279 reload();
281 SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
284 void __libogc_exit(int status)
286 if(__stub_found()) {
287 SYS_ResetSystem(SYS_SHUTDOWN,0,0);
288 __lwp_thread_stopmultitasking(reload);
290 SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
293 #endif
295 static void __init_syscall_array() {
296 __syscalls.sbrk_r = __libogc_sbrk_r;
297 __syscalls.lock_init = __libogc_lock_init;
298 __syscalls.lock_close = __libogc_lock_close;
299 __syscalls.lock_release = __libogc_lock_release;
300 __syscalls.lock_acquire = __libogc_lock_acquire;
301 __syscalls.malloc_lock = __libogc_malloc_lock;
302 __syscalls.malloc_unlock = __libogc_malloc_unlock;
303 __syscalls.exit = __libogc_exit;
304 __syscalls.gettod_r = __libogc_gettod_r;
308 static alarm_st* __lwp_syswd_allocate()
310 alarm_st *alarm;
312 __lwp_thread_dispatchdisable();
313 alarm = (alarm_st*)__lwp_objmgr_allocate(&sys_alarm_objects);
314 if(alarm) {
315 __lwp_objmgr_open(&sys_alarm_objects,&alarm->object);
316 return alarm;
318 __lwp_thread_dispatchenable();
319 return NULL;
322 static s32 __mem_onreset(s32 final)
324 if(final==TRUE) {
325 _memReg[8] = 255;
326 __UnmaskIrq(IM_MEM0|IM_MEM1|IM_MEM2|IM_MEM3);
328 return 1;
331 static void __sys_alarmhandler(void *arg)
333 alarm_st *alarm;
334 syswd_t thealarm = (syswd_t)arg;
336 if(thealarm==SYS_WD_NULL || LWP_OBJTYPE(thealarm)!=LWP_OBJTYPE_SYSWD) return;
338 __lwp_thread_dispatchdisable();
339 alarm = (alarm_st*)__lwp_objmgr_getnoprotection(&sys_alarm_objects,LWP_OBJMASKID(thealarm));
340 if(alarm) {
341 if(alarm->alarmhandler) alarm->alarmhandler(thealarm,alarm->cb_arg);
342 if(alarm->periodic) __lwp_wd_insert_ticks(&alarm->alarm,alarm->periodic);
344 __lwp_thread_dispatchunnest();
347 #if defined(HW_DOL)
348 static void __dohotreset(u32 resetcode)
350 u32 level;
352 _CPU_ISR_Disable(level);
353 _viReg[1] = 0;
354 ICFlashInvalidate();
355 __reset(resetcode<<3);
357 #endif
359 static s32 __call_resetfuncs(s32 final)
361 s32 ret;
362 sys_resetinfo *info;
363 lwp_queue *header = &sys_reset_func_queue;
365 ret = 1;
366 info = (sys_resetinfo*)header->first;
367 while(info!=(sys_resetinfo*)__lwp_queue_tail(header)) {
368 if(info->func && info->func(final)==0) ret |= (ret<<1);
369 info = (sys_resetinfo*)info->node.next;
371 if(__sram_sync()==0) ret |= (ret<<1);
373 if(ret&~0x01) return 0;
374 return 1;
377 #if defined(HW_DOL)
378 static void __doreboot(u32 resetcode,s32 force_menu)
380 u32 level;
382 _CPU_ISR_Disable(level);
384 *((u32*)0x817ffffc) = 0;
385 *((u32*)0x817ffff8) = 0;
386 *((u32*)0x800030e2) = 1;
388 #endif
390 static void __MEMInterruptHandler()
392 _memReg[16] = 0;
395 static void __RSWDefaultHandler()
400 #if defined(HW_RVL)
401 static void __POWDefaultHandler()
404 #endif
406 #if defined(HW_DOL)
407 static void __RSWHandler()
409 s64 now;
410 static s64 hold_down = 0;
412 hold_down = gettime();
413 do {
414 now = gettime();
415 if(diff_usec(hold_down,now)>=100) break;
416 } while(!(_piReg[0]&0x10000));
418 if(_piReg[0]&0x10000) {
419 __MaskIrq(IRQMASK(IRQ_PI_RSW));
421 if(__RSWCallback) {
422 __RSWCallback();
425 _piReg[0] = 2;
427 #endif
429 #if defined(HW_RVL)
430 static void __STMEventHandler(u32 event)
432 s32 ret;
433 u32 level;
435 if(event==STM_EVENT_RESET) {
436 ret = SYS_ResetButtonDown();
437 if(ret) {
438 _CPU_ISR_Disable(level);
439 __sys_resetdown = 1;
440 __RSWCallback();
441 _CPU_ISR_Restore(level);
445 if(event==STM_EVENT_POWER) {
446 _CPU_ISR_Disable(level);
447 __POWCallback();
448 _CPU_ISR_Restore(level);
451 #endif
453 void * __attribute__ ((weak)) __myArena1Lo = 0;
454 void * __attribute__ ((weak)) __myArena1Hi = 0;
456 static void __lowmem_init()
458 u32 *_gx = (u32*)__gxregs;
460 #if defined(HW_DOL)
461 void *ram_start = (void*)0x80000000;
462 void *ram_end = (void*)(0x80000000|SYSMEM1_SIZE);
463 void *arena_start = (void*)0x80003000;
464 #elif defined(HW_RVL)
465 void *arena_start = (void*)0x80003F00;
466 #endif
468 memset(_gx,0,2048);
469 memset(arena_start,0,0x100);
470 if ( __argvArena1Lo == (u8*)0xdeadbeef ) __argvArena1Lo = __Arena1Lo;
471 if (__myArena1Lo == 0) __myArena1Lo = __argvArena1Lo;
472 if (__myArena1Hi == 0) __myArena1Hi = __Arena1Hi;
474 #if defined(HW_DOL)
475 memset(ram_start,0,0x100);
476 *((u32*)(ram_start+0x20)) = 0x0d15ea5e; // magic word "disease"
477 *((u32*)(ram_start+0x24)) = 1; // version
478 *((u32*)(ram_start+0x28)) = SYSMEM1_SIZE; // physical memory size
479 *((u32*)(ram_start+0x2C)) = 1 + ((*(u32*)0xCC00302c)>>28);
481 *((u32*)(ram_start+0x30)) = (u32)__myArena1Lo;
482 *((u32*)(ram_start+0x34)) = (u32)__myArena1Hi;
484 *((u32*)(ram_start+0xEC)) = (u32)ram_end; // ram_end (??)
485 *((u32*)(ram_start+0xF0)) = SYSMEM1_SIZE; // simulated memory size
486 *((u32*)(ram_start+0xF8)) = TB_BUS_CLOCK; // bus speed: 162 MHz
487 *((u32*)(ram_start+0xFC)) = TB_CORE_CLOCK; // cpu speed: 486 Mhz
489 *((u16*)(arena_start+0xE0)) = 6; // production pads
490 *((u32*)(arena_start+0xE4)) = 0xC0008000;
492 DCFlushRangeNoSync(ram_start, 0x100);
493 #endif
495 DCFlushRangeNoSync(arena_start, 0x100);
496 DCFlushRangeNoSync(_gx, 2048);
497 _sync();
499 SYS_SetArenaLo((void*)__myArena1Lo);
500 SYS_SetArenaHi((void*)__myArena1Hi);
501 #if defined(HW_RVL)
502 SYS_SetArena2Lo((void*)__Arena2Lo);
503 SYS_SetArena2Hi((void*)__Arena2Hi);
504 #endif
507 #if defined(HW_RVL)
508 static void __ipcbuffer_init()
510 __ipcbufferlo = (void*)__ipcbufferLo;
511 __ipcbufferhi = (void*)__ipcbufferHi;
513 #endif
515 static void __memprotect_init()
517 u32 level;
519 _CPU_ISR_Disable(level);
521 __MaskIrq((IM_MEM0|IM_MEM1|IM_MEM2|IM_MEM3));
523 _memReg[16] = 0;
524 _memReg[8] = 255;
526 IRQ_Request(IRQ_MEM0,__MEMInterruptHandler,NULL);
527 IRQ_Request(IRQ_MEM1,__MEMInterruptHandler,NULL);
528 IRQ_Request(IRQ_MEM2,__MEMInterruptHandler,NULL);
529 IRQ_Request(IRQ_MEM3,__MEMInterruptHandler,NULL);
530 IRQ_Request(IRQ_MEMADDRESS,__MEMInterruptHandler,NULL);
532 SYS_RegisterResetFunc(&mem_resetinfo);
533 __UnmaskIrq(IM_MEMADDRESS); //only enable memaddress irq atm
535 _CPU_ISR_Restore(level);
538 static __inline__ u32 __get_fontsize(void *buffer)
540 u8 *ptr = (u8*)buffer;
542 if(ptr[0]=='Y' && ptr[1]=='a' && ptr[2]=='y') return (((u32*)ptr)[1]);
543 else return 0;
546 static u32 __read_rom(void *buf,u32 len,u32 offset)
548 u32 ret;
549 u32 loff;
551 DCInvalidateRange(buf,len);
553 if(EXI_Lock(EXI_CHANNEL_0,EXI_DEVICE_1,NULL)==0) return 0;
554 if(EXI_Select(EXI_CHANNEL_0,EXI_DEVICE_1,EXI_SPEED8MHZ)==0) {
555 EXI_Unlock(EXI_CHANNEL_0);
556 return 0;
559 ret = 0;
560 loff = offset<<6;
561 if(EXI_Imm(EXI_CHANNEL_0,&loff,4,EXI_WRITE,NULL)==0) ret |= 0x0001;
562 if(EXI_Sync(EXI_CHANNEL_0)==0) ret |= 0x0002;
563 if(EXI_Dma(EXI_CHANNEL_0,buf,len,EXI_READ,NULL)==0) ret |= 0x0004;
564 if(EXI_Sync(EXI_CHANNEL_0)==0) ret |= 0x0008;
565 if(EXI_Deselect(EXI_CHANNEL_0)==0) ret |= 0x0010;
566 if(EXI_Unlock(EXI_CHANNEL_0)==0) ret |= 0x00020;
568 if(ret) return 0;
569 return 1;
572 static u32 __getrtc(u32 *gctime)
574 u32 ret;
575 u32 cmd;
576 u32 time;
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);
581 return 0;
584 ret = 0;
585 time = 0;
586 cmd = 0x20000000;
587 if(EXI_Imm(EXI_CHANNEL_0,&cmd,4,EXI_WRITE,NULL)==0) ret |= 0x01;
588 if(EXI_Sync(EXI_CHANNEL_0)==0) ret |= 0x02;
589 if(EXI_Imm(EXI_CHANNEL_0,&time,4,EXI_READ,NULL)==0) ret |= 0x04;
590 if(EXI_Sync(EXI_CHANNEL_0)==0) ret |= 0x08;
591 if(EXI_Deselect(EXI_CHANNEL_0)==0) ret |= 0x10;
593 EXI_Unlock(EXI_CHANNEL_0);
594 *gctime = time;
595 if(ret) return 0;
597 return 1;
600 static u32 __sram_read(void *buffer)
602 u32 command,ret;
604 DCInvalidateRange(buffer,64);
606 if(EXI_Lock(EXI_CHANNEL_0,EXI_DEVICE_1,NULL)==0) return 0;
607 if(EXI_Select(EXI_CHANNEL_0,EXI_DEVICE_1,EXI_SPEED8MHZ)==0) {
608 EXI_Unlock(EXI_CHANNEL_0);
609 return 0;
612 ret = 0;
613 command = 0x20000100;
614 if(EXI_Imm(EXI_CHANNEL_0,&command,4,EXI_WRITE,NULL)==0) ret |= 0x01;
615 if(EXI_Sync(EXI_CHANNEL_0)==0) ret |= 0x02;
616 if(EXI_Dma(EXI_CHANNEL_0,buffer,64,EXI_READ,NULL)==0) ret |= 0x04;
617 if(EXI_Sync(EXI_CHANNEL_0)==0) ret |= 0x08;
618 if(EXI_Deselect(EXI_CHANNEL_0)==0) ret |= 0x10;
619 if(EXI_Unlock(EXI_CHANNEL_0)==0) ret |= 0x20;
621 if(ret) return 0;
622 return 1;
625 static u32 __sram_write(void *buffer,u32 loc,u32 len)
627 u32 cmd,ret;
629 if(EXI_Lock(EXI_CHANNEL_0,EXI_DEVICE_1,__sram_writecallback)==0) return 0;
630 if(EXI_Select(EXI_CHANNEL_0,EXI_DEVICE_1,EXI_SPEED8MHZ)==0) {
631 EXI_Unlock(EXI_CHANNEL_0);
632 return 0;
635 ret = 0;
636 cmd = 0xa0000100+(loc<<6);
637 if(EXI_Imm(EXI_CHANNEL_0,&cmd,4,EXI_WRITE,NULL)==0) ret |= 0x01;
638 if(EXI_Sync(EXI_CHANNEL_0)==0) ret |= 0x02;
639 if(EXI_ImmEx(EXI_CHANNEL_0,buffer,len,EXI_WRITE)==0) ret |= 0x04;
640 if(EXI_Deselect(EXI_CHANNEL_0)==0) ret |= 0x08;
641 if(EXI_Unlock(EXI_CHANNEL_0)==0) ret |= 0x10;
643 if(ret) return 0;
644 return 1;
647 static s32 __sram_writecallback(s32 chn,s32 dev)
649 sramcntrl.sync = __sram_write(sramcntrl.srambuf+sramcntrl.offset,sramcntrl.offset,(64-sramcntrl.offset));
650 if(sramcntrl.sync) sramcntrl.offset = 64;
652 return 1;
655 static s32 __sram_sync()
657 return sramcntrl.sync;
660 void __sram_init()
662 sramcntrl.enabled = 0;
663 sramcntrl.locked = 0;
664 sramcntrl.sync = __sram_read(sramcntrl.srambuf);
666 sramcntrl.offset = 64;
669 static void DisableWriteGatherPipe()
671 mtspr(920,(mfspr(920)&~0x40000000));
674 static void __buildchecksum(u16 *buffer,u16 *c1,u16 *c2)
676 u32 i;
678 *c1 = 0;
679 *c2 = 0;
680 for(i=0;i<4;i++) {
681 *c1 += buffer[6+i];
682 *c2 += buffer[6+i]^-1;
686 static void* __locksram(u32 loc)
688 u32 level;
690 _CPU_ISR_Disable(level);
691 if(!sramcntrl.locked) {
692 sramcntrl.enabled = level;
693 sramcntrl.locked = 1;
694 return (void*)((u32)sramcntrl.srambuf+loc);
696 _CPU_ISR_Restore(level);
697 return NULL;
700 static u32 __unlocksram(u32 write,u32 loc)
702 syssram *sram = (syssram*)sramcntrl.srambuf;
704 if(write) {
705 if(!loc) {
706 if((sram->flags&0x03)>0x02) sram->flags = (sram->flags&~0x03);
707 __buildchecksum((u16*)sramcntrl.srambuf,&sram->checksum,&sram->checksum_inv);
709 if(loc<sramcntrl.offset) sramcntrl.offset = loc;
711 sramcntrl.sync = __sram_write(sramcntrl.srambuf+sramcntrl.offset,sramcntrl.offset,(64-sramcntrl.offset));
712 if(sramcntrl.sync) sramcntrl.offset = 64;
714 sramcntrl.locked = 0;
715 _CPU_ISR_Restore(sramcntrl.enabled);
716 return sramcntrl.sync;
719 //returns the size of font
720 static u32 __read_font(void *buffer)
722 if(SYS_GetFontEncoding()==1) __SYS_ReadROM(buffer,315392,1769216);
723 else __SYS_ReadROM(buffer,12288,2084608);
724 return __get_fontsize(buffer);
727 static void __expand_font(const u8 *src,u8 *dest)
729 s32 cnt;
730 u32 idx;
731 u8 val1,val2;
732 u8 *data = (u8*)sys_fontdata+44;
734 if(sys_fontdata->sheet_format==0x0000) {
735 cnt = (sys_fontdata->sheet_fullsize/2)-1;
737 while(cnt>=0) {
738 idx = _SHIFTR(src[cnt],6,2);
739 val1 = data[idx];
741 idx = _SHIFTR(src[cnt],4,2);
742 val2 = data[idx];
744 dest[(cnt<<1)+0] =((val1&0xf0)|(val2&0x0f));
746 idx = _SHIFTR(src[cnt],2,2);
747 val1 = data[idx];
749 idx = _SHIFTR(src[cnt],0,2);
750 val2 = data[idx];
752 dest[(cnt<<1)+1] =((val1&0xf0)|(val2&0x0f));
754 cnt--;
757 DCStoreRange(dest,sys_fontdata->sheet_fullsize);
760 static void __dsp_bootstrap()
762 u16 status;
763 u32 tick;
765 memcpy(SYS_GetArenaHi()-128,(void*)0x81000000,128);
766 memcpy((void*)0x81000000,_dsp_initcode,128);
767 DCFlushRange((void*)0x81000000,128);
769 _dspReg[9] = 67;
770 _dspReg[5] = (DSPCR_DSPRESET|DSPCR_DSPINT|DSPCR_ARINT|DSPCR_AIINT|DSPCR_HALT);
771 _dspReg[5] |= DSPCR_RES;
772 while(_dspReg[5]&DSPCR_RES);
774 _dspReg[0] = 0;
775 while((_SHIFTL(_dspReg[2],16,16)|(_dspReg[3]&0xffff))&0x80000000);
777 ((u32*)_dspReg)[8] = 0x01000000;
778 ((u32*)_dspReg)[9] = 0;
779 ((u32*)_dspReg)[10] = 32;
781 status = _dspReg[5];
782 while(!(status&DSPCR_ARINT)) status = _dspReg[5];
783 _dspReg[5] = status;
785 tick = gettick();
786 while((gettick()-tick)<2194);
788 ((u32*)_dspReg)[8] = 0x01000000;
789 ((u32*)_dspReg)[9] = 0;
790 ((u32*)_dspReg)[10] = 32;
792 status = _dspReg[5];
793 while(!(status&DSPCR_ARINT)) status = _dspReg[5];
794 _dspReg[5] = status;
796 _dspReg[5] &= ~DSPCR_DSPRESET;
797 while(_dspReg[5]&0x400);
799 _dspReg[5] &= ~DSPCR_HALT;
800 while(!(_dspReg[2]&0x8000));
801 status = _dspReg[3];
803 _dspReg[5] |= DSPCR_HALT;
804 _dspReg[5] = (DSPCR_DSPRESET|DSPCR_DSPINT|DSPCR_ARINT|DSPCR_AIINT|DSPCR_HALT);
805 _dspReg[5] |= DSPCR_RES;
806 while(_dspReg[5]&DSPCR_RES);
808 memcpy((void*)0x81000000,SYS_GetArenaHi()-128,128);
809 #ifdef _SYS_DEBUG
810 printf("__audiosystem_init(finish)\n");
811 #endif
814 static void __dsp_shutdown()
816 u32 tick;
818 _dspReg[5] = (DSPCR_DSPRESET|DSPCR_HALT);
819 _dspReg[27] &= ~0x8000;
820 while(_dspReg[5]&0x400);
821 while(_dspReg[5]&0x200);
823 _dspReg[5] = (DSPCR_DSPRESET|DSPCR_DSPINT|DSPCR_ARINT|DSPCR_AIINT|DSPCR_HALT);
824 _dspReg[0] = 0;
825 while((_SHIFTL(_dspReg[2],16,16)|(_dspReg[3]&0xffff))&0x80000000);
827 tick = gettick();
828 while((gettick()-tick)<44);
830 _dspReg[5] |= DSPCR_RES;
831 while(_dspReg[5]&DSPCR_RES);
834 static void decode_szp(void *src,void *dest)
836 u32 i,k,link;
837 u8 *dest8,*tmp;
838 u32 loff,coff,roff;
839 u32 size,cnt,cmask,bcnt;
840 yay0header *header;
842 dest8 = (u8*)dest;
843 header = (yay0header*)src;
844 size = header->dec_size;
845 loff = header->links_offset;
846 coff = header->chunks_offset;
848 roff = sizeof(yay0header);
849 cmask = 0;
850 cnt = 0;
851 bcnt = 0;
853 do {
854 if(!bcnt) {
855 cmask = *(u32*)(src+roff);
856 roff += 4;
857 bcnt = 32;
860 if(cmask&0x80000000) {
861 dest8[cnt++] = *(u8*)(src+coff);
862 coff++;
863 } else {
864 link = *(u16*)(src+loff);
865 loff += 2;
867 tmp = dest8+(cnt-(link&0x0fff)-1);
868 k = link>>12;
869 if(k==0) {
870 k = (*(u8*)(src+coff))+18;
871 coff++;
872 } else k += 2;
874 for(i=0;i<k;i++) {
875 dest8[cnt++] = tmp[i];
878 cmask <<= 1;
879 bcnt--;
880 } while(cnt<size);
883 syssram* __SYS_LockSram()
885 return (syssram*)__locksram(0);
888 syssramex* __SYS_LockSramEx()
890 return (syssramex*)__locksram(sizeof(syssram));
893 u32 __SYS_UnlockSram(u32 write)
895 return __unlocksram(write,0);
898 u32 __SYS_UnlockSramEx(u32 write)
900 return __unlocksram(write,sizeof(syssram));
903 u32 __SYS_SyncSram()
905 return __sram_sync();
908 void __SYS_ReadROM(void *buf,u32 len,u32 offset)
910 u32 cpy_cnt;
912 while(len>0) {
913 cpy_cnt = (len>256)?256:len;
914 while(__read_rom(buf,cpy_cnt,offset)==0);
915 offset += cpy_cnt;
916 buf += cpy_cnt;
917 len -= cpy_cnt;
921 u32 __SYS_GetRTC(u32 *gctime)
923 u32 cnt,ret;
924 u32 time1,time2;
926 cnt = 0;
927 ret = 0;
928 while(cnt<16) {
929 if(__getrtc(&time1)==0) ret |= 0x01;
930 if(__getrtc(&time2)==0) ret |= 0x02;
931 if(ret) return 0;
932 if(time1==time2) {
933 *gctime = time1;
934 return 1;
936 cnt++;
938 return 0;
941 void __SYS_SetTime(s64 time)
943 u32 level;
944 s64 now;
945 s64 *pBootTime = (s64*)0x800030d8;
947 _CPU_ISR_Disable(level);
948 now = gettime();
949 now -= time;
950 now += *pBootTime;
951 *pBootTime = now;
952 settime(now);
953 EXI_ProbeReset();
954 _CPU_ISR_Restore(level);
957 s64 __SYS_GetSystemTime()
959 u32 level;
960 s64 now;
961 s64 *pBootTime = (s64*)0x800030d8;
963 _CPU_ISR_Disable(level);
964 now = gettime();
965 now += *pBootTime;
966 _CPU_ISR_Restore(level);
967 return now;
970 void __SYS_SetBootTime()
972 u32 gctime;
974 __SYS_LockSram();
975 __SYS_GetRTC(&gctime);
976 __SYS_SetTime(secs_to_ticks(gctime));
977 __SYS_UnlockSram(0);
980 u32 __SYS_LoadFont(void *src,void *dest)
982 if(__read_font(src)==0) return 0;
984 decode_szp(src,dest);
986 sys_fontdata = (sys_fontheader*)dest;
987 sys_fontwidthtab = (u8*)dest+sys_fontdata->width_table;
988 sys_fontcharsinsheet = sys_fontdata->sheet_column*sys_fontdata->sheet_row;
990 /* TODO: implement SJIS handling */
991 return 1;
994 #if defined(HW_RVL)
995 void* __SYS_GetIPCBufferLo()
997 return __ipcbufferlo;
1000 void* __SYS_GetIPCBufferHi()
1002 return __ipcbufferhi;
1005 #endif
1007 void _V_EXPORTNAME(void)
1008 { __sys_versionbuild = _V_STRING; __sys_versiondate = _V_DATE_; }
1010 #if defined(HW_RVL)
1011 void __SYS_DoPowerCB(void)
1013 u32 level;
1014 powercallback powcb;
1016 _CPU_ISR_Disable(level);
1017 powcb = __POWCallback;
1018 __POWCallback = __POWDefaultHandler;
1019 powcb();
1020 _CPU_ISR_Restore(level);
1022 #endif
1024 void __SYS_InitCallbacks()
1026 #if defined(HW_RVL)
1027 __POWCallback = __POWDefaultHandler;
1028 __sys_resetdown = 0;
1029 #endif
1030 __RSWCallback = __RSWDefaultHandler;
1033 void __attribute__((weak)) __SYS_PreInit()
1038 void SYS_Init()
1040 u32 level;
1042 _CPU_ISR_Disable(level);
1044 __SYS_PreInit();
1046 if(system_initialized) return;
1047 system_initialized = 1;
1049 _V_EXPORTNAME();
1051 __init_syscall_array();
1052 __lowmem_init();
1053 #if defined(HW_RVL)
1054 __ipcbuffer_init();
1055 #endif
1056 __lwp_wkspace_init(KERNEL_HEAP);
1057 __lwp_queue_init_empty(&sys_reset_func_queue);
1058 __lwp_objmgr_initinfo(&sys_alarm_objects,LWP_MAX_WATCHDOGS,sizeof(alarm_st));
1059 __sys_state_init();
1060 __lwp_priority_init();
1061 __lwp_watchdog_init();
1062 __exception_init();
1063 __systemcall_init();
1064 __decrementer_init();
1065 __irq_init();
1066 __exi_init();
1067 __sram_init();
1068 __si_init();
1069 __lwp_thread_coreinit();
1070 __lwp_sysinit();
1071 __memlock_init();
1072 __lwp_mqbox_init();
1073 __lwp_sema_init();
1074 __lwp_mutex_init();
1075 __lwp_cond_init();
1076 __timesystem_init();
1077 __dsp_bootstrap();
1079 if(!__sys_inIPL)
1080 __memprotect_init();
1082 #ifdef SDLOADER_FIX
1083 __SYS_SetBootTime();
1084 #endif
1085 DisableWriteGatherPipe();
1086 __SYS_InitCallbacks();
1087 #if defined(HW_RVL)
1088 __IPC_ClntInit();
1089 #elif defined(HW_DOL)
1090 IRQ_Request(IRQ_PI_RSW,__RSWHandler,NULL);
1091 __MaskIrq(IRQMASK(IRQ_PI_RSW));
1092 #endif
1093 __libc_init(1);
1094 __lwp_thread_startmultitasking();
1095 _CPU_ISR_Restore(level);
1098 // This function gets called inside the main thread, prior to the application's main() function
1099 void SYS_PreMain()
1101 #if defined(HW_RVL)
1102 u32 i;
1104 for (i = 0; i < 32; ++i)
1105 IOS_Close(i);
1107 __IOS_LoadStartupIOS();
1108 __IOS_InitializeSubsystems();
1109 STM_RegisterEventHandler(__STMEventHandler);
1110 CONF_Init();
1111 WII_Initialize();
1112 #endif
1115 u32 SYS_ResetButtonDown()
1117 return (!(_piReg[0]&0x00010000));
1120 #if defined(HW_DOL)
1121 void SYS_ResetSystem(s32 reset,u32 reset_code,s32 force_menu)
1123 u32 ret = 0;
1124 syssram *sram;
1126 __dsp_shutdown();
1128 if(reset==SYS_SHUTDOWN) {
1129 ret = __PADDisableRecalibration(TRUE);
1132 while(__call_resetfuncs(FALSE)==0);
1134 if(reset==SYS_HOTRESET && force_menu==TRUE) {
1135 sram = __SYS_LockSram();
1136 sram->flags |= 0x40;
1137 __SYS_UnlockSram(TRUE);
1138 while(!__SYS_SyncSram());
1141 __exception_closeall();
1142 __call_resetfuncs(TRUE);
1144 LCDisable();
1146 __lwp_thread_dispatchdisable();
1147 if(reset==SYS_HOTRESET) {
1148 __dohotreset(reset_code);
1149 } else if(reset==SYS_RESTART) {
1150 __lwp_thread_closeall();
1151 __lwp_thread_dispatchunnest();
1152 __doreboot(reset_code,force_menu);
1155 __lwp_thread_closeall();
1157 memset((void*)0x80000040,0,140);
1158 memset((void*)0x800000D4,0,20);
1159 memset((void*)0x800000F4,0,4);
1160 memset((void*)0x80003000,0,192);
1161 memset((void*)0x800030C8,0,12);
1162 memset((void*)0x800030E2,0,1);
1164 __PADDisableRecalibration(ret);
1166 #endif
1168 #if defined(HW_RVL)
1170 void SYS_ResetSystem(s32 reset,u32 reset_code,s32 force_menu)
1172 u32 ret = 0;
1174 __dsp_shutdown();
1176 if(reset==SYS_SHUTDOWN) {
1177 ret = __PADDisableRecalibration(TRUE);
1180 while(__call_resetfuncs(FALSE)==0);
1182 switch(reset) {
1183 case SYS_RESTART:
1184 STM_RebootSystem();
1185 break;
1186 case SYS_POWEROFF:
1187 if(CONF_GetShutdownMode() == CONF_SHUTDOWN_IDLE) {
1188 ret = CONF_GetIdleLedMode();
1189 if(ret <= 2) STM_SetLedMode(ret);
1190 STM_ShutdownToIdle();
1191 } else {
1192 STM_ShutdownToStandby();
1194 break;
1195 case SYS_POWEROFF_STANDBY:
1196 STM_ShutdownToStandby();
1197 break;
1198 case SYS_POWEROFF_IDLE:
1199 ret = CONF_GetIdleLedMode();
1200 if(ret >= 0 && ret <= 2) STM_SetLedMode(ret);
1201 STM_ShutdownToIdle();
1202 break;
1203 case SYS_RETURNTOMENU:
1204 WII_ReturnToMenu();
1205 break;
1208 //TODO: implement SYS_HOTRESET
1209 // either restart failed or this is SYS_SHUTDOWN
1211 __IOS_ShutdownSubsystems();
1213 __exception_closeall();
1214 __call_resetfuncs(TRUE);
1216 LCDisable();
1218 __lwp_thread_dispatchdisable();
1219 __lwp_thread_closeall();
1221 memset((void*)0x80000040,0,140);
1222 memset((void*)0x800000D4,0,20);
1223 memset((void*)0x800000F4,0,4);
1224 memset((void*)0x80003000,0,192);
1225 memset((void*)0x800030C8,0,12);
1226 memset((void*)0x800030E2,0,1);
1228 __PADDisableRecalibration(ret);
1230 #endif
1232 void SYS_RegisterResetFunc(sys_resetinfo *info)
1234 u32 level;
1235 sys_resetinfo *after;
1236 lwp_queue *header = &sys_reset_func_queue;
1238 _CPU_ISR_Disable(level);
1239 for(after=(sys_resetinfo*)header->first;after->node.next!=NULL && info->prio>=after->prio;after=(sys_resetinfo*)after->node.next);
1240 __lwp_queue_insertI(after->node.prev,&info->node);
1241 _CPU_ISR_Restore(level);
1244 void SYS_UnregisterResetFunc(sys_resetinfo *info) {
1245 u32 level;
1246 lwp_node *n;
1248 _CPU_ISR_Disable(level);
1249 for (n = sys_reset_func_queue.first; n->next; n = n->next) {
1250 if (n == &info->node) {
1251 __lwp_queue_extractI(n);
1252 break;
1255 _CPU_ISR_Restore(level);
1258 void SYS_SetArena1Lo(void *newLo)
1260 u32 level;
1262 _CPU_ISR_Disable(level);
1263 __sysarena1lo = newLo;
1264 _CPU_ISR_Restore(level);
1267 void* SYS_GetArena1Lo()
1269 u32 level;
1270 void *arenalo;
1272 _CPU_ISR_Disable(level);
1273 arenalo = __sysarena1lo;
1274 _CPU_ISR_Restore(level);
1276 return arenalo;
1279 void SYS_SetArena1Hi(void *newHi)
1281 u32 level;
1283 _CPU_ISR_Disable(level);
1284 __sysarena1hi = newHi;
1285 _CPU_ISR_Restore(level);
1288 void* SYS_GetArena1Hi()
1290 u32 level;
1291 void *arenahi;
1293 _CPU_ISR_Disable(level);
1294 arenahi = __sysarena1hi;
1295 _CPU_ISR_Restore(level);
1297 return arenahi;
1300 u32 SYS_GetArena1Size()
1302 u32 level,size;
1304 _CPU_ISR_Disable(level);
1305 size = ((u32)__sysarena1hi - (u32)__sysarena1lo);
1306 _CPU_ISR_Restore(level);
1308 return size;
1311 void* SYS_AllocArena1MemLo(u32 size,u32 align)
1313 u32 mem1lo;
1314 void *ptr = NULL;
1316 mem1lo = (u32)SYS_GetArena1Lo();
1317 ptr = (void*)((mem1lo+(align-1))&~(align-1));
1318 mem1lo = ((((u32)ptr+size+align)-1)&~(align-1));
1319 SYS_SetArena1Lo((void*)mem1lo);
1321 return ptr;
1324 #if defined(HW_RVL)
1325 void SYS_SetArena2Lo(void *newLo)
1327 u32 level;
1329 _CPU_ISR_Disable(level);
1330 __sysarena2lo = newLo;
1331 _CPU_ISR_Restore(level);
1334 void* SYS_GetArena2Lo()
1336 u32 level;
1337 void *arenalo;
1339 _CPU_ISR_Disable(level);
1340 arenalo = __sysarena2lo;
1341 _CPU_ISR_Restore(level);
1343 return arenalo;
1346 void SYS_SetArena2Hi(void *newHi)
1348 u32 level;
1350 _CPU_ISR_Disable(level);
1351 __sysarena2hi = newHi;
1352 _CPU_ISR_Restore(level);
1355 void* SYS_GetArena2Hi()
1357 u32 level;
1358 void *arenahi;
1360 _CPU_ISR_Disable(level);
1361 arenahi = __sysarena2hi;
1362 _CPU_ISR_Restore(level);
1364 return arenahi;
1367 u32 SYS_GetArena2Size()
1369 u32 level,size;
1371 _CPU_ISR_Disable(level);
1372 size = ((u32)__sysarena2hi - (u32)__sysarena2lo);
1373 _CPU_ISR_Restore(level);
1375 return size;
1378 void* SYS_AllocArena2MemLo(u32 size,u32 align)
1380 u32 mem2lo;
1381 void *ptr = NULL;
1383 mem2lo = (u32)SYS_GetArena2Lo();
1384 ptr = (void*)((mem2lo+(align-1))&~(align-1));
1385 mem2lo = ((((u32)ptr+size+align)-1)&~(align-1));
1386 SYS_SetArena2Lo((void*)mem2lo);
1388 return ptr;
1390 #endif
1392 void SYS_ProtectRange(u32 chan,void *addr,u32 bytes,u32 cntrl)
1394 u16 rcntrl;
1395 u32 pstart,pend,level;
1397 if(chan<SYS_PROTECTCHANMAX) {
1398 pstart = ((u32)addr)&~0x3ff;
1399 pend = ((((u32)addr)+bytes)+1023)&~0x3ff;
1400 DCFlushRange((void*)pstart,(pend-pstart));
1402 _CPU_ISR_Disable(level);
1404 __UnmaskIrq(IRQMASK(chan));
1405 _memReg[chan<<2] = _SHIFTR(pstart,10,16);
1406 _memReg[(chan<<2)+1] = _SHIFTR(pend,10,16);
1408 rcntrl = _memReg[8];
1409 rcntrl = (rcntrl&~(_SHIFTL(3,(chan<<1),2)))|(_SHIFTL(cntrl,(chan<<1),2));
1410 _memReg[8] = rcntrl;
1412 if(cntrl==SYS_PROTECTRDWR)
1413 __MaskIrq(IRQMASK(chan));
1416 _CPU_ISR_Restore(level);
1420 void* SYS_AllocateFramebuffer(GXRModeObj *rmode)
1422 return memalign(32, VIDEO_GetFrameBufferSize(rmode));
1425 u32 SYS_GetFontEncoding()
1427 u32 ret,tv_mode;
1429 if(sys_fontenc<=0x0001) return sys_fontenc;
1431 ret = 0;
1432 tv_mode = VIDEO_GetCurrentTvMode();
1433 if(tv_mode==VI_NTSC && _viReg[55]&0x0002) ret = 1;
1434 sys_fontenc = ret;
1435 return ret;
1438 u32 SYS_InitFont(sys_fontheader *font_data)
1440 void *packed_data = NULL;
1442 if(!font_data) return 0;
1444 if(SYS_GetFontEncoding()==1) {
1445 memset(font_data,0,SYS_FONTSIZE_SJIS);
1446 packed_data = (void*)((u32)font_data+868096);
1447 } else {
1448 memset(font_data,0,SYS_FONTSIZE_ANSI);
1449 packed_data = (void*)((u32)font_data+119072);
1452 if(__SYS_LoadFont(packed_data,font_data)==1) {
1453 sys_fontimage = (u8*)((((u32)font_data+font_data->sheet_image)+31)&~31);
1454 __expand_font((u8*)font_data+font_data->sheet_image,sys_fontimage);
1455 return 1;
1458 return 0;
1461 void SYS_GetFontTexture(s32 c,void **image,s32 *xpos,s32 *ypos,s32 *width)
1463 u32 sheets,rem;
1465 *xpos = 0;
1466 *ypos = 0;
1467 *image = NULL;
1468 if(!sys_fontwidthtab || ! sys_fontimage) return;
1470 if(c<sys_fontdata->first_char || c>sys_fontdata->last_char) c = sys_fontdata->inval_char;
1471 else c -= sys_fontdata->first_char;
1473 sheets = c/sys_fontcharsinsheet;
1474 rem = c%sys_fontcharsinsheet;
1475 *image = sys_fontimage+(sys_fontdata->sheet_size*sheets);
1476 *xpos = (rem%sys_fontdata->sheet_column)*sys_fontdata->cell_width;
1477 *ypos = (rem/sys_fontdata->sheet_column)*sys_fontdata->cell_height;
1478 *width = sys_fontwidthtab[c];
1481 void SYS_GetFontTexel(s32 c,void *image,s32 pos,s32 stride,s32 *width)
1483 u32 sheets,rem;
1484 u32 xoff,yoff;
1485 u32 xpos,ypos;
1486 u8 *img_start;
1487 u8 *ptr1,*ptr2;
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 xoff = (rem%sys_fontdata->sheet_column)*sys_fontdata->cell_width;
1497 yoff = (rem/sys_fontdata->sheet_column)*sys_fontdata->cell_height;
1498 img_start = sys_fontimage+(sys_fontdata->sheet_size*sheets);
1500 ypos = 0;
1501 while(ypos<sys_fontdata->cell_height) {
1502 xpos = 0;
1503 while(xpos<sys_fontdata->cell_width) {
1504 ptr1 = img_start+(((sys_fontdata->sheet_width/8)<<5)*((ypos+yoff)/8));
1505 ptr1 = ptr1+(((xpos+xoff)/8)<<5);
1506 ptr1 = ptr1+(((ypos+yoff)%8)<<2);
1507 ptr1 = ptr1+(((xpos+xoff)%8)/2);
1509 ptr2 = image+((ypos/8)*(((stride<<1)/8)<<5));
1510 ptr2 = ptr2+(((xpos+pos)/8)<<5);
1511 ptr2 = ptr2+(((xpos+pos)%8)/2);
1512 ptr2 = ptr2+((ypos%8)<<2);
1514 *ptr2 = *ptr1;
1516 xpos += 2;
1518 ypos++;
1520 *width = sys_fontwidthtab[c];
1523 s32 SYS_CreateAlarm(syswd_t *thealarm)
1525 alarm_st *alarm;
1527 alarm = __lwp_syswd_allocate();
1528 if(!alarm) return -1;
1530 alarm->alarmhandler = NULL;
1531 alarm->ticks = 0;
1532 alarm->start_per = 0;
1533 alarm->periodic = 0;
1535 *thealarm = (LWP_OBJMASKTYPE(LWP_OBJTYPE_SYSWD)|LWP_OBJMASKID(alarm->object.id));
1536 __lwp_thread_dispatchenable();
1537 return 0;
1540 s32 SYS_SetAlarm(syswd_t thealarm,const struct timespec *tp,alarmcallback cb,void *cbarg)
1542 alarm_st *alarm;
1544 alarm = __lwp_syswd_open(thealarm);
1545 if(!alarm) return -1;
1547 alarm->cb_arg = cbarg;
1548 alarm->alarmhandler = cb;
1549 alarm->ticks = __lwp_wd_calc_ticks(tp);
1551 alarm->periodic = 0;
1552 alarm->start_per = 0;
1554 __lwp_wd_initialize(&alarm->alarm,__sys_alarmhandler,alarm->object.id,(void*)thealarm);
1555 __lwp_wd_insert_ticks(&alarm->alarm,alarm->ticks);
1556 __lwp_thread_dispatchenable();
1557 return 0;
1560 s32 SYS_SetPeriodicAlarm(syswd_t thealarm,const struct timespec *tp_start,const struct timespec *tp_period,alarmcallback cb,void *cbarg)
1562 alarm_st *alarm;
1564 alarm = __lwp_syswd_open(thealarm);
1565 if(!alarm) return -1;
1567 alarm->start_per = __lwp_wd_calc_ticks(tp_start);
1568 alarm->periodic = __lwp_wd_calc_ticks(tp_period);
1569 alarm->alarmhandler = cb;
1570 alarm->cb_arg = cbarg;
1572 alarm->ticks = 0;
1574 __lwp_wd_initialize(&alarm->alarm,__sys_alarmhandler,alarm->object.id,(void*)thealarm);
1575 __lwp_wd_insert_ticks(&alarm->alarm,alarm->start_per);
1576 __lwp_thread_dispatchenable();
1577 return 0;
1580 s32 SYS_RemoveAlarm(syswd_t thealarm)
1582 alarm_st *alarm;
1584 alarm = __lwp_syswd_open(thealarm);
1585 if(!alarm) return -1;
1587 alarm->alarmhandler = NULL;
1588 alarm->ticks = 0;
1589 alarm->periodic = 0;
1590 alarm->start_per = 0;
1592 __lwp_wd_remove_ticks(&alarm->alarm);
1593 __lwp_syswd_free(alarm);
1594 __lwp_thread_dispatchenable();
1595 return 0;
1598 s32 SYS_CancelAlarm(syswd_t thealarm)
1600 alarm_st *alarm;
1602 alarm = __lwp_syswd_open(thealarm);
1603 if(!alarm) return -1;
1605 alarm->alarmhandler = NULL;
1606 alarm->ticks = 0;
1607 alarm->periodic = 0;
1608 alarm->start_per = 0;
1610 __lwp_wd_remove_ticks(&alarm->alarm);
1611 __lwp_thread_dispatchenable();
1612 return 0;
1615 resetcallback SYS_SetResetCallback(resetcallback cb)
1617 u32 level;
1618 resetcallback old;
1620 _CPU_ISR_Disable(level);
1621 old = __RSWCallback;
1622 __RSWCallback = cb;
1623 #if defined(HW_DOL)
1624 if(__RSWCallback) {
1625 _piReg[0] = 2;
1626 __UnmaskIrq(IRQMASK(IRQ_PI_RSW));
1627 } else
1628 __MaskIrq(IRQMASK(IRQ_PI_RSW));
1629 #endif
1630 _CPU_ISR_Restore(level);
1631 return old;
1634 #if defined(HW_RVL)
1635 powercallback SYS_SetPowerCallback(powercallback cb)
1637 u32 level;
1638 powercallback old;
1640 _CPU_ISR_Disable(level);
1641 old = __POWCallback;
1642 __POWCallback = cb;
1643 _CPU_ISR_Restore(level);
1644 return old;
1646 #endif
1648 void SYS_StartPMC(u32 mcr0val,u32 mcr1val)
1650 mtmmcr0(mcr0val);
1651 mtmmcr1(mcr1val);
1654 void SYS_StopPMC()
1656 mtmmcr0(0);
1657 mtmmcr1(0);
1660 void SYS_ResetPMC()
1662 mtpmc1(0);
1663 mtpmc2(0);
1664 mtpmc3(0);
1665 mtpmc4(0);
1668 void SYS_DumpPMC()
1670 printf("<%d load/stores / %d miss cycles / %d cycles / %d instructions>\n",mfpmc1(),mfpmc2(),mfpmc3(),mfpmc4());
1673 void SYS_SetWirelessID(u32 chan,u32 id)
1675 u32 write;
1676 syssramex *sram;
1678 write = 0;
1679 sram = __SYS_LockSramEx();
1680 if(sram->wirelessPad_id[chan]!=(u16)id) {
1681 sram->wirelessPad_id[chan] = (u16)id;
1682 write = 1;
1684 __SYS_UnlockSramEx(write);
1687 u32 SYS_GetWirelessID(u32 chan)
1689 u16 id;
1690 syssramex *sram;
1692 id = 0;
1693 sram = __SYS_LockSramEx();
1694 id = sram->wirelessPad_id[chan];
1695 __SYS_UnlockSramEx(0);
1696 return id;
1699 #if defined(HW_RVL)
1700 u32 SYS_GetHollywoodRevision()
1702 u32 rev;
1703 DCInvalidateRange((void*)0x80003138,8);
1704 rev = *((u32*)0x80003138);
1705 return rev;
1707 #endif