]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/arm/bsp/pxa-sa/timer-arm-pxa_sa1100.cpp
update
[l4.git] / kernel / fiasco / src / kern / arm / bsp / pxa-sa / timer-arm-pxa_sa1100.cpp
1 // ------------------------------------------------------------------------
2 INTERFACE [arm && (sa1100 || pxa)]:
3
4 #include "kmem.h"
5
6 EXTENSION class Timer
7 {
8 public:
9   static unsigned irq() { return 26; }
10
11 private:
12   enum {
13     OSMR0 = Kmem::Timer_map_base + 0x00,
14     OSMR1 = Kmem::Timer_map_base + 0x04,
15     OSMR2 = Kmem::Timer_map_base + 0x08,
16     OSMR3 = Kmem::Timer_map_base + 0x0c,
17     OSCR  = Kmem::Timer_map_base + 0x10,
18     OSSR  = Kmem::Timer_map_base + 0x14,
19     OWER  = Kmem::Timer_map_base + 0x18,
20     OIER  = Kmem::Timer_map_base + 0x1c,
21
22     Timer_diff = (36864 * Config::Scheduler_granularity) / 10000, // 36864MHz*1ms
23   };
24 };
25
26
27 // -------------------------------------------------------------
28 IMPLEMENTATION [arm && (sa1100 || pxa)]:
29
30 #include "config.h"
31 #include "kip.h"
32 #include "pic.h"
33 #include "io.h"
34
35 IMPLEMENT
36 void Timer::init(unsigned)
37 {
38   Io::write(1,          OIER); // enable OSMR0
39   Io::write(0,          OWER); // disable Watchdog
40   Io::write<Mword>(Timer_diff, OSMR0);
41   Io::write(0,          OSCR); // set timer counter to zero
42   Io::write(~0U,        OSSR); // clear all status bits
43 }
44
45 static inline
46 Unsigned64
47 Timer::timer_to_us(Unsigned32 cr)
48 { return (((Unsigned64)cr) << 14) / 60398; }
49
50 static inline
51 Unsigned64
52 Timer::us_to_timer(Unsigned64 us)
53 { return (us * 60398) >> 14; }
54
55 PUBLIC static inline NEEDS["io.h", "config.h", Timer::timer_to_us]
56 void
57 Timer::acknowledge()
58 {
59   if (Config::Scheduler_one_shot)
60     {
61       Kip::k()->clock += timer_to_us(Io::read<Unsigned32>(OSCR));
62       //puts("Reset timer");
63       Io::write(0, OSCR);
64       Io::write(0xffffffff, OSMR0);
65     }
66   else
67     Io::write(0, OSCR);
68   Io::write(1, OSSR); // clear all status bits
69
70   // hmmm?
71   //enable();
72 }
73
74 IMPLEMENT inline NEEDS["kip.h", "io.h", Timer::timer_to_us, Timer::us_to_timer]
75 void
76 Timer::update_one_shot(Unsigned64 wakeup)
77 {
78   Unsigned32 apic;
79   Kip::k()->clock += timer_to_us(Io::read<Unsigned32>(OSCR));
80   Io::write(0, OSCR);
81   Unsigned64 now = Kip::k()->clock;
82
83   if (EXPECT_FALSE (wakeup <= now) )
84     // already expired
85     apic = 1;
86   else
87     {
88       apic = us_to_timer(wakeup - now);
89       if (EXPECT_FALSE(apic > 0x0ffffffff))
90         apic = 0x0ffffffff;
91       if (EXPECT_FALSE (apic < 1) )
92         // timeout too small
93         apic = 1;
94     }
95
96   //printf("%15lld: Set Timer to %lld [%08x]\n", now, wakeup, apic);
97
98   Io::write(apic, OSMR0);
99   Io::write(1, OSSR); // clear all status bits
100 }
101
102 IMPLEMENT inline NEEDS["config.h", "kip.h", "io.h", Timer::timer_to_us]
103 Unsigned64
104 Timer::system_clock()
105 {
106   if (Config::Scheduler_one_shot)
107     return Kip::k()->clock + timer_to_us(Io::read<Unsigned32>(OSCR));
108   else
109     return Kip::k()->clock;
110 }