code:
/* $OpenBSD: mainbus.c,v 1.12 2014/12/08 13:24:04 aoyama Exp $ */
/* $NetBSD: mainbus.c,v 1.2 2000/01/07 05:13:08 nisimura Exp $ */

/*-
 * Copyright (c) 2000 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Tohru Nishimura.
 *
 * 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.
 */

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

#include <uvm/uvm_extern.h>

#include <machine/autoconf.h>
#include <machine/board.h>
#include <machine/cmmu.h>
#include <machine/cpu.h>

#include "lcd.h"
#include "pcex.h"

static const struct mainbus_attach_args devs[] = {
	{ "clock", 0x45000000, 6,  LUNA_88K|LUNA_88K2 }, /* Mostek/Dallas TimeKeeper */
#if NLCD > 0
	{ "lcd",   0x4d000000, -1, LUNA_88K|LUNA_88K2 }, /* Sharp LM16X212 LCD module */
#endif
	{ "le",	   0xf1000000, 4,  LUNA_88K|LUNA_88K2 }, /* Am7990 */
	{ "sio",   0x51000000, 5,  LUNA_88K|LUNA_88K2 }, /* uPD7201A */
	{ "fb",	   0xc1100000, -1, LUNA_88K|LUNA_88K2 }, /* BrookTree RAMDAC */
	{ "spc",   0xe1000000, 3,  LUNA_88K|LUNA_88K2 }, /* MB89352 */
	{ "spc",   0xe1000040, 3,  LUNA_88K2 },          /* ditto, LUNA-88K2 only */
	{ "cbus",  0x91000000, 4,  LUNA_88K2 },		 /* PC-9801 extension slot */
};

void	mainbus_attach(struct device *, struct device *, void *);
int	mainbus_match(struct device *, void *, void *);
int	mainbus_print(void *, const char *);
#ifdef MULTIPROCESSOR
extern void	cpu_setup_secondary_processors(void);	/* in machdep.c */
#endif

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

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

int
mainbus_match(parent, cf, args)
	struct device *parent;
	void *cf, *args;
{
	static int mainbus_matched;

	if (mainbus_matched)
		return (0);

	return ((mainbus_matched = 1));
}

void
mainbus_attach(parent, self, args)
	struct device *parent, *self;
	void *args;
{
	int i;
	extern int machtype;
	extern char cpu_model[];

	printf(": %s\n", cpu_model);

	/*
	 * Display cpu/mmu details for the main processor.
	 */
	cpu_configuration_print(1);

#ifdef MULTIPROCESSOR
	/*
	 * Let secondary processors initialize further and print
	 * their configuration information now.
	 */
	cpu_setup_secondary_processors();
#endif

	for (i = 0; i < sizeof(devs)/sizeof(devs[0]); i++)
		if (devs[i].ma_machine & machtype)
			config_found(self, (void *)&devs[i], mainbus_print);
}

int
mainbus_print(aux, pnp)
	void *aux;
	const char *pnp;
{
	struct mainbus_attach_args *ma = aux;

	if (pnp)
		printf("%s at %s", ma->ma_name, pnp);

	return (UNCONF);
}


code:
/*	$OpenBSD: pmap_table.c,v 1.13 2014/11/21 12:28:13 aoyama Exp $	*/

/*
 * Mach Operating System
 * Copyright (c) 1993-1992 Carnegie Mellon University
 * All Rights Reserved.
 *
 * Permission to use, copy, modify and distribute this software and its
 * documentation is hereby granted, provided that both the copyright
 * notice and this permission notice appear in all copies of the
 * software, derivative works or modified versions, and any portions
 * thereof, and that both notices appear in supporting documentation.
 *
 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
 *
 * Carnegie Mellon requests users of this software to return to
 *
 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
 *  School of Computer Science
 *  Carnegie Mellon University
 *  Pittsburgh PA 15213-3890
 *
 * any improvements or extensions that they make and grant Carnegie Mellon
 * the rights to redistribute these changes.
 */

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

#include <uvm/uvm_extern.h>

#include <machine/board.h>
#include <machine/pmap_table.h>

#define	R	PROT_READ
#define	RW	(PROT_READ | PROT_WRITE)
#define	CW	CACHE_WT
#define	CI	CACHE_INH
#define	CG	CACHE_GLOBAL

/*  start, size, prot, cacheability */
const struct pmap_table
luna88k_board_table[] = {
	{ PROM_ADDR,		PROM_SPACE,		R,	CI },
	{ FUSE_ROM_ADDR,	FUSE_ROM_SPACE,		R,	CI },
	{ NVRAM_ADDR,		NVRAM_SPACE,		RW,	CI },
	{ NVRAM_ADDR_88K2,	PAGE_SIZE,		RW,	CI },
	{ OBIO_PIO0_BASE,	PAGE_SIZE,		RW,	CI },
	{ OBIO_PIO1_BASE,	PAGE_SIZE,		RW,	CI },
	{ OBIO_SIO,		PAGE_SIZE,		RW,	CI },
	{ OBIO_TAS,		PAGE_SIZE,		RW,	CI },
	{ OBIO_CLOCK0,		PAGE_SIZE,		RW,	CI },
	{ INT_ST_MASK0,		PAGE_SIZE,		RW,	CI },
	{ SOFT_INT0,		PAGE_SIZE,		RW,	CI },
	{ SOFT_INT_FLAG0,	PAGE_SIZE,		RW,	CI },
	{ RESET_CPU0,		PAGE_SIZE,		RW,	CI },
	{ TRI_PORT_RAM,		TRI_PORT_RAM_SPACE,	RW,	CI },
#if 0
	{ EXT_A_ADDR,		EXT_A_SPACE,		RW,	CI },
	{ EXT_B_ADDR,		EXT_B_SPACE,		RW,	CI },
#endif
	{ PC_BASE,		PC_SPACE,		RW,	CI },
	{ MROM_ADDR,		MROM_SPACE,		R,	CI },
	{ BMAP_RFCNT,		PAGE_SIZE,		RW,	CI },
	{ BMAP_BMSEL,		PAGE_SIZE,		RW,	CI },
	{ BMAP_BMP,		BMAP_BMAP0 - BMAP_BMP,	RW,	CI, TRUE },
	{ BMAP_BMAP0,		BMAP_BMAP1 - BMAP_BMAP0, RW,	CI, TRUE },
	{ BMAP_BMAP1,		BMAP_BMAP2 - BMAP_BMAP1, RW,	CI, TRUE },
	{ BMAP_BMAP2,		BMAP_BMAP3 - BMAP_BMAP2, RW,	CI, TRUE },
	{ BMAP_BMAP3,		BMAP_BMAP4 - BMAP_BMAP3, RW,	CI, TRUE },
	{ BMAP_BMAP4,		BMAP_BMAP5 - BMAP_BMAP4, RW,	CI, TRUE },
	{ BMAP_BMAP5,		BMAP_BMAP6 - BMAP_BMAP5, RW,	CI, TRUE },
	{ BMAP_BMAP6,		BMAP_BMAP7 - BMAP_BMAP6, RW,	CI, TRUE },
	{ BMAP_BMAP7,		BMAP_FN - BMAP_BMAP7,	RW,	CI, TRUE },
	{ BMAP_FN,		PAGE_SIZE,		RW,	CI },
	{ BMAP_FN0,		PAGE_SIZE,		RW,	CI },
	{ BMAP_FN1,		PAGE_SIZE,		RW,	CI },
	{ BMAP_FN2,		PAGE_SIZE,		RW,	CI },
	{ BMAP_FN3,		PAGE_SIZE,		RW,	CI },
	{ BMAP_FN4,		PAGE_SIZE,		RW,	CI },
	{ BMAP_FN5,		PAGE_SIZE,		RW,	CI },
	{ BMAP_FN6,		PAGE_SIZE,		RW,	CI },
	{ BMAP_FN7,		PAGE_SIZE,		RW,	CI },
	{ BMAP_PALLET0,		PAGE_SIZE,		RW,	CI },
	{ BMAP_PALLET1,		PAGE_SIZE,		RW,	CI },
	{ BMAP_PALLET2,		PAGE_SIZE,		RW,	CI },
	{ BOARD_CHECK_REG,	PAGE_SIZE,		RW,	CI },
	{ BMAP_CRTC,		PAGE_SIZE,		RW,	CI },
	{ SCSI_ADDR,		PAGE_SIZE,		RW,	CI },
	{ LANCE_ADDR,		PAGE_SIZE,		RW,	CI },
	{ 0,			0xffffffff,		0,	0 },
};

