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