xref: /openbsd/sys/arch/alpha/stand/bootxx.c (revision e5dd7070)
1 /*	$OpenBSD: bootxx.c,v 1.10 2004/07/05 19:59:17 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 _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
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(devname, devlen);
64         if (ret.u.status)
65                 return 0;
66 
67 	*fd = ret.u.retval;
68 
69 	return 1;
70 }
71 
72 int
73 load_file(bbinfop, loadaddr)
74 	struct bbinfo *bbinfop;
75 	char *loadaddr;
76 {
77 	prom_return_t ret;
78 	int32_t cksum, *int32p;
79 	int i, n, fd, rv;
80 	char *cp;
81 
82 	if (bbinfop->nblocks <= 0) {
83 		puts("invalid number of blocks in boot program description\n");
84 		return 0;
85 	}
86 	if (bbinfop->bsize < DEV_BSIZE || bbinfop->bsize > MAXBSIZE) {
87 		puts("invalid block size in boot program description\n");
88 		return 0;
89 	}
90 
91 	int32p = (int32_t *)&_end;
92 	n = bbinfop->nblocks +
93 	    (sizeof(*bbinfop) / sizeof(bbinfop->blocks[0])) - 1;
94 	if ((long)&_end - (long)&start + sizeof(bbinfop->blocks[0]) * n >
95 	    15 * 512) {
96 		puts("way too many blocks\n");
97 		return 0;
98 	}
99 
100 	for (i = 0, cksum = 0; i < n; i++)
101 		cksum += *int32p++;
102 	if (cksum != 0) {
103 		puts("invalid checksum in boot program description\n");
104 		return 0;
105 	}
106 
107 	if (!open_dev(&fd)) {
108 		puts("couldn't open disk device\n");
109 		return 0;
110 	}
111 
112 	cp = loadaddr;
113 	rv = 1;
114 	for (i = 0; i < bbinfop->nblocks; i++) {
115 puts(".");
116 		ret.bits = prom_read(fd, bbinfop->bsize, cp,
117 		    bbinfop->blocks[i]);
118 puts("\b");
119 		if (ret.u.status) {
120 			rv = 0;
121 			puts("BLOCK READ ERROR!\n");
122 			break;
123 		}
124 		cp += bbinfop->bsize;
125 	}
126 	prom_close(fd);
127 
128 	return (rv);
129 }
130 
131 int
132 main()
133 {
134 	struct bbinfo *bbinfop;
135 	char *loadaddr;
136 	void (*entry)(void);
137 
138 	/* Init prom callback vector. */
139 	init_prom_calls();
140 
141 	puts("\nOpenBSD/Alpha Primary Boot\n");
142 
143 	bbinfop = (struct bbinfo *)&_end;
144 	loadaddr = (char *)SECONDARY_LOAD_ADDRESS;
145 	if (!load_file(bbinfop, loadaddr)) {
146 		puts("\nLOAD FAILED!\n\n");
147 		return;
148 	}
149 
150 #if 0
151 	puts("Jumping to entry point...\n");
152 #endif
153 	entry = (void (*)())loadaddr;
154 	(*entry)();
155 	puts("SECONDARY BOOT BLOCK RETURNED!\n");
156 }
157