code:
/*	$OpenBSD: getsecs.c,v 1.3 2013/11/12 13:56:23 aoyama Exp $	*/
/*	$NetBSD: getsecs.c,v 1.1 2013/01/13 14:10:55 tsutsui Exp $	*/

/*-
 * Copyright (c) 2004 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by UCHIYAMA Yasushi.
 *
 * 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 <luna88k/stand/boot/samachdep.h>
#include <machine/board.h>
#include <luna88k/dev/timekeeper.h>

#define _DS_GET(off, data) \
	do { *chiptime = (off); (data) = (*chipdata); } while (0)
#define _DS_SET(off, data) \
	do { *chiptime = (off); *chipdata = (u_int8_t)(data); } while (0)

time_t
getsecs(void)
{
	u_int t;

	if (machtype == LUNA_88K) {
		volatile uint32_t *mclock =
		    (volatile uint32_t *)(NVRAM_ADDR + MK_NVRAM_SPACE);
		mclock[MK_CSR] |= MK_CSR_READ << 24;
		t =  bcdtobin(mclock[MK_SEC] >> 24);
		t += bcdtobin(mclock[MK_MIN] >> 24) * 60;
		t += bcdtobin(mclock[MK_HOUR] >> 24) * 60 * 60;
		mclock[MK_CSR] &= ~(MK_CSR_READ << 24);
	} else {
		volatile uint8_t *chiptime = (volatile uint8_t *)NVRAM_ADDR;
		volatile u_int8_t *chipdata = chiptime + 1;

		uint8_t c;

		/* specify 24hr and BCD mode */
		_DS_GET(DS_REGB, c);
		c |= DS_REGB_24HR;
		c &= ~DS_REGB_BINARY;
		_DS_SET(DS_REGB, c);

		/* update in progress; spin loop */
		for (;;) {
			*chiptime = DS_REGA;
			if ((*chipdata & DS_REGA_UIP) == 0)
				break;
		}

		*chiptime = DS_SEC;
		t =  bcdtobin(*chipdata);
		*chiptime = DS_MIN;
		t += bcdtobin(*chipdata) * 60;
		*chiptime = DS_HOUR;
		t += bcdtobin(*chipdata) * 60 * 60;
	}

	return (time_t)t;
}


code:
/*	$OpenBSD: if_le.c,v 1.4 2014/08/21 14:24:08 mpi Exp $	*/
/* $NetBSD: if_le.c,v 1.3 2013/01/22 15:48:40 tsutsui Exp $ */

/*
 * Copyright (c) 2013 Izumi Tsutsui.  All rights reserved.
 * Copyright (c) 2003 Tetsuya Isaki. 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.
 */
/*
 * Copyright (c) 1982, 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.
 *
 * from: hp300/dev/if_le.c      7.16 (Berkeley) 3/11/93
 *
 *      @(#)if_le.c     8.1 (Berkeley) 6/10/93
 */

#include <sys/param.h>

#include <netinet/in.h>

#include <luna88k/stand/boot/samachdep.h>
#include <machine/board.h>
#include <lib/libsa/net.h>
#include <lib/libsa/netif.h>

/* libsa netif_driver glue functions */
static int  le_match(struct netif *, void *);
static int  le_probe(struct netif *, void *);
static void le_init(struct iodesc *, void *);
static int  le_get(struct iodesc *, void *, size_t, time_t);
static int  le_put(struct iodesc *, void *, size_t);
static void le_end(struct netif *);

static void myetheraddr(uint8_t *);

/* libsa netif glue stuff */
struct netif_stats le_stats;
struct netif_dif le_ifs[] = {
	{ 0, 1, &le_stats, 0, 0, },
};

struct netif_driver le_netif_driver = {
	"le",
	le_match,
	le_probe,
	le_init,
	le_get,
	le_put,
	le_end,
	le_ifs,
	sizeof(le_ifs) / sizeof(le_ifs[0]),
};

int
leinit(void)
{
	void *cookie;
	void *reg, *mem;
	uint8_t eaddr[6];

	reg = (void *)LANCE_ADDR;
	mem = (void *)(TRI_PORT_RAM + 0x010000);	/* XXX */

	if (badaddr(reg, 4) != 0)
		return 0;

	myetheraddr(eaddr);

	cookie = lance_attach(0, reg, mem, eaddr);
	if (cookie == NULL)
		return 0;

	printf("le0: Ethernet address %s\n", ether_sprintf(eaddr));

	return 1;
}

static int
le_match(struct netif *nif, void *machdep_hint)
{
	void *cookie;
	uint8_t *eaddr;

	/* XXX should check nif_unit and unit number in machdep_hint path */

	cookie = lance_cookie(nif->nif_unit);
	if (cookie == NULL && nif->nif_unit == 0 && leinit() != 0)
		cookie = lance_cookie(nif->nif_unit);
	if (cookie == NULL)
		return 0;

	eaddr = lance_eaddr(cookie);
	if (eaddr == NULL)
		return 0;

	return 1;
}

static int
le_probe(struct netif *nif, void *machdep_hint)
{

	/* XXX what should be checked? */

	return 0;
}

static void
le_init(struct iodesc *desc, void *machdep_hint)
{
	struct netif *nif = desc->io_netif;
	struct netif_dif *dif = &nif->nif_driver->netif_ifs[nif->nif_unit];
	void *cookie;
	uint8_t *eaddr;

#ifdef DEBUG
	printf("%s\n", __func__);
#endif

	cookie = lance_cookie(nif->nif_unit);
	eaddr = lance_eaddr(cookie);

	lance_init(cookie);

	/* fill glue stuff */
	dif->dif_private = cookie;
	memcpy(desc->myea, eaddr, 6);
}

static int
le_get(struct iodesc *desc, void *pkt, size_t maxlen, time_t timeout)
{
	struct netif *nif = desc->io_netif;
	struct netif_dif *dif = &nif->nif_driver->netif_ifs[nif->nif_unit];
	void *cookie = dif->dif_private;
	int len = -1;
	time_t t;

	t = getsecs() + timeout;
	while (getsecs() < t) {
		len = lance_get(cookie, pkt, len);
		if (len > 0)
			break;
	}

	return len;
}

static int
le_put(struct iodesc *desc, void *pkt, size_t len)
{
	struct netif *nif = desc->io_netif;
	struct netif_dif *dif = &nif->nif_driver->netif_ifs[nif->nif_unit];
	void *cookie = dif->dif_private;
#ifdef DEBUG
 	struct ether_header *eh;

 	eh = pkt;
 	printf("dst:  %s\n", ether_sprintf(eh->ether_dhost));
 	printf("src:  %s\n", ether_sprintf(eh->ether_shost));
 	printf("type: 0x%x\n", eh->ether_type & 0xffff);
#endif

	return lance_put(cookie, pkt, len) ? len : -1;
}

static void
le_end(struct netif *nif)
{
	struct netif_dif *dif = &nif->nif_driver->netif_ifs[nif->nif_unit];
	void *cookie = dif->dif_private;

#ifdef DEBUG
	printf("%s\n", __func__);
#endif
	lance_end(cookie);
}

static void
myetheraddr(uint8_t *ether)
{
	unsigned int i, loc;
	volatile struct { uint32_t ctl; } *ds1220;

	switch (machtype) {
	case LUNA_88K:
		/*
		 * fuse_rom_data[] begins with "ENADDR=00000Axxxxxx"
		 */
		loc = 7;
		for (i = 0; i < 6; i++) {
			int u, l;

			u = fuse_rom_data[loc];
			u = (u < 'A') ? u & 0xf : u - 'A' + 10;
			l = fuse_rom_data[loc + 1];
			l = (l < 'A') ? l & 0xf : l - 'A' + 10;

			ether[i] = l | (u << 4);
			loc += 2;
		}
		break;
	case LUNA_88K2:
		ds1220 = (void *)(LANCE_ADDR + 8);
		loc = 12;
		for (i = 0; i < 6; i++) {
			unsigned int u, l, hex;

			ds1220->ctl = (loc) << 16;
			u = 0xf0 & (ds1220->ctl >> 12);
			ds1220->ctl = (loc + 1) << 16;
			l = 0x0f & (ds1220->ctl >> 16);
			hex = (u < '9') ? l : l + 9;

			ds1220->ctl = (loc + 2) << 16;
			u = 0xf0 & (ds1220->ctl >> 12);
			ds1220->ctl = (loc + 3) << 16;
			l = 0x0f & (ds1220->ctl >> 16);

			ether[i] = ((u < '9') ? l : l + 9) | (hex << 4);
			loc += 4;
		}
		break;
	default:
		ether[0] = 0x00; ether[1] = 0x00; ether[2] = 0x0a;
		ether[3] = 0xDE; ether[4] = 0xAD; ether[5] = 0x00;
		break;
	}
}

license: unknown


code:
/*	$OpenBSD: init_main.c,v 1.6 2014/02/23 20:01:04 miod Exp $	*/
/*	$NetBSD: init_main.c,v 1.6 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.
 *
 *	@(#)init_main.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.
 *
 *	@(#)init_main.c	8.2 (Berkeley) 8/15/93
 */
/*
 * Mach Operating System
 * Copyright (c) 1993-1991 Carnegie Mellon University
 * Copyright (c) 1991 OMRON Corporation
 * 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 AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
 * CONDITION.  CARNEGIE MELLON AND OMRON DISCLAIM 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 the
 * rights to redistribute these changes.
 */

#include <sys/param.h>
#include <machine/board.h>
#include <luna88k/stand/boot/samachdep.h>
#include <luna88k/stand/boot/status.h>
#include <lib/libsa/loadfile.h>
#include "dev_net.h"

static void get_fuse_rom_data(void);
static void get_nvram_data(void);
static int get_plane_numbers(void);
static const char *nvram_by_symbol(char *);

int cpuspeed;	/* for DELAY() macro */
int machtype;
char default_file[64];

uint16_t dipswitch = 0;
int nplane;

/* for command parser */

#define BUFFSIZE 100
#define MAXARGS  30

char buffer[BUFFSIZE];

int   argc;
char *argv[MAXARGS];

