code:
/*      $OpenBSD: trap.h,v 1.13 2011/03/23 16:54:37 pirofti Exp $     */
/*      $NetBSD: trap.h,v 1.18 2000/06/04 02:19:26 matt Exp $     */

/*-
 * Copyright (c) 1990 The Regents of the University of California.
 * All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * William Jolitz.
 *
 * 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.
 *
 *	@(#)trap.h	5.4 (Berkeley) 5/9/91
 */

/*
 * Trap type values
 * also known in trap.c for name strings
 */
#ifndef _MACHINE_TRAP_H_
#define _MACHINE_TRAP_H_

#define	T_RESADFLT	0	/* reserved addressing */
#define	T_PRIVINFLT	1	/* privileged instruction */
#define	T_RESOPFLT	2	/* reserved operand */
#define	T_BPTFLT	3	/* breakpoint instruction */
#define	T_XFCFLT	4	/* Customer reserved instruction */
#define	T_SYSCALL	5	/* system call (kcall) */
#define	T_ARITHFLT	6	/* arithmetic trap */
#define	T_ASTFLT	7	/* system forced exception */
#define	T_PTELEN	8	/* Page table length exceeded */
#define	T_TRANSFLT	9	/* translation fault */
#define	T_TRCTRAP	10	/* trace trap */
#define	T_COMPAT	11	/* compatibility mode fault on VAX */
#define	T_ACCFLT	12	/* Access violation fault */
#define	T_KSPNOTVAL	15	/* kernel stack pointer not valid */
#define	T_KDBTRAP	17	/* kernel debugger trap */

/* These gets ORed with the word for page handling routines */
#define	T_WRITE		0x80
#define	T_PTEFETCH	0x40

/* Trap's coming from user mode */
#define	T_USER	0x100

#ifndef _LOCORE
struct	trapframe {
	long	fp;	/* Stack frame pointer */
	long	ap;     /* Argument pointer on user stack */
	long	sp;	/* Stack pointer */
	long	r0;     /* General registers saved upon trap/syscall */
	long	r1;
	long	r2;
	long	r3;
	long	r4;
	long	r5;
	long	r6;
	long	r7;
	long	r8;
	long	r9;
	long	r10;
	long	r11;
	long	trap;	/* Type of trap */
        long	code;   /* Trap specific code */
        long	pc;     /* User pc */
        long	psl;    /* User psl */
};

#endif /* _LOCORE */

#endif /* _MACHINE_TRAP_H_ */


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

#ifndef _MACHINE_UVAX_H_
#define _MACHINE_UVAX_H_

/*
 * Generic definitions common on all MicroVAXen clock chip.
 */
#define	uVAX_CLKVRT	0200
#define	uVAX_CLKUIP	0200
#define	uVAX_CLKRATE	040
#define	uVAX_CLKENABLE	06
#define	uVAX_CLKSET	0206

/* cpmbx bits  */
#define	uVAX_CLKHLTACT	03

/* halt action values */
#define	uVAX_CLKRESTRT	01
#define	uVAX_CLKREBOOT	02
#define	uVAX_CLKHALT	03

/* in progress flags */
#define	uVAX_CLKBOOT	04
#define	uVAX_CLKRSTRT	010
#define	uVAX_CLKLANG	0360

/*
 * Miscellaneous registers common on most VAXststions.
 */
struct vs_cpu {
        u_long  vc_hltcod;      /* Halt Code Register */
        u_long  vc_410mser;	/* VS2K */
        u_long  vc_410cear;	/* VS2K */
	u_char	vc_intmsk;	/* Interrupt mask register */
	u_char	vc_vdcorg;	/* Mono display origin */
	u_char	vc_vdcsel;	/* Video interrupt select */
	u_char	vc_intreq;	/* Interrupt request register */
#define	vc_intclr vc_intreq
        u_short vc_diagdsp;     /* Diagnostic display register */
        u_short pad4;
        u_long  vc_parctl;      /* Parity Control Register */
#define	vc_bwf0	vc_parctl
        u_short pad5;
        u_short pad6;
        u_short vc_diagtimu;	/* usecond timer KA46 */
        u_short vc_diagtme;     /* Diagnostic time register */
#define	vc_diagtimm vc_diagtme	/* msecond time KA46 */
};
#define	PARCTL_DMA	0x1000000
#define	PARCTL_CPEN	2
#define	PARCTL_DPEN	1

/*
 * Console Mailbox layout common to several models.
 */

struct cpmbx {
	unsigned int mbox_halt:2;	/* mailbox halt action */
	unsigned int mbox_bip:1;	/* bootstrap in progress */
	unsigned int mbox_rip:1;	/* restart in progress */
	unsigned int mbox_lang:4;	/* language info */
	unsigned int terminal:8;	/* terminal info */
	unsigned int keyboard:8;	/* keyboard info */
	unsigned int user_four:4;	/* unknown */
	unsigned int user_halt:3;	/* user halt action */
	unsigned int user_one:1;	/* unknown */
};

extern struct cpmbx *cpmbx;

void	generic_halt(void);
void	generic_reboot(int);

#define	MHALT_RESTART_REBOOT	0
#define	MHALT_RESTART		1
#define	MHALT_REBOOT		2
#define	MHALT_HALT		3

#define	UHALT_DEFAULT		0
#define	UHALT_RESTART		1
#define	UHALT_REBOOT		2
#define	UHALT_HALT		3
#define	UHALT_RESTART_REBOOT	4

#endif

license: unknown


code:
/*	$OpenBSD: varargs.h,v 1.6 2011/03/23 16:54:37 pirofti Exp $	*/
/*	$NetBSD: varargs.h,v 1.9 1995/12/26 01:16:35 mycroft Exp $	*/

/*-
 * Copyright (c) 1990 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.
 *
 *	@(#)varargs.h	5.3 (Berkeley) 4/3/91
 */

#ifndef _MACHINE_VARARGS_H_
#define	_MACHINE_VARARGS_H_

#include <machine/stdarg.h>

#if __GNUC__ == 1
#define	__va_ellipsis
#else
#define	__va_ellipsis	...
#endif

#define	va_alist	__builtin_va_alist
#define	va_dcl		long __builtin_va_alist; __va_ellipsis

#undef va_start
#define	va_start(ap) \
	((ap) = (va_list)&__builtin_va_alist)

#endif /* !_MACHINE_VARARGS_H_ */


code:
/*	$OpenBSD: vaxfp.h,v 1.2 2011/03/23 16:54:37 pirofti Exp $	*/
/*	$NetBSD: vaxfp.h,v 1.7 2008/04/28 20:23:39 martin Exp $	*/

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

/*
 * vaxfp.h defines the layout of VAX Floating-Point data types.
 * Only F_floating and D_floating types are defined here;
 * G_floating and H_floating are not supported by OpenBSD.
 */
#ifndef _MACHINE_VAXFP_H_
#define	_MACHINE_VAXFP_H_

#define	FFLT_EXPBITS	8
#define	FFLT_FRACHBITS	7
#define	FFLT_FRACLBITS	16
#define	FFLT_FRACBITS	(FFLT_FRACLBITS + FFLT_FRACHBITS)

struct vax_f_floating {
	unsigned int	fflt_frach:FFLT_FRACHBITS;
	unsigned int	fflt_exp:FFLT_EXPBITS;
	unsigned int	fflt_sign:1;
	unsigned int	fflt_fracl:FFLT_FRACLBITS;
};

#define	DFLT_EXPBITS	8
#define	DFLT_FRACHBITS	7
#define	DFLT_FRACMBITS	16
#define	DFLT_FRACLBITS	32
#define	DFLT_FRACBITS	(DFLT_FRACLBITS + DFLT_FRACMBITS + DFLT_FRACHBITS)

struct vax_d_floating {
	unsigned int	dflt_frach:DFLT_FRACHBITS;
	unsigned int	dflt_exp:DFLT_EXPBITS;
	unsigned int	dflt_sign:1;
	unsigned int	dflt_fracm:DFLT_FRACMBITS;
	unsigned int	dflt_fracl:DFLT_FRACLBITS;
};

/*
 * Exponent biases.
 */
#define	FFLT_EXP_BIAS	128
#define	DFLT_EXP_BIAS	128

/*
 * Convenience data structures.
 */
union vax_ffloating_u {
	float			ffltu_f;
	struct vax_f_floating	ffltu_fflt;
};

union vax_dfloating_u {
	double			dfltu_d;
	struct vax_d_floating	dfltu_dflt;
};

#endif /* _MACHINE_VAXFP_H_ */


code:
/*	$OpenBSD: vmparam.h,v 1.36 2014/01/30 18:16:41 miod Exp $	*/
/*	$NetBSD: vmparam.h,v 1.32 2000/03/07 00:05:59 matt Exp $	*/

/*-
 * Copyright (c) 1990 The Regents of the University of California.
 * All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * William Jolitz.
 *
 * Slightly modified for the VAX port /IC
 *
 * 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.
 *
 *	@(#)vmparam.h	5.9 (Berkeley) 5/12/91
 */
#ifndef _MACHINE_VMPARAM_H_
#define _MACHINE_VMPARAM_H_

/*
 * Machine dependent constants for VAX.
 */

/*
 * USRTEXT is the start of the user text/data space, while USRSTACK
 * is the top (end) of the user stack. Immediately above the user stack
 * resides kernel.
 */

#define USRTEXT		PAGE_SIZE
#define USRSTACK	KERNBASE

/*
 * Virtual memory related constants, all in bytes
 */

#ifndef MAXTSIZ
#define MAXTSIZ		(8*1024*1024)		/* max text size */
#endif
#ifndef MAXDSIZ
#define MAXDSIZ		(128*1024*1024)		/* max data size */
#endif
#ifndef MAXSSIZ
#define MAXSSIZ		(8*1024*1024)		/* max stack size */
#endif
#ifndef DFLDSIZ
#define DFLDSIZ		(8*1024*1024)		/* initial data size limit */
#endif
#ifndef DFLSSIZ
#define DFLSSIZ		(512*1024)		/* initial stack size limit */
#endif

#define STACKGAP_RANDOM	32*1024

#define BRKSIZ		(16*1024*1024)

/*
 * Size of shared memory map
 */

#ifndef SHMMAXPGS
#define SHMMAXPGS	64		/* XXXX should be 1024 */
#endif

#define VM_PHYSSEG_MAX		1
#define VM_PHYSSEG_NOADD
#define VM_PHYSSEG_STRAT	VM_PSTRAT_RANDOM

/* MD round macros */
#define	vax_round_page(x) (((vaddr_t)(x) + VAX_PGOFSET) & ~VAX_PGOFSET)
#define	vax_trunc_page(x) ((vaddr_t)(x) & ~VAX_PGOFSET)

