2 Copyright © 1995-2006, 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 <hidd/timer.h>
20 #include <hardware/intbits.h>
22 #include <proto/exec.h>
23 #include <proto/timer.h>
24 #include <proto/kernel.h>
25 #include <proto/utility.h>
26 #include <proto/openfirmware.h>
28 #include <utility/tagitem.h>
30 #include <aros/symbolsets.h>
33 #include <asm/mpc5200b.h>
35 #include <aros/debug.h>
36 #include <proto/arossupport.h>
38 //#include "timer_intern.h"
39 #include LC_LIBDEFS_FILE
43 void SliceHandler(struct TimerBase
*TimerBase
, struct ExecBase
*SysBase
);
44 extern volatile slt_t
*slice_timer
;
46 /****************************************************************************************/
48 static int GM_UNIQUENAME(Init
)(LIBBASETYPEPTR LIBBASE
)
50 struct ExecBase
*SysBase
= getSysBase();
51 void *KernelBase
= getKernelBase();
53 TimerBase
->tb_prev_tick
= mftbl();
55 /* Setup the timer.device data */
56 LIBBASE
->tb_CurrentTime
.tv_secs
= 0;
57 LIBBASE
->tb_CurrentTime
.tv_micro
= 0;
58 LIBBASE
->tb_VBlankTime
.tv_secs
= 0;
59 LIBBASE
->tb_VBlankTime
.tv_micro
= 1000000 / SysBase
->VBlankFrequency
;
60 LIBBASE
->tb_Elapsed
.tv_secs
= 0;
61 LIBBASE
->tb_Elapsed
.tv_micro
= 0;
63 D(bug("Timer period: %ld secs, %ld micros\n",
64 LIBBASE
->tb_VBlankTime
.tv_secs
, LIBBASE
->tb_VBlankTime
.tv_micro
));
66 LIBBASE
->tb_MiscFlags
= TF_GO
;
68 /* Initialise the lists */
69 NEWLIST( &LIBBASE
->tb_Lists
[0] );
70 NEWLIST( &LIBBASE
->tb_Lists
[1] );
71 NEWLIST( &LIBBASE
->tb_Lists
[2] );
72 NEWLIST( &LIBBASE
->tb_Lists
[3] );
73 NEWLIST( &LIBBASE
->tb_Lists
[4] );
75 void *OpenFirmwareBase
= OpenResource("openfirmware.resource");
76 void *key
= OF_OpenKey("/builtin");
79 void *prop
= OF_FindProperty(key
, "reg");
82 intptr_t *mbar
= OF_GetPropValue(prop
);
83 slice_timer
= (slt_t
*)(*mbar
+ 0x710);
85 D(bug("MBAR located at %08x\n", *mbar
));
86 D(bug("slice timer at %08x\n", slice_timer
));
90 /* Start up the interrupt server. This is shared between us and the
91 HIDD that deals with the vblank */
92 LIBBASE
->tb_VBlankInt
.is_Node
.ln_Pri
= 0;
93 LIBBASE
->tb_VBlankInt
.is_Node
.ln_Type
= NT_INTERRUPT
;
94 LIBBASE
->tb_VBlankInt
.is_Node
.ln_Name
= (STRPTR
)MOD_NAME_STRING
;
95 LIBBASE
->tb_VBlankInt
.is_Data
= LIBBASE
;
97 LIBBASE
->tb_VBlankInt
.is_Code
= KrnAddIRQHandler(MPC5200B_ST1
, SliceHandler
, LIBBASE
, SysBase
); //KrnAddExceptionHandler(10, DecrementerHandler, LIBBASE, SysBase);
99 /* Start the slice timer 1 */
100 // outl(SLT_CF_RUNWAIT | SLT_CF_INTRENA | SLT_CF_ENABLE, &slice_timer->slt_cf);
102 outl(SLT_TS_ST
, &slice_timer
->slt_ts
);
103 // TimerSetup(TimerBase, mftbl());
105 // outl(SLT_TS_ST, &slice_timer->slt_ts);
106 TimerSetup(TimerBase
, 0);
110 LIBBASE
->tb_vblank_timerequest
.tr_node
.io_Command
= TR_ADDREQUEST
;
111 LIBBASE
->tb_vblank_timerequest
.tr_node
.io_Device
= (struct Device
*)TimerBase
;
112 LIBBASE
->tb_vblank_timerequest
.tr_node
.io_Unit
= (struct Unit
*)UNIT_MICROHZ
;
113 LIBBASE
->tb_vblank_timerequest
.tr_time
.tv_secs
= 0;
114 LIBBASE
->tb_vblank_timerequest
.tr_time
.tv_micro
= 1000000 / SysBase
->VBlankFrequency
;
116 SendIO(&LIBBASE
->tb_vblank_timerequest
.tr_node
);
121 /****************************************************************************************/
123 static int GM_UNIQUENAME(Open
)
125 LIBBASETYPEPTR LIBBASE
,
126 struct timerequest
*tr
,
132 Normally, we should check the length of the message and other
133 such things, however the RKM documents an example where the
134 length of the timerrequest isn't set, so we must not check
137 This fixes bug SF# 741580
140 D(bug("[timer] OpenDevice(%d)\n", unitNum
));
147 case UNIT_WAITECLOCK
:
148 tr
->tr_node
.io_Error
= 0;
149 tr
->tr_node
.io_Unit
= (struct Unit
*)unitNum
;
150 tr
->tr_node
.io_Device
= (struct Device
*)LIBBASE
;
154 tr
->tr_node
.io_Error
= IOERR_OPENFAIL
;
160 /****************************************************************************************/
162 static int GM_UNIQUENAME(Expunge
)(LIBBASETYPEPTR LIBBASE
)
164 void *KernelBase
= getKernelBase();
166 KrnRemIRQHandler(LIBBASE
->tb_VBlankInt
.is_Code
);
171 /****************************************************************************************/
173 ADD2INITLIB(GM_UNIQUENAME(Init
), 0)
174 ADD2OPENDEV(GM_UNIQUENAME(Open
), 0)
175 ADD2EXPUNGELIB(GM_UNIQUENAME(Expunge
), 0)