1 /* -*-C++-*- $NetBSD: hpcmenu.cpp,v 1.17 2006/03/05 04:05:39 uwe Exp $ */
4 * Copyright (c) 2001, 2004 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
34 #include <res/resource.h>
35 #include <menu/window.h>
36 #include <menu/tabwindow.h>
37 #include <menu/rootwindow.h>
38 #include <menu/menu.h>
39 #include <machine/bootinfo.h>
40 #include <framebuffer.h>
44 HpcMenuInterface
*HpcMenuInterface::_instance
= 0;
47 HpcMenuInterface::Instance()
51 _instance
= new HpcMenuInterface();
56 HpcMenuInterface::Destroy()
63 HpcMenuInterface::HpcMenuInterface()
68 _pref
._version
= HPCBOOT_VERSION
;
69 _pref
._size
= sizeof(HpcMenuPreferences
);
72 memset(_cons_hook
, 0, sizeof(struct cons_hook_args
) * 4);
73 memset(&_boot_hook
, 0, sizeof(struct boot_hook_args
));
77 HpcMenuInterface::print(TCHAR
*buf
)
85 HpcMenuInterface::get_options()
93 HpcMenuInterface::dir(int i
)
95 int res
= IDS_DIR_RES(i
);
97 if (!IDS_DIR_RES_VALID(res
))
100 if (_pref
.dir_user
&& res
== IDS_DIR_USER_DEFINED
) {
101 return _pref
.dir_user_path
;
104 TCHAR
*s
= reinterpret_cast <TCHAR
*>
105 (LoadString(_root
->_app
._instance
, res
, 0, 0));
111 HpcMenuInterface::dir_default()
114 return _pref
.dir_user
? IDS_DIR_SEQ(IDS_DIR_USER_DEFINED
) : 0;
118 HpcMenuInterface::_set_default_pref()
121 _pref
._magic
= HPCBOOT_MAGIC
;
123 _pref
.dir_user
= FALSE
;
124 _pref
.kernel_user
= FALSE
;
128 wsprintf(_pref
.rootfs_file
, TEXT("miniroot.fs"));
129 _pref
.boot_serial
= FALSE
;
130 _pref
.boot_verbose
= FALSE
;
131 _pref
.boot_single_user
= FALSE
;
132 _pref
.boot_ask_for_name
= FALSE
;
133 _pref
.boot_debugger
= FALSE
;
134 wsprintf(_pref
.boot_extra
, TEXT(""));
136 _pref
.reverse_video
= FALSE
;
137 _pref
.pause_before_boot
= TRUE
;
138 _pref
.safety_message
= TRUE
;
140 _pref
.serial_speed
= 9600; // historical reason.
142 _pref
.serial_speed
= 19200;
147 // load and save current menu status.
150 HpcMenuInterface::load()
152 TCHAR path
[MAX_PATH
];
154 if (!_find_pref_dir(path
))
157 TCHAR filename
[MAX_PATH
];
158 wsprintf(filename
, TEXT("\\%s\\hpcboot.cnf"), path
);
159 HANDLE file
= CreateFile(filename
, GENERIC_READ
, 0, 0, OPEN_EXISTING
,
160 FILE_ATTRIBUTE_NORMAL
, 0);
161 if (file
== INVALID_HANDLE_VALUE
)
166 if (!ReadFile(file
, &_pref
, 12, &cnt
, 0))
168 if (_pref
._magic
!= HPCBOOT_MAGIC
)
171 SetFilePointer(file
, 0, 0, FILE_BEGIN
);
172 if (!ReadFile(file
, &_pref
, _pref
._size
, &cnt
, 0))
183 HpcMenuInterface::save()
185 TCHAR path
[MAX_PATH
];
187 if (_find_pref_dir(path
)) {
188 TCHAR filename
[MAX_PATH
];
189 wsprintf(filename
, TEXT("\\%s\\hpcboot.cnf"), path
);
190 HANDLE file
= CreateFile(filename
, GENERIC_WRITE
, 0, 0,
191 CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, 0);
193 WriteFile(file
, &_pref
, _pref
._size
, &cnt
, 0);
195 return cnt
== _pref
._size
;
201 // arguments for kernel.
203 HpcMenuInterface::setup_kernel_args(vaddr_t v
, paddr_t p
, size_t sz
)
206 kaddr_t
*argv
= reinterpret_cast <kaddr_t
*>(v
);
207 char *loc
= reinterpret_cast <char *>
208 (v
+ sizeof(char **) * MAX_KERNEL_ARGS
);
209 paddr_t locp
= p
+ sizeof(char **) * MAX_KERNEL_ARGS
;
216 argv[argc++] = ptokv(locp); \
221 // 1st arg is kernel name.
222 // DPRINTF_SETUP(); //if you want to use debug print, enable this line.
224 w
= _pref
.kernel_user_file
;
225 argv
[argc
++] = ptokv(locp
);
226 len
= WideCharToMultiByte(CP_ACP
, 0, w
, wcslen(w
), 0, 0, 0, 0);
227 WideCharToMultiByte(CP_ACP
, 0, w
, len
, loc
, len
, 0, 0);
232 if (_pref
.boot_serial
) // serial console
234 if (_pref
.boot_verbose
) // boot verbosely
236 if (_pref
.boot_single_user
) // boot to single user
238 if (_pref
.boot_ask_for_name
) // ask for file name to boot from
240 if (_pref
.boot_debugger
) // break into the kernel debugger
244 switch(_pref
.rootfs
) {
248 argv
[argc
++] = ptokv(locp
);
249 strncpy(loc
, "b=sd0", 6);
253 case 2: // memory disk
254 w
= _pref
.rootfs_file
;
255 argv
[argc
++] = ptokv(locp
);
256 strncpy(loc
, "m=", 2);
258 len
= WideCharToMultiByte(CP_ACP
, 0, w
, wcslen(w
), 0, 0, 0, 0);
259 WideCharToMultiByte(CP_ACP
, 0, w
, len
, loc
, len
, 0, 0);
265 argv
[argc
++] = ptokv(locp
);
266 strncpy(loc
, "b=nfs", 6);
272 // Extra kernel options. (Option tab window)
273 w
= _pref
.boot_extra
;
274 len
= WideCharToMultiByte(CP_ACP
, 0, w
, wcslen(w
), 0, 0, 0, 0);
276 if ((ptr
= (char *)malloc(len
)) == NULL
) {
277 MessageBox(_root
->_window
,
278 L
"Can't allocate memory for extra kernel options.",
280 MB_ICONWARNING
| MB_OK
);
281 UpdateWindow(_root
->_window
);
285 WideCharToMultiByte(CP_ACP
, 0, w
, len
, ptr
, len
, 0, 0);
288 while (*ptr
== ' ' || *ptr
== '\t')
290 while (*ptr
!= '\0') {
291 len
= strcspn(ptr
, " \t");
295 if (argc
== MAX_KERNEL_ARGS
|| locp
+ len
+ 1 > p
+ sz
) {
296 MessageBox(_root
->_window
,
297 L
"Too many extra kernel options.",
299 MB_ICONWARNING
| MB_OK
);
300 UpdateWindow(_root
->_window
);
303 argv
[argc
++] = ptokv(locp
);
304 strncpy(loc
, ptr
, len
);
310 while (*ptr
== ' ' || *ptr
== '\t')
319 HpcMenuInterface::setup_bootinfo(struct bootinfo
&bi
)
321 FrameBufferInfo
fb(_pref
.platid_hi
, _pref
.platid_lo
);
322 TIME_ZONE_INFORMATION tz
;
323 DWORD tzid
= GetTimeZoneInformation(&tz
);
325 memset(&bi
, 0, sizeof(struct bootinfo
));
326 bi
.length
= sizeof(struct bootinfo
);
328 bi
.magic
= BOOTINFO_MAGIC
;
329 bi
.fb_addr
= fb
.addr();
330 bi
.fb_type
= fb
.type();
331 bi
.fb_line_bytes
= fb
.linebytes();
332 bi
.fb_width
= fb
.width();
333 bi
.fb_height
= fb
.height();
334 bi
.platid_cpu
= _pref
.platid_hi
;
335 bi
.platid_machine
= _pref
.platid_lo
;
336 bi
.timezone
= tz
.Bias
;
337 if (tzid
== TIME_ZONE_ID_DAYLIGHT
)
338 bi
.timezone
+= tz
.DaylightBias
;
343 HpcMenuInterface::progress(const char *msg
)
346 _root
->progress(msg
);
350 HpcMenuInterface::unprogress()
358 HpcMenuInterface::boot()
360 struct support_status
*tab
= _unsupported
;
361 uint32_t cpu
= _pref
.platid_hi
;
362 uint32_t machine
= _pref
.platid_lo
;
364 if (_pref
.safety_message
)
365 for (; tab
->cpu
; tab
++) {
366 if (tab
->cpu
== cpu
&& tab
->machine
== machine
) {
367 MessageBox(_root
->_window
,
368 tab
->cause
? tab
->cause
:
369 L
"Not supported yet.",
371 MB_ICONERROR
| MB_OK
);
377 _boot_hook
.func(_boot_hook
.arg
);