/* user/kernel map constants */
#define VM_MIN_ADDRESS		((vaddr_t)PAGE_SIZE)
#define VM_MAXUSER_ADDRESS	((vaddr_t)KERNBASE)
#define VM_MAX_ADDRESS		((vaddr_t)KERNBASE)
#define VM_MIN_KERNEL_ADDRESS	((vaddr_t)KERNBASE)
#define VM_MAX_KERNEL_ADDRESS	((vaddr_t)(0xC0000000))

#define	USRIOSIZE		(8 * VAX_NPTEPG)	/* 512MB */
#define	VM_PHYS_SIZE		(USRIOSIZE*VAX_NBPG)

#endif /* _MACHINE_VMPARAM_H_ */


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

/*
 * Generic definitions for the (virtual) vsbus. contains common info
 * used by all VAXstations.
 */

#ifndef _MACHINE_VSBUS_H_
#define _MACHINE_VSBUS_H_

#include <machine/bus.h>
#include <machine/sgmap.h>

struct	vsbus_attach_args {
	vaddr_t	va_addr;		/* virtual CSR address */
	paddr_t	va_paddr;		/* physical CSR address */

	short	va_br;			/* Interrupt level */
	int	va_cvec;		/* Interrupt vector address */
	u_char	va_maskno;		/* Interrupt vector in mask */
	vaddr_t	va_dmaaddr;		/* DMA area address */
	vsize_t	va_dmasize;		/* DMA area size */
	bus_space_tag_t va_iot;
	bus_dma_tag_t va_dmat;
};

/*
 * Some chip addresses and constants, same on all VAXstations.
 */
#define VS_CFGTST	0x20020000      /* config register */
#define VS_REGS		0x20080000      /* Misc cpu internal regs */
#define VS_REGS_KA49	0x25c00000      /* ... same, on 512KB ROM systems */
#define NI_ADDR		0x20090000      /* Ethernet address */
#define DZ_CSR		0x200a0000      /* DZ11-compatible chip csr */
#define DZ_CSR_KA49	0x25000000      /* ... same, on 512KB ROM systems */
#define VS_CLOCK	0x200b0000      /* clock chip address */
#define SCA_REGS	0x200c0000      /* disk device addresses */
#define SCA_REGS_KA49	0x26000000      /* ... same, on 512KB ROM systems */
#define NI_BASE         0x200e0000      /* LANCE CSRs */
#define NI_IOSIZE       (128 * VAX_NBPG)    /* IO address size */

#define	KA49_SCSIMAP	0x27000000	/* KA49 SCSI SGMAP */
/*
 * Small monochrome graphics framebuffer, present on all machines.
 */
#define	SMADDR		0x30000000
#define	SMSIZE		0x20000		/* Actually 256k, only 128k used */

struct	vsbus_softc {
	struct	device sc_dev;
	u_char	*sc_intmsk;	/* Mask register */
	u_char	*sc_intclr;	/* Clear interrupt register */
	u_char	*sc_intreq;	/* Interrupt request register */
	u_char	sc_mask;	/* Interrupts to enable after autoconf */
	vaddr_t	sc_vsregs;	/* Where the VS_REGS are mapped */
	vaddr_t sc_dmaaddr;	/* Mass storage virtual DMA area */
	vsize_t sc_dmasize;	/* Size of the DMA area */

	struct vax_bus_dma_tag sc_dmatag;
	struct vax_sgmap sc_sgmap;
};

struct vsbus_dma {
	SIMPLEQ_ENTRY(vsbus_dma) vd_q;
	void (*vd_go)(void *);
	void *vd_arg;
};

#ifdef _KERNEL
void	vsbus_dma_init(struct vsbus_softc *, unsigned ptecnt);
u_char	vsbus_setmask(int);
void	vsbus_clrintr(int);
void	vsbus_copytoproc(struct proc *, caddr_t, caddr_t, int);
void	vsbus_copyfromproc(struct proc *, caddr_t, caddr_t, int);
void	vsbus_dma_start(struct vsbus_dma *);
void	vsbus_dma_intr(void);
#endif
#endif /* _MACHINE_VSBUS_H_ */


code: src/sys/arch/vax/mbus

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


code:
/*	$OpenBSD: dz_fwio.c,v 1.2 2008/08/24 14:49:35 miod Exp $	*/

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

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

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

#include <machine/bus.h>
#include <machine/sid.h>

#include <vax/mbus/mbusreg.h>
#include <vax/mbus/mbusvar.h>
#include <vax/mbus/fwioreg.h>
#include <vax/mbus/fwiovar.h>

#include <vax/qbus/dzreg.h>
#include <vax/qbus/dzvar.h>

#include <vax/dec/dzkbdvar.h>

#include <sys/tty.h>
#include <dev/cons.h>

#include "dzkbd.h"
#include "dzms.h"

int	dz_fwio_match(struct device *, void *, void *);
void	dz_fwio_attach(struct device *, struct device *, void *);

struct cfattach dz_fwio_ca = {
	sizeof(struct dz_softc), dz_fwio_match, dz_fwio_attach
};

extern struct cfdriver dz_cd;

int	dz_fwio_intr(void *);

#define	DZ_FWIO_CSR	0
#define	DZ_FWIO_RBUF	4
#define	DZ_FWIO_DTR	9
#define	DZ_FWIO_BREAK	13
#define	DZ_FWIO_TBUF	12
#define	DZ_FWIO_TCR	8
#define	DZ_FWIO_DCD	13
#define	DZ_FWIO_RING	13

int
dz_fwio_match(struct device *parent, void *vcf, void *aux)
{
	struct fwio_attach_args *faa = (struct fwio_attach_args *)aux;

	return strcmp(faa->faa_dev, dz_cd.cd_name) == 0 ? 1 : 0;
}

void
dz_fwio_attach(struct device *parent, struct device *self, void *aux)
{
	struct fwio_attach_args *faa = (struct fwio_attach_args *)aux;
	struct dz_softc *sc = (struct dz_softc *)self;
	paddr_t basepa;
#if NDZKBD > 0 || NDZMS > 0
	struct dzkm_attach_args daa;
	extern struct consdev wsdisplay_cons;
#endif
	extern vaddr_t dz_console_regs;
	vaddr_t dz_regs;
	unsigned int vec;
	int console;
	int serial_console;

	vec = faa->faa_vecbase + FBIC_DEVIRQ2 * 4;
	printf(" vec %d: ", vec);

	/*
	 * Map registers.
	 */

	if (dz_console_regs != 0 && faa->faa_mid == mbus_ioslot) {
		dz_regs = dz_console_regs;
		console = 1;
		serial_console = (vax_confdata & 0x60) == 0;
		if (serial_console)
			printf("console, ");
	} else {
		basepa = faa->faa_base + FWIO_DZ_REG_OFFSET;
		dz_regs = vax_map_physmem(basepa, 1);
		console = 0;
	}

	/*
	 * XXX - This is evil and ugly, but...
	 * due to the nature of how bus_space_* works on VAX, this will
	 * be perfectly good until everything is converted.
	 */
	sc->sc_ioh = dz_regs;

	sc->sc_dr.dr_csr = DZ_FWIO_CSR;
	sc->sc_dr.dr_rbuf = DZ_FWIO_RBUF;
	sc->sc_dr.dr_tbuf = DZ_FWIO_TBUF;
	sc->sc_dr.dr_tcr = DZ_FWIO_TCR;
	sc->sc_dr.dr_dtr = DZ_FWIO_DTR;
	sc->sc_dr.dr_break = DZ_FWIO_BREAK;
	sc->sc_dr.dr_dcd = DZ_FWIO_DCD;
	sc->sc_dr.dr_ring = DZ_FWIO_RING;

	sc->sc_type = DZ_DZV;

	/* no modem control bits except on line 2 */
	sc->sc_dsr = (1 << 0) | (1 << 1) | (1 << 3);

	printf("4 lines");

	/*
	 * Complete attachment.
	 */

	dzattach(sc);

	/*
	 * Register interrupt handler.
	 */

	if (mbus_intr_establish(vec, IPL_TTY, dz_fwio_intr, sc,
	    self->dv_xname) != 0) {
		printf("\n%s: can't establish interrupt\n", self->dv_xname);
		return;
	}

	/*
	 * Attach input devices, if any.
	 */

#if NDZKBD > 0
	daa.daa_line = 0;
	DZ_WRITE_WORD(sc, dr_rbuf, DZ_LPR_RX_ENABLE | (DZ_LPR_B4800 << 8) |
	    DZ_LPR_8_BIT_CHAR | daa.daa_line);
	daa.daa_flags =
	    (console && cn_tab == &wsdisplay_cons ? DZKBD_CONSOLE : 0);
	config_found(self, &daa, dz_print);
#endif
#if NDZMS > 0
	daa.daa_line = 1;
	DZ_WRITE_WORD(sc, dr_rbuf, DZ_LPR_RX_ENABLE | (DZ_LPR_B4800 << 8) |
	    DZ_LPR_8_BIT_CHAR | DZ_LPR_PARENB | DZ_LPR_OPAR | daa.daa_line);
	daa.daa_flags = 0;
	config_found(self, &daa, dz_print);
#endif
}

int
dz_fwio_intr(void *v)
{
	struct dz_softc *sc = (struct dz_softc *)v;

	/*
	 * FBIC expects edge interrupts, while the dz does level
	 * interrupts. To avoid missing interrupts while servicing,
	 * we disable further device interrupts while servicing.
	 */
	DZ_WRITE_WORD(sc, dr_csr,
	    DZ_READ_WORD(sc, dr_csr) & ~(DZ_CSR_RXIE | DZ_CSR_TXIE));

	dzrint(sc);
	dzxint(sc);

	DZ_WRITE_WORD(sc, dr_csr,
	    DZ_READ_WORD(sc, dr_csr) | (DZ_CSR_RXIE | DZ_CSR_TXIE));

	return 1;
}


code:
#	$OpenBSD: files.mbus,v 1.3 2013/09/24 20:10:52 miod Exp $

# VAXstation 3[58][24]0 internal bus
device	mbus { [mid = -1] }
attach	mbus at mainbus
file	arch/vax/mbus/mbus.c			mbus

# L2003 Firefox Workstation I/O Module
device	fwio {}
attach	fwio at mbus
file	arch/vax/mbus/fwio.c			fwio

attach	dz at fwio with dz_fwio: dzcons
file	arch/vax/mbus/dz_fwio.c			dz_fwio

attach	le at fwio with le_fwio: le24
file	arch/vax/mbus/if_le_fwio.c		le_fwio

attach	sii at fwio with sii_fwio
file	arch/vax/mbus/sii_fwio.c		sii_fwio

# L2004 LEGSS video
# (with L2005 8-plane output module and optional L2006 16-plane module)
device	legss: wsemuldisplaydev, rasops32
attach	legss at mbus
file	arch/vax/mbus/legss.c			legss needs-flag

# L2008 FQAM (CQBIC)
attach	uba at mbus with uba_mbus
file	arch/vax/mbus/uba_mbus.c		uba_mbus

# L2001 or L2010 CPU
# L2007 memory


