1/* $NetBSD: hpcboot.cpp,v 1.19 2006/03/05 04:05:39 uwe Exp $ */ 2 3/*- 4 * Copyright (c) 2001, 2002, 2004 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by UCHIYAMA Yasushi. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include <hpcmenu.h> 33#include <hpcboot.h> 34 35#include <menu/window.h> 36#include <menu/rootwindow.h> 37 38#include <console.h> 39#include <arch.h> 40#include <memory.h> 41#include <file.h> 42#include <load.h> 43 44#include <boot.h> 45 46#include "../binary/build_number.h" 47 48#if _WIN32_WCE <= 200 49OSVERSIONINFO WinCEVersion; 50#else 51OSVERSIONINFOW WinCEVersion; 52#endif 53 54int WINAPI 55WinMain(HINSTANCE instance, HINSTANCE prev_instance, 56 LPTSTR cmd_line, int window_show) 57{ 58 HpcMenuInterface::Instance(); // Menu System 59 HpcBootApp *app = 0; // Application body. 60 int ret = 0; 61 62 InitCommonControls(); 63 64 app = new HpcBootApp(instance); 65 app->_cons = Console::Instance(); 66 app->_root = new RootWindow(*app); 67 68 if (!app->registerClass(reinterpret_cast <WNDPROC>(Window::_wnd_proc))) 69 goto failed; 70 71 if (!app->_root->create(0)) 72 goto failed; 73 74 Boot::Instance(); // Boot loader 75 76 ret = app->run(); // Main loop. 77 // NOTREACHED 78 79 failed: 80 81 Boot::Destroy(); 82 if (app->_root) 83 delete app->_root; 84 delete app; 85 Console::Destroy(); 86 HpcMenuInterface::Destroy(); 87 88 return ret; 89} 90 91// 92// boot sequence. 93// 94void 95hpcboot(void *arg) 96{ 97 size_t sz = 0; 98 paddr_t p = 0; 99 TCHAR *error_message = 0; 100 101 HpcMenuInterface &menu = HPC_MENU; 102 Boot &f = Boot::Instance(); 103 104 // Open serial port for kernel KGDB. 105 SerialConsole::OpenCOM1(); 106 107 menu.progress("0"); 108 if (!f.setup()) { 109 error_message = TEXT("Architecture not supported.\n"); 110 goto failed_exit; 111 } 112 113 menu.progress("1"); 114 if (!f.create()) { 115 error_message = TEXT("Architecture ops. not found.\n"); 116 goto failed_exit; 117 } 118 119 // Now we can write console which user specified. 120 { 121 DPRINTF_SETUP(); 122 DPRINTF((TEXT("hpcboot build number: %d\n"), 123 HPCBOOT_BUILD_NUMBER)); 124 DPRINTF((TEXT("%s (cpu=0x%08x machine=0x%08x)\n"), 125 HPC_MENU.platform_get(HPC_MENU.platform_default()), 126 HPC_PREFERENCE.platid_hi, HPC_PREFERENCE.platid_lo)); 127 } 128 129 menu.progress("2"); 130 if (!f._arch->init()) { 131 error_message = TEXT("Architecture initialize failed.\n"); 132 goto failed_exit; 133 } 134 135 f._arch->systemInfo(); 136 137 menu.progress("3"); 138 // kernel / file system image directory. 139 if (!f._file->setRoot(f.args.fileRoot)) { 140 error_message = TEXT("Can't set root directory.\n"); 141 goto failed_exit; 142 } 143 144 // determine the size of file system image. 145 if (f.args.loadmfs) 146 { 147 if (!f._file->open(f.args.mfsName)) { 148 error_message = 149 TEXT("Can't open file system image.\n"); 150 goto failed_exit; 151 } 152 sz = f._file->realsize(); 153 sz = f._mem->roundPage(sz); 154 f._file->close(); 155 } 156 157 menu.progress("4"); 158 if (!f._file->open(f.args.fileName)) { 159 error_message = TEXT("Can't open kernel image.\n"); 160 goto failed_exit; 161 } 162 163 menu.progress("5"); 164 // put kernel to loader. 165 if (!f.attachLoader()) { 166 error_message = TEXT("Can't attach loader.\n"); 167 goto file_close_exit; 168 } 169 170 if (!f._loader->setFile(f._file)) { 171 error_message = TEXT("Can't initialize loader.\n"); 172 goto file_close_exit; 173 } 174 175 menu.progress("6"); 176 sz += f._mem->roundPage(f._loader->memorySize()); 177 178 // allocate required memory. 179 if (!f._arch->allocateMemory(sz)) { 180 error_message = TEXT("Can't allocate memory.\n"); 181 goto file_close_exit; 182 } 183 184 menu.progress("7"); 185 // load kernel to memory. 186 if (!f._arch->setupLoader()) { 187 error_message = TEXT("Can't set up loader.\n"); 188 goto file_close_exit; 189 } 190 191 menu.progress("8"); 192 if (!f._loader->load()) { 193 error_message = TEXT("Can't load kernel image to memory.\n"); 194 goto file_close_exit; 195 } 196 menu.progress("9"); 197 f._file->close(); 198 199 // load file system image to memory 200 if (f.args.loadmfs) { 201 if (!f._file->open(f.args.mfsName)) { 202 error_message = 203 TEXT("Can't open file system image.\n"); 204 goto failed_exit; 205 } 206 if (!f._loader->loadExtData()) { 207 error_message = 208 TEXT("Can't load file system image to memory.\n"); 209 goto file_close_exit; 210 } 211 f._file->close(); 212 } 213 f._loader->loadEnd(); 214 215 // setup arguments for kernel. 216 p = f._arch->setupBootInfo(*f._loader); 217 218 menu.progress("10"); 219 220 f._loader->tagDump(3); // dump page chain.(print first 3 links) 221 222 // jump to kernel entry. 223 if (HPC_PREFERENCE.pause_before_boot) { 224 if (MessageBox(menu._root->_window, TEXT("Push YES to boot."), 225 TEXT("Last chance..."), 226 MB_ICONWARNING | MB_YESNO) != IDYES) 227 { 228 error_message = TEXT("Canceled by user.\n"); 229 goto failed_exit; 230 } 231 // redraw areas damaged by the dialog 232 UpdateWindow(menu._root->_window); 233 } 234 235 f._arch->jump(p, f._loader->tagStart()); 236 // NOTREACHED 237 error_message = TEXT("Can't jump to the kernel.\n"); 238 239 file_close_exit: 240 f._file->close(); 241 242 failed_exit: 243 if (error_message == 0) 244 error_message = TEXT("Unknown error?\n"); 245 MessageBox(menu._root->_window, error_message, 246 TEXT("BOOT FAILED"), MB_ICONERROR | MB_OK); 247 248 menu.unprogress(); // rewind progress bar 249} 250 251// 252// HPCBOOT main loop 253// 254int 255HpcBootApp::run(void) 256{ 257 MSG msg; 258 259 while (GetMessage(&msg, 0, 0, 0)) { 260 // cancel auto-boot. 261 if (HPC_PREFERENCE.auto_boot > 0 && _root && 262 (msg.message == WM_KEYDOWN || 263 msg.message == WM_LBUTTONDOWN)) { 264 _root->disableTimer(); 265 } 266 if (!_root->isDialogMessage(msg)) { 267 TranslateMessage(&msg); 268 DispatchMessage(&msg); 269 } 270 } 271 return msg.wParam; 272} 273 274BOOL 275HpcBootApp::registerClass(WNDPROC proc) 276{ 277 TCHAR *wc_name; 278 WNDCLASS wc; 279 280 memset(&wc, 0, sizeof(WNDCLASS)); 281 wc_name = reinterpret_cast <TCHAR *> 282 (LoadString(_instance, IDS_HPCMENU, 0, 0)); 283 wc.lpfnWndProc = proc; 284 wc.hInstance = _instance; 285 wc.hIcon = LoadIcon(_instance, MAKEINTRESOURCE(IDI_ICON)); 286 wc.cbWndExtra = 4; // pointer of `this` 287 wc.hbrBackground= static_cast <HBRUSH>(GetStockObject(LTGRAY_BRUSH)); 288 wc.lpszClassName= wc_name; 289 290 return RegisterClass(&wc); 291} 292 293 294// 295// Debug support. 296// 297void 298_bitdisp(uint32_t a, int s, int e, int m, int c) 299{ 300 uint32_t j, j1; 301 int i, n; 302 303 DPRINTF_SETUP(); 304 305 n = 31; // 32bit only. 306 j1 = 1 << n; 307 e = e ? e : n; 308 for (j = j1, i = n; j > 0; j >>=1, i--) { 309 if (i > e || i < s) { 310 DPRINTF((TEXT("%c"), a & j ? '+' : '-')); 311 } else { 312 DPRINTF((TEXT("%c"), a & j ? '|' : '.')); 313 } 314 } 315 if (m) { 316 DPRINTF((TEXT("[%s]"),(char*)m)); 317 } 318 319 DPRINTF((TEXT(" [0x%08x]"), a)); 320 321 if (c) { 322 for (j = j1, i = n; j > 0; j >>=1, i--) { 323 if (!(i > e || i < s) &&(a & j)) { 324 DPRINTF((TEXT(" %d"), i)); 325 } 326 } 327 } 328 329 DPRINTF((TEXT(" %d\n"), a)); 330} 331 332void 333_dbg_bit_print(uint32_t reg, uint32_t mask, const char *name) 334{ 335 static const char onoff[3] = "_x"; 336 337 DPRINTF_SETUP(); 338 339 DPRINTF((TEXT("%S[%c] "), name, onoff[reg & mask ? 1 : 0])); 340} 341