1 /* $NetBSD: md.c,v 1.11 2022/01/29 16:01:18 martin Exp $ */
2
3 /*
4 * Copyright 1997 Piermont Information Systems Inc.
5 * All rights reserved.
6 *
7 * Based on code written by Philip A. Nelson for Piermont Information
8 * Systems Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. The name of Piermont Information Systems Inc. may not be used to endorse
19 * or promote products derived from this software without specific prior
20 * written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32 * THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 /* md.c -- hpcarm machine specific routines */
36
37 #include <stdio.h>
38 #include <util.h>
39 #include <sys/param.h>
40 #include <machine/cpu.h>
41 #include <sys/sysctl.h>
42
43 #include "defs.h"
44 #include "md.h"
45 #include "msg_defs.h"
46 #include "menu_defs.h"
47 #include "endian.h"
48 #include "mbr.h"
49
50 void
md_init(void)51 md_init(void)
52 {
53 }
54
55 void
md_init_set_status(int flags)56 md_init_set_status(int flags)
57 {
58 static const struct {
59 const char *name;
60 const int set;
61 } kern_sets[] = {
62 { "IPAQ", SET_KERNEL_IPAQ },
63 { "JORNADA720", SET_KERNEL_JORNADA720 },
64 { "WZERO3", SET_KERNEL_WZERO3 }
65 };
66 static const int mib[2] = {CTL_KERN, KERN_VERSION};
67 size_t len;
68 char *version;
69 u_int i;
70
71 /* check INSTALL kernel name to select an appropriate kernel set */
72 /* XXX: hw.cpu_model has a processor name on arm ports */
73 sysctl(mib, 2, NULL, &len, NULL, 0);
74 version = malloc(len);
75 if (version == NULL)
76 return;
77 sysctl(mib, 2, version, &len, NULL, 0);
78 for (i = 0; i < __arraycount(kern_sets); i++) {
79 if (strstr(version, kern_sets[i].name) != NULL) {
80 set_kernel_set(kern_sets[i].set);
81 break;
82 }
83 }
84 free(version);
85 }
86
87 bool
md_get_info(struct install_partition_desc * install)88 md_get_info(struct install_partition_desc *install)
89 {
90 int res;
91
92 if (pm->no_mbr || pm->no_part)
93 return true;
94
95 again:
96 if (pm->parts == NULL) {
97
98 const struct disk_partitioning_scheme *ps =
99 select_part_scheme(pm, NULL, true, NULL);
100
101 if (!ps)
102 return false;
103
104 struct disk_partitions *parts =
105 (*ps->create_new_for_disk)(pm->diskdev,
106 0, pm->dlsize, true, NULL);
107 if (!parts)
108 return false;
109
110 pm->parts = parts;
111 if (ps->size_limit > 0 && pm->dlsize > ps->size_limit)
112 pm->dlsize = ps->size_limit;
113 }
114
115 res = set_bios_geom_with_mbr_guess(pm->parts);
116 if (res == 0)
117 return false;
118 else if (res == 1)
119 return true;
120
121 pm->parts->pscheme->destroy_part_scheme(pm->parts);
122 pm->parts = NULL;
123 goto again;
124 }
125
126 /*
127 * md back-end code for menu-driven BSD disklabel editor.
128 */
129 int
md_make_bsd_partitions(struct install_partition_desc * install)130 md_make_bsd_partitions(struct install_partition_desc *install)
131 {
132 return make_bsd_partitions(install);
133 }
134
135 /*
136 * any additional partition validation
137 */
138 bool
md_check_partitions(struct install_partition_desc * install)139 md_check_partitions(struct install_partition_desc *install)
140 {
141 return true;
142 }
143
144 /*
145 * hook called before writing new disklabel.
146 */
147 bool
md_pre_disklabel(struct install_partition_desc * install,struct disk_partitions * parts)148 md_pre_disklabel(struct install_partition_desc *install,
149 struct disk_partitions *parts)
150 {
151
152 if (parts->parent == NULL)
153 return true; /* no outer partitions */
154
155 parts = parts->parent;
156
157 msg_display_subst(MSG_dofdisk, 3, parts->disk,
158 msg_string(parts->pscheme->name),
159 msg_string(parts->pscheme->short_name));
160
161 /* write edited "MBR" onto disk. */
162 if (!parts->pscheme->write_to_disk(parts)) {
163 msg_display(MSG_wmbrfail);
164 process_menu(MENU_ok, NULL);
165 return false;
166 }
167 return true;
168 }
169
170 /*
171 * hook called after writing disklabel to new target disk.
172 */
173 bool
md_post_disklabel(struct install_partition_desc * install,struct disk_partitions * parts)174 md_post_disklabel(struct install_partition_desc *install,
175 struct disk_partitions *parts)
176 {
177 #if 0
178 /* Sector forwarding / badblocks ... */
179 if (*pm->doessf) {
180 msg_display(MSG_dobad144);
181 return run_program(RUN_DISPLAY, "/usr/sbin/bad144 %s 0",
182 pm->diskdev);
183 }
184 #endif
185
186 return true;
187 }
188
189 /*
190 * hook called after upgrade() or install() has finished setting
191 * up the target disk but immediately before the user is given the
192 * ``disks are now set up'' message.
193 */
194 int
md_post_newfs(struct install_partition_desc * install)195 md_post_newfs(struct install_partition_desc *install)
196 {
197 struct mbr_sector pbr;
198 char adevname[STRSIZE];
199 ssize_t sz;
200 int fd = -1;
201
202 snprintf(adevname, sizeof(adevname), "/dev/r%sa", pm->diskdev);
203 fd = open(adevname, O_RDWR);
204 if (fd < 0)
205 goto out;
206
207 /* Read partition boot record */
208 sz = pread(fd, &pbr, sizeof(pbr), 0);
209 if (sz != sizeof(pbr))
210 goto out;
211
212 /* Check magic number */
213 if (pbr.mbr_magic != le16toh(MBR_MAGIC))
214 goto out;
215
216 #define OSNAME "NetBSD60"
217 /* Update oemname */
218 memcpy(&pbr.mbr_oemname, OSNAME, sizeof(OSNAME) - 1);
219
220 /* Clear BPB */
221 memset(&pbr.mbr_bpb, 0, sizeof(pbr.mbr_bpb));
222
223 /* write-backed new partition boot record */
224 (void)pwrite(fd, &pbr, sizeof(pbr), 0);
225
226 out:
227 if (fd >= 0)
228 close(fd);
229 return 0;
230 }
231
232 int
md_post_extract(struct install_partition_desc * install,bool upgrade)233 md_post_extract(struct install_partition_desc *install, bool upgrade)
234 {
235 return 0;
236 }
237
238 void
md_cleanup_install(struct install_partition_desc * install)239 md_cleanup_install(struct install_partition_desc *install)
240 {
241 #ifndef DEBUG
242 enable_rc_conf();
243 #endif
244 }
245
246 int
md_pre_update(struct install_partition_desc * install)247 md_pre_update(struct install_partition_desc *install)
248 {
249 return 1;
250 }
251
252 /* Upgrade support */
253 int
md_update(struct install_partition_desc * install)254 md_update(struct install_partition_desc *install)
255 {
256 md_post_newfs(install);
257 return 1;
258 }
259
260 int
md_check_mbr(struct disk_partitions * parts,mbr_info_t * mbri,bool quiet)261 md_check_mbr(struct disk_partitions *parts, mbr_info_t *mbri, bool quiet)
262 {
263 return 2;
264 }
265
266 bool
md_parts_use_wholedisk(struct disk_partitions * parts)267 md_parts_use_wholedisk(struct disk_partitions *parts)
268 {
269 return parts_use_wholedisk(parts, 0, NULL);
270 }
271
272 int
md_pre_mount(struct install_partition_desc * install,size_t ndx)273 md_pre_mount(struct install_partition_desc *install, size_t ndx)
274 {
275 return 0;
276 }
277
278 bool
md_mbr_update_check(struct disk_partitions * parts,mbr_info_t * mbri)279 md_mbr_update_check(struct disk_partitions *parts, mbr_info_t *mbri)
280 {
281 return false; /* no change, no need to write back */
282 }
283
284 #ifdef HAVE_GPT
285 bool
md_gpt_post_write(struct disk_partitions * parts,part_id root_id,bool root_is_new,part_id efi_id,bool efi_is_new)286 md_gpt_post_write(struct disk_partitions *parts, part_id root_id,
287 bool root_is_new, part_id efi_id, bool efi_is_new)
288 {
289 /* no GPT boot support, nothing needs to be done here */
290 return true;
291 }
292 #endif
293
294