1263409Smarcel/*- 2263409Smarcel * Copyright (c) 2014 Juniper Networks, Inc. 3263409Smarcel * All rights reserved. 4263409Smarcel * 5263409Smarcel * Redistribution and use in source and binary forms, with or without 6263409Smarcel * modification, are permitted provided that the following conditions 7263409Smarcel * are met: 8263409Smarcel * 1. Redistributions of source code must retain the above copyright 9263409Smarcel * notice, this list of conditions and the following disclaimer. 10263409Smarcel * 2. Redistributions in binary form must reproduce the above copyright 11263409Smarcel * notice, this list of conditions and the following disclaimer in the 12263409Smarcel * documentation and/or other materials provided with the distribution. 13263409Smarcel * 14263409Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15263409Smarcel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16263409Smarcel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17263409Smarcel * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18263409Smarcel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19263409Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20263409Smarcel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21263409Smarcel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22263409Smarcel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23263409Smarcel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24263409Smarcel * SUCH DAMAGE. 25263409Smarcel */ 26263409Smarcel 27263409Smarcel#include <sys/cdefs.h> 28263409Smarcel__FBSDID("$FreeBSD: releng/11.0/usr.bin/mkimg/pc98.c 272485 2014-10-03 20:48:11Z marcel $"); 29263409Smarcel 30263409Smarcel#include <sys/types.h> 31263409Smarcel#include <sys/diskpc98.h> 32263697Smarcel#include <sys/endian.h> 33263442Smarcel#include <sys/errno.h> 34263409Smarcel#include <stdlib.h> 35263697Smarcel#include <string.h> 36263697Smarcel#include <unistd.h> 37263409Smarcel 38266176Smarcel#include "image.h" 39263409Smarcel#include "mkimg.h" 40263409Smarcel#include "scheme.h" 41263409Smarcel 42263923Smarcel#ifndef PC98_MAGIC 43263923Smarcel#define PC98_MAGIC 0xaa55 44263923Smarcel#endif 45263923Smarcel#ifndef PC98_MAGICOFS 46263923Smarcel#define PC98_MAGICOFS 510 47263923Smarcel#endif 48263923Smarcel#ifndef PC98_NPARTS 49263923Smarcel#define PC98_NPARTS 16 50263923Smarcel#endif 51263923Smarcel#ifndef PC98_PTYP_386BSD 52263923Smarcel#define PC98_PTYP_386BSD 0xc494 53263923Smarcel#endif 54263923Smarcel 55263697Smarcel#define PC98_BOOTCODESZ 8192 56263697Smarcel 57263409Smarcelstatic struct mkimg_alias pc98_aliases[] = { 58263697Smarcel { ALIAS_FREEBSD, ALIAS_INT2TYPE(PC98_PTYP_386BSD) }, 59263487Smarcel { ALIAS_NONE, 0 } 60263409Smarcel}; 61263409Smarcel 62271881Smarcelstatic lba_t 63271881Smarcelpc98_metadata(u_int where, lba_t blk) 64263409Smarcel{ 65271881Smarcel if (where == SCHEME_META_IMG_START) 66271881Smarcel blk += PC98_BOOTCODESZ / secsz; 67271881Smarcel return (round_track(blk)); 68263409Smarcel} 69263409Smarcel 70263697Smarcelstatic void 71272485Smarcelpc98_chs(u_short *cylp, u_char *hdp, u_char *secp, lba_t lba) 72263697Smarcel{ 73272485Smarcel u_int cyl, hd, sec; 74263697Smarcel 75272485Smarcel mkimg_chs(lba, 0xffff, &cyl, &hd, &sec); 76272485Smarcel le16enc(cylp, cyl); 77272485Smarcel *hdp = hd; 78272485Smarcel *secp = sec; 79263697Smarcel} 80263697Smarcel 81263442Smarcelstatic int 82266176Smarcelpc98_write(lba_t imgsz __unused, void *bootcode) 83263442Smarcel{ 84263697Smarcel struct part *part; 85263697Smarcel struct pc98_partition *dpbase, *dp; 86263697Smarcel u_char *buf; 87272485Smarcel lba_t size; 88263697Smarcel int error, ptyp; 89263697Smarcel 90263697Smarcel buf = malloc(PC98_BOOTCODESZ); 91263697Smarcel if (buf == NULL) 92263697Smarcel return (ENOMEM); 93263697Smarcel if (bootcode != NULL) { 94263697Smarcel memcpy(buf, bootcode, PC98_BOOTCODESZ); 95263697Smarcel memset(buf + secsz, 0, secsz); 96263697Smarcel } else 97263697Smarcel memset(buf, 0, PC98_BOOTCODESZ); 98263697Smarcel le16enc(buf + PC98_MAGICOFS, PC98_MAGIC); 99263697Smarcel dpbase = (void *)(buf + secsz); 100263697Smarcel STAILQ_FOREACH(part, &partlist, link) { 101272485Smarcel size = round_track(part->size); 102263697Smarcel dp = dpbase + part->index; 103263697Smarcel ptyp = ALIAS_TYPE2INT(part->type); 104263697Smarcel dp->dp_mid = ptyp; 105263697Smarcel dp->dp_sid = ptyp >> 8; 106263697Smarcel pc98_chs(&dp->dp_scyl, &dp->dp_shd, &dp->dp_ssect, 107263697Smarcel part->block); 108263697Smarcel pc98_chs(&dp->dp_scyl, &dp->dp_shd, &dp->dp_ssect, 109272485Smarcel part->block + size - 1); 110263697Smarcel if (part->label != NULL) 111263697Smarcel memcpy(dp->dp_name, part->label, strlen(part->label)); 112263697Smarcel } 113266176Smarcel error = image_write(0, buf, PC98_BOOTCODESZ / secsz); 114263697Smarcel free(buf); 115263697Smarcel return (error); 116263442Smarcel} 117263442Smarcel 118263409Smarcelstatic struct mkimg_scheme pc98_scheme = { 119263409Smarcel .name = "pc98", 120263409Smarcel .description = "PC-9800 disk partitions", 121263409Smarcel .aliases = pc98_aliases, 122263440Smarcel .metadata = pc98_metadata, 123263442Smarcel .write = pc98_write, 124263697Smarcel .bootcode = PC98_BOOTCODESZ, 125263697Smarcel .labellen = 16, 126263700Smarcel .nparts = PC98_NPARTS, 127263700Smarcel .maxsecsz = 512 128263409Smarcel}; 129263409Smarcel 130263409SmarcelSCHEME_DEFINE(pc98_scheme); 131