3 * (c) 2010 Adam Lackorzynski <adam@os.inf.tu-dresden.de>
4 * economic rights: Technische Universität Dresden (Germany)
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.
12 #include <l4/sys/compiler.h>
13 #include <l4/sys/types.h>
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; }
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(); }
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)
41 _int_status = 1 << irqnum; l4_wmb();
42 typeof(_int_status) dummy = *(volatile typeof(_int_status) *)&_int_status;
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(); }
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(); }
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; }
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(); }
68 unsigned periodic_int_capable() const { return _conf_and_cap & (1 << 4); }
69 unsigned can_64bit() const { return _conf_and_cap & (1 << 5); }
71 void val_set_cnf() { _conf_and_cap |= 1 << 6; l4_wmb(); }
73 void force_32bit() { _conf_and_cap |= 1 << 8; l4_wmb(); }
74 unsigned forced_32bit() const { return _conf_and_cap & (1 << 8); }
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); }
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); }
84 unsigned can_fsb() const { return _conf_and_cap & (1 << 15); }
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(); }
91 int get_first_int(int i = 0)
93 l4_uint32_t cap = int_route_cap();
100 l4_uint64_t comparator() const { return _comp; }
101 void set_comparator(l4_uint64_t v) { _comp = v; l4_wmb(); }
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; }
106 void print_state() const;
108 l4_uint64_t conf_and_cap() const { return _conf_and_cap; }
109 l4_uint64_t comp() const { return _comp; }
112 l4_uint64_t _conf_and_cap;
114 l4_uint32_t _int_route_addr; // right order?
115 l4_uint32_t _int_route_val;
116 } __attribute__((packed));
118 Timer *timer(int nr) const
120 return reinterpret_cast<Timer *>((char *)this + 0x100 + 0x20 * nr);
123 unsigned ioapic_irq(int nr) const
125 return timer(nr)->int_route_cnf();
128 void print_state() const;
130 l4_uint64_t clk2ns(l4_uint64_t v) const
131 { return v * counter_clk_period() / 1000000ULL; }
133 l4_uint64_t clk2us(l4_uint64_t v) const
134 { return v * counter_clk_period() / 1000000000ULL; }
136 l4_uint64_t us2clk(unsigned us) const
137 { return us * 1000000000ULL / counter_clk_period(); }
139 l4_uint64_t ns2clk(unsigned us) const
140 { return us * 1000000ULL / counter_clk_period(); }
142 l4_uint64_t cap_and_id() const { return _cap_and_id; }
143 l4_uint64_t conf() const { return _conf; }
146 l4_uint64_t _cap_and_id; // 0x0
148 l4_uint64_t _conf; // 0x10
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));