code:
/*	$OpenBSD: mfm.c,v 1.5 2011/03/13 00:13:53 deraadt Exp $	*/
/*	$NetBSD: mfm.c,v 1.4 2001/07/26 22:55:13 wiz Exp $	*/
/*
 * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
 * All rights reserved.
 *
 * This code is derived from software contributed to Ludd by
 * Bertram Barth.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed at Ludd, University of
 *	Lule}, Sweden and its contributors.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * ToDo:
 *
 * - insert appropriate delays for diskette-drive where needed
 * - allow more than one sector per diskette-read
 * - check for and handle bad sectors
 * - ???
 */

#include "sys/param.h"
#include "sys/reboot.h"
#include "sys/disklabel.h"

#include "lib/libsa/stand.h"
#include "lib/libsa/ufs.h"

#include "../include/pte.h"
#include "../include/sid.h"
#include "../include/mtpr.h"
#include "../include/reg.h"
#include "../include/rpb.h"

#include "ka410.h"
#include "../vsa/hdc9224.h"

#include "data.h"
#include "vaxstand.h"

#define MAX_WAIT	(1000*1000)	/* # of loop-instructions in seconds */

struct mfm_softc {
	int		part;
	int		unit;
};

static struct disklabel mfmlabel;
static struct mfm_softc mfm_softc;
static char io_buf[DEV_BSIZE];

/*
 * These should probably be somewhere else, but ka410 is the only
 * one with mfm disks anyway...
 */
volatile unsigned char *ka410_intreq = (void*)0x2008000f;
volatile unsigned char *ka410_intclr = (void*)0x2008000f;
volatile unsigned char *ka410_intmsk = (void*)0x2008000c;

static volatile struct hdc9224_DKCreg *dkc = (void *) 0x200c0000;
static volatile struct hdc9224_UDCreg sreg;	/* input */
static volatile struct hdc9224_UDCreg creg;	/* output */

static void sreg_read(void);
static void creg_write(void);
static int mfm_rxprepare(void);
static int mfm_command(int cmd);
static int mfm_rxselect(int unit);
static int mfm_rdselect(int unit);
static int mfm_rxstrategy(void *f, int func, daddr32_t dblk, size_t size, void *buf, size_t *rsize);
static int mfm_rdstrategy(void *f, int func, daddr32_t dblk, size_t size, void *buf, size_t *rsize);
/*
 * we have to wait 0.7 usec between two accesses to any of the
 * dkc-registers, on a VS2000 with 1 MIPS, this is roughly one
 * instruction. Thus the loop-overhead will be enough...
 */
static void
sreg_read(void)
{
	int	i;
	char    *p;

	dkc->dkc_cmd = 0x40;	/* set internal counter to zero */
	p = (void *) &sreg;
	for (i = 0; i < 10; i++)
		*p++ = dkc->dkc_reg;	/* dkc_reg auto-increments */
}

static void
creg_write(void)
{
	int	i;
	char    *p;

	dkc->dkc_cmd = 0x40;	/* set internal counter to zero */
	p = (void *) &creg;
	for (i = 0; i < 10; i++)
		dkc->dkc_reg = *p++;	/* dkc_reg auto-increments */
}

/*
 * floppies are handled in a quite strange way by this controller...
 *
 * before reading/writing a sector from/to floppy, we use the SEEK/READ_ID
 * command to place the head at the desired location. Then we wait some
 * time before issuing the real command in order to let the drive become
 * ready...
 */
int
mfm_rxprepare(void)
{
	int	error;

	error = mfm_command(DKC_CMD_SEEKREADID | 0x04); /* step=1, verify=0 */
	if (error) {
		printf("error while stepping to position %d/%d/%x. Retry...\n",
		    creg.udc_dsect, creg.udc_dhead, creg.udc_dcyl);
		error = mfm_command(DKC_CMD_SEEKREADID | 0x04);
	}
	return error;
}

int
mfm_rxselect(int unit)
{
	int	error;

	/*
	 * bring "creg" in some known-to-work state and
	 * select the drive with the DRIVE SELECT command.
	 */
	creg.udc_dma7 = 0;
	creg.udc_dma15 = 0;
	creg.udc_dma23 = 0;
	creg.udc_dsect = 1;	/* sectors are numbered 1..15 !!! */
	creg.udc_dhead = 0;
	creg.udc_dcyl = 0;
	creg.udc_scnt = 0;

	creg.udc_rtcnt = UDC_RC_RX33READ;
	creg.udc_mode = UDC_MD_RX33;
	creg.udc_term = UDC_TC_FDD;

	/*
	 * this is ...
	 */
	error = mfm_command(DKC_CMD_DRSEL_RX33 | unit);

	if ((error != 0) || ((sreg.udc_dstat & UDC_DS_READY) == 0)) {
		printf("\nfloppy-drive not ready (new floppy inserted?)\n\n");

		creg.udc_rtcnt &= ~UDC_RC_INVRDY;	/* clear INVRDY-flag */
		error = mfm_command(DKC_CMD_DRSEL_RX33 | unit);
		if ((error != 0) || ((sreg.udc_dstat & UDC_DS_READY) == 0)) {
			printf("diskette not ready(1): %x/%x\n",
			       error, sreg.udc_dstat);
			printf("floppy-drive offline?\n");
			return (-1);
		}
		if (sreg.udc_dstat & UDC_DS_TRK00)
			error = mfm_command(DKC_CMD_STEPIN_FDD);
		else
			error = mfm_command(DKC_CMD_STEPOUT_FDD);

		/*
		 * now ready should be 0, cause INVRDY is not set
		 * (retrying a command makes this fail...)
		 */
		if ((error != 0) || ((sreg.udc_dstat & UDC_DS_READY) == 1)) {
			printf("diskette not ready(2): %x/%x\n",
			       error, sreg.udc_dstat);
		}
		creg.udc_rtcnt |= UDC_RC_INVRDY;
		error = mfm_command(DKC_CMD_DRSEL_RX33 | unit);

		if ((error != 0) || ((sreg.udc_dstat & UDC_DS_READY) == 0)) {
			printf("diskette not ready(3): %x/%x\n",
			       error, sreg.udc_dstat);
			printf("no floppy inserted or floppy-door open\n");
			return (-1);
		}
		printf("floppy-drive reselected.\n");
	}
	return (error);
}

int
mfm_rdselect(int unit)
{
	int	error;

	/*
	 * bring "creg" in some known-to-work state and
	 * select the drive with the DRIVE SELECT command.
	 */
	creg.udc_dma7 = 0;
	creg.udc_dma15 = 0;
	creg.udc_dma23 = 0;
	creg.udc_dsect = 0;	/* sectors are numbered 0..16 */
	creg.udc_dhead = 0;
	creg.udc_dcyl = 0;
	creg.udc_scnt = 0;

	creg.udc_rtcnt = UDC_RC_HDD_READ;
	creg.udc_mode = UDC_MD_HDD;
	creg.udc_term = UDC_TC_HDD;

	error = mfm_command(DKC_CMD_DRSEL_HDD | unit);

	return (error);
}

static int	mfm_retry = 0;

int
mfm_command(int	cmd)
{
	int	termcode, ready, i;

	creg_write();		/* write command-registers */
	*ka410_intclr = INTR_DC;
	dkc->dkc_cmd = cmd;	/* issue command */
	for (i = 0; i < MAX_WAIT; i++) {
		if (*ka410_intreq & INTR_DC)	/* wait for interrupt */
			break;
	}
	if ((*ka410_intreq & INTR_DC) == 0)
		printf("timeout in mfm_command...\n");

	sreg_read();		/* read status-registers */

	if (dkc->dkc_stat == (DKC_ST_DONE | DKC_TC_SUCCESS))
		return (0);

	if (sreg.udc_cstat & UDC_CS_ECCERR) {
		printf(
"\nspurious(?) ECC/CRC error at s%d/t%d/c%d [s%d/t%d/c%d(%d)]\n",
		   sreg.udc_csect, sreg.udc_chead, sreg.udc_ccyl,
		   creg.udc_dsect, creg.udc_dhead, creg.udc_dcyl,creg.udc_scnt);
		if (sreg.udc_csect != creg.udc_dsect + creg.udc_scnt - 1) {
			printf("DMA: %x %x %x [%x]\n",
			    sreg.udc_dma23, sreg.udc_dma15,
			    sreg.udc_dma7, 512 * (sreg.udc_csect -
			    creg.udc_dsect));
			creg.udc_scnt = creg.udc_scnt -
			    (sreg.udc_csect - creg.udc_dsect) - 1;
			creg.udc_dsect = sreg.udc_csect + 1;
			creg.udc_dma23 = sreg.udc_dma23;
			creg.udc_dma15 = sreg.udc_dma15 + 2;
			creg.udc_dma7 = 0;
			printf("Retry starting from s%d/t%d/c%d (%d). ",
			    creg.udc_dsect, creg.udc_dhead, creg.udc_dcyl,
			    creg.udc_scnt);
		}
		goto retry;
	}
	termcode = (dkc->dkc_stat & DKC_ST_TERMCOD) >> 3;
	ready = sreg.udc_dstat & UDC_DS_READY;

	printf("cmd:0x%x: termcode=0x%x, status=0x%x, cstat=0x%x, dstat=0x%x\n",
	       cmd, termcode, dkc->dkc_stat, sreg.udc_cstat, sreg.udc_dstat);

	if (dkc->dkc_stat & DKC_ST_BADSECT)
		printf("bad sector found: s%d/t%d/c%d\n", creg.udc_dsect,
		       creg.udc_dhead, creg.udc_dcyl);
retry:
	if ((mfm_retry == 0) && (sreg.udc_cstat & UDC_CS_RETREQ)) {
		mfm_retry = 1;
		printf("Retrying... ");
		mfm_command(cmd);
		printf("Retry done.\n");
		mfm_retry = 0;
	}
	return ((dkc->dkc_stat & DKC_ST_TERMCOD) >> 3);
}

/*
 * on-disk geometry block
 */
#define _aP	__attribute__ ((packed))	/* force byte-alignment */

volatile struct mfm_xbn {
	char		mbz[10];/* 10 bytes of zero */
	long xbn_count	_aP;	/* number of XBNs */
	long dbn_count	_aP;	/* number of DBNs */
	long lbn_count	_aP;	/* number of LBNs (Logical-Block-Numbers) */
	long rbn_count	_aP;	/* number of RBNs (Replacement-Block-Numbers) */
	short		nspt;	/* number of sectors per track */
	short		ntracks;/* number of tracks */
	short		ncylinders;	/* number of cylinders */
	short		precomp;/* first cylinder for write precompensation */
	short		reduced;/* first cylinder for reduced write current */
	short		seek_rate;	/* seek rate or zero for buffered
					 * seeks */
	short		crc_eec;/* 0 if CRC is being used or 1 if ECC is
				 * being used */
	short		rct;	/* "replacement control table" (RCT) */
	short		rct_ncopies;	/* number of copies of the RCT */
	long media_id	_aP;	/* media identifier */
	short		interleave;	/* sector-to-sector interleave */
	short		headskew;	/* head-to-head skew */
	short		cylskew;/* cylinder-to-cylinder skew */
	short		gap0_size;	/* size of GAP 0 in the MFM format */
	short		gap1_size;	/* size of GAP 1 in the MFM format */
	short		gap2_size;	/* size of GAP 2 in the MFM format */
	short		gap3_size;	/* size of GAP 3 in the MFM format */
	short		sync_value;	/* sync value used to start a track
					 * when formatting */
	char		reserved[32];	/* reserved for use by the RQDX1/2/3
					 * formatter */
	short		serial_number;	/* serial number */
	char		fill[412];	/* Filler bytes to the end of the
					 * block */
	short		checksum;	/* checksum over the XBN */
} mfm_xbn;