const struct pmap_table *
pmap_table_build()
{
	return luna88k_board_table;
}

license: unknown


code:
/Makefile/1.1/Mon Oct 28 22:13:11 2013//TOPENBSD_5_8_BASE
/Makefile.inc/1.2/Wed Oct 30 20:39:05 2013//TOPENBSD_5_8_BASE
D/boot////


code:
#	$OpenBSD: Makefile,v 1.1 2013/10/28 22:13:11 miod Exp $
#	$NetBSD: Makefile,v 1.1 2013/01/06 07:04:49 tsutsui Exp $

.if ${MACHINE} == "luna88k"
SUBDIR= boot
.endif

.include <bsd.subdir.mk>


code:
#	$OpenBSD: Makefile.inc,v 1.2 2013/10/30 20:39:05 miod Exp $
#	$NetBSD: Makefile.inc,v 1.1 2013/01/06 07:04:49 tsutsui Exp $

NOPIE=
MDEC_DIR?=	/usr/mdec
CFLAGS+=	-Wall -Werror -fno-stack-protector
CFLAGS+=	-mmemcpy
CFLAGS+=	-fno-builtin-printf -fno-builtin-putchar -fno-builtin-vprintf


code:
#	$OpenBSD: Makefile,v 1.6 2014/02/23 20:01:04 miod Exp $
#	$NetBSD: Makefile,v 1.9 2013/01/22 15:48:40 tsutsui Exp $
#	@(#)Makefile	8.2 (Berkeley) 8/15/93

NOMAN= # defined

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

CPPFLAGS+=	-nostdinc -D_STANDALONE
CPPFLAGS+=	-I${.CURDIR} -I${.OBJDIR} -I${S} -I${S}/arch

CPPFLAGS+=	-DSUPPORT_DISK
CPPFLAGS+=	-DSUPPORT_ETHERNET
CPPFLAGS+=	-DSUPPORT_BOOTP
#CPPFLAGS+=	-DBOOTP_DEBUG -DNETIF_DEBUG -DETHER_DEBUG -DNFS_DEBUG
#CPPFLAGS+=	-DRPC_DEBUG -DRARP_DEBUG -DNET_DEBUG -DDEBUG -DPARANOID

OBJCOPY?=	objcopy
TEXTADDR=	0x700000	# 7MB
LDSCRIPT=	${.CURDIR}/boot.ldscript
LINKFORMAT=	-static -N -Ttext ${TEXTADDR} -T ${LDSCRIPT} \
		--warn-common -nopie

SRCS=	locore.S
SRCS+=	init_main.c
SRCS+=	fault.c setjmp.S
SRCS+=	bcd.c
SRCS+=	devopen.c
SRCS+=	conf.c
SRCS+=	getline.c parse.c
SRCS+=	boot.c
SRCS+=	cons.c prf.c awaitkey.c
SRCS+=	sio.c
SRCS+=	bmc.c bmd.c font.c kbd.c
SRCS+=	sc.c sd.c
SRCS+=	ufs_disksubr.c

# netboot support
SRCS+=	if_le.c lance.c getsecs.c
SRCS+=	dev_net.c

PROG=   boot

### find out what to use for libkern
.PATH:	${S}/lib/libkern
SRCS+=	memcpy.c strlcat.c strlcpy.c strlen.c
SRCS+=	muldi3.c negdi2.c ashrdi3.c

### find out what to use for libsa
.PATH:	${S}/lib/libsa
SRCS+=	strtol.c

SAREL=
SADST=	.
USE_LOADFILE=	yes
.include "${S}/lib/libsa/Makefile.inc"

LIBS=	${SALIB} ${ZLIB} ${KERNLIB}

${PROG}: ${LDSCRIPT} ${OBJS} ${LIBS}
	${LD} ${LINKFORMAT} -x -o ${PROG}.elf ${OBJS} ${LIBS}
	${OBJCOPY} -S -O a.out-m88k-openbsd --impure ${PROG}.elf ${PROG}

install: ${PROG}
	install -m 555 -g bin -o bin ${PROG} ${DESTDIR}${MDEC_DIR}

CLEANFILES+=	${PROG}.elf

.BEGIN:
	@([ -h machine ] || ln -s ${.CURDIR}/../../include machine)
	@([ -h m88k ] || ln -s ${.CURDIR}/../../../m88k/include m88k)

.include <bsd.prog.mk>


code:
/*	$OpenBSD: awaitkey.c,v 1.2 2013/10/29 21:49:07 miod Exp $	*/
/*	$NetBSD: awaitkey.c,v 1.1 2013/01/21 11:58:12 tsutsui Exp $	*/

/*-
 * Copyright (c) 2013 Izumi Tsutsui.  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.
 *
 * 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 <lib/libkern/libkern.h>
#include <luna88k/stand/boot/samachdep.h>

static void print_countdown(const char *, int);

#define FMTLEN	40

static void
print_countdown(const char *pfmt, int n)
{
	int len, i;
	char fmtbuf[FMTLEN];

	len = snprintf(fmtbuf, FMTLEN, pfmt, n);
	printf("%s", fmtbuf);
	for (i = 0; i < len; i++)
		putchar('\b');
}

/*
 * awaitkey(const char *pfmt, int timeout, int tell)
 *
 * Wait timeout seconds until any input from stdin.
 * print countdown message using "pfmt" if tell is nonzero.
 * Requires tgetchar(), which returns 0 if there is no input.
 */
char
awaitkey(const char *pfmt, int timeout, int tell)
{
	uint32_t otick;
	char c = 0;

	if (timeout <= 0)
		goto out;

	if (tell)
		print_countdown(pfmt, timeout);

	otick = getsecs();

	for (;;) {
		c = tgetchar();
		if (c != 0)
			break;
		if (getsecs() != otick) {
			otick = getsecs();
			if (--timeout == 0)
				break;
			if (tell)
				print_countdown(pfmt, timeout);
		}
	}

 out:
	if (tell) {
		printf(pfmt, timeout);
		printf("\n");
	}
	return c;
}