#define BOOT_TIMEOUT 5
int boot_timeout = BOOT_TIMEOUT;

static const char prompt[] = "boot> ";

int debug;

/*
 * FUSE ROM and NVRAM data
 */
struct fuse_rom_byte {
	u_int32_t h;
	u_int32_t l;
};
#define	FUSE_ROM_SPACE		1024
#define FUSE_ROM_BYTES		(FUSE_ROM_SPACE / sizeof(struct fuse_rom_byte))
char fuse_rom_data[FUSE_ROM_BYTES];

#define NNVSYM		8
#define NVSYMLEN	16
#define NVVALLEN	16
struct nvram_t {
	char symbol[1 + NVSYMLEN];
	char value[1 + NVVALLEN];
} nvram[NNVSYM];

int
main(void)
{
	int status = ST_NORMAL;
	const char *machstr;
	const char *nvv;
	int unit, part;

	/* Determine the machine type from FUSE ROM data.  */
	get_fuse_rom_data();
	if (strncmp(fuse_rom_data, "MNAME=LUNA88K+", 14) == 0)
		machtype = LUNA_88K2;
	else
		machtype = LUNA_88K;

	/*
	 * Initialize the console before we print anything out.
	 */
	if (machtype == LUNA_88K) {
		machstr  = "LUNA-88K";
		cpuspeed = MHZ_25;
	} else {
		machstr  = "LUNA-88K2";
		cpuspeed = MHZ_33;
	}

	nplane = get_plane_numbers();
	cninit();

	printf("\nOpenBSD/" MACHINE " (%s) boot 0.4\n\n", machstr);

#ifdef SUPPORT_ETHERNET
	try_bootp = 1;
#endif

        /* Determine the 'auto-boot' device from NVRAM data */
        get_nvram_data();

	nvv = nvram_by_symbol("boot_unit");
	if (nvv != NULL)
		unit = (int)strtol(nvv, NULL, 10);
	else
		unit = 0;
	nvv = nvram_by_symbol("boot_partition");
	if (nvv != NULL)
		part = (int)strtol(nvv, NULL, 10);
	else
		part = 0;

	nvv = nvram_by_symbol("boot_device");

	snprintf(default_file, sizeof(default_file),
	    "%s(%d,%d)%s", nvv != NULL ? nvv : "sd", unit, part, "bsd");

	/* auto-boot? (SW1) */
	if ((dipswitch & 0x8000) != 0) {
		char c;

		printf("Press return to boot now,"
		    " any other key for boot menu\n");
		printf("booting %s - starting in ", default_file);
		c = awaitkey("%d seconds. ", boot_timeout, 1);
		if (c == '\r' || c == '\n' || c == 0) {
			printf("auto-boot %s\n", default_file);
			bootunix(default_file);
		}
	}

	/*
	 * Main Loop
	 */

	printf("type \"help\" for help.\n");

	do {
		memset(buffer, 0, BUFFSIZE);
		if (getline(prompt, buffer) > 0) {
			argc = getargs(buffer, argv, sizeof(argv)/sizeof(char *));

			status = parse(argc, argv);
			if (status == ST_NOTFOUND)
				printf("unknown command \"%s\"\n", argv[0]);
		}
	} while (status != ST_EXIT);

	_rtt();
	/* NOTREACHED */
}

int
get_plane_numbers(void)
{
	int r = *((int *)0x1114);
	int n = 0;

	for (; r ; r >>= 1)
		if (r & 0x1)
			n++;

	return(n);
}

/* Get data from FUSE ROM */

void
get_fuse_rom_data(void)
{
	int i;
	struct fuse_rom_byte *p = (struct fuse_rom_byte *)FUSE_ROM_ADDR;

	for (i = 0; i < FUSE_ROM_BYTES; i++) {
		fuse_rom_data[i] =
		    (char)((((p->h) >> 24) & 0x000000f0) |
		           (((p->l) >> 28) & 0x0000000f));
		p++;
	}
}

/* Get data from NVRAM */

void
get_nvram_data(void)
{
	int i, j;
	u_int8_t *page;
	char buf[NVSYMLEN], *data;

	if (machtype == LUNA_88K) {
		data = (char *)(NVRAM_ADDR + 0x80);

		for (i = 0; i < NNVSYM; i++) {
			for (j = 0; j < NVSYMLEN; j++) {
				buf[j] = *data;
				data += 4;
			}
			strncpy(nvram[i].symbol, buf, sizeof(nvram[i].symbol));

			for (j = 0; j < NVVALLEN; j++) {
				buf[j] = *data;
				data += 4;
			}
			strncpy(nvram[i].value, buf, sizeof(nvram[i].value));
		}
	} else if (machtype == LUNA_88K2) {
		page = (u_int8_t *)(NVRAM_ADDR_88K2 + 0x20);

		for (i = 0; i < NNVSYM; i++) {
			*page = (u_int8_t)i;

			data = (char *)NVRAM_ADDR_88K2;
			strncpy(nvram[i].symbol, data, sizeof(nvram[i].symbol));

			data = (char *)(NVRAM_ADDR_88K2 + 0x10);
			strncpy(nvram[i].value, data, sizeof(nvram[i].value));
		}
	}
}

const char *
nvram_by_symbol(symbol)
	char *symbol;
{
	const char *value;
	int i;

	value = NULL;

	for (i = 0; i < NNVSYM; i++) {
		if (strncmp(nvram[i].symbol, symbol, NVSYMLEN) == 0) {
			value = nvram[i].value;
			break;
		}
	}

	return value;
}

void
_rtt(void)
{
	*(volatile unsigned int *)RESET_CPU_ALL = 0;
	for (;;) ;
	/* NOTREACHED */
}


code:
/*	$OpenBSD: kbd.c,v 1.1 2013/10/28 22:13:12 miod Exp $	*/
/*	$NetBSD: kbd.c,v 1.1 2013/01/05 17:44:24 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.
 *
 *	@(#)kbd.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.
 *
 *	@(#)kbd.c	8.1 (Berkeley) 6/10/93
 */

/*
 * kbd.c -- key-code decoding routine
 *   by A.Fujita, Dec-12-1992
 */

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

