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