1 /* $NetBSD: hpcboot.cpp,v 1.14 2004/02/27 02:02:16 uwe Exp $ */ 2 3 /*- 4 * Copyright (c) 2001, 2002 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 OSVERSIONINFOW WinCEVersion; 54 55 int WINAPI 56 WinMain(HINSTANCE instance, HINSTANCE prev_instance, 57 LPTSTR cmd_line, int window_show) 58 { 59 HpcMenuInterface::Instance(); // Menu System 60 HpcBootApp *app = 0; // Application body. 61 int ret = 0; 62 63 InitCommonControls(); 64 65 app = new HpcBootApp(instance); 66 app->_cons = Console::Instance(); 67 app->_root = new RootWindow(*app); 68 69 if (!app->registerClass(reinterpret_cast <WNDPROC>(Window::_wnd_proc))) 70 goto failed; 71 72 if (!app->_root->create(0)) 73 goto failed; 74 75 Boot::Instance(); // Boot loader 76 77 ret = app->run(); // Main loop. 78 // NOTREACHED 79 80 failed: 81 82 Boot::Destroy(); 83 if (app->_root) 84 delete app->_root; 85 delete app; 86 Console::Destroy(); 87 HpcMenuInterface::Destroy(); 88 89 return ret; 90 } 91 92 // 93 // boot sequence. 94 // 95 void 96 hpcboot(void *arg) 97 { 98 size_t sz = 0; 99 paddr_t p = 0; 100 TCHAR *error_message = 0; 101 102 HpcMenuInterface &menu = HPC_MENU; 103 Boot &f = Boot::Instance(); 104 105 // Open serial port for kernel KGDB. 106 SerialConsole::OpenCOM1(); 107 108 menu.progress(); 109 if (!f.setup()) { 110 error_message = TEXT("Architecture not supported.\n"); 111 goto failed_exit; 112 } 113 114 menu.progress(); 115 if (!f.create()) { 116 error_message = TEXT("Architecture ops. not found.\n"); 117 goto failed_exit; 118 } 119 120 menu.progress(); 121 if (!f._arch->init()) { 122 error_message = TEXT("Architecture initialize failed.\n"); 123 goto failed_exit; 124 } 125 126 f._arch->systemInfo(); 127 128 menu.progress(); 129 // kernel / file system image directory. 130 if (!f._file->setRoot(f.args.fileRoot)) { 131 error_message = TEXT("Can't set root directory.\n"); 132 goto failed_exit; 133 } 134 135 // determine the size of file system image. 136 if (f.args.loadmfs) 137 { 138 if (!f._file->open(f.args.mfsName)) { 139 error_message = 140 TEXT("Can't open file system image.\n"); 141 goto failed_exit; 142 } 143 sz = f._file->realsize(); 144 sz = f._mem->roundPage(sz); 145 f._file->close(); 146 } 147 148 menu.progress(); 149 if (!f._file->open(f.args.fileName)) { 150 error_message = TEXT("Can't open kernel image.\n"); 151 goto failed_exit; 152 } 153 154 menu.progress(); 155 // put kernel to loader. 156 if (!f.attachLoader()) { 157 error_message = TEXT("Can't attach loader.\n"); 158 goto file_close_exit; 159 } 160 161 if (!f._loader->setFile(f._file)) { 162 error_message = TEXT("Can't initialize loader.\n"); 163 goto file_close_exit; 164 } 165 166 menu.progress(); 167 sz += f._mem->roundPage(f._loader->memorySize()); 168 169 // allocate required memory. 170 if (!f._arch->allocateMemory(sz)) { 171 error_message = TEXT("Can't allocate memory.\n"); 172 goto file_close_exit; 173 } 174 175 menu.progress(); 176 // load kernel to memory. 177 if (!f._arch->setupLoader()) { 178 error_message = TEXT("Can't set up loader.\n"); 179 goto file_close_exit; 180 } 181 182 menu.progress(); 183 if (!f._loader->load()) { 184 error_message = TEXT("Can't load kernel image to memory.\n"); 185 goto file_close_exit; 186 } 187 menu.progress(); 188 f._file->close(); 189 190 // load file system image to memory 191 if (f.args.loadmfs) { 192 if (!f._file->open(f.args.mfsName)) { 193 error_message = 194 TEXT("Can't open file system image.\n"); 195 goto failed_exit; 196 } 197 if (!f._loader->loadExtData()) { 198 error_message = 199 TEXT("Can't load file system image to memory.\n"); 200 goto file_close_exit; 201 } 202 f._file->close(); 203 } 204 f._loader->loadEnd(); 205 206 // setup arguments for kernel. 207 p = f._arch->setupBootInfo(*f._loader); 208 209 menu.progress(); 210 211 f._loader->tagDump(3); // dump page chain.(print first 3 links) 212 213 // jump to kernel entry. 214 if (HPC_PREFERENCE.pause_before_boot) { 215 if (MessageBox(menu._root->_window, TEXT("Push YES to boot."), 216 TEXT("Last chance..."), 217 MB_ICONWARNING | MB_YESNO) != IDYES) 218 { 219 error_message = TEXT("Canceled by user.\n"); 220 goto failed_exit; 221 } 222 // redraw areas damaged by the dialog 223 UpdateWindow(menu._root->_window); 224 } 225 226 f._arch->jump(p, f._loader->tagStart()); 227 // NOTREACHED 228 error_message = TEXT("Can't jump to the kernel.\n"); 229 230 file_close_exit: 231 f._file->close(); 232 233 failed_exit: 234 if (error_message == 0) 235 error_message = TEXT("Unknown error?\n"); 236 MessageBox(menu._root->_window, error_message, 237 TEXT("BOOT FAILED"), MB_ICONERROR | MB_OK); 238 239 menu.unprogress(); // rewind progress bar 240 } 241 242 // 243 // HPCBOOT main loop 244 // 245 int 246 HpcBootApp::run(void) 247 { 248 MSG msg; 249 250 while (GetMessage(&msg, 0, 0, 0)) { 251 // cancel auto-boot. 252 if (HPC_PREFERENCE.auto_boot > 0 && _root && 253 (msg.message == WM_KEYDOWN || 254 msg.message == WM_LBUTTONDOWN)) { 255 _root->disableTimer(); 256 } 257 if (!_root->isDialogMessage(msg)) { 258 TranslateMessage(&msg); 259 DispatchMessage(&msg); 260 } 261 } 262 return msg.wParam; 263 } 264 265 BOOL 266 HpcBootApp::registerClass(WNDPROC proc) 267 { 268 TCHAR *wc_name; 269 WNDCLASS wc; 270 271 memset(&wc, 0, sizeof(WNDCLASS)); 272 wc_name = reinterpret_cast <TCHAR *> 273 (LoadString(_instance, IDS_HPCMENU, 0, 0)); 274 wc.lpfnWndProc = proc; 275 wc.hInstance = _instance; 276 wc.hIcon = LoadIcon(_instance, MAKEINTRESOURCE(IDI_ICON)); 277 wc.cbWndExtra = 4; // pointer of `this` 278 wc.hbrBackground= static_cast <HBRUSH>(GetStockObject(LTGRAY_BRUSH)); 279 wc.lpszClassName= wc_name; 280 281 return RegisterClass(&wc); 282 } 283 284 285 // 286 // Debug support. 287 // 288 void 289 _bitdisp(u_int32_t a, int s, int e, int m, int c) 290 { 291 u_int32_t j, j1; 292 int i, n; 293 294 DPRINTF_SETUP(); 295 296 n = 31; // 32bit only. 297 j1 = 1 << n; 298 e = e ? e : n; 299 for (j = j1, i = n; j > 0; j >>=1, i--) { 300 if (i > e || i < s) { 301 DPRINTF((TEXT("%c"), a & j ? '+' : '-')); 302 } else { 303 DPRINTF((TEXT("%c"), a & j ? '|' : '.')); 304 } 305 } 306 if (m) { 307 DPRINTF((TEXT("[%s]"),(char*)m)); 308 } 309 310 DPRINTF((TEXT(" [0x%08x]"), a)); 311 312 if (c) { 313 for (j = j1, i = n; j > 0; j >>=1, i--) { 314 if (!(i > e || i < s) &&(a & j)) { 315 DPRINTF((TEXT(" %d"), i)); 316 } 317 } 318 } 319 320 DPRINTF((TEXT(" %d\n"), a)); 321 } 322 323 void 324 _dbg_bit_print(u_int32_t reg, u_int32_t mask, const char *name) 325 { 326 static const char onoff[3] = "_x"; 327 328 DPRINTF_SETUP(); 329 330 DPRINTF((TEXT("%S[%c] "), name, onoff[reg & mask ? 1 : 0])); 331 } 332