#ifdef verbose
display_xbn(struct mfm_xbn *p)
{
	printf("**DiskData**	XBNs: %d, DBNs: %d, LBNs: %d, RBNs: %d\n",
	    p->xbn_count, p->dbn_count, p->lbn_count, p->rbn_count);
	printf("sect/track: %d, tracks: %d, cyl: %d, precomp/reduced: %d/%d\n",
	    p->nspt, p->ntracks, p->ncylinders, p->precomp, p->reduced);
	printf("seek-rate: %d, crc/eec: %s, RCT: %d, RCT-copies: %d\n",
	    p->seek_rate, p->crc_eec ? "EEC" : "CRC", p->rct, p->rct_ncopies);
	printf("media-ID: 0x%x, interleave: %d, headskew: %d, cylskew: %d\n",
	    &p->media_id, p->interleave, p->headskew, p->cylskew);
	printf("gap0: %d, gap1: %d, gap2: %d, gap3: %d, sync-value: %d\n",
	    p->gap0_size, p->gap1_size, p->gap2_size, p->gap3_size,
	    p->sync_value);
	printf("serial: %d, checksum: %d, size: %d, reserved: %32c\n",
	    p->serial_number, p->checksum, sizeof(*p), p->reserved);
}
#endif

int
mfmopen(struct open_file *f, int adapt, int ctlr, int unit, int part)
{
	char *msg;
	struct disklabel *lp = &mfmlabel;
	struct mfm_softc *msc = &mfm_softc;
	int err;
	size_t i;

	bzero(lp, sizeof(struct disklabel));
	msc->unit = unit;
	msc->part = part;

	err = mfmstrategy(msc, F_READ, LABELSECTOR, DEV_BSIZE, io_buf, &i);
	if (err) {
		printf("reading disklabel: %s\n", strerror(err));
		return 0;
	}
	msg = getdisklabel(io_buf + LABELOFFSET, lp);
	if (msg)
		printf("getdisklabel: %s\n", msg);

	f->f_devdata = (void *) msc;

	{
#ifdef verbose
		int		k;
		unsigned char  *ucp;
		struct mfm_xbn *xp;
#endif

		/* mfmstrategy(msc, F_READ, -16, 8192, io_buf, &i); */
		mfmstrategy(msc, F_READ, -16, 512, io_buf, &i);
#ifdef verbose
		printf("dumping raw disk-block #0:\n");
		ucp = io_buf;
		for (k = 0; k < 128; k++) {
			if (ucp[k] < 0x10)
				printf("0");
			printf("%x ", ucp[k]);
			if (k % 8 == 7)
				printf("  ");
			if (k % 16 == 15)
				printf("\n");
		}
		printf("\n");

		xp = (void *) io_buf;
		display_xbn(xp);
		printf("\n");
#endif
	}

	if (unit == 2) {	/* floppy! */
		if (lp->d_ntracks != 2) {
#ifdef verbose
			printf("changing number of tracks from %d to %d.\n",
			       lp->d_ntracks, 2);
#endif
			lp->d_ntracks = 2;
		}
	} else {		/* hard-disk */
		unsigned short *usp = (void *) io_buf;
#ifdef verbose
		printf("label says: s/t/c = %d/%d/%d\n",
		       lp->d_nsectors, lp->d_ntracks, lp->d_ncylinders);
#endif
		if (lp->d_nsectors != usp[13]) {
#ifdef verbose
			printf("changing number of sectors from %d to %d.\n",
			       lp->d_nsectors, usp[13]);
#endif
			lp->d_nsectors = usp[13];
		}
		if (lp->d_ntracks != usp[14]) {
#ifdef verbose
			printf("changing number of heads/tracks from %d to %d.\n",
			       lp->d_ntracks, usp[14]);
#endif
			lp->d_ntracks = usp[14];
		}
		if (lp->d_ncylinders != usp[15]) {
#ifdef verbose
			printf("changing number of cylinders from %d to %d.\n",
			       lp->d_ncylinders, usp[15]);
#endif
			lp->d_ncylinders = usp[15];
		}
		lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks;
	}

	return (0);
}

int
mfm_rxstrategy(void *f, int func, daddr32_t dblk, size_t size, void *buf, size_t *rsize)
{
	struct mfm_softc *msc = f;
	struct disklabel *lp;
	int	block, sect, head, cyl, scount, res;

	lp = &mfmlabel;
	block = (dblk < 0 ? 0 : dblk + lp->d_partitions[msc->part].p_offset);

	mfm_rxselect(msc->unit);

	/*
	 * if label is empty, assume RX33
	 */
	if (lp->d_nsectors == 0)
		lp->d_nsectors = 15;
	if (lp->d_ntracks == 0)
		lp->d_ntracks = 2;
	if (lp->d_secpercyl == 0)
		lp->d_secpercyl = 30;

	bzero((void *) 0x200D0000, size);
	scount = size / 512;

	while (scount) {
		/*
		 * prepare drive/operation parameter
		 */
		cyl = block / lp->d_secpercyl;
		sect = block % lp->d_secpercyl;
		head = sect / lp->d_nsectors;
		sect = sect % lp->d_nsectors;

		/*
		 * *rsize = 512;		one sector after the other
		 * ...
		 */
		*rsize = 512 * min(scount, lp->d_nsectors - sect);

		/*
		 * now initialize the register values ...
		 */
		creg.udc_dma7 = 0;
		creg.udc_dma15 = 0;
		creg.udc_dma23 = 0;

		creg.udc_dsect = sect + 1;	/* sectors are numbered 1..15
						 * !!! */
		head |= (cyl >> 4) & 0x70;
		creg.udc_dhead = head;
		creg.udc_dcyl = cyl;

		creg.udc_scnt = *rsize / 512;

		if (func == F_WRITE) {
			creg.udc_rtcnt = UDC_RC_RX33WRT;
			creg.udc_mode = UDC_MD_RX33;
			creg.udc_term = UDC_TC_FDD;

			mfm_rxprepare();
			/* copy from buf */
			bcopy(buf, (void *) 0x200D0000, *rsize);
			res = mfm_command(DKC_CMD_WRITE_RX33);
		} else {
			creg.udc_rtcnt = UDC_RC_RX33READ;
			creg.udc_mode = UDC_MD_RX33;
			creg.udc_term = UDC_TC_FDD;

			mfm_rxprepare();
			/* clear disk buffer */
			bzero((void *) 0x200D0000, *rsize);
			res = mfm_command(DKC_CMD_READ_RX33);
			/* copy to buf */
			bcopy((void *) 0x200D0000, buf, *rsize);
		}

		scount -= *rsize / 512;
		block += *rsize / 512;
		(char *)buf += *rsize;
	}

	*rsize = size;
	return 0;
}

int
mfm_rdstrategy(void *f, int func, daddr32_t dblk, size_t size, void *buf, size_t *rsize)
{
	struct mfm_softc *msc = f;
	struct disklabel *lp;
	int	block, sect, head, cyl, scount, cmd, res;

	lp = &mfmlabel;
	block = (dblk < 0 ? 0 : dblk + lp->d_partitions[msc->part].p_offset);

	/*
	 * if label is empty, assume RD32 (XXX this must go away!!!)
	 */
	if (lp->d_nsectors == 0)
		lp->d_nsectors = 17;
	if (lp->d_ntracks == 0)
		lp->d_ntracks = 6;
	if (lp->d_secpercyl == 0)
		lp->d_secpercyl = 102;

	mfm_rdselect(msc->unit);

	bzero((void *) 0x200D0000, size);
	scount = size / 512;

	while (scount) {
		/*
		 * prepare drive/operation parameter
		 */
		cyl = block / lp->d_secpercyl;
		sect = block % lp->d_secpercyl;
		head = sect / lp->d_nsectors;
		sect = sect % lp->d_nsectors;

		if (dblk < 0) {
#ifdef verbose
			printf("using raw diskblock-data!\n");
			printf("block %d, dblk %d ==> cyl %d, head %d, sect %d\n",
			       block, dblk, cyl, sect, head);
#endif
		} else
			cyl += 1;	/* first cylinder is reserved for
					 * controller! */

		*rsize = 512 * min(scount, lp->d_nsectors - sect);
		/*
		 * now re-initialize the register values ...
		 */
		creg.udc_dma7 = 0;
		creg.udc_dma15 = 0;
		creg.udc_dma23 = 0;

		creg.udc_dsect = sect;
		head |= (cyl >> 4) & 0x70;
		creg.udc_dhead = head;
		creg.udc_dcyl = cyl;

		creg.udc_scnt = *rsize / 512;

		if (func == F_WRITE) {
			creg.udc_rtcnt = UDC_RC_HDD_WRT;
			creg.udc_mode = UDC_MD_HDD;
			creg.udc_term = UDC_TC_HDD;
			cmd = DKC_CMD_WRITE_HDD;

			bcopy(buf, (void *) 0x200D0000, *rsize);
			res = mfm_command(cmd);
		} else {
			creg.udc_rtcnt = UDC_RC_HDD_READ;
			creg.udc_mode = UDC_MD_HDD;
			creg.udc_term = UDC_TC_HDD;
			cmd = DKC_CMD_READ_HDD;

			bzero((void *) 0x200D0000, *rsize);
			res = mfm_command(cmd);
			bcopy((void *) 0x200D0000, buf, *rsize);
		}

		scount -= *rsize / 512;
		block += *rsize / 512;
		(char *)buf += *rsize;
	}

	/*
	 * unselect the drive ...
	 */
	mfm_command(DKC_CMD_DRDESELECT);

	*rsize = size;
	return 0;
}

int
mfmstrategy(void *f, int func, daddr32_t dblk, size_t size, void *buf, size_t *rsize)
{
	struct mfm_softc *msc = f;
	int	res = -1;

	switch (msc->unit) {
	case 0:
	case 1:
		res = mfm_rdstrategy(f, func, dblk, size, buf, rsize);
		break;
	case 2:
		res = mfm_rxstrategy(f, func, dblk, size, buf, rsize);
		break;
	default:
		printf("invalid unit %d in mfmstrategy()\n", msc->unit);
	}
	return (res);
}


code:
/*	$OpenBSD: netio.c,v 1.6 2014/08/21 14:24:08 mpi Exp $	*/
/*	$NetBSD: netio.c,v 1.6 2000/05/26 20:16:46 ragge Exp $	*/

/*-
 * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Jason R. Thorpe.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * Copyright (c) 1995 Gordon W. Ross
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 * 4. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by Gordon W. Ross
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * This module implements a "raw device" interface suitable for
 * use by the stand-alone I/O library NFS code.	 This interface
 * does not support any "block" access, and exists only for the
 * purpose of initializing the network interface, getting boot
 * parameters, and performing the NFS mount.
 *
 * At open time, this does:
 *
 * find interface      - netif_open()
 * RARP for IP address - rarp_getipaddress()
 * RPC/bootparams      - callrpc(d, RPC_BOOTPARAMS, ...)
 * RPC/mountd	       - nfs_mount(sock, ip, path)
 *
 * the root file handle from mountd is saved in a global
 * for use by the NFS open code (NFS/lookup).
 */

#include <sys/param.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>