struct kbd_keymap kbd_keymap[] = {
	{ KC_IGNORE,	{ 0,	    0        } },	/*   0 [0x00]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*   1 [0x01]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*   2 [0x02]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*   3 [0x03]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*   4 [0x04]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*   5 [0x05]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*   6 [0x06]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*   7 [0x07]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*   8 [0x08]	      */
	{ KC_CODE,	{ 0x09,     0x09     } },	/*   9 [0x09]	TAB   */
	{ KC_SHIFT,	{ KS_CTRL,  KS_CTRL  } },	/*  10 [0x0A]	CTRL  */
	{ KC_IGNORE,	{ 0,        0        } },	/*  11 [0x0B]	      */
	{ KC_SHIFT,	{ KS_SHIFT, KS_SHIFT } },	/*  12 [0x0C]	SHIFT */
	{ KC_SHIFT,	{ KS_SHIFT, KS_SHIFT } },	/*  13 [0x0D]	SHIFT */
	{ KC_IGNORE,	{ 0,        0        } },	/*  14 [0x0E]	      */
	{ KC_SHIFT,	{ KS_META,  KS_META  } },	/*  15 [0x0F]	META  */
	{ KC_CODE,	{ 0x1B,     0x1B     } },	/*  16 [0x10]	ESC   */
	{ KC_CODE,	{ 0x08,	    0x08     } },	/*  17 [0x11]	BS    */
	{ KC_CODE,	{ 0x0D,	    0x0D     } },	/*  18 [0x12]	CR    */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  19 [0x13]	      */
	{ KC_CODE,	{ 0x20,	    0x20     } },	/*  20 [0x14]	SP    */
	{ KC_CODE,	{ 0x7F,	    0x7F     } },	/*  21 [0x15]	DEL   */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  22 [0x16]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  23 [0x17]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  24 [0x18]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  25 [0x19]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  26 [0x1A]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  27 [0x1B]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  28 [0x1C]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  29 [0x1D]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  30 [0x1E]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  31 [0x1F]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  32 [0x20]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  33 [0x21]	      */
	{ KC_CODE,	{ 0x31,	    0x21     } },	/*  34 [0x22]	 1    */
	{ KC_CODE,	{ 0x32,	    0x22     } },	/*  35 [0x23]	 2    */
	{ KC_CODE,	{ 0x33,	    0x23     } },	/*  36 [0x24]	 3    */
	{ KC_CODE,	{ 0x34,	    0x24     } },	/*  37 [0x25]	 4    */
	{ KC_CODE,	{ 0x35,	    0x25     } },	/*  38 [0x26]	 5    */
	{ KC_CODE,	{ 0x36,	    0x26     } },	/*  39 [0x27]	 6    */
	{ KC_CODE,	{ 0x37,	    0x27     } },	/*  40 [0x28]	 7    */
	{ KC_CODE,	{ 0x38,	    0x28     } },	/*  41 [0x29]	 8    */
	{ KC_CODE,	{ 0x39,	    0x29     } },	/*  42 [0x2A]	 9    */
	{ KC_CODE,	{ 0x30,	    0x30     } },	/*  43 [0x2B]	 0    */
	{ KC_CODE,	{ 0x2D,	    0x3D     } },	/*  44 [0x2C]	 -    */
	{ KC_CODE,	{ 0x5E,	    0x7E     } },	/*  45 [0x2D]	 ^    */
	{ KC_CODE,	{ 0x5C,	    0x7C     } },	/*  46 [0x2E]	 \    */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  47 [0x2F]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  48 [0x30]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  49 [0x31]	      */
	{ KC_CODE,	{ 0x71,	    0x51     } },	/*  50 [0x32]	 q    */
	{ KC_CODE,	{ 0x77,	    0x57     } },	/*  51 [0x33]	 w    */
	{ KC_CODE,	{ 0x65,	    0x45     } },	/*  52 [0x34]	 e    */
	{ KC_CODE,	{ 0x72,	    0x52     } },	/*  53 [0x35]	 r    */
	{ KC_CODE,	{ 0x74,	    0x54     } },	/*  54 [0x36]	 t    */
	{ KC_CODE,	{ 0x79,	    0x59     } },	/*  55 [0x37]	 y    */
	{ KC_CODE,	{ 0x75,	    0x55     } },	/*  56 [0x38]	 u    */
	{ KC_CODE,	{ 0x69,	    0x49     } },	/*  57 [0x39]	 i    */
	{ KC_CODE,	{ 0x6F,	    0x4F     } },	/*  58 [0x3A]	 o    */
	{ KC_CODE,	{ 0x70,	    0x50     } },	/*  59 [0x3B]	 p    */
	{ KC_CODE,	{ 0x40,	    0x60     } },	/*  60 [0x3C]	 @    */
	{ KC_CODE,	{ 0x5B,	    0x7B     } },	/*  61 [0x3D]	 [    */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  62 [0x3E]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  63 [0x3F]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  64 [0x40]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  65 [0x41]	      */
	{ KC_CODE,	{ 0x61,	    0x41     } },	/*  66 [0x42]	 a    */
	{ KC_CODE,	{ 0x73,	    0x53     } },	/*  67 [0x43]	 s    */
	{ KC_CODE,	{ 0x64,	    0x44     } },	/*  68 [0x44]	 d    */
	{ KC_CODE,	{ 0x66,	    0x46     } },	/*  69 [0x45]	 f    */
	{ KC_CODE,	{ 0x67,	    0x47     } },	/*  70 [0x46]	 g    */
	{ KC_CODE,	{ 0x68,	    0x48     } },	/*  71 [0x47]	 h    */
	{ KC_CODE,	{ 0x6A,	    0x4A     } },	/*  72 [0x48]	 j    */
	{ KC_CODE,	{ 0x6B,	    0x4B     } },	/*  73 [0x49]	 k    */
	{ KC_CODE,	{ 0x6C,	    0x4C     } },	/*  74 [0x4A]	 l    */
	{ KC_CODE,	{ 0x3B,	    0x2B     } },	/*  75 [0x4B]	 ;    */
	{ KC_CODE,	{ 0x3A,	    0x2A     } },	/*  76 [0x4C]	 :    */
	{ KC_CODE,	{ 0x5D,	    0x7D     } },	/*  77 [0x4D]	 ]    */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  78 [0x4E]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  79 [0x4F]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  80 [0x50]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  81 [0x51]	      */
	{ KC_CODE,	{ 0x7A,	    0x5A     } },	/*  82 [0x52]	 z    */
	{ KC_CODE,	{ 0x78,	    0x58     } },	/*  83 [0x53]	 x    */
	{ KC_CODE,	{ 0x63,	    0x43     } },	/*  84 [0x54]	 c    */
	{ KC_CODE,	{ 0x76,	    0x56     } },	/*  85 [0x55]	 v    */
	{ KC_CODE,	{ 0x62,	    0x42     } },	/*  86 [0x56]	 b    */
	{ KC_CODE,	{ 0x6E,	    0x4E     } },	/*  87 [0x57]	 n    */
	{ KC_CODE,	{ 0x6D,	    0x4D     } },	/*  88 [0x58]	 m    */
	{ KC_CODE,	{ 0x2C,	    0x3C     } },	/*  89 [0x59]	 ,    */
	{ KC_CODE,	{ 0x2E,	    0x3E     } },	/*  90 [0x5A]	 .    */
	{ KC_CODE,	{ 0x2F,	    0x3F     } },	/*  91 [0x5B]	 /    */
	{ KC_CODE,	{ 0x5F,	    0x5F     } },	/*  92 [0x5C]	 _    */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  93 [0x5D]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  94 [0x5E]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  95 [0x5F]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  96 [0x60]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  97 [0x61]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  98 [0x62]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/*  99 [0x63]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 100 [0x64]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 101 [0x65]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 102 [0x66]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 103 [0x67]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 104 [0x68]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 105 [0x69]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 106 [0x6A]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 107 [0x6B]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 108 [0x6C]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 109 [0x6D]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 110 [0x6E]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 111 [0x6F]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 112 [0x70]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 113 [0x71]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 114 [0x72]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 115 [0x73]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 116 [0x74]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 117 [0x75]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 118 [0x76]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 119 [0x77]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 120 [0x78]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 121 [0x79]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 122 [0x7A]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 123 [0x7B]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 124 [0x7C]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 125 [0x7D]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 126 [0x7E]	      */
	{ KC_IGNORE,	{ 0,	    0        } },	/* 127 [0x7F]	      */
};

int	shift_flag = 0;
int	ctrl_flag  = 0;
int	meta_flag  = 0;

int
kbd_decode(u_char code)
{
	unsigned int c, updown = 0;

	if (code & 0x80)
		updown = 1;

	code &= 0x7F;

	c = kbd_keymap[code].km_type;

	if (c == KC_IGNORE)
		return(KC_IGNORE);

	if ((c == KC_CODE) && updown)
		return(KC_IGNORE);

	if (c == KC_SHIFT) {
		switch(kbd_keymap[code].km_code[0]) {

		case KS_SHIFT:
			shift_flag = 1 - updown;
			break;

		case KS_CTRL:
			ctrl_flag  = 1 - updown;
			break;

		case KS_META:
			meta_flag  = 1 - updown;
			break;
		}

		return(KC_IGNORE);
	}

	if (shift_flag)
		c = kbd_keymap[code].km_code[1];
	else
		c = kbd_keymap[code].km_code[0];

	if (meta_flag)
		c |= 0x80;

	if (ctrl_flag)
		c &= 0x1F;

	return(c);
}


code:
/*	$OpenBSD: kbdreg.h,v 1.1 2013/10/28 22:13:12 miod Exp $	*/
/*	$NetBSD: kbdreg.h,v 1.1 2013/01/05 17:44:24 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.
 *
 *	@(#)kbdreg.h	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.
 *
 *	@(#)kbdreg.h	8.1 (Berkeley) 6/10/93
 */

/*
 * kbdreg.h --
 *
 */

struct kbd_keymap {
	int	km_type;
	int	km_code[2];
};

#define KC_CHAR		0x000000FF
#define KC_TYPE		0x0000FF00
#define	KC_CODE		0x00000000
#define	KC_SHIFT	0x00000100
#define	KC_IGNORE	0x0000FF00

#define KS_SHIFT	0
#define KS_CTRL		1
#define KS_META		2


code:
/*	$OpenBSD: lance.c,v 1.2 2013/10/29 21:49:07 miod Exp $	*/
/*	$NetBSD: lance.c,v 1.1 2013/01/13 14:10:55 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.
 */
/*-
 * Copyright (c) 2004 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by UCHIYAMA Yasushi.
 *
 * 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.
 */

/*
 * LANCE driver for LUNA
 * based on sys/arch/ews4800mips/stand/common/lance.c
 */

#include <luna88k/stand/boot/samachdep.h>

#include <dev/ic/am7990reg.h>
#include <dev/ic/lancereg.h>

#include <luna88k/stand/boot/lance.h>

static void lance_setup(struct le_softc *);
static int lance_set_initblock(struct le_softc *);
static int lance_do_initialize(struct le_softc *);

#define NLE	1	/* XXX for now */
static struct le_softc lesc[NLE];

void *
lance_attach(uint unit, void *reg, void *mem, uint8_t *eaddr)
{
	struct le_softc *sc;

	if (unit >= NLE) {
		printf("%s: invalid unit number\n", __func__);
		return NULL;
	}
	sc = &lesc[unit];

	if (sc->sc_reg != NULL) {
		printf("%s: unit %d is already attached\n", __func__, unit);
		return NULL;
	}
	sc->sc_reg = reg;
	sc->sc_mem = mem;
	memcpy(sc->sc_enaddr, eaddr, 6);

	return sc;
}

void *
lance_cookie(uint unit)
{
	struct le_softc *sc;

	if (unit >= NLE)
		return NULL;

	sc = &lesc[unit];

	if (sc->sc_reg == NULL)
		return NULL;

	return sc;
}

uint8_t *
lance_eaddr(void *cookie)
{
	struct le_softc *sc = cookie;

	if (sc == NULL || sc->sc_reg == NULL)
		return NULL;

	return sc->sc_enaddr;
}

int
lance_init(void *cookie)
{
	struct le_softc *sc = cookie;

	lance_setup(sc);

	if (!lance_set_initblock(sc))
		return 0;

	if (!lance_do_initialize(sc))
		return 0;

	return 1;
}

int
lance_get(void *cookie, void *data, size_t maxlen)
{
	struct le_softc *sc = cookie;
	struct lereg *lereg = sc->sc_reg;
	struct lemem *lemem = sc->sc_mem;
	struct lermd_v *rmd;
	uint16_t csr;
	int len = -1;

	lereg->ler_rap = LE_CSR0;
	if ((lereg->ler_rdp & LE_C0_RINT) != 0)
		lereg->ler_rdp = LE_C0_RINT;
	rmd = &lemem->lem_rmd[sc->sc_currmd];
	if ((rmd->rmd1_bits & LE_R1_OWN) != 0)
		return -1;

	csr = lereg->ler_rdp;
#if 0
	if ((csr & LE_C0_ERR) != 0)
		printf("%s: RX poll error (CSR=0x%x)\n", __func__, csr);
#endif
	if ((rmd->rmd1_bits & LE_R1_ERR) != 0) {
		printf("%s: RX error (rmd status=0x%x)\n", __func__,
		    rmd->rmd1_bits);
		goto out;
	}

	len = rmd->rmd3;
	if (len < LEMINSIZE + 4 || len > LEMTU) {
		printf("%s: RX error (bad length %d)\n", __func__, len);
		goto out;
	}
	len -= 4;
	memcpy(data, (void *)lemem->lem_rbuf[sc->sc_currmd], min(len, maxlen));

 out:
	rmd->rmd2 = -LEMTU;
	rmd->rmd1_bits = LE_R1_OWN;	/* return to LANCE */
	sc->sc_currmd = LE_NEXTRMD(sc->sc_currmd);

	return len;
}

