]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/bootstrap/server/src/libc_support+.cc
update
[l4.git] / l4 / pkg / bootstrap / server / src / libc_support+.cc
1 /**
2  * \file        bootstrap/server/src/libc_support.c
3  * \brief       Support for C library
4  *
5  * \date        2004-2008
6  * \author      Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
7  *              Frank Mehnert <fm3@os.inf.tu-dresden.de> */
8
9 /*
10  * (c) 2005-2009 Author(s)
11  *     economic rights: Technische Universität Dresden (Germany)
12  *
13  * This file is part of TUD:OS and distributed under the terms of the
14  * GNU General Public License 2.
15  * Please see the COPYING-GPL-2 file for details.
16  */
17
18 #include <unistd.h>
19 #include <string.h>
20 #include <strings.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdarg.h>
24 #include <errno.h>
25 #include <sys/types.h>
26 #include "panic.h"
27
28 #include <l4/cxx/basic_ostream>
29
30 #include "support.h"
31
32 Platform_base *Platform_base::platform;
33
34 static L4::Uart *stdio_uart;
35
36 L4::Uart *uart()
37 { return stdio_uart; }
38
39 void set_stdio_uart(L4::Uart *uart)
40 { stdio_uart = uart; }
41
42
43 inline void *operator new (size_t, void *p) { return p; }
44 // IO Stream backend
45 namespace {
46
47   class BootstrapIOBackend : public L4::IOBackend
48   {
49   protected:
50     void write(char const *str, unsigned len);
51   };
52
53   void BootstrapIOBackend::write(char const *str, unsigned len)
54   {
55     ::write(STDOUT_FILENO, str, len);
56   }
57
58 };
59
60 namespace L4 {
61   typedef char Fake_iobackend[sizeof(BootstrapIOBackend)]
62     __attribute__((aligned(__alignof__(BootstrapIOBackend))));
63   typedef char Fake_ostream[sizeof(BasicOStream)]
64     __attribute__((aligned(__alignof__(BasicOStream))));
65
66   Fake_ostream cout;
67   Fake_ostream cerr;
68
69   static Fake_iobackend _iob;
70
71   void iostream_init();
72   void iostream_init()
73   {
74     static int _initialized;
75     if (!_initialized)
76       {
77         _initialized = 1;
78         BootstrapIOBackend *iob = new (&_iob) BootstrapIOBackend();
79         new (&cerr) BasicOStream(iob);
80         new (&cout) BasicOStream(iob);
81       }
82   }
83 };
84
85 typedef void Ctor();
86
87 static void call_ctors(Ctor **start, Ctor **end)
88 {
89   for (; start < end; ++start)
90     if (*start)
91       (*start)();
92 }
93
94 static void
95 ctor_init()
96 {
97   extern Ctor *__CTORS_BEGIN[];
98   extern Ctor *__CTORS_END[];
99   extern Ctor *__init_array_start[];
100   extern Ctor *__init_array_end[];
101   extern Ctor *__preinit_array_start[];
102   extern Ctor *__preinit_array_end[];
103
104   call_ctors(__preinit_array_start, __preinit_array_end);
105   call_ctors(__CTORS_BEGIN, __CTORS_END);
106   call_ctors(__init_array_start, __init_array_end);
107 }
108
109
110 static inline void clear_bss()
111 {
112   extern char _bss_start[], _bss_end[];
113   extern int crt0_stack_low, crt0_stack_high;
114   memset(_bss_start, 0, (char *)&crt0_stack_low - _bss_start);
115   memset((char *)&crt0_stack_high, 0, _bss_end - (char *)&crt0_stack_high);
116 }
117
118 extern "C"
119 void startup(unsigned long p1, unsigned long p2,
120              unsigned long p3, unsigned long p4);
121
122 #ifdef ARCH_arm
123
124 extern "C" int __aeabi_unwind_cpp_pr0(void);
125 extern "C" int __aeabi_unwind_cpp_pr1(void);
126 enum { _URC_FAILURE  = 9 };
127 extern "C" int __aeabi_unwind_cpp_pr0(void) { return _URC_FAILURE; }
128 extern "C" int __aeabi_unwind_cpp_pr1(void) { return _URC_FAILURE; }
129
130 extern "C" void __main();
131 void __main()
132 {
133   unsigned long r;
134
135   asm volatile("mrc p15, 0, %0, c1, c0, 0" : "=r" (r) : : "memory");
136   r &= ~1UL;
137   r |= 2; // alignment check on
138   asm volatile("mcr p15, 0, %0, c1, c0, 0" : : "r" (r) : "memory");
139
140   clear_bss();
141   ctor_init();
142   Platform_base::iterate_platforms();
143
144   startup(0, 0, 0, 0);
145   while(1)
146     ;
147 }
148 #endif
149
150 #ifdef ARCH_ppc32
151 #include <l4/drivers/of.h>
152 extern "C" void __main(unsigned long p1, unsigned long p2, unsigned long p3);
153 void __main(unsigned long, unsigned long, unsigned long p3)
154 {
155   clear_bss();
156   ctor_init();
157   L4_drivers::Of::set_prom(p3); //p3 is OF prom pointer
158   Platform_base::iterate_platforms();
159
160   printf("PPC platform initialized\n");
161   startup(0, 0, 0, 0);
162   while(1)
163     ;
164 }
165 #endif
166
167 #if defined(ARCH_x86) || defined(ARCH_amd64)
168 extern l4util_mb_info_t *x86_bootloader_mbi;
169 extern "C" void __main(unsigned long p1, unsigned long p2, unsigned long p3, unsigned long p4);
170 void __main(unsigned long p1, unsigned long p2, unsigned long p3, unsigned long p4)
171 {
172   ctor_init();
173   x86_bootloader_mbi = (l4util_mb_info_t *)p1;
174   Platform_base::iterate_platforms();
175   startup(p1, p2, p3, p4);
176 }
177 #endif
178
179 #if defined(ARCH_sparc)
180 extern "C" void __main();
181 void __main()
182 {
183   clear_bss();
184   ctor_init();
185   Platform_base::iterate_platforms();
186   startup(0, 0, 0, 0);
187 }
188 #endif
189
190 void exit(int c) throw()
191 {
192   _exit(c);
193 }
194
195 void (*__exit_cleanup) (int) = 0;
196
197 extern "C" void __attribute__((noreturn))
198 __assert(const char *, const char *, int, register const char *);
199
200 extern "C" void __attribute__((noreturn))
201 __assert(const char *assertion, const char * filename,
202          int linenumber, register const char * function)
203 {
204   printf("%s:%d: %s: Assertion `%s' failed.\n",
205                                 filename,
206                                 linenumber,
207                                 ((function == NULL) ? "?function?" : function),
208                                 assertion
209                                 );
210   panic("Assertion");
211   while(1)
212     ;
213 }
214
215 ssize_t
216 write(int fd, const void *buf, size_t count)
217 {
218   if (!uart())
219     return 0;
220
221   if (fd == STDOUT_FILENO || fd == STDERR_FILENO)
222     {
223       char *b = (char *)buf;
224       int i = count;
225       while (i--)
226         {
227           char c = *b++;
228           if (c == '\n')
229             uart()->write("\r", 1);
230           uart()->write(&c, 1);
231         }
232
233       return count;
234     }
235
236   errno = EBADF;
237   return -1;
238 }
239
240 #undef getchar
241 int
242 getchar(void)
243 {
244   int c;
245   if (!uart())
246     return -1;
247
248   do
249     c = uart()->get_char(0);
250   while (c == -1);
251   return c;
252 }
253
254 off_t lseek(int /*fd*/, off_t /*offset*/, int /*whence*/)
255 {
256   return 0;
257 }
258
259 void *__dso_handle = &__dso_handle;
260
261 extern "C" void reboot(void) __attribute__((noreturn));
262 void reboot(void)
263 {
264   void reboot_arch() __attribute__((noreturn));
265   reboot_arch();
266 }
267
268 extern "C" void __attribute__((noreturn))
269 _exit(int /*rc*/)
270 {
271   printf("\n\033[1mKey press reboots...\033[m\n");
272   getchar();
273   printf("Rebooting.\n\n");
274   reboot();
275 }
276
277 /** for assert */
278 void
279 abort(void) throw()
280 {
281   _exit(1);
282 }
283
284 void
285 panic(const char *fmt, ...)
286 {
287   va_list v;
288   va_start (v, fmt);
289   vprintf(fmt, v);
290   va_end(v);
291   putchar('\n');
292   exit(1);
293 }