#include "lib/libsa/stand.h"
#include "lib/libsa/net.h"
#include "lib/libsa/netif.h"
#include "lib/libsa/bootparam.h"
#include "lib/libsa/nfs.h"
#include "lib/libsa/bootp.h"

#include "vaxstand.h"

static struct iodesc desc;
static int inited = 0;

struct iodesc *
socktodesc(sock)
{
	return &desc;
}

int
net_devinit(struct open_file *f, struct netif_driver *drv, u_char *eaddr) {
	static struct netif best_if;
	struct iodesc *s;
	int r;

	if (inited)
		return 0;
	/* find a free socket */
	s = &desc;

	bzero(s, sizeof(*s));
	best_if.nif_driver = drv;
	s->io_netif = &best_if;
	bcopy(eaddr, s->myea, 6);

	/*
	 * Get info for NFS boot: our IP address, our hostname,
	 * server IP address, and our root path on the server.
	 * There are two ways to do this:  The old, Sun way,
	 * and the more modern, BOOTP way. (RFC951, RFC1048)
	 */

#ifdef SUPPORT_BOOTP

	/* Get boot info using BOOTP way. (RFC951, RFC1048) */
	printf("Trying BOOTP\n");
	bootp(0);

	if (myip.s_addr) {
		printf("Using IP address: %s\n", inet_ntoa(myip));

		printf("myip: %s (%s)\n", hostname, inet_ntoa(myip));
	} else

#endif /* SUPPORT_BOOTP */
	{
#ifdef	SUPPORT_BOOTPARAMS
		/* Get boot info using RARP and Sun bootparams. */

		printf("Trying BOOTPARAMS\n");
		/* Get our IP address.	(rarp.c) */
		if (rarp_getipaddress(0) == -1)
			return (errno);

		printf("boot: client IP address: %s\n", inet_ntoa(myip));

		/* Get our hostname, server IP address. */
		if (bp_whoami(0))
			return (errno);

		printf("boot: client name: %s\n", hostname);

		/* Get the root pathname. */
		if (bp_getfile(0, "root", &rootip, rootpath))
			return (errno);
#endif
	}
	printf("root addr=%s path=%s\n", inet_ntoa(rootip), rootpath);
	f->f_devdata = s;

	/* Get the NFS file handle (mount). */
	r = nfs_mount(0, rootip, rootpath);
	if (r)
		return r;

	inited = 1;
	return 0;
}

ssize_t
netif_put(struct iodesc *desc, void *pkt, size_t len)
{
	return (*desc->io_netif->nif_driver->netif_put)(desc, pkt, len);
}

ssize_t
netif_get(struct iodesc *desc, void *pkt, size_t len, time_t timo)
{
	return (*desc->io_netif->nif_driver->netif_get)(desc, pkt, len, timo);
}

license: unknown


code:
/*	$OpenBSD: ra.c,v 1.5 2011/07/06 18:32:59 miod Exp $ */
/*	$NetBSD: ra.c,v 1.11 2002/06/04 15:13:55 ragge Exp $ */
/*
 * Copyright (c) 1995 Ludd, University of Lule}, Sweden.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *     This product includes software developed at Ludd, University of Lule}.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

 /* All bugs are subject to removal without further notice */

#define NRSP 1 /* Kludge */
#define NCMD 1 /* Kludge */

#include "sys/param.h"
#include "sys/disklabel.h"

#include "lib/libsa/stand.h"

#include "../include/pte.h"
#include "../include/rpb.h"

#include "arch/vax/mscp/mscp.h"
#include "arch/vax/mscp/mscpreg.h"

#include "vaxstand.h"

static void command(int, int);

/*
 * These routines for RA disk standalone boot is wery simple,
 * assuming a lots of thing like that we only working at one ra disk
 * a time, no separate routines for uba driver etc..
 * This code is foolish and should need a cleanup.
 * But it works :)
 */

static volatile struct uda {
	struct	mscp_1ca uda_ca;  /* communications area */
	struct	mscp uda_rsp;	  /* response packets */
	struct	mscp uda_cmd;	  /* command packets */
} uda;

static struct disklabel ralabel;
static char io_buf[DEV_BSIZE];
static int dpart, dunit, is_tmscp, curblock;
static volatile u_short *ra_ip, *ra_sa, *ra_sw;
static volatile u_int *mapregs;

int
raopen(struct open_file *f, int adapt, int ctlr, int unit, int part)
{
	static volatile struct uda *ubauda;
	unsigned short johan, johan2;
	size_t i;
	int err;
	char *msg;

#ifdef DEV_DEBUG
	printf("raopen: adapter %d ctlr %d unit %d part %d\n",
	    adapt, ctlr, unit, part);
	printf("raopen: csrbase %x nexaddr %x\n", csrbase, nexaddr);
#endif
	bzero(&ralabel, sizeof(struct disklabel));
	bzero((void *)&uda, sizeof(struct uda));
	if (bootrpb.devtyp == BDEV_TK)
		is_tmscp = 1;
	dunit = unit;
	dpart = part;
	if (ctlr < 0)
		ctlr = 0;
	curblock = 0;
	/* Assume uda-alike adapter */
	if (askname == 0) {
		csrbase = bootrpb.csrphy;
		dunit = bootrpb.unit;
		nexaddr = bootrpb.adpphy;
	} else
		csrbase += (ctlr ? 000334 : 012150);
	ra_ip = (short *)csrbase;
	ra_sa = ra_sw = (short *)csrbase + 1;
	if (nexaddr) { /* have map registers */
		mapregs = (int *)nexaddr + 512;
		mapregs[494] = PG_V | (((u_int)&uda) >> 9);
		mapregs[495] = mapregs[494] + 1;
		(char *)ubauda = (char *)0x3dc00 +
		    (((u_int)(&uda))&0x1ff);
	} else
		ubauda = &uda;
	johan = (((u_int)ubauda) & 0xffff) + 8;
	johan2 = (((u_int)ubauda) >> 16) & 077;
	*ra_ip = 0; /* Start init */
	bootrpb.csrphy = csrbase;

#ifdef DEV_DEBUG
	printf("start init\n");
#endif
	/* Init of this uda */
	while ((*ra_sa & MP_STEP1) == 0)
		;
#ifdef DEV_DEBUG
	printf("MP_STEP1...");
#endif
	*ra_sw = 0x8000;
	while ((*ra_sa & MP_STEP2) == 0)
		;
#ifdef DEV_DEBUG
	printf("MP_STEP2...");
#endif

	*ra_sw = johan;
	while ((*ra_sa & MP_STEP3) == 0)
		;
#ifdef DEV_DEBUG
	printf("MP_STEP3...");
#endif

	*ra_sw = johan2;
	while ((*ra_sa & MP_STEP4) == 0)
		;
#ifdef DEV_DEBUG
	printf("MP_STEP4\n");
#endif

	*ra_sw = 0x0001;
	uda.uda_ca.ca_rspdsc = (int)&ubauda->uda_rsp.mscp_cmdref;
	uda.uda_ca.ca_cmddsc = (int)&ubauda->uda_cmd.mscp_cmdref;
	if (is_tmscp) {
		uda.uda_cmd.mscp_un.un_seq.seq_addr =
		    (long *)&uda.uda_ca.ca_cmddsc;
		uda.uda_rsp.mscp_un.un_seq.seq_addr =
		    (long *)&uda.uda_ca.ca_rspdsc;
		uda.uda_cmd.mscp_vcid = 1;
		uda.uda_cmd.mscp_un.un_sccc.sccc_ctlrflags = 0;
	}

	command(M_OP_SETCTLRC, 0);
	uda.uda_cmd.mscp_unit = dunit;
	command(M_OP_ONLINE, 0);

	if (is_tmscp) {
		if (part) {
#ifdef DEV_DEBUG
			printf("Repos of tape...");
#endif
			uda.uda_cmd.mscp_un.un_seq.seq_buffer = part;
			command(M_OP_POS, 0);
			uda.uda_cmd.mscp_un.un_seq.seq_buffer = 0;
#ifdef DEV_DEBUG
			printf("Done!\n");
#endif
		}
		return 0;
	}
#ifdef DEV_DEBUG
	printf("reading disklabel\n");
#endif
	err = rastrategy(0, F_READ, LABELSECTOR, DEV_BSIZE, io_buf, &i);
	if(err){
		printf("reading disklabel: %s\n",strerror(err));
		return 0;
	}

#ifdef DEV_DEBUG
	printf("getting disklabel\n");
#endif
	msg = getdisklabel(io_buf+LABELOFFSET, &ralabel);
	if (msg)
		printf("getdisklabel: %s\n", msg);
	return(0);
}

static void
command(int cmd, int arg)
{
	volatile short hej;
	int to;

igen:	uda.uda_cmd.mscp_opcode = cmd;
	uda.uda_cmd.mscp_modifier = arg;

	uda.uda_cmd.mscp_msglen = MSCP_MSGLEN;
	uda.uda_rsp.mscp_msglen = MSCP_MSGLEN;
	uda.uda_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT;
	uda.uda_ca.ca_cmddsc |= MSCP_OWN|MSCP_INT;
#ifdef DEV_DEBUG
	printf("sending cmd %x...", cmd);
#endif
	hej = *ra_ip;
	to = 10000000;
	while (uda.uda_ca.ca_rspdsc < 0) {
//		if (uda.uda_ca.ca_cmdint)
//			uda.uda_ca.ca_cmdint = 0;
		if (--to < 0) {
#ifdef DEV_DEBUG
			printf("timing out, retry\n");
#endif
			goto igen;
		}
	}
#ifdef DEV_DEBUG
	printf("sent.\n");
#endif
}

int
rastrategy(void *f, int func, daddr32_t dblk,
    size_t size, void *buf, size_t *rsize)
{
	u_int	pfnum, mapnr, nsize;

#ifdef DEV_DEBUG
	printf("rastrategy: buf %p is_tmscp %d\n",
	    buf, is_tmscp);
#endif
	pfnum = (u_int)buf >> VAX_PGSHIFT;

	for(mapnr = 0, nsize = size; (nsize + VAX_NBPG) > 0; nsize -= VAX_NBPG)
		mapregs[mapnr++] = PG_V | pfnum++;
	uda.uda_cmd.mscp_seq.seq_buffer = ((u_int)buf) & 0x1ff;

	if (is_tmscp) {
		int i;

		/*
		 * First position tape. Remember where we are.
		 */
		if (dblk < curblock) {
			uda.uda_cmd.mscp_seq.seq_bytecount = curblock - dblk;
			command(M_OP_POS, 12); /* 12 == step block backward */
		} else {
			uda.uda_cmd.mscp_seq.seq_bytecount = dblk - curblock;
			command(M_OP_POS, 4); /* 4 == step block forward */
		}
		curblock = size/512 + dblk;

		/*
		 * Read in the number of blocks we need.
		 * Why doesn't read of multiple blocks work?????
		 */
		for (i = 0 ; i < size/512 ; i++) {
			uda.uda_cmd.mscp_seq.seq_lbn = 1;
			uda.uda_cmd.mscp_seq.seq_bytecount = 512;
			uda.uda_cmd.mscp_seq.seq_buffer =
			    (((u_int)buf) & 0x1ff) + i * 512;
			uda.uda_cmd.mscp_unit = dunit;
			command(M_OP_READ, 0);
		}
	} else {

		uda.uda_cmd.mscp_seq.seq_lbn =
		    dblk + ralabel.d_partitions[dpart].p_offset;
		uda.uda_cmd.mscp_seq.seq_bytecount = size;
		uda.uda_cmd.mscp_unit = dunit;
#ifdef DEV_DEBUG
		printf("rastrategy: blk 0x%lx count %lx unit %x\n",
		    uda.uda_cmd.mscp_seq.seq_lbn, size, dunit);
#endif
#ifdef notdef
		if (func == F_WRITE)
			command(M_OP_WRITE, 0);
		else
#endif
			command(M_OP_READ, 0);
	}

	*rsize = size;
	return 0;
}


