]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/timer_tick.cpp
Some minor fixes.
[l4.git] / kernel / fiasco / src / kern / timer_tick.cpp
1 INTERFACE:
2
3 #include "irq_chip.h"
4 #include "thread.h"
5
6 class Timer_tick : public Irq_base
7 {
8 public:
9   enum Mode
10   {
11     Any_cpu, ///< Might hit on any CPU
12     Sys_cpu, ///< Hit only on the CPU that manages the system time
13     App_cpu, ///< Hit only on application CPUs
14   };
15   /// Create a timer IRQ object
16   explicit Timer_tick(Mode mode)
17   {
18     switch (mode)
19       {
20       case Any_cpu: set_hit(&handler_all); break;
21       case Sys_cpu: set_hit(&handler_sys_time); break;
22       case App_cpu: set_hit(&handler_app); break;
23       }
24   }
25
26   static void setup(Cpu_number cpu);
27   static void enable(Cpu_number cpu);
28   static void disable(Cpu_number cpu);
29
30   static Timer_tick *boot_cpu_timer_tick();
31
32 protected:
33   static bool allocate_irq(Irq_base *irq, unsigned irqnum);
34
35 private:
36   // we do not support triggering modes
37   void switch_mode(bool) {}
38 };
39
40 // ------------------------------------------------------------------------
41 INTERFACE [debug]:
42
43 #include "tb_entry.h"
44
45 EXTENSION class Timer_tick
46 {
47 public:
48   struct Log : public Tb_entry
49   {
50     Irq_base *obj;
51     Address user_ip;
52     void print(String_buffer *) const;
53   };
54 };
55
56 // ------------------------------------------------------------------------
57 IMPLEMENTATION:
58
59 #include "timer.h"
60
61 #include "kernel_console.h"
62 #include "vkey.h"
63
64 PRIVATE static inline NEEDS["thread.h", "timer.h", "kernel_console.h", "vkey.h"]
65 void
66 Timer_tick::handle_timer(Irq_base *_s, Upstream_irq const *ui,
67                          Thread *t, Cpu_number cpu)
68 {
69   Timer_tick *self = nonull_static_cast<Timer_tick *>(_s);
70   self->ack();
71   ui->ack();
72   Timer::update_system_clock(cpu);
73   if (Config::esc_hack && cpu == Cpu_number::boot_cpu())
74     {
75       if (Kconsole::console()->char_avail() && !Vkey::check_())
76         kdb_ke("SERIAL_ESC");
77     }
78   self->log_timer();
79   t->handle_timer_interrupt();
80 }
81
82 PUBLIC static inline NEEDS[Timer_tick::handle_timer]
83 void
84 Timer_tick::handler_all(Irq_base *_s, Upstream_irq const *ui)
85 {
86   Thread *t = current_thread();
87   handle_timer(_s, ui, t, current_cpu());
88 }
89
90 PUBLIC static inline NEEDS[Timer_tick::handle_timer]
91 void
92 Timer_tick::handler_sys_time(Irq_base *_s, Upstream_irq const *ui)
93 {
94   // assume the boot CPU to be the CPU that manages the system time
95   handle_timer(_s, ui, current_thread(), Cpu_number::boot_cpu());
96 }
97
98 PUBLIC static inline NEEDS["thread.h", "timer.h"]
99 void
100 Timer_tick::handler_app(Irq_base *_s, Upstream_irq const *ui)
101 {
102   Timer_tick *self = nonull_static_cast<Timer_tick *>(_s);
103   self->ack();
104   ui->ack();
105   self->log_timer();
106   current_thread()->handle_timer_interrupt();
107 }
108
109 // --------------------------------------------------------------------------
110 IMPLEMENTATION [!debug]:
111
112 PUBLIC static inline
113 void
114 Timer_tick::log_timer()
115 {}
116
117 // --------------------------------------------------------------------------
118 IMPLEMENTATION [debug]:
119
120 #include "logdefs.h"
121 #include "irq_chip.h"
122 #include "string_buffer.h"
123
124 IMPLEMENT
125 void
126 Timer_tick::Log::print(String_buffer *buf) const
127 {
128   buf->printf("u-ip=0x%lx", user_ip);
129 }
130
131 PUBLIC inline NEEDS["logdefs.h"]
132 void
133 Timer_tick::log_timer()
134 {
135   Context *c = current();
136   LOG_TRACE("Timer IRQs (kernel scheduling)", "timer", c, Log,
137       l->user_ip  = c->regs()->ip();
138       l->obj      = this;
139   );
140 }