1 /* $NetBSD: hpcboot.cpp,v 1.7 2002/03/02 22:01:35 uch 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("architexture 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("couldn't set root directory.\n"); 132 goto failed_exit; 133 } 134 135 // open file system image. 136 if (f.args.loadmfs) 137 { 138 if (!f._file->open(f.args.mfsName)) { 139 error_message = 140 TEXT("couldn't open file system image.\n"); 141 goto failed_exit; 142 } 143 sz = f._file->size(); 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("couldn't open kernel image.\n"); 151 goto failed_exit; 152 } 153 154 menu.progress(); 155 // put kernel to loader. 156 if (!f.attachLoader()) 157 goto file_close_exit; 158 159 if (!f._loader->setFile(f._file)) { 160 error_message = TEXT("couldn't initialize loader.\n"); 161 goto file_close_exit; 162 } 163 164 menu.progress(); 165 sz += f._mem->roundPage(f._loader->memorySize()); 166 167 // allocate required memory. 168 if (!f._arch->allocateMemory(sz)) { 169 error_message = TEXT("couldn't allocate memory.\n"); 170 goto file_close_exit; 171 } 172 173 menu.progress(); 174 // load kernel to memory. 175 if (!f._arch->setupLoader()) { 176 error_message = TEXT("couldn't set up loader.\n"); 177 goto file_close_exit; 178 } 179 180 menu.progress(); 181 if (!f._loader->load()) { 182 error_message = TEXT("couldn't load kernel image to memory.\n"); 183 goto file_close_exit; 184 } 185 menu.progress(); 186 f._file->close(); 187 188 // load file system image to memory 189 if (f.args.loadmfs) { 190 if (!f._file->open(f.args.mfsName)) { 191 error_message = 192 TEXT("couldn't open file system image.\n"); 193 goto failed_exit; 194 } 195 if (!f._loader->loadExtData()) { 196 error_message = 197 TEXT("couldn't load filesystem image to memory.\n"); 198 goto file_close_exit; 199 } 200 f._file->close(); 201 } 202 f._loader->loadEnd(); 203 204 // setup arguments for kernel. 205 p = f._arch->setupBootInfo(*f._loader); 206 207 menu.progress(); 208 209 f._loader->tagDump(3); // dump page chain.(print first 3 links) 210 211 // jump to kernel entry. 212 if (HPC_PREFERENCE.pause_before_boot) { 213 if (MessageBox(menu._root->_window, TEXT("Push OK to boot."), 214 TEXT("Last chance..."), MB_YESNO) != IDYES) 215 goto failed_exit; 216 } 217 218 f._arch->jump(p, f._loader->tagStart()); 219 // NOTREACHED 220 221 file_close_exit: 222 if (error_message == 0) 223 error_message = TEXT("can't jump to kernel.\n"); 224 f._file->close(); 225 failed_exit: 226 MessageBox(menu._root->_window, error_message, 227 TEXT("BOOT FAILED"), 0); 228 } 229 230 // 231 // HPCBOOT main loop 232 // 233 int 234 HpcBootApp::run(void) 235 { 236 MSG msg; 237 238 while (GetMessage(&msg, 0, 0, 0)) { 239 // cancel auto-boot. 240 if (HPC_PREFERENCE.auto_boot > 0 && _root && 241 (msg.message == WM_KEYDOWN || 242 msg.message == WM_LBUTTONDOWN)) { 243 _root->disableTimer(); 244 } 245 if (!_root->isDialogMessage(msg)) { 246 TranslateMessage(&msg); 247 DispatchMessage(&msg); 248 } 249 } 250 return msg.wParam; 251 } 252 253 BOOL 254 HpcBootApp::registerClass(WNDPROC proc) 255 { 256 TCHAR *wc_name; 257 WNDCLASS wc; 258 259 memset(&wc, 0, sizeof(WNDCLASS)); 260 wc_name = reinterpret_cast <TCHAR *> 261 (LoadString(_instance, IDS_HPCMENU, 0, 0)); 262 wc.lpfnWndProc = proc; 263 wc.hInstance = _instance; 264 wc.hIcon = LoadIcon(_instance, MAKEINTRESOURCE(IDI_ICON)); 265 wc.cbWndExtra = 4; // pointer of `this` 266 wc.hbrBackground= static_cast <HBRUSH>(GetStockObject(LTGRAY_BRUSH)); 267 wc.lpszClassName= wc_name; 268 269 return RegisterClass(&wc); 270 } 271 272 273 // 274 // Debug support. 275 // 276 void 277 _bitdisp(u_int32_t a, int s, int e, int m, int c) 278 { 279 u_int32_t j, j1; 280 int i, n; 281 282 DPRINTF_SETUP(); 283 284 n = 31; // 32bit only. 285 j1 = 1 << n; 286 e = e ? e : n; 287 for (j = j1, i = n; j > 0; j >>=1, i--) { 288 if (i > e || i < s) { 289 DPRINTF((TEXT("%c"), a & j ? '+' : '-')); 290 } else { 291 DPRINTF((TEXT("%c"), a & j ? '|' : '.')); 292 } 293 } 294 if (m) { 295 DPRINTF((TEXT("[%s]"),(char*)m)); 296 } 297 298 DPRINTF((TEXT(" [0x%08x]"), a)); 299 300 if (c) { 301 for (j = j1, i = n; j > 0; j >>=1, i--) { 302 if (!(i > e || i < s) &&(a & j)) { 303 DPRINTF((TEXT(" %d"), i)); 304 } 305 } 306 } 307 308 DPRINTF((TEXT(" %d\n"), a)); 309 } 310 311 void 312 _dbg_bit_print(u_int32_t reg, u_int32_t mask, const char *name) 313 { 314 static const char onoff[3] = "_x"; 315 316 DPRINTF_SETUP(); 317 318 DPRINTF((TEXT("%S[%c] "), name, onoff[reg & mask ? 1 : 0])); 319 } 320