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