2 * (c) 2010 Alexander Warg <warg@os.inf.tu-dresden.de>,
3 * Torsten Frenzel <frenzel@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.
10 #include <l4/drivers/uart_pl011.h>
11 #include <l4/drivers/uart_omap35x.h>
14 #include <l4/re/error_helper>
15 #include <l4/re/namespace>
16 #include <l4/re/util/cap_alloc>
17 #include <l4/re/util/object_registry>
18 #include <l4/re/util/icu_svr>
19 #include <l4/re/util/vcon_svr>
20 #include <l4/re/util/br_manager>
22 #include <l4/util/util.h>
28 #include <l4/cxx/ipc_server>
29 #include <l4/sys/cxx/ipc_legacy>
33 using L4Re::Util::Registry_server;
35 static Registry_server<L4Re::Util::Br_manager_hooks> server(l4_utcb(),
36 Env::env()->main_thread(),
37 Env::env()->factory());
39 using L4Re::Util::Vcon_svr;
40 using L4Re::Util::Icu_cap_array_svr;
43 public Vcon_svr<Serial_drv>,
44 public Icu_cap_array_svr<Serial_drv>,
45 public L4::Server_object_t<L4::Vcon>
49 virtual ~Serial_drv() throw() {}
51 bool running() const { return _running; }
53 int vcon_write(const char *buffer, unsigned size);
54 unsigned vcon_read(char *buffer, unsigned size);
60 // FIXME: this breaks IRQ handling need an extra object for this!
61 L4_RPC_LEGACY_DISPATCH(L4::Vcon);
62 int dispatch(l4_umword_t obj, L4::Ipc::Iostream &ios)
63 { return dispatch<L4::Ipc::Iostream>(obj, ios); }
65 void serprintf(char const *fmt, ...)
66 __attribute__((format(printf, 2, 3)));
71 L4::Cap<L4::Irq> _uart_irq;
72 Icu_cap_array_svr<Serial_drv>::Irq _irq;
75 Serial_drv::Serial_drv()
76 : Icu_cap_array_svr<Serial_drv>(1, &_irq),
77 _running(false), _uart(0), _uart_irq(L4_INVALID_CAP),
85 Serial_drv::vcon_write(const char *buffer, unsigned size)
87 _uart->write(buffer, size);
92 Serial_drv::vcon_read(char *buffer, unsigned size)
95 while (_uart->char_avail() && size)
97 int c = _uart->get_char(false);
100 buffer[i++] = (char)c;
106 // if there still some data available send this info to the client
107 if (_uart->char_avail())
115 Serial_drv::handle_irq()
117 if (_irq.cap().is_valid())
118 _irq.cap()->trigger();
120 //_uart_irq->unmask();
126 Serial_drv::serprintf(const char *fmt, ...)
131 unsigned len = vsnprintf(buf, sizeof(buf), fmt, l);
132 buf[sizeof(buf) - 1] = 0;
135 _uart->write(buf, len > sizeof(buf) ? sizeof(buf) : len);
143 l4_addr_t phys_base = 0x1000a000;
146 l4_addr_t phys_base = 0x49020000;
148 l4_addr_t virt_base = 0;
150 if (l4io_request_iomem(phys_base, 0x1000, L4IO_MEM_NONCACHED, &virt_base))
152 printf("serial-drv: request io-memory from l4io failed.\n");
155 printf("serial-drv: virtual base at:%lx\n", virt_base);
157 L4::Io_register_block_mmio *regs = new L4::Io_register_block_mmio(virt_base);
158 _uart = new (malloc(sizeof(L4::Uart_pl011))) L4::Uart_pl011(24019200);
159 //_uart = new (malloc(sizeof(L4::Uart_omap35x))) L4::Uart_omap35x;
160 _uart->startup(regs);
162 _uart_irq = L4Re::Util::cap_alloc.alloc<L4::Irq>();
163 if (!_uart_irq.is_valid())
165 serprintf("serial-drv: Alloc capability for uart-irq failed.\n");
169 if (l4io_request_irq(irq_num, _uart_irq.cap()))
171 serprintf("serial-drv: request uart-irq from l4io failed\n");
175 /* setting IRQ type to L4_IRQ_F_POS_EDGE seems to be wrong place */
176 if (l4_error(_uart_irq->attach((l4_umword_t)static_cast<L4::Server_object *>(this),
177 L4Re::Env::env()->main_thread())))
179 serprintf("serial-drv: attach to uart-irq failed.\n");
183 if ((l4_ipc_error(_uart_irq->unmask(), l4_utcb())))
185 serprintf("serial-drv: unmask uart-irq failed.\n");
188 _uart->enable_rx_irq(true);
195 Serial_drv::dispatch(l4_umword_t obj, L4::Ipc::Iostream &ios)
203 int r = L4Re::Util::Icu_svr<Serial_drv>::dispatch(obj, ios);
209 return L4Re::Util::Vcon_svr<Serial_drv>::dispatch(obj, ios);
211 return -L4_EBADPROTO;
218 Serial_drv serial_drv;
220 if (!server.registry()->register_obj(&serial_drv, "vcon"))
222 printf("Failed to register serial driver; Aborting.\n");
226 if (!serial_drv.running())
228 printf("Failed to initialize serial driver; Aborting.\n");
232 printf("Starting server loop\n");