1*d6be11a5Suwe /* $NetBSD: hpcboot.cpp,v 1.14 2004/02/27 02:02:16 uwe Exp $ */ 29173eae7Such 39173eae7Such /*- 47758e172Such * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc. 59173eae7Such * All rights reserved. 69173eae7Such * 79173eae7Such * This code is derived from software contributed to The NetBSD Foundation 89173eae7Such * by UCHIYAMA Yasushi. 99173eae7Such * 109173eae7Such * Redistribution and use in source and binary forms, with or without 119173eae7Such * modification, are permitted provided that the following conditions 129173eae7Such * are met: 139173eae7Such * 1. Redistributions of source code must retain the above copyright 149173eae7Such * notice, this list of conditions and the following disclaimer. 159173eae7Such * 2. Redistributions in binary form must reproduce the above copyright 169173eae7Such * notice, this list of conditions and the following disclaimer in the 179173eae7Such * documentation and/or other materials provided with the distribution. 189173eae7Such * 3. All advertising materials mentioning features or use of this software 199173eae7Such * must display the following acknowledgement: 209173eae7Such * This product includes software developed by the NetBSD 219173eae7Such * Foundation, Inc. and its contributors. 229173eae7Such * 4. Neither the name of The NetBSD Foundation nor the names of its 239173eae7Such * contributors may be used to endorse or promote products derived 249173eae7Such * from this software without specific prior written permission. 259173eae7Such * 269173eae7Such * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 279173eae7Such * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 289173eae7Such * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 299173eae7Such * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 309173eae7Such * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 319173eae7Such * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 329173eae7Such * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 339173eae7Such * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 349173eae7Such * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 359173eae7Such * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 369173eae7Such * POSSIBILITY OF SUCH DAMAGE. 379173eae7Such */ 389173eae7Such 399173eae7Such #include <hpcmenu.h> 409173eae7Such #include <hpcboot.h> 419173eae7Such 429173eae7Such #include <menu/window.h> 439173eae7Such #include <menu/rootwindow.h> 449173eae7Such 459173eae7Such #include <console.h> 469173eae7Such #include <arch.h> 479173eae7Such #include <memory.h> 489173eae7Such #include <file.h> 499173eae7Such #include <load.h> 509173eae7Such 519173eae7Such #include <boot.h> 529173eae7Such 532a2cc9f4Such OSVERSIONINFOW WinCEVersion; 542a2cc9f4Such 559173eae7Such int WINAPI 569173eae7Such WinMain(HINSTANCE instance, HINSTANCE prev_instance, 579173eae7Such LPTSTR cmd_line, int window_show) 589173eae7Such { 59bd926f64Such HpcMenuInterface::Instance(); // Menu System 609173eae7Such HpcBootApp *app = 0; // Application body. 619173eae7Such int ret = 0; 629173eae7Such 639173eae7Such InitCommonControls(); 649173eae7Such 659173eae7Such app = new HpcBootApp(instance); 669173eae7Such app->_cons = Console::Instance(); 679173eae7Such app->_root = new RootWindow(*app); 689173eae7Such 699173eae7Such if (!app->registerClass(reinterpret_cast <WNDPROC>(Window::_wnd_proc))) 709173eae7Such goto failed; 719173eae7Such 729173eae7Such if (!app->_root->create(0)) 739173eae7Such goto failed; 749173eae7Such 75bd926f64Such Boot::Instance(); // Boot loader 769173eae7Such 77bd926f64Such ret = app->run(); // Main loop. 789173eae7Such // NOTREACHED 799173eae7Such 809173eae7Such failed: 819173eae7Such 829173eae7Such Boot::Destroy(); 839173eae7Such if (app->_root) 849173eae7Such delete app->_root; 859173eae7Such delete app; 869173eae7Such Console::Destroy(); 879173eae7Such HpcMenuInterface::Destroy(); 889173eae7Such 899173eae7Such return ret; 909173eae7Such } 919173eae7Such 92bd926f64Such // 93bd926f64Such // boot sequence. 94bd926f64Such // 959173eae7Such void 96bd926f64Such hpcboot(void *arg) 979173eae7Such { 989173eae7Such size_t sz = 0; 999173eae7Such paddr_t p = 0; 1009173eae7Such TCHAR *error_message = 0; 1019173eae7Such 102bd926f64Such HpcMenuInterface &menu = HPC_MENU; 103bd926f64Such Boot &f = Boot::Instance(); 104bd926f64Such 1052a2cc9f4Such // Open serial port for kernel KGDB. 1062a2cc9f4Such SerialConsole::OpenCOM1(); 1072a2cc9f4Such 1089173eae7Such menu.progress(); 1097758e172Such if (!f.setup()) { 110f578e43dSuwe error_message = TEXT("Architecture not supported.\n"); 1117758e172Such goto failed_exit; 1127758e172Such } 1139173eae7Such 1149173eae7Such menu.progress(); 1157758e172Such if (!f.create()) { 116f578e43dSuwe error_message = TEXT("Architecture ops. not found.\n"); 1177758e172Such goto failed_exit; 1187758e172Such } 1199173eae7Such 1209173eae7Such menu.progress(); 1219173eae7Such if (!f._arch->init()) { 122f578e43dSuwe error_message = TEXT("Architecture initialize failed.\n"); 1237758e172Such goto failed_exit; 1249173eae7Such } 1259173eae7Such 1269173eae7Such f._arch->systemInfo(); 1279173eae7Such 1289173eae7Such menu.progress(); 1299173eae7Such // kernel / file system image directory. 1309173eae7Such if (!f._file->setRoot(f.args.fileRoot)) { 131f578e43dSuwe error_message = TEXT("Can't set root directory.\n"); 1327758e172Such goto failed_exit; 1339173eae7Such } 1349173eae7Such 135*d6be11a5Suwe // determine the size of file system image. 1369173eae7Such if (f.args.loadmfs) 1379173eae7Such { 1389173eae7Such if (!f._file->open(f.args.mfsName)) { 1399173eae7Such error_message = 140f578e43dSuwe TEXT("Can't open file system image.\n"); 1417758e172Such goto failed_exit; 1429173eae7Such } 143*d6be11a5Suwe sz = f._file->realsize(); 144984e0193Such sz = f._mem->roundPage(sz); 1459173eae7Such f._file->close(); 1469173eae7Such } 1479173eae7Such 1489173eae7Such menu.progress(); 1499173eae7Such if (!f._file->open(f.args.fileName)) { 150f578e43dSuwe error_message = TEXT("Can't open kernel image.\n"); 1512a2cc9f4Such goto failed_exit; 1529173eae7Such } 1539173eae7Such 1549173eae7Such menu.progress(); 1559173eae7Such // put kernel to loader. 1560c9676c9Suwe if (!f.attachLoader()) { 1570c9676c9Suwe error_message = TEXT("Can't attach loader.\n"); 1582a2cc9f4Such goto file_close_exit; 1590c9676c9Suwe } 1609173eae7Such 1619173eae7Such if (!f._loader->setFile(f._file)) { 162f578e43dSuwe error_message = TEXT("Can't initialize loader.\n"); 1632a2cc9f4Such goto file_close_exit; 1649173eae7Such } 1659173eae7Such 1669173eae7Such menu.progress(); 167984e0193Such sz += f._mem->roundPage(f._loader->memorySize()); 1689173eae7Such 1699173eae7Such // allocate required memory. 1709173eae7Such if (!f._arch->allocateMemory(sz)) { 171f578e43dSuwe error_message = TEXT("Can't allocate memory.\n"); 1722a2cc9f4Such goto file_close_exit; 1739173eae7Such } 1749173eae7Such 1759173eae7Such menu.progress(); 1769173eae7Such // load kernel to memory. 1779173eae7Such if (!f._arch->setupLoader()) { 178f578e43dSuwe error_message = TEXT("Can't set up loader.\n"); 1792a2cc9f4Such goto file_close_exit; 1809173eae7Such } 1819173eae7Such 1829173eae7Such menu.progress(); 1839173eae7Such if (!f._loader->load()) { 184f578e43dSuwe error_message = TEXT("Can't load kernel image to memory.\n"); 1852a2cc9f4Such goto file_close_exit; 1869173eae7Such } 1879173eae7Such menu.progress(); 18887aeed61Such f._file->close(); 1899173eae7Such 1909173eae7Such // load file system image to memory 1919173eae7Such if (f.args.loadmfs) { 1922a2cc9f4Such if (!f._file->open(f.args.mfsName)) { 1932a2cc9f4Such error_message = 194f578e43dSuwe TEXT("Can't open file system image.\n"); 1952a2cc9f4Such goto failed_exit; 1962a2cc9f4Such } 197984e0193Such if (!f._loader->loadExtData()) { 198984e0193Such error_message = 199f578e43dSuwe TEXT("Can't load file system image to memory.\n"); 2002a2cc9f4Such goto file_close_exit; 201984e0193Such } 2029173eae7Such f._file->close(); 2039173eae7Such } 2049173eae7Such f._loader->loadEnd(); 2059173eae7Such 2069173eae7Such // setup arguments for kernel. 2079173eae7Such p = f._arch->setupBootInfo(*f._loader); 2089173eae7Such 2099173eae7Such menu.progress(); 2109173eae7Such 2119173eae7Such f._loader->tagDump(3); // dump page chain.(print first 3 links) 2129173eae7Such 2139173eae7Such // jump to kernel entry. 214bd926f64Such if (HPC_PREFERENCE.pause_before_boot) { 2158b377aadSuwe if (MessageBox(menu._root->_window, TEXT("Push YES to boot."), 2168b377aadSuwe TEXT("Last chance..."), 217f578e43dSuwe MB_ICONWARNING | MB_YESNO) != IDYES) 218816df014Suwe { 219f578e43dSuwe error_message = TEXT("Canceled by user.\n"); 2202a2cc9f4Such goto failed_exit; 2219173eae7Such } 2229f2e9e23Suwe // redraw areas damaged by the dialog 2239f2e9e23Suwe UpdateWindow(menu._root->_window); 224816df014Suwe } 2259173eae7Such 2269173eae7Such f._arch->jump(p, f._loader->tagStart()); 2279173eae7Such // NOTREACHED 2280c9676c9Suwe error_message = TEXT("Can't jump to the kernel.\n"); 2299173eae7Such 2302a2cc9f4Such file_close_exit: 23187aeed61Such f._file->close(); 2320c9676c9Suwe 2337758e172Such failed_exit: 2340c9676c9Suwe if (error_message == 0) 2350c9676c9Suwe error_message = TEXT("Unknown error?\n"); 2369173eae7Such MessageBox(menu._root->_window, error_message, 2378b377aadSuwe TEXT("BOOT FAILED"), MB_ICONERROR | MB_OK); 238f94c4399Suwe 239f94c4399Suwe menu.unprogress(); // rewind progress bar 2409173eae7Such } 2419173eae7Such 2429173eae7Such // 2439173eae7Such // HPCBOOT main loop 2449173eae7Such // 2459173eae7Such int 2469173eae7Such HpcBootApp::run(void) 2479173eae7Such { 2489173eae7Such MSG msg; 2499173eae7Such 2509173eae7Such while (GetMessage(&msg, 0, 0, 0)) { 2519173eae7Such // cancel auto-boot. 252bd926f64Such if (HPC_PREFERENCE.auto_boot > 0 && _root && 2539173eae7Such (msg.message == WM_KEYDOWN || 2549173eae7Such msg.message == WM_LBUTTONDOWN)) { 2559173eae7Such _root->disableTimer(); 2569173eae7Such } 2579173eae7Such if (!_root->isDialogMessage(msg)) { 2589173eae7Such TranslateMessage(&msg); 2599173eae7Such DispatchMessage(&msg); 2609173eae7Such } 2619173eae7Such } 2629173eae7Such return msg.wParam; 2639173eae7Such } 2649173eae7Such 2659173eae7Such BOOL 2669173eae7Such HpcBootApp::registerClass(WNDPROC proc) 2679173eae7Such { 2689173eae7Such TCHAR *wc_name; 2699173eae7Such WNDCLASS wc; 2709173eae7Such 2719173eae7Such memset(&wc, 0, sizeof(WNDCLASS)); 2729173eae7Such wc_name = reinterpret_cast <TCHAR *> 2739173eae7Such (LoadString(_instance, IDS_HPCMENU, 0, 0)); 2749173eae7Such wc.lpfnWndProc = proc; 2759173eae7Such wc.hInstance = _instance; 2769173eae7Such wc.hIcon = LoadIcon(_instance, MAKEINTRESOURCE(IDI_ICON)); 2779173eae7Such wc.cbWndExtra = 4; // pointer of `this` 2789173eae7Such wc.hbrBackground= static_cast <HBRUSH>(GetStockObject(LTGRAY_BRUSH)); 2799173eae7Such wc.lpszClassName= wc_name; 2809173eae7Such 2819173eae7Such return RegisterClass(&wc); 2829173eae7Such } 283984e0193Such 284984e0193Such 285984e0193Such // 286984e0193Such // Debug support. 287984e0193Such // 288984e0193Such void 289984e0193Such _bitdisp(u_int32_t a, int s, int e, int m, int c) 290984e0193Such { 291984e0193Such u_int32_t j, j1; 292984e0193Such int i, n; 293984e0193Such 294984e0193Such DPRINTF_SETUP(); 295984e0193Such 296984e0193Such n = 31; // 32bit only. 297984e0193Such j1 = 1 << n; 298984e0193Such e = e ? e : n; 299984e0193Such for (j = j1, i = n; j > 0; j >>=1, i--) { 300984e0193Such if (i > e || i < s) { 301984e0193Such DPRINTF((TEXT("%c"), a & j ? '+' : '-')); 302984e0193Such } else { 303984e0193Such DPRINTF((TEXT("%c"), a & j ? '|' : '.')); 304984e0193Such } 305984e0193Such } 306984e0193Such if (m) { 307984e0193Such DPRINTF((TEXT("[%s]"),(char*)m)); 308984e0193Such } 309984e0193Such 310984e0193Such DPRINTF((TEXT(" [0x%08x]"), a)); 311984e0193Such 312984e0193Such if (c) { 313984e0193Such for (j = j1, i = n; j > 0; j >>=1, i--) { 314984e0193Such if (!(i > e || i < s) &&(a & j)) { 315984e0193Such DPRINTF((TEXT(" %d"), i)); 316984e0193Such } 317984e0193Such } 318984e0193Such } 319984e0193Such 320984e0193Such DPRINTF((TEXT(" %d\n"), a)); 321984e0193Such } 322984e0193Such 323984e0193Such void 324984e0193Such _dbg_bit_print(u_int32_t reg, u_int32_t mask, const char *name) 325984e0193Such { 326984e0193Such static const char onoff[3] = "_x"; 327984e0193Such 328984e0193Such DPRINTF_SETUP(); 329984e0193Such 330984e0193Such DPRINTF((TEXT("%S[%c] "), name, onoff[reg & mask ? 1 : 0])); 331984e0193Such } 332