]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/kernel_uart.cpp
Some minor fixes.
[l4.git] / kernel / fiasco / src / kern / kernel_uart.cpp
1 INTERFACE:
2
3 class Kernel_uart
4 {
5 public:
6   enum Init_mode
7   {
8     Init_before_mmu,
9     Init_after_mmu
10   };
11   Kernel_uart();
12   static void enable_rcv_irq();
13 };
14
15 INTERFACE [serial]:
16
17 #include "uart.h"
18 #include "std_macros.h"
19 #include "pm.h"
20
21 /**
22  * Glue between kernel and UART driver.
23  */
24 EXTENSION class Kernel_uart : public Uart, public Pm_object
25 {
26 private:
27   /**
28    * Prototype for the UART specific startup implementation.
29    * @param uart, the instantiation to start.
30    * @param port, the com port number.
31    */
32   bool startup(unsigned port, int irq=-1);
33
34   static bool init_for_mode(Init_mode init_mode);
35 };
36
37 //---------------------------------------------------------------------------
38 IMPLEMENTATION [serial]:
39
40 #include <cassert>
41 #include <cstring>
42 #include <cstdlib>
43 #include <cstdio>
44
45 #include "filter_console.h"
46 #include "irq_chip.h"
47 #include "irq_mgr.h"
48 #include "kdb_ke.h"
49 #include "kernel_console.h"
50 #include "uart.h"
51 #include "config.h"
52 #include "kip.h"
53 #include "koptions.h"
54 #include "panic.h"
55 #include "vkey.h"
56
57 static Static_object<Filter_console> _fcon;
58 static Static_object<Kernel_uart> _kernel_uart;
59
60 PUBLIC static FIASCO_CONST
61 Uart *
62 Kernel_uart::uart()
63 { return _kernel_uart; }
64
65
66 IMPLEMENT_DEFAULT inline
67 bool
68 Kernel_uart::init_for_mode(Init_mode init_mode)
69 { return (int)init_mode == Bsp_init_mode; }
70
71 PUBLIC static
72 bool
73 Kernel_uart::init(Init_mode init_mode = Init_before_mmu)
74 {
75   if (!init_for_mode(init_mode))
76     return false;
77
78   if (Koptions::o()->opt(Koptions::F_noserial)) // do not use serial uart
79     return true;
80
81   _kernel_uart.construct();
82   _fcon.construct(_kernel_uart);
83
84   Kconsole::console()->register_console(_fcon, 0);
85   return true;
86 }
87
88 PUBLIC
89 void
90 Kernel_uart::setup()
91 {
92   unsigned           n = Config::default_console_uart_baudrate;
93   Uart::TransferMode m = Uart::MODE_8N1;
94   unsigned long long p = Config::default_console_uart;
95   int                i = -1;
96
97   if (Koptions::o()->opt(Koptions::F_uart_baud))
98     n = Koptions::o()->uart.baud;
99
100   if (Koptions::o()->opt(Koptions::F_uart_base))
101     p = Koptions::o()->uart.base_address;
102
103   if (Koptions::o()->opt(Koptions::F_uart_irq))
104     i = Koptions::o()->uart.irqno;
105
106   if (!startup(p, i))
107     printf("Comport/base 0x%04llx is not accepted by the uart driver!\n", p);
108   else if (!change_mode(m, n))
109     panic("Something is wrong with the baud rate (%u)!\n", n);
110 }
111
112 IMPLEMENT
113 Kernel_uart::Kernel_uart()
114 {
115   setup();
116   register_pm(Cpu_number::boot_cpu());
117 }
118
119 PUBLIC void
120 Kernel_uart::pm_on_suspend(Cpu_number cpu)
121 {
122   (void)cpu;
123   assert (cpu == Cpu_number::boot_cpu());
124
125   uart()->state(Console::DISABLED);
126
127   if(Config::serial_esc != Config::SERIAL_ESC_NOIRQ)
128     uart()->disable_rcv_irq();
129 }
130
131 PUBLIC void
132 Kernel_uart::pm_on_resume(Cpu_number cpu)
133 {
134   (void)cpu;
135   assert (cpu == Cpu_number::boot_cpu());
136   static_cast<Kernel_uart*>(Kernel_uart::uart())->setup();
137   uart()->state(Console::ENABLED);
138
139   if(Config::serial_esc != Config::SERIAL_ESC_NOIRQ)
140     uart()->enable_rcv_irq();
141 }
142
143
144 class Kuart_irq : public Irq_base
145 {
146 public:
147   Kuart_irq() { hit_func = &handler_wrapper<Kuart_irq>; }
148   void switch_mode(bool) {}
149   void handle(Upstream_irq const *ui)
150   {
151     Kernel_uart::uart()->irq_ack();
152     mask_and_ack();
153     ui->ack();
154     unmask();
155     if (!Vkey::check_())
156       kdb_ke("IRQ ENTRY");
157   }
158 };
159
160
161 IMPLEMENT
162 void
163 Kernel_uart::enable_rcv_irq()
164 {
165   static Kuart_irq uart_irq;
166   if (Irq_mgr::mgr->alloc(&uart_irq, uart()->irq()))
167     {
168       uart_irq.unmask();
169       uart()->enable_rcv_irq();
170     }
171 }
172
173 //---------------------------------------------------------------------------
174 IMPLEMENTATION [!serial]:
175
176 PUBLIC static
177 bool
178 Kernel_uart::init(Init_mode = Init_before_mmu)
179 { return false; }
180
181 IMPLEMENT inline
182 Kernel_uart::Kernel_uart()
183 {}
184
185 IMPLEMENT inline
186 void
187 Kernel_uart::enable_rcv_irq()
188 {}