code:
/* $OpenBSD: bcd.c,v 1.1 2013/10/28 22:13:12 miod Exp $ */
/* $NetBSD: bcd.c,v 1.1 2006/03/11 15:40:07 kleink Exp $ */

/*
 * Convert a single byte between (unsigned) packed bcd and binary.
 * Public domain.
 */

#include <lib/libkern/libkern.h>

unsigned int
bcdtobin(unsigned int bcd)
{

        return (((bcd >> 4) & 0x0f) * 10 + (bcd & 0x0f));
}

unsigned int
bintobcd(unsigned int bin)
{

	return ((((bin / 10) << 4) & 0xf0) | (bin % 10));
}


code:
/*	$OpenBSD: bmc.c,v 1.1 2013/10/28 22:13:12 miod Exp $	*/
/*	$NetBSD: bmc.c,v 1.4 2013/01/21 11:58:12 tsutsui Exp $	*/

/*
 * Copyright (c) 1992 OMRON Corporation.
 *
 * This code is derived from software contributed to Berkeley by
 * OMRON Corporation.
 *
 * 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 by the University of
 *	California, Berkeley and its contributors.
 * 4. 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.
 *
 *	@(#)bmc.c	8.1 (Berkeley) 6/10/93
 */
/*
 * Copyright (c) 1992, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * OMRON Corporation.
 *
 * 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.
 *
 *	@(#)bmc.c	8.1 (Berkeley) 6/10/93
 */

/*
 * bmc.c -- bitmap console driver
 *   by A.Fujita, JUL-06-1992
 */

#include <sys/param.h>
#include <luna88k/stand/boot/samachdep.h>
#include <luna88k/stand/boot/rcvbuf.h>

/*
 * Following are all routines needed for SIO to act as console
 */
#include <dev/cons.h>

void
bmccnprobe(struct consdev *cp)
{
	/* serial console enabled? */
	if ((dipswitch & 0x4000) == 0) {
		cp->cn_pri = CN_DEAD;
		return;
	}

	/* frame buffer missing? */
	if (nplane == 0) {
		cp->cn_pri = CN_DEAD;
		return;
	}

	/* initialize required fields */
	cp->cn_dev = 1;
	cp->cn_pri = CN_LOWPRI;
}

void
bmccninit(struct consdev *cp)
{
	sioinit();
	bmdinit();
}

int
bmccngetc(dev_t dev)
{
	int c;
	int unit = 1;

	_siointr();
	if (RBUF_EMPTY(unit))
		return 0;

	POP_RBUF(unit, c);

	return(c);
/*
	return(siocngetc(dev));
 */
}

void
bmccnputc(dev_t dev, int c)
{
	bmdputc(c);
}


code:
/*	$OpenBSD: bmd.c,v 1.4 2013/10/29 21:49:07 miod Exp $	*/
/*	$NetBSD: bmd.c,v 1.2 2013/01/20 13:35:43 tsutsui Exp $	*/

/*
 * Copyright (c) 1992 OMRON Corporation.
 *
 * This code is derived from software contributed to Berkeley by
 * OMRON Corporation.
 *
 * 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 by the University of
 *	California, Berkeley and its contributors.
 * 4. 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.
 *
 *	@(#)bmd.c	8.2 (Berkeley) 8/15/93
 */
/*
 * Copyright (c) 1992, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * OMRON Corporation.
 *
 * 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.
 *
 *	@(#)bmd.c	8.2 (Berkeley) 8/15/93
 */
/*

 * bmd.c --- Bitmap-Display raw-level driver routines
 *
 *	by A.Fujita, SEP-09-1992
 */

#include <sys/param.h>
#include <machine/board.h>
#include <luna88k/stand/boot/samachdep.h>

/*
 *  RFCNT register
 */

union bmd_rfcnt {
	struct {
		short	rfc_hcnt;
		short	rfc_vcnt;
	} p;
	uint32_t u;
};

#define isprint(c)      ((c) >= 0x20 && (c) < 0x7f)

/*
 *  Width & Height
 */

#define	PB_WIDTH	2048			/* Plane Width   (Bit) */
#define	PB_HEIGHT	1024			/* Plane Height  (Bit) */
#define PS_WIDTH	128			/* Plane Width   (Short) */
#define P_WIDTH		256			/* Plane Width   (Byte) */

#define SB_WIDTH	1280			/* Screen Width  (Bit) */
#define	SB_HEIGHT	1024			/* Screen Height (Bit) */
#define SS_WIDTH	80			/* Screen Width  (Short) */
#define S_WIDTH		160			/* Screen Width  (Byte) */

#define FB_WIDTH	12			/* Font Width    (Bit) */
#define FB_HEIGHT	20			/* Font Height   (Bit) */

#define NEXT_LINE(addr)			((addr) + (PS_WIDTH * FB_HEIGHT))
#define SKIP_NEXT_LINE(addr)		(addr) += (PS_WIDTH - SS_WIDTH)

void	bmd_draw_char(char *, char *, int, int, int);
void	bmd_reverse_char(char *, char *, int, int);
void	bmd_erase_char(char *, char *, int, int);
void	bmd_erase_screen(volatile u_short *);
void	bmd_scroll_screen(volatile u_short *, volatile u_short *,
	    int, int, int, int);

struct bmd_linec {
	struct bmd_linec *bl_next;
	struct bmd_linec *bl_prev;
	int	bl_col;
	int	bl_end;
	u_char	bl_line[128];
};

struct bmd_softc {
	int	bc_stat;
	char   *bc_raddr;
	char   *bc_waddr;
	int	bc_xmin;
	int	bc_xmax;
	int	bc_ymin;
	int	bc_ymax;
	int	bc_col;
	int	bc_row;
	struct bmd_linec *bc_bl;
	char	bc_escseq[8];
	char   *bc_esc;
	void  (*bc_escape)(int);
};

#define	STAT_NORMAL	0x0000
#define	STAT_ESCAPE	0x0001
#define	STAT_INSERT	0x0100

struct	bmd_softc bmd_softc;
struct	bmd_linec bmd_linec[52];

void	bmd_escape(int);
void	bmd_escape_0(int);
void	bmd_escape_1(int);

/*
 * Escape-Sequence
 */

void
bmd_escape(int c)
{
	struct bmd_softc *bp = &bmd_softc;

	switch (c) {

	case '[':
		bp->bc_escape = bmd_escape_0;
		break;

	default:
		bp->bc_stat &= ~STAT_ESCAPE;
		bp->bc_esc = &bp->bc_escseq[0];
		bp->bc_escape = bmd_escape;
		break;
	}
}

