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>
26 #include <aros/symbolsets.h>
29 #include <asm/amcc440.h>
31 #include <aros/debug.h>
33 #include <proto/arossupport.h>
35 //#include "timer_intern.h"
36 #include LC_LIBDEFS_FILE
38 #include "../kernel/syscall.h"
42 void DecrementerHandler(struct TimerBase
*TimerBase
, struct ExecBase
*SysBase
);
43 void GPTHandler(struct TimerBase
*TimerBase
, struct ExecBase
*SysBase
);
45 /****************************************************************************************/
47 static int GM_UNIQUENAME(Init
)(LIBBASETYPEPTR LIBBASE
)
49 void *KernelBase
= rdspr(SPRG4U
);
50 struct ExecBase
*SysBase
= rdspr(SPRG5U
);
52 TimerBase
->tb_prev_tick
= inl(GPT0_TBC
);
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
* SysBase
->PowerSupplyFrequency
);
59 LIBBASE
->tb_Elapsed
.tv_secs
= 0;
60 LIBBASE
->tb_Elapsed
.tv_micro
= 0;
62 D(kprintf("Timer period: %ld secs, %ld micros\n",
63 LIBBASE
->tb_VBlankTime
.tv_secs
, LIBBASE
->tb_VBlankTime
.tv_micro
));
65 LIBBASE
->tb_MiscFlags
= TF_GO
;
67 /* Initialise the lists */
68 NEWLIST( &LIBBASE
->tb_Lists
[0] );
69 NEWLIST( &LIBBASE
->tb_Lists
[1] );
70 NEWLIST( &LIBBASE
->tb_Lists
[2] );
71 NEWLIST( &LIBBASE
->tb_Lists
[3] );
72 NEWLIST( &LIBBASE
->tb_Lists
[4] );
74 /* Start up the interrupt server. This is shared between us and the
75 HIDD that deals with the vblank */
76 LIBBASE
->tb_VBlankInt
.is_Node
.ln_Pri
= 0;
77 LIBBASE
->tb_VBlankInt
.is_Node
.ln_Type
= NT_INTERRUPT
;
78 LIBBASE
->tb_VBlankInt
.is_Node
.ln_Name
= (STRPTR
)MOD_NAME_STRING
;
79 // LIBBASE->tb_VBlankInt.is_Code = (APTR)&VBlankInt;
80 LIBBASE
->tb_VBlankInt
.is_Data
= LIBBASE
;
82 // AddIntServer(INTB_TIMERTICK, &LIBBASE->tb_VBlankInt);
83 // KrnAddIRQHandler(0x20, VBlankInt, LIBBASE, SysBase);
84 LIBBASE
->tb_VBlankInt
.is_Code
= KrnAddIRQHandler(INTR_GDP
, GPTHandler
, LIBBASE
, SysBase
); //KrnAddExceptionHandler(10, DecrementerHandler, LIBBASE, SysBase);
86 outl(GPT0_DCIS_DCIS
, GPT0_DCIS
);
87 TimerSetup(TimerBase
, inl(GPT0_TBC
));
88 //outl(1333, GPT0_DCT0);
93 LIBBASE
->tb_vblank_timerequest
.tr_node
.io_Command
= TR_ADDREQUEST
;
94 LIBBASE
->tb_vblank_timerequest
.tr_node
.io_Device
= (struct Device
*)TimerBase
;
95 LIBBASE
->tb_vblank_timerequest
.tr_node
.io_Unit
= (struct Unit
*)UNIT_MICROHZ
;
96 LIBBASE
->tb_vblank_timerequest
.tr_time
.tv_secs
= 0;
97 LIBBASE
->tb_vblank_timerequest
.tr_time
.tv_micro
= 1000000 / SysBase
->VBlankFrequency
;
99 SendIO(&LIBBASE
->tb_vblank_timerequest
.tr_node
);
104 /****************************************************************************************/
106 static int GM_UNIQUENAME(Open
)
108 LIBBASETYPEPTR LIBBASE
,
109 struct timerequest
*tr
,
115 Normally, we should check the length of the message and other
116 such things, however the RKM documents an example where the
117 length of the timerrequest isn't set, so we must not check
120 This fixes bug SF# 741580
123 D(bug("[timer] OpenDevice(%d)\n", unitNum
));
130 case UNIT_WAITECLOCK
:
131 tr
->tr_node
.io_Error
= 0;
132 tr
->tr_node
.io_Unit
= (struct Unit
*)unitNum
;
133 tr
->tr_node
.io_Device
= (struct Device
*)LIBBASE
;
137 tr
->tr_node
.io_Error
= IOERR_OPENFAIL
;
143 /****************************************************************************************/
145 static int GM_UNIQUENAME(Expunge
)(LIBBASETYPEPTR LIBBASE
)
147 void *KernelBase
= rdspr(SPRG4U
);
149 KrnRemIRQHandler(LIBBASE
->tb_VBlankInt
.is_Code
);
154 /****************************************************************************************/
156 ADD2INITLIB(GM_UNIQUENAME(Init
), 0)
157 ADD2OPENDEV(GM_UNIQUENAME(Open
), 0)
158 ADD2EXPUNGELIB(GM_UNIQUENAME(Expunge
), 0)