code:
/*	$OpenBSD: fwio.c,v 1.2 2011/07/06 20:42:52 miod Exp $	*/

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

/*
 * Firefox Workstation I/O Module
 *
 * This M-bus board sports:
 * - a System Support Chip implementing the (off cpu) clocks.
 * - a SII controller, in SCSI mode, with 128KB static memory.
 * - a LANCE Ethernet controller, with 128KB static memory.
 * - a DZQ11-compatible DC7085 4 lines serial controller.
 */

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

#include <machine/bus.h>

#include <vax/mbus/mbusreg.h>
#include <vax/mbus/mbusvar.h>
#include <vax/mbus/fwioreg.h>
#include <vax/mbus/fwiovar.h>

struct fwio_softc {
	struct device	sc_dev;
	int		sc_loc[1];	/* locators override */
};

void	fwio_attach(struct device *, struct device *, void *);
int	fwio_match(struct device *, void *, void *);

struct cfdriver fwio_cd = {
	NULL, "fwio", DV_DULL
};

const struct cfattach fwio_ca = {
	sizeof(struct fwio_softc), fwio_match, fwio_attach
};

int	fwio_print(void *, const char *);

int
fwio_match(struct device *parent, void *vcf, void *aux)
{
	struct mbus_attach_args *maa = (struct mbus_attach_args *)aux;

	if (maa->maa_class == CLASS_IO && maa->maa_interface == INTERFACE_FBIC)
		return 1;

	return 0;
}

void
fwio_attach(struct device *parent, struct device *self, void *aux)
{
	struct mbus_attach_args *maa = (struct mbus_attach_args *)aux;
	struct fwio_softc *sc = (struct fwio_softc *)self;
	struct fwio_attach_args faa;

	printf("\n");

	/*
	 * Save our mid in locators.  booted_sd() in autoconf.c depends
	 * on this to find the correct boot device.
	 */
	sc->sc_loc[0] = maa->maa_mid;
	self->dv_cfdata->cf_loc = sc->sc_loc;

	faa.faa_mid = maa->maa_mid;
	faa.faa_base = MBUS_SLOT_BASE(maa->maa_mid);
	faa.faa_vecbase = maa->maa_vecbase;

	faa.faa_dev = "dz";
	(void)config_found(self, &faa, fwio_print);

	faa.faa_dev = "le";
	(void)config_found(self, &faa, fwio_print);

	faa.faa_dev = "sii";
	(void)config_found(self, &faa, fwio_print);
}

int
fwio_print(void *aux, const char *pnp)
{
	struct fwio_attach_args *faa = (struct fwio_attach_args *)aux;

	if (pnp != NULL)
		printf("%s at %s", faa->faa_dev, pnp);

	return (UNCONF);
}


code:
/*	$OpenBSD: fwioreg.h,v 1.1 2008/08/18 23:19:25 miod Exp $	*/

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

/*
 * Firefox Workstation I/O Module registers and memory layout
 */

#define	FWIO_SSC_REMAP_ADDR	0x21400000

#define	FWIO_SII_REG_OFFSET	0x000000
#define	FWIO_LANCE_REG_OFFSET	0x200000
#define	FWIO_SII_BUF_OFFSET	0x400000
#define	FWIO_SII_BUF_SIZE	0x020000
#define	FWIO_DZ_REG_OFFSET	0x600000
#define	FWIO_IOCSR_OFFSET	0x800000
#define	FWIO_ESAR_OFFSET	0x800000
#define	FWIO_LANCE_BUF_OFFSET	0xa00000
#define	FWIO_LANCE_BUF_SIZE	0x020000

/*
 * IOCSR bits
 */

#define	FWIO_IOCSR_CNSL		0x80000000 /* break on line 3 asserts MHALT */
#define	FWIO_IOCSR_MRUN		0x40000000 /* assert MRUN */
#define	FWIO_IOCSR_CLKIEN	0x20000000 /* drive MCLKI */
#define	FWIO_IOCSR_RSTWS	0x10000000 /* reset workstation */

#define	FWIO_ESAR_MASK		0x00ff0000
#define	FWIO_ESAR_SHIFT		16


code:
/*	$OpenBSD: fwiovar.h,v 1.1 2008/08/18 23:19:25 miod Exp $	*/

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

/*
 * Firefox Workstation I/O Module subdevice attachment glue
 */

struct fwio_attach_args {
	const char 	*faa_dev;
	unsigned int	 faa_mid;
	paddr_t		 faa_base;
	unsigned int	 faa_vecbase;
};


code:
/*	$OpenBSD: if_le_fwio.c,v 1.4 2014/12/22 02:26:54 tedu Exp $	*/

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

/*-
 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
 * Simulation Facility, NASA Ames Research Center.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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) 1992, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Ralph Campbell and Rick Macklem.
 *
 * 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_le.c	8.2 (Berkeley) 11/16/93
 */

#include "bpfilter.h"

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

#include <machine/bus.h>

#include <uvm/uvm_extern.h>

#include <net/if.h>
#include <net/if_media.h>

#include <netinet/in.h>
#include <netinet/if_ether.h>

#include <vax/mbus/mbusreg.h>
#include <vax/mbus/mbusvar.h>
#include <vax/mbus/fwioreg.h>
#include <vax/mbus/fwiovar.h>

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

struct le_fwio_softc {
	struct am7990_softc sc_am7990;
	volatile uint16_t *sc_rap;
	volatile uint16_t *sc_rdp;
};

int	le_fwio_match(struct device *, void *, void *);
void	le_fwio_attach(struct device *, struct device *, void *);

struct cfattach le_fwio_ca = {
	sizeof(struct le_fwio_softc), le_fwio_match, le_fwio_attach
};

int	le_fwio_intr(void *);
uint16_t le_fwio_rdcsr(struct lance_softc *, uint16_t);
void	le_fwio_wrcsr(struct lance_softc *, uint16_t, uint16_t);
void	le_fwio_wrcsr_interrupt(struct lance_softc *, uint16_t, uint16_t);

int
le_fwio_match(struct device *parent, void *vcf, void *aux)
{
	struct fwio_attach_args *faa = (struct fwio_attach_args *)aux;

	return strcmp(faa->faa_dev, le_cd.cd_name) == 0 ? 1 : 0;
}

void
le_fwio_attach(struct device *parent, struct device *self, void *aux)
{
	struct fwio_attach_args *faa = (struct fwio_attach_args *)aux;
	struct le_fwio_softc *lsc = (struct le_fwio_softc *)self;
	struct lance_softc *sc = &lsc->sc_am7990.lsc;
	unsigned int vec;
	uint32_t *esar;
	int i;

	vec = faa->faa_vecbase + FBIC_DEVIRQ1 * 4;
	printf(" vec %d", vec);

	/*
	 * Map registers.
	 */

	lsc->sc_rdp = (volatile uint16_t *)
	    vax_map_physmem(faa->faa_base + FWIO_LANCE_REG_OFFSET, 1);
	lsc->sc_rap = lsc->sc_rdp + 2;

	/*
	 * Register access functions.
	 */

	sc->sc_rdcsr = le_fwio_rdcsr;
	sc->sc_wrcsr = le_fwio_wrcsr;

	/*
	 * Map buffers.
	 */

	sc->sc_mem = (void *)uvm_km_valloc(kernel_map, FWIO_LANCE_BUF_SIZE);
	if (sc->sc_mem == NULL) {
		vax_unmap_physmem(faa->faa_base + FWIO_LANCE_REG_OFFSET, 1);
		printf(": can't map buffers\n");
		return;
	}

	ioaccess((vaddr_t)sc->sc_mem, faa->faa_base +
	    FWIO_LANCE_BUF_OFFSET, FWIO_LANCE_BUF_SIZE >> VAX_PGSHIFT);

	sc->sc_addr = FWIO_LANCE_BUF_OFFSET;
	sc->sc_memsize = FWIO_LANCE_BUF_SIZE;
	sc->sc_conf3 = 0;

	sc->sc_copytodesc = lance_copytobuf_contig;
	sc->sc_copyfromdesc = lance_copyfrombuf_contig;
	sc->sc_copytobuf = lance_copytobuf_contig;
	sc->sc_copyfrombuf = lance_copyfrombuf_contig;
	sc->sc_zerobuf = lance_zerobuf_contig;

	/*
	 * Get the Ethernet address from the Station Address ROM.
	 */

	esar = (uint32_t *)vax_map_physmem(faa->faa_base + FWIO_ESAR_OFFSET, 1);
	for (i = 0; i < 6; i++)
		sc->sc_arpcom.ac_enaddr[i] =
		    (esar[i] & FWIO_ESAR_MASK) >> FWIO_ESAR_SHIFT;
	vax_unmap_physmem((vaddr_t)esar, 1);

	/*
	 * Register interrupt handler.
	 */

	if (mbus_intr_establish(vec, IPL_NET, le_fwio_intr, sc,
	    self->dv_xname) != 0) {
		vax_unmap_physmem(faa->faa_base + FWIO_LANCE_REG_OFFSET, 1);
		uvm_km_free(kernel_map, (vaddr_t)sc->sc_mem,
		    FWIO_LANCE_BUF_SIZE);
		printf(": can't establish interrupt\n");
		return;
	}

	/*
	 * Complete attachment.
	 */

	am7990_config(&lsc->sc_am7990);
}

int
le_fwio_intr(void *v)
{
	struct le_fwio_softc *lsc = (struct le_fwio_softc *)v;
	struct lance_softc *sc = &lsc->sc_am7990.lsc;
	int rc;

	/*
	 * FBIC expects edge interrupts, while the LANCE does level
	 * interrupts. To avoid missing interrupts while servicing,
	 * we disable further device interrupts while servicing.
	 *
	 * However, am7990_intr() will flip the interrupt enable bit
	 * itself; we override wrcsr with a specific version during
	 * servicing, so as not to reenable interrupts accidentally...
	 */
	sc->sc_wrcsr = le_fwio_wrcsr_interrupt;

	rc = am7990_intr(v);

	sc->sc_wrcsr = le_fwio_wrcsr;
	/*
	 * ...but we should not forget to reenable interrupts at this point!
	 */
	le_fwio_wrcsr(sc, LE_CSR0, LE_C0_INEA | le_fwio_rdcsr(sc, LE_CSR0));

	return rc;
}

uint16_t
le_fwio_rdcsr(struct lance_softc *sc, uint16_t port)
{
	struct le_fwio_softc *lsc = (struct le_fwio_softc *)sc;

	*lsc->sc_rap = port;
	return *lsc->sc_rdp;
}

void
le_fwio_wrcsr(struct lance_softc *sc, uint16_t port, uint16_t val)
{
	struct le_fwio_softc *lsc = (struct le_fwio_softc *)sc;

	*lsc->sc_rap = port;
	*lsc->sc_rdp = val;
}

void
le_fwio_wrcsr_interrupt(struct lance_softc *sc, uint16_t port, uint16_t val)
{
	if (port == LE_CSR0)
		val &= ~LE_C0_INEA;

	le_fwio_wrcsr(sc, port, val);
}


