1 /* $OpenBSD: bootxx.c,v 1.11 2023/01/16 07:29:32 deraadt Exp $ */
2 /* $NetBSD: bootxx.c,v 1.4 1997/01/18 00:28:59 cgd Exp $ */
3
4 /*
5 * Copyright (c) 1995 Carnegie-Mellon University.
6 * All rights reserved.
7 *
8 * Author: Chris G. Demetriou
9 *
10 * Permission to use, copy, modify and distribute this software and
11 * its documentation is hereby granted, provided that both the copyright
12 * notice and this permission notice appear in all copies of the
13 * software, derivative works or modified versions, and any portions
14 * thereof, and that both notices appear in supporting documentation.
15 *
16 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
18 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19 *
20 * Carnegie Mellon requests users of this software to return to
21 *
22 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
23 * School of Computer Science
24 * Carnegie Mellon University
25 * Pittsburgh PA 15213-3890
26 *
27 * any improvements or extensions that they make and grant Carnegie the
28 * rights to redistribute these changes.
29 */
30
31 #include <sys/param.h>
32 #include <machine/rpb.h>
33 #include <machine/prom.h>
34
35 #include "bbinfo.h"
36
37 extern long _end, start;
38
39 struct bbinfoloc desc = {
40 0xbabefacedeadbeef,
41 (u_int64_t)&start,
42 (u_int64_t)&_end,
43 { 0, },
44 0xdeadbeeffacebabe
45 };
46
47 int
open_dev(fd)48 open_dev(fd)
49 int *fd;
50 {
51 prom_return_t ret;
52 char devname[64];
53 int devlen;
54
55 /*
56 * XXX
57 * We don't know what device names look like yet,
58 * so we can't change them.
59 */
60 ret.bits = prom_getenv(PROM_E_BOOTED_DEV, devname, sizeof(devname));
61 devlen = ret.u.retval;
62
63 ret.bits = prom_open((u_int64_t)devname, devlen);
64 if (ret.u.status)
65 return 0;
66
67 *fd = ret.u.retval;
68
69 return 1;
70 }
71
72 void puts(char *);
73
74 int
load_file(bbinfop,loadaddr)75 load_file(bbinfop, loadaddr)
76 struct bbinfo *bbinfop;
77 char *loadaddr;
78 {
79 prom_return_t ret;
80 int32_t cksum, *int32p;
81 int i, n, fd, rv;
82 char *cp;
83
84 if (bbinfop->nblocks <= 0) {
85 puts("invalid number of blocks in boot program description\n");
86 return 0;
87 }
88 if (bbinfop->bsize < DEV_BSIZE || bbinfop->bsize > MAXBSIZE) {
89 puts("invalid block size in boot program description\n");
90 return 0;
91 }
92
93 int32p = (int32_t *)&_end;
94 n = bbinfop->nblocks +
95 (sizeof(*bbinfop) / sizeof(bbinfop->blocks[0])) - 1;
96 if ((long)&_end - (long)&start + sizeof(bbinfop->blocks[0]) * n >
97 15 * 512) {
98 puts("way too many blocks\n");
99 return 0;
100 }
101
102 for (i = 0, cksum = 0; i < n; i++)
103 cksum += *int32p++;
104 if (cksum != 0) {
105 puts("invalid checksum in boot program description\n");
106 return 0;
107 }
108
109 if (!open_dev(&fd)) {
110 puts("couldn't open disk device\n");
111 return 0;
112 }
113
114 cp = loadaddr;
115 rv = 1;
116 for (i = 0; i < bbinfop->nblocks; i++) {
117 puts(".");
118 ret.bits = prom_read(fd, bbinfop->bsize, cp,
119 bbinfop->blocks[i]);
120 puts("\b");
121 if (ret.u.status) {
122 rv = 0;
123 puts("BLOCK READ ERROR!\n");
124 break;
125 }
126 cp += bbinfop->bsize;
127 }
128 prom_close(fd);
129
130 return (rv);
131 }
132
133 void init_prom_calls(void);
134
135 int
main()136 main()
137 {
138 struct bbinfo *bbinfop;
139 char *loadaddr;
140 void (*entry)(void);
141
142 /* Init prom callback vector. */
143 init_prom_calls();
144
145 puts("\nOpenBSD/Alpha Primary Boot\n");
146
147 bbinfop = (struct bbinfo *)&_end;
148 loadaddr = (char *)SECONDARY_LOAD_ADDRESS;
149 if (!load_file(bbinfop, loadaddr)) {
150 puts("\nLOAD FAILED!\n\n");
151 return 1;
152 }
153
154 #if 0
155 puts("Jumping to entry point...\n");
156 #endif
157 entry = (void (*)())loadaddr;
158 (*entry)();
159 puts("SECONDARY BOOT BLOCK RETURNED!\n");
160 return 1;
161 }
162
163