code:
/*	$OpenBSD: rom.c,v 1.5 2011/03/13 00:13:53 deraadt Exp $ */
/*	$NetBSD: rom.c,v 1.3 2000/07/19 00:58:25 matt Exp $ */
/*
 * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
 * All rights reserved.
 *
 * This code is derived from software contributed to Ludd by
 * Bertram Barth.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed at Ludd, University of
 *      Lule}, Sweden and its contributors.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "sys/param.h"
#include "sys/reboot.h"
#include "sys/disklabel.h"

#include "lib/libsa/stand.h"
#include "lib/libsa/ufs.h"

#include "../include/pte.h"
#include "../include/sid.h"
#include "../include/mtpr.h"
#include "../include/reg.h"
#include "../include/rpb.h"

#include "data.h"
#include "vaxstand.h"

static struct disklabel romlabel;
static char io_buf[DEV_BSIZE];
static struct bqo *bqo;
static int dpart, dunit;

int
romopen(struct open_file *f, int adapt, int ctlr, int unit, int part)
{
	char *msg;
	struct disklabel *lp = &romlabel;
	size_t i;
	int err;

	bqo = (void *)bootrpb.iovec;

	if (bootrpb.unit > 0 && (bootrpb.unit % 100) == 0) {
		printf ("changing bootrpb.unit from %d ", bootrpb.unit);
		bootrpb.unit /= 100;
		printf ("to %d\n", bootrpb.unit);
	}

	bzero(lp, sizeof(struct disklabel));
	dunit = unit;
	dpart = part;

	err = romstrategy(0, F_READ, LABELSECTOR, DEV_BSIZE, io_buf, &i);
	if (err) {
		printf("reading disklabel: %s\n",strerror(err));
		return 0;
	}
	msg = getdisklabel(io_buf+LABELOFFSET, lp);
	if (msg)
		printf("getdisklabel: %s\n",msg);
	return(0);
}

int	romwrite_uvax(int, int, void *, struct rpb *);
int	romread_uvax(int, int, void *, struct rpb *);

int
romstrategy (f, func, dblk, size, buf, rsize)
	void *f;
	int func;
	daddr32_t dblk;
	size_t size;
	void *buf;
	size_t *rsize;
{
	struct	disklabel *lp;
	int	block;

	lp = &romlabel;
	block = dblk + lp->d_partitions[dpart].p_offset;
	if (dunit >= 0 && dunit < 10)
		bootrpb.unit = dunit;

	if (func == F_WRITE)
		romwrite_uvax(block, size, buf, &bootrpb);
	else
		romread_uvax(block, size, buf, &bootrpb);

	*rsize = size;
	return 0;
}


code:
/*	$OpenBSD: vaxstand.h,v 1.3 2011/07/06 18:32:59 miod Exp $ */
/*	$NetBSD: vaxstand.h,v 1.5 2000/06/15 19:53:23 ragge Exp $ */
/*
 * Copyright (c) 1994 Ludd, University of Lule}, Sweden.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *     This product includes software developed at Ludd, University of Lule}.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/* Variables used in autoconf */
extern int askname;
extern struct rpb bootrpb;
extern int csrbase, nexaddr;

/* devsw type definitions, used in bootxx and conf */
#define SADEV(name,strategy,open,close,ioctl) \
	{ (char *)name, \
	 (int(*)(void *, int, daddr32_t, size_t, void *, size_t *))strategy, \
	 (int(*)(struct open_file *, ...))open, \
	 (int(*)(struct open_file *))close, \
	 (int(*)(struct open_file *,u_long, void *))ioctl}

#define SDELAY(count) {volatile int i; for (i = count; i; i--);}
/*
 * Easy-to-use definitions
 */
#ifndef min
#define min(x,y) (x < y ? x : y)
#endif /* min */

struct netif_driver;

char *index(char *, int);
int net_devinit(struct open_file *f, struct netif_driver *drv, u_char *eaddr);

/* device calls */
int	raopen(struct open_file *, int, int, int, int),
	    rastrategy(void *, int, daddr32_t, size_t, void *, size_t *);
int	romopen(struct open_file *, int, int, int, int),
	    romstrategy(void *, int, daddr32_t, size_t, void *, size_t *);
int	mfmopen(struct open_file *, int, int, int, int),
	    mfmstrategy(void *, int, daddr32_t, size_t, void *, size_t *);
int	sdopen(struct open_file *),
	    sdstrategy(void *, int, daddr32_t, size_t, void *, size_t *);
int	leopen(struct open_file *, int, int, int, int),
	    leclose(struct open_file *);
int	qeopen(struct open_file *, int, int, int, int),
	    qeclose(struct open_file *);
int	zeopen(struct open_file *, int, int, int, int),
	    zeclose(struct open_file *);
int	deopen(struct open_file *, int, int, int, int),
	    declose(struct open_file *);
int	netopen(struct open_file *), netclose(struct open_file *);


code:
$OpenBSD: version,v 1.11 2014/02/19 22:13:53 miod Exp $
$NetBSD: version,v 1.4 2001/11/09 19:53:15 scw Exp $

NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE.  The format of this
file is important - make sure the entries are appended on end, last item
is taken as the current.

1.0:	Initial import.
1.1:	Bunch of small fixes to make boot work on most VAXen.
1.2:	Use common routines to identify cpu type.
	Set up a SCB to be able to handle clock interrupts in the boot program.
	Now timer countdown should work on all types of vaxen.
1.3:	Unify the ra and tmscp driver.
	Standalone driver for the Digital Equipment Unibus Network Adapter
	(DEUNA). This allows 11/750 owners to install from a single TU58
	cassette.
	Adapt to the RPB changes. Complete change of how network devices are
	handled. No more hacks to find bus addresses.
1.5:	Standalone device driver for DEBNx (ni) ethernet controllers.
1.6:	Add support for VAX 6000 + VAX 8000. Tweak console routines.
	Create a fake RPB if either netbooted (on machine without RPB) or
	loaded from console storage (without VMB intervention).
1.7:	Add support for loading a 2nd stage boot in either a.out or ELF.
	Add support for loading a 2nd stage boot directly to its desired
	address if possible.
	Cleanup use of u_int/size_t.
1.8:	Switch to loadfile instead of exec.  Now we can load a.out or ELF
	kernels. (disabled in OpenBSD)
1.9:	Support verbose/quiet boot.
1.10:	Remove the 11/750 pcs code and the list of kernels to try to boot
	in order.
	Work around some PROM bugs in graphics mode which cause \h and \t not
	to behave as expected.
1.11:	Better VXT2000{,+} support.
1.12:	Glass console support on VXT2000{,+}.
1.13:	Enable the loadfile code added in revision 1.8.
1.14:	Support for VaxStation 3[58][24]0.
1.15:	Restore boot sd()... functionality on machines with asc(4) or sii(4)
	controllers.
1.16:	Remove support for VAX 11/7x0, VAX6000 and VAX8000
1.17:	ELF bootblocks.
1.18:	/etc/random.seed support

path: sys/arch/vax/stand/boot/version


path: sys/arch/vax/stand/common/CVS/Entries


path: sys/arch/vax/stand/common/CVS/Tag


code:
/*	$OpenBSD: romread.S,v 1.3 2013/07/05 21:13:06 miod Exp $ */
/*	$NetBSD: romread.S,v 1.1 2002/02/24 01:04:25 matt Exp $ */
/*
 * Copyright (c) 1995 Ludd, University of Lule}, Sweden.
 * All rights reserved.
 *
 * This code is derived from software contributed to Ludd by
 * Bertram Barth.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed at Ludd, University of
 *      Lule}, Sweden and its contributors.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

 /* All bugs are subject to removal without further notice */

#include "../include/asm.h"

/*
 * romread_uvax (int lbn, int size, void *buf, struct rpb *rpb)
 */
ENTRY(romread_uvax, 0xFFE)
	movl	16(%ap),%r11	# restore boot-contents of %r11 (rpb)
	movl    52(%r11), %r7	# load iovec/bqo into %r7
	addl3   (%r7), %r7, %r6	# load qio into %r6
	pushl	%r11		# base of rpb
	pushl	$0		# virtual-flag
	pushl	$33		# read-logical-block
	pushl	4(%ap)		# lbn to start reading
	pushl	8(%ap)		# number of bytes to read
	pushl	12(%ap)		# buffer-address
	calls	$6, (%r6)	# call the qio-routine
	ret			# %r0 holds the result

/*
 * romwrite_uvax (int lbn, int size, void *buf, struct rpb *rpb)
 */
ENTRY(romwrite_uvax, 0xFFE)
	movl    16(%ap), %r11	# restore boot-contents of %r11 (rpb)
	movl    52(%r11), %r7	# load iovec/bqo into %r7
	addl3   (%r7), %r7, %r6	# load qio into %r6
	pushl   %r11		# base of rpb
	pushl   $0		# virtual-flag
	pushl   $32		# write-logical-block
	pushl   4(%ap)		# lbn to start reading
	pushl   8(%ap)		# number of bytes to read
	pushl   12(%ap)		# buffer-address
	calls   $6, (%r6)	# call the qio-routine
	ret			# %r0 holds the result


code:
/*	$OpenBSD: srt0.S,v 1.3 2013/07/05 21:13:06 miod Exp $ */
/*	$NetBSD: srt0.S,v 1.2 2002/03/31 00:11:14 matt Exp $ */
/*
 * Copyright (c) 1994 Ludd, University of Lule}, Sweden.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *     This product includes software developed at Ludd, University of Lule}.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

 /* All bugs are subject to removal without further notice */

#include "../include/asm.h"

/*
 * Auto-moving startup code for standalone programs. Can be loaded
 * (almost) anywhere in memory but moves itself to the position
 * it is linked for. Must be started at first position, recommended
 * is phys addr 0 (boot loads programs at 0, but starts them at the
 * position set in a.out header.
 */

ALTENTRY(start)
	nop;nop;
	movl	$_C_LABEL(start), %sp	# Probably safe place for stack
	pushr	$0x1fff		# save for later usage

	subl3	$_C_LABEL(start), $_C_LABEL(edata), %r0
	movab	_C_LABEL(start), %r1 # get where we are
	movl	$_C_LABEL(start), %r3 # get where we want to be
	cmpl	%r1,%r3		# are we where we want to be?
	beql	relocated	# already relocated, skip copy
	movc3	%r0,(%r1),(%r3)	# copy
	subl3	$_C_LABEL(edata), $_C_LABEL(end), %r2
	movc5	$0,(%r3),$0,%r2,(%r3) # Zero bss

	movpsl	-(%sp)
	pushl	$relocated
	rei
relocated:	                # now relocation is done !!!
	movl	%sp,_C_LABEL(bootregs)	# *bootregs
	calls	$0, _C_LABEL(Xmain)	# Were here!
	halt			# no return

