xref: /openbsd/sys/arch/alpha/stand/bootxx.c (revision e3d38566)
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