int
lance_put(void *cookie, void *data, size_t len)
{
	struct le_softc *sc = cookie;
	struct lereg *lereg = sc->sc_reg;
	struct lemem *lemem = sc->sc_mem;
	struct letmd_v *tmd;
	uint16_t stat;
	int timeout;

	lereg->ler_rap = LE_CSR0;
	stat = lereg->ler_rdp;
	lereg->ler_rdp =
	    stat & (LE_C0_BABL | LE_C0_CERR | LE_C0_MISS | LE_C0_TINT);
#if 0
	if (stat & (LE_C0_BABL | LE_C0_CERR | LE_C0_MISS | LE_C0_MERR))
		printf("%s: TX error before xmit csr0=0x%x\n",
		    __func__, stat);
#endif

	/* setup TX descriptor */
	tmd = &lemem->lem_tmd[sc->sc_curtmd];
	while (tmd->tmd1_bits & LE_T1_OWN)
		continue;
	tmd->tmd1_bits = LE_T1_STP | LE_T1_ENP;
	memcpy((void *)lemem->lem_tbuf[sc->sc_curtmd], data, len);
	tmd->tmd2 = -max(len, LEMINSIZE);
	tmd->tmd3 = 0;

	/* start TX */
	tmd->tmd1_bits |= LE_T1_OWN;
	lereg->ler_rap = LE_CSR0;
	lereg->ler_rdp = LE_C0_TDMD;

	/* check TX complete */
	timeout = 0;
	do {
		lereg->ler_rap = LE_CSR0;
		stat = lereg->ler_rdp;
#if 0
		if (stat & LE_C0_ERR) {
			printf("%s: TX error (CSR0=%x)\n", __func__, stat);
			if (stat & LE_C0_CERR) {
				lereg->ler_rdp = LE_C0_CERR;
			}
		}
#endif
		if (timeout++ > 1000) {
			printf("%s: TX timeout (CSR0=%x)\n", __func__, stat);
			return 0;
		}
	} while ((stat & LE_C0_TINT) == 0);

	lereg->ler_rdp = LE_C0_TINT;

	sc->sc_curtmd = LE_NEXTTMD(sc->sc_curtmd);

	return 1;
}

int
lance_end(void *cookie)
{
	struct le_softc *sc = cookie;
	struct lereg *lereg = sc->sc_reg;

	lereg->ler_rap = LE_CSR0;
	lereg->ler_rdp = LE_C0_STOP;

	return 1;
}

static int
lance_set_initblock(struct le_softc *sc)
{
	struct lereg *lereg = sc->sc_reg;
	uint32_t addr = (uint32_t)sc->sc_mem;

	lereg->ler_rap = LE_CSR0;
	lereg->ler_rdp = LE_C0_STOP;	/* disable all external activity */
	DELAY(100);

	/* Set the correct byte swapping mode */
	lereg->ler_rap = LE_CSR3;
	lereg->ler_rdp = LE_C3_BSWP;

	/* Low address of init block */
	lereg->ler_rap = LE_CSR1;
	lereg->ler_rdp = addr & 0xfffe;

	/* High address of init block */
	lereg->ler_rap = LE_CSR2;
	lereg->ler_rdp = (addr >> 16) & 0x00ff;
	DELAY(100);

	return 1;
}

static int
lance_do_initialize(struct le_softc *sc)
{
	struct lereg *lereg = sc->sc_reg;
	uint16_t reg;
	int timeout;

	sc->sc_curtmd = 0;
	sc->sc_currmd = 0;

	/* Initialze LANCE */
	lereg->ler_rap = LE_CSR0;
	lereg->ler_rdp = LE_C0_INIT;

	/* Wait interrupt */
	timeout = 1000000;
	do {
		lereg->ler_rap = LE_CSR0;
		reg = lereg->ler_rdp;
		if (--timeout == 0) {
			printf("le: init timeout (CSR=0x%x)\n", reg);
			return 0;
		}
		DELAY(1);
	} while ((reg & LE_C0_IDON) == 0);

	lereg->ler_rap = LE_CSR0;
	lereg->ler_rdp = LE_C0_STRT | LE_C0_IDON;

	return 1;
}

static void
lance_setup(struct le_softc *sc)
{
	struct lereg *lereg = sc->sc_reg;
	struct lemem *lemem = sc->sc_mem;
	uint32_t addr;
	int i;

	/* make sure to stop LANCE chip before setup memory */
	lereg->ler_rap = LE_CSR0;
	lereg->ler_rdp = LE_C0_STOP;

	memset(lemem, 0, sizeof *lemem);

	/* Init block */
	lemem->lem_mode = LE_MODE_NORMAL;
	lemem->lem_padr[0] = (sc->sc_enaddr[1] << 8) | sc->sc_enaddr[0];
	lemem->lem_padr[1] = (sc->sc_enaddr[3] << 8) | sc->sc_enaddr[2];
	lemem->lem_padr[2] = (sc->sc_enaddr[5] << 8) | sc->sc_enaddr[4];
	/* Logical address filter */
	for (i = 0; i < 4; i++)
		lemem->lem_ladrf[i] = 0x0000;

	/* Location of Rx descriptor ring */
	addr = (uint32_t)lemem->lem_rmd;
	lemem->lem_rdra = addr & 0xffff;
	lemem->lem_rlen = LE_RLEN | ((addr >> 16) & 0xff);

	/* Location of Tx descriptor ring */
	addr = (uint32_t)lemem->lem_tmd;
	lemem->lem_tdra = addr & 0xffff;
	lemem->lem_tlen = LE_TLEN | ((addr >> 16) & 0xff);

	/* Rx descriptor */
	for (i = 0; i < LERBUF; i++) {
		addr = (uint32_t)lemem->lem_rbuf[i];
		lemem->lem_rmd[i].rmd0 = addr & 0xffff;
		lemem->lem_rmd[i].rmd1_hadr = (addr >> 16) & 0xff;
		lemem->lem_rmd[i].rmd1_bits = LE_R1_OWN;
		lemem->lem_rmd[i].rmd2 = LE_XMD2_ONES | -LEMTU;
		lemem->lem_rmd[i].rmd3 = 0;
	}

	/* Tx descriptor */
	for (i = 0; i < LETBUF; i++) {
		addr = (uint32_t)lemem->lem_tbuf[i];
		lemem->lem_tmd[i].tmd0 = addr & 0xffff;
		lemem->lem_tmd[i].tmd1_hadr = (addr >> 16) & 0xff;
		lemem->lem_tmd[i].tmd1_bits = 0;
		lemem->lem_tmd[i].tmd2 = LE_XMD2_ONES | 0;
		lemem->lem_tmd[i].tmd3 = 0;
	}
}


code:
/*	$OpenBSD: lance.h,v 1.1 2013/10/28 22:13:12 miod Exp $	*/
/*	$NetBSD: lance.h,v 1.1 2013/01/13 14:10:55 tsutsui Exp $ */

/*-
 * Copyright (c) 1982, 1992, 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.
 *
 * @(#)if_lereg.h	8.2 (Berkeley) 10/30/93
 */

#define	LEMTU		1518
#define	LEMINSIZE	60	/* should be 64 if mode DTCR is set */
#define	LERBUF		8
#define	LERBUFLOG2	3
#define	LE_RLEN		(LERBUFLOG2 << 13)
#define	LE_NEXTRMD(x)	(((x) + 1) & (LERBUF - 1))
#define	LETBUF		1
#define	LETBUFLOG2	0
#define	LE_TLEN		(LETBUFLOG2 << 13)
#define	LE_NEXTTMD(x)	(((x) + 1) & (LETBUF - 1))

/* Local Area Network Controller for Ethernet (LANCE) registers */
struct lereg {
	volatile uint16_t	ler_rdp;	/* register data port */
	uint16_t unused;
	volatile uint16_t	ler_rap;	/* register address port */
};

/*
 * lance memory
 */

/* receive message descriptors. bits/hadr are byte order dependent. */
struct	lermd_v {
	volatile uint16_t rmd0;		/* low address of packet */
#if BYTE_ORDER == BIG_ENDIAN
	volatile uint8_t  rmd1_bits;	/* descriptor bits */
	volatile uint8_t  rmd1_hadr;	/* high address of packet */
#else
	volatile uint8_t  rmd1_hadr;	/* high address of packet */
	volatile uint8_t  rmd1_bits;	/* descriptor bits */
#endif
	volatile int16_t  rmd2;		/* buffer byte count */
	volatile uint16_t rmd3;		/* message byte count */
};

/* transmit message descriptors */
struct	letmd_v {
	volatile uint16_t tmd0;		/* low address of packet */
#if BYTE_ORDER == BIG_ENDIAN
	volatile uint8_t  tmd1_bits;	/* descriptor bits */
	volatile uint8_t  tmd1_hadr;	/* high address of packet */
#else
	volatile uint8_t  tmd1_hadr;	/* high address of packet */
	volatile uint8_t  tmd1_bits;	/* descriptor bits */
#endif
	volatile int16_t  tmd2;		/* buffer byte count */
	volatile uint16_t tmd3;		/* transmit error bits */
};

struct lemem {
	/* initialization block */
	volatile uint16_t	lem_mode;	/* mode */
	volatile uint16_t	lem_padr[3];	/* physical address */
	volatile uint16_t	lem_ladrf[4];	/* logical address filter */
	volatile uint16_t	lem_rdra;	/* receive descriptor addr */
	volatile uint16_t	lem_rlen;	/* rda high and ring size */
	volatile uint16_t	lem_tdra;	/* transmit descriptor addr */
	volatile uint16_t	lem_tlen;	/* tda high and ring size */
	uint16_t		lem_pad0[4];
	struct lermd_v		lem_rmd[LERBUF];
	struct letmd_v		lem_tmd[LETBUF];
	volatile uint8_t	lem_rbuf[LERBUF][LEMTU];
	volatile uint8_t	lem_tbuf[LETBUF][LEMTU];
};

struct le_softc {
	struct lereg *sc_reg;
	struct lemem *sc_mem;
	uint8_t sc_enaddr[6];
	int sc_curtmd;
	int sc_currmd;
};


