]> 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   {
73     static int _initialized;
74     if (!_initialized)
75       {
76         _initialized = 1;
77         BootstrapIOBackend *iob = new (&_iob) BootstrapIOBackend();
78         new (&cerr) BasicOStream(iob);
79         new (&cout) BasicOStream(iob);
80       }
81   }
82 };
83
84 typedef void Ctor();
85
86 static void call_ctors(Ctor **start, Ctor **end)
87 {
88   for (; start < end; ++start)
89     if (*start)
90       (*start)();
91 }
92
93 static void
94 ctor_init()
95 {
96   extern Ctor *__CTORS_BEGIN[];
97   extern Ctor *__CTORS_END[];
98   extern Ctor *__init_array_start[];
99   extern Ctor *__init_array_end[];
100   extern Ctor *__preinit_array_start[];
101   extern Ctor *__preinit_array_end[];
102
103   call_ctors(__preinit_array_start, __preinit_array_end);
104   call_ctors(__CTORS_BEGIN, __CTORS_END);
105   call_ctors(__init_array_start, __init_array_end);
106 }
107
108 extern char _bss_start[], _bss_end[];
109
110 extern "C"
111 void startup(unsigned long p1, unsigned long p2,
112              unsigned long p3, unsigned long p4);
113
114 #ifdef ARCH_arm
115
116 extern "C" int __aeabi_unwind_cpp_pr0(void);
117 extern "C" int __aeabi_unwind_cpp_pr1(void);
118 enum { _URC_FAILURE  = 9 };
119 extern "C" int __aeabi_unwind_cpp_pr0(void) { return _URC_FAILURE; }
120 extern "C" int __aeabi_unwind_cpp_pr1(void) { return _URC_FAILURE; }
121
122 extern "C" void __main(int, const char **);
123 void __main(int, const char **)
124 {
125   extern int crt0_stack_low, crt0_stack_high;
126   unsigned long r;
127
128   asm volatile("mrc p15, 0, %0, c1, c0, 0" : "=r" (r) : : "memory");
129   r |= 2; // alignment check on
130   asm volatile("mcr p15, 0, %0, c1, c0, 0" : : "r" (r) : "memory");
131
132   memset(_bss_start, 0, (char *)&crt0_stack_low - _bss_start);
133   memset((char *)&crt0_stack_high, 0, _bss_end - (char *)&crt0_stack_high);
134
135   ctor_init();
136   Platform_base::iterate_platforms();
137
138   startup(0, 0, 0, 0);
139   while(1)
140     ;
141 }
142 #endif
143
144 #ifdef ARCH_ppc32
145 #include <l4/drivers/of.h>
146 extern "C" void __main(unsigned long p1, unsigned long p2,
147                        unsigned long p3);
148 void __main(unsigned long /*p1*/, unsigned long /*p2*/, unsigned long p3)
149 {
150   extern int crt0_stack_low, crt0_stack_high;
151   memset(_bss_start, 0, (char *)&crt0_stack_low - _bss_start);
152   memset((char *)&crt0_stack_high, 0, _bss_end - (char *)&crt0_stack_high);
153
154   ctor_init();
155   L4_drivers::Of::set_prom(p3); //p3 is OF prom pointer
156   Platform_base::iterate_platforms();
157
158   printf("PPC platform initialized\n");
159   startup(0, 0, 0, 0);
160   while(1)
161     ;
162 }
163 #endif
164
165 #if defined(ARCH_x86) || defined(ARCH_amd64)
166 extern "C" void __main(unsigned long p1, unsigned long p2, unsigned long p3, unsigned long p4);
167 void __main(unsigned long p1, unsigned long p2, unsigned long p3, unsigned long p4)
168 {
169   ctor_init();
170   Platform_base::iterate_platforms();
171   startup(p1, p2, p3, p4);
172 }
173 #endif
174
175
176 #if defined(ARCH_sparc)
177 extern "C" void __main(unsigned long p1, unsigned long p2, unsigned long p3);
178 void __main(unsigned long p1, unsigned long p2, unsigned long p3)
179 {
180         (void)p1;
181         (void)p2;
182         (void)p3;
183         ctor_init();
184         Platform_base::iterate_platforms();
185         // startup(0,0,0,0);
186 }
187 #endif
188
189 void exit(int c) throw()
190 {
191   _exit(c);
192 }
193
194 void (*__exit_cleanup) (int) = 0;
195
196 extern "C" void __attribute__((noreturn))
197 __assert(const char *assertion, const char * filename,
198          int linenumber, register const char * function)
199 {
200   printf("%s:%d: %s: Assertion `%s' failed.\n",
201                                 filename,
202                                 linenumber,
203                                 ((function == NULL) ? "?function?" : function),
204                                 assertion
205                                 );
206   panic("Assertion");
207   while(1)
208     ;
209 }
210
211 ssize_t
212 write(int fd, const void *buf, size_t count)
213 {
214   if (!uart())
215     return 0;
216   // just accept write to stdout and stderr
217   if (fd == STDOUT_FILENO || fd == STDERR_FILENO)
218     {
219       uart()->write((const char*)buf, count);
220       return count;
221     }
222
223   // writes to other fds shall fail fast
224   errno = EBADF;
225   return -1;
226 }
227
228 #undef getchar
229 int
230 getchar(void)
231 {
232   int c;
233   if (!uart())
234     return -1;
235
236   do
237     c = uart()->get_char(0);
238   while (c == -1)
239     ;
240   return c;
241 }
242
243 off_t lseek(int /*fd*/, off_t /*offset*/, int /*whence*/)
244 {
245   return 0;
246 }
247
248 void *__dso_handle = &__dso_handle;
249
250 extern "C" void reboot(void) __attribute__((noreturn));
251 void reboot(void)
252 {
253   void reboot_arch() __attribute__((noreturn));
254   reboot_arch();
255 }
256
257 extern "C" void __attribute__((noreturn))
258 _exit(int /*rc*/)
259 {
260   printf("\n\033[1mKey press reboots...\033[m\n");
261   getchar();
262   printf("Rebooting.\n\n");
263   reboot();
264 }
265
266 /** for assert */
267 void
268 abort(void) throw()
269 {
270   _exit(1);
271 }
272
273 void
274 panic(const char *fmt, ...)
275 {
276   va_list v;
277   va_start (v, fmt);
278   vprintf(fmt, v);
279   va_end(v);
280   putchar('\n');
281   exit(1);
282 }