1/* 2 * Copyright 2011, Fran��ois Revol, revol@free.fr. 3 * Copyright 2003-2010, Axel D��rfler, axeld@pinc-software.de. 4 * Copyright 2011, Alexander von Gluck, kallisti5@unixzen.com 5 * Distributed under the terms of the MIT License. 6 */ 7 8 9#include <string.h> 10 11#include <OS.h> 12 13#include <boot/platform.h> 14#include <boot/stage2.h> 15#include <boot/heap.h> 16#include <boot/platform/cfe/cfe.h> 17#include <platform_arch.h> 18 19#include "console.h" 20#include "real_time_clock.h" 21 22 23#define HEAP_SIZE 65536 24 25 26extern "C" uint32 _start(uint64 handle, uint64 entry, uint32 _unused, 27 uint32 signature); 28extern "C" void start(uint64 cfeHandle, uint64 cfeEntry); 29 30// GCC defined globals 31extern void (*__ctor_list)(void); 32extern void (*__ctor_end)(void); 33extern uint8 __bss_start; 34extern uint8 _end; 35 36#if 0//OF 37uint32 gMachine; 38#endif 39static uint32 sBootOptions; 40 41 42static void 43call_ctors(void) 44{ 45 void (**f)(void); 46 47 for (f = &__ctor_list; f < &__ctor_end; f++) { 48 (**f)(); 49 } 50} 51 52 53static void 54clear_bss(void) 55{ 56 memset(&__bss_start, 0, &_end - &__bss_start); 57} 58 59 60extern "C" void 61platform_start_kernel(void) 62{ 63 preloaded_elf32_image* image = static_cast<preloaded_elf32_image*>( 64 gKernelArgs.kernel_image.Pointer()); 65 66 addr_t kernelEntry = image->elf_header.e_entry; 67 addr_t stackTop = gKernelArgs.cpu_kstack[0].start 68 + gKernelArgs.cpu_kstack[0].size; 69 70 printf("kernel entry at %p\n", (void*)kernelEntry); 71 printf("kernel stack top: %p\n", (void*)stackTop); 72 73 /* TODO: ? 74 mmu_init_for_kernel(); 75 smp_boot_other_cpus(); 76 */ 77 78 status_t error = arch_start_kernel(&gKernelArgs, kernelEntry, stackTop); 79 80 panic("Kernel returned! Return value: %ld\n", error); 81} 82 83 84extern "C" void 85platform_exit(void) 86{ 87 cfe_exit(CFE_FLG_WARMSTART, 0); 88 panic("cfe_exit() failed."); 89} 90 91 92extern "C" uint32 93platform_boot_options(void) 94{ 95 return sBootOptions; 96} 97 98 99extern "C" uint32 100_start(uint64 handle, uint64 entry, uint32 _unused, uint32 signature) 101{ 102 103 if (signature != CFE_EPTSEAL) 104 return 123;//XXX:something? 105 106 clear_bss(); 107 call_ctors(); 108 // call C++ constructors before doing anything else 109 //return 456; 110 111 start(handle, entry); 112} 113 114 115extern "C" void 116start(uint64 cfeHandle, uint64 cfeEntry) 117{ 118 char bootargs[512]; 119 120 // stage2 args - might be set via the command line one day 121 stage2_args args; 122 args.heap_size = HEAP_SIZE; 123 args.arguments = NULL; 124 125 cfe_init(cfeHandle, cfeEntry); 126 127 // check for arguments 128#if 0//OF 129 if (of_getprop(gChosen, "bootargs", bootargs, sizeof(bootargs)) 130 != OF_FAILED) { 131 static const char *sArgs[] = { NULL, NULL }; 132 sArgs[0] = (const char *)bootargs; 133 args.arguments = sArgs; 134 } 135#endif 136 137#if 0//OF 138 determine_machine(); 139#endif 140 console_init(); 141 142 // XXX:FIXME: doesn't even land here. 143 dprintf("testing...\n"); 144 while (true); 145 146#if 0//OF 147 if ((gMachine & MACHINE_QEMU) != 0) 148 dprintf("OpenBIOS (QEMU?) OpenFirmware machine detected\n"); 149 else if ((gMachine & MACHINE_PEGASOS) != 0) 150 dprintf("Pegasos PowerPC machine detected\n"); 151 else 152 dprintf("Apple PowerPC machine assumed\n"); 153#endif 154 155 // Initialize and take over MMU and set the OpenFirmware callbacks - it 156 // will ask us for memory after that instead of maintaining it itself 157 // (the kernel will need to adjust the callback later on as well) 158 arch_mmu_init(); 159 160 if (boot_arch_cpu_init() != B_OK) 161 cfe_exit(CFE_FLG_WARMSTART, 1); 162 163#if 0//OF FIXME 164 if (init_real_time_clock() != B_OK) 165 cfe_exit(CFE_FLG_WARMSTART, 1); 166#endif 167 168 // check for key presses once 169 sBootOptions = 0; 170 int key = console_check_for_key(); 171 if (key == 32) { 172 // space bar: option menu 173 sBootOptions |= BOOT_OPTION_MENU; 174 } else if (key == 27) { 175 // ESC: debug output 176 sBootOptions |= BOOT_OPTION_DEBUG_OUTPUT; 177 } 178 179 gKernelArgs.platform_args.cfe_entry = cfeEntry; 180 181 main(&args); 182 // if everything goes fine, main() never returns 183 184 cfe_exit(CFE_FLG_WARMSTART, 1); 185} 186