code:
/*	$OpenBSD: locore.S,v 1.2 2013/10/29 21:49:07 miod 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.
 */
/*
 * Mach Operating System
 * Copyright (c) 1993-1991 Carnegie Mellon University
 * Copyright (c) 1991 OMRON Corporation
 * 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 AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
 * CONDITION.  CARNEGIE MELLON AND OMRON DISCLAIM 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 the
 * rights to redistribute these changes.
 */

#define _KERNEL
#define _LOCORE

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

	.text

ASGLOBAL(__start)
	NOP
	NOP

ASLOCAL(main_start)
	/*
	 * We want to only run on one processors, but still allow the
	 * other processors to run the kernel after it is loaded.
	 *
	 * To achieve this, we will `park' secondary processors into
	 * a spin loop, which they will exit once the kernel entry
	 * point and arguments are known.
	 *
	 * They will then proceed to run the kernel, as if the kernel
	 * had been directly booted from the PROM.
	 */
	or.u	%r3,  %r0,  %hi16(_ASM_LABEL(cpu_park_address))
	or	%r3,  %r3,  %lo16(_ASM_LABEL(cpu_park_address))

	or.u	%r2,  %r0,  %hi16(_ASM_LABEL(cpu_park))
	or	%r2,  %r2,  %lo16(_ASM_LABEL(cpu_park))
	FLUSH_PIPELINE
	xmem	%r2,  %r3,  %r0

	bcnd	eq0,  %r2, 1f	/* master! causing all the others to park */
	jmp	%r2		/* park ourselves */

1:
	/* clear BSS */
	or.u	%r2, %r0, %hi16(_C_LABEL(edata))
	or	%r2, %r2, %lo16(_C_LABEL(edata))
	or.u	%r4, %r0, %hi16(_C_LABEL(end))
	or	%r4, %r4, %lo16(_C_LABEL(end))
1:	st	%r0, %r2, %r0
	addu	%r2, %r2, 4
	cmp	%r3, %r2, %r4
	bb1	ne,  %r3, 1b

	/* setup stack, below our image */
	or.u	%r31, %r0,  %hi16(_ASM_LABEL(__start))
	or	%r31, %r31, %lo16(_ASM_LABEL(__start))

	/* read dip switch settings */
	or.u	%r11, %r0,  %hi16(OBIO_PIO0A)
	ld.bu	%r10, %r11, %lo16(OBIO_PIO0A)
	mak	%r10, %r10, 0<8>
	ld.bu	%r12, %r11, %lo16(OBIO_PIO0B)
	or	%r10, %r10, %r12

	or.u	%r11, %r0,  %hi16(_C_LABEL(dipswitch))
	st.h	%r10, %r11, %lo16(_C_LABEL(dipswitch))

	bsr	_C_LABEL(main)
	bsr	_C_LABEL(_rtt)
1:	br	1b

ASLOCAL(cpu_park)
	/* spin a while */
	or.u	%r2,  %r0,  1
9:
	subu	%r2,  %r2,  1
	bcnd	ne0,  %r2,  9b

	/* if kernel entry point is known, exit */
	or.u	%r1,  %r0,  %hi16(_C_LABEL(cpu_boot))
	ld	%r1,  %r1,  %lo16(_C_LABEL(cpu_boot))
	bcnd	eq0,  %r1,  _ASM_LABEL(cpu_park)

	or.u	%r2,  %r0,  1
9:
	subu	%r2,  %r2,  1
	bcnd	ne0,  %r2,  9b

	or.u	%r2,  %r0, %hi16(_C_LABEL(cpu_bootarg1))
	ld	%r2,  %r2, %lo16(_C_LABEL(cpu_bootarg1))
	or.u	%r3,  %r0, %hi16(_C_LABEL(cpu_bootarg2))
	ld	%r3,  %r3, %lo16(_C_LABEL(cpu_bootarg2))

	jmp	%r1

GLOBAL(delay)
	bcnd	eq0, %r2, 2f
	or.u	%r3, %r0, %hi16(_C_LABEL(cpuspeed))
	ld	%r3, %r3, %lo16(_C_LABEL(cpuspeed))
	mul	%r4, %r2, %r3
	subu	%r4, %r4, 4
1:
	bcnd.n	gt0, %r4, 1b
	 subu	%r4, %r4, 2
2:
	jmp	%r1

	.data

ASLOCAL(cpu_park_address)
	.word	0


code:
/*	$OpenBSD: parse.c,v 1.1 2013/10/28 22:13:13 miod Exp $	*/
/*	$NetBSD: parse.c,v 1.4 2013/01/22 15:48:40 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.
 *
 *	@(#)parse.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.
 *
 *	@(#)parse.c	8.1 (Berkeley) 6/10/93
 */

/*
 * parse.c -- command parser
 * by A.Fujita, JAN-30-1992
 */

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

static int cmd_help(int, char *[]);

int
exit_program(int argc, char *argv[])
{
	return(ST_EXIT);
}

static const char helpmsg[] =
	"commands are:\n"
	"boot [device(unit,part)filename]\n"
	" (ex. \"boot sd(0,0)bsd\", \"boot le(0,0)obsd\" etc.)\n"
	"help\n"
	"exit\n"
;

static int
cmd_help(int argc, char *argv[])
{

	printf(helpmsg);
	return ST_NORMAL;
}

struct command_entry {
	char *name;
	int (*func)(int, char **);
};

struct command_entry entries[] = {
	{ "b",		boot         },
	{ "boot",	boot         },
	{ "exit",	exit_program },
	{ "help",	cmd_help     },
	{ "quit",	exit_program },
	{ 0, 0 }
};

int
parse(int argc, char *argv[])
{
	int i, status = ST_NOTFOUND;

	for (i = 0; entries[i].name != (char *) 0; i++) {
		if (!strcmp(argv[0], entries[i].name)) {
			status = (*entries[i].func)(argc, argv);
			break;
		}
	}

	return(status);
}

/*
 * getargs -- make argument arrays
 */

int
getargs(char buffer[], char *argv[], int maxargs)
{
	int n = 0;
	char *p = buffer;

	argv[n++] = p;
	while (*p != '\0') {
		if ( *p == ' ' ) {
			*p = '\0';
		} else if (p != buffer && *(p-1) == '\0') {
			if ( n < maxargs )
				argv[n++] = p;
		}
		p++;
	}

	return(n);
}


code:
/*	$OpenBSD: prf.c,v 1.1 2013/10/28 22:13:13 miod Exp $	*/
/*	$NetBSD: prf.c,v 1.3 2013/01/22 15:48:40 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.
 *
 *	@(#)prf.c	8.1 (Berkeley) 6/10/93
 */

#include <luna88k/stand/boot/samachdep.h>

int
getchar(void)
{
	int c;

	while ((c = cngetc()) == 0)
		;
	if (c == '\r')
		c = '\n';
	else if (c == ('c'&037)) {
		panic("^C");
		/* NOTREACHED */
	}
	return c;
}

int
tgetchar(void)
{
	int c;

	if ((c = cngetc()) == 0)
		return 0;

	if (c == '\r')
		c = '\n';
	else if (c == ('c'&037)) {
		panic("^C");
		/* NOTREACHED */
	}
	return c;
}

void
putchar(int c)
{
	cnputc(c);
	if (c == '\n')
		cnputc('\r');
}


code:
/*	$OpenBSD: rcvbuf.h,v 1.1 2013/10/28 22:13:13 miod Exp $	*/
/*	$NetBSD: rcvbuf.h,v 1.1 2013/01/05 17:44:24 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.
 *
 *	@(#)rcvbuf.h	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.
 *
 *	@(#)rcvbuf.h	8.1 (Berkeley) 6/10/93
 */

/*
 * rcvbuf.h -- receive buffer control structure definition
 *	by A.Fujita, Dec-12-1992
 */

#define	RBUF_SIZE	128

struct rcvbuf {
	u_char	* volatile rb_push;
	u_char	* volatile rb_pop;
	u_char	 rb_buf[RBUF_SIZE+4];
};

#define RBUF_INIT(n)	rcvbuf[n].rb_pop = rcvbuf[n].rb_push = &rcvbuf[n].rb_buf[RBUF_SIZE]

#define PUSH_RBUF(n, c)							\
do {									\
	*(--rcvbuf[n].rb_push) = c ;					\
	if (rcvbuf[n].rb_push == rcvbuf[n].rb_buf)			\
		rcvbuf[n].rb_push = &rcvbuf[n].rb_buf[RBUF_SIZE];	\
} while (/* CONSTCOND */0)

#define POP_RBUF(n, c)							\
do {									\
	c= *(--rcvbuf[n].rb_pop);					\
	if (rcvbuf[n].rb_pop == rcvbuf[n].rb_buf)			\
		rcvbuf[n].rb_pop = &rcvbuf[n].rb_buf[RBUF_SIZE];	\
} while (0)

#define RBUF_EMPTY(n)	(rcvbuf[n].rb_push == rcvbuf[n].rb_pop ? 1: 0)

extern	struct rcvbuf	rcvbuf[];


code:
/*	$OpenBSD: samachdep.h,v 1.3 2013/10/29 21:49:07 miod Exp $	*/
/*	$NetBSD: samachdep.h,v 1.10 2013/03/05 15:34:53 tsutsui Exp $	*/

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

#include <sys/param.h>
#include <lib/libsa/stand.h>

#define MHZ_25		25
#define MHZ_33		33

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

/* autoconf.c */
void configure(void);
void find_devs(void);

/* awaitkey.c */
char awaitkey(const char *, int, int);

/* bcd.c */
unsigned int bcdtobin(unsigned int);

/* bmc.c */
void bmccnprobe(struct consdev *);
void bmccninit(struct consdev *);
int  bmccngetc(dev_t);
void bmccnputc(dev_t, int);

/* bmd.c */
void bmdinit(void);
int bmdputc(int);
void bmdadjust(short, short);
void bmdclear(void);

/* boot.c */
extern int howto;
int boot(int, char **);
int bootunix(char *);