void
bmd_escape_0(int c)
{
	struct bmd_softc *bp = &bmd_softc;
	struct bmd_linec *bq = bp->bc_bl;

	switch (c) {

	case 'A':
		if (bp->bc_row > bp->bc_ymin) {
			bp->bc_row--;
		}
		break;

	case 'C':
		if (bq->bl_col < bp->bc_xmax - 1) {
			bq->bl_col++;
		}
		break;

	case 'K':
		if (bq->bl_col < bp->bc_xmax) {
			int col;
			for (col = bq->bl_col; col < bp->bc_xmax; col++)
				bmd_erase_char(bp->bc_raddr,
					       bp->bc_waddr,
					       col, bp->bc_row);
		}
		bq->bl_end = bq->bl_col;
		break;

	case 'H':
		bq->bl_col = bq->bl_end = bp->bc_xmin;
		bp->bc_row = bp->bc_ymin;
		break;

	default:
/*
		*bp->bc_esc++ = c;
		bp->bc_escape = bmd_escape_1;
		return;
 */
		break;
	}

	bp->bc_stat &= ~STAT_ESCAPE;
	bp->bc_esc = &bp->bc_escseq[0];
	bp->bc_escape = bmd_escape;
}

void
bmd_escape_1(int c)
{
	struct bmd_softc *bp = &bmd_softc;
	struct bmd_linec *bq = bp->bc_bl;
	int col = 0, row = 0;
	char *p;

	switch (c) {

	case 'J':
		bp->bc_stat &= ~STAT_ESCAPE;
		bp->bc_esc = &bp->bc_escseq[0];
		bp->bc_escape = bmd_escape;
		break;

	case 'H':
		for (p = &bp->bc_escseq[0]; *p != ';'; p++)
			row = (row * 10) + (*p - 0x30);
		p++;
		for (p = &bp->bc_escseq[0]; p != bp->bc_esc; p++)
			col = (col * 10) + (*p - 0x30);

		bq->bl_col = col + bp->bc_xmin;
		bp->bc_row = row + bp->bc_ymin;

		bp->bc_stat &= ~STAT_ESCAPE;
		bp->bc_esc = &bp->bc_escseq[0];
		bp->bc_escape = bmd_escape;
		break;

	default:
		*bp->bc_esc++ = c;
		break;
	}
}

/*
 * Entry Routine
 */

void
bmdinit(void)
{
	volatile uint32_t *bmd_rfcnt = (volatile uint32_t *)BMAP_RFCNT;
	volatile long *bmd_bmsel = (volatile long *)BMAP_BMSEL;
	struct bmd_softc *bp = &bmd_softc;
	struct bmd_linec *bq;
	int i;
	union bmd_rfcnt rfcnt;

	/*
	 *  adjust plane position
	 */

	bp->bc_raddr = (char *)(BMAP_BMAP0 + 8);	/* plane-0 hardware address */
	bp->bc_waddr = (char *)(BMAP_BMP + 8);		/* common bitmap hardware address */
	rfcnt.p.rfc_hcnt = 7;				/* shift left   16 dot */
	rfcnt.p.rfc_vcnt = -27;				/* shift down    1 dot */
	*bmd_rfcnt = rfcnt.u;

	bp->bc_stat  = STAT_NORMAL;

	bp->bc_xmin  = 8;
	bp->bc_xmax  = 96;
	bp->bc_ymin  = 2;
	bp->bc_ymax  = 48;

	bp->bc_row = bp->bc_ymin;

	for (i = bp->bc_ymin; i < bp->bc_ymax; i++) {
		bmd_linec[i].bl_next = &bmd_linec[i+1];
		bmd_linec[i].bl_prev = &bmd_linec[i-1];
	}
	bmd_linec[bp->bc_ymax-1].bl_next = &bmd_linec[bp->bc_ymin];
	bmd_linec[bp->bc_ymin].bl_prev = &bmd_linec[bp->bc_ymax-1];

	bq = bp->bc_bl = &bmd_linec[bp->bc_ymin];
	bq->bl_col = bq->bl_end = bp->bc_xmin;

	bp->bc_col = bp->bc_xmin;

	bp->bc_esc = &bp->bc_escseq[0];
	bp->bc_escape = bmd_escape;

	*bmd_bmsel = 0xff;				/* all planes */
	bmd_erase_screen((u_short *) bp->bc_waddr);	/* clear screen */
	*bmd_bmsel = 0x01;				/* 1 plane */

							/* turn on  cursole */
	bmd_reverse_char(bp->bc_raddr,
			 bp->bc_waddr,
			 bq->bl_col, bp->bc_row);
}

void
bmdadjust(short hcnt, short vcnt)
{
	volatile uint32_t *bmd_rfcnt = (volatile uint32_t *)BMAP_RFCNT;
	union bmd_rfcnt rfcnt;

	printf("bmdadjust: hcnt = %d, vcnt = %d\n", hcnt, vcnt);

	rfcnt.p.rfc_hcnt = hcnt;		/* shift left   16 dot */
	rfcnt.p.rfc_vcnt = vcnt;		/* shift down    1 dot */

	*bmd_rfcnt = rfcnt.u;
}

int
bmdputc(int c)
{
	struct bmd_softc *bp = &bmd_softc;
	struct bmd_linec *bq = bp->bc_bl;
	int i;

	c &= 0x7F;
							/* turn off cursole */
	bmd_reverse_char(bp->bc_raddr,
			 bp->bc_waddr,
			 bq->bl_col, bp->bc_row);
							/* do escape-sequence */
	if (bp->bc_stat & STAT_ESCAPE) {
		*bp->bc_esc++ = c;
		(*bp->bc_escape)(c);
		goto done;
	}

	if (isprint(c)) {
		bmd_draw_char(bp->bc_raddr, bp->bc_waddr,
			      bq->bl_col, bp->bc_row, c);
		bq->bl_col++;
		bq->bl_end++;
		if (bq->bl_col >= bp->bc_xmax) {
			bq->bl_col = bq->bl_end = bp->bc_xmin;
			bp->bc_row++;
			if (bp->bc_row >= bp->bc_ymax) {
				bmd_scroll_screen((u_short *) bp->bc_raddr,
						  (u_short *) bp->bc_waddr,
						  bp->bc_xmin, bp->bc_xmax,
						  bp->bc_ymin, bp->bc_ymax);

				bp->bc_row = bp->bc_ymax - 1;
			}
		}
	} else {
		switch (c) {
		case 0x08:				/* BS */
			if (bq->bl_col > bp->bc_xmin) {
				bq->bl_col--;
			}
			break;

		case 0x09:				/* HT */
		case 0x0B:				/* VT */
			i = ((bq->bl_col / 8) + 1) * 8;
			if (i < bp->bc_xmax) {
				bq->bl_col = bq->bl_end = i;
			}
			break;

		case 0x0A:				/* NL */
			bp->bc_row++;
			if (bp->bc_row >= bp->bc_ymax) {
				bmd_scroll_screen((u_short *) bp->bc_raddr,
						  (u_short *) bp->bc_waddr,
						  bp->bc_xmin, bp->bc_xmax,
						  bp->bc_ymin, bp->bc_ymax);

				bp->bc_row = bp->bc_ymax - 1;
			}
			break;

		case 0x0D:				/* CR */
			bq->bl_col = bp->bc_xmin;
			break;

		case 0x1b:				/* ESC */
			bp->bc_stat |= STAT_ESCAPE;
			*bp->bc_esc++ = 0x1b;
			break;

		case 0x7F:				/* DEL */
			if (bq->bl_col > bp->bc_xmin) {
				bq->bl_col--;
				bmd_erase_char(bp->bc_raddr,
					       bp->bc_waddr,
					       bq->bl_col, bp->bc_row);
			}
			break;

		default:
			break;
		}
	}

 done:
							/* turn on  cursole */
	bmd_reverse_char(bp->bc_raddr,
			 bp->bc_waddr,
			 bq->bl_col, bp->bc_row);

	return(c);
}

