xref: /netbsd-src/usr.sbin/installboot/arch/amiga.c (revision e5c09b191b3a14e8b4648a699077b773caf1ed9b)
1*e5c09b19Sthorpej /*	$NetBSD: amiga.c,v 1.10 2019/05/07 04:35:31 thorpej Exp $	*/
2e7852b05Smhitch 
3e7852b05Smhitch /*-
4e7852b05Smhitch  * Copyright (c) 1999, 2002 The NetBSD Foundation, Inc.
5e7852b05Smhitch  * All rights reserved.
6e7852b05Smhitch  *
7e7852b05Smhitch  * This code is derived from software contributed to The NetBSD Foundation
8e7852b05Smhitch  * by Michael Hitch.
9e7852b05Smhitch  *
10e7852b05Smhitch  * This code is derived from software contributed to The NetBSD Foundation
11e7852b05Smhitch  * by Luke Mewburn of Wasabi Systems.
12e7852b05Smhitch  *
13e7852b05Smhitch  * Redistribution and use in source and binary forms, with or without
14e7852b05Smhitch  * modification, are permitted provided that the following conditions
15e7852b05Smhitch  * are met:
16e7852b05Smhitch  * 1. Redistributions of source code must retain the above copyright
17e7852b05Smhitch  *    notice, this list of conditions and the following disclaimer.
18e7852b05Smhitch  * 2. Redistributions in binary form must reproduce the above copyright
19e7852b05Smhitch  *    notice, this list of conditions and the following disclaimer in the
20e7852b05Smhitch  *    documentation and/or other materials provided with the distribution.
21e7852b05Smhitch  *
22e7852b05Smhitch  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
23e7852b05Smhitch  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24e7852b05Smhitch  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25e7852b05Smhitch  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26e7852b05Smhitch  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27e7852b05Smhitch  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28e7852b05Smhitch  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29e7852b05Smhitch  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30e7852b05Smhitch  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31e7852b05Smhitch  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32e7852b05Smhitch  * POSSIBILITY OF SUCH DAMAGE.
33e7852b05Smhitch  */
34e7852b05Smhitch 
35b2f78261Sjmc #if HAVE_NBTOOL_CONFIG_H
36b2f78261Sjmc #include "nbtool_config.h"
37b2f78261Sjmc #endif
38b2f78261Sjmc 
39e7852b05Smhitch #include <sys/cdefs.h>
40e5f39b5eStsutsui #if !defined(__lint)
41*e5c09b19Sthorpej __RCSID("$NetBSD: amiga.c,v 1.10 2019/05/07 04:35:31 thorpej Exp $");
42e7852b05Smhitch #endif	/* !__lint */
43e7852b05Smhitch 
44e7852b05Smhitch #include <sys/param.h>
45e7852b05Smhitch #include <sys/stat.h>
46e7852b05Smhitch 
47e7852b05Smhitch #include <assert.h>
48e7852b05Smhitch #include <err.h>
49e7852b05Smhitch #include <stddef.h>
50e7852b05Smhitch #include <stdio.h>
51e7852b05Smhitch #include <stdlib.h>
52e7852b05Smhitch #include <unistd.h>
53e7852b05Smhitch #include <string.h>
54e7852b05Smhitch 
55e7852b05Smhitch #include "installboot.h"
56e7852b05Smhitch 
57e7852b05Smhitch /* XXX Must be kept in sync with bbstart.s! */
58e7852b05Smhitch #define CMDLN_LOC 0x10
59e7852b05Smhitch #define CMDLN_LEN 0x20
60e7852b05Smhitch 
61e7852b05Smhitch #define CHKSUMOFFS 1
62e7852b05Smhitch 
63e7852b05Smhitch u_int32_t chksum(u_int32_t *, int);
64e7852b05Smhitch 
65cce659e2Sdsl static int amiga_setboot(ib_params *);
66e7852b05Smhitch 
67*e5c09b19Sthorpej struct ib_mach ib_mach_amiga = {
68*e5c09b19Sthorpej 	.name		=	"amiga",
69*e5c09b19Sthorpej 	.setboot	=	amiga_setboot,
70*e5c09b19Sthorpej 	.clearboot	=	no_clearboot,
71*e5c09b19Sthorpej 	.editboot	=	no_editboot,
72*e5c09b19Sthorpej 	.valid_flags	=	IB_STAGE1START | IB_STAGE2START | IB_COMMAND,
73*e5c09b19Sthorpej };
74e7852b05Smhitch 
75cce659e2Sdsl static int
amiga_setboot(ib_params * params)76e7852b05Smhitch amiga_setboot(ib_params *params)
77e7852b05Smhitch {
78e7852b05Smhitch 	int retval;
79e7852b05Smhitch 	ssize_t			rv;
80e7852b05Smhitch 	char *dline;
81e7852b05Smhitch 	int sumlen;
82e7852b05Smhitch 	u_int32_t sum2, sum16;
83e7852b05Smhitch 
84e7852b05Smhitch 	struct stat		bootstrapsb;
85e7852b05Smhitch 
86e7852b05Smhitch 	u_int32_t block[128*16];
87e7852b05Smhitch 
881363df60Slukem 	retval = 0;
89e7852b05Smhitch 	if (fstat(params->s1fd, &bootstrapsb) == -1) {
90e7852b05Smhitch 		warn("Examining `%s'", params->stage1);
91e7852b05Smhitch 		goto done;
92e7852b05Smhitch 	}
93e7852b05Smhitch 	if (!S_ISREG(bootstrapsb.st_mode)) {
94e7852b05Smhitch 		warnx("`%s' must be a regular file", params->stage1);
95e7852b05Smhitch 		goto done;
96e7852b05Smhitch 	}
97e7852b05Smhitch 
98e7852b05Smhitch 	rv = pread(params->s1fd, &block, sizeof(block), 0);
99e7852b05Smhitch 	if (rv == -1) {
100e7852b05Smhitch 		warn("Reading `%s'", params->stage1);
101e7852b05Smhitch 		goto done;
102e7852b05Smhitch 	} else if (rv != sizeof(block)) {
103e7852b05Smhitch 		warnx("Reading `%s': short read", params->stage1);
104e7852b05Smhitch 		goto done;
105e7852b05Smhitch 	}
106e7852b05Smhitch 
107e7852b05Smhitch 	/* XXX the choices should not be hardcoded */
108e7852b05Smhitch 
109e7852b05Smhitch 	sum2  = chksum(block, 1024/4);
110e7852b05Smhitch 	sum16 = chksum(block, 8192/4);
111e7852b05Smhitch 
112e7852b05Smhitch 	if (sum16 == 0xffffffff) {
113e7852b05Smhitch 		sumlen = 8192/4;
114e7852b05Smhitch 	} else if (sum2 == 0xffffffff) {
115e7852b05Smhitch 		sumlen = 1024/4;
116e7852b05Smhitch 	} else {
117e7852b05Smhitch 		errx(1, "%s: wrong checksum", params->stage1);
118e7852b05Smhitch 		/* NOTREACHED */
119e7852b05Smhitch 	}
120e7852b05Smhitch 
121e7852b05Smhitch 	if (sum2 == sum16) {
122e7852b05Smhitch 		warnx("eek - both sums are the same");
123e7852b05Smhitch 	}
124e7852b05Smhitch 
125e7852b05Smhitch 	if (params->flags & IB_COMMAND) {
126e7852b05Smhitch 		dline = (char *)&(block[CMDLN_LOC/4]);
127e7852b05Smhitch 		/* XXX keep the default default line in sync with bbstart.s */
128e7852b05Smhitch 		if (strcmp(dline, "netbsd -ASn2") != 0) {
129e7852b05Smhitch 			errx(1, "Old bootblock version? Can't change command line.");
130e7852b05Smhitch 		}
131ed45ba76Sdsl 		(void)strncpy(dline, params->command, CMDLN_LEN-1);
132e7852b05Smhitch 
133bddb934aSmlelstv 		block[1] = htobe32(0);
134bddb934aSmlelstv 		block[1] = htobe32(0xffffffff - chksum(block, sumlen));
135e7852b05Smhitch 	}
136e7852b05Smhitch 
137e7852b05Smhitch 	if (params->flags & IB_NOWRITE) {
138e7852b05Smhitch 		retval = 1;
139e7852b05Smhitch 		goto done;
140e7852b05Smhitch 	}
141e7852b05Smhitch 
142e7852b05Smhitch 	if (params->flags & IB_VERBOSE)
143e7852b05Smhitch 		printf("Writing boot block\n");
144e7852b05Smhitch 	rv = pwrite(params->fsfd, &block, sizeof(block), 0);
145e7852b05Smhitch 	if (rv == -1) {
146e7852b05Smhitch 		warn("Writing `%s'", params->filesystem);
147e7852b05Smhitch 		goto done;
148e7852b05Smhitch 	} else if (rv != sizeof(block)) {
149e7852b05Smhitch 		warnx("Writing `%s': short write", params->filesystem);
150e7852b05Smhitch 		goto done;
151e7852b05Smhitch 	} else {
152e7852b05Smhitch 		retval = 1;
153e7852b05Smhitch 	}
154e7852b05Smhitch 
155e7852b05Smhitch  done:
156e7852b05Smhitch 	return (retval);
157e7852b05Smhitch }
158e7852b05Smhitch 
159e7852b05Smhitch u_int32_t
chksum(block,size)160e7852b05Smhitch chksum(block, size)
161e7852b05Smhitch 	u_int32_t *block;
162e7852b05Smhitch 	int size;
163e7852b05Smhitch {
164e7852b05Smhitch 	u_int32_t sum, lastsum;
165e7852b05Smhitch 	int i;
166e7852b05Smhitch 
167e7852b05Smhitch 	sum = 0;
168e7852b05Smhitch 
169e7852b05Smhitch 	for (i=0; i<size; i++) {
170e7852b05Smhitch 		lastsum = sum;
171bddb934aSmlelstv 		sum += be32toh(block[i]);
172e7852b05Smhitch 		if (sum < lastsum)
173e7852b05Smhitch 			++sum;
174e7852b05Smhitch 	}
175e7852b05Smhitch 
176e7852b05Smhitch 	return sum;
177e7852b05Smhitch }
178