ia64/xen-unstable

view extras/mini-os/kernel.c @ 16838:945820bfedb6

minios: POSIX fixes
Fixes some functions which are POSIX. Also make them ifndef HAVE_LIBC.

Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Jan 22 14:20:22 2008 +0000 (2008-01-22)
parents d5e22e766d1f
children 580bcd4c9642
line source
1 /******************************************************************************
2 * kernel.c
3 *
4 * Assorted crap goes here, including the initial C entry point, jumped at
5 * from head.S.
6 *
7 * Copyright (c) 2002-2003, K A Fraser & R Neugebauer
8 * Copyright (c) 2005, Grzegorz Milos, Intel Research Cambridge
9 * Copyright (c) 2006, Robert Kaiser, FH Wiesbaden
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to
13 * deal in the Software without restriction, including without limitation the
14 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
15 * sell copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 * DEALINGS IN THE SOFTWARE.
28 */
30 #include <os.h>
31 #include <hypervisor.h>
32 #include <mm.h>
33 #include <events.h>
34 #include <time.h>
35 #include <types.h>
36 #include <lib.h>
37 #include <sched.h>
38 #include <xenbus.h>
39 #include <gnttab.h>
40 #include <netfront.h>
41 #include <blkfront.h>
42 #include <fs.h>
43 #include <xmalloc.h>
44 #include <fcntl.h>
45 #include <xen/features.h>
46 #include <xen/version.h>
49 u8 xen_features[XENFEAT_NR_SUBMAPS * 32];
51 void setup_xen_features(void)
52 {
53 xen_feature_info_t fi;
54 int i, j;
56 for (i = 0; i < XENFEAT_NR_SUBMAPS; i++)
57 {
58 fi.submap_idx = i;
59 if (HYPERVISOR_xen_version(XENVER_get_features, &fi) < 0)
60 break;
62 for (j=0; j<32; j++)
63 xen_features[i*32+j] = !!(fi.submap & 1<<j);
64 }
65 }
67 void test_xenbus(void);
69 static void xenbus_tester(void *p)
70 {
71 printk("Xenbus tests disabled, because of a Xend bug.\n");
72 /* test_xenbus(); */
73 }
75 static void periodic_thread(void *p)
76 {
77 struct timeval tv;
78 printk("Periodic thread started.\n");
79 for(;;)
80 {
81 gettimeofday(&tv, NULL);
82 printk("T(s=%ld us=%ld)\n", tv.tv_sec, tv.tv_usec);
83 msleep(1000);
84 }
85 }
87 static void netfront_thread(void *p)
88 {
89 init_netfront(NULL, NULL, NULL);
90 }
92 static struct blkfront_dev *blk_dev;
93 static uint64_t blk_sectors;
94 static unsigned blk_sector_size;
95 static int blk_mode;
96 static uint64_t blk_size_read;
97 static uint64_t blk_size_write;
99 struct blk_req {
100 struct blkfront_aiocb aiocb;
101 int rand_value;
102 struct blk_req *next;
103 };
105 #ifdef BLKTEST_WRITE
106 static struct blk_req *blk_to_read;
107 #endif
109 static struct blk_req *blk_alloc_req(uint64_t sector)
110 {
111 struct blk_req *req = xmalloc(struct blk_req);
112 req->aiocb.aio_dev = blk_dev;
113 req->aiocb.aio_buf = _xmalloc(blk_sector_size, blk_sector_size);
114 req->aiocb.aio_nbytes = blk_sector_size;
115 req->aiocb.aio_offset = sector * blk_sector_size;
116 req->aiocb.data = req;
117 req->next = NULL;
118 return req;
119 }
121 static void blk_read_completed(struct blkfront_aiocb *aiocb, int ret)
122 {
123 struct blk_req *req = aiocb->data;
124 if (ret)
125 printk("got error code %d when reading at offset %ld\n", ret, aiocb->aio_offset);
126 else
127 blk_size_read += blk_sector_size;
128 free(aiocb->aio_buf);
129 free(req);
130 }
132 static void blk_read_sector(uint64_t sector)
133 {
134 struct blk_req *req;
136 req = blk_alloc_req(sector);
137 req->aiocb.aio_cb = blk_read_completed;
139 blkfront_aio_read(&req->aiocb);
140 }
142 #ifdef BLKTEST_WRITE
143 static void blk_write_read_completed(struct blkfront_aiocb *aiocb, int ret)
144 {
145 struct blk_req *req = aiocb->data;
146 int rand_value;
147 int i;
148 int *buf;
150 if (ret) {
151 printk("got error code %d when reading back at offset %ld\n", ret, aiocb->aio_offset);
152 free(aiocb->aio_buf);
153 free(req);
154 return;
155 }
156 blk_size_read += blk_sector_size;
157 buf = (int*) aiocb->aio_buf;
158 rand_value = req->rand_value;
159 for (i = 0; i < blk_sector_size / sizeof(int); i++) {
160 if (buf[i] != rand_value) {
161 printk("bogus data at offset %ld\n", aiocb->aio_offset + i);
162 break;
163 }
164 rand_value *= RAND_MIX;
165 }
166 free(aiocb->aio_buf);
167 free(req);
168 }
170 static void blk_write_completed(struct blkfront_aiocb *aiocb, int ret)
171 {
172 struct blk_req *req = aiocb->data;
173 if (ret) {
174 printk("got error code %d when writing at offset %ld\n", ret, aiocb->aio_offset);
175 free(aiocb->aio_buf);
176 free(req);
177 return;
178 }
179 blk_size_write += blk_sector_size;
180 /* Push write check */
181 req->next = blk_to_read;
182 blk_to_read = req;
183 }
185 static void blk_write_sector(uint64_t sector)
186 {
187 struct blk_req *req;
188 int rand_value;
189 int i;
190 int *buf;
192 req = blk_alloc_req(sector);
193 req->aiocb.aio_cb = blk_write_completed;
194 req->rand_value = rand_value = rand();
196 buf = (int*) req->aiocb.aio_buf;
197 for (i = 0; i < blk_sector_size / sizeof(int); i++) {
198 buf[i] = rand_value;
199 rand_value *= RAND_MIX;
200 }
202 blkfront_aio_write(&req->aiocb);
203 }
204 #endif
206 static void blkfront_thread(void *p)
207 {
208 time_t lasttime = 0;
209 blk_dev = init_blkfront(NULL, &blk_sectors, &blk_sector_size, &blk_mode);
210 if (!blk_dev)
211 return;
213 #ifdef BLKTEST_WRITE
214 if (blk_mode == O_RDWR) {
215 blk_write_sector(0);
216 blk_write_sector(blk_sectors-1);
217 } else
218 #endif
219 {
220 blk_read_sector(0);
221 blk_read_sector(blk_sectors-1);
222 }
224 while (1) {
225 uint64_t sector = rand() % blk_sectors;
226 struct timeval tv;
227 #ifdef BLKTEST_WRITE
228 if (blk_mode == O_RDWR)
229 blk_write_sector(sector);
230 else
231 #endif
232 blk_read_sector(sector);
233 blkfront_aio_poll(blk_dev);
234 gettimeofday(&tv, NULL);
235 if (tv.tv_sec > lasttime + 10) {
236 printk("%llu read, %llu write\n", blk_size_read, blk_size_write);
237 lasttime = tv.tv_sec;
238 }
240 #ifdef BLKTEST_WRITE
241 while (blk_to_read) {
242 struct blk_req *req = blk_to_read;
243 blk_to_read = blk_to_read->next;
244 req->aiocb.aio_cb = blk_write_read_completed;
245 blkfront_aio_read(&req->aiocb);
246 }
247 #endif
248 }
249 }
251 static void fs_thread(void *p)
252 {
253 init_fs_frontend();
254 }
256 /* This should be overridden by the application we are linked against. */
257 __attribute__((weak)) int app_main(start_info_t *si)
258 {
259 printk("Dummy main: start_info=%p\n", si);
260 create_thread("xenbus_tester", xenbus_tester, si);
261 create_thread("periodic_thread", periodic_thread, si);
262 create_thread("netfront", netfront_thread, si);
263 create_thread("blkfront", blkfront_thread, si);
264 create_thread("fs-frontend", fs_thread, si);
265 return 0;
266 }
268 /*
269 * INITIAL C ENTRY POINT.
270 */
271 void start_kernel(start_info_t *si)
272 {
273 static char hello[] = "Bootstrapping...\n";
275 (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(hello), hello);
277 arch_init(si);
279 trap_init();
281 /* print out some useful information */
282 printk("Xen Minimal OS!\n");
283 printk("start_info: %p\n", si);
284 printk(" nr_pages: %lu", si->nr_pages);
285 printk(" shared_inf: %08lx\n", si->shared_info);
286 printk(" pt_base: %p", (void *)si->pt_base);
287 printk(" mod_start: 0x%lx\n", si->mod_start);
288 printk(" mod_len: %lu\n", si->mod_len);
289 printk(" flags: 0x%x\n", (unsigned int)si->flags);
290 printk(" cmd_line: %s\n",
291 si->cmd_line ? (const char *)si->cmd_line : "NULL");
293 /* Set up events. */
294 init_events();
296 /* ENABLE EVENT DELIVERY. This is disabled at start of day. */
297 __sti();
299 arch_print_info();
301 setup_xen_features();
303 /* Init memory management. */
304 init_mm();
306 /* Init time and timers. */
307 init_time();
309 /* Init the console driver. */
310 init_console();
312 /* Init grant tables */
313 init_gnttab();
315 /* Init scheduler. */
316 init_sched();
318 /* Init XenBus */
319 init_xenbus();
321 /* Call (possibly overridden) app_main() */
322 app_main(&start_info);
324 /* Everything initialised, start idle thread */
325 run_idle_thread();
326 }
329 /*
330 * do_exit: This is called whenever an IRET fails in entry.S.
331 * This will generally be because an application has got itself into
332 * a really bad state (probably a bad CS or SS). It must be killed.
333 * Of course, minimal OS doesn't have applications :-)
334 */
336 void do_exit(void)
337 {
338 printk("Do_exit called!\n");
339 for( ;; )
340 {
341 struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_crash };
342 HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
343 }
344 }