void
bmdclear(void)
{
	struct bmd_softc *bp = &bmd_softc;
	struct bmd_linec *bq = bp->bc_bl;

	bmd_erase_screen((u_short *) bp->bc_waddr);	/* clear screen */

	bq->bl_col = bq->bl_end = bp->bc_xmin;
	bp->bc_row = bp->bc_ymin;

	bmd_reverse_char(bp->bc_raddr,
			 bp->bc_waddr,
			 bq->bl_col, bp->bc_row);	/* turn on  cursole */
}

/*
 *  charactor operation routines
 */

void
bmd_draw_char(char *raddr, char *waddr, int col, int row, int c)
{
	volatile u_short *p, *q;
	const u_short *fp;
	int i;

	fp = &bmdfont[c][0];

	switch (col % 4) {

	case 0:
		p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
		q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
		for (i = 0; i < FB_HEIGHT; i++) {
			*q = (*p & 0x000F) | (*fp & 0xFFF0);
			p += 128;
			q += 128;
			fp++;
		}
		break;

	case 1:
		p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
		q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
		for (i = 0; i < FB_HEIGHT; i++) {
			q[0] = (p[0] & 0xFFF0) | ((*fp & 0xF000) >> 12);
			q[1] = (p[1] & 0x00FF) | ((*fp & 0x0FF0) << 4);
			p += 128;
			q += 128;
			fp++;
		}
		break;

	case 2:
		p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 );
		q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 );
		for (i = 0; i < FB_HEIGHT; i++) {
			q[0] = (p[0] & 0xFF00) | ((*fp & 0xFF00) >> 8);
			q[1] = (p[1] & 0x0FFF) | ((*fp & 0x00F0) << 8);
			p += 128;
			q += 128;
			fp++;
		}
		break;

	case 3:
		p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 );
		q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 );
		for (i = 0; i < FB_HEIGHT; i++) {
			*q = (*p & 0xF000) | ((*fp & 0xFFF0) >> 4);
			p += 128;
			q += 128;
			fp++;
		}
		break;

	default:
		break;
	}
}

void
bmd_reverse_char(char *raddr, char *waddr, int col, int row)
{
	volatile u_short *p, *q;
	int i;

	switch (col%4) {

	case 0:
		p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
		q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
		for (i = 0; i < FB_HEIGHT; i++) {
			*q = (*p & 0x000F) | (~(*p) & 0xFFF0);
			p += 128;
			q += 128;
		}
		break;

	case 1:
		p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
		q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ));
		for (i = 0; i < FB_HEIGHT; i++) {
			q[0] = (p[0] & 0xFFF0) | (~p[0] & 0x000F);
			q[1] = (p[1] & 0x00FF) | (~p[1] & 0xFF00);
			p += 128;
			q += 128;
		}
		break;

	case 2:
		p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 );
		q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 2 );
		for (i = 0; i < FB_HEIGHT; i++) {
			q[0] = (p[0] & 0xFF00) | (~p[0] & 0x00FF);
			q[1] = (p[1] & 0x0FFF) | (~p[1] & 0xF000);
			p += 128;
			q += 128;
		}
		break;

	case 3:
		p = (u_short *) ( raddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 );
		q = (u_short *) ( waddr + (( row * FB_HEIGHT ) << 8 ) + (( col / 4 ) * 6 ) + 4 );
		for (i = 0; i < FB_HEIGHT; i++) {
			*q = (*p & 0xF000) | (~(*p) & 0x0FFF);
			p += 128;
			q += 128;
		}
		break;

	default:
		break;
	}
}

void
bmd_erase_char(char *raddr, char *waddr, int col, int row)
{
	bmd_draw_char(raddr, waddr, col, row, 0);

	return;
}

/*
 * screen operation routines
 */

void
bmd_erase_screen(volatile u_short *p)
{
	int i, j;

	for (i = 0; i < SB_HEIGHT; i++) {
		for (j = 0; j < SS_WIDTH; j++)
			*p++ = 0;
		SKIP_NEXT_LINE(p);
	}

	return;
}

void
bmd_scroll_screen(volatile u_short *p, volatile u_short *q,
    int xmin, int xmax, int ymin, int ymax)
{
	int i, j;

	p += ((PS_WIDTH * FB_HEIGHT) * (ymin + 1));
	q += ((PS_WIDTH * FB_HEIGHT) *  ymin);

	for (i = 0; i < ((ymax - ymin -1) * FB_HEIGHT); i++) {
		for (j = 0; j < SS_WIDTH; j++) {
			*q++ = *p++;
		}
		p += (PS_WIDTH - SS_WIDTH);
		q += (PS_WIDTH - SS_WIDTH);
	}

	for (i = 0; i < FB_HEIGHT; i++) {
		for (j = 0; j < SS_WIDTH; j++) {
			*q++ = 0;
		}
		q += (PS_WIDTH - SS_WIDTH);
	}

}


code:
/*	$OpenBSD: boot.c,v 1.4 2014/02/23 20:01:04 miod Exp $	*/
/*	$NetBSD: boot.c,v 1.3 2013/03/05 15:34:53 tsutsui Exp $	*/

/*
 * Copyright (c) 1992 OMRON Corporation.
 *
 * This code is derived from software contributed to Berkeley by
 * OMRON Corporation.
 *
 * 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 by the University of
 *	California, Berkeley and its contributors.
 * 4. 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	8.1 (Berkeley) 6/10/93
 */
/*
 * Copyright (c) 1992, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * OMRON Corporation.
 *
 * 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	8.1 (Berkeley) 6/10/93
 */

/*
 * boot.c -- boot program
 * by A.Fujita, MAR-01-1992
 */

#include <sys/param.h>
#include <sys/reboot.h>
#include <sys/stat.h>
#define _KERNEL
#include <sys/fcntl.h>
#undef _KERNEL

#include <lib/libkern/libkern.h>
#include <luna88k/stand/boot/samachdep.h>
#include <luna88k/stand/boot/status.h>
#include <lib/libsa/loadfile.h>

int howto;

int	loadrandom(const char *, char *, size_t);
#if 0
static int get_boot_device(const char *, int *, int *, int *);
#endif

void (*cpu_boot)(uint32_t, uint32_t);
uint32_t cpu_bootarg1;
uint32_t cpu_bootarg2;

char rnddata[BOOTRANDOM_MAX];

#if 0
int
get_boot_device(const char *s, int *devp, int *unitp, int *partp)
{
	const char *p = s;
	int unit = 0, part = 0;

	while (*p != '(') {
		if (*p == '\0')
			goto error;
		p++;
	}

	p++;
	for (; *p != ',' && *p != ')'; p++) {
		if (*p == '\0')
			goto error;
		if (*p >= '0' && *p <= '9')
			unit = (unit * 10) + (*p - '0');
	}

	if (*p == ',')
		p++;
	for (; *p != ')'; p++) {
		if (*p == '\0')
			goto error;
		if (*p >= '0' && *p <= '9')
			part = (part * 10) + (*p - '0');
	}

	*devp  = 0;	/* XXX not yet */
	*unitp = unit;	/* XXX should pass SCSI ID, not logical unit number */
	*partp = part;

	return 0;

error:
	return -1;
}
#endif