extern void (*cpu_boot)(uint32_t, uint32_t);
extern uint32_t cpu_bootarg1;
extern uint32_t cpu_bootarg2;
#define	BOOT_MAGIC	0xf1abde3f

/* cons.c */
void cninit(void);
int cngetc(void);
void cnputc(int);

/* fault.c */
int badaddr(void *, int);

/* font.c */
extern const u_short bmdfont[][20];

/* getline.c */
int getline(const char *, char *);

/* init_main.c */
extern int cpuspeed;
extern int nplane;
extern int machtype;
extern char default_file[];
extern char fuse_rom_data[];

/* kbd.c */
int kbd_decode(u_char);

/* lance.c */
void *lance_attach(uint, void *, void *, uint8_t *);
void *lance_cookie(uint);
uint8_t *lance_eaddr(void *);
int lance_init(void *);
int lance_get(void *, void *, size_t);
int lance_put(void *, void *, size_t);
int lance_end(void *);

/* locore.S */
extern u_int bootdev;
extern uint16_t dipswitch;
extern volatile uint32_t tick;
int setjmp(label_t *);
void delay(int);

/* prf.c */
int tgetchar(void);

/* parse.c */
int exit_program(int, char **);
int parse(int, char **);
int getargs(char *, char **, int);

/* sc.c */
struct scsi_softc;
int scinit(struct scsi_softc *, uint);
struct scsi_generic_cdb;
int scsi_immed_command(struct scsi_softc *, int, int, struct scsi_generic_cdb *,
    u_char *, unsigned int);
int scsi_request_sense(struct scsi_softc *, int, int, u_char *, unsigned int);
int scsi_test_unit_rdy(struct scsi_softc *, int, int);

/* sd.c */
int sdstrategy(void *, int, daddr32_t, size_t, void *, size_t *);
int sdopen(struct open_file *, ...);
int sdclose(struct open_file *);

/* sio.c */
void _siointr(void);
void siocnprobe(struct consdev *);
void siocninit(struct consdev *);
int  siocngetc(dev_t);
void siocnputc(dev_t, int);
void sioinit(void);

/* ufs_disklabel.c */
char *readdisklabel(struct scsi_softc *, uint, struct disklabel *);

#define DELAY(n)	delay(n)

extern	struct fs_ops file_system_disk[];
extern	int nfsys_disk;
extern	struct fs_ops file_system_nfs[];


code:
/*	$OpenBSD: sc.c,v 1.3 2013/10/29 21:49:07 miod Exp $	*/
/*	$NetBSD: sc.c,v 1.4 2013/01/22 15:48:40 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.
 *
 *	@(#)sc.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.
 *
 *	@(#)sc.c	8.1 (Berkeley) 6/10/93
 */

/*
 * sc.c -- SCSI Protocole Controller (SPC)  driver
 * remaked by A.Fujita, MAR-11-199
 */

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

#define SCSI_ID		7

int scintr(struct scsi_softc *);
void screset(struct scsi_softc *);
int issue_select(struct scsidevice *, u_char);
void ixfer_start(struct scsidevice *, int, u_char, int);
void ixfer_out(struct scsidevice *, int, u_char *);
void ixfer_in(struct scsidevice *, int, u_char *);
int scrun(struct scsi_softc *, uint, u_char *, int, u_char *, int,
    volatile int *);
int scfinish(struct scsi_softc *);
void scabort(struct scsi_softc *, struct scsidevice *);

/*
 * Initialize SPC & Data Structure
 */

int
scinit(struct scsi_softc *hs, uint unit)
{
	void *reg;

	switch (unit) {
	case 0:
		reg = (void *)SCSI_ADDR;
		break;
	case 1:
		reg = (void *)(SCSI_ADDR + 0x40);
		break;
	default:
		return 0;
	}

	if (unit != 0 && machtype != LUNA_88K2)
		return 0;

	hs->sc_sd     = (struct scsidevice *)reg;

	hs->sc_unit   = unit;
	hs->sc_flags  = 0;
	hs->sc_phase  = BUS_FREE_PHASE;
	hs->sc_target = SCSI_ID;

	hs->sc_cdb    = NULL;
	hs->sc_cdblen = 0;
	hs->sc_buf    = NULL;
	hs->sc_len    = 0;
	hs->sc_lock   = NULL;

	hs->sc_stat   = 0;
	hs->sc_msg[0] = 0;

	screset(hs);
	return(1);
}

void
screset(struct scsi_softc *hs)
{
	struct scsidevice *hd = hs->sc_sd;

#ifdef DEBUG
	printf("sc%d: ", hs->sc_unit);
#endif

	/*
	 * Disable interrupts then reset the FUJI chip.
	 */

	hd->scsi_sctl = SCTL_DISABLE | SCTL_CTRLRST;
	hd->scsi_scmd = 0;
	hd->scsi_pctl = 0;
	hd->scsi_temp = 0;
	hd->scsi_tch  = 0;
	hd->scsi_tcm  = 0;
	hd->scsi_tcl  = 0;
	hd->scsi_ints = 0;

#ifdef DEBUG
	/* We can use Asynchronous Transfer only */
	printf("async");
#endif

	/*
	 * Configure MB89352 with its SCSI address, all
	 * interrupts enabled & appropriate parity.
	 */
	hd->scsi_bdid = SCSI_ID;
	hd->scsi_sctl = SCTL_DISABLE | SCTL_ABRT_ENAB|
			SCTL_PARITY_ENAB | SCTL_RESEL_ENAB |
			SCTL_INTR_ENAB;
#ifdef DEBUG
	printf(", parity");
#endif

	DELAY(400);
	hd->scsi_sctl &= ~SCTL_DISABLE;

#ifdef DEBUG
	printf(", scsi id %d\n", SCSI_ID);
#endif
}

/*
 * SPC Arbitration/Selection routine
 */

int
issue_select(struct scsidevice *hd, u_char target)
{
	hd->scsi_pctl = 0;
	hd->scsi_temp = (1 << SCSI_ID) | (1 << target);

	/* select timeout is hardcoded to 250ms */
	hd->scsi_tch = 2;
	hd->scsi_tcm = 113;
	hd->scsi_tcl = 3;

	hd->scsi_scmd = SCMD_SELECT;

	return (1);
}

/*
 * SPC Manual Transfer routines
 */

/* not yet */

/*
 * SPC Program Transfer routines
 */

void
ixfer_start(struct scsidevice *hd, int len, u_char phase, int wait)
{
	hd->scsi_tch  = ((len & 0xff0000) >> 16);
	hd->scsi_tcm  = ((len & 0x00ff00) >>  8);
	hd->scsi_tcl  =  (len & 0x0000ff);
	hd->scsi_pctl = phase;
	hd->scsi_scmd = SCMD_XFR | SCMD_PROG_XFR;
}

void
ixfer_out(struct scsidevice *hd, int len, u_char *buf)
{
	for(; len > 0; len--) {
		while (hd->scsi_ssts & SSTS_DREG_FULL) {
			DELAY(5);
		}
		hd->scsi_dreg = *buf++;
	}
}

void
ixfer_in(struct scsidevice *hd, int len, u_char *buf)
{
	for (; len > 0; len--) {
		while (hd->scsi_ssts & SSTS_DREG_EMPTY) {
			DELAY(5);
		}
		*buf++ = hd->scsi_dreg;
	}
}

/*
 * SPC drive routines
 */

int
scrun(struct scsi_softc *hs, uint target, u_char *cdb, int cdblen, u_char *buf,
    int len, volatile int *lock)
{
	struct scsidevice *hd;

	hd = hs->sc_sd;

	if (hd->scsi_ssts & (SSTS_INITIATOR|SSTS_TARGET|SSTS_BUSY))
		return(0);

	if (target > 7)
		return 0;

	hs->sc_flags  = 0;
	hs->sc_phase  = ARB_SEL_PHASE;
	hs->sc_target = target >= 7 ? target : 6 - target;

	hs->sc_cdb    = cdb;
	hs->sc_cdblen = cdblen;
	hs->sc_buf    = buf;
	hs->sc_len    = len;
	hs->sc_lock   = lock;

	hs->sc_stat   = 0;
	hs->sc_msg[0] = 0;

	*(hs->sc_lock) = SC_IN_PROGRESS;
	issue_select(hd, hs->sc_target);

	return(1);
}

int
scfinish(struct scsi_softc *hs)
{
	int status = hs->sc_stat;

	hs->sc_flags  = 0;
	hs->sc_phase  = BUS_FREE_PHASE;
	hs->sc_target = SCSI_ID;

	hs->sc_cdb    = NULL;
	hs->sc_cdblen = 0;
	hs->sc_buf    = NULL;
	hs->sc_len    = 0;
	hs->sc_lock   = NULL;

	hs->sc_stat   = 0;
	hs->sc_msg[0] = 0;

	return(status);
}

void
scabort(struct scsi_softc *hs, struct scsidevice *hd)
{
	int len;
	u_char junk;

	printf("sc%d: abort  phase=0x%x, ssts=0x%x, ints=0x%x\n",
		hs->sc_unit, hd->scsi_psns, hd->scsi_ssts, hd->scsi_ints);

	if (hd->scsi_ints != 0)
		hd->scsi_ints = hd->scsi_ints;

	if (hd->scsi_psns == 0 || (hd->scsi_ssts & SSTS_INITIATOR) == 0)
		/* no longer connected to scsi target */
		return;

	/* get the number of bytes remaining in current xfer + fudge */
	len = (hd->scsi_tch << 16) | (hd->scsi_tcm << 8) | hd->scsi_tcl;

	/* for that many bus cycles, try to send an abort msg */
	for (len += 1024; (hd->scsi_ssts & SSTS_INITIATOR) && --len >= 0; ) {
		hd->scsi_scmd = SCMD_SET_ATN;

		while ((hd->scsi_psns & PSNS_REQ) == 0) {
			if (! (hd->scsi_ssts & SSTS_INITIATOR))
				goto out;
			DELAY(1);
		}

		if ((hd->scsi_psns & PHASE) == MESG_OUT_PHASE)
			hd->scsi_scmd = SCMD_RST_ATN;
		hd->scsi_pctl = hs->sc_phase = hd->scsi_psns & PHASE;

		if (hd->scsi_psns & PHASE_IO) {
			/* one of the input phases - read & discard a byte */
			hd->scsi_scmd = SCMD_SET_ACK;
			while (hd->scsi_psns & PSNS_REQ)
				DELAY(1);
			junk = hd->scsi_temp;
		} else {
			/* one of the output phases - send an abort msg */
			hd->scsi_temp = MSG_ABORT;
			hd->scsi_scmd = SCMD_SET_ACK;
			while (hd->scsi_psns & PSNS_REQ)
				DELAY(1);
		}

		hd->scsi_scmd = SCMD_RST_ACK;
	}
out:
	/*
	 * Either the abort was successful & the bus is disconnected or
	 * the device didn't listen.  If the latter, announce the problem.
	 * Either way, reset the card & the SPC.
	 */
	if (len < 0 && hs)
		printf("sc%d: abort failed.  phase=0x%x, ssts=0x%x\n",
			hs->sc_unit, hd->scsi_psns, hd->scsi_ssts);
}