code:
/*	$OpenBSD: legss.c,v 1.8 2014/12/23 21:39:12 miod Exp $	*/

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

/*
 * The wsdisplay emulops routines ({copy,erase}{cols,rows}, putchar, and
 * do_cursor) are adapted from the rasops routines found in rasops.c and
 * rasops32.c, under the following licence terms:
 *
 * Copyright (c) 1999 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Andrew Doran.
 *
 * 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.
 */

/*
 * LEGSS frame buffer
 *
 * This beast is different enough from a QDSS or a GPX to need a specific
 * driver.  Unfortunately, it is not yet known how this hardware works.
 *
 * The frame buffer memory is accessible linearly in 32 bit words (one
 * per pixel, although apparently only 20 bits are writable).
 *
 * We currently drive the frame buffer as a monochrome, unaccelerated
 * display.
 *
 * Note that the hardware probe is made easier since graphics can only
 * exist in the last M-Bus slot, and the terminal information in the SSC
 * will tell us whether it is properly populated or not.
 */

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

#include <machine/cpu.h>
#include <machine/cvax.h>
#include <machine/sid.h>

#include <vax/mbus/mbusreg.h>
#include <vax/mbus/mbusvar.h>

#include <uvm/uvm_extern.h>

#include <dev/cons.h>

#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wsdisplayvar.h>
#include <dev/rasops/rasops.h>
#include <dev/wsfont/wsfont.h>

/* Graphics can only exist at mid 7 */
#define	MID_GRAPHICS		7
#define	LEGSS_BASE		MBUS_SLOT_BASE(MID_GRAPHICS)

#define	LEGSS_VRAM_OFFSET	0x00800000

#define	LEGSS_VISWIDTH	1280
#define	LEGSS_WIDTH	2048
#define	LEGSS_VISHEIGHT	1024
#define	LEGSS_HEIGHT	2048

int	legss_match(struct device *, void *, void *);
void	legss_attach(struct device *, struct device *, void *);

struct	legss_screen {
	struct rasops_info ss_ri;
	int		ss_console;
	u_int		ss_depth;
	vaddr_t		ss_vram;
};

/* for console */
struct legss_screen legss_consscr;

struct	legss_softc {
	struct device sc_dev;
	struct legss_screen *sc_scr;
	int	sc_nscreens;
};

struct cfattach legss_ca = {
	sizeof(struct legss_softc), legss_match, legss_attach,
};

struct	cfdriver legss_cd = {
	NULL, "legss", DV_DULL
};

struct wsscreen_descr legss_stdscreen = {
	"std",
};

const struct wsscreen_descr *_legss_scrlist[] = {
	&legss_stdscreen,
};

const struct wsscreen_list legss_screenlist = {
	sizeof(_legss_scrlist) / sizeof(struct wsscreen_descr *),
	_legss_scrlist,
};

int	legss_ioctl(void *, u_long, caddr_t, int, struct proc *);
paddr_t	legss_mmap(void *, off_t, int);
int	legss_alloc_screen(void *, const struct wsscreen_descr *,
	    void **, int *, int *, long *);
void	legss_free_screen(void *, void *);
int	legss_show_screen(void *, void *, int,
	    void (*) (void *, int, int), void *);
int	legss_load_font(void *, void *, struct wsdisplay_font *);
int	legss_list_font(void *, struct wsdisplay_font *);

const struct wsdisplay_accessops legss_accessops = {
	.ioctl = legss_ioctl,
	.mmap = legss_mmap,
	.alloc_screen = legss_alloc_screen,
	.free_screen = legss_free_screen,
	.show_screen = legss_show_screen,
	.load_font = legss_load_font,
	.list_font = legss_list_font
};

int	legss_setup_screen(struct legss_screen *);
void	legss_clear_screen(struct legss_screen *);

int	legss_copycols(void *, int, int, int, int);
int	legss_copyrows(void *, int, int, int);
int	legss_do_cursor(struct rasops_info *);
int	legss_erasecols(void *, int, int, int, long);
int	legss_eraserows(void *, int, int, long);
int	legss_putchar(void *, int, int, u_int, long);

u_int	legss_probe_depth(vaddr_t);

/*
 * Autoconf glue
 */

int
legss_match(struct device *parent, void *vcf, void *aux)
{
	struct mbus_attach_args *maa = (struct mbus_attach_args *)aux;

	if (maa->maa_class == CLASS_GRAPHICS &&
	    maa->maa_interface == INTERFACE_FBIC &&
	    maa->maa_mid == MID_GRAPHICS)
		return 1;

	return 0;
}

void
legss_attach(struct device *parent, struct device *self, void *aux)
{
	struct legss_softc *sc = (struct legss_softc *)self;
	struct legss_screen *scr;
	struct wsemuldisplaydev_attach_args aa;
	int console;
	vaddr_t tmp;
	extern struct consdev wsdisplay_cons;

	console = (vax_confdata & 0x60) != 0 && cn_tab == &wsdisplay_cons;
	if (console) {
		scr = &legss_consscr;
		sc->sc_nscreens = 1;
	} else {
		scr = malloc(sizeof(struct legss_screen), M_DEVBUF, M_NOWAIT);
		if (scr == NULL) {
			printf(": can not allocate memory\n");
			return;
		}

		tmp = vax_map_physmem(LEGSS_BASE + LEGSS_VRAM_OFFSET, 1);
		if (tmp == 0L) {
			printf(": can not probe depth\n");
			goto bad1;
		}
		scr->ss_depth = legss_probe_depth(tmp);
		vax_unmap_physmem(tmp, 1);

		if (scr->ss_depth == 0) {
			printf(": unrecognized depth\n");
			goto bad1;
		}

		scr->ss_vram = vax_map_physmem(LEGSS_BASE + LEGSS_VRAM_OFFSET,
		    (LEGSS_VISHEIGHT * LEGSS_WIDTH * 32 / NBBY) / VAX_NBPG);
		if (scr->ss_vram == 0L) {
			printf(": can not map frame buffer\n");
			goto bad1;
		}

		if (legss_setup_screen(scr) != 0) {
			printf(": initialization failed\n");
			goto bad2;
		}
	}
	sc->sc_scr = scr;

	printf(": %dx%d %d plane color framebuffer\n",
	    LEGSS_VISWIDTH, LEGSS_VISHEIGHT, scr->ss_depth);

	aa.console = console;
	aa.scrdata = &legss_screenlist;
	aa.accessops = &legss_accessops;
	aa.accesscookie = sc;
	aa.defaultscreens = 0;

	config_found(self, &aa, wsemuldisplaydevprint);

	return;

bad2:
	vax_unmap_physmem(scr->ss_vram,
	    (LEGSS_VISHEIGHT * LEGSS_WIDTH * 32 / NBBY) / VAX_NBPG);
bad1:
	free(scr, M_DEVBUF, sizeof(struct legss_screen));
}

/*
 * wsdisplay accessops
 */

int
legss_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
{
	struct legss_softc *sc = v;
	struct legss_screen *ss = sc->sc_scr;
	struct wsdisplay_fbinfo *wdf;

	switch (cmd) {
	case WSDISPLAYIO_GTYPE:
		*(u_int *)data = WSDISPLAY_TYPE_LEGSS;
		break;

	case WSDISPLAYIO_GINFO:
		wdf = (struct wsdisplay_fbinfo *)data;
		wdf->height = ss->ss_ri.ri_height;
		wdf->width = ss->ss_ri.ri_width;
		wdf->depth = ss->ss_depth;
		wdf->cmsize = 0;
		break;

	case WSDISPLAYIO_LINEBYTES:
		*(u_int *)data = LEGSS_WIDTH * 32 / NBBY;

	case WSDISPLAYIO_GETCMAP:
	case WSDISPLAYIO_PUTCMAP:
		break;

	case WSDISPLAYIO_GVIDEO:
	case WSDISPLAYIO_SVIDEO:
		break;

	default:
		return -1;
	}

	return 0;
}

paddr_t
legss_mmap(void *v, off_t offset, int prot)
{
	/* Do not allow mmap yet because of the read-only upper 12 bits */
	return -1;
}

int
legss_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
    int *curxp, int *curyp, long *defattrp)
{
	struct legss_softc *sc = v;
	struct legss_screen *ss = sc->sc_scr;
	struct rasops_info *ri = &ss->ss_ri;

	if (sc->sc_nscreens > 0)
		return ENOMEM;

	*cookiep = ri;
	*curxp = *curyp = 0;
	ri->ri_ops.alloc_attr(ri, 0, 0, 0, defattrp);
	sc->sc_nscreens++;

	return 0;
}

void
legss_free_screen(void *v, void *cookie)
{
	struct legss_softc *sc = v;

	sc->sc_nscreens--;
}

int
legss_show_screen(void *v, void *cookie, int waitok,
    void (*cb)(void *, int, int), void *cbarg)
{
	return 0;
}

int
legss_load_font(void *v, void *emulcookie, struct wsdisplay_font *font)
{
	struct legss_softc *sc = v;
	struct legss_screen *ss = sc->sc_scr;
	struct rasops_info *ri = &ss->ss_ri;

	return rasops_load_font(ri, emulcookie, font);
}

int
legss_list_font(void *v, struct wsdisplay_font *font)
{
	struct legss_softc *sc = v;
	struct legss_screen *ss = sc->sc_scr;
	struct rasops_info *ri = &ss->ss_ri;

	return rasops_list_font(ri, font);
}

int
legss_setup_screen(struct legss_screen *ss)
{
	struct rasops_info *ri = &ss->ss_ri;

	bzero(ri, sizeof(*ri));
	ri->ri_depth = 32;	/* masquerade as a 32 bit device for rasops */
	ri->ri_width = LEGSS_VISWIDTH;
	ri->ri_height = LEGSS_VISHEIGHT;
	ri->ri_stride = LEGSS_WIDTH * 32 / NBBY;
	ri->ri_flg = RI_FORCEMONO | RI_CENTER;		/* no RI_CLEAR ! */
	ri->ri_hw = ss;
	ri->ri_bits = (u_char *)ss->ss_vram;

	/*
	 * Ask for an unholy big display, rasops will trim this to more
	 * reasonable values.
	 */
	if (rasops_init(ri, 160, 160) != 0)
		return -1;

	/*
	 * Override the rasops emulops.
	 */
	ri->ri_ops.copyrows = legss_copyrows;
	ri->ri_ops.copycols = legss_copycols;
	ri->ri_ops.eraserows = legss_eraserows;
	ri->ri_ops.erasecols = legss_erasecols;
	ri->ri_ops.putchar = legss_putchar;
	ri->ri_do_cursor = legss_do_cursor;

	legss_stdscreen.ncols = ri->ri_cols;
	legss_stdscreen.nrows = ri->ri_rows;
	legss_stdscreen.textops = &ri->ri_ops;
	legss_stdscreen.fontwidth = ri->ri_font->fontwidth;
	legss_stdscreen.fontheight = ri->ri_font->fontheight;
	legss_stdscreen.capabilities = ri->ri_caps;

	/*
	 * Clear display.
	 */
	legss_clear_screen(ss);

	return 0;
}

