xref: /netbsd/usr.sbin/installboot/arch/macppc.c (revision 6dd44c41)
1*6dd44c41Sthorpej /*	$NetBSD: macppc.c,v 1.12 2019/05/07 04:35:31 thorpej Exp $ */
235749cafSlukem 
335749cafSlukem /*-
435749cafSlukem  * Copyright (c) 2002 The NetBSD Foundation, Inc.
535749cafSlukem  * All rights reserved.
635749cafSlukem  *
735749cafSlukem  * This code is derived from software contributed to The NetBSD Foundation
835749cafSlukem  * by Luke Mewburn.
935749cafSlukem  *
1035749cafSlukem  * Redistribution and use in source and binary forms, with or without
1135749cafSlukem  * modification, are permitted provided that the following conditions
1235749cafSlukem  * are met:
1335749cafSlukem  * 1. Redistributions of source code must retain the above copyright
1435749cafSlukem  *    notice, this list of conditions and the following disclaimer.
1535749cafSlukem  * 2. Redistributions in binary form must reproduce the above copyright
1635749cafSlukem  *    notice, this list of conditions and the following disclaimer in the
1735749cafSlukem  *    documentation and/or other materials provided with the distribution.
1835749cafSlukem  *
1935749cafSlukem  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2035749cafSlukem  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2135749cafSlukem  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2235749cafSlukem  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2335749cafSlukem  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2435749cafSlukem  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2535749cafSlukem  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2635749cafSlukem  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2735749cafSlukem  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2835749cafSlukem  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2935749cafSlukem  * POSSIBILITY OF SUCH DAMAGE.
3035749cafSlukem  */
3135749cafSlukem 
32171d6532Slukem #if HAVE_NBTOOL_CONFIG_H
33171d6532Slukem #include "nbtool_config.h"
3435749cafSlukem #endif
3535749cafSlukem 
36171d6532Slukem #include <sys/cdefs.h>
37171d6532Slukem #if !defined(__lint)
38*6dd44c41Sthorpej __RCSID("$NetBSD: macppc.c,v 1.12 2019/05/07 04:35:31 thorpej Exp $");
39171d6532Slukem #endif	/* !__lint */
40171d6532Slukem 
4135749cafSlukem #include <sys/param.h>
42a9e4cec8Stsutsui #ifndef HAVE_NBTOOL_CONFIG_H
43a9e4cec8Stsutsui #include <sys/ioctl.h>
44a9e4cec8Stsutsui #include <sys/dkio.h>
45ff1b9852Stsutsui #include <errno.h>
46a9e4cec8Stsutsui #endif
4735749cafSlukem 
4835749cafSlukem #include <assert.h>
4935749cafSlukem #include <err.h>
5035749cafSlukem #include <stdio.h>
512b7c014cSlukem #include <string.h>
522b7c014cSlukem #include <unistd.h>
5335749cafSlukem 
5435749cafSlukem #include "installboot.h"
5535749cafSlukem 
5635749cafSlukem static struct bbinfo_params bbparams = {
5735749cafSlukem 	MACPPC_BBINFO_MAGIC,
5835749cafSlukem 	MACPPC_BOOT_BLOCK_OFFSET,
5935749cafSlukem 	MACPPC_BOOT_BLOCK_BLOCKSIZE,
6035749cafSlukem 	MACPPC_BOOT_BLOCK_MAX_SIZE,
6135749cafSlukem 	0,
62d22f5cffSlukem 	BBINFO_BIG_ENDIAN,
6335749cafSlukem };
6435749cafSlukem 
65d22f5cffSlukem static int writeapplepartmap(ib_params *, struct bbinfo_params *, uint8_t *);
662b7c014cSlukem 
67cce659e2Sdsl static int macppc_clearboot(ib_params *);
68cce659e2Sdsl static int macppc_setboot(ib_params *);
6935749cafSlukem 
70*6dd44c41Sthorpej struct ib_mach ib_mach_macppc = {
71*6dd44c41Sthorpej 	.name		=	"macppc",
72*6dd44c41Sthorpej 	.setboot	=	macppc_setboot,
73*6dd44c41Sthorpej 	.clearboot	=	macppc_clearboot,
74*6dd44c41Sthorpej 	.editboot	=	no_editboot,
75*6dd44c41Sthorpej 	.valid_flags	=	IB_STAGE2START,
76*6dd44c41Sthorpej };
77cce659e2Sdsl 
78cce659e2Sdsl static int
macppc_clearboot(ib_params * params)7935749cafSlukem macppc_clearboot(ib_params *params)
8035749cafSlukem {
8135749cafSlukem 
8235749cafSlukem 	assert(params != NULL);
8335749cafSlukem 
84a6fac9a7Slukem 		/* XXX: maybe clear the apple partition map too? */
85d22f5cffSlukem 	return (shared_bbinfo_clearboot(params, &bbparams, NULL));
8635749cafSlukem }
8735749cafSlukem 
88cce659e2Sdsl static int
macppc_setboot(ib_params * params)89d22f5cffSlukem macppc_setboot(ib_params *params)
90d22f5cffSlukem {
91d22f5cffSlukem 
92d22f5cffSlukem 	assert(params != NULL);
93d22f5cffSlukem 
94d22f5cffSlukem 	return (shared_bbinfo_setboot(params, &bbparams, writeapplepartmap));
95d22f5cffSlukem }
96d22f5cffSlukem 
97d22f5cffSlukem 
982b7c014cSlukem static int
writeapplepartmap(ib_params * params,struct bbinfo_params * bb_params,uint8_t * bb)99d22f5cffSlukem writeapplepartmap(ib_params *params, struct bbinfo_params *bb_params,
100d22f5cffSlukem     uint8_t *bb)
1012b7c014cSlukem {
1022b7c014cSlukem 	struct apple_drvr_map dm;
1032b7c014cSlukem 	struct apple_part_map_entry pme;
104a9e4cec8Stsutsui 	int rv;
1052b7c014cSlukem 
1062b7c014cSlukem 	assert (params != NULL);
1072b7c014cSlukem 	assert (bb_params != NULL);
1082b7c014cSlukem 	assert (bb != NULL);
1092b7c014cSlukem 
1102b7c014cSlukem 	if (params->flags & IB_NOWRITE)
1112b7c014cSlukem 		return (1);
1122b7c014cSlukem 
1132b7c014cSlukem 		/* block 0: driver map  */
1142b7c014cSlukem 	if (pread(params->fsfd, &dm, MACPPC_BOOT_BLOCK_BLOCKSIZE, 0) !=
1152b7c014cSlukem 	    MACPPC_BOOT_BLOCK_BLOCKSIZE) {
1162b7c014cSlukem 		warn("Can't read sector 0 of `%s'", params->filesystem);
1172b7c014cSlukem 		return (0);
1182b7c014cSlukem 	}
119a6fac9a7Slukem 	dm.sbSig =		htobe16(APPLE_DRVR_MAP_MAGIC);
120a6fac9a7Slukem 	dm.sbBlockSize =	htobe16(512);
121a6fac9a7Slukem 	dm.sbBlkCount =		htobe32(0);
122a9e4cec8Stsutsui 
123ff1b9852Stsutsui 	rv = pwrite(params->fsfd, &dm, MACPPC_BOOT_BLOCK_BLOCKSIZE, 0);
124a9e4cec8Stsutsui #ifdef DIOCWLABEL
125ff1b9852Stsutsui 	if (rv == -1 && errno == EROFS) {
126a9e4cec8Stsutsui 		/*
127a9e4cec8Stsutsui 		 * block 0 is LABELSECTOR which might be protected by
128a9e4cec8Stsutsui 		 * bounds_check_with_label(9).
129a9e4cec8Stsutsui 		 */
130ff1b9852Stsutsui 		int enable;
131ff1b9852Stsutsui 
132a9e4cec8Stsutsui 		enable = 1;
133a9e4cec8Stsutsui 		rv = ioctl(params->fsfd, DIOCWLABEL, &enable);
134a9e4cec8Stsutsui 		if (rv != 0) {
135a9e4cec8Stsutsui 			warn("Cannot enable writes to the label sector");
136a9e4cec8Stsutsui 			return 0;
137a9e4cec8Stsutsui 		}
138ff1b9852Stsutsui 
139a9e4cec8Stsutsui 		rv = pwrite(params->fsfd, &dm, MACPPC_BOOT_BLOCK_BLOCKSIZE, 0);
140a9e4cec8Stsutsui 
141a9e4cec8Stsutsui 		/* Reset write-protect. */
142a9e4cec8Stsutsui 		enable = 0;
143a9e4cec8Stsutsui 		(void)ioctl(params->fsfd, DIOCWLABEL, &enable);
144ff1b9852Stsutsui 	}
145a9e4cec8Stsutsui #endif
146a9e4cec8Stsutsui 	if (rv != MACPPC_BOOT_BLOCK_BLOCKSIZE) {
1472b7c014cSlukem 		warn("Can't write sector 0 of `%s'", params->filesystem);
1482b7c014cSlukem 		return (0);
1492b7c014cSlukem 	}
1502b7c014cSlukem 
1512b7c014cSlukem 		/* block 1: Apple Partition Map */
1522b7c014cSlukem 	memset(&pme, 0, sizeof(pme));
153a6fac9a7Slukem 	pme.pmSig =		htobe16(APPLE_PART_MAP_ENTRY_MAGIC);
154a6fac9a7Slukem 	pme.pmMapBlkCnt =	htobe32(2);
155a6fac9a7Slukem 	pme.pmPyPartStart =	htobe32(1);
156a6fac9a7Slukem 	pme.pmPartBlkCnt =	htobe32(2);
157a6fac9a7Slukem 	pme.pmDataCnt =		htobe32(2);
1582b7c014cSlukem 	strlcpy(pme.pmPartName, "Apple", sizeof(pme.pmPartName));
1592b7c014cSlukem 	strlcpy(pme.pmPartType, "Apple_partition_map", sizeof(pme.pmPartType));
160a6fac9a7Slukem 	pme.pmPartStatus =	htobe32(0x37);
1612b7c014cSlukem 	if (pwrite(params->fsfd, &pme, MACPPC_BOOT_BLOCK_BLOCKSIZE,
1622b7c014cSlukem 	    1 * MACPPC_BOOT_BLOCK_BLOCKSIZE) != MACPPC_BOOT_BLOCK_BLOCKSIZE) {
1632b7c014cSlukem 		warn("Can't write Apple Partition Map into sector 1 of `%s'",
1642b7c014cSlukem 		    params->filesystem);
1652b7c014cSlukem 		return (0);
1662b7c014cSlukem 	}
1672b7c014cSlukem 
1682b7c014cSlukem 		/* block 2: NetBSD partition */
1692b7c014cSlukem 	memset(&pme, 0, sizeof(pme));
170a6fac9a7Slukem 	pme.pmSig =		htobe16(APPLE_PART_MAP_ENTRY_MAGIC);
171a6fac9a7Slukem 	pme.pmMapBlkCnt =	htobe32(2);
172a6fac9a7Slukem 	pme.pmPyPartStart =	htobe32(4);
173a6fac9a7Slukem 	pme.pmPartBlkCnt =	htobe32(0x7fffffff);
174a6fac9a7Slukem 	pme.pmDataCnt =		htobe32(0x7fffffff);
1752b7c014cSlukem 	strlcpy(pme.pmPartName, "NetBSD", sizeof(pme.pmPartName));
1762b7c014cSlukem 	strlcpy(pme.pmPartType, "NetBSD/macppc", sizeof(pme.pmPartType));
177a6fac9a7Slukem 	pme.pmPartStatus =	htobe32(0x3b);
17886dee8f4Slukem 	pme.pmBootSize =	htobe32(roundup(params->s1stat.st_size, 512));
179a6fac9a7Slukem 	pme.pmBootLoad =	htobe32(0x4000);
180a6fac9a7Slukem 	pme.pmBootEntry =	htobe32(0x4000);
1812b7c014cSlukem 	strlcpy(pme.pmProcessor, "PowerPC", sizeof(pme.pmProcessor));
1822b7c014cSlukem 	if (pwrite(params->fsfd, &pme, MACPPC_BOOT_BLOCK_BLOCKSIZE,
1832b7c014cSlukem 	    2 * MACPPC_BOOT_BLOCK_BLOCKSIZE) != MACPPC_BOOT_BLOCK_BLOCKSIZE) {
1842b7c014cSlukem 		warn("Can't write Apple Partition Map into sector 2 of `%s'",
1852b7c014cSlukem 		    params->filesystem);
1862b7c014cSlukem 		return (0);
1872b7c014cSlukem 	}
1882b7c014cSlukem 
1892b7c014cSlukem 	return (1);
1902b7c014cSlukem }
191