/*
 * SCSI Command Handler
 */

int
scsi_test_unit_rdy(struct scsi_softc *sc, int target, int unit)
{
	static struct scsi_cdb6 cdb = { CMD_TEST_UNIT_READY };
	int status;
	volatile int lock;

#ifdef DEBUG
	printf("scsi_test_unit_rdy(%d,%d,%d): Start\n",
	    sc->sc_unit, target, unit);
#endif

	cdb.lun = unit;

	if (!(scrun(sc, target, (void *)&cdb, 6, NULL, 0, &lock))) {
#ifdef DEBUG
		printf("scsi_test_unit_rdy: Command Transfer Failed.\n");
#endif
		return(-1);
	}

	while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED)) {
		if (scintr(sc))
			DELAY(10);
	}

	status = scfinish(sc);

	if (lock == SC_IO_COMPLETE) {
#ifdef DEBUG
		printf("scsi_test_unit_rdy: Status -- 0x%x\n", status);
#endif
		return(status);
	} else {
		return(lock);
	}
}

int
scsi_request_sense(struct scsi_softc *sc, int target, int unit, u_char *buf,
    unsigned int len)
{
	static struct scsi_cdb6 cdb = {	CMD_REQUEST_SENSE };
	int status;
	volatile int lock;

#ifdef DEBUG
	printf("scsi_request_sense: Start\n");
#endif

	cdb.lun = unit;
	cdb.len = len;

	if (!(scrun(sc, target, (void *)&cdb, 6, buf, len, &lock))) {
#ifdef DEBUG
		printf("scsi_request_sense: Command Transfer Failed.\n");
#endif
		return(-1);
	}

	while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED)) {
		if (scintr(sc))
			DELAY(10);
	}

	status = scfinish(sc);

	if (lock == SC_IO_COMPLETE) {
#ifdef DEBUG
		printf("scsi_request_sense: Status -- 0x%x\n", status);
#endif
		return(status);
	} else {
		return(lock);
	}
}

int
scsi_immed_command(struct scsi_softc *sc, int target, int unit,
    struct scsi_generic_cdb *cdb, u_char *buf, unsigned int len)
{
	int status;
	volatile int lock;

#ifdef DEBUG
	printf("scsi_immed_command( %d, %d, %d, cdb(%d), buf, %d): Start\n",
	       sc->sc_unit, target, unit, cdb->len, len);
#endif

	cdb->cdb[1] |= unit << 5;

	if (!(scrun(sc, target, (void *)&cdb->cdb[0], cdb->len, buf, len,
	    &lock))) {
#ifdef DEBUG
		printf("scsi_immed_command: Command Transfer Failed.\n");
#endif
		return(-1);
	}

	while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED)) {
		if (scintr(sc))
			DELAY(10);
	}

	status = scfinish(sc);

	if (lock == SC_IO_COMPLETE) {
#ifdef DEBUG
		printf("scsi_immed_command: Status -- 0x%x\n", status);
#endif
		return(status);
	} else {
		return(lock);
	}
}

/*
 * Interrupt Routine
 */

int
scintr(struct scsi_softc *hs)
{
	struct scsidevice *hd;
	u_char ints, temp;
	u_char *buf;
	int i, len;

	hd = hs->sc_sd;
	if ((ints = hd->scsi_ints) == 0)
		return -1;

#ifdef DEBUG
	printf("scintr: INTS 0x%x, SSTS 0x%x,  PCTL 0x%x,  PSNS 0x%x    0x%x\n",
	        ints, hd->scsi_ssts, hd->scsi_pctl, hd->scsi_psns,
	        hs->sc_phase);
#endif
	if (ints & INTS_RESEL) {
		if (hs->sc_phase == BUS_FREE_PHASE) {
			temp = hd->scsi_temp & ~(1 << SCSI_ID);
			for (i = 0; temp != 1; i++) {
				temp >>= 1;
			}
			hs->sc_target = i;
			*(hs->sc_lock) = SC_IN_PROGRESS;
		} else
			goto abort;
	} else if (ints & INTS_DISCON) {
		if (hs->sc_msg[0] == MSG_CMD_COMPLETE ||
		    hs->sc_msg[0] == MSG_DISCONNECT) {
			hs->sc_phase  = BUS_FREE_PHASE;
			hs->sc_target = SCSI_ID;
			if (hs->sc_msg[0] == MSG_CMD_COMPLETE)
				/* SCSI IO complete */
				*(hs->sc_lock) = SC_IO_COMPLETE;
			else
				/* Cisconnected from Target */
				*(hs->sc_lock) = SC_DISCONNECTED;
			hd->scsi_ints = ints;
			return 0;
		} else
			goto abort;
	} else if (ints & INTS_CMD_DONE) {
		if (hs->sc_phase == BUS_FREE_PHASE)
			goto abort;
		else if (hs->sc_phase == MESG_IN_PHASE) {
			hd->scsi_scmd = SCMD_RST_ACK;
			hd->scsi_ints = ints;
			hs->sc_phase  = hd->scsi_psns & PHASE;
			return 0;
		}
		if (hs->sc_flags & SC_SEL_TIMEOUT)
			hs->sc_flags &= ~SC_SEL_TIMEOUT;
	} else if (ints & INTS_SRV_REQ) {
		if (hs->sc_phase != MESG_IN_PHASE)
			goto abort;
	} else if (ints & INTS_TIMEOUT) {
		if (hs->sc_phase == ARB_SEL_PHASE) {
			if (hs->sc_flags & SC_SEL_TIMEOUT) {
				hs->sc_flags &= ~SC_SEL_TIMEOUT;
				hs->sc_phase  = BUS_FREE_PHASE;
				hs->sc_target = SCSI_ID;
				/* Such SCSI Device is not conected. */
				*(hs->sc_lock) = SC_DEV_NOT_FOUND;
				hd->scsi_ints = ints;
				return 0;
			} else {
				/* wait more 250 usec */
				hs->sc_flags |= SC_SEL_TIMEOUT;
				hd->scsi_temp = 0;
				hd->scsi_tch  = 0;
				hd->scsi_tcm  = 0x06;
				hd->scsi_tcl  = 0x40;
				hd->scsi_ints = ints;
				return 0;
			}
		} else
			goto abort;
	} else
		goto abort;

	hd->scsi_ints = ints;

	/*
	 * Next SCSI Transfer
	 */

	while ((hd->scsi_psns & PSNS_REQ) == 0) {
		DELAY(1);
	}

	hs->sc_phase = hd->scsi_psns & PHASE;

	if (hs->sc_phase == DATA_OUT_PHASE || hs->sc_phase == DATA_IN_PHASE) {
		len = hs->sc_len;
		buf = hs->sc_buf;
	} else if (hs->sc_phase == CMD_PHASE) {
		len = hs->sc_cdblen;
		buf = hs->sc_cdb;
	} else if (hs->sc_phase == STATUS_PHASE) {
		len = 1;
		buf = &hs->sc_stat;
	} else {
		len = 1;
		buf = hs->sc_msg;
	}

	ixfer_start(hd, len, hs->sc_phase, 0);
	if (hs->sc_phase & PHASE_IO)
		ixfer_in(hd, len, buf);
	else
		ixfer_out(hd, len, buf);

	return 0;

	/*
	 * SCSI Abort
	 */
 abort:
	/* SCSI IO failed */
	scabort(hs, hd);
	hd->scsi_ints = ints;
	*(hs->sc_lock) = SC_IO_FAILED;
	return -1;
}


code:
/*	$OpenBSD: scsireg.h,v 1.2 2013/10/29 21:49:07 miod Exp $	*/
/*	$NetBSD: scsireg.h,v 1.2 2013/01/22 15:48:40 tsutsui Exp $	*/

/*
 * Copyright (c) 1990, 1992, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Van Jacobson of Lawrence Berkeley Laboratory.
 *
 * 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.
 *
 *	@(#)scsireg.h	8.1 (Berkeley) 6/10/93
 */

/*
 * MB89352 SCSI Protocol Controller Hardware Description.
 */