ENTRY(machdep_start, 0)
	mtpr	$0x1f,$0x12	# Block all interrupts
	mtpr	$0,$0x18	# stop real time interrupt clock
	movl	4(%ap), %r6
	movl	20(%ap), %r9	# end of symbol table
	pushl	8(%ap)		# number of symbols
	pushl	16(%ap)		# start of symbols
	movab	_C_LABEL(bootrpb),%r10	# get RPB address
	pushl	%r10		# argument for new boot
	ashl	$9,76(%r10),%r8	# memory size (COMPAT)
	movl	$3,%r11		# ask boot (COMPAT)
	clrl	%r10		# no boot dev (COMPAT)

	calls	$3,(%r6)
	halt


code:
/*	$OpenBSD: str.S,v 1.4 2013/07/05 21:13:06 miod Exp $ */
/*	$NetBSD: str.S,v 1.1 2002/02/24 01:04:25 matt Exp $ */
/*
 * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed at Ludd, University of
 *      Lule}, Sweden and its contributors.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * Small versions of the most common functions not using any
 * emulated instructions.
 */

#include "asm.h"

/*
 * atoi() used in devopen.
 */
ENTRY(atoi, 0)
	movl	4(%ap),%r1
	clrl	%r0

2:	movzbl	(%r1)+,%r2
	cmpb	%r2,$48
	blss	1f
	cmpb	%r2,$57
	bgtr	1f
	subl2	$48,%r2
	mull2	$10,%r0
	addl2	%r2,%r0
	brb	2b
1:	ret

/*
 * index() small and easy.
 * doesnt work if we search for null.
 */
ENTRY(index, 0)
	movq	4(%ap),%r0
1:	cmpb	(%r0), %r1
	beql	2f
	tstb	(%r0)+
	bneq	1b
	clrl	%r0
2:	ret

/*
 * cmpc3 is emulated on MVII.
 */
ENTRY(bcmp, 0)
	movl	4(%ap), %r2
	movl	8(%ap), %r1
	movl	12(%ap), %r0
2:	cmpb	(%r2)+, (%r1)+
	bneq	1f
	decl	%r0
	bneq	2b
1:	ret

/*
 * Is movc3/movc5 emulated on any CPU? I dont think so; use them here.
 */
ENTRY(bzero,0)
	movc5	$0,*4(%ap),$0,8(%ap),*4(%ap)
	ret

ENTRY(bcopy,0)
	movc3	12(%ap), *4(%ap), *8(%ap)
	ret

ENTRY(strlen, 0)
	movl	4(%ap), %r0
1:	tstb	(%r0)+
	bneq	1b
	decl	%r0
	subl2	4(%ap), %r0
	ret

ENTRY(strcmp, 0)
	movl	$250, %r3	# max string len to compare
5:	movl	4(%ap), %r2
	movl	8(%ap), %r1
	movl	$1, %r0

2:	cmpb	(%r2),(%r1)+
	bneq	1f		# something differ
	tstb	(%r2)+
	beql	4f		# continue, strings unequal
	decl	%r3		# max string len encountered?
	bneq	2b

4:	clrl	%r0		# We are done, strings equal.
	ret

1:	bgtr	3f
	mnegl	%r0, %r0
3:	ret

ENTRY(strncpy, 0)
	movl	4(%ap), %r1
	movl	8(%ap), %r2
	movl	12(%ap), %r3
	bleq	2f

1:	movb	(%r2)+, (%r1)+
	beql	2f
	decl	%r3
	bneq	1b
2:	ret

ENTRY(setjmp, 0)
	movl	4(%ap), %r0
	movl	8(%fp), (%r0)
	movl	12(%fp), 4(%r0)
	movl	16(%fp), 8(%r0)
	addl3	%fp,$28,12(%r0)
	clrl	%r0
	ret

ENTRY(longjmp, 0)
	movl	4(%ap), %r1
	movl	$1, %r0
	movl	(%r1), %ap
	movl	4(%r1), %fp
	movl	12(%r1), %sp
	jmp	*8(%r1)


code:
/*	$OpenBSD: vaxstand.h,v 1.3 2011/07/06 18:32:59 miod Exp $ */
/*	$NetBSD: vaxstand.h,v 1.1 1999/03/06 16:36:05 ragge Exp $ */
/*
 * Copyright (c) 1994 Ludd, University of Lule}, Sweden.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *     This product includes software developed at Ludd, University of Lule}.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

 /* All bugs are subject to removal without further notice */

#define MAXNUBA 8 /* Unibusadapters */

/* Variables used in autoconf */
extern int *ubaaddr, *mbaaddr, *udaaddr;
extern int cpunumber, howto;
extern dev_t bootdev;

/* devsw type definitions, used in bootxx and conf */
#define SADEV(name,strategy,open,close,ioctl) \
        { (char *)name, \
         (int(*)(void *, int, daddr32_t, size_t, void *, size_t *))strategy, \
         (int(*)(struct open_file *, ...))open, \
         (int(*)(struct open_file *))close, \
         (int(*)(struct open_file *,u_long, void *))ioctl}

#define	SDELAY(count) {volatile int i; for (i = count; i; i--);}
/*
 * Easy-to-use definitions
 */

char *index();


path: sys/arch/vax/stand/xxboot/CVS/Entries


path: sys/arch/vax/stand/xxboot/CVS/Tag


code:
#	$OpenBSD: Makefile,v 1.14 2013/11/15 03:10:33 uebayasi Exp $
#	$NetBSD: Makefile,v 1.12 2002/02/24 01:04:25 matt Exp $

S=	${.CURDIR}/../../../../

PROG=	xxboot
LINKS=	${BINDIR}/xxboot ${BINDIR}/raboot
LINKS+=	${BINDIR}/xxboot ${BINDIR}/hdboot
LINKS+=	${BINDIR}/xxboot ${BINDIR}/sdboot
WARNS?=	1

SRCS=	start.S bootxx.c romread.S str.S urem.s udiv.s

INSTALL_STRIP=
CPPFLAGS+=-D_STANDALONE -DLIBSA_NO_FD_CHECKING -DLIBSA_NO_RAW_ACCESS \
	-DLIBSA_NO_TWIDDLE -DLIBSA_SINGLE_DEVICE=rom \
	-DLIBSA_NO_COMPAT_UFS \
	-DLIBSA_NO_FS_SYMLINK -DLIBSA_NO_FS_CLOSE \
	-DLIBSA_NO_FS_WRITE -DLIBSA_NO_FS_SEEK \
	-DNEED_UFS
AFLAGS+=-D_LOCORE
BINDIR=	/usr/mdec
NOMAN=	# defined
NOPIE=

CFLAGS=	-Os

SAREL=
SA_AS=	library
.include "${S}/lib/libsa/Makefile.inc"
LIBSA=	${SALIB}

STRIP?=strip
OBJCOPY?=objcopy

.if ${MACHINE} == "vax"
.PHONY: machine-links
beforedepend: machine-links
machine-links:
	@[ -h machine ] || ln -s ${S}/arch/${MACHINE}/include machine
	@[ -h ${MACHINE_ARCH} ] || ln -s ${S}/arch/${MACHINE_ARCH}/include ${MACHINE_ARCH}
.NOPATH: machine ${MACHINE_ARCH}
CLEANFILES+= machine ${MACHINE_ARCH} ${PROG}.out assym.h
.endif

start.o: assym.h

assym.h: $S/kern/genassym.sh Makefile ${.CURDIR}/genassym.cf
	sh $S/kern/genassym.sh ${CC} ${CFLAGS} ${CPPFLAGS} \
	    < ${.CURDIR}/genassym.cf | sort -u > assym.h

${PROG}: ${OBJS} ${LIBSA}
	${LD} -N -Ttext 100000 -o ${PROG}.out ${OBJS} ${LIBSA}
	${STRIP} ${PROG}.out
	/usr/bin/size ${PROG}.out
	${OBJCOPY} -O binary ${PROG}.out ${PROG}

clean::
	rm -f a.out [Ee]rrs mklog *.core ${PROG} ${OBJS} ${LOBJS} \
	    ${CLEANFILES}

.include <bsd.prog.mk>

path: sys/arch/vax/stand/xxboot/Makefile


code:
/*	$OpenBSD: bootxx.c,v 1.13 2013/07/05 21:13:07 miod Exp $ */
/* $NetBSD: bootxx.c,v 1.16 2002/03/29 05:45:08 matt Exp $ */

/*-
 * Copyright (c) 1982, 1986 The Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)boot.c	7.15 (Berkeley) 5/4/91
 */

#include <sys/param.h>
#include <sys/reboot.h>
#include <sys/disklabel.h>
#include <sys/exec.h>
#include <sys/exec_elf.h>

#include <lib/libsa/stand.h>
#include <lib/libsa/ufs.h>
#include <lib/libsa/cd9660.h>

#include <machine/pte.h>
#include <machine/sid.h>
#include <machine/mtpr.h>
#include <machine/reg.h>
#include <machine/rpb.h>
#include <arch/vax/vax/gencons.h>

#define NRSP 1 /* Kludge */
#define NCMD 1 /* Kludge */
#define LIBSA_TOO_OLD

#include <arch/vax/mscp/mscp.h>
#include <arch/vax/mscp/mscpreg.h>

#include "../boot/data.h"

#define	RF_PROTECTED_SECTORS	64	/* XXX refer to <.../rf_optnames.h> */

void	Xmain(void);
void	hoppabort(int);
void	romread_uvax(int lbn, int size, void *buf, struct rpb *rpb);
int	unit_init(int, struct rpb *, int);

struct open_file file;

unsigned *bootregs;
struct	rpb *rpb;
struct	bqo *bqo;
int	vax_cputype;
int	vax_load_failure;
struct udadevice {u_short udaip;u_short udasa;};
volatile struct udadevice *csr;
static int moved;

extern int from;
#define	FROMMV	2
#define	FROMVMB	4

/*
 * The boot blocks are used by MicroVAX II/III, VS2000,
 * VS3100, VS4000, and only when booting from disk.
 */
void
Xmain(void)
{
	union {
		struct exec aout;
		Elf32_Ehdr elf;
	} hdr;
	int io;
	u_long entry;

	vax_cputype = (mfpr(PR_SID) >> 24) & 0xFF;
	moved = 0;
	/*
	 */
	rpb = (void *)0xf0000; /* Safe address right now */
	bqo = (void *)0xf1000;
        if (from == FROMMV) {
		/*
		 * now relocate rpb/bqo (which are used by ROM-routines)
		 */
		bcopy ((void *)bootregs[11], rpb, sizeof(struct rpb));
		bcopy ((void*)rpb->iovec, bqo, rpb->iovecsz);
#if 0
		if (rpb->devtyp == BDEV_SDN)
			rpb->devtyp = BDEV_SD;	/* XXX until driver fixed */
#endif
	} else {
		bzero(rpb, sizeof(struct rpb));
		rpb->devtyp = bootregs[0];
		rpb->unit = bootregs[3];
		rpb->rpb_bootr5 = bootregs[5];
		rpb->csrphy = bootregs[2];
		rpb->adpphy = bootregs[1];	/* BI node on 8200 */
        }
	rpb->rpb_base = rpb;
	rpb->iovec = (int)bqo;

	io = open("/boot.vax", 0);
	if (io < 0)
		io = open("/boot", 0);
	if (io < 0)
		asm("movl $0xbeef1, %r0; halt");

	read(io, (void *)&hdr.aout, sizeof(hdr.aout));
	if (N_GETMAGIC(hdr.aout) == OMAGIC && N_GETMID(hdr.aout) == MID_VAX) {
		vax_load_failure++;
		entry = hdr.aout.a_entry;
		if (entry < sizeof(hdr.aout))
			entry = sizeof(hdr.aout);
		read(io, (void *) entry, hdr.aout.a_text + hdr.aout.a_data);
		memset((void *) (entry + hdr.aout.a_text + hdr.aout.a_data),
		       0, hdr.aout.a_bss);
	} else if (memcmp(hdr.elf.e_ident, ELFMAG, SELFMAG) == 0) {
		Elf32_Phdr ph;
		size_t off = sizeof(hdr.elf);
		vax_load_failure += 2;
		read(io, (caddr_t)(&hdr.elf) + sizeof(hdr.aout),
		     sizeof(hdr.elf) - sizeof(hdr.aout));
		if (hdr.elf.e_machine != EM_VAX || hdr.elf.e_type != ET_EXEC
		    || hdr.elf.e_phnum != 1)
			goto die;
		vax_load_failure++;
		entry = hdr.elf.e_entry;
		if (hdr.elf.e_phoff != sizeof(hdr.elf))
			goto die;
		vax_load_failure++;
		read(io, &ph, sizeof(ph));
		off += sizeof(ph);
		if (ph.p_type != PT_LOAD)
			goto die;
		vax_load_failure++;
		while (off < ph.p_offset) {
			u_int32_t tmp;
			read(io, &tmp, sizeof(tmp));
			off += sizeof(tmp);
		}
		read(io, (void *) ph.p_paddr, ph.p_filesz);
		memset((void *) (ph.p_paddr + ph.p_filesz), 0,
		       ph.p_memsz - ph.p_filesz);
	} else {
		goto die;
	}
	hoppabort(entry);
die:
	asm("movl $0xbeef2, %r0; halt");
}

