]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/drivers-frst/hpet/include/hpet
update
[l4.git] / l4 / pkg / drivers-frst / hpet / include / hpet
1 // vim: set ft=cpp:
2 /*
3  * (c) 2010 Adam Lackorzynski <adam@os.inf.tu-dresden.de>
4  *     economic rights: Technische Universität Dresden (Germany)
5  *
6  * This file is part of TUD:OS and distributed under the terms of the
7  * GNU General Public License 2.
8  * Please see the COPYING-GPL-2 file for details.
9  */
10 #pragma once
11
12 #include <l4/sys/compiler.h>
13 #include <l4/sys/types.h>
14
15 namespace L4 {
16 namespace Driver {
17
18 class Hpet
19 {
20 public:
21   // General Capabilities and ID Register
22   unsigned rev_id() const { l4_mb(); return _cap_and_id & 0xff; }
23   unsigned num_tim_cap() const { l4_mb(); return ((_cap_and_id >> 8) & 0xf) + 1; }
24   unsigned count_size_cap() const { l4_mb(); return _cap_and_id & (1 << 13); }
25   unsigned leg_rt_cap() const { l4_mb(); return _cap_and_id & (1 << 13); }
26   unsigned vendor_id() const { l4_mb(); return (_cap_and_id >> 16) & 0xffff; };
27   l4_uint32_t counter_clk_period() const { l4_mb(); return _cap_and_id >> 32; }
28
29   // General Configuration Register
30   unsigned enabled() const { return _conf & 1; }
31   void enable() { _conf |= 1; l4_wmb(); }
32   void disable() { _conf &= ~1; l4_wmb(); }
33   unsigned leg_rt_cnf() const { return _conf & 2; }
34   void legacy_route_enable() { _conf |= 2; l4_wmb(); }
35   void legacy_route_disable() { _conf &= ~2; l4_wmb(); }
36
37   // General Interrupt Status Register
38   unsigned irq_active(int irqnum) const { l4_mb(); return (1 << irqnum) & _int_status; }
39   void irq_clear_active(int irqnum)
40   {
41     _int_status = 1 << irqnum; l4_wmb();
42     typeof(_int_status) dummy = *(volatile typeof(_int_status) *)&_int_status;
43     (void)dummy;
44   }
45
46   // Main Counter Register
47   l4_uint64_t main_counter_val() const { l4_mb(); return _main_counter; }
48   void main_counter_val(l4_uint64_t v) { _main_counter = v; l4_wmb(); }
49
50   class Timer
51   {
52   public:
53     // Timer N Configuration and Capability Register
54     void set_int_type_level() { _conf_and_cap |= 2; l4_wmb(); }
55     void set_int_type_edge() { _conf_and_cap &= ~2; l4_wmb(); }
56     unsigned is_int_type_level() const { return _conf_and_cap & 2; }
57     unsigned is_int_type_edge() const { return !is_int_type_level(); }
58
59     void enable_int() { _conf_and_cap |= 4; l4_wmb(); }
60     void disable_int() { _conf_and_cap &= ~4; l4_wmb(); }
61     unsigned is_int_enabled() const { return _conf_and_cap & 4; }
62
63     void set_periodic() { _conf_and_cap |= 8; l4_wmb(); }
64     void set_nonperiodic() { _conf_and_cap &= ~8; l4_wmb(); }
65     unsigned is_periodic() const { return _conf_and_cap & 8; }
66     unsigned is_nonperiodic() const { return !is_periodic(); }
67
68     unsigned periodic_int_capable() const { return _conf_and_cap & (1 << 4); }
69     unsigned can_64bit() const { return _conf_and_cap & (1 << 5); }
70
71     void val_set_cnf() { _conf_and_cap |= 1 << 6; l4_wmb(); }
72
73     void force_32bit() { _conf_and_cap |= 1 << 8; l4_wmb(); }
74     unsigned forced_32bit() const { return _conf_and_cap & (1 << 8); }
75
76     unsigned int_route_cnf() const { return (_conf_and_cap >> 9) & 0x1f; }
77     void set_int_route(unsigned irqnum)
78     { _conf_and_cap = (_conf_and_cap & ~(31 << 9)) | (irqnum << 9); }
79
80     void enable_fsb() { _conf_and_cap |= 1 << 14; l4_wmb(); }
81     void disable_fsb() { _conf_and_cap &= ~(1 << 14); l4_wmb(); }
82     unsigned is_fsb() const { return _conf_and_cap & (1 << 14); }
83
84     unsigned can_fsb() const { return _conf_and_cap & (1 << 15); }
85
86
87     l4_uint32_t int_route_cap() const { return _conf_and_cap >> 32; }
88     unsigned int_avail(int int_nr) const { return int_route_cap() & int_nr; }
89     unsigned ints_avail() const { return int_route_cap(); }
90
91     int get_first_int(int i = 0)
92     {
93       l4_uint32_t cap = int_route_cap();
94       for (; i < 32; ++i)
95         if (cap & (1 << i))
96           return i;
97       return ~0U;
98     }
99
100     l4_uint64_t comparator() const { return _comp; }
101     void set_comparator(l4_uint64_t v) { _comp = v; l4_wmb(); }
102
103     void fsb_int_addr(l4_uint32_t addr) { _int_route_addr = addr; }
104     void fsb_int_val(l4_uint32_t val) { _int_route_val = val; }
105
106     void print_state() const;
107
108     l4_uint64_t conf_and_cap() const { return _conf_and_cap; }
109     l4_uint64_t comp() const { return _comp; }
110
111   private:
112     l4_uint64_t _conf_and_cap;
113     l4_uint64_t _comp;
114     l4_uint32_t _int_route_addr; // right order?
115     l4_uint32_t _int_route_val;
116   } __attribute__((packed));
117
118   Timer *timer(int nr) const
119   {
120     return reinterpret_cast<Timer *>((char *)this + 0x100 + 0x20 * nr);
121   }
122
123   unsigned ioapic_irq(int nr) const
124   {
125     return timer(nr)->int_route_cnf();
126   }
127
128   void print_state() const;
129
130   l4_uint64_t clk2ns(l4_uint64_t v) const
131   { return v * counter_clk_period() / 1000000ULL; }
132
133   l4_uint64_t clk2us(l4_uint64_t v) const
134   { return v * counter_clk_period() / 1000000000ULL; }
135
136   l4_uint64_t us2clk(unsigned us) const
137   { return us * 1000000000ULL / counter_clk_period(); }
138
139   l4_uint64_t ns2clk(unsigned us) const
140   { return us * 1000000ULL / counter_clk_period(); }
141
142   l4_uint64_t cap_and_id() const { return _cap_and_id; }
143   l4_uint64_t conf() const { return _conf; }
144
145 private:
146   l4_uint64_t _cap_and_id;   // 0x0
147   l4_uint64_t _pad1;
148   l4_uint64_t _conf;         // 0x10
149   l4_uint64_t _pad2;
150   l4_uint64_t _int_status;   // 0x20
151   l4_uint64_t _pad3[(0xf0 - 0x28) / sizeof(l4_uint64_t)];
152   l4_uint64_t _main_counter;
153 } __attribute__((packed));
154
155 }}