revert between 56095 -> 55830 in arch
[AROS.git] / arch / ppc-chrp / efika / timer / lowlevel.c
blobab1eaeac4a2099592b96273d96b94a9c2f6a79d8
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define DEBUG 1
8 #include <aros/debug.h>
9 #include <asm/mpc5200b.h>
10 #include <asm/io.h>
12 #include <aros/asmcall.h>
13 #include <hardware/intbits.h>
14 #include <exec/execbase.h>
16 #include <inttypes.h>
17 #include <proto/exec.h>
18 #include <proto/timer.h>
20 #include "lowlevel.h"
22 uint32_t tbc_expected;
23 uint32_t tbc_achieved;
24 int32_t corr;
26 volatile slt_t *slice_timer;
28 This is a slightly faster version of AddTime() that we use here. It
29 also saves the function call overhead...
31 #define FastAddTime(d, s)\
32 (d)->tv_micro += (s)->tv_micro;\
33 (d)->tv_secs += (s)->tv_secs;\
34 if((d)->tv_micro > 999999) {\
35 (d)->tv_secs++;\
36 (d)->tv_micro -= 1000000;\
39 BOOL timer_addToWaitList(struct TimerBase *, struct MinList *, struct timerequest *);
41 void SliceHandler(struct TimerBase *TimerBase, struct ExecBase *SysBase)
43 uint32_t startup_time = mftbl();
45 if (inl(&slice_timer->slt_ts) & SLT_TS_ST)
47 struct timerequest *tr, *next;
49 /* Clear interrupt request. */
50 outl(SLT_TS_ST, &slice_timer->slt_ts);
51 sync();
52 /* Stop the timer */
53 outl(0, &slice_timer->slt_cf);
54 // outl(SLT_CF_RUNWAIT | SLT_CF_INTRENA | SLT_CF_ENABLE, &slice_timer->slt_cf);
56 // D(bug("[timer] SliceHandler on %08x%08x slt->cv=%08x\n", (uint32_t)(mftb() >> 32),mftbl(),inl(&slice_timer->slt_cv)));
58 EClockUpdate(TimerBase);
60 tbc_achieved = startup_time;
62 /* Timer errors bigger than approx 15 microseconds shouldn't be taken into account */
63 //if (tbc_achieved > tbc_expected) // && (tbc_achieved - tbc_expected) < 1000)
65 corr = ((int32_t)(tbc_achieved - tbc_expected))-1;
70 Go through the "wait for x seconds" list and return requests
71 that have completed. A completed request is one whose time
72 is less than that of the elapsed time.
74 ForeachNodeSafe(&TimerBase->tb_Lists[TL_VBLANK], tr, next)
76 if(CmpTime(&TimerBase->tb_Elapsed, &tr->tr_time) <= 0)
78 if (tr == &TimerBase->tb_vblank_timerequest)
80 struct IntVector *iv = &SysBase->IntVects[INTB_VERTB];
82 /* VBlank Emu */
84 if (iv->iv_Code)
86 AROS_INTC1(iv->iv_Code, iv->iv_Data);
88 /* Automatically requeue/reactivate request */
90 Remove((struct Node *)tr);
91 tr->tr_node.io_Command = TR_ADDREQUEST;
92 tr->tr_time.tv_secs = 0;
93 tr->tr_time.tv_micro = 1000000 / SysBase->VBlankFrequency;
94 AddTime(&tr->tr_time, &TimerBase->tb_Elapsed);
96 timer_addToWaitList(TimerBase, &TimerBase->tb_Lists[TL_VBLANK], tr);
98 else
100 /* This request has finished */
101 Remove((struct Node *)tr);
102 tr->tr_time.tv_secs = tr->tr_time.tv_micro = 0;
103 tr->tr_node.io_Error = 0;
104 ReplyMsg((struct Message *)tr);
107 else
110 The first request hasn't finished, as all requests are in
111 order, we don't bother searching through the remaining
113 break;
118 The other this is the "wait until a specified time". Here a request
119 is complete if the time we are waiting for is before the current time.
121 ForeachNodeSafe(&TimerBase->tb_Lists[TL_WAITVBL], tr, next)
123 if(CmpTime(&TimerBase->tb_CurrentTime, &tr->tr_time) <= 0)
125 /* This request has finished */
126 Remove((struct Node *)tr);
127 tr->tr_time.tv_secs = tr->tr_time.tv_micro = 0;
128 tr->tr_node.io_Error = 0;
129 ReplyMsg((struct Message *)tr);
131 else
134 The first request hasn't finished, as all requests are in
135 order, we don't bother searching through the remaining
137 break;
140 TimerSetup(TimerBase, startup_time);