int
boot(int argc, char *argv[])
{
	char *line, *lparen, *rparen;
	char rndpath[MAXPATHLEN];
	static int rnd_loaded = 0;

	if (argc < 2)
		line = default_file;
	else
		line = argv[1];

	printf("Booting %s\n", line);

	/*
	 * Try and load randomness from the boot device.
	 */
	if (rnd_loaded == 0) {
		lparen = strchr(line, '(');
		if (lparen != NULL)
			rparen = strchr(line, ')');
		else
			rparen = NULL;
		if (rparen != NULL &&
		    rparen + 1 - line < sizeof rndpath) {
			rparen++;
			memcpy(rndpath, line, rparen - line);
			rndpath[rparen - line] = '\0';
			strlcat(rndpath, BOOTRANDOM, sizeof rndpath);
		} else
			strlcpy(rndpath, BOOTRANDOM, sizeof rndpath);

		rnd_loaded = loadrandom(rndpath, rnddata, sizeof(rnddata));
	}

	return bootunix(line);
}

int
bootunix(char *line)
{
	int io;
#if 0
	int dev, unit, part;
#endif
	u_long marks[MARK_MAX];

#if 0
	if (get_boot_device(line, &dev, &unit, &part) != 0) {
		printf("Bad file name %s\n", line);
		return ST_ERROR;
	}
#endif

	/* Note marks[MARK_START] is passed as an load address offset */
	memset(marks, 0, sizeof(marks));

	io = loadfile(line, marks, LOAD_KERNEL);
	if (io >= 0) {
#ifdef DEBUG
		printf("entry = 0x%lx\n", marks[MARK_ENTRY]);
		printf("ssym  = 0x%lx\n", marks[MARK_SYM]);
		printf("esym  = 0x%lx\n", marks[MARK_END]);
#endif

		cpu_bootarg1 = BOOT_MAGIC;
		cpu_bootarg2 = marks[MARK_END];
		cpu_boot = (void (*)(uint32_t, uint32_t))marks[MARK_ENTRY];
		(*cpu_boot)(cpu_bootarg1, cpu_bootarg2);
	}
	printf("Booting kernel failed. (%s)\n", strerror(errno));

	return ST_ERROR;
}

int
loadrandom(const char *name, char *buf, size_t buflen)
{
	struct stat sb;
	int fd;
	int rc = 0;

	fd = open(name, O_RDONLY);
	if (fd == -1) {
		if (errno != EPERM)
			printf("cannot open %s: %s\n", name, strerror(errno));
		return 0;
	}
	if (fstat(fd, &sb) == -1 || sb.st_uid != 0 || !S_ISREG(sb.st_mode) ||
	    (sb.st_mode & (S_IWOTH|S_IROTH)))
		goto fail;
	(void) read(fd, buf, buflen);
	rc = 1;
fail:
	close(fd);
	return rc;
}


code:
/*	$OpenBSD: boot.ldscript,v 1.2 2013/10/30 18:40:38 miod Exp $	*/

/*
 * Copyright (c) 2012 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.
 */

/*
 * This linker script is used to merge .rodata into .text and pad .text to
 * a page size. This allows objcopy to correctly be able to convert it to
 * an OMAGIC binary, suitable to be booted from the PROM.
 */
OUTPUT_FORMAT("elf32-m88k")
OUTPUT_ARCH(m88k)
ENTRY(__start)
SECTIONS
{
	.text :
	{
		*(.text)
		*(.rodata*)
		PROVIDE(etext = ABSOLUTE(.));
		FILL(0xf4005800)
		. = ALIGN(0x10);
	}
	.data :
	{
		*(.data)
		PROVIDE(edata = ABSOLUTE(.));
	}
	.bss :
	{
		*(.bss)
	}
	PROVIDE(end = ABSOLUTE(.));
	/DISCARD/ :
	{
		*(.comment)
	}
}


code:
/*	$OpenBSD: conf.c,v 1.3 2014/08/21 14:24:08 mpi Exp $	*/
/*	$NetBSD: conf.c,v 1.3 2013/01/16 15:46:20 tsutsui Exp $	*/

/*
 * Copyright (c) 1982, 1986, 1990, 1993
 *	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.
 *
 *	@(#)conf.c	8.1 (Berkeley) 6/10/93
 */

#include <sys/param.h>
#include <sys/socket.h>

#include <dev/cons.h>

#include <net/if.h>
#include <netinet/in.h>

#include <luna88k/stand/boot/samachdep.h>
#include <lib/libsa/nfs.h>
#include <lib/libsa/ufs.h>
#include "dev_net.h"

#define xxstrategy	\
	(int (*)(void *, int, daddr32_t, size_t, void *, size_t *))nullsys
#define xxopen		(int (*)(struct open_file *, ...))nodev
#define xxclose		(int (*)(struct open_file *))nullsys

/*
 * Device configuration
 */
#ifndef SUPPORT_ETHERNET
#define	netstrategy	xxstrategy
#define	netopen		xxopen
#define	netclose	xxclose
#else
#define	netstrategy	net_strategy
#define	netopen		net_open
#define	netclose	net_close
#endif
#define	netioctl	noioctl

#ifndef SUPPORT_DISK
#define	sdstrategy	xxstrategy
#define	sdopen		xxopen
#define	sdclose		xxclose
#endif
#define	sdioctl		noioctl

/*
 * Note: "le" isn't a major offset.
 */
struct devsw devsw[] = {
	{ "sd",	sdstrategy,	sdopen,	sdclose,	sdioctl },
	{ "le",	netstrategy,	netopen, netclose,	netioctl },
};
int	ndevs = sizeof(devsw) / sizeof(devsw[0]);

#ifdef SUPPORT_ETHERNET
extern struct netif_driver le_netif_driver;
struct netif_driver *netif_drivers[] = {
	&le_netif_driver,
};
int	n_netif_drivers = sizeof(netif_drivers) / sizeof(netif_drivers[0]);
#endif

/*
 * Filesystem configuration
 */
#define	FS_OPS(fs) { \
	__CONCAT(fs,_open), \
	__CONCAT(fs,_close), \
	__CONCAT(fs,_read), \
	__CONCAT(fs,_write), \
	__CONCAT(fs,_seek), \
	__CONCAT(fs,_stat) }
#ifdef SUPPORT_DISK
struct fs_ops file_system_disk[] = {
	FS_OPS(ufs),
};
int	nfsys_disk = sizeof(file_system_disk) / sizeof(file_system_disk[0]);
#endif
#ifdef SUPPORT_ETHERNET
struct fs_ops file_system_nfs[] = { FS_OPS(nfs) };
#endif

#define MAX_NFSYS	5
struct fs_ops file_system[MAX_NFSYS];
int	nfsys = 1;		/* we always know which one we want */

/*
 * Console configuration
 */

struct	consdev constab[] = {
	{ bmccnprobe,	bmccninit,	bmccngetc,	bmccnputc },
	{ siocnprobe,	siocninit,	siocngetc,	siocnputc },
	{ 0 },
};

