summaryrefslogtreecommitdiff
path: root/packages/libogcfpc/src/ogc
diff options
context:
space:
mode:
authorLegolas <Legolas@3ad0048d-3df7-0310-abae-a5850022a9f2>2011-03-05 21:27:40 +0000
committerLegolas <Legolas@3ad0048d-3df7-0310-abae-a5850022a9f2>2011-03-05 21:27:40 +0000
commit2b4cfd4bfa34efb605b790bec8c846a3c4c0be1b (patch)
treeead514e6acae5695b57df901c2a80db34570d78e /packages/libogcfpc/src/ogc
parent450d1f0ab946ba913a81c43c4f12bbbb60f117b2 (diff)
downloadfpc-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.inc85
-rw-r--r--packages/libogcfpc/src/ogc/lwp_mutex.inc99
-rw-r--r--packages/libogcfpc/src/ogc/lwp_priority.inc49
-rw-r--r--packages/libogcfpc/src/ogc/lwp_threads.inc97
-rw-r--r--packages/libogcfpc/src/ogc/lwp_watchdog.inc83
-rw-r--r--packages/libogcfpc/src/ogc/machine/processor.inc32
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;