diff options
| author | Legolas <Legolas@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2011-03-05 21:27:40 +0000 |
|---|---|---|
| committer | Legolas <Legolas@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2011-03-05 21:27:40 +0000 |
| commit | 2b4cfd4bfa34efb605b790bec8c846a3c4c0be1b (patch) | |
| tree | ead514e6acae5695b57df901c2a80db34570d78e /packages/libogcfpc/src/ogc | |
| parent | 450d1f0ab946ba913a81c43c4f12bbbb60f117b2 (diff) | |
| download | fpc-2b4cfd4bfa34efb605b790bec8c846a3c4c0be1b.tar.gz | |
* libogc improved by adding some helper functions
* fixed examples and makefiles
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@17082 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'packages/libogcfpc/src/ogc')
| -rw-r--r-- | packages/libogcfpc/src/ogc/lwp_heap.inc | 85 | ||||
| -rw-r--r-- | packages/libogcfpc/src/ogc/lwp_mutex.inc | 99 | ||||
| -rw-r--r-- | packages/libogcfpc/src/ogc/lwp_priority.inc | 49 | ||||
| -rw-r--r-- | packages/libogcfpc/src/ogc/lwp_threads.inc | 97 | ||||
| -rw-r--r-- | packages/libogcfpc/src/ogc/lwp_watchdog.inc | 83 | ||||
| -rw-r--r-- | packages/libogcfpc/src/ogc/machine/processor.inc | 32 |
6 files changed, 420 insertions, 25 deletions
diff --git a/packages/libogcfpc/src/ogc/lwp_heap.inc b/packages/libogcfpc/src/ogc/lwp_heap.inc index 6b5c405c04..3fb2468771 100644 --- a/packages/libogcfpc/src/ogc/lwp_heap.inc +++ b/packages/libogcfpc/src/ogc/lwp_heap.inc @@ -44,16 +44,10 @@ type pheap_cntrl = ^heap_cntrl; -function __lwp_heap_init(theheap: Pheap_cntrl; start_addr: pointer; - size, pg_size: cuint32): cuint32; cdecl; external; - +function __lwp_heap_init(theheap: Pheap_cntrl; start_addr: pointer; size, pg_size: cuint32): cuint32; cdecl; external; function __lwp_heap_allocate(theheap: Pheap_cntrl; size: cuint32): pointer; cdecl; external; - function __lwp_heap_free(theheap: Pheap_cntrl; ptr: pointer): cbool; cdecl; external; - -function __lwp_heap_getinfo(theheap: Pheap_cntrl; theinfo: Pheap_iblock) - : cuint32; cdecl; external; - +function __lwp_heap_getinfo(theheap: Pheap_cntrl; theinfo: Pheap_iblock): cuint32; cdecl; external; //{$ifdef LIBOGC_INTERNAL} //{$include libogc/lwp_heap.inl} @@ -61,3 +55,78 @@ function __lwp_heap_getinfo(theheap: Pheap_cntrl; theinfo: Pheap_iblock) {$ENDIF} +{$IFDEF OGC_IMPLEMENTATION} +function __lwp_heap_head(theheap: pheap_cntrl): pheap_block; +begin + result := theheap^.start; +end; + +function __lwp_heap_tail(heap: pheap_cntrl): pheap_block; +begin + result := heap^.final; +end; + +function __lwp_heap_prevblock(block: pheap_block): pheap_block; +begin + result := pheap_block (pcchar(block)^ - (block^.back_flag and not HEAP_BLOCK_USED)); +end; + +function __lwp_heap_nextblock(block: pheap_block): pheap_block; +begin + result := pheap_block(pcchar(block)^ + (block^.front_flag and not HEAP_BLOCK_USED)); +end; + +function __lwp_heap_blockat(block: pheap_block; offset: cuint32): pheap_block; +begin + result := pheap_block(pcchar(block) + offset); +end; + +function __lwp_heap_usrblockat(ptr: pointer): pheap_block; +var + offset: cuint32; +begin + offset := (pcuint32(ptr)^ - 1); + result := __lwp_heap_blockat(ptr, -offset + (-HEAP_BLOCK_USED_OVERHEAD)); +end; + +function __lwp_heap_prev_blockfree(block: pheap_block): boolean; +begin + result := (block^.back_flag and HEAP_BLOCK_USED) = 0; +end; + +function __lwp_heap_blockfree(block: pheap_block): boolean; +begin + result := (block^.front_flag and HEAP_BLOCK_USED) = 0; +end; + +function __lwp_heap_blockused(block: pheap_block): boolean; +begin + result := (block^.front_flag and HEAP_BLOCK_USED) <> 0; +end; + +function __lwp_heap_blocksize(block: pheap_block): cuint32; +begin + result := (block^.front_flag and not HEAP_BLOCK_USED); +end; + +function __lwp_heap_startuser(block: pheap_block): pointer; +begin + result := pointer(block^.next); +end; + +function __lwp_heap_blockin(heap: pheap_cntrl; block: pheap_block): boolean; +begin + result := ((cuint32(block) >= cuint32(heap^.start)) and (cuint32(block) <= cuint32(heap^.final))); +end; + +function __lwp_heap_pgsize_valid(pgsize: cuint32): boolean; +begin + result := (pgsize <> 0) and ((pgsize mod PPC_ALIGNMENT) = 0); +end; + +function __lwp_heap_buildflag(size, flag: cuint32): cuint32; +begin + result := (size or flag); +end; +{$ENDIF} + diff --git a/packages/libogcfpc/src/ogc/lwp_mutex.inc b/packages/libogcfpc/src/ogc/lwp_mutex.inc index be01108f58..00277c38e3 100644 --- a/packages/libogcfpc/src/ogc/lwp_mutex.inc +++ b/packages/libogcfpc/src/ogc/lwp_mutex.inc @@ -49,8 +49,7 @@ procedure __lwp_mutex_seize_irq_blocking(mutex: Plwp_mutex; timeout: cuint64); c procedure __lwp_mutex_flush(mutex: Plwp_mutex; status: cuint32); cdecl; external; - -function __lwp_mutex_seize_irq_trylock(mutex: plwp_mutex; isr_level: pcuint32): cuint32; cdecl; external; +function __lwp_mutex_seize_irq_trylock(mutex: plwp_mutex; isr_level: pcuint32): cuint32; inline; procedure __lwp_mutex_seize(_mutex_t: plwp_mutex; _id: cuint32; _wait: cuint8; _timeout, _level: cuint32); inline; @@ -58,6 +57,32 @@ procedure __lwp_mutex_seize(_mutex_t: plwp_mutex; _id: cuint32; _wait: cuint8; _ {$IFDEF OGC_IMPLEMENTATION} + +function __lwp_mutex_locked(mutex: plwp_mutex): boolean; +begin + result := (mutex^.lock = LWP_MUTEX_LOCKED); +end; + +function __lwp_mutex_isinheritprio(attrs: plwp_mutex_attr): boolean; +begin + result := (attrs^.mode = LWP_MUTEX_INHERITPRIO); +end; + +function __lwp_mutex_isprioceiling(attrs: plwp_mutex_attr): boolean; +begin + result := (attrs^.mode = LWP_MUTEX_PRIORITYCEIL); +end; + +function __lwp_mutex_ispriority(attrs: plwp_mutex_attr): boolean; +begin + result := (attrs^.mode = LWP_MUTEX_PRIORITY); +end; + +function __lwp_mutex_isfifo(attrs: plwp_mutex_attr): boolean; +begin + result := (attrs^.mode = LWP_MUTEX_FIFO); +end; + procedure __lwp_mutex_seize(_mutex_t: plwp_mutex; _id: cuint32; _wait: cuint8; _timeout, _level: cuint32); inline; begin repeat @@ -79,6 +104,76 @@ begin end; until false; end; + +function __lwp_mutex_seize_irq_trylock(mutex: plwp_mutex; isr_level: pcuint32): cuint32; inline; +var + exec: plwp_cntrl; + level: cuint32; + prioceiling, priocurr: cuint32; +begin + level := isr_level^; + exec := _thr_executing; + exec^.wait.ret_code := LWP_MUTEX_SUCCESSFUL; + if not __lwp_mutex_locked(mutex) then + begin + mutex^.lock := LWP_MUTEX_LOCKED; + mutex^.holder := exec; + mutex^.nest_cnt := 1; + if __lwp_mutex_isinheritprio(@(mutex^.atrrs)) or __lwp_mutex_isprioceiling(@(mutex^.atrrs)) then + inc(exec^.res_cnt); + if not __lwp_mutex_isprioceiling(@(mutex^.atrrs)) then + begin + _CPU_ISR_Restore(level); + result := 0; + end; + begin + prioceiling := mutex^.atrrs.prioceil; + priocurr := exec^.cur_prio; + if (priocurr = prioceiling) then + begin + _CPU_ISR_Restore(level); + result := 0; + end; + if (priocurr > prioceiling) then + begin + __lwp_thread_dispatchdisable(); + _CPU_ISR_Restore(level); + __lwp_thread_changepriority(mutex^.holder, mutex^.atrrs.prioceil, 0); + __lwp_thread_dispatchenable(); + result := 0; + end; + exec^.wait.ret_code := LWP_MUTEX_CEILINGVIOL; + mutex^.nest_cnt := 0; + dec(exec^.res_cnt); + _CPU_ISR_Restore(level); + result := 0; + end; + result := 0; + end; + + if (__lwp_thread_isexec(mutex^.holder)) <> 0 then + begin + case mutex^.atrrs.nest_behavior of + LWP_MUTEX_NEST_ACQUIRE: + begin + inc(mutex^.nest_cnt); + _CPU_ISR_Restore(level); + result := 0; + end; + LWP_MUTEX_NEST_ERROR: + begin + exec^.wait.ret_code := LWP_MUTEX_NEST_NOTALLOWED; + _CPU_ISR_Restore(level); + result := 0; + end; + LWP_MUTEX_NEST_BLOCK: + begin + end; + end; + end; + result := 1; +end; + //{$ifdef LIBOGC_INTERNAL} //{$include libogc/lwp_mutex.inl} //{$endif} diff --git a/packages/libogcfpc/src/ogc/lwp_priority.inc b/packages/libogcfpc/src/ogc/lwp_priority.inc index ef8fcab64f..ed6b776698 100644 --- a/packages/libogcfpc/src/ogc/lwp_priority.inc +++ b/packages/libogcfpc/src/ogc/lwp_priority.inc @@ -29,3 +29,52 @@ procedure __lwp_priority_init; cdecl; external; //{$endif} {$ENDIF} + +{$IFDEF OGC_IMPLEMENTATION} +procedure __lwp_priomap_init(theprio: pprio_cntrl; prio: cuint32); +var + major,minor,mask: cuint32; +begin + major := prio div 16; + minor := prio mod 16; + + theprio^.minor := @(_prio_bitmap[major]); + + mask := $80000000 shr major; + theprio^.ready_major := mask; + theprio^.block_major := not mask; + + mask := $80000000 shr minor; + theprio^.ready_minor := mask; + theprio^.block_minor := not mask; +//#ifdef _LWPPRIO_DEBUG +// printf("__lwp_priomap_init(%p,%d,%p,%d,%d,%d,%d)\n",theprio,prio,theprio->minor,theprio->ready_major,theprio->ready_minor,theprio->block_major,theprio->block_minor); +//#endif +end; + +procedure __lwp_priomap_addto(theprio: pprio_cntrl); +begin + theprio^.minor^ := theprio^.minor^ or theprio^.ready_minor; + _prio_major_bitmap := _prio_major_bitmap or theprio^.ready_major; +end; + +procedure __lwp_priomap_removefrom(theprio: pprio_cntrl); +begin + theprio^.minor^ := theprio^.minor^ and theprio^.block_minor; + if theprio^.minor^ = 0 then + _prio_major_bitmap := _prio_major_bitmap and theprio^.block_major; +end; + +function __lwp_priomap_highest(): cuint32; +var + major, minor: cuint32; +begin + major := cntlzw(_prio_major_bitmap); + minor := cntlzw(_prio_bitmap[major]); +//#ifdef _LWPPRIO_DEBUG +// printf("__lwp_priomap_highest(%d)\n",((major<<4)+minor)); +//#endif + result := ((major shl 4) + minor); +end; +{$ENDIF} + diff --git a/packages/libogcfpc/src/ogc/lwp_threads.inc b/packages/libogcfpc/src/ogc/lwp_threads.inc index bbdb739b2b..485d7464a5 100644 --- a/packages/libogcfpc/src/ogc/lwp_threads.inc +++ b/packages/libogcfpc/src/ogc/lwp_threads.inc @@ -133,9 +133,102 @@ procedure __lwp_thread_dispatchdisable(); inline; {$ENDIF} {$IFDEF OGC_IMPLEMENTATION} -procedure __lwp_thread_dispatchdisable(); inline; +function __lwp_thread_isexec(thethread: plwp_cntrl): cuint32; +begin + result := 0; + if (thethread = _thr_executing) then result := 1; +end; + +function __lwp_thread_isheir(thethread: plwp_cntrl): cuint32; +begin + result := 0; + if (thethread = _thr_heir) then result := 1; +end; + +procedure __lwp_thread_calcheir(); +begin + _thr_heir := plwp_cntrl(_lwp_thr_ready[__lwp_priomap_highest()].first); +//#ifdef _LWPTHREADS_DEBUG +// printf("__lwp_thread_calcheir(%p)\n",_thr_heir); +//#endif +end; + +function __lwp_thread_isallocatedfp(thethread: plwp_cntrl): cuint32; +begin + result := 0; + if (thethread = _thr_allocated_fp) then result := 1; +end; + +procedure __lwp_thread_deallocatefp(); +begin + _thr_allocated_fp := nil; +end; + +procedure __lwp_thread_dispatchinitialize(); +begin + _thread_dispatch_disable_level := 1; +end; + +procedure __lwp_thread_dispatchenable(); +begin + dec(_thread_dispatch_disable_level); + if (_thread_dispatch_disable_level = 0) then + __thread_dispatch(); +end; + +procedure __lwp_thread_dispatchdisable(); +begin + inc(_thread_dispatch_disable_level); +end; + +procedure __lwp_thread_dispatchunnest(); begin - inc(_thread_dispatch_disable_level); + dec(_thread_dispatch_disable_level); end; + +procedure __lwp_thread_unblock(thethread: plwp_cntrl); +begin + __lwp_thread_clearstate(thethread, LWP_STATES_BLOCKED); +end; + +function __lwp_thread_getlibcreent(): pointer; +begin + result := __lwp_thr_libc_reent; +end; + +procedure __lwp_thread_setlibcreent(libc_reent: pointer); +begin + __lwp_thr_libc_reent := libc_reent; +end; + +function __lwp_thread_isswitchwant(): cbool; +begin + result := cbool(_context_switch_want); +end; + +function __lwp_thread_isdispatchenabled(): cbool; +begin + result := (_thread_dispatch_disable_level = 0); +end; + +procedure __lwp_thread_inittimeslice(); +begin + __lwp_wd_initialize(@_lwp_wd_timeslice, @__lwp_thread_tickle_timeslice, LWP_TIMESLICE_TIMER_ID, nil); +end; + +procedure __lwp_thread_starttimeslice(); +begin + __lwp_wd_insert_ticks(@_lwp_wd_timeslice, millisecs_to_ticks(1)); +end; + +procedure __lwp_thread_stoptimeslice(); +begin + __lwp_wd_remove_ticks(@_lwp_wd_timeslice); +end; + +//procedure __lwp_thread_dispatchdisable(); inline; +//begin +// inc(_thread_dispatch_disable_level); +//end; {$ENDIF} diff --git a/packages/libogcfpc/src/ogc/lwp_watchdog.inc b/packages/libogcfpc/src/ogc/lwp_watchdog.inc index 3482ab39aa..354a7d0694 100644 --- a/packages/libogcfpc/src/ogc/lwp_watchdog.inc +++ b/packages/libogcfpc/src/ogc/lwp_watchdog.inc @@ -173,4 +173,87 @@ begin result := -x; end; + +procedure __lwp_wd_initialize(wd: pwd_cntrl; routine: wd_service_routine; id: cuint32; usr_data: pointer); +begin + wd^.state := LWP_WD_INACTIVE; + wd^.id := id; + wd^.routine := routine; + wd^.usr_data := usr_data; +end; + +function __lwp_wd_first(queue: plwp_queue): pwd_cntrl; +begin + result := pwd_cntrl(@(queue^.first)); +end; + +function __lwp_wd_last(queue: plwp_queue): pwd_cntrl; +begin + result := pwd_cntrl(@(queue^.last)); +end; + +function __lwp_wd_next(wd: pwd_cntrl): pwd_cntrl; +begin + result := pwd_cntrl(@(wd^.node.next)); +end; + +function __lwp_wd_prev(wd: pwd_cntrl): pwd_cntrl; +begin + result := pwd_cntrl(@(wd^.node.prev)); +end; + +procedure __lwp_wd_activate(wd: pwd_cntrl); +begin + wd^.state := LWP_WD_ACTIVE; +end; + +procedure __lwp_wd_deactivate(wd: pwd_cntrl); +begin + wd^.state := LWP_WD_REMOVE; +end; + +function __lwp_wd_isactive(wd: pwd_cntrl): cuint32; +begin + result := 0; + if (wd^.state = LWP_WD_ACTIVE) then result := 1; +end; + +function __lwp_wd_calc_ticks(const time: ptimespec): cuint64; +var + ticks: cuint64; +begin + ticks := secs_to_ticks(time^.tv_sec); + ticks := ticks + nanosecs_to_ticks(time^.tv_nsec); + result := ticks; +end; + +procedure __lwp_wd_tickle_ticks(); +begin + __lwp_wd_tickle(@_wd_ticks_queue); +end; + +procedure __lwp_wd_insert_ticks(wd: pwd_cntrl; interval: cint64); +begin + wd^.start := gettime(); + wd^.fire := (wd^.start + LWP_WD_ABS(interval)); + __lwp_wd_insert(@_wd_ticks_queue, wd); +end; + +procedure __lwp_wd_adjust_ticks(dir: cuint32; interval: cint64); +begin + __lwp_wd_adjust(@_wd_ticks_queue,dir,interval); +end; + +procedure __lwp_wd_remove_ticks(wd: pwd_cntrl); +begin + __lwp_wd_remove(@_wd_ticks_queue,wd); +end; + +procedure __lwp_wd_reset(wd: pwd_cntrl); +begin + __lwp_wd_remove(@_wd_ticks_queue,wd); + __lwp_wd_insert(@_wd_ticks_queue,wd); +end; + + {$ENDIF} diff --git a/packages/libogcfpc/src/ogc/machine/processor.inc b/packages/libogcfpc/src/ogc/machine/processor.inc index f6ba329b56..48e32b368d 100644 --- a/packages/libogcfpc/src/ogc/machine/processor.inc +++ b/packages/libogcfpc/src/ogc/machine/processor.inc @@ -11,13 +11,13 @@ procedure ppchalt(); inline; //procedure mfpvr(); inline; function mfpvr(): cint32; inline; -procedure mfdcr(_rn: cuint); inline; +function mfdcr(_rn: cuint): cuint32; inline; procedure mtdcr(rn, val: cuint); inline; -procedure mfmsr(); inline; +function mfmsr(): cuint32; inline; procedure mtmsr(val: cuint); inline; -procedure mfdec(); inline; +function mfdec(): cuint32; inline; procedure mtdec(_val: cuint); inline; -procedure mfspr(_rn: cuint); inline; +function mfspr(_rn: cuint): cuint32; inline; procedure mtspr(_rn, _val: cuint); inline; {$define mfwpar() := mfspr(WPAR)} @@ -46,12 +46,12 @@ procedure mtspr(_rn, _val: cuint); inline; {$define mfhid4() := mfspr(HID4)} {$define mthid4(_val) := mtspr(HID4,_val)} -procedure __lhbrx(base, index: cuint32); inline; +function __lhbrx(base, index: cuint32): cuint16; inline; //procedure __lwbrx(base,index: cuint32); inline; function __lwbrx(base,index: cuint32): cuint32; inline; procedure __sthbrx(base,index,value: cuint32); inline; procedure __stwbrx(base,index,value: cuint32); inline; -procedure cntlzw(_val: cuint32); inline; +function cntlzw(_val: cuint32): cuint32; inline; procedure _CPU_MSR_GET( _msr_value: cuint32 ); inline; procedure _CPU_MSR_SET( _msr_value: cuint32 ); inline; procedure _CPU_ISR_Enable(); inline; @@ -118,13 +118,14 @@ begin result := _rval; end; -procedure mfdcr(_rn: cuint); inline; +function mfdcr(_rn: cuint): cuint32; inline; var _rval: cuint32; begin asm // mfdcr r3,_rn // unrecognized opcode? end; + result := _rval; end; procedure mtdcr(rn, val: cuint); inline; @@ -134,13 +135,14 @@ begin end; end; -procedure mfmsr(); inline; +function mfmsr(): cuint32; inline; var _rval: cuint32; begin asm mfmsr r3 end; + result := _rval; end; procedure mtmsr(val: cuint); inline; @@ -150,7 +152,7 @@ begin end; end; -procedure mfdec(); inline; +function mfdec(): cuint32; inline; var _rval: cuint32; begin @@ -158,6 +160,7 @@ begin // mfdec r3 // unrecognized opcode? mfspr r3,22 // unrecognized opcode? end; + result := _rval; end; procedure mtdec(_val: cuint); inline; @@ -168,13 +171,14 @@ begin end; end; -procedure mfspr(_rn: cuint); inline; +function mfspr(_rn: cuint): cuint32; inline; var _rval: cuint32 = 0; begin asm mfspr r3,r4 end; + result := _rval; end; procedure mtspr(_rn, _val: cuint); inline; @@ -184,13 +188,14 @@ begin end; end; -procedure __lhbrx(base, index: cuint32); inline; +function __lhbrx(base, index: cuint32): cuint16; inline; var res: cuint16; begin asm lhbrx r3,r4,r5 end; + result := res; end; //procedure __lwbrx(base,index: cuint32); inline; @@ -218,13 +223,14 @@ begin end; end; -procedure cntlzw(_val: cuint32); inline; +function cntlzw(_val: cuint32): cuint32; inline; var _rval: cuint32; begin asm cntlzw r3, r4 end; + result := _rval; end; procedure _CPU_MSR_GET( _msr_value: cuint32 ); inline; @@ -327,7 +333,7 @@ var tmp: cuint16; begin tmp := val; - __lhbrx(tmp,0); //?? + result := __lhbrx(tmp,0); //?? end; function bswap32(val: cuint32): cuint32; inline; |
