17f983a3marcel/*-
27f983a3marcel * Copyright (c) 2014 Juniper Networks, Inc.
37f983a3marcel * All rights reserved.
47f983a3marcel *
57f983a3marcel * Redistribution and use in source and binary forms, with or without
67f983a3marcel * modification, are permitted provided that the following conditions
77f983a3marcel * are met:
87f983a3marcel * 1. Redistributions of source code must retain the above copyright
97f983a3marcel *    notice, this list of conditions and the following disclaimer.
107f983a3marcel * 2. Redistributions in binary form must reproduce the above copyright
117f983a3marcel *    notice, this list of conditions and the following disclaimer in the
127f983a3marcel *    documentation and/or other materials provided with the distribution.
137f983a3marcel *
147f983a3marcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
157f983a3marcel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
167f983a3marcel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
177f983a3marcel * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
187f983a3marcel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
197f983a3marcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
207f983a3marcel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
217f983a3marcel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
227f983a3marcel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
237f983a3marcel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
247f983a3marcel * SUCH DAMAGE.
257f983a3marcel */
267f983a3marcel
277f983a3marcel#include <sys/cdefs.h>
287f983a3marcel__FBSDID("$FreeBSD$");
297f983a3marcel
300dddaf6marcel#include <sys/errno.h>
315e84416marcel#include <stdint.h>
324eff23dmarcel#include <stdio.h>
334eff23dmarcel#include <string.h>
347f983a3marcel
35a31300amarcel#include <vtoc.h>
365e84416marcel
37741bf12marcel#include "endian.h"
3824cdcc8marcel#include "image.h"
397f983a3marcel#include "mkimg.h"
407f983a3marcel#include "scheme.h"
417f983a3marcel
427f983a3marcelstatic struct mkimg_alias vtoc8_aliases[] = {
434eff23dmarcel    {	ALIAS_FREEBSD_NANDFS, ALIAS_INT2TYPE(VTOC_TAG_FREEBSD_NANDFS) },
444eff23dmarcel    {	ALIAS_FREEBSD_SWAP, ALIAS_INT2TYPE(VTOC_TAG_FREEBSD_SWAP) },
454eff23dmarcel    {	ALIAS_FREEBSD_UFS, ALIAS_INT2TYPE(VTOC_TAG_FREEBSD_UFS) },
464eff23dmarcel    {	ALIAS_FREEBSD_VINUM, ALIAS_INT2TYPE(VTOC_TAG_FREEBSD_VINUM) },
474eff23dmarcel    {	ALIAS_FREEBSD_ZFS, ALIAS_INT2TYPE(VTOC_TAG_FREEBSD_NANDFS) },
48ace52aemarcel    {	ALIAS_NONE, 0 }
497f983a3marcel};
507f983a3marcel
519dc0698marcelstatic lba_t
529dc0698marcelvtoc8_metadata(u_int where, lba_t blk)
537f983a3marcel{
547f983a3marcel
559dc0698marcel	blk += (where == SCHEME_META_IMG_START) ? 1 : 0;
569dc0698marcel	return (round_cylinder(blk));
577f983a3marcel}
587f983a3marcel
590dddaf6marcelstatic int
6024cdcc8marcelvtoc8_write(lba_t imgsz, void *bootcode __unused)
610dddaf6marcel{
624eff23dmarcel	struct vtoc8 vtoc8;
634eff23dmarcel	struct part *part;
64452aa44marcel	u_char *p;
6550a0b74marcel	int error, n;
66452aa44marcel	uint16_t ofs, sum;
674eff23dmarcel
6812d9d80marcel	imgsz = (lba_t)ncyls * nheads * nsecs;
6950a0b74marcel
704eff23dmarcel	memset(&vtoc8, 0, sizeof(vtoc8));
7150a0b74marcel	sprintf(vtoc8.ascii, "FreeBSD%lldM",
7250a0b74marcel	    (long long)(imgsz * secsz / 1048576));
734eff23dmarcel	be32enc(&vtoc8.version, VTOC_VERSION);
744eff23dmarcel	be16enc(&vtoc8.nparts, VTOC8_NPARTS);
754eff23dmarcel	be32enc(&vtoc8.sanity, VTOC_SANITY);
764eff23dmarcel	be16enc(&vtoc8.rpm, 3600);
77452aa44marcel	be16enc(&vtoc8.physcyls, ncyls);
78452aa44marcel	be16enc(&vtoc8.ncyls, ncyls);
79452aa44marcel	be16enc(&vtoc8.altcyls, 0);
80452aa44marcel	be16enc(&vtoc8.nheads, nheads);
81452aa44marcel	be16enc(&vtoc8.nsecs, nsecs);
824eff23dmarcel	be16enc(&vtoc8.magic, VTOC_MAGIC);
834eff23dmarcel
8450a0b74marcel	be32enc(&vtoc8.map[VTOC_RAW_PART].nblks, imgsz);
85f258aa5marcel	TAILQ_FOREACH(part, &partlist, link) {
8650a0b74marcel		n = part->index + ((part->index >= VTOC_RAW_PART) ? 1 : 0);
8750a0b74marcel		be16enc(&vtoc8.part[n].tag, ALIAS_TYPE2INT(part->type));
8850a0b74marcel		be32enc(&vtoc8.map[n].cyl, part->block / (nsecs * nheads));
8950a0b74marcel		be32enc(&vtoc8.map[n].nblks, part->size);
904eff23dmarcel	}
91452aa44marcel
92452aa44marcel	/* Calculate checksum. */
93452aa44marcel	sum = 0;
94452aa44marcel	p = (void *)&vtoc8;
95452aa44marcel	for (ofs = 0; ofs < sizeof(vtoc8) - 2; ofs += 2)
96452aa44marcel		sum ^= be16dec(p + ofs);
97452aa44marcel	be16enc(&vtoc8.cksum, sum);
98452aa44marcel
9924cdcc8marcel	error = image_write(0, &vtoc8, 1);
1004eff23dmarcel	return (error);
1010dddaf6marcel}
1020dddaf6marcel
1037f983a3marcelstatic struct mkimg_scheme vtoc8_scheme = {
1047f983a3marcel	.name = "vtoc8",
1057f983a3marcel	.description = "SMI VTOC8 disk labels",
1067f983a3marcel	.aliases = vtoc8_aliases,
1073f2295fmarcel	.metadata = vtoc8_metadata,
1080dddaf6marcel	.write = vtoc8_write,
10950a0b74marcel	.nparts = VTOC8_NPARTS - 1,
110cedbce4marcel	.maxsecsz = 512
1117f983a3marcel};
1127f983a3marcel
1137f983a3marcelSCHEME_DEFINE(vtoc8_scheme);
114