u_int
legss_probe_depth(vaddr_t vram)
{
	uint32_t probe;

	*(volatile uint32_t *)vram = 0;
	*(volatile uint32_t *)vram = 0xffffffff;
	probe = *(volatile uint32_t *)vram;

	/*
	 * Need to mask the upper 12 bits, they don't seem to be connected
	 * to anything and latch random bus data.
	 */
	switch (probe & 0x000fffff) {
	case 0x000ff:
		return 8;
	default:
		return 0;
	}
}

/*
 * Console support code
 */

int	legsscnprobe(void);
int	legsscninit(void);

int
legsscnprobe()
{
	extern vaddr_t virtual_avail;
	int depth;

	if (vax_boardtype != VAX_BTYP_60)
		return 0;	/* move along, nothing there */

	/* no working graphics hardware, or forced serial console? */
	if ((vax_confdata & 0x60) == 0)
		return 0;

	/*
	 * Check for a recognized color depth.
	 */

	ioaccess(virtual_avail, LEGSS_BASE + LEGSS_VRAM_OFFSET, 1);
	depth = legss_probe_depth(virtual_avail);
	iounaccess(virtual_avail, 1);

	if (depth == 0)
		return 0;	/* unsupported, default to serial */

	return 1;
}

/*
 * Called very early to setup the glass tty as console.
 * Because it's called before the VM system is initialized, virtual memory
 * for the framebuffer can be stolen directly without disturbing anything.
 */
int
legsscninit()
{
	struct legss_screen *ss = &legss_consscr;
	extern vaddr_t virtual_avail;
	vaddr_t ova;
	long defattr;
	struct rasops_info *ri;

	ova = virtual_avail;

	ioaccess(virtual_avail, LEGSS_BASE + LEGSS_VRAM_OFFSET, 1);
	ss->ss_depth = legss_probe_depth(virtual_avail);
	iounaccess(virtual_avail, 1);
	if (ss->ss_depth == 0)
		return 1;

	ioaccess(virtual_avail, LEGSS_BASE + LEGSS_VRAM_OFFSET,
	    (LEGSS_VISHEIGHT * LEGSS_WIDTH * 32 / NBBY) / VAX_NBPG);
	ss->ss_vram = virtual_avail;
	virtual_avail += (LEGSS_VISHEIGHT * LEGSS_WIDTH * 32 / NBBY);
	virtual_avail = round_page(virtual_avail);

	/* this had better not fail */
	if (legss_setup_screen(ss) != 0) {
		iounaccess(ss->ss_vram,
		    (LEGSS_VISHEIGHT * LEGSS_WIDTH * 32 / NBBY) / VAX_NBPG);
		virtual_avail = ova;
		return 1;
	}

	ri = &ss->ss_ri;
	ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr);
	wsdisplay_cnattach(&legss_stdscreen, ri, 0, 0, defattr);

	return 0;
}

/*
 * wsdisplay emulops
 */

int
legss_putchar(void *v, int row, int col, u_int uc, long attr)
{
	struct rasops_info *ri = v;
	struct wsdisplay_font *font = ri->ri_font;
	int width, height, cnt, fs, fb, fg, bg, ul;
	int32_t *dp, *rp;
	u_char *fr;

	ri->ri_ops.unpack_attr(v, attr, &fg, &bg, &ul);

	rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
	height = font->fontheight;
	width = font->fontwidth;

	if (uc == ' ') {
		while (height--) {
			dp = rp;
			DELTA(rp, ri->ri_stride, int32_t *);

			for (cnt = width; cnt; cnt--) {
				*(int8_t *)dp = bg;
				dp++;
			}
		}
	} else {
		uc -= font->firstchar;
		fr = (u_char *)font->data + uc * ri->ri_fontscale;
		fs = font->stride;

		while (height--) {
			dp = rp;
			fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) |
			    (fr[0] << 24);
			fr += fs;
			DELTA(rp, ri->ri_stride, int32_t *);

			for (cnt = width; cnt; cnt--) {
				if ((fb >> 31) & 1)
					*(int8_t *)dp = fg;
				else
					*(int8_t *)dp = bg;
				dp++;
				fb <<= 1;
			}
		}
	}

	/* Do underline */
	if (ul) {
		DELTA(rp, -(ri->ri_stride << 1), int32_t *);

		while (width--) {
			*(int8_t *)rp = fg;
			rp++;
		}
	}

	return 0;
}

int
legss_copycols(void *v, int row, int src, int dst, int num)
{
	struct rasops_info *ri = v;
	struct wsdisplay_font *font = ri->ri_font;
	u_char *sp, *dp;
	int height, cnt, delta;

	num *= font->fontwidth;
	row *= ri->ri_yscale;
	height = font->fontheight;

	sp = ri->ri_bits + row + src * ri->ri_xscale;
	dp = ri->ri_bits + row + dst * ri->ri_xscale;

	if (dst <= src) {
		/* non overlapping copy */
		delta = ri->ri_stride - (num << 2);
		while (height--) {
			for (cnt = num; cnt != 0; cnt--) {
				*dp = *sp;
				sp += 1 << 2;
				dp += 1 << 2;
			}
			dp += delta;
			sp += delta;
		}
	} else {
		/* possibly overlapping copy */
		delta = num << 2;
		while (height--) {
			dp += delta;
			sp += delta;
			for (cnt = num; cnt != 0; cnt--) {
				dp -= 1 << 2;
				sp -= 1 << 2;
				*dp = *sp;
			}
			dp += ri->ri_stride;
			sp += ri->ri_stride;
		}
	}

	return 0;
}

int
legss_erasecols(void *v, int row, int col, int num, long attr)
{
	struct rasops_info *ri = v;
	struct wsdisplay_font *font = ri->ri_font;
	int height, cnt, fg, bg;
	int32_t *rp, *dp;

	ri->ri_ops.unpack_attr(v, attr, &fg, &bg, NULL);
	rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
	height = font->fontheight;
	num *= font->fontwidth;

	while (height--) {
		dp = rp;
		DELTA(rp, ri->ri_stride, int32_t *);

		for (cnt = num; cnt; cnt--) {
			*(int8_t *)dp = bg;
			dp++;
		}
	}

	return 0;
}

int
legss_copyrows(void *v, int src, int dst, int num)
{
	struct rasops_info *ri = v;
	struct wsdisplay_font *font = ri->ri_font;
	int32_t *srp, *drp;
	int8_t *sp, *dp;
	int n, cnt, delta;

	num *= font->fontheight;
	n = ri->ri_emustride >> 2;

	if (dst < src) {
		srp = (int32_t *)(ri->ri_bits + src * ri->ri_yscale);
		drp = (int32_t *)(ri->ri_bits + dst * ri->ri_yscale);
		delta = ri->ri_stride;
	} else {
		src = font->fontheight * src + num - 1;
		dst = font->fontheight * dst + num - 1;
		srp = (int32_t *)(ri->ri_bits + src * ri->ri_stride);
		drp = (int32_t *)(ri->ri_bits + dst * ri->ri_stride);
		delta = -ri->ri_stride;
	}

	while (num--) {
		dp = (int8_t *)drp;
		sp = (int8_t *)srp;
		DELTA(drp, delta, int32_t *);
		DELTA(srp, delta, int32_t *);

		for (cnt = n; cnt; cnt--) {
			*dp = *sp;
			dp += 1 << 2;
			sp += 1 << 2;
		}
	}

	return 0;
}

int
legss_eraserows(void *v, int row, int num, long attr)
{
	struct rasops_info *ri = v;
	struct wsdisplay_font *font = ri->ri_font;
	int n, cnt, delta, fg, bg;
	int32_t *dp;

	ri->ri_ops.unpack_attr(v, attr, &fg, &bg, NULL);
	n = ri->ri_emustride >> 2;
	num *= font->fontheight;
	dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale);
	delta = ri->ri_delta;

	while (num--) {
		for (cnt = n; cnt; cnt--) {
			*(int8_t *)dp = bg;
			DELTA(dp, 4, int32_t *);
		}

		DELTA(dp, delta, int32_t *);
	}

	return 0;
}

int
legss_do_cursor(struct rasops_info *ri)
{
	struct wsdisplay_font *font = ri->ri_font;
	int height, cnt, row, col;
	u_char *dp, *rp;

	row = ri->ri_crow;
	col = ri->ri_ccol;

	rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
	height = font->fontheight;

	while (height--) {
		dp = rp;
		rp += ri->ri_stride;

		for (cnt = font->fontwidth; cnt; cnt--) {
			*(int8_t *)dp ^= ~0;
			dp += 4;
		}
	}

	return 0;
}

/* Clear the whole screen */
void
legss_clear_screen(struct legss_screen *ss)
{
	struct rasops_info *ri = &ss->ss_ri;
	int n, cnt, num, delta;
	int32_t *dp, clr;

	n = ri->ri_stride >> 2;
	num = ri->ri_height;
	dp = (int32_t *)ri->ri_origbits;
	delta = 0;
	clr = ri->ri_devcmap[0];

	while (num--) {
		for (cnt = n; cnt; cnt--) {
			*(int8_t *)dp = clr;
			DELTA(dp, 4, int32_t *);
		}

		DELTA(dp, delta, int32_t *);
	}
}


code:
/*	$OpenBSD: mbus.c,v 1.4 2011/04/07 15:30:16 miod Exp $	*/

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

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

#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/intr.h>
#include <machine/nexus.h>
#include <machine/scb.h>

#include <vax/mbus/mbusreg.h>
#include <vax/mbus/mbusvar.h>

#define	PR_CPUID 14

/*
 * FBIC interrupt handlers
 */
struct fbic_irq {
	int	(*fi_fn)(void *);
	void	*fi_arg;
	struct evcount fi_cnt;
	int	fi_ipl;
};

/*
 * Generic information for each slot.
 *
 * This information is maintained at the mbus level, rather than
 * enforcing each child driver to provide it.  This allows proper
 * M-bus configuration on slots where no driver attaches.
 */

struct	fbic {
	paddr_t		base;
	vaddr_t		regs;
	int		vecbase;
	struct fbic_irq	*firq[FBIC_DEVIRQMAX];
};

struct mbus_slot {
	uint8_t		ms_interface;	/* MODTYPE interface */
	uint8_t		ms_class;	/* MODTYPE class */

	unsigned int	ms_nfbic;
	struct fbic	ms_fbic[2];
};

struct mbus_softc {
	struct device	sc_dev;
	struct mbus_slot *sc_slots[MBUS_SLOT_MAX];
};

void	mbus_attach(struct device *, struct device *, void *);
int	mbus_match(struct device *, void *, void *);

struct cfdriver mbus_cd = {
	NULL, "mbus", DV_DULL
};

