2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
5 Desc: Timer startup and device commands
8 /****************************************************************************************/
12 #include <exec/types.h>
14 #include <exec/errors.h>
15 #include <exec/devices.h>
16 #include <exec/alerts.h>
17 #include <exec/initializers.h>
18 #include <devices/timer.h>
19 #include <hardware/intbits.h>
21 #include <proto/exec.h>
22 #include <proto/timer.h>
23 #include <proto/kernel.h>
24 #include <proto/utility.h>
25 #include <proto/openfirmware.h>
27 #include <utility/tagitem.h>
29 #include <aros/symbolsets.h>
32 #include <asm/mpc5200b.h>
34 #include <aros/debug.h>
35 #include <proto/arossupport.h>
37 //#include "timer_intern.h"
38 #include LC_LIBDEFS_FILE
42 void SliceHandler(struct TimerBase
*TimerBase
, struct ExecBase
*SysBase
);
43 extern volatile slt_t
*slice_timer
;
45 /****************************************************************************************/
47 static int GM_UNIQUENAME(Init
)(LIBBASETYPEPTR LIBBASE
)
49 struct ExecBase
*SysBase
= getSysBase();
50 void *KernelBase
= getKernelBase();
52 TimerBase
->tb_prev_tick
= mftbl();
54 /* Setup the timer.device data */
55 LIBBASE
->tb_CurrentTime
.tv_secs
= 0;
56 LIBBASE
->tb_CurrentTime
.tv_micro
= 0;
57 LIBBASE
->tb_VBlankTime
.tv_secs
= 0;
58 LIBBASE
->tb_VBlankTime
.tv_micro
= 1000000 / SysBase
->VBlankFrequency
;
59 LIBBASE
->tb_Elapsed
.tv_secs
= 0;
60 LIBBASE
->tb_Elapsed
.tv_micro
= 0;
62 D(bug("Timer period: %ld secs, %ld micros\n",
63 LIBBASE
->tb_VBlankTime
.tv_secs
, LIBBASE
->tb_VBlankTime
.tv_micro
));
65 /* Initialise the lists */
66 NEWLIST( &LIBBASE
->tb_Lists
[0] );
67 NEWLIST( &LIBBASE
->tb_Lists
[1] );
68 NEWLIST( &LIBBASE
->tb_Lists
[2] );
69 NEWLIST( &LIBBASE
->tb_Lists
[3] );
70 NEWLIST( &LIBBASE
->tb_Lists
[4] );
72 void *OpenFirmwareBase
= OpenResource("openfirmware.resource");
73 void *key
= OF_OpenKey("/builtin");
76 void *prop
= OF_FindProperty(key
, "reg");
79 intptr_t *mbar
= OF_GetPropValue(prop
);
80 slice_timer
= (slt_t
*)(*mbar
+ 0x710);
82 D(bug("MBAR located at %08x\n", *mbar
));
83 D(bug("slice timer at %08x\n", slice_timer
));
87 /* Start up the interrupt server */
89 LIBBASE
->tb_TimerIRQHandle
= KrnAddIRQHandler(MPC5200B_ST1
, SliceHandler
, LIBBASE
, SysBase
); //KrnAddExceptionHandler(10, DecrementerHandler, LIBBASE, SysBase);
91 /* Start the slice timer 1 */
92 // outl(SLT_CF_RUNWAIT | SLT_CF_INTRENA | SLT_CF_ENABLE, &slice_timer->slt_cf);
94 outl(SLT_TS_ST
, &slice_timer
->slt_ts
);
95 // TimerSetup(TimerBase, mftbl());
97 // outl(SLT_TS_ST, &slice_timer->slt_ts);
98 TimerSetup(TimerBase
, 0);
102 LIBBASE
->tb_vblank_timerequest
.tr_node
.io_Command
= TR_ADDREQUEST
;
103 LIBBASE
->tb_vblank_timerequest
.tr_node
.io_Device
= (struct Device
*)TimerBase
;
104 LIBBASE
->tb_vblank_timerequest
.tr_node
.io_Unit
= (struct Unit
*)UNIT_MICROHZ
;
105 LIBBASE
->tb_vblank_timerequest
.tr_time
.tv_secs
= 0;
106 LIBBASE
->tb_vblank_timerequest
.tr_time
.tv_micro
= 1000000 / SysBase
->VBlankFrequency
;
108 SendIO(&LIBBASE
->tb_vblank_timerequest
.tr_node
);
113 /****************************************************************************************/
115 static int GM_UNIQUENAME(Open
)
117 LIBBASETYPEPTR LIBBASE
,
118 struct timerequest
*tr
,
124 Normally, we should check the length of the message and other
125 such things, however the RKM documents an example where the
126 length of the timerrequest isn't set, so we must not check
129 This fixes bug SF# 741580
132 D(bug("[timer] OpenDevice(%d)\n", unitNum
));
139 case UNIT_WAITECLOCK
:
140 tr
->tr_node
.io_Error
= 0;
141 tr
->tr_node
.io_Unit
= (struct Unit
*)unitNum
;
142 tr
->tr_node
.io_Device
= (struct Device
*)LIBBASE
;
146 tr
->tr_node
.io_Error
= IOERR_OPENFAIL
;
152 /****************************************************************************************/
154 static int GM_UNIQUENAME(Expunge
)(LIBBASETYPEPTR LIBBASE
)
156 void *KernelBase
= getKernelBase();
158 KrnRemIRQHandler(LIBBASE
->tb_TimerIRQHandle
);
163 /****************************************************************************************/
165 ADD2INITLIB(GM_UNIQUENAME(Init
), 0)
166 ADD2OPENDEV(GM_UNIQUENAME(Open
), 0)
167 ADD2EXPUNGELIB(GM_UNIQUENAME(Expunge
), 0)