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