struct consdev *cn_tab;


code:
/*	$OpenBSD: dev_net.c,v 1.3 2014/07/13 15:31:20 mpi Exp $	*/
/*	$NetBSD: dev_net.c,v 1.26 2011/07/17 20:54:52 joerg Exp $	*/

/*-
 * Copyright (c) 1997 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Gordon W. Ross.
 *
 * 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.
 */

/*
 * 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 <netinet/in.h>

#include <lib/libkern/libkern.h>

#include <lib/libsa/stand.h>
#include <lib/libsa/net.h>
#include <lib/libsa/netif.h>
#include <lib/libsa/nfs.h>
#include <lib/libsa/bootparam.h>
#include "dev_net.h"
#ifdef SUPPORT_BOOTP
#include <lib/libsa/bootp.h>
#endif

extern int nfs_root_node[];	/* XXX - get from nfs_mount() */

static int netdev_sock = -1;
static int netdev_opens;

static int net_getparams(int);

#ifdef DEBUG
int debug;
#endif

/*
 * Called by devopen after it sets f->f_dev to our devsw entry.
 * This opens the low-level device and sets f->f_devdata.
 * This is declared with variable arguments...
 */
int
net_open(struct open_file *f, ...)
{
	va_list ap;
	char *devname;		/* Device part of file name (or NULL). */
	int error = 0;

	va_start(ap, f);
	devname = va_arg(ap, char *);
	va_end(ap);

#ifdef	NETIF_DEBUG
	if (debug)
		printf("%s\n", devname);
#endif

	/* On first open, do netif open, mount, etc. */
	if (netdev_opens == 0) {
		/* Find network interface. */
		if (netdev_sock < 0) {
			netdev_sock = netif_open(devname);
			if (netdev_sock < 0) {
				printf("netif_open() failed\n");
				return ENXIO;
			}
#ifdef NETIF_DEBUG
			if (debug)
				printf("netif_open() succeeded\n");
#endif
		}
		if (rootip.s_addr == 0) {
			/* Get root IP address, and path, etc. */
			error = net_getparams(netdev_sock);
			if (error) {
				/* getparams makes its own noise */
				goto fail;
			}
			/* Get the NFS file handle (mountd). */
			error = nfs_mount(netdev_sock, rootip, rootpath);
			if (error) {
				printf("NFS mount error=%d\n", errno);
				rootip.s_addr = 0;
			fail:
				netif_close(netdev_sock);
				netdev_sock = -1;
				return error;
			}
#ifdef NETIF_DEBUG
			if (debug)
				printf("NFS mount succeeded\n");
#endif
		}
	}
	netdev_opens++;
	f->f_devdata = nfs_root_node;
	return error;
}

int
net_close(struct open_file *f)
{

#ifdef	NETIF_DEBUG
	if (debug)
		printf("net_close: opens=%d\n", netdev_opens);
#endif

	/* On last close, do netif close, etc. */
	f->f_devdata = NULL;
	/* Extra close call? */
	if (netdev_opens <= 0)
		return 0;
	netdev_opens--;
	/* Not last close? */
	if (netdev_opens > 0)
		return 0;
	rootip.s_addr = 0;
	if (netdev_sock >= 0) {
#ifdef NETIF_DEBUG
		if (debug)
			printf("net_close: calling netif_close()\n");
#endif
		netif_close(netdev_sock);
		netdev_sock = -1;
	}
	return 0;
}

int
net_ioctl(struct open_file *f, u_long cmd, void *data)
{

	return EIO;
}

int
net_strategy(void *devdata, int rw, daddr32_t blk, size_t size, void *buf,
	size_t *rsize)
{

	return EIO;
}

/*
 * 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)
 *
 * The default is to use the Sun bootparams RPC
 * (because that is what the kernel will do).
 * MD code can make try_bootp initialied data,
 * which will override this common definition.
 */
#ifdef	SUPPORT_BOOTP
int try_bootp;
#endif

static int
net_getparams(int sock)
{
	char buf[MAXHOSTNAMELEN];
	u_int32_t smask;

#ifdef	SUPPORT_BOOTP
	/*
	 * Try to get boot info using BOOTP.  If we succeed, then
	 * the server IP address, gateway, and root path will all
	 * be initialized.  If any remain uninitialized, we will
	 * use RARP and RPC/bootparam (the Sun way) to get them.
	 */
	if (try_bootp)
		bootp(sock);
	if (myip.s_addr != 0)
		return 0;
#ifdef NETIF_DEBUG
	if (debug)
		printf("BOOTP failed, trying RARP/RPC...\n");
#endif
#endif

	/*
	 * Use RARP to get our IP address.  This also sets our
	 * netmask to the "natural" default for our address.
	 */
	if (rarp_getipaddress(sock)) {
		printf("RARP failed\n");
		return EIO;
	}
#ifdef NETIF_DEBUG
	if (debug)
		printf("client addr: %s\n", inet_ntoa(myip));
#endif

	/* Get our hostname, server IP address, gateway. */
	if (bp_whoami(sock)) {
		printf("bootparam/whoami RPC failed\n");
		return EIO;
	}
#ifdef NETIF_DEBUG
	if (debug)
		printf("client name: %s\n", hostname);
#endif

	/*
	 * Ignore the gateway from whoami (unreliable).
	 * Use the "gateway" parameter instead.
	 */
	smask = 0;
	gateip.s_addr = 0;
	if (bp_getfile(sock, "gateway", &gateip, buf)) {
		printf("nfs_open: gateway bootparam missing\n");
	} else {
		/* Got it!  Parse the netmask. */
		smask = inet_addr(buf);
	}
	if (smask) {
		netmask = smask;
#ifdef NETIF_DEBUG
		if (debug)
			printf("subnet mask: %s\n", intoa(netmask));
#endif
	}
#ifdef NETIF_DEBUG
	if (debug)
		if (gateip.s_addr)
			printf("net gateway: %s\n", inet_ntoa(gateip));
#endif

	/* Get the root server and pathname. */
	if (bp_getfile(sock, "root", &rootip, rootpath)) {
		printf("bootparam/getfile RPC failed\n");
		return EIO;
	}

#ifdef NETIF_DEBUG
	if (debug) {
		printf("server addr: %s\n", inet_ntoa(rootip));
		printf("server path: %s\n", rootpath);
	}
#endif

	return 0;
}


code:
/*	$NetBSD: dev_net.h,v 1.6 2009/01/17 14:00:36 tsutsui Exp $	*/

int	net_open(struct open_file *, ...);
int	net_close(struct open_file *);
int	net_ioctl(struct open_file *, u_long, void *);
int	net_strategy(void *, int , daddr32_t , size_t, void *, size_t *);

#ifdef SUPPORT_BOOTP
extern int try_bootp;
#endif


code:
/*	$OpenBSD: devopen.c,v 1.2 2013/10/29 21:49:07 miod Exp $	*/
/*	$NetBSD: devopen.c,v 1.3 2013/01/16 15:46:20 tsutsui Exp $	*/

/*
 * Copyright (c) 1992 OMRON Corporation.
 *
 * This code is derived from software contributed to Berkeley by
 * OMRON Corporation.
 *
 * 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 by the University of
 *	California, Berkeley and its contributors.
 * 4. 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.
 *
 *	@(#)conf.c	8.1 (Berkeley) 6/10/93
 */