/*
 * Write an extremely limited version of a (us)tar filesystem, suitable
 * for loading secondary-stage boot loader.
 * - Can only load file "boot".
 * - Must be the first file on tape.
 */
struct fs_ops file_system[] = {
#ifdef NEED_UFS
	{ ufs_open, 0, ufs_read, 0, 0, ufs_stat },
#endif
#ifdef NEED_CD9660
	{ cd9660_open, 0, cd9660_read, 0, 0, cd9660_stat },
#endif
#ifdef NEED_USTARFS
	{ ustarfs_open, 0, ustarfs_read, 0, 0, ustarfs_stat },
#endif
};

int nfsys = (sizeof(file_system) / sizeof(struct fs_ops));

#ifdef LIBSA_TOO_OLD
#include "../boot/vaxstand.h"

struct rom_softc {
       int part;
       int unit;
} rom_softc;

int    romstrategy(void *, int, daddr32_t, size_t, void *, size_t *);
int romopen(struct open_file *, int, int, int, int);
struct devsw   devsw[] = {
       SADEV("rom", romstrategy, romopen, nullsys, noioctl),
};
int    ndevs = (sizeof(devsw)/sizeof(devsw[0]));

int
romopen(struct open_file *f, int adapt, int ctlr, int unit, int part)
{
       rom_softc.unit = unit;
       rom_softc.part = part;

       f->f_devdata = (void *)&rom_softc;

       return 0;
}

#endif

int
devopen(struct open_file *f, const char *fname, char **file)
{

#ifdef LIBSA_TOO_OLD
	f->f_dev = &devsw[0];
#endif
	*file = (char *)fname;

	/*
	 * Reinit the VMB boot device.
	 */
	if (bqo->unit_init && (moved++ == 0)) {
		int initfn;

		initfn = rpb->iovec + bqo->unit_init;
		if (rpb->devtyp == BDEV_UDA || rpb->devtyp == BDEV_TK) {
			/*
			 * This reset do not seem to be done in the
			 * ROM routines, so we have to do it manually.
			 */
			csr = (struct udadevice *)rpb->csrphy;
			csr->udaip = 0;
			while ((csr->udasa & MP_STEP1) == 0)
				;
		}
		/*
		 * AP (R12) have a pointer to the VMB argument list,
		 * wanted by bqo->unit_init.
		 */
		unit_init(initfn, rpb, bootregs[12]);
	}
	return 0;
}

extern struct disklabel romlabel;

int
romstrategy(sc, func, dblk, size, buf, rsize)
	void    *sc;
	int     func;
	daddr32_t dblk;
	size_t	size;
	void    *buf;
	size_t	*rsize;
{
	int	block = dblk;
	int     nsize = size;

	if (romlabel.d_magic == DISKMAGIC && romlabel.d_magic2 == DISKMAGIC) {
		if (romlabel.d_npartitions > 1) {
			block += romlabel.d_partitions[0].p_offset;
			if (romlabel.d_partitions[0].p_fstype == FS_RAID) {
				block += RF_PROTECTED_SECTORS;
			}
		}
	}

	romread_uvax(block, size, buf, rpb);

	if (rsize)
		*rsize = nsize;
	return 0;
}

extern char end[];
static char *top = (char*)end;

void *
alloc(unsigned int size)
{
	void *ut = top;
	top += size;
	return ut;
}

void
free(void *ptr, unsigned int size)
{
}

#ifdef USE_PRINTF
void
putchar(int ch)
{
	/*
	 * On KA88 we may get C-S/C-Q from the console.
	 * Must obey it.
	 */
	while (mfpr(PR_RXCS) & GC_DON) {
		if ((mfpr(PR_RXDB) & 0x7f) == 19) {
			while (1) {
				while ((mfpr(PR_RXCS) & GC_DON) == 0)
					;
				if ((mfpr(PR_RXDB) & 0x7f) == 17)
					break;
			}
		}
	}

	while ((mfpr(PR_TXCS) & GC_RDY) == 0)
		;
	mtpr(0, PR_TXCS);
	mtpr(ch & 0377, PR_TXDB);
	if (ch == 10)
		putchar(13);
}
#endif


code:
#	$OpenBSD: genassym.cf,v 1.1 2011/09/29 18:02:41 miod Exp $
#
# Copyright (c) 2011 Miodrag Vallat.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

include	<sys/param.h>
include	<sys/disklabel.h>

struct	disklabel
export	LABELOFFSET


code:
/*	$OpenBSD: start.S,v 1.5 2013/07/05 21:13:07 miod Exp $ */
/*	$NetBSD: start.S,v 1.1 2002/02/24 01:04:26 matt Exp $ */
/*
 * Copyright (c) 1995 Ludd, University of Lule}, Sweden.
 * All rights reserved.
 *
 * This code is derived from software contributed to Ludd by
 * Bertram Barth.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed at Ludd, University of
 *	Lule}, Sweden and its contributors.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

 /* All bugs are subject to removal without further notice */

#include "../include/mtpr.h"
#include "../include/asm.h"

#include "assym.h"

_C_LABEL(_start):
_C_LABEL(start):
	.globl _C_LABEL(start)	# this is the symbolic name for the start
	.globl _C_LABEL(_start) # of code to be relocated. We can use this
				# to get the actual/real address (pc-rel)
				# or to get the relocated address (abs).

.org	0x00			# uVAX booted from TK50 starts here
	brb	from_0x00	# continue behind dispatch-block

.org	0x02			# information used by uVAX-ROM
	.byte	0xff		# offset in words to identification area
	.byte	1		# this byte must be 1
	.word	0		# logical block number (word swapped)
	.word	0		# of the secondary image

.org	0x08			#
	brb	from_0x08	# skip ...

.org	0x0C			# 11/750  & 8200 starts here
	halt			# not supported

from_0x00:			# uVAX from TK50
	brw	start_uvax	# all uVAXen continue there

from_0x08:			# Any machine from VMB
	movzbl	$4,_C_LABEL(from)		# Booted from full VMB
	brw	start_vmb

# the complete area reserved for label
# must be empty (i.e. filled with zeroes).
# disklabel(8) checks that before installing
# the bootblocks over existing label.

.org	LABELOFFSET
	.globl	_C_LABEL(romlabel)
_C_LABEL(romlabel):
	.long	0

.org	LABELOFFSET + DISKLABEL_SIZEOF
start_vmb:
	/*
	 * Read in block 1-15.
	 */
	movl	52(%r11), %r7	# load iovec/bqo into %r7
	addl3	(%r7), %r7, %r6	# load qio into %r6
	pushl	%r11		# base of rpb
	pushl	$0		# virtual-flag
	pushl	$33		# read-logical-block
	pushl	$1		# lbn to start reading
	pushl	$7680		# number of bytes to read
	pushab	start_uvax	# buffer-address
	calls	$6, (%r6)	# call the qio-routine
	brw	start_uvax

/*
 * Parameter block for uVAX boot.
 */
#define VOLINFO		0	/* 1=single-sided  81=double-sided volumes */
#define SISIZE		16	/* size in blocks of secondary image */
#define SILOAD		0	/* load offset (usually 0) from the default */
#define SIOFF		0x260	/* byte offset into secondary image */

.org	0x1fe
	.byte	0x18		# must be 0x18
	.byte	0x00		# must be 0x00 (MBZ)
	.byte	0x00		# any value
	.byte	0xFF - (0x18 + 0x00 + 0x00)
		/* 4th byte holds 1s' complement of sum of previous 3 bytes */

	.byte	0x00		# must be 0x00 (MBZ)
	.byte	VOLINFO
	.byte	0x00		# any value
	.byte	0x00		# any value

	.long	SISIZE		# size in blocks of secondary image
	.long	SILOAD		# load offset (usually 0)
	.long	SIOFF		# byte offset into secondary image
	.long	(SISIZE + SILOAD + SIOFF)	# sum of previous 3

	.p2align 2
	.globl	_C_LABEL(from)
_C_LABEL(from):
	.long	0

/* uVAX main entry is at the start of the second disk block.  This is
 * needed for multi-arch CD booting where multiple architecture need
 * to shove stuff in boot block 0.
 */
	.org	0x260		# uVAX booted from disk starts here

start_uvax:
	movzbl	$2,_C_LABEL(from)	# Booted from subset-VMB
	brb	start_all

/*
 * start_all: stack already at RELOC, we save registers, move ourself
 * to RELOC and loads boot.
 */
start_all:
	movl	$_C_LABEL(start), %sp	# move stack to a better
	pushr	$0x1fff			# save all regs, used later.

	subl3	$_C_LABEL(start), $_C_LABEL(edata), %r0
					# get size of text+data (w/o bss)
	moval	_C_LABEL(start), %r1	# get actual base-address of code
	subl3	$_C_LABEL(start), $_C_LABEL(end), %r2
					# get complete size (incl. bss)
	movl	$_C_LABEL(start), %r3	# get relocated base-address of code
	movc5	%r0, (%r1), $0, %r2, (%r3) # copy code to new location

	movpsl	-(%sp)
	movl	$relocated, -(%sp)	# return-address on top of stack
	rei				# can be replaced with new address
relocated:				# now relocation is done !!!
	movl	%sp, _C_LABEL(bootregs)
	calls	$0, _C_LABEL(Xmain)	# call Xmain (gcc workaround)which is
	halt				# not intended to return ...

/*
 * hoppabort() is called when jumping to the newly loaded program.
 */
ENTRY(hoppabort, 0)
	movl    4(%ap),%r6
	movl	_C_LABEL(rpb),%r11
	mnegl	$1,%ap		# Hack to figure out boot device.
	movpsl	-(%sp)
	pushab	2(%r6)
	mnegl	$1,_C_LABEL(vax_load_failure)
	rei
#	calls	$0,(%r6)
	halt

