xref: /netbsd-src/sys/arch/ews4800mips/ews4800mips/disklabel_conv.c (revision ce099b40997c43048fb78bd578195f81d2456523)
1 /*	$NetBSD: disklabel_conv.c,v 1.4 2008/04/28 20:23:18 martin Exp $	*/
2 
3 /*-
4  * Copyright (c) 2004 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by UCHIYAMA Yasushi.
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  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: disklabel_conv.c,v 1.4 2008/04/28 20:23:18 martin Exp $");
34 
35 #include <sys/systm.h>
36 #include <sys/param.h>
37 
38 #ifndef _KERNEL
39 #include "local.h"
40 #endif
41 
42 #include <sys/disklabel.h>
43 
44 /*
45  * NetBSD/ews4800mips EWS-UX compatible disk layout.
46  *
47  * 0============================+ cylinder 0
48  * 1	1stboot	program (4KB)	|
49  * .				.
50  * 7----------------------------+
51  * 8	PDINFO			| UX unvisible region.
52  * 9    BSD disklabel           | I (uch) decided to locate disklabel here.
53  * .				.
54  * .	error log	(UX)	|
55  * +============================+ cylinder 1
56  * |	logical_start	(UX)	|
57  * |	VTOC			|
58  * .				. UX Boot block	(partition 7)
59  * .				. 100 blocks (default. at least 2 blocks)
60  * .				.
61  * .				.
62  * +============================+
63  * |   BFS			|
64  * |		boot loader	|
65  * .		disklabel	.
66  * .		and etc.	. BFS		(partition 3)
67  * .				.
68  * .				.
69  * .				.
70  * -----------------------------+
71  */
72 
73 #define	_BFS_SIZE			16384	/* 8MB */
74 #define	_BOOTBLOCK_SIZE			100	/* UX default */
75 #define	_FAKE_TRACKS_PER_CYLINDER	16
76 #define	_FAKE_SECTORS_PER_TRACK		1
77 
78 void
disklabel_set_default(struct disklabel * d)79 disklabel_set_default(struct disklabel *d)
80 {
81 
82 	d->d_magic = DISKMAGIC;
83 	d->d_magic2 = DISKMAGIC;
84 	d->d_secsize = DEV_BSIZE;
85 	d->d_npartitions = MAXPARTITIONS;
86 }
87 
88 void
vtoc_set_default(struct cpu_disklabel * ux,struct disklabel * d)89 vtoc_set_default( struct cpu_disklabel *ux, struct disklabel *d)
90 {
91 	struct pdinfo_sector *pdinfo = &ux->pdinfo;
92 	struct vtoc_sector *vtoc = &ux->vtoc;
93 	struct ux_partition *bfs;
94 	struct ux_partition *boot;
95 	struct ux_partition *bsdraw;
96 	int nsectors, logical_sector, cylinder_blocks, res;
97 
98 	memset(vtoc, 0, sizeof *vtoc);
99 	memset(pdinfo, 0, sizeof *pdinfo);
100 	if (d)
101 		cylinder_blocks = d->d_ntracks * d->d_nsectors;
102 	else
103 		cylinder_blocks =
104 		    _FAKE_TRACKS_PER_CYLINDER * _FAKE_SECTORS_PER_TRACK;
105 	logical_sector = cylinder_blocks;
106 
107 	pdinfo->drive_id = 0x5c512000;	/* Fake for EWS-UX */
108 	pdinfo->magic = PDINFO_MAGIC;
109 	pdinfo->version = PDINFO_VERSION;
110 	pdinfo->logical_sector = logical_sector;
111 	pdinfo->ux.errorlog_sector = logical_sector - 1;
112 	pdinfo->ux.errorlog_size_byte = DEV_BSIZE;
113 
114 	if (d) { /* use drivers disk geometory */
115 		pdinfo->geometory.cylinders_per_drive = d->d_ncylinders;
116 		pdinfo->geometory.tracks_per_cylinder = d->d_ntracks;
117 		pdinfo->geometory.sectors_per_track = d->d_nsectors;
118 		pdinfo->geometory.bytes_per_sector = d->d_secsize;
119 		nsectors = d->d_ncylinders * d->d_ntracks * d->d_nsectors;
120 	} else { /* set fake */
121 		pdinfo->geometory.sectors_per_track =
122 		    _FAKE_SECTORS_PER_TRACK;
123 		pdinfo->geometory.tracks_per_cylinder =
124 		    _FAKE_TRACKS_PER_CYLINDER;
125 		pdinfo->geometory.cylinders_per_drive = 0x1fffffff;
126 		pdinfo->geometory.bytes_per_sector = DEV_BSIZE;
127 		nsectors = 0x1fffffff;
128 	}
129 
130 	/* following magic numbers are required for EWS-UX */
131 	pdinfo->device_depend[15] = 0xfb7e10;
132 	pdinfo->device_depend[16] = 0x200;
133 	pdinfo->device_depend[17] = 0x10;
134 
135 	vtoc->magic = VTOC_MAGIC;
136 	vtoc->version = VTOC_VERSION;
137 	vtoc->sector_size_byte = DEV_BSIZE;
138 	vtoc->npartitions = VTOC_MAXPARTITIONS;
139 
140 	boot = &vtoc->partition[7];
141 	boot->tag = VTOC_TAG_BOOT;
142 	boot->flags = VTOC_FLAG_UNMOUNT;
143 	boot->start_sector = 0;
144 	boot->nsectors = _BOOTBLOCK_SIZE;
145 
146 	bfs = &vtoc->partition[3];
147 	bfs->tag = VTOC_TAG_STAND;
148 	bfs->flags = 0;
149 	bfs->start_sector = _BOOTBLOCK_SIZE;
150 
151 	res = nsectors - bfs->start_sector;
152 	bfs->nsectors = res > _BFS_SIZE ? _BFS_SIZE : res;
153 
154 	bsdraw = &vtoc->partition[RAW_PART];
155 	bsdraw->tag = VTOC_TAG_NONAME;
156 	bsdraw->flags = VTOC_FLAG_UNMOUNT;
157 	bsdraw->start_sector = -pdinfo->logical_sector;
158 	bsdraw->nsectors = nsectors;
159 }
160 
161 void
disklabel_to_vtoc(struct cpu_disklabel * ux,struct disklabel * d)162 disklabel_to_vtoc(struct cpu_disklabel *ux, struct disklabel *d)
163 {
164 	struct pdinfo_sector *pdinfo = &ux->pdinfo;
165 	struct vtoc_sector *vtoc = &ux->vtoc;
166 	struct ux_partition *up;
167 	struct partition *p;
168 	uint32_t offset = pdinfo->logical_sector;
169 	int i;
170 
171 	pdinfo->geometory.cylinders_per_drive = d->d_ncylinders;
172 	pdinfo->geometory.tracks_per_cylinder = d->d_ntracks;
173 	pdinfo->geometory.sectors_per_track = d->d_nsectors;
174 	pdinfo->geometory.bytes_per_sector = d->d_secsize;
175 
176 	vtoc->npartitions = d->d_npartitions;
177 	vtoc->sector_size_byte = d->d_secsize;
178 
179 	up = vtoc->partition;
180 	p = d->d_partitions;
181 	for (i = 0; i < vtoc->npartitions; i++, up++, p++) {
182 		if ((up->nsectors = p->p_size) != 0)
183 			up->start_sector = p->p_offset - offset;
184 		else
185 			up->start_sector = 0;
186 
187 		switch (p->p_fstype) {
188 		case FS_BOOT:
189 			up->tag = VTOC_TAG_BOOT;
190 			up->flags = VTOC_FLAG_UNMOUNT;
191 			break;
192 		case FS_SYSVBFS:
193 			up->tag = VTOC_TAG_STAND;
194 			break;
195 		case FS_SWAP:
196 			up->tag = VTOC_TAG_SWAP;
197 			up->flags = VTOC_FLAG_UNMOUNT;
198 			break;
199 		case FS_BSDFFS:
200 			up->tag = __VTOC_TAG_BSDFFS;
201 			break;
202 		case FS_UNUSED:
203 			if (i != RAW_PART && p->p_size > 0) {
204 				up->tag = VTOC_TAG_RAWDISK;
205 				up->flags = VTOC_FLAG_UNMOUNT;
206 			}
207 			break;
208 		default:
209 			break;
210 		}
211 	}
212 }
213 
214 void
vtoc_to_disklabel(struct cpu_disklabel * ux,struct disklabel * d)215 vtoc_to_disklabel(struct cpu_disklabel *ux, struct disklabel *d)
216 {
217 	struct pdinfo_sector *pdinfo = &ux->pdinfo;
218 	struct vtoc_sector *vtoc = &ux->vtoc;
219 	struct ux_partition *up;
220 	struct partition *p;
221 	uint32_t offset = pdinfo->logical_sector;
222 	int i;
223 
224 	d->d_secsize = pdinfo->geometory.bytes_per_sector;
225 	d->d_nsectors = pdinfo->geometory.sectors_per_track;
226 	d->d_ntracks = pdinfo->geometory.tracks_per_cylinder;
227 	d->d_ncylinders = pdinfo->geometory.cylinders_per_drive;
228 	d->d_secpercyl = d->d_nsectors * d->d_ntracks;
229 	d->d_secperunit = d->d_ncylinders * d->d_secpercyl;
230 
231 	d->d_npartitions = vtoc->npartitions;
232 	d->d_secsize = vtoc->sector_size_byte;
233 
234 	up = vtoc->partition;
235 	p = d->d_partitions;
236 	for (i = 0; i < vtoc->npartitions; i++, up++, p++) {
237 
238 		if ((p->p_size = up->nsectors) != 0)
239 			p->p_offset = up->start_sector + offset;
240 		else
241 			p->p_offset = 0;
242 
243 		switch (up->tag) {
244 		case VTOC_TAG_BOOT:
245 			p->p_fstype = FS_BOOT;
246 			break;
247 		case VTOC_TAG_STAND:
248 			p->p_fstype = FS_SYSVBFS;
249 			break;
250 		case VTOC_TAG_RAWDISK:
251 			p->p_fstype = FS_UNUSED;
252 			break;
253 		case VTOC_TAG_SWAP:
254 			p->p_fstype = FS_SWAP;
255 			break;
256 		case VTOC_TAG_NONAME:
257 		case VTOC_TAG_ROOT:
258 		case VTOC_TAG_USR:
259 		case VTOC_TAG_VAR:
260 		case VTOC_TAG_HOME:
261 			p->p_fstype = FS_SYSV;
262 			break;
263 		default:
264 			if (up->nsectors != 0)
265 				p->p_fstype = FS_SYSV;
266 			else
267 				p->p_fstype = FS_UNUSED;
268 			break;
269 		}
270 	}
271 
272 	d->d_checksum = 0;
273 	d->d_checksum = dkcksum(d);
274 }
275 
276 bool
disklabel_sanity(struct disklabel * d)277 disklabel_sanity(struct disklabel *d)
278 {
279 
280 	if (d->d_magic != DISKMAGIC || d->d_magic2 != DISKMAGIC ||
281 	    dkcksum(d) != 0)
282 		return false;
283 
284 	return true;
285 }
286