const struct cfattach mbus_ca = {
	sizeof(struct mbus_softc), mbus_match, mbus_attach
};

void	mbus_initialize_cpu(struct mbus_slot *, unsigned int, int);
void	mbus_initialize_device(struct mbus_slot *, unsigned int, uint8_t);
void	mbus_intr_dispatch(void *);
int	mbus_print(void *, const char *);
int	mbus_submatch(struct device *, void *, void *);

unsigned int mbus_ioslot = (unsigned int)-1;

int
mbus_match(struct device *parent, void *vcf, void *aux)
{
	struct mainbus_attach_args *maa = (struct mainbus_attach_args *)aux;

	return maa->maa_bustype == VAX_MBUS ? 1 : 0;
}

void
mbus_attach(struct device *parent, struct device *self, void *aux)
{
	struct mbus_softc *sc = (struct mbus_softc *)self;
	struct mbus_slot *ms;
	unsigned int mid;
	struct mbus_attach_args maa;
	paddr_t pa;
	vaddr_t fbic;
	uint32_t modtype;
	uint8_t class, interface;

	printf("\n");

	/*
	 * Walk the bus and probe slots.
	 * We will also record information about all occupied slots,
	 * and keep a permanent mapping of their FBIC, as we will end
	 * up needing to play with them often...
	 */

	for (mid = 0; mid < MBUS_SLOT_MAX; mid++) {

		/*
		 * Map main (and often, only) FBIC.
		 */

		pa = MBUS_SLOT_BASE(mid);
		fbic = vax_map_physmem(pa + FBIC_BASE, 1);
		if (fbic == 0)
			panic("unable to map slot %d registers", mid);

		if (badaddr((caddr_t)(fbic + FBIC_MODTYPE), 4) != 0)
			modtype = 0;
		else
			modtype = *(uint32_t *)(fbic + FBIC_MODTYPE);

		if (modtype == 0 || modtype == 0xffffffff) {
			vax_unmap_physmem(fbic, 1);
			continue;
		}

		/*
		 * The slot is populated.  Write things down.
		 */

		ms = (struct mbus_slot *)malloc(sizeof(*ms),
		    M_DEVBUF, M_NOWAIT | M_ZERO);
		if (ms == NULL)
			panic("not enough memory to probe M-bus");

		sc->sc_slots[mid] = ms;
		ms->ms_nfbic = 1;	/* only one so far! */
		ms->ms_fbic[0].base = pa + FBIC_BASE;
		ms->ms_fbic[0].regs = fbic;

		class = (modtype & MODTYPE_CLASS_MASK) >> MODTYPE_CLASS_SHIFT;
		interface = (modtype & MODTYPE_INTERFACE_MASK) >>
		    MODTYPE_INTERFACE_SHIFT;

		ms->ms_interface = interface;
		ms->ms_class = class;

		/*
		 * If there are two FBICs on this board, map the second one.
		 */

		if (class == CLASS_CPU) {
			/* the FBIC we mapped is in fact the second one... */
			ms->ms_fbic[1].base = ms->ms_fbic[0].base;
			ms->ms_fbic[1].regs = ms->ms_fbic[0].regs;
			ms->ms_nfbic = 2;
			fbic = vax_map_physmem(pa + FBIC_CPUA_BASE, 1);
			if (fbic == 0)
				panic("unable to map slot %d registers", mid);
			ms->ms_fbic[0].base = pa + FBIC_CPUA_BASE;
			ms->ms_fbic[0].regs = fbic;
		}

		/*
		 * Perform a minimal sane initialization.
		 */

		if (class == CLASS_CPU) {
			mbus_initialize_cpu(ms, mid, 0);
			mbus_initialize_cpu(ms, mid, 1);
		} else
			mbus_initialize_device(ms, mid, interface);

		/*
		 * Attach subdevices if possible.
		 */

		maa.maa_mid = mid;
		maa.maa_class = class;
		maa.maa_subclass = (modtype & MODTYPE_SUBCLASS_MASK) >>
		    MODTYPE_SUBCLASS_SHIFT;
		maa.maa_interface = interface;
		maa.maa_revision = (modtype & MODTYPE_REVISION_MASK) >>
		    MODTYPE_REVISION_SHIFT;
		maa.maa_addr = pa;
		maa.maa_vecbase = ms->ms_fbic[0].vecbase;

		(void)config_found_sm(self, &maa, mbus_print, mbus_submatch);
	}
}

int
mbus_print(void *aux, const char *pnp)
{
	struct mbus_attach_args *maa = (struct mbus_attach_args *)aux;
	int rc = UNCONF;
	const char *descr;

	switch (maa->maa_class) {
	case CLASS_BA:
		descr = "Bus Adaptor";
		break;
	case CLASS_GRAPHICS:
		descr = "Graphics";
		break;
	case CLASS_IO:
		descr = "I/O Module";
		break;
	case CLASS_CPU:
		descr = "cpu";
		break;
	case CLASS_MEMORY:
		descr = maa->maa_interface == INTERFACE_FMDC ?
		    "ECC memory" : "Memory";
		break;
	default:
		descr = NULL;
		rc = UNSUPP;
		break;
	}

	if (maa->maa_interface != INTERFACE_FBIC) {
		if (maa->maa_class != CLASS_MEMORY ||
		    (maa->maa_interface != INTERFACE_FMCM &&
		     maa->maa_interface != INTERFACE_FMDC))
			rc = UNSUPP;
	}

	if (pnp != NULL) {
		if (rc == UNSUPP) {
			printf("logic board class %02x:%02x interface %u.%u ",
			    maa->maa_class, maa->maa_subclass,
			    maa->maa_interface, maa->maa_revision);
			if (descr != NULL)
				printf("(%s)", descr);
		} else
			printf("%s", descr);
		printf(" at %s", pnp);
	}
	printf(" mid %u", maa->maa_mid);

	return (rc);
}

int
mbus_submatch(struct device *parent, void *vcf, void *aux)
{
	struct mbus_attach_args *maa = (struct mbus_attach_args *)aux;
	struct cfdata *cf = (struct cfdata *)vcf;

	/*
	 * If attachment specifies the mid, it has to match.
	 */
	if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != maa->maa_mid)
		return 0;

	return (*cf->cf_attach->ca_match)(parent, vcf, aux);
}

/*
 * CPU board initialization.
 */

void
mbus_initialize_cpu(struct mbus_slot *ms, unsigned int mid, int cpu)
{
	struct fbic *fbic = &ms->ms_fbic[cpu];
	uint32_t fbicsr;
	int cpuid;

	cpuid = (mid << CPUID_MID_SHIFT) |
	    (cpu != 0 ? CPUID_PROC_1 : CPUID_PROC_0);

	/*
	 * Clear error log
	 */
	*(uint32_t *)(fbic->regs + FBIC_BUSCSR) = BUSCSR_RESET;

	/*
	 * Set (IPI) interrupt vectors base, but do not enable them yet.
	 */
	fbic->vecbase = MBUS_VECTOR_BASE(mid, cpu);
	*(uint32_t *)(fbic->regs + FBIC_IPDVINT) = 0 /* IPDVINT_IPUNIT */ |
	    (fbic->vecbase & IPDVINT_VECTOR_MASK);

	/*
	 * Enable all interrupt sources if on the boot processor,
	 * disable them otherwise (this does not affect IPIs).
	 */
	fbicsr = *(uint32_t *)(fbic->regs + FBIC_BUSCSR);
	if (cpuid == mfpr(PR_CPUID))
		fbicsr |= FBICSR_IRQEN_MASK;
	else
		fbicsr &= ~FBICSR_IRQEN_MASK;

	/*
	 * Route interrupts from the M-bus to the CVAX.
	 */
	fbicsr &= ~FBICSR_IRQC2M_MASK;

	/*
	 * Allow the CPU to be halted.
	 */
	fbicsr |= FBICSR_HALTEN;

	*(uint32_t *)(fbic->regs + FBIC_BUSCSR) = fbicsr;
}

/*
 * Device board initialization.
 */

void
mbus_initialize_device(struct mbus_slot *ms, unsigned int mid,
    uint8_t interface)
{
	struct fbic *fbic = ms->ms_fbic;
	uint32_t fbicsr;

	/*
	 * Clear error log if applicable
	 */
	if (interface == INTERFACE_FBIC || interface == INTERFACE_FMDC)
		*(uint32_t *)(fbic->regs + FBIC_BUSCSR) = BUSCSR_RESET;

	if (interface == INTERFACE_FBIC) {
		/*
		 * Set interrupt vector base.
		 */
		fbic->vecbase = MBUS_VECTOR_BASE(mid, 0);
		*(uint32_t *)(fbic->regs + FBIC_IPDVINT) = IPDVINT_DEVICE |
		    (fbic->vecbase & IPDVINT_VECTOR_MASK);

		/*
		 * Disable all interrupt sources, and route them
		 * from the devices to the M-bus.
		 */
		fbicsr = *(uint32_t *)(fbic->regs + FBIC_BUSCSR);
		fbicsr &= ~FBICSR_IRQEN_MASK;
		fbicsr |= FBICSR_IRQC2M_MASK;
		*(uint32_t *)(fbic->regs + FBIC_BUSCSR) = fbicsr;
	}
}

/*
 * Interrupt handling.
 */

int
mbus_intr_establish(unsigned int vec, int ipl, int (*fn)(void *), void *arg,
    const char *name)
{
	struct mbus_softc *sc;
	struct mbus_slot *ms;
	struct fbic *fbic;
	struct fbic_irq *fi;
	uint32_t fbicsr;
	unsigned int mid, fbicirq;

	mid = MBUS_VECTOR_TO_MID(vec);

#ifdef DIAGNOSTIC
	if (mid >= MBUS_SLOT_MAX)
		return EINVAL;
	if (mbus_cd.cd_ndevs == 0)
		return ENXIO;
#endif
	sc = (struct mbus_softc *)mbus_cd.cd_devs[0];
#ifdef DIAGNOSTIC
	if (sc == NULL)
		return ENXIO;
#endif
	ms = sc->sc_slots[mid];
#ifdef DIAGNOSTIC
	if (ms == NULL)
		return ENXIO;
#endif
	fi = (struct fbic_irq *)malloc(sizeof *fi, M_DEVBUF, M_NOWAIT);
	if (fi == NULL)
		return ENOMEM;

	/*
	 * This interface is intended to be used for device interrupts
	 * only, so there is no need to handle dual-FBIC slots.
	 */
	fbic = &ms->ms_fbic[0 /* MBUS_VECTOR_TO_FBIC(vec) */];

	fi->fi_fn = fn;
	fi->fi_arg = arg;
	fi->fi_ipl = ipl;
	evcount_attach(&fi->fi_cnt, name, &fi->fi_ipl);

	fbicirq = MBUS_VECTOR_TO_IRQ(vec);
	fbic->firq[fbicirq] = fi;
	scb_vecalloc(vec, mbus_intr_dispatch, fi, SCB_ISTACK, &fi->fi_cnt);

	/*
	 * Enable device interrupt in the module FBIC.  Proper direction
	 * has been setup in mbus_slot_initialize().
	 */

	fbicsr = *(uint32_t *)(fbic->regs + FBIC_BUSCSR);
	fbicsr |= fbicirq << FBICSR_IRQEN_SHIFT;
	*(uint32_t *)(fbic + FBIC_BUSCSR) = fbicsr;

	return 0;
}

