1 1.6 msaitoh /* $NetBSD: riscospart.c,v 1.6 2020/09/29 02:58:52 msaitoh Exp $ */ 2 1.1 bjh21 3 1.1 bjh21 /*- 4 1.1 bjh21 * Copyright (c) 2006 Ben Harris 5 1.1 bjh21 * All rights reserved. 6 1.1 bjh21 * 7 1.1 bjh21 * Redistribution and use in source and binary forms, with or without 8 1.1 bjh21 * modification, are permitted provided that the following conditions 9 1.1 bjh21 * are met: 10 1.1 bjh21 * 1. Redistributions of source code must retain the above copyright 11 1.1 bjh21 * notice, this list of conditions and the following disclaimer. 12 1.1 bjh21 * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 bjh21 * notice, this list of conditions and the following disclaimer in the 14 1.1 bjh21 * documentation and/or other materials provided with the distribution. 15 1.1 bjh21 * 3. The name of the author may not be used to endorse or promote products 16 1.1 bjh21 * derived from this software without specific prior written permission. 17 1.1 bjh21 * 18 1.1 bjh21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 1.1 bjh21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 1.1 bjh21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 1.1 bjh21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 1.1 bjh21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 1.1 bjh21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 1.1 bjh21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 1.1 bjh21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 1.1 bjh21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 1.1 bjh21 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 1.1 bjh21 */ 29 1.1 bjh21 30 1.1 bjh21 /* 31 1.1 bjh21 * Copyright (c) 1995 Mark Brinicombe 32 1.1 bjh21 * All rights reserved. 33 1.1 bjh21 * 34 1.1 bjh21 * Redistribution and use in source and binary forms, with or without 35 1.1 bjh21 * modification, are permitted provided that the following conditions 36 1.1 bjh21 * are met: 37 1.1 bjh21 * 1. Redistributions of source code must retain the above copyright 38 1.1 bjh21 * notice, this list of conditions and the following disclaimer. 39 1.1 bjh21 * 2. Redistributions in binary form must reproduce the above copyright 40 1.1 bjh21 * notice, this list of conditions and the following disclaimer in the 41 1.1 bjh21 * documentation and/or other materials provided with the distribution. 42 1.1 bjh21 * 3. All advertising materials mentioning features or use of this software 43 1.1 bjh21 * must display the following acknowledgement: 44 1.1 bjh21 * This product includes software developed by the University of 45 1.1 bjh21 * California, Berkeley and its contributors. 46 1.1 bjh21 * 4. Neither the name of the University nor the names of its contributors 47 1.1 bjh21 * may be used to endorse or promote products derived from this software 48 1.1 bjh21 * without specific prior written permission. 49 1.1 bjh21 * 50 1.1 bjh21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 51 1.1 bjh21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52 1.1 bjh21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 53 1.1 bjh21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 54 1.1 bjh21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 55 1.1 bjh21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 56 1.1 bjh21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 57 1.1 bjh21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 58 1.1 bjh21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 59 1.1 bjh21 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 60 1.1 bjh21 * SUCH DAMAGE. 61 1.1 bjh21 */ 62 1.1 bjh21 63 1.1 bjh21 #include <sys/types.h> 64 1.1 bjh21 #include <sys/param.h> 65 1.1 bjh21 #include <sys/disklabel.h> 66 1.1 bjh21 #include <sys/disklabel_acorn.h> 67 1.1 bjh21 68 1.1 bjh21 #include <lib/libsa/stand.h> 69 1.1 bjh21 70 1.1 bjh21 #include "riscospart.h" 71 1.1 bjh21 72 1.1 bjh21 /* 73 1.1 bjh21 * This function should be shared between here, 74 1.1 bjh21 * sys/arch/arm/arm/disksubr_acorn.c, and 75 1.1 bjh21 * sys/fs/filecorefs/filecore_utils.c, rather than being copied. 76 1.1 bjh21 */ 77 1.1 bjh21 /* 78 1.1 bjh21 * static int filecore_checksum(u_char *bootblock) 79 1.1 bjh21 * 80 1.1 bjh21 * Calculates the filecore boot block checksum. This is used to validate 81 1.1 bjh21 * a filecore boot block on the disk. If a boot block is validated then 82 1.1 bjh21 * it is used to locate the partition table. If the boot block is not 83 1.1 bjh21 * validated, it is assumed that the whole disk is NetBSD. 84 1.1 bjh21 * 85 1.1 bjh21 * The basic algorithm is: 86 1.1 bjh21 * 87 1.1 bjh21 * for (each byte in block, excluding checksum) { 88 1.1 bjh21 * sum += byte; 89 1.1 bjh21 * if (sum > 255) 90 1.1 bjh21 * sum -= 255; 91 1.1 bjh21 * } 92 1.1 bjh21 * 93 1.1 bjh21 * That's equivalent to summing all of the bytes in the block 94 1.1 bjh21 * (excluding the checksum byte, of course), then calculating the 95 1.1 bjh21 * checksum as "cksum = sum - ((sum - 1) / 255) * 255)". That 96 1.1 bjh21 * expression may or may not yield a faster checksum function, 97 1.1 bjh21 * but it's easier to reason about. 98 1.1 bjh21 * 99 1.1 bjh21 * Note that if you have a block filled with bytes of a single 100 1.1 bjh21 * value "X" (regardless of that value!) and calculate the cksum 101 1.1 bjh21 * of the block (excluding the checksum byte), you will _always_ 102 1.1 bjh21 * end up with a checksum of X. (Do the math; that can be derived 103 1.1 bjh21 * from the checksum calculation function!) That means that 104 1.1 bjh21 * blocks which contain bytes which all have the same value will 105 1.6 msaitoh * always checksum properly. That's a _very_ unlikely occurrence 106 1.1 bjh21 * (probably impossible, actually) for a valid filecore boot block, 107 1.1 bjh21 * so we treat such blocks as invalid. 108 1.1 bjh21 */ 109 1.1 bjh21 static int 110 1.1 bjh21 filecore_checksum(u_char *bootblock) 111 1.1 bjh21 { 112 1.1 bjh21 u_char byte0, accum_diff; 113 1.1 bjh21 u_int sum; 114 1.1 bjh21 int i; 115 1.1 bjh21 116 1.1 bjh21 sum = 0; 117 1.1 bjh21 accum_diff = 0; 118 1.1 bjh21 byte0 = bootblock[0]; 119 1.1 bjh21 120 1.1 bjh21 /* 121 1.1 bjh21 * Sum the contents of the block, keeping track of whether 122 1.1 bjh21 * or not all bytes are the same. If 'accum_diff' ends up 123 1.1 bjh21 * being zero, all of the bytes are, in fact, the same. 124 1.1 bjh21 */ 125 1.1 bjh21 for (i = 0; i < 511; ++i) { 126 1.1 bjh21 sum += bootblock[i]; 127 1.1 bjh21 accum_diff |= bootblock[i] ^ byte0; 128 1.1 bjh21 } 129 1.1 bjh21 130 1.1 bjh21 /* 131 1.1 bjh21 * Check to see if the checksum byte is the same as the 132 1.1 bjh21 * rest of the bytes, too. (Note that if all of the bytes 133 1.1 bjh21 * are the same except the checksum, a checksum compare 134 1.1 bjh21 * won't succeed, but that's not our problem.) 135 1.1 bjh21 */ 136 1.1 bjh21 accum_diff |= bootblock[i] ^ byte0; 137 1.1 bjh21 138 1.1 bjh21 /* All bytes in block are the same; call it invalid. */ 139 1.1 bjh21 if (accum_diff == 0) 140 1.1 bjh21 return (-1); 141 1.1 bjh21 142 1.1 bjh21 return (sum - ((sum - 1) / 255) * 255); 143 1.1 bjh21 } 144 1.1 bjh21 145 1.1 bjh21 146 1.1 bjh21 int 147 1.1 bjh21 getdisklabel_acorn(struct open_file *f, struct disklabel *lp) 148 1.1 bjh21 { 149 1.1 bjh21 size_t rsize; 150 1.1 bjh21 int err; 151 1.2 christos char *buf; 152 1.1 bjh21 struct filecore_bootblock *bb; 153 1.1 bjh21 daddr_t labelsect; 154 1.1 bjh21 char *msg; 155 1.1 bjh21 156 1.1 bjh21 buf = alloc(DEV_BSIZE); 157 1.1 bjh21 err = DEV_STRATEGY(f->f_dev)(f->f_devdata, F_READ, 158 1.1 bjh21 FILECORE_BOOT_SECTOR, DEV_BSIZE, buf, &rsize); 159 1.4 skrll if (err != 0) 160 1.4 skrll goto out; 161 1.1 bjh21 bb = (struct filecore_bootblock *) buf; 162 1.1 bjh21 if (bb->checksum == filecore_checksum((u_char *)bb)) { 163 1.1 bjh21 if (bb->partition_type == PARTITION_FORMAT_RISCBSD) 164 1.3 skrll labelsect = ((bb->partition_cyl_high << 8) + bb->partition_cyl_low) * 165 1.1 bjh21 bb->heads * bb->secspertrack + LABELSECTOR; 166 1.1 bjh21 else { 167 1.1 bjh21 err = EUNLAB; 168 1.1 bjh21 goto out; 169 1.1 bjh21 } 170 1.1 bjh21 } else 171 1.1 bjh21 labelsect = LABELSECTOR; 172 1.1 bjh21 err = DEV_STRATEGY(f->f_dev)(f->f_devdata, F_READ, 173 1.1 bjh21 labelsect, DEV_BSIZE, buf, &rsize); 174 1.4 skrll if (err != 0) 175 1.4 skrll goto out; 176 1.1 bjh21 msg = getdisklabel(buf, lp); 177 1.1 bjh21 if (msg) { 178 1.1 bjh21 printf("%s\n", msg); 179 1.1 bjh21 err = ERDLAB; 180 1.1 bjh21 } 181 1.1 bjh21 out: 182 1.1 bjh21 dealloc(buf, DEV_BSIZE); 183 1.1 bjh21 return err; 184 1.1 bjh21 } 185