main.c revision 1.1.10.2 1 1.1.10.2 tls /* $NetBSD: main.c,v 1.1.10.2 2014/08/20 00:03:05 tls Exp $ */
2 1.1.10.2 tls
3 1.1.10.2 tls /*
4 1.1.10.2 tls * Copyright (c) 2003 ITOH Yasufumi.
5 1.1.10.2 tls * All rights reserved.
6 1.1.10.2 tls *
7 1.1.10.2 tls * Redistribution and use in source and binary forms, with or without
8 1.1.10.2 tls * modification, are permitted provided that the following conditions
9 1.1.10.2 tls * are met:
10 1.1.10.2 tls * 1. Redistributions of source code must retain the above copyright
11 1.1.10.2 tls * notice, this list of conditions and the following disclaimer.
12 1.1.10.2 tls * 2. Redistributions in binary forms are unlimited.
13 1.1.10.2 tls *
14 1.1.10.2 tls * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS''
15 1.1.10.2 tls * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 1.1.10.2 tls * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 1.1.10.2 tls * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS
18 1.1.10.2 tls * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 1.1.10.2 tls * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 1.1.10.2 tls * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 1.1.10.2 tls * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 1.1.10.2 tls * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 1.1.10.2 tls * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 1.1.10.2 tls * THE POSSIBILITY OF SUCH DAMAGE.
25 1.1.10.2 tls */
26 1.1.10.2 tls
27 1.1.10.2 tls #include <sys/types.h>
28 1.1.10.2 tls #include <sys/param.h>
29 1.1.10.2 tls #include <ufs/ufs/dinode.h>
30 1.1.10.2 tls #include <sys/disklabel.h>
31 1.1.10.2 tls #include <sys/exec_elf.h>
32 1.1.10.2 tls #include "readufs.h"
33 1.1.10.2 tls
34 1.1.10.2 tls #define STACK_SIZE ((unsigned) (64*1024))
35 1.1.10.2 tls #define LOAD_ALIGN ((unsigned) 2048)
36 1.1.10.2 tls
37 1.1.10.2 tls #define PZ_MEM_BOOT 0x3d0
38 1.1.10.2 tls #define DEV_CLASS 0x2c
39 1.1.10.2 tls #define DEV_CL_MASK 0xf
40 1.1.10.2 tls #define DEV_CL_SEQU 0x2 /* sequential record access media */
41 1.1.10.2 tls
42 1.1.10.2 tls static char *hexstr(char *, unsigned);
43 1.1.10.2 tls void ipl_main(unsigned /*interactive*/, unsigned /*sptop*/, unsigned /*psw*/);
44 1.1.10.2 tls void load_file(const char *, uintptr_t /*loadadr*/, unsigned /*interactive*/,
45 1.1.10.2 tls int /*part*/);
46 1.1.10.2 tls void load_file_ino(ino32_t, const char *, uintptr_t /*loadadr*/,
47 1.1.10.2 tls unsigned /*interactive*/, int /*part*/);
48 1.1.10.2 tls
49 1.1.10.2 tls struct loadinfo {
50 1.1.10.2 tls void *sec_image;
51 1.1.10.2 tls unsigned sec_size;
52 1.1.10.2 tls #if 0
53 1.1.10.2 tls unsigned sec_pad;
54 1.1.10.2 tls #endif
55 1.1.10.2 tls unsigned entry_offset;
56 1.1.10.2 tls };
57 1.1.10.2 tls static inline void xi_elf32(struct loadinfo *, Elf32_Ehdr *);
58 1.1.10.2 tls static inline void xi_elf64(struct loadinfo *, Elf64_Ehdr *);
59 1.1.10.2 tls int xi_load(struct loadinfo *, void *);
60 1.1.10.2 tls
61 1.1.10.2 tls void reboot(void);
62 1.1.10.2 tls void halt(void);
63 1.1.10.2 tls void dispatch(unsigned /*interactive*/, unsigned /*top*/,
64 1.1.10.2 tls unsigned /*end*/, int /*part*/, unsigned /*entry*/);
65 1.1.10.2 tls void print(const char *);
66 1.1.10.2 tls void putch(int);
67 1.1.10.2 tls int getch(void);
68 1.1.10.2 tls int boot_input(void *, int /*len*/, int /*pos*/);
69 1.1.10.2 tls
70 1.1.10.2 tls /* to make generated code relocatable, do NOT mark them as const */
71 1.1.10.2 tls extern char str_seekseq[], str_bit_firmware[];
72 1.1.10.2 tls extern char str_crlf[], str_space[], str_rubout[];
73 1.1.10.2 tls extern char str_bootpart[], str_booting_part[];
74 1.1.10.2 tls extern char str_warn_2GB[], str_warn_unused[], str_nolabel[];
75 1.1.10.2 tls extern char str_filesystem[], str_nofs[];
76 1.1.10.2 tls extern char str_lookup[], str_loading[], str_at[], str_dddot[], str_done[];
77 1.1.10.2 tls extern char str_boot1[], str_boot2[], str_boot3[];
78 1.1.10.2 tls extern char str_noboot[];
79 1.1.10.2 tls extern char str_ukfmt[];
80 1.1.10.2 tls
81 1.1.10.2 tls #ifdef __GNUC__
82 1.1.10.2 tls #define memcpy(d, s, n) __builtin_memcpy(d, s, n)
83 1.1.10.2 tls #else
84 1.1.10.2 tls void *memcpy(void *, const void *, size_t);
85 1.1.10.2 tls #endif
86 1.1.10.2 tls void *memmove(void *, const void *, size_t);
87 1.1.10.2 tls
88 1.1.10.2 tls /* disklabel */
89 1.1.10.2 tls union {
90 1.1.10.2 tls char dklsec[512];
91 1.1.10.2 tls struct disklabel dkl; /* to ensure alignment */
92 1.1.10.2 tls } labelsector;
93 1.1.10.2 tls #define dklabel (*(struct disklabel *)(labelsector.dklsec + LABELOFFSET))
94 1.1.10.2 tls
95 1.1.10.2 tls unsigned offset_raw_read;
96 1.1.10.2 tls
97 1.1.10.2 tls extern char diskbuf[2048];
98 1.1.10.2 tls #define BLK_PER_READ 4
99 1.1.10.2 tls #define MASK_BLK_PER_READ (BLK_PER_READ - 1)
100 1.1.10.2 tls
101 1.1.10.2 tls void
102 1.1.10.2 tls RAW_READ(void *buf, daddr_t blkpos, size_t bytelen)
103 1.1.10.2 tls {
104 1.1.10.2 tls char *b = buf;
105 1.1.10.2 tls size_t off, readlen;
106 1.1.10.2 tls int devoff;
107 1.1.10.2 tls static int prvdevoff = -dbtob(BLK_PER_READ);
108 1.1.10.2 tls int pos;
109 1.1.10.2 tls
110 1.1.10.2 tls for ( ; bytelen > 0; b += readlen, bytelen -= readlen) {
111 1.1.10.2 tls /*
112 1.1.10.2 tls * read 2KB, avoiding unneeded read
113 1.1.10.2 tls */
114 1.1.10.2 tls devoff = dbtob(blkpos & ~MASK_BLK_PER_READ) + offset_raw_read;
115 1.1.10.2 tls if (prvdevoff != devoff) {
116 1.1.10.2 tls #if 1 /* supports sequential media */
117 1.1.10.2 tls if ((*(unsigned *)(PZ_MEM_BOOT+DEV_CLASS) & DEV_CL_MASK)
118 1.1.10.2 tls == DEV_CL_SEQU) {
119 1.1.10.2 tls /*
120 1.1.10.2 tls * sequential media
121 1.1.10.2 tls * -- read sequentially or rewind
122 1.1.10.2 tls */
123 1.1.10.2 tls pos = prvdevoff + dbtob(BLK_PER_READ);
124 1.1.10.2 tls if (devoff < pos)
125 1.1.10.2 tls pos = 0; /* rewind */
126 1.1.10.2 tls
127 1.1.10.2 tls /* "repositioning media...\r\n" */
128 1.1.10.2 tls if (devoff - pos > 512 * 1024)
129 1.1.10.2 tls print(str_seekseq);
130 1.1.10.2 tls
131 1.1.10.2 tls for (; pos < devoff; pos += dbtob(BLK_PER_READ))
132 1.1.10.2 tls boot_input(diskbuf,
133 1.1.10.2 tls dbtob(BLK_PER_READ), pos);
134 1.1.10.2 tls }
135 1.1.10.2 tls #endif
136 1.1.10.2 tls prvdevoff = devoff;
137 1.1.10.2 tls boot_input(diskbuf, dbtob(BLK_PER_READ), devoff);
138 1.1.10.2 tls }
139 1.1.10.2 tls /*
140 1.1.10.2 tls * copy specified size to the destination
141 1.1.10.2 tls */
142 1.1.10.2 tls off = dbtob(blkpos & MASK_BLK_PER_READ),
143 1.1.10.2 tls readlen = dbtob(BLK_PER_READ) - off;
144 1.1.10.2 tls if (readlen > bytelen)
145 1.1.10.2 tls readlen = bytelen;
146 1.1.10.2 tls memcpy(b, diskbuf + off, readlen);
147 1.1.10.2 tls blkpos = (blkpos & ~MASK_BLK_PER_READ) + BLK_PER_READ;
148 1.1.10.2 tls }
149 1.1.10.2 tls }
150 1.1.10.2 tls
151 1.1.10.2 tls /*
152 1.1.10.2 tls * convert number to hex string
153 1.1.10.2 tls * buf must have enough space
154 1.1.10.2 tls */
155 1.1.10.2 tls static char *
156 1.1.10.2 tls hexstr(char *buf, unsigned val)
157 1.1.10.2 tls {
158 1.1.10.2 tls unsigned v;
159 1.1.10.2 tls char rev[16];
160 1.1.10.2 tls char *r = rev, *b = buf;
161 1.1.10.2 tls
162 1.1.10.2 tls /* inverse order */
163 1.1.10.2 tls do {
164 1.1.10.2 tls v = val & 0xf;
165 1.1.10.2 tls *r++ = (v <= 9) ? '0' + v : 'a' - 10 + v;
166 1.1.10.2 tls val >>= 4;
167 1.1.10.2 tls } while (val);
168 1.1.10.2 tls
169 1.1.10.2 tls /* reverse string */
170 1.1.10.2 tls while (r > rev)
171 1.1.10.2 tls *b++ = *--r;
172 1.1.10.2 tls
173 1.1.10.2 tls *b = '\0';
174 1.1.10.2 tls return buf;
175 1.1.10.2 tls }
176 1.1.10.2 tls
177 1.1.10.2 tls void
178 1.1.10.2 tls ipl_main(unsigned interactive, unsigned sptop, unsigned psw)
179 1.1.10.2 tls /* interactive: parameters from PDC */
180 1.1.10.2 tls /* sptop: value of sp on function entry */
181 1.1.10.2 tls /* psw: PSW on startup */
182 1.1.10.2 tls {
183 1.1.10.2 tls char buf[32];
184 1.1.10.2 tls int part = 0; /* default partition "a" */
185 1.1.10.2 tls unsigned secsz, partoff, partsz;
186 1.1.10.2 tls int c, c1;
187 1.1.10.2 tls uintptr_t loadadr;
188 1.1.10.2 tls
189 1.1.10.2 tls #if 0
190 1.1.10.2 tls print(hexstr(buf, interactive));
191 1.1.10.2 tls print(str_crlf);
192 1.1.10.2 tls print(hexstr(buf, sptop));
193 1.1.10.2 tls print(str_crlf);
194 1.1.10.2 tls print(hexstr(buf, psw));
195 1.1.10.2 tls print(str_crlf);
196 1.1.10.2 tls #endif
197 1.1.10.2 tls
198 1.1.10.2 tls print(hexstr(buf, (psw & 0x08000000) ? (unsigned) 0x64 : 0x32));
199 1.1.10.2 tls print(str_bit_firmware); /* "bit firmware\r\n" */
200 1.1.10.2 tls
201 1.1.10.2 tls /*
202 1.1.10.2 tls * check disklabel
203 1.1.10.2 tls * (dklabel has disklabel on startup)
204 1.1.10.2 tls */
205 1.1.10.2 tls if (dklabel.d_magic == DISKMAGIC && (secsz = dklabel.d_secsize) != 0) {
206 1.1.10.2 tls /*
207 1.1.10.2 tls * select boot partition
208 1.1.10.2 tls */
209 1.1.10.2 tls if (interactive) {
210 1.1.10.2 tls select_partition:
211 1.1.10.2 tls /* "boot partition (a-p, ! to reboot) [a]:" */
212 1.1.10.2 tls print(str_bootpart);
213 1.1.10.2 tls part = 0; /* default partition "a" */
214 1.1.10.2 tls c1 = 0;
215 1.1.10.2 tls while ((c = getch()) >= 0) {
216 1.1.10.2 tls switch (c) {
217 1.1.10.2 tls case '\n':
218 1.1.10.2 tls case '\r':
219 1.1.10.2 tls goto break_while;
220 1.1.10.2 tls case '\b':
221 1.1.10.2 tls case '\177':
222 1.1.10.2 tls if (c1) {
223 1.1.10.2 tls print(str_rubout);
224 1.1.10.2 tls part = c1 = 0;
225 1.1.10.2 tls }
226 1.1.10.2 tls break;
227 1.1.10.2 tls case '!': /* reset */
228 1.1.10.2 tls if (c1 == 0) {
229 1.1.10.2 tls part = -1;
230 1.1.10.2 tls goto echoback;
231 1.1.10.2 tls }
232 1.1.10.2 tls break;
233 1.1.10.2 tls default:
234 1.1.10.2 tls if (c1 == 0 && c >= 'a' && c <= 'p') {
235 1.1.10.2 tls part = c - 'a';
236 1.1.10.2 tls echoback:
237 1.1.10.2 tls putch(c);
238 1.1.10.2 tls c1 = 1;
239 1.1.10.2 tls }
240 1.1.10.2 tls break;
241 1.1.10.2 tls }
242 1.1.10.2 tls }
243 1.1.10.2 tls break_while:
244 1.1.10.2 tls if (part == -1)
245 1.1.10.2 tls return; /* reset */
246 1.1.10.2 tls }
247 1.1.10.2 tls
248 1.1.10.2 tls /*
249 1.1.10.2 tls * "\r\nbooting from partition _\r\n"
250 1.1.10.2 tls */
251 1.1.10.2 tls str_booting_part[25] = 'a' + part;
252 1.1.10.2 tls print(str_booting_part);
253 1.1.10.2 tls
254 1.1.10.2 tls partoff = dklabel.d_partitions[part].p_offset;
255 1.1.10.2 tls partsz = dklabel.d_partitions[part].p_size;
256 1.1.10.2 tls
257 1.1.10.2 tls if (part >= (int) dklabel.d_npartitions || partsz == 0) {
258 1.1.10.2 tls print(str_warn_unused); /* "unused partition\r\n" */
259 1.1.10.2 tls goto select_partition;
260 1.1.10.2 tls }
261 1.1.10.2 tls
262 1.1.10.2 tls /* boot partition must be below 2GB */
263 1.1.10.2 tls if (partoff + partsz > ((unsigned)2*1024*1024*1024) / secsz) {
264 1.1.10.2 tls /* "boot partition exceeds 2GB boundary\r\n" */
265 1.1.10.2 tls print(str_warn_2GB);
266 1.1.10.2 tls goto select_partition;
267 1.1.10.2 tls }
268 1.1.10.2 tls
269 1.1.10.2 tls /*
270 1.1.10.2 tls * following device accesses are only in the partition
271 1.1.10.2 tls */
272 1.1.10.2 tls offset_raw_read = partoff * secsz;
273 1.1.10.2 tls } else {
274 1.1.10.2 tls /*
275 1.1.10.2 tls * no disklabel --- assume the whole of the device
276 1.1.10.2 tls * is a filesystem
277 1.1.10.2 tls */
278 1.1.10.2 tls print(str_nolabel); /* "no disklabel\r\n" */
279 1.1.10.2 tls }
280 1.1.10.2 tls
281 1.1.10.2 tls if (ufs_init()) {
282 1.1.10.2 tls print(str_nofs); /* "no filesystem found\r\n" */
283 1.1.10.2 tls return;
284 1.1.10.2 tls }
285 1.1.10.2 tls str_filesystem[12] = (ufs_info.fstype == UFSTYPE_FFS) ? 'F' : 'L';
286 1.1.10.2 tls print(str_filesystem); /* "filesystem: _FS\r\n" */
287 1.1.10.2 tls
288 1.1.10.2 tls loadadr = (sptop + STACK_SIZE + LOAD_ALIGN - 1) & (-LOAD_ALIGN);
289 1.1.10.2 tls load_file(str_boot1, loadadr, interactive, part); /* "boot.hp700" */
290 1.1.10.2 tls load_file(str_boot2, loadadr, interactive, part); /* "boot" */
291 1.1.10.2 tls load_file(str_boot3, loadadr, interactive, part); /* "usr/mdec/boot" */
292 1.1.10.2 tls
293 1.1.10.2 tls print(str_noboot); /* "no secondary boot found\r\n" */
294 1.1.10.2 tls }
295 1.1.10.2 tls
296 1.1.10.2 tls void
297 1.1.10.2 tls load_file(const char *path, uintptr_t loadadr, unsigned interactive, int part)
298 1.1.10.2 tls {
299 1.1.10.2 tls
300 1.1.10.2 tls /* look-up the file */
301 1.1.10.2 tls print(str_lookup); /* "looking up " */
302 1.1.10.2 tls print(path);
303 1.1.10.2 tls print(str_crlf);
304 1.1.10.2 tls load_file_ino(ufs_lookup_path(path), path, loadadr, interactive, part);
305 1.1.10.2 tls }
306 1.1.10.2 tls
307 1.1.10.2 tls void
308 1.1.10.2 tls load_file_ino(ino32_t ino, const char *fn, uintptr_t loadadr, unsigned interactive, int part)
309 1.1.10.2 tls /* fn: for message only */
310 1.1.10.2 tls {
311 1.1.10.2 tls union ufs_dinode dinode;
312 1.1.10.2 tls size_t sz;
313 1.1.10.2 tls struct loadinfo inf;
314 1.1.10.2 tls char buf[32];
315 1.1.10.2 tls
316 1.1.10.2 tls if (ino == 0 || ufs_get_inode(ino, &dinode))
317 1.1.10.2 tls return; /* not found */
318 1.1.10.2 tls
319 1.1.10.2 tls print(str_loading); /* "loading " */
320 1.1.10.2 tls print(fn);
321 1.1.10.2 tls print(str_at); /* " at 0x" */
322 1.1.10.2 tls print(hexstr(buf, loadadr));
323 1.1.10.2 tls print(str_dddot); /* "..." */
324 1.1.10.2 tls
325 1.1.10.2 tls sz = DI_SIZE(&dinode);
326 1.1.10.2 tls ufs_read(&dinode, (void *) loadadr, 0, sz);
327 1.1.10.2 tls
328 1.1.10.2 tls print(str_done); /* "done\r\n" */
329 1.1.10.2 tls
330 1.1.10.2 tls /* digest executable format */
331 1.1.10.2 tls inf.sec_size = sz;
332 1.1.10.2 tls inf.entry_offset = 0;
333 1.1.10.2 tls if (xi_load(&inf, (void *) loadadr)) {
334 1.1.10.2 tls print(fn);
335 1.1.10.2 tls print(str_ukfmt); /* ": unknown format -- exec from top\r\n" */
336 1.1.10.2 tls }
337 1.1.10.2 tls
338 1.1.10.2 tls /* pass control to the secondary boot */
339 1.1.10.2 tls dispatch(interactive, loadadr, loadadr + inf.sec_size, part,
340 1.1.10.2 tls loadadr + inf.entry_offset);
341 1.1.10.2 tls }
342 1.1.10.2 tls
343 1.1.10.2 tls /*
344 1.1.10.2 tls * fill in loading information from an ELF executable
345 1.1.10.2 tls */
346 1.1.10.2 tls static inline void
347 1.1.10.2 tls xi_elf32(struct loadinfo *inf, Elf32_Ehdr *hdr)
348 1.1.10.2 tls {
349 1.1.10.2 tls char *top = (void *) hdr;
350 1.1.10.2 tls Elf32_Phdr *ph;
351 1.1.10.2 tls
352 1.1.10.2 tls /* text + data, bss */
353 1.1.10.2 tls ph = (void *) (top + hdr->e_phoff);
354 1.1.10.2 tls inf->sec_image = top + ph->p_offset;
355 1.1.10.2 tls inf->sec_size = ph->p_filesz;
356 1.1.10.2 tls #if 0
357 1.1.10.2 tls inf->sec_pad = ph->p_memsz - ph->p_filesz;
358 1.1.10.2 tls #endif
359 1.1.10.2 tls /* entry */
360 1.1.10.2 tls inf->entry_offset = hdr->e_entry - ph->p_vaddr;
361 1.1.10.2 tls }
362 1.1.10.2 tls
363 1.1.10.2 tls static inline void
364 1.1.10.2 tls xi_elf64(struct loadinfo *inf, Elf64_Ehdr *hdr)
365 1.1.10.2 tls {
366 1.1.10.2 tls char *top = (void *) hdr;
367 1.1.10.2 tls Elf64_Phdr *ph;
368 1.1.10.2 tls
369 1.1.10.2 tls /*
370 1.1.10.2 tls * secondary boot is not so large, so 32bit (unsigned) arithmetic
371 1.1.10.2 tls * is enough
372 1.1.10.2 tls */
373 1.1.10.2 tls /* text + data, bss */
374 1.1.10.2 tls ph = (void *) (top + (unsigned) hdr->e_phoff);
375 1.1.10.2 tls inf->sec_image = top + (unsigned) ph->p_offset;
376 1.1.10.2 tls inf->sec_size = (unsigned) ph->p_filesz;
377 1.1.10.2 tls #if 0
378 1.1.10.2 tls inf->sec_pad = (unsigned) ph->p_memsz - (unsigned) ph->p_filesz;
379 1.1.10.2 tls #endif
380 1.1.10.2 tls /* entry */
381 1.1.10.2 tls inf->entry_offset = (unsigned) hdr->e_entry - (unsigned) ph->p_vaddr;
382 1.1.10.2 tls }
383 1.1.10.2 tls
384 1.1.10.2 tls int
385 1.1.10.2 tls xi_load(struct loadinfo *inf, void *buf)
386 1.1.10.2 tls {
387 1.1.10.2 tls Elf32_Ehdr *e32hdr = buf;
388 1.1.10.2 tls Elf64_Ehdr *e64hdr = buf;
389 1.1.10.2 tls uint16_t class_data;
390 1.1.10.2 tls
391 1.1.10.2 tls /*
392 1.1.10.2 tls * check ELF header
393 1.1.10.2 tls * (optimized assuming big endian byte order)
394 1.1.10.2 tls */
395 1.1.10.2 tls /* ELF magic */
396 1.1.10.2 tls if (*(uint32_t *)&e32hdr->e_ident[EI_MAG0] !=
397 1.1.10.2 tls (ELFMAG0 << 24 | ELFMAG1 << 16 | ELFMAG2 << 8 | ELFMAG3) ||
398 1.1.10.2 tls e32hdr->e_ident[EI_VERSION] != EV_CURRENT)
399 1.1.10.2 tls return 1; /* Not an ELF */
400 1.1.10.2 tls
401 1.1.10.2 tls /* file and machine type */
402 1.1.10.2 tls if (*(uint32_t *)&e32hdr->e_type != (ET_EXEC << 16 | EM_PARISC))
403 1.1.10.2 tls return 1; /* Not an executable / Wrong architecture */
404 1.1.10.2 tls
405 1.1.10.2 tls if ((class_data = *(uint16_t *)&e32hdr->e_ident[EI_CLASS]) ==
406 1.1.10.2 tls (ELFCLASS32 << 8 | ELFDATA2MSB)) {
407 1.1.10.2 tls
408 1.1.10.2 tls /* support one section executable (ld -N) only */
409 1.1.10.2 tls if (e32hdr->e_phnum != 1)
410 1.1.10.2 tls return 1; /* Wrong number of loading sections */
411 1.1.10.2 tls
412 1.1.10.2 tls /* fill in loading information */
413 1.1.10.2 tls xi_elf32(inf, e32hdr);
414 1.1.10.2 tls
415 1.1.10.2 tls } else if (class_data == (ELFCLASS64 << 8 | ELFDATA2MSB)) {
416 1.1.10.2 tls
417 1.1.10.2 tls /* support one section executable (ld -N) only */
418 1.1.10.2 tls if (e64hdr->e_phnum != 1)
419 1.1.10.2 tls return 1; /* Wrong number of loading sections */
420 1.1.10.2 tls
421 1.1.10.2 tls /* fill in loading information */
422 1.1.10.2 tls xi_elf64(inf, e64hdr);
423 1.1.10.2 tls
424 1.1.10.2 tls } else
425 1.1.10.2 tls return 1; /* Not a 32bit or 64bit ELF */
426 1.1.10.2 tls
427 1.1.10.2 tls /* move text + data to the top address */
428 1.1.10.2 tls memmove(buf, inf->sec_image, inf->sec_size);
429 1.1.10.2 tls
430 1.1.10.2 tls #if 0 /* XXX bss clear is done by the secondary boot itself */
431 1.1.10.2 tls memset((char *) buf + inf->sec_size, 0, inf->sec_pad);
432 1.1.10.2 tls #endif
433 1.1.10.2 tls
434 1.1.10.2 tls return 0;
435 1.1.10.2 tls }
436