boot.c revision 1.2 1 1.2 tsutsui /* $NetBSD: boot.c,v 1.2 2006/01/26 16:26:58 tsutsui Exp $ */
2 1.1 tsutsui
3 1.1 tsutsui /*-
4 1.1 tsutsui * Copyright (c) 2004 The NetBSD Foundation, Inc.
5 1.1 tsutsui * All rights reserved.
6 1.1 tsutsui *
7 1.1 tsutsui * This code is derived from software contributed to The NetBSD Foundation
8 1.1 tsutsui * by UCHIYAMA Yasushi.
9 1.1 tsutsui *
10 1.1 tsutsui * Redistribution and use in source and binary forms, with or without
11 1.1 tsutsui * modification, are permitted provided that the following conditions
12 1.1 tsutsui * are met:
13 1.1 tsutsui * 1. Redistributions of source code must retain the above copyright
14 1.1 tsutsui * notice, this list of conditions and the following disclaimer.
15 1.1 tsutsui * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 tsutsui * notice, this list of conditions and the following disclaimer in the
17 1.1 tsutsui * documentation and/or other materials provided with the distribution.
18 1.1 tsutsui * 3. All advertising materials mentioning features or use of this software
19 1.1 tsutsui * must display the following acknowledgement:
20 1.1 tsutsui * This product includes software developed by the NetBSD
21 1.1 tsutsui * Foundation, Inc. and its contributors.
22 1.1 tsutsui * 4. Neither the name of The NetBSD Foundation nor the names of its
23 1.1 tsutsui * contributors may be used to endorse or promote products derived
24 1.1 tsutsui * from this software without specific prior written permission.
25 1.1 tsutsui *
26 1.1 tsutsui * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 1.1 tsutsui * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 1.1 tsutsui * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 1.1 tsutsui * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 1.1 tsutsui * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 1.1 tsutsui * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 1.1 tsutsui * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 1.1 tsutsui * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 1.1 tsutsui * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 1.1 tsutsui * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 1.1 tsutsui * POSSIBILITY OF SUCH DAMAGE.
37 1.1 tsutsui */
38 1.1 tsutsui
39 1.1 tsutsui #include <lib/libsa/stand.h>
40 1.1 tsutsui #include <lib/libkern/libkern.h>
41 1.1 tsutsui
42 1.1 tsutsui #include "local.h"
43 1.1 tsutsui #include "cmd.h"
44 1.1 tsutsui #include "common.h"
45 1.1 tsutsui
46 1.1 tsutsui #include <machine/sbd.h>
47 1.1 tsutsui #include <machine/pdinfo.h>
48 1.1 tsutsui #include <machine/vtoc.h>
49 1.1 tsutsui
50 1.1 tsutsui #include "console.h"
51 1.1 tsutsui
52 1.1 tsutsui
53 1.1 tsutsui extern const char bootprog_name[];
54 1.1 tsutsui extern const char bootprog_rev[];
55 1.1 tsutsui extern const char bootprog_date[];
56 1.1 tsutsui extern const char bootprog_maker[];
57 1.1 tsutsui
58 1.1 tsutsui struct cmd_batch_tab cmd_batch_tab[] = {
59 1.1 tsutsui /* func argc argp... */
60 1.1 tsutsui #if 0
61 1.1 tsutsui { cmd_boot, 1, { "mem:", 0, 0, 0, 0, 0, 0 } },
62 1.1 tsutsui { cmd_boot, 1, { "sd0k:netbsd", 0, 0, 0, 0, 0, 0 } },
63 1.1 tsutsui { cmd_load_binary, 1, { "0x80001000", 0, 0, 0, 0, 0, 0 } },
64 1.1 tsutsui { cmd_jump, 2, { "0x80001000", "0x80001000", 0, 0, 0, 0, 0 } },
65 1.1 tsutsui #endif
66 1.1 tsutsui { NULL, 0, { 0, 0, 0, 0, 0, 0, 0 } } /* terminate */
67 1.1 tsutsui };
68 1.1 tsutsui
69 1.1 tsutsui struct ipl_args ipl_args;
70 1.1 tsutsui struct device_capability DEVICE_CAPABILITY;
71 1.1 tsutsui void set_device_capability(void);
72 1.1 tsutsui boolean_t guess_boot_kernel(char *, size_t, int);
73 1.1 tsutsui extern int kernel_binary_size;
74 1.1 tsutsui
75 1.1 tsutsui void
76 1.1 tsutsui main(int a0, int v0, int v1)
77 1.1 tsutsui {
78 1.1 tsutsui extern char edata[], end[];
79 1.1 tsutsui char boot_kernel[32];
80 1.1 tsutsui char *args[CMDARG_MAX];
81 1.1 tsutsui int i;
82 1.1 tsutsui
83 1.1 tsutsui memset(edata, 0, end - edata);
84 1.1 tsutsui /* Save args for chain-boot to iopboot */
85 1.1 tsutsui ipl_args.a0 = a0;
86 1.1 tsutsui ipl_args.v0 = v0;
87 1.1 tsutsui ipl_args.v1 = v1;
88 1.1 tsutsui
89 1.1 tsutsui console_init();
90 1.1 tsutsui
91 1.1 tsutsui printf("\n");
92 1.1 tsutsui printf("%s boot, Revision %s\n", bootprog_name, bootprog_rev);
93 1.1 tsutsui printf("(%s, %s)\n", bootprog_date, bootprog_maker);
94 1.1 tsutsui
95 1.1 tsutsui
96 1.1 tsutsui /* Inquire IPL activated device */
97 1.1 tsutsui set_device_capability();
98 1.1 tsutsui
99 1.1 tsutsui if (!guess_boot_kernel(boot_kernel, sizeof boot_kernel, 0))
100 1.1 tsutsui goto prompt;
101 1.1 tsutsui printf(
102 1.1 tsutsui ">> Press return to boot now, any other key for boot console.\n");
103 1.1 tsutsui
104 1.1 tsutsui for (i = 5000; i >= 0; i--) {
105 1.1 tsutsui int c;
106 1.1 tsutsui if (i % 1000 == 0)
107 1.1 tsutsui printf("booting %s - starting %d\r",
108 1.1 tsutsui boot_kernel, i / 1000);
109 1.1 tsutsui if ((c = cnscan()) == -1) {
110 1.1 tsutsui delay(10);
111 1.1 tsutsui continue;
112 1.1 tsutsui }
113 1.1 tsutsui else if (c == '\r')
114 1.1 tsutsui break;
115 1.1 tsutsui else
116 1.1 tsutsui goto prompt;
117 1.1 tsutsui }
118 1.1 tsutsui printf("\n[non-interactive mode]\n");
119 1.1 tsutsui args[0] = "boot";
120 1.1 tsutsui args[1] = boot_kernel;
121 1.1 tsutsui cmd_boot(2, args, FALSE);
122 1.1 tsutsui prompt:
123 1.1 tsutsui
124 1.1 tsutsui printf("\ntype \"help\" for help.\n");
125 1.1 tsutsui console_cursor(TRUE);
126 1.1 tsutsui prompt();
127 1.1 tsutsui /* NOTREACHED */
128 1.1 tsutsui }
129 1.1 tsutsui
130 1.1 tsutsui boolean_t
131 1.1 tsutsui guess_boot_kernel(char *name, size_t len, int pri)
132 1.1 tsutsui {
133 1.1 tsutsui extern struct vtoc_sector vtoc;
134 1.1 tsutsui struct ux_partition *partition;
135 1.1 tsutsui int i, unit;
136 1.1 tsutsui
137 1.1 tsutsui if (!DEVICE_CAPABILITY.active)
138 1.1 tsutsui return FALSE;
139 1.1 tsutsui
140 1.1 tsutsui unit = DEVICE_CAPABILITY.booted_unit;
141 1.1 tsutsui
142 1.1 tsutsui switch (DEVICE_CAPABILITY.booted_device) {
143 1.1 tsutsui default:
144 1.1 tsutsui return FALSE;
145 1.1 tsutsui case NVSRAM_BOOTDEV_FLOPPYDISK:
146 1.1 tsutsui strncpy(name, "fd:netbsd", len); /* ustarfs */
147 1.1 tsutsui return TRUE;
148 1.1 tsutsui
149 1.1 tsutsui case NVSRAM_BOOTDEV_HARDDISK:
150 1.1 tsutsui snprintf(name, len, "sd%d:netbsd", unit); /* ustarfs */
151 1.1 tsutsui if (!read_vtoc())
152 1.1 tsutsui return TRUE;
153 1.1 tsutsui
154 1.1 tsutsui partition = vtoc.partition;
155 1.1 tsutsui for (i = 0; i < VTOC_MAXPARTITIONS; i++, partition++) {
156 1.1 tsutsui if (partition->tag != __VTOC_TAG_BSDFFS)
157 1.1 tsutsui continue;
158 1.1 tsutsui /* ffs */
159 1.1 tsutsui snprintf(name, len, "sd%d%c:netbsd", unit, 'a' + i);
160 1.1 tsutsui return TRUE;
161 1.1 tsutsui }
162 1.1 tsutsui return TRUE;
163 1.1 tsutsui
164 1.1 tsutsui case NVSRAM_BOOTDEV_CGMT:
165 1.1 tsutsui break;
166 1.1 tsutsui case NVSRAM_BOOTDEV_NETWORK:
167 1.1 tsutsui /*FALLTHROUGH*/
168 1.1 tsutsui case NVSRAM_BOOTDEV_NETWORK_T_AND_D:
169 1.1 tsutsui if (kernel_binary_size) {
170 1.1 tsutsui strncpy(name, "mem:", len); /* datafs */
171 1.1 tsutsui return TRUE;
172 1.1 tsutsui }
173 1.1 tsutsui if (DEVICE_CAPABILITY.network_enabled) {
174 1.1 tsutsui strncpy(name, "nfs:netbsd", len); /* nfs */
175 1.1 tsutsui return TRUE;
176 1.1 tsutsui }
177 1.1 tsutsui break;
178 1.1 tsutsui }
179 1.1 tsutsui
180 1.1 tsutsui return FALSE;
181 1.1 tsutsui }
182 1.1 tsutsui
183 1.1 tsutsui int
184 1.1 tsutsui cmd_info(int argc, char *argp[], int interactive)
185 1.1 tsutsui {
186 1.1 tsutsui extern char _ftext[], _etext[], _fdata[], _edata[];
187 1.1 tsutsui extern char _fbss[], end[];
188 1.1 tsutsui uint32_t m;
189 1.1 tsutsui int i, size, total;
190 1.1 tsutsui struct sbdinfo *sbd = SBD_INFO;
191 1.1 tsutsui
192 1.1 tsutsui printf("\n>> %s boot, rev. %s [%s, %s] <<\n", bootprog_name,
193 1.1 tsutsui bootprog_rev, bootprog_date, bootprog_maker);
194 1.1 tsutsui
195 1.1 tsutsui printf("IPL args: 0x%x 0x%x 0x%x\n", ipl_args.a0, ipl_args.v0,
196 1.1 tsutsui ipl_args.v1);
197 1.1 tsutsui printf("\ttext : %p-%p\n\tdata : %p-%p\n\t"
198 1.1 tsutsui "bss : %p-%p\n\tstack: %p\n\theap : %p\n",
199 1.1 tsutsui _ftext, _etext, _fdata, _edata,
200 1.1 tsutsui _fbss, end, _ftext, end);
201 1.1 tsutsui
202 1.1 tsutsui m = ipl_args.v1;
203 1.1 tsutsui total = 0;
204 1.1 tsutsui printf("Memory Area:\n\t");
205 1.1 tsutsui for (i = 0; i < 8; i++, m >>= 4) {
206 1.1 tsutsui size = m & 0xf ? ((m & 0xf) << 4) : 0;
207 1.1 tsutsui total += size;
208 1.1 tsutsui if (size)
209 1.1 tsutsui printf("M%d=%dMB ", i, size);
210 1.1 tsutsui }
211 1.1 tsutsui printf(" total %dMB\n", total);
212 1.1 tsutsui
213 1.1 tsutsui printf("Board Revision:\n");
214 1.1 tsutsui printf("\tmachine=0x%x, ", sbd->machine);
215 1.1 tsutsui printf("model=0x%x\n", sbd->model);
216 1.1 tsutsui printf("\tpmmu=%d, ", sbd->mmu);
217 1.1 tsutsui printf("cache=%d, ", sbd->cache);
218 1.1 tsutsui printf("panel=%d, ", sbd->panel);
219 1.1 tsutsui printf("fdd=%d\n", sbd->fdd);
220 1.1 tsutsui printf("\tcpu=%d, fpp=%d, fpa=%d, iop=%d\n",
221 1.1 tsutsui sbd->cpu, sbd->fpp, sbd->fpa, sbd->iop);
222 1.1 tsutsui printf("\tclock=%d\n", sbd->clock);
223 1.1 tsutsui printf("\tipl=%d, cpu_ex=%d, fpp_ex=%d\n",
224 1.1 tsutsui sbd->ipl, sbd->cpu_ex, sbd->fpp_ex);
225 1.1 tsutsui printf("\tkbms=%d, sio=%d, battery=%d, scsi=%d\n",
226 1.1 tsutsui sbd->kbms, sbd->sio, sbd->battery, sbd->scsi);
227 1.1 tsutsui printf("model name=%s\n", sbd->model_name);
228 1.1 tsutsui
229 1.1 tsutsui return 0;
230 1.1 tsutsui }
231 1.1 tsutsui
232 1.1 tsutsui int
233 1.1 tsutsui cmd_reboot(int argc, char *argp[], int interactive)
234 1.1 tsutsui {
235 1.1 tsutsui int bootdev = -1;
236 1.1 tsutsui
237 1.1 tsutsui if (argc > 1)
238 1.1 tsutsui bootdev = strtoul(argp[1], 0, 0); /* next boot device. */
239 1.1 tsutsui if (bootdev != NVSRAM_BOOTDEV_FLOPPYDISK &&
240 1.1 tsutsui bootdev != NVSRAM_BOOTDEV_HARDDISK &&
241 1.1 tsutsui bootdev != NVSRAM_BOOTDEV_CGMT &&
242 1.1 tsutsui bootdev != NVSRAM_BOOTDEV_NETWORK) {
243 1.1 tsutsui printf("invalid boot device.");
244 1.1 tsutsui bootdev = -1;
245 1.1 tsutsui }
246 1.1 tsutsui
247 1.1 tsutsui switch (SBD_INFO->machine) {
248 1.1 tsutsui case MACHINE_TR2A:
249 1.1 tsutsui if (bootdev != -1)
250 1.1 tsutsui *(uint8_t *)0xbe493030 = bootdev;
251 1.1 tsutsui *(volatile uint32_t *)0xbe000064 |= 0x80000000;
252 1.1 tsutsui *(volatile uint8_t *)0xba000004 = 1;
253 1.1 tsutsui *(uint8_t *)0xbfbffffc = 255;
254 1.1 tsutsui break;
255 1.1 tsutsui case MACHINE_TR2:
256 1.1 tsutsui if (bootdev != -1)
257 1.1 tsutsui *(uint8_t *)0xbb023030 = bootdev;
258 1.1 tsutsui *(volatile uint32_t *)0xbfb00000 |= 0x10;
259 1.1 tsutsui break;
260 1.1 tsutsui default:
261 1.1 tsutsui ROM_MONITOR();
262 1.1 tsutsui }
263 1.1 tsutsui
264 1.1 tsutsui while (/*CONSTCOND*/1)
265 1.1 tsutsui ;
266 1.1 tsutsui /* NOTREACHED */
267 1.1 tsutsui return 0;
268 1.1 tsutsui }
269 1.1 tsutsui
270 1.1 tsutsui void
271 1.1 tsutsui set_device_capability(void)
272 1.1 tsutsui {
273 1.1 tsutsui const char *devname[] = {
274 1.1 tsutsui "Floppy disk",
275 1.1 tsutsui "Unknown",
276 1.1 tsutsui "Hard disk",
277 1.1 tsutsui "Unknown",
278 1.1 tsutsui "CGMT",
279 1.1 tsutsui "Unknown",
280 1.1 tsutsui "Network",
281 1.1 tsutsui "Unknown",
282 1.1 tsutsui "Network T&D"
283 1.1 tsutsui };
284 1.1 tsutsui int booted_device, booted_unit, fd_format;
285 1.1 tsutsui
286 1.1 tsutsui boot_device(&booted_device, &booted_unit, &fd_format);
287 1.1 tsutsui if (booted_device > NVSRAM_BOOTDEV_MAX ||
288 1.1 tsutsui booted_device < NVSRAM_BOOTDEV_MIN) {
289 1.1 tsutsui printf(
290 1.1 tsutsui "invalid booted device. NVSRAM infomation isn't valid\n");
291 1.1 tsutsui } else {
292 1.1 tsutsui DEVICE_CAPABILITY.booted_device = booted_device;
293 1.1 tsutsui }
294 1.1 tsutsui DEVICE_CAPABILITY.booted_unit = booted_unit;
295 1.1 tsutsui
296 1.1 tsutsui switch (SBD_INFO->machine) {
297 1.1 tsutsui case MACHINE_TR2A:
298 1.1 tsutsui DEVICE_CAPABILITY.active = TRUE;
299 1.1 tsutsui /* boot has LANCE driver */
300 1.1 tsutsui DEVICE_CAPABILITY.network_enabled = TRUE;
301 1.1 tsutsui break;
302 1.1 tsutsui case MACHINE_TR2:
303 1.1 tsutsui DEVICE_CAPABILITY.active = TRUE;
304 1.1 tsutsui break;
305 1.1 tsutsui default:
306 1.1 tsutsui DEVICE_CAPABILITY.active = FALSE;
307 1.1 tsutsui break;
308 1.1 tsutsui }
309 1.1 tsutsui
310 1.1 tsutsui DEVICE_CAPABILITY.fd_enabled = TRUE; /* always enabled */
311 1.1 tsutsui
312 1.1 tsutsui if (DEVICE_CAPABILITY.active) {
313 1.1 tsutsui /*
314 1.1 tsutsui * When NETWORK IPL, FD IPL doesn't activate ROM DISK routine.
315 1.1 tsutsui */
316 1.1 tsutsui if (DEVICE_CAPABILITY.booted_device == NVSRAM_BOOTDEV_HARDDISK)
317 1.1 tsutsui DEVICE_CAPABILITY.disk_enabled = TRUE;
318 1.1 tsutsui }
319 1.1 tsutsui
320 1.1 tsutsui printf("FD[%c] DISK[%c] NETWORK[%c] COMPILED[%c]\n",
321 1.1 tsutsui DEVICE_CAPABILITY.fd_enabled ? 'x' : '_',
322 1.1 tsutsui DEVICE_CAPABILITY.disk_enabled ? 'x' : '_',
323 1.1 tsutsui DEVICE_CAPABILITY.network_enabled ? 'x' : '_',
324 1.1 tsutsui kernel_binary_size ? 'x' : '_');
325 1.1 tsutsui
326 1.2 tsutsui printf("booted from %s IPL", devname[DEVICE_CAPABILITY.booted_device]);
327 1.1 tsutsui if ((DEVICE_CAPABILITY.booted_device == NVSRAM_BOOTDEV_NETWORK) ||
328 1.1 tsutsui (DEVICE_CAPABILITY.booted_device == NVSRAM_BOOTDEV_NETWORK_T_AND_D))
329 1.1 tsutsui {
330 1.1 tsutsui printf("\n");
331 1.1 tsutsui } else {
332 1.1 tsutsui printf(" unit %d\n", DEVICE_CAPABILITY.booted_unit);
333 1.1 tsutsui }
334 1.1 tsutsui }
335 1.1 tsutsui
336 1.1 tsutsui int
337 1.1 tsutsui cmd_test(int argc, char *argp[], int interactive)
338 1.1 tsutsui {
339 1.1 tsutsui
340 1.1 tsutsui /* MISC TEST ROUTINE */
341 1.1 tsutsui extern int fdd_test(void);
342 1.1 tsutsui fdd_test();
343 1.1 tsutsui #if 0
344 1.1 tsutsui int i;
345 1.1 tsutsui
346 1.1 tsutsui printf("argc=%d\n", argc);
347 1.1 tsutsui for (i = 0; i < argc; i++)
348 1.1 tsutsui printf("[%d] %s\n", i, argp[i]);
349 1.1 tsutsui #endif
350 1.1 tsutsui #if 0 /* Recover my 360ADII NVSRAM.. */
351 1.1 tsutsui uint8_t *p = (uint8_t *)0xbe490000;
352 1.1 tsutsui uint8_t *q = nvsram_tr2a;
353 1.1 tsutsui int i;
354 1.1 tsutsui
355 1.1 tsutsui for (i = 0; i < sizeof nvsram_tr2a; i++) {
356 1.1 tsutsui *p = *q;
357 1.1 tsutsui p += 4;
358 1.1 tsutsui q += 1;
359 1.1 tsutsui }
360 1.1 tsutsui #endif
361 1.1 tsutsui #if 0 /* ROM PUTC test */
362 1.1 tsutsui char a[]= "ohayotest!";
363 1.1 tsutsui int i;
364 1.1 tsutsui for (i = 0; i < 10; i++)
365 1.1 tsutsui ROM_PUTC(120 + i * 12, 24 * 10, a[i]);
366 1.1 tsutsui #endif
367 1.1 tsutsui #if 0 /* ROM SCSI disk routine test TR2 */
368 1.1 tsutsui uint8_t buf[512*2];
369 1.1 tsutsui uint8_t *p;
370 1.1 tsutsui int i;
371 1.1 tsutsui
372 1.1 tsutsui printf("type=%d\n", *(uint8_t *)0xbb023034);
373 1.1 tsutsui memset(buf, 0, sizeof buf);
374 1.1 tsutsui p = (uint8_t *)(((uint32_t)buf + 511) & ~511);
375 1.1 tsutsui i = ROM_DK_READ(0, 0, 1, p);
376 1.1 tsutsui printf("err=%d\n", i);
377 1.1 tsutsui for (i = 0; i < 64; i++) {
378 1.1 tsutsui printf("%x ", p[i]);
379 1.1 tsutsui if (((i + 1) & 0xf) == 0)
380 1.1 tsutsui printf("\n");
381 1.1 tsutsui }
382 1.1 tsutsui #endif
383 1.1 tsutsui #if 0
384 1.1 tsutsui /*XXX failed. */
385 1.1 tsutsui __asm volatile(
386 1.1 tsutsui ".set noreorder;"
387 1.1 tsutsui "li $4, 2;"
388 1.1 tsutsui "mtc0 $4, $16;" /* Config */
389 1.1 tsutsui "lui $4, 0xbfc2;"
390 1.1 tsutsui "jr $4;"
391 1.1 tsutsui "nop;"
392 1.1 tsutsui ".set reorder");
393 1.1 tsutsui /* NOTREACHED */
394 1.1 tsutsui #endif
395 1.1 tsutsui #if 0
396 1.1 tsutsui /* FPU test */
397 1.1 tsutsui {
398 1.1 tsutsui int v;
399 1.1 tsutsui __asm volatile(
400 1.1 tsutsui ".set noreorder;"
401 1.1 tsutsui "lui %0, 0x2000;"
402 1.1 tsutsui "mtc0 %0, $12;" /* Cu1 */
403 1.1 tsutsui "nop;"
404 1.1 tsutsui "nop;"
405 1.1 tsutsui "cfc1 %0, $%1;"
406 1.1 tsutsui "nop;"
407 1.1 tsutsui "nop;"
408 1.1 tsutsui ".set reorder"
409 1.1 tsutsui : "=r"(v) : "i"(0));
410 1.1 tsutsui printf("FPUId: %x\n", v);
411 1.1 tsutsui }
412 1.1 tsutsui #endif
413 1.1 tsutsui return 0;
414 1.1 tsutsui }
415