/*
 * Copyright (c) 1992, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * OMRON Corporation.
 *
 * 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.
 *
 *	@(#)conf.c	8.1 (Berkeley) 6/10/93
 */

#include <lib/libkern/libkern.h>
#include <luna88k/stand/boot/samachdep.h>
#include <machine/disklabel.h>

#define MAXDEVNAME	16

static int make_device(const char *, int *, int *, int *, char **);

int
devopen(struct open_file *f, const char *fname, char **file)
{
	int dev, unit, part;
	int error;
	struct devsw *dp;
	int i;

	if (make_device(fname, &dev, &unit, &part, file) != 0)
		return ENXIO;

#ifdef DEBUG
	printf("%s: %s(%d,%d)%s\n", __func__,
	    devsw[dev].dv_name, unit, part, *file);
#endif
	dp = &devsw[dev];
	error = (*dp->dv_open)(f, unit, part);
	if (error != 0) {
#ifdef DEBUG
		printf("%s: open %s(%d,%d)%s failed (%s)\n", __func__,
		    devsw[dev].dv_name, unit, part, *file, strerror(error));
#endif
		return error;
	}

	for (i = 0; i < nfsys_disk; i++)
		file_system[i] = file_system_disk[i];
	nfsys = nfsys_disk;

#ifdef SUPPORT_ETHERNET
	if (strcmp(dp->dv_name, "le") == 0) {
		/* XXX mixing local fs_ops on netboot could be troublesome */
		file_system[0] = file_system_nfs[0];
		nfsys = 1;
	}
#endif

	f->f_dev = dp;

	return 0;
}

int
make_device(const char *str, int *devp, int *unitp, int *partp, char **fname)
{
	const char *cp;
	struct devsw *dp;
	int major, unit = 0, part = 0;
	int i;
	char devname[MAXDEVNAME + 1];

	/*
	 * parse path strings
	 */
				/* find end of dev type name */
	for (cp = str, i = 0; *cp != '\0' && *cp != '(' && i < MAXDEVNAME; i++)
			devname[i] = *cp++;
	if (*cp != '(') {
		return (-1);
	}
	devname[i] = '\0';
				/* compare dev type name */
	for (dp = devsw; dp->dv_name; dp++)
		if (!strcmp(devname, dp->dv_name))
			break;
	cp++;
	if (dp->dv_name == NULL) {
		return (-1);
	}
	major = dp - devsw;
				/* get mixed controller and unit number */
	for (; *cp != ',' && *cp != ')'; cp++) {
		if (*cp == '\0')
			return -1;
		if (*cp >= '0' && *cp <= '9')
			unit = unit * 10 + *cp - '0';
	}
	if (unit < 0 || unit >= 20 || (unit % 10) > 7) {
#ifdef DEBUG
		printf("%s: invalid unit number (%d)\n", __func__, unit);
#endif
		return (-1);
	}
				/* get optional partition number */
	if (*cp == ',')
		cp++;

	for (; /* *cp != ',' && */ *cp != ')'; cp++) {
		if (*cp == '\0')
			return -1;
		if (*cp >= '0' && *cp <= '9')
			part = part * 10 + *cp - '0';
	}
	if (part < 0 || part >= MAXPARTITIONS) {
#ifdef DEBUG
		printf("%s: invalid partition number (%d)\n", __func__, part);
#endif
		return (-1);
	}
				/* check out end of dev spec */
	*devp  = major;
	*unitp = unit;
	*partp = part;
	cp++;
	if (*cp == '\0')
		*fname = "bsd";
	else
		*fname = (char *)cp;	/* XXX */
#ifdef DEBUG
	printf("%s: major = %d, unit = %d, part = %d, fname = %s\n",
	    __func__, major, unit, part, *fname);
#endif

	return 0;
}


code:
/*	$OpenBSD: fault.c,v 1.2 2014/03/29 18:09:29 guenther Exp $	*/

/*
 * Copyright (c) 2013 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.
 */

/*
 * Standalone code to recover from faults. Allows for hardware detection.
 */

#include <sys/param.h>

#include <machine/asm.h>
#include <machine/asm_macro.h>
#include <machine/psl.h>

typedef struct label_t {
        long val[19];
} label_t;

extern int setjmp(label_t *);
extern void longjmp(label_t *);

static label_t badaddr_jmpbuf;
static uint32_t badaddr_psr;

static uint32_t prom_vbr;
static uint32_t vector_page[512 * 2] __attribute__ ((__aligned__(0x1000)));

static __inline__ uint32_t
get_vbr()
{
	uint32_t vbr;
	__asm__ volatile ("ldcr %0, %%cr7" : "=r"(vbr));
	return vbr;
}

static __inline__ void
set_vbr(uint32_t vbr)
{
	__asm__ volatile ("stcr %0, %%cr7" :: "r"(vbr));
}

/*
 * This is an horribly crude logic to recover from data access exceptions
 * by longjmp'ing back to badaddr(). We should theoretically at least use
 * an `rte' somewhere to unfreeze the scoreboard. But since we restore a
 * PSR with interrupts disabled, this turns out to be safe.
 */
static void
libsa_fault_handler(void)
{
	set_psr(badaddr_psr | PSR_IND);	/* undo SFRZ */
	flush_pipeline();

	longjmp(&badaddr_jmpbuf);
	/* NOTREACHED */
}

static __inline__ uint32_t
br(uint32_t delta)
{
	return 0xc0000000 | (((int32_t)delta >> 2) & 0x03ffffff);
}

static void
libsa_fault_init()
{
	int vec;
	uint32_t *insn;
	uint32_t br_insn;

	prom_vbr = get_vbr();

	insn = vector_page;
	br_insn = br(prom_vbr - (uint32_t)&vector_page - 4);
	for (vec = 512; vec != 0; vec--) {
		*insn++ = 0xf4005800;	/* nop */
		*insn++ = br_insn;	/* br into prom vbr page */
	}

	/* override data access exception */
	vector_page[3 * 2 + 1] =
	    br((uint32_t)&libsa_fault_handler -
	       (uint32_t)&vector_page[3 * 2 + 1]);
}

int
badaddr(void *addr, int len)
{
	int rc;

	if (vector_page[0] == 0)
		libsa_fault_init();

	badaddr_psr = get_psr();
	set_psr(badaddr_psr | PSR_IND);

	set_vbr((uint32_t)&vector_page);

	if (setjmp(&badaddr_jmpbuf) == 0) {
		switch (len) {
		case 1:
			(void)*(volatile uint8_t *)addr;
			rc = 0;
			break;
		case 2:
			if ((uint32_t)addr & 1)
				rc = 1;
			else {
				(void)*(volatile uint16_t *)addr;
				rc = 0;
			}
			break;
		case 4:
			if ((uint32_t)addr & 3)
				rc = 1;
			else {
				(void)*(volatile uint32_t *)addr;
				rc = 0;
			}
			break;
		default:
			rc = 1;
			break;
		}
	} else {
		rc = 1;
	}

	set_vbr(prom_vbr);
	flush_pipeline();
	set_psr(badaddr_psr);

	return rc;
}