revert between 56095 -> 55830 in arch
[AROS.git] / arch / ppc-sam440 / boot / parthenope / src / parthenope.c
blob7675921814f67155b7c6f30fe3855aca6e346c1d
1 /* parthenope.c */
3 /* <project_name> -- <project_description>
5 * Copyright (C) 2006 - 2007
6 * Giuseppe Coviello <cjg@cruxppc.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include "context.h"
24 #include "device.h"
25 #include "tftp.h"
26 #include "ext2.h"
27 #include "sfs.h"
28 #include "dos.h"
29 #include "menu.h"
30 #include "elf.h"
31 #include "image.h"
32 #include "cdrom.h"
34 char __attribute__ ((__used__)) * version =
35 "\0$VER: Parthenope 0." VERSION " (" DATE ") "
36 "Copyright (C) 2008 Giuseppe Coviello. "
37 "This is free software. You may redistribute copies of it under the "
38 "terms of the GNU General Public License "
39 "<http://www.gnu.org/licenses/gpl.html>. There is NO WARRANTY, "
40 "to the extent permitted by law.";
42 extern unsigned long __bss_start;
43 extern unsigned long _end;
45 list_t *debug_info;
47 #define __startup __attribute__((section(".aros.startup")))
49 static void clear_bss()
51 unsigned long *ptr = &__bss_start;
52 while (ptr < &_end)
53 *ptr++ = 0;
56 static void flush_cache(char *start, char *end)
58 start = (char *)((unsigned long)start & 0xffffffe0);
59 end = (char *)((unsigned long)end & 0xffffffe0);
60 char *ptr;
62 for (ptr = start; ptr < end; ptr += 32)
63 asm volatile ("dcbst 0,%0"::"r" (ptr));
65 asm volatile ("sync");
67 for (ptr = start; ptr < end; ptr += 32)
68 asm volatile ("icbi 0,%0"::"r" (ptr));
69 asm volatile ("sync; isync; ");
72 int max_entries;
73 static void set_progress(int progress)
75 int p = progress * 66 / max_entries;
76 video_repeat_char(7, 7, p, 219, 0);
77 video_repeat_char(7 + p, 7, 66 - p, 177, 0);
80 static boot_dev_t *get_booting_device(void)
82 SCAN_HANDLE hnd;
83 hnd = get_curr_device();
85 switch (hnd->ush_device.type) {
86 case DEV_TYPE_HARDDISK:
87 return NULL;
88 break;
89 case DEV_TYPE_NETBOOT:
90 return tftp_create();
91 break;
92 case DEV_TYPE_CDROM:
93 return cdrom_create();
94 break;
97 return NULL;
100 void testboot_linux(menu_t * entry, void *kernel, boot_dev_t * dev)
102 image_header_t *header;
103 char *argv[3];
104 int argc;
105 void *initrd;
107 header = kernel;
109 if (header->ih_magic != IH_MAGIC
110 || header->ih_type != IH_TYPE_KERNEL
111 || header->ih_os != IH_OS_LINUX)
112 return;
114 setenv("stdout", "vga");
115 printf("We should boot %s:\n\t%s %s\n\t%s\n", entry->title,
116 entry->kernel, entry->append, entry->initrd);
118 if (entry->append != NULL)
119 setenv("bootargs", entry->append);
120 else
121 setenv("bootargs", "");
123 argc = 2;
124 argv[0] = "bootm";
125 argv[1] = malloc(32);
126 sprintf(argv[1], "%p", kernel);
127 argv[2] = NULL;
129 if (entry->initrd != NULL) {
130 initrd = malloc(18 * 1024 * 1024);
131 dev->load_file(dev, entry->initrd, initrd);
132 argc = 3;
133 argv[2] = malloc(32);
134 sprintf(argv[2], "%p", initrd);
137 bootm(NULL, 0, argc, argv);
140 void testboot_standalone(menu_t * entry, void *kernel, boot_dev_t * dev)
142 image_header_t *header;
143 char *argv[2];
144 int argc;
146 header = kernel;
148 if (header->ih_magic != IH_MAGIC
149 || header->ih_type != IH_TYPE_STANDALONE)
150 return;
152 setenv("autostart", "yes");
153 setenv("stdout", "vga");
155 argc = 2;
156 argv[0] = "bootm";
157 argv[1] = malloc(32);
158 sprintf(argv[1], "%p", kernel);
160 bootm(NULL, 0, argc, argv);
163 void testboot_aros(menu_t * menu, void *kernel, boot_dev_t * boot)
165 const uint32_t magic = ('A' << 24) | ('R' << 16) | ('O' << 8) | 'S';
166 int i;
167 char tmpbuf[100];
168 void *file_buff = malloc(10 * 1024 * 1024);
169 tagitem_t items[50];
170 tagitem_t *tags = &items[0];
172 if (!load_elf_file(menu->kernel, kernel))
173 return;
175 max_entries = menu->modules_cnt + 1;
176 sprintf(tmpbuf, "Booting %s", menu->title);
177 video_clear();
178 video_set_partial_scroll_limits(12, 25);
180 video_draw_box(1, 0, tmpbuf, 1, 5, 4, 70, 7);
181 set_progress(1);
182 video_draw_text(7, 9, 0, menu->kernel, 66);
184 for (i = 0; i < menu->modules_cnt; i++) {
185 printf("[BOOT] Loading file '%s'\n", menu->modules[i]->name);
186 if (boot->load_file(boot, menu->modules[i]->name, file_buff) < 0) {
187 return;
189 if (!load_elf_file(menu->modules[i]->name, file_buff)) {
190 printf("[BOOT] Load ERROR\n");
191 return;
193 set_progress(i + 2);
194 video_draw_text(7, 9, 0, menu->modules[i]->name, 66);
197 void (*entry) (void *, uint32_t);
198 flush_cache(get_ptr_rw(), get_ptr_ro());
200 entry = (void *)KERNEL_PHYS_BASE;
202 tags->ti_tag = KRN_KernelBss;
203 tags->ti_data = (unsigned long)&tracker[0];
204 tags++;
206 tags->ti_tag = KRN_KernelLowest;
207 tags->ti_data = (unsigned long)get_ptr_rw();
208 tags++;
210 tags->ti_tag = KRN_KernelHighest;
211 tags->ti_data = (unsigned long)get_ptr_ro();
212 tags++;
214 tags->ti_tag = KRN_KernelBase;
215 tags->ti_data = (unsigned long)KERNEL_PHYS_BASE;
216 tags++;
218 tags->ti_tag = KRN_ProtAreaStart;
219 tags->ti_data = (unsigned long)KERNEL_VIRT_BASE;
220 tags++;
222 tags->ti_tag = KRN_ProtAreaEnd;
223 tags->ti_data = (unsigned long)get_ptr_ro();
224 tags++;
226 tags->ti_tag = KRN_CmdLine;
227 tags->ti_data = (unsigned long)menu->append;
228 tags++;
230 tags->ti_tag = KRN_BootLoader;
231 tags->ti_data = (unsigned long)"Parthenope 0." VERSION " (" DATE ")";
232 tags++;
234 tags->ti_tag = KRN_DebugInfo;
235 tags->ti_data = (unsigned long)debug_info;
236 tags++;
238 tags->ti_tag = 0;
240 struct bss_tracker *bss = &tracker[0];
241 while (bss->addr) {
242 printf("[BOOT] Bss: %p-%p, %08x\n",
243 bss->addr, (char *)bss->addr + bss->length - 1,
244 bss->length);
245 bss++;
248 printf("[BOOT] Jumping into kernel @ %p\n", entry);
249 entry(&items[0], magic);
251 printf("[BOOT] Shouldn't be back...\n");
253 while (1) ;
256 struct module {
257 node_t node;
258 char *name;
259 char *options;
260 uint16_t id;
261 uint16_t flags;
262 void *alloc;
263 void *dealloc;
264 void *address;
265 unsigned size;
268 void testboot_aos(menu_t * menu, void *kernel, boot_dev_t * boot)
270 int i;
271 char tmpbuf[100];
272 int length;
273 struct module *module;
274 list_t *list;
276 list = list_new();
277 max_entries = menu->modules_cnt + 1;
278 sprintf(tmpbuf, "Booting %s", menu->title);
279 video_clear();
280 video_set_partial_scroll_limits(12, 25);
282 video_draw_box(1, 0, tmpbuf, 1, 5, 4, 70, 7);
283 set_progress(1);
284 video_draw_text(7, 9, 0, menu->kernel, 66);
286 module = malloc(sizeof(struct module));
287 void *buffer = malloc(16 * 1024 * 1024);
288 for (i = 0; i < menu->modules_cnt; i++) {
289 video_draw_text(7, 9, 0, menu->modules[i]->name, 66);
290 if ((length = boot->load_file(boot, menu->modules[i]->name,
291 buffer)) < 0)
292 return;
293 module = malloc(sizeof(struct module));
294 module->name = menu->modules[i]->name;
295 module->options = NULL;
296 module->id = 0x2;
297 module->flags = 0x3;
298 module->alloc = NULL;
299 module->dealloc = NULL;
300 module->address = malloc(length);
301 memmove((char *)module->address, (char *)buffer, length);
302 module->size = length;
303 list_append(list, (node_t *) module);
304 set_progress(i + 2);
306 ((void (*)(unsigned char *, void *, void *, void *))
307 kernel) (NULL, list, context_get()->c_get_board_info(),
308 getenv("os4_commandline"));
311 int __startup bootstrap(context_t * ctx)
313 boot_dev_t *boot;
314 menu_t *menu, *entry;
316 clear_bss();
318 context_init(ctx);
320 setenv("stdout", "serial");
322 debug_info = list_new();
324 video_clear();
325 video_draw_text(5, 4, 0, " Parthenope (ub2lb) version 0." VERSION, 80);
327 RdbPartitionTable_init();
328 boot = get_booting_device();
330 menu = menu_load(boot);
331 if (menu == NULL) {
332 setenv("stdout", "vga");
333 printf("No menu.lst or Kicklayout found!\n");
334 goto exit;
337 entry = menu_display(menu);
339 if (entry == NULL)
340 goto exit;
342 if (entry->other != NULL)
343 return bootu(entry->other);
345 switch (entry->device_type) {
346 case IDE_TYPE:
348 struct RdbPartition *partition;
349 boot = NULL;
350 partition = RdbPartitionTable_get(entry->device_num,
351 entry->partition);
352 if(partition == NULL)
353 break;
354 boot = dos_create(partition);
355 if (boot == NULL)
356 boot = sfs_create(partition);
357 if (boot == NULL)
358 boot = ext2_create(partition);
360 break;
361 case TFTP_TYPE:
362 boot = tftp_create();
363 break;
364 case CD_TYPE:
365 boot = cdrom_create();
366 break;
369 if (boot == NULL)
370 goto exit;
372 void *kernel = malloc(5 * 1024 * 1024);
373 if (boot->load_file(boot, entry->kernel, kernel) < 0)
374 return 1;
376 testboot_standalone(entry, kernel, boot);
377 testboot_linux(entry, kernel, boot);
378 testboot_aros(entry, kernel, boot);
379 testboot_aos(entry, kernel, boot);
381 free(kernel);
383 boot->destroy(boot);
384 exit:
385 setenv("stdout", "vga");
386 printf("Press a key to open U-Boot prompt!\n");
387 video_get_key();
388 return 0;