struct scsidevice {
	volatile u_char	scsi_bdid, p0, p1, p2;		/* 000 */
	volatile u_char	scsi_sctl, p3, p4, p5;		/* 004 */
#define			SCTL_DISABLE	0x80
#define			SCTL_CTRLRST	0x40
#define			SCTL_DIAG	0x20
#define			SCTL_ABRT_ENAB	0x10
#define			SCTL_PARITY_ENAB 0x08
#define			SCTL_SEL_ENAB	0x04
#define			SCTL_RESEL_ENAB	0x02
#define			SCTL_INTR_ENAB	0x01
	volatile u_char	scsi_scmd, p6, p7, p8;		/* 008 */
#define			SCMD_RST	0x10
#define			SCMD_ICPT_XFR	0x08
#define			SCMD_PROG_XFR	0x04
#define			SCMD_PAD	0x01	/* if initiator */
#define			SCMD_PERR_STOP	0x01	/* if target */
			/* command codes */
#define			SCMD_BUS_REL	0x00
#define			SCMD_SELECT	0x20
#define			SCMD_RST_ATN	0x40
#define			SCMD_SET_ATN	0x60
#define			SCMD_XFR	0x80
#define			SCMD_XFR_PAUSE	0xa0
#define			SCMD_RST_ACK	0xc0
#define			SCMD_SET_ACK	0xe0
	volatile u_char	scsi_tmod, p9, p10, p11;	/* 00C */
#define			TMOD_SYNC	0x80
	volatile u_char	scsi_ints, p12, p13, p14;	/* 010 */
#define			INTS_SEL	0x80
#define			INTS_RESEL	0x40
#define			INTS_DISCON	0x20
#define			INTS_CMD_DONE	0x10
#define			INTS_SRV_REQ	0x08
#define			INTS_TIMEOUT	0x04
#define			INTS_HARD_ERR	0x02
#define			INTS_RST	0x01
	volatile u_char	scsi_psns, p15, p16, p17;	/* 014 */
#define			PSNS_REQ	0x80
#define			PSNS_ACK	0x40
#define			PSNS_ATN	0x20
#define			PSNS_SEL	0x10
#define			PSNS_BSY	0x08
#define		scsi_sdgc scsi_psns
#define			SDGC_XFER_ENAB	0x20
	volatile u_char	scsi_ssts, p18, p19, p20;	/* 018 */
#define			SSTS_INITIATOR	0x80
#define			SSTS_TARGET	0x40
#define			SSTS_BUSY	0x20
#define			SSTS_XFR	0x10
#define			SSTS_ACTIVE	(SSTS_INITIATOR|SSTS_XFR)
#define			SSTS_RST	0x08
#define			SSTS_TCZERO	0x04
#define			SSTS_DREG_FULL	0x02
#define			SSTS_DREG_EMPTY	0x01
	volatile u_char	scsi_serr, p21, p22, p23;	/* 01C */
#define			SERR_SCSI_PAR	0x80
#define			SERR_SPC_PAR	0x40
#define			SERR_XFER_OUT	0x20
#define			SERR_TC_PAR	0x08
#define			SERR_PHASE_ERR	0x04
#define			SERR_SHORT_XFR	0x02
#define			SERR_OFFSET	0x01
	volatile u_char	scsi_pctl, p24, p25, p26;	/* 020 */
#define			PCTL_BFINT_ENAB	0x80
	volatile u_char	scsi_mbc,  p27, p28, p29;	/* 024 */
	volatile u_char	scsi_dreg, p30, p31, p32;	/* 028 */
	volatile u_char	scsi_temp, p33, p34, p35;	/* 02C */
	volatile u_char	scsi_tch,  p36, p37, p38;	/* 030 */
	volatile u_char	scsi_tcm,  p39, p40, p41;	/* 034 */
	volatile u_char	scsi_tcl,  p42, p43, p44;	/* 038 */
	volatile u_char	scsi_exbf, p45, p46, p47;	/* 03C */
};

/* psns/pctl phase lines as bits */
#define	PHASE_MSG	0x04
#define	PHASE_CD	0x02		/* =1 if 'command' */
#define	PHASE_IO	0x01		/* =1 if data inbound */
/* Phase lines as values */
#define	PHASE		0x07		/* mask for psns/pctl phase */
#define	DATA_OUT_PHASE	0x00
#define	DATA_IN_PHASE	0x01
#define	CMD_PHASE	0x02
#define	STATUS_PHASE	0x03
#define	BUS_FREE_PHASE	0x04
#define	ARB_SEL_PHASE	0x05	/* Fuji chip combines arbitration with sel. */
#define	MESG_OUT_PHASE	0x06
#define	MESG_IN_PHASE	0x07

/* SCSI Messages */

#define	MSG_CMD_COMPLETE	0x00
#define MSG_EXT_MESSAGE		0x01
#define	MSG_SAVE_DATA_PTR	0x02
#define	MSG_RESTORE_PTR		0x03
#define	MSG_DISCONNECT		0x04
#define	MSG_INIT_DETECT_ERROR	0x05
#define	MSG_ABORT		0x06
#define	MSG_REJECT		0x07
#define	MSG_NOOP		0x08
#define	MSG_PARITY_ERROR	0x09
#define	MSG_BUS_DEVICE_RESET	0x0C
#define	MSG_IDENTIFY		0x80
#define	MSG_IDENTIFY_DR		0xc0	/* (disconnect/reconnect allowed) */
#define	MSG_SYNC_REQ 		0x01

/* SCSI Commands */

#define CMD_TEST_UNIT_READY	0x00
#define CMD_REQUEST_SENSE	0x03
#define	CMD_INQUIRY		0x12
#define CMD_SEND_DIAGNOSTIC	0x1D

#define CMD_REWIND		0x01
#define CMD_FORMAT_UNIT		0x04
#define CMD_READ_BLOCK_LIMITS	0x05
#define CMD_REASSIGN_BLOCKS	0x07
#define CMD_READ		0x08
#define CMD_WRITE		0x0A
#define CMD_WRITE_FILEMARK	0x10
#define CMD_SPACE		0x11
#define CMD_MODE_SELECT		0x15
#define CMD_RELEASE_UNIT	0x17
#define CMD_ERASE		0x19
#define CMD_MODE_SENSE		0x1A
#define CMD_LOADUNLOAD		0x1B
#define CMD_RECEIVE_DIAG	0x1C
#define CMD_SEND_DIAG		0x1D
#define CMD_P_A_MEDIA_REMOVAL	0x1E
#define CMD_READ_CAPACITY	0x25
#define CMD_READ_EXT		0x28
#define CMD_WRITE_EXT		0x2A
#define CMD_READ_DEFECT_DATA	0x37
#define		SD_MANUFAC_DEFECTS	0x14000000
#define		SD_GROWN_DEFECTS	0x0c000000
#define CMD_READ_BUFFER		0x3B
#define CMD_WRITE_BUFFER	0x3C
#define CMD_READ_FULL		0xF0
#define CMD_MEDIA_TEST		0xF1
#define CMD_ACCESS_LOG		0xF2
#define CMD_WRITE_FULL		0xFC
#define CMD_MANAGE_PRIMARY	0xFD
#define CMD_EXECUTE_DATA	0xFE

/* SCSI status bits */

#define	STS_CHECKCOND	0x02	/* Check Condition (ie., read sense) */
#define	STS_CONDMET	0x04	/* Condition Met (ie., search worked) */
#define	STS_BUSY	0x08
#define	STS_INTERMED	0x10	/* Intermediate status sent */
#define	STS_EXT		0x80	/* Extended status valid */

/* command descriptor blocks */

struct scsi_cdb6 {
	u_char	cmd;		/* command code */
	u_char	lun:  3,	/* logical unit on ctlr */
		lbah: 5;	/* msb of read/write logical block addr */
	u_char	lbam;		/* middle byte of l.b.a. */
	u_char	lbal;		/* lsb of l.b.a. */
	u_char	len;		/* transfer length */
	u_char	xtra;
};

struct scsi_cdb10 {
	u_char	cmd;		/* command code */
	u_char	lun: 3,		/* logical unit on ctlr */
		   : 4,
		rel: 1;		/* l.b.a. is relative addr if =1 */
	u_char	lbah;		/* msb of read/write logical block addr */
	u_char	lbahm;		/* high middle byte of l.b.a. */
	u_char	lbalm;		/* low middle byte of l.b.a. */
	u_char	lbal;		/* lsb of l.b.a. */
	u_char	reserved;
	u_char	lenh;		/* msb transfer length */
	u_char	lenl;		/* lsb transfer length */
	u_char	xtra;
};

/* basic sense data */

struct scsi_sense {
	u_char	valid: 1,	/* l.b.a. is valid */
		class: 3,
		code:  4;
	u_char	vu:    4,	/* vendor unique */
		lbah:  4;
	u_char	lbam;
	u_char	lbal;
};

struct scsi_xsense {
	u_char	valid: 1,	/* l.b.a. is valid */
		class: 3,
		code:  4;
	u_char	segment;
	u_char	filemark: 1,
		eom:      1,
		ili:      1,	/* illegal length indicator */
		rsvd:	  1,
		key:	  4;
	u_char	info1;
	u_char	info2;
	u_char	info3;
	u_char	info4;
	u_char	len;		/* additional sense length */
};

/* inquiry data */
struct scsi_inquiry {
	u_char	type;
	u_char	qual;
	u_char	version;
	u_char	rsvd;
	u_char	len;
	char	class[3];
	char	vendor_id[8];
	char	product_id[16];
	char	rev[4];
};

struct scsi_generic_cdb {
	int len;		/* cdb length (in bytes) */
	u_char cdb[28];		/* cdb to use on next read/write */
};


code:
/*	$OpenBSD: scsivar.h,v 1.2 2013/10/29 21:49:07 miod Exp $	*/
/*	$NetBSD: scsivar.h,v 1.1 2013/01/05 17:44:24 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.
 *
 *	@(#)scsivar.h	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.
 *
 *	@(#)scsivar.h	8.1 (Berkeley) 6/10/93
 */

struct scsidevice;

struct	scsi_softc {
	struct	scsidevice *sc_sd;
	int	sc_unit;
	u_char	*sc_buf;				/* Data Buffer Pointor*/
	u_char	*sc_cdb;				/* CDB Buffer Pointor */
	volatile int *sc_lock;				/* Lock Flag addres   */
	int	sc_flags;				/* SPC Status Flags   */
	int	sc_phase;				/* Current SCSI Phase */
	int	sc_target;				/* Current Target ID  */
	int	sc_len;					/* Buffer Length      */
	int	sc_cdblen;				/* CDB length         */
	u_char	sc_stat;
	u_char	sc_msg[7];
};

/* sc_lock  */

#define	SC_IN_PROGRESS		 0
#define SC_IO_COMPLETE		 1
#define	SC_DISCONNECTED		 2

#define	SC_IO_FAILED		-1
#define	SC_DEV_NOT_FOUND	-2

/* sc_flags */

#define	SC_SEL_TIMEOUT	0x00000001