loadbsd.c revision 1.26 1 1.26 aymeric /* $NetBSD: loadbsd.c,v 1.26 2000/10/30 14:40:33 aymeric Exp $ */
2 1.15 cgd
3 1.7 chopps /*
4 1.12 chopps * Copyright (c) 1994 Michael L. Hitch
5 1.12 chopps * All rights reserved.
6 1.12 chopps *
7 1.12 chopps * Redistribution and use in source and binary forms, with or without
8 1.12 chopps * modification, are permitted provided that the following conditions
9 1.12 chopps * are met:
10 1.12 chopps * 1. Redistributions of source code must retain the above copyright
11 1.12 chopps * notice, this list of conditions and the following disclaimer.
12 1.12 chopps * 2. Redistributions in binary form must reproduce the above copyright
13 1.12 chopps * notice, this list of conditions and the following disclaimer in the
14 1.12 chopps * documentation and/or other materials provided with the distribution.
15 1.12 chopps * 3. All advertising materials mentioning features or use of this software
16 1.12 chopps * must display the following acknowledgement:
17 1.12 chopps * This product includes software developed by Michael L. Hitch.
18 1.12 chopps * 4. The name of the author may not be used to endorse or promote products
19 1.12 chopps * derived from this software without specific prior written permission
20 1.12 chopps *
21 1.12 chopps * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 1.12 chopps * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 1.12 chopps * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 1.12 chopps * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 1.12 chopps * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 1.12 chopps * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 1.12 chopps * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 1.12 chopps * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 1.12 chopps * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 1.12 chopps * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 1.7 chopps */
32 1.7 chopps
33 1.1 mw #include <sys/types.h>
34 1.1 mw #include <a.out.h>
35 1.1 mw #include <stdio.h>
36 1.8 chopps #include <unistd.h>
37 1.12 chopps #include <errno.h>
38 1.12 chopps #include <stdarg.h>
39 1.12 chopps #include <signal.h>
40 1.12 chopps #ifdef __NetBSD__
41 1.12 chopps #include <err.h>
42 1.12 chopps #endif
43 1.1 mw #include <exec/types.h>
44 1.1 mw #include <exec/execbase.h>
45 1.1 mw #include <exec/memory.h>
46 1.10 chopps #include <exec/resident.h>
47 1.12 chopps #include <graphics/gfxbase.h>
48 1.1 mw #include <libraries/configregs.h>
49 1.12 chopps #include <libraries/configvars.h>
50 1.12 chopps #include <libraries/expansion.h>
51 1.1 mw #include <libraries/expansionbase.h>
52 1.1 mw
53 1.1 mw #include <inline/exec.h>
54 1.1 mw #include <inline/expansion.h>
55 1.5 mw #include <inline/graphics.h>
56 1.1 mw
57 1.3 mw /* Get definitions for boothowto */
58 1.3 mw #include "reboot.h"
59 1.3 mw
60 1.1 mw #undef __LDPGSZ
61 1.1 mw #define __LDPGSZ 8192
62 1.1 mw
63 1.12 chopps #ifndef __NetBSD__
64 1.12 chopps #ifndef __P
65 1.12 chopps #ifdef __STDC__
66 1.12 chopps #define __P(x) x
67 1.12 chopps #else
68 1.12 chopps #define __P(x)
69 1.12 chopps #endif
70 1.12 chopps #endif
71 1.12 chopps void err __P((int, const char *, ...));
72 1.12 chopps void errx __P((int, const char *, ...));
73 1.12 chopps void warn __P((const char *, ...));
74 1.12 chopps void warnx __P((const char *, ...));
75 1.12 chopps #endif
76 1.6 chopps
77 1.9 chopps /*
78 1.9 chopps * Version history:
79 1.19 mhitch * 1.x Kernel startup interface version check.
80 1.10 chopps * 2.0 Added symbol table end address and symbol table support.
81 1.10 chopps * 2.1 03/23/94 - Round up end of fastram segment.
82 1.10 chopps * Check fastram segment size for minimum of 2M.
83 1.10 chopps * Use largest segment of highest priority if -p option.
84 1.10 chopps * Print out fastram size in KB if not a multiple of MB.
85 1.10 chopps * 2.2 03/24/94 - Zero out all unused registers.
86 1.10 chopps * Started version history comment.
87 1.10 chopps * 2.3 04/26/94 - Added -D option to enter debugger on boot.
88 1.10 chopps * 2.4 04/30/94 - Cpuid includes base machine type.
89 1.10 chopps * Also check if CPU is capable of running NetBSD.
90 1.11 chopps * 2.5 05/17/94 - Add check for "A3000 bonus".
91 1.11 chopps * 2.6 06/05/94 - Added -c option to override machine type.
92 1.12 chopps * 2.7 06/15/94 - Pass E clock frequency.
93 1.13 chopps * 2.8 06/22/94 - Fix supervisor stack usage.
94 1.14 chopps * 2.9 06/26/94 - Use PAL flag for E clock freq on pre 2.0 WB
95 1.14 chopps * Added AGA enable parameter
96 1.16 chopps * 2.10 12/22/94 - Use FindResident() & OpenResource() for machine
97 1.16 chopps * type detection.
98 1.16 chopps * Add -n flag & option for non-contiguous memory.
99 1.16 chopps * 01/28/95 - Corrected -n on usage & help messages.
100 1.17 jtc * 2.11 03/12/95 - Check kernel size against chip memory size.
101 1.17 jtc * 2.12 11/11/95 - Add -I option to inhibit synchronous transfer
102 1.19 mhitch * 11/12/95 - New kernel startup interface version - to
103 1.19 mhitch * support loading kernel image to fastmem rather than chipmem.
104 1.19 mhitch * 2.13 04/15/96 - Direct load to fastmem.
105 1.19 mhitch * Add -Z flag to force chipmem load.
106 1.19 mhitch * Moved test mode exit to later - kernel image is created
107 1.19 mhitch * and startup interface version checked in test mode.
108 1.19 mhitch * Add -s flag for compatibility to bootblock loader.
109 1.19 mhitch * 05/02/96 - Add a maximum startup interface version level
110 1.20 is * to allow future kernel compatibility.
111 1.20 is * 2.14 06/26/96 is - Add first version of kludges needed to
112 1.20 is * boot on DraCos. This can probably be done a bit more cleanly
113 1.20 is * using TTRs, but it works for now.
114 1.21 is * 2.15 07/28/96 is - Add first version of kludges needed to
115 1.21 is * get FusionForty kickrom'd memory back. Hope this doesn't
116 1.21 is * break anything else.
117 1.25 jdolecek * 2.16 07/08/00 - added bootverbose support
118 1.9 chopps */
119 1.25 jdolecek static const char _version[] = "$VER: LoadBSD 2.16 (19.9.2000)";
120 1.9 chopps
121 1.12 chopps /*
122 1.19 mhitch * Kernel startup interface version
123 1.12 chopps * 1: first version of loadbsd
124 1.12 chopps * 2: needs esym location passed in a4
125 1.19 mhitch * 3: load kernel image into fastmem rather than chipmem
126 1.19 mhitch * MAX: highest version with backward compatibility.
127 1.12 chopps */
128 1.19 mhitch #define KERNEL_STARTUP_VERSION 3
129 1.19 mhitch #define KERNEL_STARTUP_VERSION_MAX 9
130 1.10 chopps
131 1.20 is #define DRACOREVISION (*(UBYTE *)0x02000009)
132 1.20 is #define DRACOMMUMARGIN 0x200000
133 1.20 is
134 1.12 chopps #define MAXMEMSEG 16
135 1.12 chopps struct boot_memlist {
136 1.12 chopps u_int m_nseg; /* num_mem; */
137 1.12 chopps struct boot_memseg {
138 1.12 chopps u_int ms_start;
139 1.12 chopps u_int ms_size;
140 1.12 chopps u_short ms_attrib;
141 1.12 chopps short ms_pri;
142 1.12 chopps } m_seg[MAXMEMSEG];
143 1.12 chopps };
144 1.12 chopps struct boot_memlist memlist;
145 1.12 chopps struct boot_memlist *kmemlist;
146 1.12 chopps
147 1.12 chopps
148 1.12 chopps void get_mem_config __P((void **, u_long *, u_long *));
149 1.12 chopps void get_cpuid __P((void));
150 1.12 chopps void get_eclock __P((void));
151 1.14 chopps void get_AGA __P((void));
152 1.12 chopps void usage __P((void));
153 1.12 chopps void verbose_usage __P((void));
154 1.12 chopps void Version __P((void));
155 1.19 mhitch void startit __P((void *, u_long, u_long, void *, u_long, u_long, int, void *,
156 1.19 mhitch int, int, u_long, u_long, int));
157 1.19 mhitch void startit_end __P((void));
158 1.5 mw
159 1.12 chopps extern struct ExecBase *SysBase;
160 1.5 mw extern char *optarg;
161 1.5 mw extern int optind;
162 1.5 mw
163 1.12 chopps int k_flag;
164 1.12 chopps int p_flag;
165 1.12 chopps int t_flag;
166 1.12 chopps int reqmemsz;
167 1.12 chopps int S_flag;
168 1.17 jtc u_long I_flag;
169 1.19 mhitch int Z_flag;
170 1.12 chopps u_long cpuid;
171 1.12 chopps long eclock_freq;
172 1.16 chopps long amiga_flags;
173 1.12 chopps char *program_name;
174 1.12 chopps char *kname;
175 1.12 chopps struct ExpansionBase *ExpansionBase;
176 1.12 chopps struct GfxBase *GfxBase;
177 1.20 is u_char *kp;
178 1.20 is int ksize;
179 1.1 mw
180 1.10 chopps int
181 1.12 chopps main(argc, argv)
182 1.12 chopps int argc;
183 1.12 chopps char **argv;
184 1.1 mw {
185 1.12 chopps struct exec e;
186 1.12 chopps struct ConfigDev *cd, *kcd;
187 1.12 chopps u_long fmemsz, cmemsz;
188 1.20 is int fd, boothowto, textsz, stringsz, ncd, i, mem_ix, ch;
189 1.12 chopps u_short *kvers;
190 1.12 chopps int *nkcd;
191 1.12 chopps void *fmem;
192 1.12 chopps char *esym;
193 1.19 mhitch void (*start_it) __P((void *, u_long, u_long, void *, u_long, u_long,
194 1.19 mhitch int, void *, int, int, u_long, u_long, int)) = startit;
195 1.12 chopps
196 1.12 chopps program_name = argv[0];
197 1.12 chopps boothowto = RB_SINGLE;
198 1.12 chopps
199 1.12 chopps if (argc < 2)
200 1.12 chopps usage();
201 1.12 chopps if ((GfxBase = (void *)OpenLibrary(GRAPHICSNAME, 0)) == NULL)
202 1.12 chopps err(20, "can't open graphics library");
203 1.12 chopps if ((ExpansionBase=(void *)OpenLibrary(EXPANSIONNAME, 0)) == NULL)
204 1.12 chopps err(20, "can't open expansion library");
205 1.12 chopps
206 1.25 jdolecek while ((ch = getopt(argc, argv, "aAbc:DhI:km:n:qptsSvVZ")) != -1) {
207 1.12 chopps switch (ch) {
208 1.12 chopps case 'k':
209 1.12 chopps k_flag = 1;
210 1.12 chopps break;
211 1.12 chopps case 'a':
212 1.12 chopps boothowto &= ~(RB_SINGLE);
213 1.12 chopps boothowto |= RB_AUTOBOOT;
214 1.12 chopps break;
215 1.12 chopps case 'b':
216 1.12 chopps boothowto |= RB_ASKNAME;
217 1.12 chopps break;
218 1.12 chopps case 'p':
219 1.12 chopps p_flag = 1;
220 1.12 chopps break;
221 1.12 chopps case 't':
222 1.12 chopps t_flag = 1;
223 1.12 chopps break;
224 1.12 chopps case 'm':
225 1.12 chopps reqmemsz = atoi(optarg) * 1024;
226 1.12 chopps break;
227 1.19 mhitch case 's':
228 1.19 mhitch boothowto &= ~(RB_AUTOBOOT);
229 1.19 mhitch boothowto |= RB_SINGLE;
230 1.19 mhitch break;
231 1.25 jdolecek case 'q':
232 1.25 jdolecek boothowto |= AB_QUIET;
233 1.26 aymeric break;
234 1.25 jdolecek case 'v':
235 1.25 jdolecek boothowto |= AB_VERBOSE;
236 1.25 jdolecek break;
237 1.12 chopps case 'V':
238 1.12 chopps fprintf(stderr,"%s\n",_version + 6);
239 1.12 chopps break;
240 1.12 chopps case 'S':
241 1.12 chopps S_flag = 1;
242 1.12 chopps break;
243 1.12 chopps case 'D':
244 1.12 chopps boothowto |= RB_KDB;
245 1.12 chopps break;
246 1.12 chopps case 'c':
247 1.12 chopps cpuid = atoi(optarg) << 16;
248 1.12 chopps break;
249 1.14 chopps case 'A':
250 1.16 chopps amiga_flags |= 1;
251 1.16 chopps break;
252 1.16 chopps case 'n':
253 1.16 chopps i = atoi(optarg);
254 1.16 chopps if (i >= 0 && i <= 3)
255 1.16 chopps amiga_flags |= i << 1;
256 1.16 chopps else
257 1.16 chopps err(20, "-n option must be 0, 1, 2, or 3");
258 1.14 chopps break;
259 1.17 jtc case 'I':
260 1.17 jtc I_flag = strtoul(optarg, NULL, 16);
261 1.17 jtc break;
262 1.19 mhitch case 'Z':
263 1.19 mhitch Z_flag = 1;
264 1.19 mhitch break;
265 1.12 chopps case 'h':
266 1.12 chopps verbose_usage();
267 1.12 chopps default:
268 1.12 chopps usage();
269 1.12 chopps }
270 1.12 chopps }
271 1.12 chopps argc -= optind;
272 1.12 chopps argv += optind;
273 1.12 chopps
274 1.12 chopps if (argc != 1)
275 1.12 chopps usage();
276 1.12 chopps kname = argv[0];
277 1.12 chopps
278 1.12 chopps if ((fd = open(kname, 0)) < 0)
279 1.12 chopps err(20, "open");
280 1.12 chopps if (read(fd, &e, sizeof(e)) != sizeof(e))
281 1.12 chopps err(20, "reading exec");
282 1.12 chopps if (e.a_magic != NMAGIC)
283 1.12 chopps err(20, "unknown binary");
284 1.12 chopps
285 1.12 chopps for (cd = 0, ncd = 0; cd = FindConfigDev(cd, -1, -1); ncd++)
286 1.12 chopps ;
287 1.20 is get_cpuid();
288 1.12 chopps get_mem_config(&fmem, &fmemsz, &cmemsz);
289 1.12 chopps get_eclock();
290 1.14 chopps get_AGA();
291 1.12 chopps
292 1.12 chopps textsz = (e.a_text + __LDPGSZ - 1) & (-__LDPGSZ);
293 1.12 chopps esym = NULL;
294 1.12 chopps ksize = textsz + e.a_data + e.a_bss + ncd * sizeof(*cd)
295 1.12 chopps + 4 + memlist.m_nseg * sizeof(struct boot_memseg) + 4;
296 1.12 chopps
297 1.12 chopps /*
298 1.12 chopps * get symbol table size & string size
299 1.12 chopps * (should check kernel version to see if it will handle it)
300 1.12 chopps */
301 1.12 chopps if (S_flag && e.a_syms) {
302 1.12 chopps if (lseek(fd, e.a_text + e.a_data + e.a_syms, SEEK_CUR) <= 0
303 1.12 chopps || read(fd, &stringsz, 4) != 4
304 1.12 chopps || lseek(fd, sizeof(e), SEEK_SET) < 0)
305 1.12 chopps err(20, "lseek for symbols");
306 1.19 mhitch ksize += e.a_syms + 4 + ((stringsz + 3) & ~3);
307 1.12 chopps }
308 1.12 chopps
309 1.20 is kp = (u_char *)AllocMem(ksize + ((char *)startit_end - (char *)startit) + 256,
310 1.20 is MEMF_FAST|MEMF_REVERSE);
311 1.12 chopps if (t_flag) {
312 1.12 chopps for (i = 0; i < memlist.m_nseg; ++i) {
313 1.12 chopps printf("mem segment %d: start=%08lx size=%08lx"
314 1.12 chopps " attribute=%04lx pri=%d\n",
315 1.12 chopps i + 1, memlist.m_seg[i].ms_start,
316 1.12 chopps memlist.m_seg[i].ms_size,
317 1.12 chopps memlist.m_seg[i].ms_attrib,
318 1.12 chopps memlist.m_seg[i].ms_pri);
319 1.10 chopps }
320 1.17 jtc printf("kernel size: %d\n", ksize);
321 1.12 chopps }
322 1.12 chopps if (kp == NULL)
323 1.12 chopps err(20, "failed malloc %d\n", ksize);
324 1.12 chopps
325 1.12 chopps if (read(fd, kp, e.a_text) != e.a_text
326 1.12 chopps || read(fd, kp + textsz, e.a_data) != e.a_data)
327 1.12 chopps err(20, "unable to read kernel image\n");
328 1.12 chopps
329 1.12 chopps if (k_flag) {
330 1.12 chopps fmem += 4 * 1024 * 1024;
331 1.12 chopps fmemsz -= 4 * 1024 * 1024;
332 1.12 chopps }
333 1.1 mw
334 1.12 chopps if (reqmemsz && reqmemsz <= fmemsz)
335 1.12 chopps fmemsz = reqmemsz;
336 1.12 chopps if (boothowto & RB_AUTOBOOT)
337 1.12 chopps printf("Autobooting...");
338 1.12 chopps if (boothowto & RB_ASKNAME)
339 1.12 chopps printf("Askboot...");
340 1.12 chopps
341 1.12 chopps printf("Using %d%c FASTMEM at 0x%x, %dM CHIPMEM\n",
342 1.12 chopps (fmemsz & 0xfffff) ? fmemsz >> 10 : fmemsz >> 20,
343 1.12 chopps (fmemsz & 0xfffff) ? 'K' : 'M', fmem, cmemsz >> 20);
344 1.12 chopps kvers = (u_short *)(kp + e.a_entry - 2);
345 1.19 mhitch if (*kvers > KERNEL_STARTUP_VERSION_MAX && *kvers != 0x4e73)
346 1.12 chopps err(20, "newer loadbsd required: %d\n", *kvers);
347 1.19 mhitch if (*kvers > KERNEL_STARTUP_VERSION) {
348 1.17 jtc printf("****************************************************\n");
349 1.17 jtc printf("*** Notice: this kernel has features which require\n");
350 1.17 jtc printf("*** a newer version of loadbsd. To allow the use of\n");
351 1.17 jtc printf("*** any newer features or capabilities, you should\n");
352 1.19 mhitch printf("*** update to a newer version of loadbsd\n");
353 1.17 jtc printf("****************************************************\n");
354 1.17 jtc sleep(3); /* even more time to see that message */
355 1.17 jtc }
356 1.12 chopps if ((cpuid & AFB_68020) == 0)
357 1.12 chopps err(20, "cpu not supported");
358 1.12 chopps /*
359 1.12 chopps * give them a chance to read the information...
360 1.12 chopps */
361 1.12 chopps sleep(2);
362 1.12 chopps
363 1.12 chopps bzero(kp + textsz + e.a_data, e.a_bss);
364 1.12 chopps /*
365 1.12 chopps * If symbols wanted (and kernel can handle them),
366 1.12 chopps * load symbol table & strings and set esym to end.
367 1.12 chopps */
368 1.12 chopps nkcd = (int *)(kp + textsz + e.a_data + e.a_bss);
369 1.12 chopps if (*kvers != 0x4e73 && *kvers > 1 && S_flag && e.a_syms) {
370 1.12 chopps *nkcd++ = e.a_syms;
371 1.12 chopps read(fd, (char *)nkcd, e.a_syms);
372 1.12 chopps nkcd = (int *)((char *)nkcd + e.a_syms);
373 1.12 chopps read(fd, (char *)nkcd, stringsz);
374 1.19 mhitch nkcd = (int*)((char *)nkcd + ((stringsz + 3) & ~3));
375 1.12 chopps esym = (char *)(textsz + e.a_data + e.a_bss
376 1.19 mhitch + e.a_syms + 4 + ((stringsz + 3) & ~3));
377 1.10 chopps }
378 1.12 chopps *nkcd = ncd;
379 1.12 chopps
380 1.12 chopps kcd = (struct ConfigDev *)(nkcd + 1);
381 1.20 is while(cd = FindConfigDev(cd, -1, -1)) {
382 1.20 is *kcd = *cd;
383 1.20 is if (((cpuid >> 24) == 0x7d) &&
384 1.20 is ((u_long)kcd->cd_BoardAddr < 0x1000000)) {
385 1.20 is if (t_flag)
386 1.20 is printf("Transformed Z2 device from %08lx ",
387 1.20 is kcd->cd_BoardAddr);
388 1.20 is kcd->cd_BoardAddr += 0x3000000;
389 1.20 is
390 1.20 is if (t_flag)
391 1.20 is printf("to %08lx\n", kcd->cd_BoardAddr);
392 1.20 is }
393 1.20 is ++kcd;
394 1.20 is }
395 1.12 chopps
396 1.12 chopps kmemlist = (struct boot_memlist *)kcd;
397 1.12 chopps kmemlist->m_nseg = memlist.m_nseg;
398 1.12 chopps for (mem_ix = 0; mem_ix < memlist.m_nseg; mem_ix++)
399 1.12 chopps kmemlist->m_seg[mem_ix] = memlist.m_seg[mem_ix];
400 1.19 mhitch
401 1.19 mhitch if (*kvers > 2 && Z_flag == 0) {
402 1.19 mhitch /*
403 1.19 mhitch * Kernel supports direct load to fastmem, and the -Z
404 1.19 mhitch * option was not specified. Copy startup code to end
405 1.19 mhitch * of kernel image and set start_it.
406 1.19 mhitch */
407 1.20 is if ((void *)kp < fmem) {
408 1.20 is printf("Kernel at %08lx, Fastmem used at %08lx\n",
409 1.20 is kp, fmem);
410 1.22 is errx(20, "Can't copy upwards yet.\nDefragment your memory and try again OR try the -p OR try the -Z options.");
411 1.20 is }
412 1.19 mhitch memcpy(kp + ksize + 256, (char *)startit,
413 1.19 mhitch (char *)startit_end - (char *)startit);
414 1.19 mhitch CacheClearU();
415 1.19 mhitch start_it = (void (*)())kp + ksize + 256;
416 1.19 mhitch printf("*** Loading from %08lx to Fastmem %08lx ***\n",
417 1.19 mhitch kp, fmem);
418 1.19 mhitch sleep(2);
419 1.19 mhitch } else {
420 1.19 mhitch /*
421 1.19 mhitch * Either the kernel doesn't suppport loading directly to
422 1.19 mhitch * fastmem or the -Z flag was given. Verify kernel image
423 1.19 mhitch * fits into chipmem.
424 1.19 mhitch */
425 1.19 mhitch if (ksize >= cmemsz) {
426 1.19 mhitch printf("Kernel size %d exceeds Chip Memory of %d\n",
427 1.19 mhitch ksize, cmemsz);
428 1.19 mhitch err(20, "Insufficient Chip Memory for kernel");
429 1.19 mhitch }
430 1.19 mhitch Z_flag = 1;
431 1.24 is printf("*** Loading from %08lx to Chipmem ***\n", kp);
432 1.19 mhitch }
433 1.19 mhitch
434 1.12 chopps /*
435 1.12 chopps * if test option set, done
436 1.12 chopps */
437 1.20 is if (t_flag) {
438 1.20 is if (kp)
439 1.20 is FreeMem(kp, ksize + ((char *)startit_end
440 1.20 is - (char *)startit) + 256);
441 1.12 chopps exit(0);
442 1.20 is }
443 1.12 chopps
444 1.12 chopps /*
445 1.12 chopps * XXX AGA startup - may need more
446 1.12 chopps */
447 1.16 chopps LoadView(NULL); /* Don't do this if AGA active? */
448 1.19 mhitch start_it(kp, ksize, e.a_entry, fmem, fmemsz, cmemsz, boothowto, esym,
449 1.19 mhitch cpuid, eclock_freq, amiga_flags, I_flag, Z_flag == 0);
450 1.12 chopps /*NOTREACHED*/
451 1.12 chopps }
452 1.1 mw
453 1.1 mw void
454 1.12 chopps get_mem_config(fmem, fmemsz, cmemsz)
455 1.12 chopps void **fmem;
456 1.12 chopps u_long *fmemsz, *cmemsz;
457 1.1 mw {
458 1.12 chopps struct MemHeader *mh, *nmh;
459 1.20 is u_int segsz, seg, eseg, nmem, nseg, nsegsz;
460 1.20 is u_int tseg, tsegsz;
461 1.12 chopps char mempri;
462 1.12 chopps
463 1.12 chopps nmem = 0;
464 1.12 chopps mempri = -128;
465 1.12 chopps *fmemsz = 0;
466 1.12 chopps *cmemsz = 0;
467 1.12 chopps
468 1.12 chopps /*
469 1.12 chopps * walk thru the exec memory list
470 1.12 chopps */
471 1.12 chopps Forbid();
472 1.20 is for (mh = (void *) SysBase->MemList.lh_Head;
473 1.20 is nmh = (void *) mh->mh_Node.ln_Succ; mh = nmh) {
474 1.20 is
475 1.20 is nseg = (u_int)mh->mh_Lower;
476 1.20 is nsegsz = (u_int)mh->mh_Upper - nseg;
477 1.20 is
478 1.20 is segsz = nsegsz;
479 1.20 is seg = (u_int)CachePreDMA((APTR)nseg, (LONG *)&segsz, 0L);
480 1.20 is nsegsz -= segsz, nseg += segsz;
481 1.20 is for (;segsz;
482 1.20 is segsz = nsegsz,
483 1.20 is seg = (u_int)CachePreDMA((APTR)nseg, (LONG *)&segsz, DMA_Continue),
484 1.20 is nsegsz -= segsz, nseg += segsz, ++nmem) {
485 1.20 is
486 1.20 is if (t_flag)
487 1.20 is printf("Translated %08x sz %08x to %08x sz %08x\n",
488 1.20 is nseg - segsz, nsegsz + segsz, seg, segsz);
489 1.20 is
490 1.20 is eseg = seg + segsz;
491 1.20 is
492 1.20 is
493 1.20 is if ((cpuid >> 24) == 0x7D) {
494 1.20 is /* DraCo MMU table kludge */
495 1.20 is
496 1.20 is segsz = ((segsz -1) | 0xfffff) + 1;
497 1.20 is seg = eseg - segsz;
498 1.20 is
499 1.20 is /*
500 1.20 is * Only use first SIMM to boot; we know it is VA==PA.
501 1.20 is * Enter into table and continue. Yes,
502 1.20 is * this is ugly.
503 1.20 is */
504 1.20 is if (seg != 0x40000000) {
505 1.20 is memlist.m_seg[nmem].ms_attrib = mh->mh_Attributes;
506 1.20 is memlist.m_seg[nmem].ms_pri = mh->mh_Node.ln_Pri;
507 1.20 is memlist.m_seg[nmem].ms_size = segsz;
508 1.20 is memlist.m_seg[nmem].ms_start = seg;
509 1.20 is ++nmem;
510 1.20 is continue;
511 1.20 is }
512 1.20 is
513 1.20 is memlist.m_seg[nmem].ms_attrib = mh->mh_Attributes;
514 1.20 is memlist.m_seg[nmem].ms_pri = mh->mh_Node.ln_Pri;
515 1.20 is memlist.m_seg[nmem].ms_size = DRACOMMUMARGIN;
516 1.20 is memlist.m_seg[nmem].ms_start = seg;
517 1.20 is
518 1.20 is ++nmem;
519 1.20 is seg += DRACOMMUMARGIN;
520 1.20 is segsz -= DRACOMMUMARGIN;
521 1.20 is }
522 1.12 chopps
523 1.20 is memlist.m_seg[nmem].ms_attrib = mh->mh_Attributes;
524 1.20 is memlist.m_seg[nmem].ms_pri = mh->mh_Node.ln_Pri;
525 1.20 is memlist.m_seg[nmem].ms_size = segsz;
526 1.20 is memlist.m_seg[nmem].ms_start = seg;
527 1.20 is
528 1.20 is if ((mh->mh_Attributes & (MEMF_CHIP|MEMF_FAST)) == MEMF_CHIP) {
529 1.20 is /*
530 1.20 is * there should hardly be more than one entry for
531 1.20 is * chip mem, but handle it the same nevertheless
532 1.20 is * cmem always starts at 0, so include vector area
533 1.20 is */
534 1.20 is memlist.m_seg[nmem].ms_start = seg = 0;
535 1.20 is /*
536 1.20 is * round to multiple of 512K
537 1.20 is */
538 1.20 is segsz = (segsz + 512 * 1024 - 1) & -(512 * 1024);
539 1.20 is memlist.m_seg[nmem].ms_size = segsz;
540 1.20 is if (segsz > *cmemsz)
541 1.20 is *cmemsz = segsz;
542 1.20 is continue;
543 1.20 is }
544 1.12 chopps /*
545 1.20 is * some heuristics..
546 1.12 chopps */
547 1.20 is seg &= -__LDPGSZ;
548 1.20 is eseg = (eseg + __LDPGSZ - 1) & -__LDPGSZ;
549 1.20 is
550 1.12 chopps /*
551 1.20 is * get the mem back stolen by incore kickstart on
552 1.20 is * A3000 with V36 bootrom.
553 1.12 chopps */
554 1.20 is if (eseg == 0x07f80000)
555 1.20 is eseg = 0x08000000;
556 1.20 is
557 1.20 is /*
558 1.20 is * or by zkick on a A2000.
559 1.20 is */
560 1.20 is if (seg == 0x280000 &&
561 1.20 is strcmp(mh->mh_Node.ln_Name, "zkick memory") == 0)
562 1.20 is seg = 0x200000;
563 1.21 is /*
564 1.21 is * or by Fusion Forty fastrom
565 1.21 is */
566 1.21 is if ((seg & ~(1024*1024-1)) == 0x11000000) {
567 1.21 is /*
568 1.21 is * XXX we should test the name.
569 1.21 is * Unfortunately, the memory is just called
570 1.21 is * "32 bit memory" which isn't very specific.
571 1.21 is */
572 1.21 is seg = 0x11000000;
573 1.21 is }
574 1.20 is
575 1.20 is segsz = eseg - seg;
576 1.20 is memlist.m_seg[nmem].ms_start = seg;
577 1.12 chopps memlist.m_seg[nmem].ms_size = segsz;
578 1.20 is /*
579 1.20 is * If this segment is smaller than 2M,
580 1.20 is * don't use it to load the kernel
581 1.20 is */
582 1.20 is if (segsz < 2 * 1024 * 1024)
583 1.20 is continue;
584 1.20 is /*
585 1.20 is * if p_flag is set, select memory by priority
586 1.20 is * instead of size
587 1.20 is */
588 1.20 is if ((!p_flag && segsz > *fmemsz) || (p_flag &&
589 1.20 is mempri <= mh->mh_Node.ln_Pri && segsz > *fmemsz)) {
590 1.20 is *fmemsz = segsz;
591 1.20 is *fmem = (void *)seg;
592 1.20 is mempri = mh->mh_Node.ln_Pri;
593 1.20 is }
594 1.12 chopps
595 1.12 chopps }
596 1.1 mw }
597 1.12 chopps memlist.m_nseg = nmem;
598 1.12 chopps Permit();
599 1.1 mw }
600 1.1 mw
601 1.10 chopps /*
602 1.10 chopps * Try to determine the machine ID by searching the resident module list
603 1.10 chopps * for modules only present on specific machines. (Thanks, Bill!)
604 1.10 chopps */
605 1.10 chopps void
606 1.12 chopps get_cpuid()
607 1.10 chopps {
608 1.10 chopps u_long *rl;
609 1.10 chopps struct Resident *rm;
610 1.16 chopps struct Node *rn; /* Resource node entry */
611 1.10 chopps
612 1.11 chopps cpuid |= SysBase->AttnFlags; /* get FPU and CPU flags */
613 1.11 chopps if (cpuid & 0xffff0000) {
614 1.24 is if ((cpuid >> 24) == 0x7D)
615 1.20 is return;
616 1.20 is
617 1.11 chopps switch (cpuid >> 16) {
618 1.11 chopps case 500:
619 1.11 chopps case 600:
620 1.11 chopps case 1000:
621 1.11 chopps case 1200:
622 1.11 chopps case 2000:
623 1.11 chopps case 3000:
624 1.11 chopps case 4000:
625 1.11 chopps return;
626 1.11 chopps default:
627 1.12 chopps printf("machine Amiga %d is not recognized\n",
628 1.11 chopps cpuid >> 16);
629 1.12 chopps exit(1);
630 1.11 chopps }
631 1.11 chopps }
632 1.18 chopps if (FindResident("A4000 Bonus") || FindResident("A4000 bonus")
633 1.18 chopps || FindResident("A1000 Bonus"))
634 1.16 chopps cpuid |= 4000 << 16;
635 1.16 chopps else if (FindResident("A3000 Bonus") || FindResident("A3000 bonus"))
636 1.16 chopps cpuid |= 3000 << 16;
637 1.16 chopps else if (OpenResource("card.resource")) {
638 1.16 chopps /* Test for AGA? */
639 1.16 chopps cpuid |= 1200 << 16;
640 1.20 is } else if (OpenResource("draco.resource")) {
641 1.20 is cpuid |= (32000 | DRACOREVISION) << 16;
642 1.10 chopps }
643 1.12 chopps /*
644 1.12 chopps * Nothing found, it's probably an A2000 or A500
645 1.12 chopps */
646 1.16 chopps if ((cpuid >> 16) == 0)
647 1.10 chopps cpuid |= 2000 << 16;
648 1.10 chopps }
649 1.1 mw
650 1.12 chopps void
651 1.12 chopps get_eclock()
652 1.12 chopps {
653 1.12 chopps /* Fix for 1.3 startups? */
654 1.14 chopps if (SysBase->LibNode.lib_Version > 36)
655 1.14 chopps eclock_freq = SysBase->ex_EClockFrequency;
656 1.14 chopps else
657 1.14 chopps eclock_freq = (GfxBase->DisplayFlags & PAL) ?
658 1.14 chopps 709379 : 715909;
659 1.14 chopps }
660 1.14 chopps
661 1.14 chopps void
662 1.14 chopps get_AGA()
663 1.14 chopps {
664 1.14 chopps /*
665 1.14 chopps * Determine if an AGA mode is active
666 1.14 chopps */
667 1.12 chopps }
668 1.12 chopps
669 1.1 mw
670 1.12 chopps asm("
671 1.1 mw .set ABSEXECBASE,4
672 1.1 mw
673 1.1 mw .text
674 1.1 mw .globl _startit
675 1.1 mw
676 1.1 mw _startit:
677 1.1 mw movel sp,a3
678 1.1 mw movel 4:w,a6
679 1.20 is lea pc@(start_super),a5
680 1.1 mw jmp a6@(-0x1e) | supervisor-call
681 1.1 mw
682 1.1 mw start_super:
683 1.1 mw movew #0x2700,sr
684 1.1 mw
685 1.1 mw | the BSD kernel wants values into the following registers:
686 1.1 mw | a0: fastmem-start
687 1.1 mw | d0: fastmem-size
688 1.1 mw | d1: chipmem-size
689 1.16 chopps | d3: Amiga specific flags
690 1.12 chopps | d4: E clock frequency
691 1.5 mw | d5: AttnFlags (cpuid)
692 1.3 mw | d7: boothowto
693 1.8 chopps | a4: esym location
694 1.17 jtc | a2: Inhibit sync flags
695 1.10 chopps | All other registers zeroed for possible future requirements.
696 1.1 mw
697 1.20 is lea pc@(_startit),sp | make sure we have a good stack ***
698 1.20 is
699 1.1 mw movel a3@(4),a1 | loaded kernel
700 1.1 mw movel a3@(8),d2 | length of loaded kernel
701 1.14 chopps | movel a3@(12),sp | entry point in stack pointer
702 1.20 is movel a3@(12),a6 | push entry point ***
703 1.1 mw movel a3@(16),a0 | fastmem-start
704 1.1 mw movel a3@(20),d0 | fastmem-size
705 1.1 mw movel a3@(24),d1 | chipmem-size
706 1.3 mw movel a3@(28),d7 | boothowto
707 1.8 chopps movel a3@(32),a4 | esym
708 1.10 chopps movel a3@(36),d5 | cpuid
709 1.12 chopps movel a3@(40),d4 | E clock frequency
710 1.16 chopps movel a3@(44),d3 | Amiga flags
711 1.17 jtc movel a3@(48),a2 | Inhibit sync flags
712 1.19 mhitch movel a3@(52),d6 | Load to fastmem flag
713 1.8 chopps subl a5,a5 | target, load to 0
714 1.1 mw
715 1.20 is cmpb #0x7D,a3@(36) | is it DraCo?
716 1.20 is beq nott | yes, switch off MMU later
717 1.20 is
718 1.20 is | no, it is an Amiga:
719 1.20 is
720 1.20 is | movew #0xf00,0xdff180 |red
721 1.20 is | moveb #0,0x200003c8
722 1.20 is | moveb #63,0x200003c9
723 1.20 is | moveb #0,0x200003c9
724 1.20 is | moveb #0,0x200003c9
725 1.20 is
726 1.20 is movew #(1<<9),0xdff096 | disable DMA on Amigas.
727 1.20 is
728 1.20 is | ------ mmu off start -----
729 1.20 is
730 1.20 is btst #3,d5 | AFB_68040,SysBase->AttnFlags
731 1.5 mw beq not040
732 1.5 mw
733 1.20 is | Turn off 68040/060 MMU
734 1.5 mw
735 1.20 is subl a3,a3
736 1.20 is .word 0x4e7b,0xb003 | movec a3,tc
737 1.20 is .word 0x4e7b,0xb806 | movec a3,urp
738 1.20 is .word 0x4e7b,0xb807 | movec a3,srp
739 1.20 is .word 0x4e7b,0xb004 | movec a3,itt0
740 1.20 is .word 0x4e7b,0xb005 | movec a3,itt1
741 1.20 is .word 0x4e7b,0xb006 | movec a3,dtt0
742 1.20 is .word 0x4e7b,0xb007 | movec a3,dtt1
743 1.5 mw bra nott
744 1.5 mw
745 1.5 mw not040:
746 1.20 is lea pc@(zero),a3
747 1.1 mw pmove a3@,tc | Turn off MMU
748 1.20 is lea pc@(nullrp),a3
749 1.1 mw pmove a3@,crp | Turn off MMU some more
750 1.1 mw pmove a3@,srp | Really, really, turn off MMU
751 1.1 mw
752 1.1 mw | Turn off 68030 TT registers
753 1.1 mw
754 1.20 is btst #2,d5 | AFB_68030,SysBase->AttnFlags
755 1.1 mw beq nott | Skip TT registers if not 68030
756 1.20 is lea pc@(zero),a3
757 1.1 mw .word 0xf013,0x0800 | pmove a3@,tt0 (gas only knows about 68851 ops..)
758 1.1 mw .word 0xf013,0x0c00 | pmove a3@,tt1 (gas only knows about 68851 ops..)
759 1.1 mw
760 1.1 mw nott:
761 1.20 is | ---- mmu off end ----
762 1.20 is | movew #0xf60,0xdff180 | orange
763 1.20 is | moveb #0,0x200003c8
764 1.20 is | moveb #63,0x200003c9
765 1.20 is | moveb #24,0x200003c9
766 1.20 is | moveb #0,0x200003c9
767 1.1 mw
768 1.20 is | ---- copy kernel start ----
769 1.1 mw
770 1.19 mhitch tstl d6 | Can we load to fastmem?
771 1.19 mhitch beq L0 | No, leave destination at 0
772 1.19 mhitch movl a0,a5 | Move to start of fastmem chunk
773 1.20 is addl a0,a6 | relocate kernel entry point
774 1.1 mw L0:
775 1.19 mhitch movl a1@+,a5@+
776 1.19 mhitch subl #4,d2
777 1.1 mw bcc L0
778 1.1 mw
779 1.20 is lea pc@(ckend:w),a1
780 1.20 is movl a5,sp@-
781 1.20 is movl #_startit_end - ckend,d2
782 1.20 is L2:
783 1.20 is movl a1@+,a5@+
784 1.20 is subl #4,d2
785 1.20 is bcc L2
786 1.20 is
787 1.20 is btst #3,d5
788 1.20 is jeq L1
789 1.20 is .word 0xf4f8
790 1.20 is L1: movql #0,d2 | switch off cache to ensure we use
791 1.20 is movec d2,cacr | valid kernel data
792 1.20 is
793 1.20 is | movew #0xFF0,0xdff180 | yellow
794 1.20 is | moveb #0,0x200003c8
795 1.20 is | moveb #63,0x200003c9
796 1.20 is | moveb #0,0x200003c9
797 1.20 is | moveb #0,0x200003c9
798 1.20 is rts
799 1.20 is
800 1.21 is | ---- copy kernel end ----
801 1.20 is
802 1.20 is ckend:
803 1.20 is | movew #0x0ff,0xdff180 | petrol
804 1.20 is | moveb #0,0x200003c8
805 1.20 is | moveb #0,0x200003c9
806 1.20 is | moveb #63,0x200003c9
807 1.20 is | moveb #63,0x200003c9
808 1.20 is
809 1.20 is movl d5,d2
810 1.20 is roll #8,d2
811 1.20 is cmpb #0x7D,d2
812 1.20 is jne noDraCo
813 1.20 is
814 1.20 is | DraCo: switch off MMU now:
815 1.20 is
816 1.20 is subl a3,a3
817 1.20 is .word 0x4e7b,0xb003 | movec a3,tc
818 1.20 is .word 0x4e7b,0xb806 | movec a3,urp
819 1.20 is .word 0x4e7b,0xb807 | movec a3,srp
820 1.20 is .word 0x4e7b,0xb004 | movec a3,itt0
821 1.20 is .word 0x4e7b,0xb005 | movec a3,itt1
822 1.20 is .word 0x4e7b,0xb006 | movec a3,dtt0
823 1.20 is .word 0x4e7b,0xb007 | movec a3,dtt1
824 1.20 is
825 1.20 is noDraCo:
826 1.9 chopps moveq #0,d2 | zero out unused registers
827 1.14 chopps moveq #0,d6 | (might make future compatibility
828 1.14 chopps movel d6,a1 | would have known contents)
829 1.9 chopps movel d6,a3
830 1.9 chopps movel d6,a5
831 1.20 is movel a6,sp | entry point into stack pointer
832 1.9 chopps movel d6,a6
833 1.20 is
834 1.20 is | movew #0x0F0,0xdff180 | green
835 1.20 is | moveb #0,0x200003c8
836 1.20 is | moveb #0,0x200003c9
837 1.20 is | moveb #63,0x200003c9
838 1.20 is | moveb #0,0x200003c9
839 1.20 is
840 1.20 is jmp sp@ | jump to kernel entry point
841 1.1 mw
842 1.1 mw
843 1.1 mw | A do-nothing MMU root pointer (includes the following long as well)
844 1.1 mw
845 1.1 mw nullrp: .long 0x7fff0001
846 1.1 mw zero: .long 0
847 1.1 mw
848 1.19 mhitch _startit_end:
849 1.1 mw
850 1.1 mw ");
851 1.1 mw
852 1.12 chopps void
853 1.12 chopps usage()
854 1.6 chopps {
855 1.19 mhitch fprintf(stderr, "usage: %s [-abhkpstADSVZ] [-c machine] [-m mem] [-n mode] [-I sync-inhibit] kernel\n",
856 1.12 chopps program_name);
857 1.12 chopps exit(1);
858 1.6 chopps }
859 1.6 chopps
860 1.12 chopps
861 1.12 chopps void
862 1.12 chopps verbose_usage()
863 1.12 chopps {
864 1.12 chopps fprintf(stderr, "
865 1.12 chopps NAME
866 1.12 chopps \t%s - loads NetBSD from amiga dos.
867 1.12 chopps SYNOPSIS
868 1.19 mhitch \t%s [-abhkpstADSVZ] [-c machine] [-m mem] [-n flags] [-I sync-inhibit] kernel
869 1.12 chopps OPTIONS
870 1.12 chopps \t-a Boot up to multiuser mode.
871 1.17 jtc \t-A Use AGA display mode, if available.
872 1.12 chopps \t-b Ask for which root device.
873 1.12 chopps \t Its possible to have multiple roots and choose between them.
874 1.20 is \t-c Set machine type. [e.g 3000; use 32000+N for DraCo rev. N]
875 1.17 jtc \t-D Enter debugger
876 1.16 chopps \t-h This help message.
877 1.17 jtc \t-I Inhibit sync negotiation. Option value is bit-encoded targets.
878 1.12 chopps \t-k Reserve the first 4M of fast mem [Some one else
879 1.12 chopps \t is going to have to answer what that it is used for].
880 1.12 chopps \t-m Tweak amount of available memory, for finding minimum amount
881 1.12 chopps \t of memory required to run. Sets fastmem size to specified
882 1.12 chopps \t size in Kbytes.
883 1.16 chopps \t-n Enable multiple non-contiguous memory: value = 0 (disabled),
884 1.16 chopps \t 1 (two segments), 2 (all avail segments), 3 (same as 2?).
885 1.12 chopps \t-p Use highest priority fastmem segement instead of the largest
886 1.12 chopps \t segment. The higher priority segment is usually faster
887 1.12 chopps \t (i.e. 32 bit memory), but some people have smaller amounts
888 1.12 chopps \t of 32 bit memory.
889 1.25 jdolecek \t-q Boot up in quiet mode.
890 1.19 mhitch \t-s Boot up in singleuser mode (default).
891 1.17 jtc \t-S Include kernel symbol table.
892 1.12 chopps \t-t This is a *test* option. It prints out the memory
893 1.12 chopps \t list information being passed to the kernel and also
894 1.12 chopps \t exits without actually starting NetBSD.
895 1.25 jdolecek \t-v Boot up in verbose mode.
896 1.12 chopps \t-V Version of loadbsd program.
897 1.19 mhitch \t-Z Force kernel load to chipmem.
898 1.12 chopps HISTORY
899 1.12 chopps \tThis version supports Kernel version 720 +\n",
900 1.12 chopps program_name, program_name);
901 1.12 chopps exit(1);
902 1.12 chopps }
903 1.12 chopps
904 1.12 chopps
905 1.12 chopps void
906 1.12 chopps _Vdomessage(doexit, eval, doerrno, fmt, args)
907 1.12 chopps int doexit, doerrno, eval;
908 1.12 chopps const char *fmt;
909 1.12 chopps va_list args;
910 1.12 chopps {
911 1.12 chopps fprintf(stderr, "%s: ", program_name);
912 1.12 chopps if (fmt) {
913 1.12 chopps vfprintf(stderr, fmt, args);
914 1.12 chopps fprintf(stderr, ": ");
915 1.12 chopps }
916 1.12 chopps if (doerrno && errno < sys_nerr) {
917 1.12 chopps fprintf(stderr, "%s", strerror(errno));
918 1.20 is #if 0
919 1.12 chopps if (errno == EINTR || errno == 0) {
920 1.12 chopps int sigs;
921 1.12 chopps sigpending((sigset_t *)&sigs);
922 1.12 chopps printf("%x\n", sigs);
923 1.12 chopps }
924 1.20 is #endif
925 1.12 chopps }
926 1.12 chopps fprintf(stderr, "\n");
927 1.20 is if (doexit) {
928 1.20 is if (kp)
929 1.20 is FreeMem(kp, ksize + ((char *)startit_end
930 1.20 is - (char *)startit) + 256);
931 1.12 chopps exit(eval);
932 1.20 is }
933 1.12 chopps }
934 1.12 chopps
935 1.12 chopps void
936 1.12 chopps err(int eval, const char *fmt, ...)
937 1.12 chopps {
938 1.12 chopps va_list ap;
939 1.12 chopps va_start(ap, fmt);
940 1.12 chopps _Vdomessage(1, eval, 1, fmt, ap);
941 1.12 chopps /*NOTREACHED*/
942 1.12 chopps }
943 1.12 chopps
944 1.12 chopps void
945 1.12 chopps errx(int eval, const char *fmt, ...)
946 1.12 chopps {
947 1.12 chopps va_list ap;
948 1.12 chopps va_start(ap, fmt);
949 1.12 chopps _Vdomessage(1, eval, 0, fmt, ap);
950 1.12 chopps /*NOTREACHED*/
951 1.12 chopps }
952 1.12 chopps
953 1.12 chopps void
954 1.12 chopps warn(const char *fmt, ...)
955 1.12 chopps {
956 1.12 chopps va_list ap;
957 1.12 chopps va_start(ap, fmt);
958 1.12 chopps _Vdomessage(0, 0, 1, fmt, ap);
959 1.12 chopps va_end(ap);
960 1.12 chopps }
961 1.12 chopps
962 1.12 chopps void
963 1.12 chopps warnx(const char *fmt, ...)
964 1.6 chopps {
965 1.12 chopps va_list ap;
966 1.12 chopps va_start(ap, fmt);
967 1.12 chopps _Vdomessage(0, 0, 0, fmt, ap);
968 1.12 chopps va_end(ap);
969 1.20 is }
970 1.20 is
971 1.20 is
972 1.20 is u_int
973 1.20 is sleep(u_int n)
974 1.20 is {
975 1.20 is (void)TimeDelay(0L, n, 0L);
976 1.6 chopps }
977 1.21 is
978 1.21 is
979