ENTRY(unit_init, R6|R7|R8|R9|R10|R11)
	mfpr	$17,%r7			# Wanted bu KDB
	movl	4(%ap),%r0		# init routine address
	movl	8(%ap),%r9		# RPB in %r9
	movl	12(%ap),%r1		# VMB argument list
	callg	(%r1),(%r0)
	ret

# A bunch of functions unwanted in boot blocks.
ENTRY(getchar, 0)
	halt

#ifndef USE_PRINTF
ENTRY(putchar, 0)
	ret

#endif

ENTRY(panic, 0)
	halt


code: src/sys/arch/vax/uba

path: sys/arch/vax/uba/CVS/Repository


code:
/*	$OpenBSD: uba_common.h,v 1.6 2015/02/01 15:27:12 miod Exp $	*/
/*	$NetBSD: uba_common.h,v 1.2 1999/06/21 16:23:01 ragge Exp $ */
/*-
 * Copyright (c) 1982, 1986 The Regents of the University of California.
 * All rights reserved.
 * (c) UNIX System Laboratories, Inc.
 * All or some portions of this file are derived from material licensed
 * to the University of California by American Telephone and Telegraph
 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
 * the permission of UNIX System Laboratories, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)ubareg.h	7.8 (Berkeley) 5/9/91
 */

/*
 * VAX-specific parts of the Unibus softc.
 */

struct	uba_vsoftc {
	struct	uba_softc uv_sc;/* Common vars from arch/vax/qbus/ubavar.h */
	struct	vax_bus_dma_tag uv_dmat;
	struct	vax_sgmap uv_sgmap;
	int	uv_size;	/* Size of UBA addressable memory */
	paddr_t uv_addr;	/* Physical address of map registers */
};

void	uba_dma_init(struct uba_vsoftc *);


code:
/*	$OpenBSD: uba_dma.c,v 1.5 2008/06/26 05:42:14 ray Exp $	*/
/* $NetBSD: uba_dma.c,v 1.2 1999/06/20 00:59:55 ragge Exp $ */

/*-
 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
 * NASA Ames Research Center.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPEUBAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/malloc.h>
#include <uvm/uvm_extern.h>

#define _VAX_BUS_DMA_PRIVATE
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/sgmap.h>

#include <arch/vax/qbus/ubavar.h>

#include <arch/vax/uba/uba_common.h>

int	uba_bus_dmamap_create_sgmap(bus_dma_tag_t, bus_size_t, int,
	    bus_size_t, bus_size_t, int, bus_dmamap_t *);

void	uba_bus_dmamap_destroy_sgmap(bus_dma_tag_t, bus_dmamap_t);

int	uba_bus_dmamap_load_sgmap(bus_dma_tag_t, bus_dmamap_t, void *,
	    bus_size_t, struct proc *, int);

int	uba_bus_dmamap_load_mbuf_sgmap(bus_dma_tag_t, bus_dmamap_t,
	    struct mbuf *, int);

int	uba_bus_dmamap_load_uio_sgmap(bus_dma_tag_t, bus_dmamap_t,
	    struct uio *, int);

int	uba_bus_dmamap_load_raw_sgmap(bus_dma_tag_t, bus_dmamap_t,
	    bus_dma_segment_t *, int, bus_size_t, int);

void	uba_bus_dmamap_unload_sgmap(bus_dma_tag_t, bus_dmamap_t);

void	uba_bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
	    bus_size_t, int);

void
uba_dma_init(sc)
	struct uba_vsoftc *sc;
{
	bus_dma_tag_t t;
	pt_entry_t *pte;

	/*
	 * Initialize the DMA tag used for sgmap-mapped DMA.
	 */
	t = &sc->uv_dmat;
	t->_cookie = sc;
	t->_wbase = 0;
	t->_wsize = sc->uv_size;
	t->_boundary = 0;
	t->_sgmap = &sc->uv_sgmap;
	t->_dmamap_create = uba_bus_dmamap_create_sgmap;
	t->_dmamap_destroy = uba_bus_dmamap_destroy_sgmap;
	t->_dmamap_load = uba_bus_dmamap_load_sgmap;
	t->_dmamap_load_mbuf = uba_bus_dmamap_load_mbuf_sgmap;
	t->_dmamap_load_uio = uba_bus_dmamap_load_uio_sgmap;
	t->_dmamap_load_raw = uba_bus_dmamap_load_raw_sgmap;
	t->_dmamap_unload = uba_bus_dmamap_unload_sgmap;
	t->_dmamap_sync = uba_bus_dmamap_sync;

	t->_dmamem_alloc = _bus_dmamem_alloc;
	t->_dmamem_free = _bus_dmamem_free;
	t->_dmamem_map = _bus_dmamem_map;
	t->_dmamem_unmap = _bus_dmamem_unmap;
	t->_dmamem_mmap = _bus_dmamem_mmap;

	/*
	 * Map in Unibus map registers.
	 */
	pte = (pt_entry_t *)vax_map_physmem(sc->uv_addr, sc->uv_size/VAX_NBPG);
	if (pte == NULL)
		panic("uba_dma_init");
	/*
	 * Initialize the SGMAP.
	 */
	vax_sgmap_init(t, &sc->uv_sgmap, "uba_sgmap", 0, sc->uv_size, pte, 0);

}

/*
 * Create a UBA SGMAP-mapped DMA map.
 */
int
uba_bus_dmamap_create_sgmap(t, size, nsegments, maxsegsz, boundary,
    flags, dmamp)
	bus_dma_tag_t t;
	bus_size_t size;
	int nsegments;
	bus_size_t maxsegsz;
	bus_size_t boundary;
	int flags;
	bus_dmamap_t *dmamp;
{
	bus_dmamap_t map;
	int error;

	error = _bus_dmamap_create(t, size, nsegments, maxsegsz,
	    boundary, flags, dmamp);
	if (error)
		return (error);

	map = *dmamp;

	if (flags & BUS_DMA_ALLOCNOW) {
		error = vax_sgmap_alloc(map, vax_round_page(size),
		    t->_sgmap, flags);
		if (error)
			uba_bus_dmamap_destroy_sgmap(t, map);
	}

	return (error);
}

/*
 * Destroy a UBA SGMAP-mapped DMA map.
 */
void
uba_bus_dmamap_destroy_sgmap(t, map)
	bus_dma_tag_t t;
	bus_dmamap_t map;
{

	if (map->_dm_flags & DMAMAP_HAS_SGMAP)
		vax_sgmap_free(map, t->_sgmap);

	_bus_dmamap_destroy(t, map);
}

/*
 * Load a UBA SGMAP-mapped DMA map with a linear buffer.
 */
int
uba_bus_dmamap_load_sgmap(t, map, buf, buflen, p, flags)
	bus_dma_tag_t t;
	bus_dmamap_t map;
	void *buf;
	bus_size_t buflen;
	struct proc *p;
	int flags;
{
	int error;

	error = vax_sgmap_load(t, map, buf, buflen, p, flags, t->_sgmap);
	/*
	 * XXX - Set up BDPs.
	 */

	return (error);
}

/*
 * Load a UBA SGMAP-mapped DMA map with an mbuf chain.
 */
int
uba_bus_dmamap_load_mbuf_sgmap(t, map, m, flags)
	bus_dma_tag_t t;
	bus_dmamap_t map;
	struct mbuf *m;
	int flags;
{
	int error;

	error = vax_sgmap_load_mbuf(t, map, m, flags, t->_sgmap);

	return (error);
}

/*
 * Load a UBA SGMAP-mapped DMA map with a uio.
 */
int
uba_bus_dmamap_load_uio_sgmap(t, map, uio, flags)
	bus_dma_tag_t t;
	bus_dmamap_t map;
	struct uio *uio;
	int flags;
{
	int error;

	error = vax_sgmap_load_uio(t, map, uio, flags, t->_sgmap);

	return (error);
}

/*
 * Load a UBA SGMAP-mapped DMA map with raw memory.
 */
int
uba_bus_dmamap_load_raw_sgmap(t, map, segs, nsegs, size, flags)
	bus_dma_tag_t t;
	bus_dmamap_t map;
	bus_dma_segment_t *segs;
	int nsegs;
	bus_size_t size;
	int flags;
{
	int error;

	error = vax_sgmap_load_raw(t, map, segs, nsegs, size, flags,
	    t->_sgmap);

	return (error);
}

/*
 * Unload a UBA DMA map.
 */
void
uba_bus_dmamap_unload_sgmap(t, map)
	bus_dma_tag_t t;
	bus_dmamap_t map;
{

	/*
	 * Invalidate any SGMAP page table entries used by this
	 * mapping.
	 */
	vax_sgmap_unload(t, map, t->_sgmap);

	/*
	 * Do the generic bits of the unload.
	 */
	_bus_dmamap_unload(t, map);
}

/*
 * Sync the bus map. This is only needed if BDP's are used.
 */
void
uba_bus_dmamap_sync(tag, dmam, offset, len, ops)
	bus_dma_tag_t tag;
	bus_dmamap_t dmam;
	bus_addr_t offset;
	bus_size_t len;
	int ops;
{
	/* Only BDP handling, but not yet. */
}


code:
/*	$OpenBSD: uba_ibus.c,v 1.4 2015/02/01 15:27:12 miod Exp $	*/
/*	$NetBSD: uba_ibus.c,v 1.1 1999/08/07 10:36:47 ragge Exp $	   */
/*
 * Copyright (c) 1996 Jonathan Stone.
 * Copyright (c) 1994, 1996 Ludd, University of Lule}, Sweden.
 * Copyright (c) 1982, 1986 The Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)uba.c	7.10 (Berkeley) 12/16/90
 *	@(#)autoconf.c	7.20 (Berkeley) 5/9/91
 */

#include <sys/param.h>
#include <sys/device.h>
#include <sys/systm.h>

#define	_VAX_BUS_DMA_PRIVATE
#include <machine/bus.h>
#include <machine/mtpr.h>
#include <machine/nexus.h>
#include <machine/cpu.h>
#include <machine/sgmap.h>

#include <arch/vax/uba/ubareg.h>
#include <arch/vax/qbus/ubavar.h>
#include <arch/vax/uba/uba_common.h>

/*
 * The Q22 bus is the main IO bus on MicroVAX II/MicroVAX III systems.
 * It has an address space of 4MB (22 address bits), therefore the name,
 * and is hardware compatible with all 16 and 18 bits Q-bus devices.
 */
static	int	qba_match(struct device *, struct cfdata *, void *);
static	void	qba_attach(struct device *, struct device *, void *);
static	void	qba_beforescan(struct uba_softc*);
static	void	qba_init(struct uba_softc*);

struct	cfattach uba_ibus_ca = {
	sizeof(struct uba_vsoftc), (cfmatch_t)qba_match, qba_attach
};

extern	struct vax_bus_space vax_mem_bus_space;

int
qba_match(parent, vcf, aux)
	struct device *parent;
	struct cfdata *vcf;
	void *aux;
{
	struct	bp_conf *bp = aux;

	if (strcmp(bp->type, "uba"))
		return 0;

	return 1;
}

void
qba_attach(parent, self, aux)
	struct device *parent, *self;
	void *aux;
{
	struct uba_vsoftc *sc = (void *)self;

	printf(": Q22\n");
	/*
	 * Fill in bus specific data.
	 */
	sc->uv_sc.uh_beforescan = qba_beforescan;
	sc->uv_sc.uh_ubainit = qba_init;
	sc->uv_sc.uh_iot = &vax_mem_bus_space;
	sc->uv_sc.uh_dmat = &sc->uv_dmat;

	/*
	 * Fill in variables used by the sgmap system.
	 */
	sc->uv_size = QBASIZE;	/* Size in bytes of Qbus space */
	sc->uv_addr = QBAMAP;	/* Physical address of map registers */

	uba_dma_init(sc);
	uba_attach(&sc->uv_sc, QIOPAGE);
}