/*
 * Interrupt dispatcher.
 */

void
mbus_intr_dispatch(void *v)
{
	struct fbic_irq *fi = (struct fbic_irq *)v;
	int s;

	/*
	 * FBIC interrupts are at fixed levels.  In case the level is
	 * below the level the driver expects the interrupt at, we need
	 * to raise spl to be safe (e.g. for sii).
	 */
	s = _splraise(fi->fi_ipl);
	(void)(*fi->fi_fn)(fi->fi_arg);
	splx(s);
}


code:
/*	$OpenBSD: mbusreg.h,v 1.1 2008/08/18 23:19:25 miod Exp $	*/

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

/*
 * M-bus
 *
 * The M-bus connects up to 8 slots, of 32MB memory space each.
 *
 * All these modules contain a ``Firefox Bus Interface Chip'' (FBIC),
 * which provides common registers at the end of each slot address space,
 * allowing modules to recognize and configure each other.
 */

#define	MBUS_SLOT_MAX			8

/*
 * Addressing
 *
 * The M-bus provides a 32-bit address space.
 *
 * The low half (bit 31 clear) is the physical memory space (and being on
 * vax, really stops at 512MB).
 * The high half is the I/O space, where each slot has a 32MB window.
 * In addition to its window, there are two 128MB areas, allowing a given
 * module to provide functionnality regardless of its actual position on
 * the bus.
 *
 * From the host CPU, the M-bus I/O space is remapped in the vax I/O space.
 *
 * The address map is thus:
 * M-bus address	CPU address	Length
 * 0000.0000		0000.0000	2000.0000	memory space
 * 8000.0000		2000.0000	0800.0000	global I/O
 * 8800.0000		2800.0000	0800.0000	local I/O
 * 9000.0000		3000.0000	0200.0000	slot 0 I/O
 * 9200.0000		3200.0000	0200.0000	slot 1 I/O
 * 9400.0000		3400.0000	0200.0000	slot 2 I/O
 * 9600.0000		3600.0000	0200.0000	slot 3 I/O
 * 9800.0000		3800.0000	0200.0000	slot 4 I/O
 * 9a00.0000		3a00.0000	0200.0000	slot 5 I/O
 * 9c00.0000		3c00.0000	0200.0000	slot 6 I/O
 * 9e00.0000		3e00.0000	0200.0000	slot 7 I/O
 */

/* base address of a slot, as seen from the cpu */
#define	MBUS_SLOT_BASE(s)		(0x30000000 + ((s) << 25))

/* convert I/O space addresses (assumed to be in their correct range) */
#define	HOST_TO_MBUS(pa)		((pa) ^ 0xa0000000)
#define	MBUS_TO_HOST(pa)		((pa) ^ 0xa0000000)

/*
 * Common FBIC slot registers
 */

/* FBIC or compatible registers occupy the last page (running down)... */
#define	FBIC_BASE			0x1fffe00
/* ...but dual-CPU modules have two of them. */
#define	FBIC_CPUA_BASE			0x0fffe00
#define	FBIC_CPUB_BASE			0x1fffe00

/* module identification */
#define	FBIC_MODTYPE			0x1fc
/* M-bus error status */
#define	FBIC_BUSCSR			0x1f8
/* M-bus error control signal log */
#define	FBIC_BUSCTL			0x1f4
/* M-bus error address signal log */
#define	FBIC_BUSADR			0x1f0
/* M-bus error data signal log */
#define	FBIC_BUSDAT			0x1ec
/* FBIC control and status */
#define	FBIC_CSR			0x1e8
/* I/O space range decode */
#define	FBIC_RANGE			0x1e4
/* Interprocessor and device interrupt */
#define	FBIC_IPDVINT			0x1e0
/* Unique software ID */
#define	FBIC_WHAMI			0x1dc
/* Unique hardware ID */
#define	FBIC_CPUID			0x1d8
/* Interlock 1 address */
#define	FBIC_IADR1			0x1d4
/* Interlock 2 address */
#define	FBIC_IADR2			0x1d0
/* Console scratch register */
#define	FBIC_SAVGPR			0x1c4

/*
 * Module identification
 */
#define	MODTYPE_CLASS_MASK		0x000000ff
#define	MODTYPE_CLASS_SHIFT		0
#define	CLASS_BA			0x01
#define	CLASS_GRAPHICS			0x02
#define	CLASS_IO			0x04
#define	CLASS_CPU			0x08
#define	CLASS_MEMORY			0x10
#define	MODTYPE_SUBCLASS_MASK		0x0000ff00
#define	MODTYPE_SUBCLASS_SHIFT		8
#define	MODTYPE_INTERFACE_MASK		0x00ff0000
#define	MODTYPE_INTERFACE_SHIFT		16
#define	INTERFACE_FBIC			0x01
#define	INTERFACE_FMDC			0x02 /* ECC memory */
#define	INTERFACE_FMCM			0xfe /* 8MB board */
#define	MODTYPE_REVISION_MASK		0xff000000
#define	MODTYPE_REVISION_SHIFT		24

/*
 * M-bus error status and error logging
 * Conditions are active low
 */
#define	BUSCSR_FRZN			0x80000000 /* logging frozen */
#define	BUSCSR_ARB			0x40000000 /* arbitration error */
#define	BUSCSR_ICMD			0x20000000 /* invalid MCMD encoding */
#define	BUSCSR_IDAT			0x10000000 /* invalid data supplied */
#define	BUSCSR_MTPE			0x08000000 /* tag parity error */
#define	BUSCSR_MDPE			0x04000000 /* MDAL parity error */
#define	BUSCSR_MSPE			0x02000000 /* MSTATUS parity error */
#define	BUSCSR_MCPE			0x01000000 /* MCMD parity error */
#define	BUSCSR_ILCK			0x00800000 /* interlock violation */
#define	BUSCSR_MTO			0x00400000 /* slave timeout */
#define	BUSCSR_NOS			0x00200000 /* no slave response */
#define	BUSCSR_CTO			0x00100000 /* CDAL data cycle timeout */
#define	BUSCSR_CDPE			0x00080000 /* CDAL parity error */
#define	BUSCSR_CTPE			0x00040000 /* CDAL tag parity error */
#define	BUSCSR_SERR			0x00020000 /* error on MSTATUS */
#define	BUSCSR_DBLE			0x00010000 /* double M-bus error */

#define	BUSCSR_RESET			0xffff0000 /* reset all conditions */

/*
 * FBIC control and status
 */
#define	FBICSR_MFMD_MASK		0xc0000000 /* manufacturing mode */
#define	FBICSR_CMISS			0x08000000 /* CVAX cache miss */
#define	FBICSR_EXCAEN			0x04000000 /* external cache enable */
#define	FBICSR_HALTCPU			0x02000000 /* CVAX halt */
#define	FBICSR_RESET			0x01000000 /* CVAX reset */
#define	FBICSR_IRQEN_MASK		0x00f00000 /* interrupt enables */
#define	FBICSR_IRQEN_SHIFT		20
#define	FBIC_DEVIRQ0		0
#define	FBIC_DEVIRQ1		1
#define	FBIC_DEVIRQ2		2
#define	FBIC_DEVIRQ3		3
#define	FBIC_DEVIRQMAX		4
#define	FBICSR_IRQC2M_MASK		0x000f0000 /* interrupt direction */
#define	FBICSR_IRQC2M_SHIFT		16
#define	FBICSR_LEDS_MASK		0x00003f00 /* module leds, active low */
#define	FBICSR_LEDS_SHIFT		8
#define	FBICSR_HALTEN			0x00000080 /* halt enable */
#define	FBICSR_TSTFNC_MASK		0x0000007e /* test function */
#define	FBICSR_TSTFNC_SHIFT		1
#define	TSTFNC_NORMAL_MODE		0x1f	   /* normal operation */
#define	FBICSR_CDPE			0x00000001 /* CVAX parity enable */

/*
 * I/O Range
 *
 * This programs an M-bus address range which in the global I/O space, which
 * is answered by this module.  Note that the upper bit in the match field
 * must be set, for the address to be in the I/O space; this is why the
 * upper bit of the mask field acts as an enable.
 */
#define	RANGE_MATCH			0xffff0000 /* address bits 31:16 */
#define	RANGE_ENABLE			0x00008000 /* mask address bit 31 */
#define	RANGE_MASK			0x00007fff /* address bits 30:16 */

/*
 * Interprocessor and device interrupts
 */
#define	IPDVINT_IPL17			0x08000000 /* trigger IRQ3 */
#define	IPDVINT_IPL16			0x04000000 /* trigger IRQ2 */
#define	IPDVINT_IPL15			0x02000000 /* trigger IRQ1 */
#define	IPDVINT_IPL14			0x01000000 /* trigger IRQ0 */
#define	IPDVINT_IPUNIT			0x00020000 /* interrupts CPU */
#define	IPDVINT_DEVICE			0x00010000 /* interrupts M-bus */
#define	IPDVINT_VECTOR_MASK		0x0000fff0 /* interrupt vector */
#define	IPDVINT_VECTOR_SHIFT		4
#define	IPDVINT_IPL_MASK		0x0000000c /* interrupt ipl */
#define	IPDVINT_IPL_SHIFT		2

/*
 * CPUID (also EPR 14)
 */
#define	CPUID_MID_MASK			0x0000001c /* slot mid */
#define	CPUID_MID_SHIFT			2
#define	CPUID_PROC_MASK			0x00000003 /* slot processor id */
#define	CPUID_PROC_SHIFT		0
#define	CPUID_PROC_0			0x00
#define	CPUID_PROC_1			0x03

/*
 * FMCM registers (not FBIC compatible except for MODTYPE and BUSCSR)
 */

/* module identification */
#define	FMCM_MODTYPE			0x1fc
/* M-bus error status */
/* NOTE: only implements FRZN, ICMD, MDPE, MSPE and MCPE */
#define	FMCM_BUSCSR			0x1f8
/* FMCM control and status register */
#define	FMCM_FMDCSR			0x1f4
/* Memory space base address register */
#define	FMCM_BASEADDR			0x1f0

#define	FMDCSR_ISOLATE			0x00008000 /* no MABORT on error */
#define	FMDCSR_DIAGNOSTIC_REFRESH_START	0x00004000
#define	FMDCSR_REFRESH_PERIOD_SELECT	0x00002000 /* set: slow (80ns) */
#define	FMDCSR_DISABLE_REFRESH		0x00001000

#define	BASEADDR_STARTADDR_MASK		0x7ff00000
#define	BASEADDR_MEMORY_SPACE_ENABLE	0x80000000

