wip .. provide our bootstrap memory layout in a header for the bootstrap and kernel...
[AROS.git] / arch / all-pc / timer / timer_init.c
blob14cb3f22cc5138e97fdd0928b9f69857ce1e1c8f
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Timer startup and device commands
6 */
8 /****************************************************************************************/
10 #include <exec/devices.h>
11 #include <exec/interrupts.h>
12 #include <devices/timer.h>
13 #include <hardware/intbits.h>
14 #include <proto/exec.h>
15 #include <proto/kernel.h>
16 #include <aros/symbolsets.h>
17 #include <asm/io.h>
18 #include <aros/debug.h>
20 #include "ticks.h"
22 #define KernelBase LIBBASE->tb_KernelBase
24 /****************************************************************************************/
26 static void TimerInt(struct TimerBase *TimerBase, struct ExecBase *SysBase)
29 * Sync up with the hardware, we need the proper time value in order to
30 * process our requests correctly.
32 EClockUpdate(TimerBase);
34 * Process MICROHZ requests.
35 * VBLANK is emulated by us, so we don't check it here. We always
36 * have one active request in this list, which will cause VBLANK checking.
38 handleMicroHZ(TimerBase, SysBase);
39 /* Request next interrupt from the hardware */
40 Timer0Setup(TimerBase);
43 /****************************************************************************************/
45 static int hw_Init(struct TimerBase *LIBBASE)
47 /* We must have kernel.resource */
48 D(bug("[Timer] KernelBase = 0x%p\n", KernelBase));
49 if (!KernelBase)
50 return FALSE;
52 /* Start up the interrupt server. We know that our HW timer is at IRQ 0 */
53 LIBBASE->tb_TimerIRQHandle = KrnAddIRQHandler(0, TimerInt, LIBBASE, SysBase);
54 D(bug("[Timer] IRQ handle = 0x%p\n", LIBBASE->tb_TimerIRQHandle));
55 if (!LIBBASE->tb_TimerIRQHandle)
56 return FALSE;
58 D(bug("[Timer] Initializing hardware...\n"));
60 /* We have fixed EClock rate. VBlank will be emulated at 50Hz, can be changed at runtime. */
61 SysBase->VBlankFrequency = 50;
62 SysBase->ex_EClockFrequency = 1193180;
63 LIBBASE->tb_eclock_rate = 1193180;
64 LIBBASE->tb_prev_tick = 0xFFFF;
66 /* Start up the timer. Count the whole range for now. */
67 outb(CH0|ACCESS_FULL|MODE_SW_STROBE, PIT_CONTROL); /* Software strobe mode, 16-bit access */
68 ch_write(0xFFFF, PIT_CH0);
71 * Start the timer2.
72 * FIXME: This is not used by timer.device any more and must be removed.
73 * However PS/2 port driver uses polled microsecond delays via channel 2,
74 * and it relies on it being activated by us. This urgently needs to
75 * be fixed!
77 outb((inb(0x61) & 0xfd) | 1, 0x61); /* Enable the timer (set GATE on) */
78 outb(0xb4, 0x43); /* Binary mode on Timer2, count mode 2 */
79 outb(0x00, 0x42); /* We're counting whole range */
80 outb(0x00, 0x42);
82 /* Own VBlank EMU */
83 D(bug("[Timer] Starting VBlank emulation (%u Hz)...\n", SysBase->VBlankFrequency));
85 LIBBASE->tb_vblank_timerequest.tr_node.io_Command = TR_ADDREQUEST;
86 LIBBASE->tb_vblank_timerequest.tr_node.io_Device = &LIBBASE->tb_Device;
87 LIBBASE->tb_vblank_timerequest.tr_node.io_Unit = (struct Unit *)UNIT_MICROHZ;
88 LIBBASE->tb_vblank_timerequest.tr_time.tv_secs = 0;
89 LIBBASE->tb_vblank_timerequest.tr_time.tv_micro = 1000000 / SysBase->VBlankFrequency;
91 SendIO(&LIBBASE->tb_vblank_timerequest.tr_node);
93 D(bug("[Timer] Done\n"));
95 return TRUE;
98 /****************************************************************************************/
100 static int hw_Expunge(struct TimerBase *LIBBASE)
102 KrnRemIRQHandler(LIBBASE->tb_TimerIRQHandle);
104 return TRUE;
107 /****************************************************************************************/
109 ADD2INITLIB(hw_Init, 0)
110 ADD2EXPUNGELIB(hw_Expunge, 0)