/*
 * Called when the QBA is set up; to enable DMA access from
 * QBA devices to main memory.
 */
void
qba_beforescan(sc)
	struct uba_softc *sc;
{
	bus_space_write_2(sc->uh_tag, sc->uh_ioh, QIPCR, Q_LMEAE);
}

void
qba_init(sc)
	struct uba_softc *sc;
{
	mtpr(0, PR_IUR);
	DELAY(500000);
	qba_beforescan(sc);
}


code:
/*	$OpenBSD: ubareg.h,v 1.15 2015/02/01 15:27:12 miod Exp $ */
/*	$NetBSD: ubareg.h,v 1.11 2000/01/24 02:40:36 matt Exp $ */

/*-
 * Copyright (c) 1982, 1986 The Regents of the University of California.
 * All rights reserved.
 * (c) UNIX System Laboratories, Inc.
 * All or some portions of this file are derived from material licensed
 * to the University of California by American Telephone and Telegraph
 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
 * the permission of UNIX System Laboratories, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)ubareg.h	7.8 (Berkeley) 5/9/91
 */

/*
 * VAX UNIBUS adapter registers
 */

/*
 * Size of unibus memory address space in pages
 * (also number of map registers).
 */
#define UBAPAGES	496
#define UBAIOADDR	0760000	 /* start of I/O page */
#define UBAIOPAGES	16
#define	UBAIOSIZE	(UBAIOPAGES * VAX_NBPG)	/* 8K I/O space */

/* Some Qbus-specific defines */
#define	QBAPAGES	8192
#define	QBASIZE		(QBAPAGES * VAX_NBPG)
#define	QBAMAP		0x20088000
#define	QIOPAGE		0x20000000

/*
 * Q-bus control registers
 */
#define QIPCR		0x1f40		/* from start of iopage */
/* bits in QIPCR */
#define Q_DBIRQ		0x0001		/* doorbell interrupt request */
#define Q_LMEAE		0x0020		/* local mem external access enable */
#define Q_DBIIE		0x0040		/* doorbell interrupt enable */
#define Q_AUXHLT	0x0100		/* auxiliary processor halt */
#define Q_DMAQPE	0x8000		/* Q22 bus address space parity error */


code: src/sys/arch/vax/vax

path: sys/arch/vax/vax/CVS/Repository


code:
/*	$OpenBSD: autoconf.c,v 1.40 2015/07/04 10:27:05 dlg Exp $	*/
/*	$NetBSD: autoconf.c,v 1.45 1999/10/23 14:56:05 ragge Exp $	*/

/*
 * Copyright (c) 1988 University of Utah.
 * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
 * Copyright (c) 1994 Ludd, University of Lule}, Sweden.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *     This product includes software developed at Ludd, University of Lule}.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/param.h>
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/reboot.h>
#include <sys/disklabel.h>
#include <sys/conf.h>
#include <sys/buf.h>

#include <uvm/uvm_extern.h>

#include <machine/cpu.h>
#include <machine/sid.h>
#include <machine/vmparam.h>
#include <machine/nexus.h>
#include <machine/clock.h>
#include <machine/rpb.h>
#ifdef VAX60
#include <vax/mbus/mbusreg.h>
#endif

#include <dev/cons.h>

#include "led.h"

#include <vax/vax/gencons.h>

void	dumpconf(void);	/* machdep.c */

struct cpu_dep *dep_call;

int	mastercpu;	/* chief of the system */

struct device *bootdv;
int booted_partition;	/* defaults to 0 (aka 'a' partition) */

void
cpu_configure(void)
{
	softintr_init();

	if (config_rootfound("mainbus", NULL) == NULL)
		panic("mainbus not configured");

	/*
	 * We're ready to start up. Clear CPU cold start flag.
	 */
	cold = 0;

	if (dep_call->cpu_clrf)
		(*dep_call->cpu_clrf)();
}

void
diskconf(void)
{
	if (bootdv == NULL)
		printf("boot device: unknown (rpb %d/%d)\n",
		    rpb.devtyp, rpb.unit);
	else
		printf("boot device: %s\n", bootdv->dv_xname);

	setroot(bootdv, booted_partition, RB_USERREQ);
	dumpconf();
}

int	mainbus_print(void *, const char *);
int	mainbus_match(struct device *, struct cfdata *, void *);
void	mainbus_attach(struct device *, struct device *, void *);

int
mainbus_print(void *aux, const char *hej)
{
	struct mainbus_attach_args *maa = aux;

	if (maa->maa_bustype == VAX_LEDS)
		return (QUIET);

	if (hej) {
		printf("nothing at %s", hej);
	}
	return (UNCONF);
}

int
mainbus_match(struct device *parent, struct cfdata *cf, void *aux)
{
	if (cf->cf_unit == 0 &&
	    strcmp(cf->cf_driver->cd_name, "mainbus") == 0)
		return 1; /* First (and only) mainbus */

	return (0);
}

void
mainbus_attach(struct device *parent, struct device *self, void *hej)
{
	struct mainbus_attach_args maa;

	printf("\n");

	maa.maa_bustype = vax_bustype;
	config_found(self, &maa, mainbus_print);

#if VAX53
	/* These models have both vsbus and ibus */
	if (vax_boardtype == VAX_BTYP_1303) {
		maa.maa_bustype = VAX_VSBUS;
		config_found(self, &maa, mainbus_print);
	}
#endif

#if NLED > 0
	maa.maa_bustype = VAX_LEDS;
	config_found(self, &maa, mainbus_print);
#endif

#if 1 /* boot blocks too old */
        if (rpb.rpb_base == (void *)-1)
                printf("\nWARNING: you must update your boot blocks.\n\n");
#endif

}

struct	cfattach mainbus_ca = {
	sizeof(struct device), (cfmatch_t) mainbus_match, mainbus_attach
};

struct  cfdriver mainbus_cd = {
	NULL, "mainbus", DV_DULL
};

#include "sd.h"
#include "cd.h"
#include "ra.h"

static int ubtest(void *);
static int jmfr(char *, struct device *, int);
static int booted_qe(struct device *, void *);
static int booted_le(struct device *, void *);
static int booted_ze(struct device *, void *);
static int booted_de(struct device *, void *);
#if NSD > 0 || NCD > 0
static int booted_sd(struct device *, void *);
#endif
#if NRA
static int booted_ra(struct device *, void *);
#endif
#if NRD
static int booted_rd(struct device *, void *);
#endif

int (*devreg[])(struct device *, void *) = {
	booted_qe,
	booted_le,
	booted_ze,
	booted_de,
#if NSD > 0 || NCD > 0
	booted_sd,
#endif
#if NRA
	booted_ra,
#endif
#if NRD
	booted_hd,
#endif
	0,
};

void
device_register(struct device *dev, void *aux)
{
	int (**dp)(struct device *, void *) = devreg;

	/* If there's a synthetic RPB, we can't trust it */
	if (rpb.rpb_base == (void *)-1)
		return;

	while (*dp) {
		if ((*dp)(dev, aux)) {
			if (bootdv == NULL)
				bootdv = dev;
			break;
		}
		dp++;
	}
}

/*
 * Simple checks. Return 1 on fail.
 */
int
jmfr(char *n, struct device *dev, int nr)
{
	if (rpb.devtyp != nr)
		return 1;
	return strcmp(n, dev->dv_cfdata->cf_driver->cd_name);
}

#include <arch/vax/qbus/ubavar.h>
int
ubtest(void *aux)
{
	paddr_t p;

	p = kvtophys(((struct uba_attach_args *)aux)->ua_ioh);
	if (rpb.csrphy != p)
		return 1;
	return 0;
}

#if 1 /* NDE */
int
booted_de(struct device *dev, void *aux)
{

	if (jmfr("de", dev, BDEV_DE) || ubtest(aux))
		return 0;

	return 1;
}
#endif /* NDE */

int
booted_le(struct device *dev, void *aux)
{
	if (jmfr("le", dev, BDEV_LE))
		return 0;
	return 1;
}

int
booted_ze(struct device *dev, void *aux)
{
	if (jmfr("ze", dev, BDEV_ZE))
		return 0;
	return 1;
}

#if 1 /* NQE */
int
booted_qe(struct device *dev, void *aux)
{
	if (jmfr("qe", dev, BDEV_QE) || ubtest(aux))
		return 0;

	return 1;
}
#endif /* NQE */

#if NSD > 0 || NCD > 0
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
int
booted_sd(struct device *dev, void *aux)
{
	struct scsi_attach_args *sa = aux;
	struct device *ppdev;

	/* Is this a SCSI device? */
	if (jmfr("sd", dev, BDEV_SD) && jmfr("cd", dev, BDEV_SD) &&
	    jmfr("sd", dev, BDEV_SDN) && jmfr("cd", dev, BDEV_SDN) &&
	    jmfr("sd", dev, BDEV_SDS) && jmfr("cd", dev, BDEV_SDS))
		return 0;

	if (sa->sa_sc_link->target != rpb.unit)
		return 0; /* Wrong unit */

	ppdev = dev->dv_parent->dv_parent;

	/* VS3100 NCR 53C80 (si) & VS4000 NCR 53C94 (asc) */
	if (((jmfr("ncr", ppdev, BDEV_SD) == 0) ||	/* old name */
	    (jmfr("asc", ppdev, BDEV_SD) == 0) ||
	    (jmfr("asc", ppdev, BDEV_SDN) == 0)) &&
	    (ppdev->dv_cfdata->cf_loc[0] == rpb.csrphy))
			return 1;

#ifdef VAX60
	/* VS35x0 (sii) */
	if (jmfr("sii", ppdev, BDEV_SDS) == 0 && rpb.csrphy ==
	    MBUS_SLOT_BASE(ppdev->dv_parent->dv_cfdata->cf_loc[0]))
		return 1;
#endif

	return 0; /* Where did we come from??? */
}
#endif

#if NRA
#include <arch/vax/mscp/mscp.h>
#include <arch/vax/mscp/mscpreg.h>
#include <arch/vax/mscp/mscpvar.h>
int
booted_ra(struct device *dev, void *aux)
{
	struct drive_attach_args *da = aux;
	struct mscp_softc *pdev = (void *)dev->dv_parent;
	paddr_t ioaddr;

	if (jmfr("ra", dev, BDEV_UDA))
		return 0;

	if (da->da_mp->mscp_unit != rpb.unit)
		return 0; /* Wrong unit number */

	ioaddr = kvtophys(pdev->mi_iph); /* Get phys addr of CSR */
	if (rpb.devtyp == BDEV_UDA && rpb.csrphy == ioaddr)
		return 1; /* Did match CSR */

	return 0;
}
#endif
#if NHD
int
booted_hd(struct device *dev, void *aux)
{
	int *nr = aux; /* XXX - use the correct attach struct */

	if (jmfr("hd", dev, BDEV_RD))
		return 0;

	if (*nr != rpb.unit)
		return 0;

	return 1;
}
#endif

struct nam2blk nam2blk[] = {
	{ "ra",          9 },
	{ "rx",         12 },
	{ "hd",		19 },
	{ "sd",         20 },
	{ "cd",         22 },
	{ "rd",         23 },
	{ "raid",       25 },
	{ "vnd",	18 },
	{ NULL,		-1 }
};