/*
 * Interrupt vector assignments
 *
 * Since each FBIC controls four interrupts, and passes the IPI in bits
 * 3:2 of the vector number, we have to reserve them on 0x10 boundaries.
 *
 * Note that this is different from the usual scheme of using bits 5:4
 * for this purpose.
 *
 * CPU boards also use the IPDVINT to have an extra 0x10 range for IPIs.
 *
 * To make things simpler, we use a static assignment where the number is
 * computed from the mid and fbic number (for cpu boards).
 *
 * This means the 0x100..0x1fc range is used for M-bus interrupts only.
 * Q-bus interrupts will use the usual 0x200..0x3fc range.
 */

#define	MBUS_VECTOR_BASE(mid,fbic)	(0x100 + (mid) * 0x20 + (fbic) * 0x10)
#define	MBUS_VECTOR_TO_MID(vec)		(((vec) - 0x100) >> 5)
#define	MBUS_VECTOR_TO_FBIC(vec)	(((vec) & 0x10) >> 4)
#define	MBUS_VECTOR_TO_IRQ(vec)		(((vec) & 0xc) >> 2)


code:
/*	$OpenBSD: mbusvar.h,v 1.1 2008/08/18 23:19:25 miod Exp $	*/

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

struct mbus_attach_args {
	unsigned int	maa_mid;
	uint8_t		maa_class;
	uint8_t		maa_subclass;
	uint8_t		maa_interface;
	uint8_t		maa_revision;
	paddr_t		maa_addr;
	unsigned int	maa_vecbase;
};

extern unsigned int mbus_ioslot;

int	mbus_intr_establish(unsigned int, int, int (*)(void *), void *,
	    const char *);
uint32_t mbus_ddb_hook(int, uint32_t);


code:
/*	$OpenBSD: sii_fwio.c,v 1.2 2008/08/23 12:40:22 miod Exp $	*/

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

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

#include <machine/bus.h>
#include <machine/cvax.h>

#include <uvm/uvm_extern.h>

#include <vax/mbus/mbusreg.h>
#include <vax/mbus/mbusvar.h>
#include <vax/mbus/fwioreg.h>
#include <vax/mbus/fwiovar.h>

#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
#include <scsi/scsi_message.h>

#include <vax/dec/siireg.h>
#include <vax/dec/siivar.h>

struct sii_fwio_softc {
	struct sii_softc sc_dev;
	u_char *sc_buf;
};

int	sii_fwio_match(struct device *, void *, void *);
void	sii_fwio_attach(struct device *, struct device *, void *);

struct cfattach sii_fwio_ca = {
	sizeof(struct sii_fwio_softc), sii_fwio_match, sii_fwio_attach
};

extern struct cfdriver sii_cd;

void	sii_fwio_copyfrombuf(void *, u_int, u_char *, int);
void	sii_fwio_copytobuf(void *, u_char *, u_int, int);
int	sii_fwio_intr(void *);

int
sii_fwio_match(struct device *parent, void *vcf, void *aux)
{
	struct fwio_attach_args *faa = (struct fwio_attach_args *)aux;

	return strcmp(faa->faa_dev, sii_cd.cd_name) == 0 ? 1 : 0;
}

void
sii_fwio_attach(struct device *parent, struct device *self, void *aux)
{
	struct fwio_attach_args *faa = (struct fwio_attach_args *)aux;
	struct sii_fwio_softc *sfc = (struct sii_fwio_softc *)self;
	struct sii_softc *sc = &sfc->sc_dev;
	unsigned int vec;

	vec = faa->faa_vecbase + FBIC_DEVIRQ0 * 4;
	printf(" vec %d", vec);

	/*
	 * Map registers.
	 */

	sc->sc_regs =
	    (SIIRegs *)vax_map_physmem(faa->faa_base + FWIO_SII_REG_OFFSET, 1);

	/*
	 * Map buffers.
	 */

	sfc->sc_buf = (u_char *)uvm_km_valloc(kernel_map, FWIO_SII_BUF_SIZE);
	if (sfc->sc_buf == NULL) {
		vax_unmap_physmem(faa->faa_base + FWIO_SII_REG_OFFSET, 1);
		printf(": can't map buffers\n");
		return;
	}

	ioaccess((vaddr_t)sfc->sc_buf, faa->faa_base + FWIO_SII_BUF_OFFSET,
	    FWIO_SII_BUF_SIZE >> VAX_PGSHIFT);

	sc->sii_copytobuf = sii_fwio_copytobuf;
	sc->sii_copyfrombuf = sii_fwio_copyfrombuf;

	/*
	 * Register interrupt handler.
	 */

	if (mbus_intr_establish(vec, IPL_BIO, sii_fwio_intr, sfc,
	    self->dv_xname) != 0) {
		vax_unmap_physmem(faa->faa_base + FWIO_SII_REG_OFFSET, 1);
		uvm_km_free(kernel_map, (vaddr_t)sfc->sc_buf,
		    FWIO_SII_BUF_SIZE);
		printf(": can't establish interrupt\n");
		return;
	}

	/*
	 * Complete attachment.
	 */
	sc->sc_hostid = *(uint8_t *)((vaddr_t)cvax_ssc_ptr + 0x4c0) & 07;
	sii_attach(sc);
}

int
sii_fwio_intr(void *v)
{
	struct sii_softc *sc = (struct sii_softc *)v;
	int rc;
	uint16_t csr;

	/*
	 * FBIC expects edge interrupts, while the sii does level
	 * interrupts. To avoid missing interrupts while servicing,
	 * we disable further device interrupts while servicing.
	 */
	csr = sc->sc_regs->csr;
	sc->sc_regs->csr = csr & ~SII_IE;

	rc = sii_intr(v);

	sc->sc_regs->csr = csr;

	return rc;
}

/*
 * Copy data between the fixed SCSI buffers. The sii driver only ``knows''
 * offsets inside the SCSI buffer.
 */

void
sii_fwio_copyfrombuf(void *v, u_int offs, u_char *dst, int len)
{
	struct sii_fwio_softc *sc = (struct sii_fwio_softc *)v;
	u_char *src = sc->sc_buf + offs;

	memcpy(dst, src, len);
}

void
sii_fwio_copytobuf(void *v, u_char *src, u_int offs, int len)
{
	struct sii_fwio_softc *sc = (struct sii_fwio_softc *)v;
	u_char *dst = sc->sc_buf + offs;

	memcpy(dst, src, len);
}


code:
/*	$OpenBSD: uba_mbus.c,v 1.5 2015/02/01 15:27:11 miod Exp $	*/

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

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

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

#include <vax/mbus/mbusreg.h>
#include <vax/mbus/mbusvar.h>

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

void	uba_mbus_attach(struct device *, struct device *, void *);
int	uba_mbus_match(struct device *, void *, void *);

const struct cfattach uba_mbus_ca = {
	sizeof(struct uba_vsoftc), uba_mbus_match, uba_mbus_attach
};

void	uba_mbus_beforescan(struct uba_softc*);
void	uba_mbus_init(struct uba_softc*);

extern	struct vax_bus_space vax_mem_bus_space;

int
uba_mbus_match(struct device *parent, void *vcf, void *aux)
{
	struct mbus_attach_args *maa = (struct mbus_attach_args *)aux;

	/*
	 * There can only be one QBus adapter (because it uses range-mapped
	 * MBus I/O), and it has to be in slot zero for connectivity reasons.
	 */
	if (maa->maa_mid != 0)
		return 0;

	if (maa->maa_class == CLASS_BA && maa->maa_interface == INTERFACE_FBIC)
		return 1;

	return 0;
}

void
uba_mbus_attach(struct device *parent, struct device *self, void *aux)
{
	struct mbus_attach_args *maa = (struct mbus_attach_args *)aux;
	struct uba_vsoftc *sc = (void *)self;
	paddr_t modaddr;
	vaddr_t fbic;

	printf(": Q22\n");

	/*
	 * Configure M-Bus I/O range.
	 *
	 * This will map the sgmap at 2008xxxx (QBAMAP), and the doorbell
	 * registers at 2000xxxx (QIOPAGE).
	 */
	modaddr = MBUS_SLOT_BASE(maa->maa_mid);
	fbic = vax_map_physmem(modaddr + FBIC_BASE, 1);
	if (fbic == 0) {
		printf("%s: can't setup M-bus range register\n",
		    self->dv_xname);
		return;
	}
	*(uint32_t *)(fbic + FBIC_RANGE) =
	    (HOST_TO_MBUS(QBAMAP & RANGE_MATCH)) | RANGE_ENABLE |
	    ((QBAMAP ^ QIOPAGE) >> 16);
	vax_unmap_physmem(fbic, 1);

	/*
	 * There is nothing special to do to enable interrupt routing;
	 * the CQBIC will route Q-bus interrupts to the C-bus, and
	 * mbus(4) has already configured our FBIC interrupt registers
	 * to route C-bus interrupts to the M-bus (whether they are
	 * generated by the FBIC or by the Q-bus), which will make them
	 * visible to the processor.
	 *
	 * Note that we do not enable the boards' FBIC memory error
	 * interrupt yet.
	 */

	/*
	 * Fill in bus specific data.
	 */
	sc->uv_sc.uh_beforescan = uba_mbus_beforescan;
	sc->uv_sc.uh_ubainit = uba_mbus_init;
	sc->uv_sc.uh_iot = &vax_mem_bus_space;
	sc->uv_sc.uh_dmat = &sc->uv_dmat;

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

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

/*
 * Called when the CQBIC is set up; to enable DMA access from
 * Q-bus devices to main memory.
 */
void
uba_mbus_beforescan(sc)
	struct uba_softc *sc;
{
	/*
	 * Writing to the doorbell registers causes a bus error and
	 * a machine check.  Don't do this for now, the built-in
	 * tape drive still works without this.
	bus_space_write_2(sc->uh_iot, sc->uh_ioh, QIPCR, Q_LMEAE);
	 */
}

void
uba_mbus_init(sc)
	struct uba_softc *sc;
{
	DELAY(500000);
	uba_mbus_beforescan(sc);
}


code: src/sys/arch/vax/mscp

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


code:
#	$OpenBSD: files.mscp,v 1.3 2000/04/27 03:14:45 bjc Exp $
#	$NetBSD: files.mscp,v 1.7 1999/06/06 19:16:18 ragge Exp $
#
# File and device description for MSCP devices.
#

define	mscp {}
file	arch/vax/mscp/mscp.c		mscp
file	arch/vax/mscp/mscp_subr.c	mscp

device	mscpbus {drive = -1}
attach	mscpbus at mscp

device	rx: disk
attach	rx at mscpbus

device	ra: disk
attach	ra at mscpbus
file	arch/vax/mscp/mscp_disk.c	ra | rx needs-flag

device	mt: tape
attach	mt at mscpbus
file	arch/vax/mscp/mscp_tape.c	mt needs-flag