code:
/* $OpenBSD: db_instruction.h,v 1.5 2002/07/10 20:30:14 jsyn Exp $ */
/* $NetBSD: db_instruction.h,v 1.7 2001/04/26 03:10:44 ross Exp $ */

/*
 * Copyright (c) 1999 Christopher G. Demetriou.  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 by Christopher G. Demetriou
 *	for the NetBSD Project.
 * 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.
 */

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

/*
 *	File: alpha_instruction.h
 * 	Author: Alessandro Forin, Carnegie Mellon University
 *	Date:	11/91
 *
 *	Alpha Instruction set definition
 *
 *	Reference: "Alpha System Reference Manual", V4.0, April 1991
 *
 */

#ifndef	_ALPHA_INSTRUCTION_H_
#define	_ALPHA_INSTRUCTION_H_ 1

#if	!defined(ASSEMBLER)

/*
 *	All instructions are in one of five formats:
 *		Memory, Branch, Operate, Floating-point Operate, PAL
 *
 *	The original Mach sources attempted to use 'smarter' names
 *	for registers, which reflected source and destination.  These
 *	definitions use the names from the Architecture Reference Manual,
 *	both for clarity and because you can't differentiate between
 *	'source' and 'destinations' for some types of instructions (loads
 *	and stores; they'd be correct for one, but swapped for the other).
 */

typedef union {
	/*
	 *	All instructions are 32 bits wide
	 */
	unsigned int	bits;

	/*
	 *	Generic instruction pseudo format; look at
	 *	opcode to see how to interpret the rest.
	 */
	struct {
		unsigned	bits:26,
				opcode:6;
	} generic_format;

	/*
	 *	Memory instructions contain a 16 bit
	 *	signed immediate value and two register
	 *	specifiers
	 */
	struct {
		signed short	displacement;
		unsigned	rb : 5,
				ra : 5,
				opcode : 6;
	} mem_format;

	/*
	 *	Branch instruction contain a 21 bit offset,
	 *	which is sign-extended, shifted and combined
	 *	with the PC to form a 64 bit destination address.
	 *
	 *	In computed jump instructions the opcode is further
	 *	specified in the offset field, the rest of it is
	 *	used as branch target hint.  The destination of the
	 *	jump is the source register.
	 */
	struct {
		signed int	displacement : 21;
		unsigned	ra : 5,
				opcode : 6;
	} branch_format;

	struct {
		signed int	hint : 14;
		unsigned	action : 2,
				rb : 5,
				ra : 5,
				opcode : 6;
	} jump_format;

	/*
	 *	Operate instructions are of two types, with
	 *	a second source register or with a literal
	 *	specifier.  Bit 12 says which is which.
	 */
	struct {
		unsigned	rc : 5,
				function : 7,
				is_lit : 1,
				sbz_or_litlo : 3,
				rb_or_lithi : 5,
				ra : 5,
				opcode : 6;
	} operate_generic_format;

	struct {
		unsigned	rc : 5,
				function : 7,
				zero : 1,
				sbz : 3,
				rb : 5,
				ra : 5,
				opcode : 6;
	} operate_reg_format;

	struct {
		unsigned	rc : 5,
				function : 7,
				one : 1,
				literal : 8,
				ra : 5,
				opcode : 6;
	} operate_lit_format;

	/*
	 *	Floating point operate instruction are quite
	 *	uniform in the encoding.  As for the semantics..
	 */
	struct {
		unsigned	fc : 5,
				function : 11,
				fb : 5,
				fa : 5,
				opcode : 6;
	} float_format;

	struct {
		unsigned	fc : 5,
				opclass : 4,
				src : 2,
				rnd : 2,
				trp : 3,
				fb : 5,
				fa : 5,
				opcode : 6;
	} float_detail;

	/*
	 *	PAL instructions just define the major opcode
	 */

	struct {
		unsigned	function : 26,
				opcode : 6;
	} pal_format;

} alpha_instruction;

#endif /* !defined(ASSEMBLER) */

/*
 *
 *	Encoding of regular instructions  (Appendix C op cit)
 *
 */

		/* OPCODE, bits 26..31 */

#define	op_pal		0x00		/* see PAL sub-table */
					/* 1..7 reserved */
#define	op_lda		0x08
#define	op_ldah		0x09
#define	op_ldbu		0x0a
#define	op_ldq_u	0x0b
#define	op_ldwu		0x0c
#define	op_stw		0x0d
#define	op_stb		0x0e
#define	op_stq_u	0x0f

#define	op_arit		0x10		/* see ARIT sub-table */
#define	op_logical	0x11		/* see LOGICAL sub-table */
#define	op_bit		0x12		/* see BIT sub-table */
#define	op_mul		0x13		/* see MUL sub-table */
					/* reserved */
#define	op_fix_float	0x14		/* if ALPHA_AMASK_FIX */
#define	op_vax_float	0x15		/* see FLOAT sub-table */
#define	op_ieee_float	0x16		/* see FLOAT sub-table */
#define	op_any_float	0x17		/* see FLOAT sub-table */

#define	op_special	0x18		/* see SPECIAL sub-table */
#define	op_pal19	0x19		/* reserved for pal code */
#define	op_j		0x1a		/* see JUMP sub-table */
#define	op_pal1b	0x1b		/* reserved for pal code */
#define	op_intmisc	0x1c		/* see INTMISC sub-table */
#define	op_pal1d	0x1d		/* reserved for pal code */
#define	op_pal1e	0x1e		/* reserved for pal code */
#define	op_pal1f	0x1f		/* reserved for pal code */

#define	op_ldf		0x20
#define	op_ldg		0x21
#define	op_lds		0x22
#define	op_ldt		0x23
#define	op_stf		0x24
#define	op_stg		0x25
#define	op_sts		0x26
#define	op_stt		0x27
#define	op_ldl		0x28
#define	op_ldq		0x29
#define	op_ldl_l	0x2a
#define	op_ldq_l	0x2b
#define	op_stl		0x2c
#define	op_stq		0x2d
#define	op_stl_c	0x2e
#define	op_stq_c	0x2f
#define	op_br		0x30
#define	op_fbeq		0x31
#define	op_fblt		0x32
#define	op_fble		0x33
#define	op_bsr		0x34
#define	op_fbne		0x35
#define	op_fbge		0x36
#define	op_fbgt		0x37
#define	op_blbc		0x38
#define	op_beq		0x39
#define	op_blt		0x3a
#define	op_ble		0x3b
#define	op_blbs		0x3c
#define	op_bne		0x3d
#define	op_bge		0x3e
#define op_bgt		0x3f

		/* PAL, "function" opcodes (bits 0..25) */
/*
 * What we will implement is TBD.  These are the unprivileged ones
 * that we probably have to support for compat reasons.
 */

/* See <machine/pal.h> */

		/* ARIT, "function" opcodes (bits 5..11)  */

#define	op_addl		0x00
#define	op_s4addl	0x02
#define	op_subl		0x09
#define	op_s4subl	0x0b
#define	op_cmpbge	0x0f
#define	op_s8addl	0x12
#define	op_s8subl	0x1b
#define	op_cmpult	0x1d
#define	op_addq		0x20
#define	op_s4addq	0x22
#define	op_subq		0x29
#define	op_s4subq	0x2b
#define	op_cmpeq	0x2d
#define	op_s8addq	0x32
#define	op_s8subq	0x3b
#define	op_cmpule	0x3d
#define	op_addl_v	0x40
#define	op_subl_v	0x49
#define	op_cmplt	0x4d
#define	op_addq_v	0x60
#define	op_subq_v	0x69
#define	op_cmple	0x6d

		/* LOGICAL, "function" opcodes (bits 5..11)  */

#define	op_and		0x00
#define	op_andnot	0x08	/* bic */
#define	op_cmovlbs	0x14
#define	op_cmovlbc	0x16
#define	op_or		0x20	/* bis */
#define	op_cmoveq	0x24
#define	op_cmovne	0x26
#define	op_ornot	0x28
#define	op_xor		0x40
#define	op_cmovlt	0x44
#define	op_cmovge	0x46
#define	op_xornot	0x48	/* eqv */
#define	op_amask	0x61
#define	op_cmovle	0x64
#define	op_cmovgt	0x66
#define	op_implver	0x6c

		/* BIT, "function" opcodes (bits 5..11)  */

#define	op_mskbl	0x02
#define	op_extbl	0x06
#define	op_insbl	0x0b
#define	op_mskwl	0x12
#define	op_extwl	0x16
#define	op_inswl	0x1b
#define	op_mskll	0x22
#define	op_extll	0x26
#define	op_insll	0x2b
#define	op_zap		0x30
#define	op_zapnot	0x31
#define	op_mskql	0x32
#define	op_srl		0x34
#define	op_extql	0x36
#define	op_sll		0x39
#define	op_insql	0x3b
#define	op_sra		0x3c
#define	op_mskwh	0x52
#define	op_inswh	0x57
#define	op_extwh	0x5a
#define	op_msklh	0x62
#define	op_inslh	0x67
#define	op_extlh	0x6a
#define	op_extqh	0x7a
#define	op_insqh	0x77
#define	op_mskqh	0x72

		/* MUL, "function" opcodes (bits 5..11)  */

#define	op_mull		0x00
#define	op_mulq_v	0x60
#define	op_mull_v	0x40
#define	op_umulh	0x30
#define	op_mulq		0x20

		/* SPECIAL, "displacement" opcodes (bits 0..15)  */

#define	op_trapb	0x0000
#define	op_excb		0x0400
#define	op_mb		0x4000
#define	op_wmb		0x4400
#define	op_fetch	0x8000
#define	op_fetch_m	0xa000
#define	op_rpcc		0xc000
#define op_rc		0xe000
#define	op_ecb		0xe800
#define	op_rs		0xf000
#define	op_wh64		0xf800

		/* JUMP, "action" opcodes (bits 14..15) */

#define	op_jmp		0x0
#define	op_jsr		0x1
#define	op_ret		0x2
#define	op_jcr		0x3

		/* INTMISC, "function" opcodes (operate format) */

#define	op_sextb	0x00
#define	op_sextw	0x01
#define	op_ctpop	0x30
#define	op_perr		0x31
#define	op_ctlz		0x32
#define	op_cttz		0x33
#define	op_unpkbw	0x34
#define	op_unpkbl	0x35
#define	op_pkwb		0x36
#define	op_pklb		0x37
#define	op_minsb8	0x38
#define	op_minsw4	0x39
#define	op_minub8	0x3a
#define	op_minuw4	0x3b
#define	op_maxub8	0x3c
#define	op_maxuw4	0x3d
#define	op_maxsb8	0x3e
#define	op_maxsw4	0x3f
#define	op_ftoit	0x70
#define	op_ftois	0x78

/*
 *
 *	Encoding of floating point instructions (pagg. C-5..6 op cit)
 *
 *	Load and store operations use opcodes op_ldf..op_stt
 */

		/* src encoding from function, 9..10 */
#define	op_src_sf	0
#define op_src_xd	1
#define op_src_tg	2
#define op_src_qq	3

		/* any FLOAT, "function" opcodes (bits 5..11)  */

#define	op_cvtlq	0x010
#define	op_cpys		0x020
#define	op_cpysn	0x021
#define	op_cpyse	0x022
#define	op_mt_fpcr	0x024
#define	op_mf_fpcr	0x025
#define	op_fcmoveq	0x02a
#define	op_fcmovne	0x02b
#define	op_fcmovlt	0x02c
#define	op_fcmovge	0x02d
#define	op_fcmovle	0x02e
#define	op_fcmovgt	0x02f
#define	op_cvtql	0x030
#define	op_cvtql_v	0x130
#define	op_cvtql_sv	0x530

		/* ieee FLOAT, "function" opcodes (bits 5..11)  */

#define	op_adds_c	0x000
#define	op_subs_c	0x001
#define	op_muls_c	0x002
#define	op_divs_c	0x003
#define	op_addt_c	0x020
#define	op_subt_c	0x021
#define	op_mult_c	0x022
#define	op_divt_c	0x023
#define	op_cvtts_c	0x02c
#define	op_cvttq_c	0x02f
#define	op_cvtqs_c	0x03c
#define	op_cvtqt_c	0x03e
#define	op_adds_m	0x040
#define	op_subs_m	0x041
#define	op_muls_m	0x042
#define	op_divs_m	0x043
#define	op_addt_m	0x060
#define	op_subt_m	0x061
#define	op_mult_m	0x062
#define	op_divt_m	0x063
#define	op_cvtts_m	0x06c
#define	op_cvtqs_m	0x07c
#define	op_cvtqt_m	0x07e
#define	op_adds		0x080
#define	op_subs		0x081
#define	op_muls		0x082
#define	op_divs		0x083
#define	op_addt		0x0a0
#define	op_subt		0x0a1
#define	op_mult		0x0a2
#define	op_divt		0x0a3
#define	op_cmptun	0x0a4
#define	op_cmpteq	0x0a5
#define	op_cmptlt	0x0a6
#define	op_cmptle	0x0a7
#define	op_cvtts	0x0ac
#define	op_cvttq	0x0af
#define	op_cvtqs	0x0bc
#define	op_cvtqt	0x0be
#define	op_adds_d	0x0c0
#define	op_subs_d	0x0c1
#define	op_muls_d	0x0c2
#define	op_divs_d	0x0c3
#define	op_addt_d	0x0e0
#define	op_subt_d	0x0e1
#define	op_mult_d	0x0e2
#define	op_divt_d	0x0e3
#define	op_cvtts_d	0x0ec
#define	op_cvtqs_d	0x0fc
#define	op_cvtqt_d	0x0fe
#define	op_adds_uc	0x100
#define	op_subs_uc	0x101
#define	op_muls_uc	0x102
#define	op_divs_uc	0x103
#define	op_addt_uc	0x120
#define	op_subt_uc	0x121
#define	op_mult_uc	0x122
#define	op_divt_uc	0x123
#define	op_cvtts_uc	0x12c
#define	op_cvttq_vc	0x12f
#define	op_adds_um	0x140
#define	op_subs_um	0x141
#define	op_muls_um	0x142
#define	op_divs_um	0x143
#define	op_addt_um	0x160
#define	op_subt_um	0x161
#define	op_mult_um	0x162
#define	op_divt_um	0x163
#define	op_cvtts_um	0x16c
#define	op_adds_u	0x180
#define	op_subs_u	0x181
#define	op_muls_u	0x182
#define	op_divs_u	0x183
#define	op_addt_u	0x1a0
#define	op_subt_u	0x1a1
#define	op_mult_u	0x1a2
#define	op_divt_u	0x1a3
#define	op_cvtts_u	0x1ac
#define	op_cvttq_v	0x1af
#define	op_adds_ud	0x1c0
#define	op_subs_ud	0x1c1
#define	op_muls_ud	0x1c2
#define	op_divs_ud	0x1c3
#define	op_addt_ud	0x1e0
#define	op_subt_ud	0x1e1
#define	op_mult_ud	0x1e2
#define	op_divt_ud	0x1e3
#define	op_cvtts_ud	0x1ec
#define	op_cvtst	0x2ac
#define	op_adds_suc	0x500
#define	op_subs_suc	0x501
#define	op_muls_suc	0x502
#define	op_divs_suc	0x503
#define	op_addt_suc	0x520
#define	op_subt_suc	0x521
#define	op_mult_suc	0x522
#define	op_divt_suc	0x523
#define	op_cvtts_suc	0x52c
#define	op_cvttq_svc	0x52f
#define	op_adds_sum	0x540
#define	op_subs_sum	0x541
#define	op_muls_sum	0x542
#define	op_divs_sum	0x543
#define	op_addt_sum	0x560
#define	op_subt_sum	0x561
#define	op_mult_sum	0x562
#define	op_divt_sum	0x563
#define	op_cvtts_sum	0x56c
#define	op_adds_su	0x580
#define	op_subs_su	0x581
#define	op_muls_su	0x582
#define	op_divs_su	0x583
#define	op_addt_su	0x5a0
#define	op_subt_su	0x5a1
#define	op_mult_su	0x5a2
#define	op_divt_su	0x5a3
#define	op_cmptun_su	0x5a4
#define	op_cmpteq_su	0x5a5
#define	op_cmptlt_su	0x5a6
#define	op_cmptle_su	0x5a7
#define	op_cvtts_su	0x5ac
#define	op_cvttq_sv	0x5af
#define	op_adds_sud	0x5c0
#define	op_subs_sud	0x5c1
#define	op_muls_sud	0x5c2
#define	op_divs_sud	0x5c3
#define	op_addt_sud	0x5e0
#define	op_subt_sud	0x5e1
#define	op_mult_sud	0x5e2
#define	op_divt_sud	0x5e3
#define	op_cvtts_sud	0x5ec
#define	op_cvtst_u	0x6ac
#define	op_adds_suic	0x700
#define	op_subs_suic	0x701
#define	op_muls_suic	0x702
#define	op_divs_suic	0x703
#define	op_addt_suic	0x720
#define	op_subt_suic	0x721
#define	op_mult_suic	0x722
#define	op_divt_suic	0x723
#define	op_cvtts_suic	0x72c
#define	op_cvttq_svic	0x72f
#define	op_cvtqs_suic	0x73c
#define	op_cvtqt_suic	0x73e
#define	op_adds_suim	0x740
#define	op_subs_suim	0x741
#define	op_muls_suim	0x742
#define	op_divs_suim	0x743
#define	op_addt_suim	0x760
#define	op_subt_suim	0x761
#define	op_mult_suim	0x762
#define	op_divt_suim	0x763
#define	op_cvtts_suim	0x76c
#define	op_cvtqs_suim	0x77c
#define	op_cvtqt_suim	0x77e
#define	op_adds_sui	0x780
#define	op_subs_sui	0x781
#define	op_muls_sui	0x782
#define	op_divs_sui	0x783
#define	op_addt_sui	0x7a0
#define	op_subt_sui	0x7a1
#define	op_mult_sui	0x7a2
#define	op_divt_sui	0x7a3
#define	op_cvtts_sui	0x7ac
#define	op_cvttq_svi	0x7af
#define	op_cvtqs_sui	0x7bc
#define	op_cvtqt_sui	0x7be
#define	op_adds_suid	0x7c0
#define	op_subs_suid	0x7c1
#define	op_muls_suid	0x7c2
#define	op_divs_suid	0x7c3
#define	op_addt_suid	0x7e0
#define	op_subt_suid	0x7e1
#define	op_mult_suid	0x7e2
#define	op_divt_suid	0x7e3
#define	op_cvtts_suid	0x7ec
#define	op_cvtqs_suid	0x7fc
#define	op_cvtqt_suid	0x7fe

		/* vax FLOAT, "function" opcodes (bits 5..11)  */

#define	op_addf_c	0x000
#define	op_subf_c	0x001
#define	op_mulf_c	0x002
#define	op_divf_c	0x003
#define	op_cvtdg_c	0x01e
#define	op_addg_c	0x020
#define	op_subg_c	0x021
#define	op_mulg_c	0x022
#define	op_divg_c	0x023
#define	op_cvtgf_c	0x02c
#define	op_cvtgd_c	0x02d
#define	op_cvtgqg_c	0x02f
#define	op_cvtqf_c	0x03c
#define	op_cvtqg_c	0x03e
#define	op_addf		0x080
#define	op_subf		0x081
#define	op_mulf		0x082
#define	op_divf		0x083
#define	op_cvtdg	0x09e
#define	op_addg		0x0a0
#define	op_subg		0x0a1
#define	op_mulg		0x0a2
#define	op_divg		0x0a3
#define	op_cmpgeq	0x0a5
#define	op_cmpglt	0x0a6
#define	op_cmpgle	0x0a7
#define	op_cvtgf	0x0ac
#define	op_cvtgd	0x0ad
#define	op_cvtgq	0x0af
#define	op_cvtqf	0x0bc
#define	op_cvtqg	0x0be
#define	op_addf_uc	0x100
#define	op_subf_uc	0x101
#define	op_mulf_uc	0x102
#define	op_divf_uc	0x103
#define	op_cvtdg_uc	0x11e
#define	op_addg_uc	0x120
#define	op_subg_uc	0x121
#define	op_mulg_uc	0x122
#define	op_divg_uc	0x123
#define	op_cvtgf_uc	0x12c
#define	op_cvtgd_uc	0x12d
#define	op_cvtgqg_vc	0x12f
#define	op_addf_u	0x180
#define	op_subf_u	0x181
#define	op_mulf_u	0x182
#define	op_divf_u	0x183
#define	op_cvtdg_u	0x19e
#define	op_addg_u	0x1a0
#define	op_subg_u	0x1a1
#define	op_mulg_u	0x1a2
#define	op_divg_u	0x1a3
#define	op_cvtgf_u	0x1ac
#define	op_cvtgd_u	0x1ad
#define	op_cvtgqg_v	0x1af
#define	op_addf_sc	0x400
#define	op_subf_sc	0x401
#define	op_mulf_sc	0x402
#define	op_divf_sc	0x403
#define	op_cvtdg_sc	0x41e
#define	op_addg_sc	0x420
#define	op_subg_sc	0x421
#define	op_mulg_sc	0x422
#define	op_divg_sc	0x423
#define	op_cvtgf_sc	0x42c
#define	op_cvtgd_sc	0x42d
#define	op_cvtgqg_sc	0x42f
#define	op_cvtqf_sc	0x43c
#define	op_cvtqg_sc	0x43e
#define	op_addf_s	0x480
#define	op_subf_s	0x481
#define	op_mulf_s	0x482
#define	op_divf_s	0x483
#define	op_cvtdg_s	0x49e
#define	op_addg_s	0x4a0
#define	op_subg_s	0x4a1
#define	op_mulg_s	0x4a2
#define	op_divg_s	0x4a3
#define	op_cmpgeq_s	0x4a5
#define	op_cmpglt_s	0x4a6
#define	op_cmpgle_s	0x4a7
#define	op_cvtgf_s	0x4ac
#define	op_cvtgd_s	0x4ad
#define	op_cvtgqg_s	0x4af
#define	op_cvtqf_s	0x4bc
#define	op_cvtqg_s	0x4be
#define	op_addf_suc	0x500
#define	op_subf_suc	0x501
#define	op_mulf_suc	0x502
#define	op_divf_suc	0x503
#define	op_cvtdg_suc	0x51e
#define	op_addg_suc	0x520
#define	op_subg_suc	0x521
#define	op_mulg_suc	0x522
#define	op_divg_suc	0x523
#define	op_cvtgf_suc	0x52c
#define	op_cvtgd_suc	0x52d
#define	op_cvtgqg_svc	0x52f
#define	op_addf_su	0x580
#define	op_subf_su	0x581
#define	op_mulf_su	0x582
#define	op_divf_su	0x583
#define	op_cvtdg_su	0x59e
#define	op_addg_su	0x5a0
#define	op_subg_su	0x5a1
#define	op_mulg_su	0x5a2
#define	op_divg_su	0x5a3
#define	op_cvtgf_su	0x5ac
#define	op_cvtgd_su	0x5ad
#define	op_cvtgqg_sv	0x5af

#endif	/* _ALPHA_INSTRUCTION_H_ */


code:
/* $OpenBSD: db_interface.c,v 1.21 2014/07/13 12:11:01 jasper Exp $ */
/* $NetBSD: db_interface.c,v 1.8 1999/10/12 17:08:57 jdolecek Exp $ */

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

/*
 * Parts of this file are derived from Mach 3:
 *
 *	File: alpha_instruction.c
 *	Author: Alessandro Forin, Carnegie Mellon University
 *	Date:	6/92
 */

/*
 * Interface to DDB.
 *
 * Modified for NetBSD/alpha by:
 *
 *	Christopher G. Demetriou, Carnegie Mellon University
 *
 *	Jason R. Thorpe, Numerical Aerospace Simulation Facility,
 *	NASA Ames Research Center
 */

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

#include <uvm/uvm_extern.h>

#include <dev/cons.h>

#include <machine/db_machdep.h>
#include <machine/pal.h>
#include <machine/prom.h>

#include <alpha/alpha/db_instruction.h>

#include <ddb/db_sym.h>
#include <ddb/db_command.h>
#include <ddb/db_extern.h>
#include <ddb/db_access.h>
#include <ddb/db_output.h>
#include <ddb/db_variables.h>
#include <ddb/db_interface.h>

extern label_t	*db_recover;

#if 0
extern char *trap_type[];
extern int trap_types;
#endif

db_regs_t ddb_regs;

#if defined(MULTIPROCESSOR)
void	db_mach_cpu(db_expr_t, int, db_expr_t, char *);
#endif

struct db_command db_machine_command_table[] = {
#if defined(MULTIPROCESSOR)
	{ "ddbcpu",	db_mach_cpu,	0,	NULL },
#endif
	{ NULL,		NULL,		0,	NULL }
};

int	db_active = 0;

struct db_variable db_regs[] = {
	{	"v0",	&ddb_regs.tf_regs[FRAME_V0],	FCN_NULL	},
	{	"t0",	&ddb_regs.tf_regs[FRAME_T0],	FCN_NULL	},
	{	"t1",	&ddb_regs.tf_regs[FRAME_T1],	FCN_NULL	},
	{	"t2",	&ddb_regs.tf_regs[FRAME_T2],	FCN_NULL	},
	{	"t3",	&ddb_regs.tf_regs[FRAME_T3],	FCN_NULL	},
	{	"t4",	&ddb_regs.tf_regs[FRAME_T4],	FCN_NULL	},
	{	"t5",	&ddb_regs.tf_regs[FRAME_T5],	FCN_NULL	},
	{	"t6",	&ddb_regs.tf_regs[FRAME_T6],	FCN_NULL	},
	{	"t7",	&ddb_regs.tf_regs[FRAME_T7],	FCN_NULL	},
	{	"s0",	&ddb_regs.tf_regs[FRAME_S0],	FCN_NULL	},
	{	"s1",	&ddb_regs.tf_regs[FRAME_S1],	FCN_NULL	},
	{	"s2",	&ddb_regs.tf_regs[FRAME_S2],	FCN_NULL	},
	{	"s3",	&ddb_regs.tf_regs[FRAME_S3],	FCN_NULL	},
	{	"s4",	&ddb_regs.tf_regs[FRAME_S4],	FCN_NULL	},
	{	"s5",	&ddb_regs.tf_regs[FRAME_S5],	FCN_NULL	},
	{	"s6",	&ddb_regs.tf_regs[FRAME_S6],	FCN_NULL	},
	{	"a0",	&ddb_regs.tf_regs[FRAME_A0],	FCN_NULL	},
	{	"a1",	&ddb_regs.tf_regs[FRAME_A1],	FCN_NULL	},
	{	"a2",	&ddb_regs.tf_regs[FRAME_A2],	FCN_NULL	},
	{	"a3",	&ddb_regs.tf_regs[FRAME_A3],	FCN_NULL	},
	{	"a4",	&ddb_regs.tf_regs[FRAME_A4],	FCN_NULL	},
	{	"a5",	&ddb_regs.tf_regs[FRAME_A5],	FCN_NULL	},
	{	"t8",	&ddb_regs.tf_regs[FRAME_T8],	FCN_NULL	},
	{	"t9",	&ddb_regs.tf_regs[FRAME_T9],	FCN_NULL	},
	{	"t10",	&ddb_regs.tf_regs[FRAME_T10],	FCN_NULL	},
	{	"t11",	&ddb_regs.tf_regs[FRAME_T11],	FCN_NULL	},
	{	"ra",	&ddb_regs.tf_regs[FRAME_RA],	FCN_NULL	},
	{	"t12",	&ddb_regs.tf_regs[FRAME_T12],	FCN_NULL	},
	{	"at",	&ddb_regs.tf_regs[FRAME_AT],	FCN_NULL	},
	{	"gp",	&ddb_regs.tf_regs[FRAME_GP],	FCN_NULL	},
	{	"sp",	&ddb_regs.tf_regs[FRAME_SP],	FCN_NULL	},
	{	"pc",	&ddb_regs.tf_regs[FRAME_PC],	FCN_NULL	},
	{	"ps",	&ddb_regs.tf_regs[FRAME_PS],	FCN_NULL	},
	{	"ai",	&ddb_regs.tf_regs[FRAME_T11],	FCN_NULL	},
	{	"pv",	&ddb_regs.tf_regs[FRAME_T12],	FCN_NULL	},
};
struct db_variable *db_eregs = db_regs + nitems(db_regs);

/*
 * ddb_trap - field a kernel trap
 */
int
ddb_trap(a0, a1, a2, entry, regs)
	unsigned long a0, a1, a2, entry;
	db_regs_t *regs;
{
	struct cpu_info *ci = curcpu();
	int s;

	if (entry != ALPHA_KENTRY_IF ||
	    (a0 != ALPHA_IF_CODE_BPT && a0 != ALPHA_IF_CODE_BUGCHK)) {
		if (db_recover != 0) {
			/* This will longjmp back into db_command_loop() */
			db_error("Caught exception in ddb.\n");
			/* NOTREACHED */
		}

		/*
		 * Tell caller "We did NOT handle the trap."
		 * Caller should panic, or whatever.
		 */
		return (0);
	}

	/*
	 * alpha_debug() switches us to the debugger stack.
	 */

	ci->ci_db_regs = regs;
	ddb_regs = *regs;

	s = splhigh();

	db_active++;
	cnpollc(TRUE);		/* Set polling mode, unblank video */

	db_trap(entry, a0);	/* Where the work happens */

	cnpollc(FALSE);		/* Resume interrupt mode */
	db_active--;

	splx(s);

	*regs = ddb_regs;

	/*
	 * Tell caller "We HAVE handled the trap."
	 */
	return (1);
}

/*
 * Read bytes from kernel address space for debugger.
 */
void
db_read_bytes(addr, size, data)
	vaddr_t		addr;
	register size_t	size;
	register char	*data;
{
	register char	*src;

	src = (char *)addr;
	while (size-- > 0)
		*data++ = *src++;
}

/*
 * Write bytes to kernel address space for debugger.
 */
void
db_write_bytes(addr, size, data)
	vaddr_t		addr;
	register size_t	size;
	register char	*data;
{
	register char	*dst;

	dst = (char *)addr;
	while (size-- > 0)
		*dst++ = *data++;
	alpha_pal_imb();
}

void
Debugger()
{

	__asm volatile("call_pal 0x81");		/* bugchk */
}

/*
 * Map Alpha register numbers to trapframe/db_regs_t offsets.
 */
static int reg_to_frame[32] = {
	FRAME_V0,
	FRAME_T0,
	FRAME_T1,
	FRAME_T2,
	FRAME_T3,
	FRAME_T4,
	FRAME_T5,
	FRAME_T6,
	FRAME_T7,

	FRAME_S0,
	FRAME_S1,
	FRAME_S2,
	FRAME_S3,
	FRAME_S4,
	FRAME_S5,
	FRAME_S6,

	FRAME_A0,
	FRAME_A1,
	FRAME_A2,
	FRAME_A3,
	FRAME_A4,
	FRAME_A5,

	FRAME_T8,
	FRAME_T9,
	FRAME_T10,
	FRAME_T11,
	FRAME_RA,
	FRAME_T12,
	FRAME_AT,
	FRAME_GP,
	FRAME_SP,
	-1,		/* zero */
};

u_long
db_register_value(regs, regno)
	db_regs_t *regs;
	int regno;
{

	if (regno > 31 || regno < 0) {
		db_printf(" **** STRANGE REGISTER NUMBER %d **** ", regno);
		return (0);
	}

	if (regno == 31)
		return (0);

	return (regs->tf_regs[reg_to_frame[regno]]);
}

/*
 * Support functions for software single-step.
 */

boolean_t
db_inst_call(ins)
	int ins;
{
	alpha_instruction insn;

	insn.bits = ins;
	return ((insn.branch_format.opcode == op_bsr) ||
	    ((insn.jump_format.opcode == op_j) &&
	     (insn.jump_format.action & 1)));
}

boolean_t
db_inst_return(ins)
	int ins;
{
	alpha_instruction insn;

	insn.bits = ins;
	return ((insn.jump_format.opcode == op_j) &&
	    (insn.jump_format.action == op_ret));
}

boolean_t
db_inst_trap_return(ins)
	int ins;
{
	alpha_instruction insn;

	insn.bits = ins;
	return ((insn.pal_format.opcode == op_pal) &&
	    (insn.pal_format.function == PAL_OSF1_rti));
}

boolean_t
db_inst_branch(ins)
	int ins;
{
	alpha_instruction insn;

	insn.bits = ins;
	switch (insn.branch_format.opcode) {
	case op_j:
	case op_br:
	case op_fbeq:
	case op_fblt:
	case op_fble:
	case op_fbne:
	case op_fbge:
	case op_fbgt:
	case op_blbc:
	case op_beq:
	case op_blt:
	case op_ble:
	case op_blbs:
	case op_bne:
	case op_bge:
	case op_bgt:
		return (TRUE);
	}

	return (FALSE);
}

boolean_t
db_inst_unconditional_flow_transfer(ins)
	int ins;
{
	alpha_instruction insn;

	insn.bits = ins;
	switch (insn.branch_format.opcode) {
	case op_j:
	case op_br:
		return (TRUE);

	case op_pal:
		switch (insn.pal_format.function) {
		case PAL_OSF1_retsys:
		case PAL_OSF1_rti:
		case PAL_OSF1_callsys:
			return (TRUE);
		}
	}

	return (FALSE);
}

#if 0
boolean_t
db_inst_spill(ins, regn)
	int ins, regn;
{
	alpha_instruction insn;

	insn.bits = ins;
	return ((insn.mem_format.opcode == op_stq) &&
	    (insn.mem_format.rd == regn));
}
#endif

boolean_t
db_inst_load(ins)
	int ins;
{
	alpha_instruction insn;

	insn.bits = ins;

	/* Loads. */
	if (insn.mem_format.opcode == op_ldbu ||
	    insn.mem_format.opcode == op_ldq_u ||
	    insn.mem_format.opcode == op_ldwu)
		return (TRUE);
	if ((insn.mem_format.opcode >= op_ldf) &&
	    (insn.mem_format.opcode <= op_ldt))
		return (TRUE);
	if ((insn.mem_format.opcode >= op_ldl) &&
	    (insn.mem_format.opcode <= op_ldq_l))
		return (TRUE);

	/* Prefetches. */
	if (insn.mem_format.opcode == op_special) {
		/* Note: MB is treated as a store. */
		if ((insn.mem_format.displacement == (short)op_fetch) ||
		    (insn.mem_format.displacement == (short)op_fetch_m))
			return (TRUE);
	}

	return (FALSE);
}

db_addr_t
db_branch_taken(ins, pc, regs)
	int ins;
	db_addr_t pc;
	db_regs_t *regs;
{
	long signed_immediate;
	alpha_instruction insn;
	db_addr_t newpc;

	insn.bits = ins;
	switch (insn.branch_format.opcode) {
	/*
	 * Jump format: target PC is (contents of instruction's "RB") & ~3.
	 */
	case op_j:
		newpc = db_register_value(regs, insn.jump_format.rb) & ~3;
		break;

	/*
	 * Branch format: target PC is
	 *	(new PC) + (4 * sign-ext(displacement)).
	 */
	case op_br:
	case op_fbeq:
	case op_fblt:
	case op_fble:
	case op_bsr:
	case op_fbne:
	case op_fbge:
	case op_fbgt:
	case op_blbc:
	case op_beq:
	case op_blt:
	case op_ble:
	case op_blbs:
	case op_bne:
	case op_bge:
	case op_bgt:
		signed_immediate = insn.branch_format.displacement;
		newpc = (pc + 4) + (signed_immediate << 2);
		break;

	default:
		printf("DDB: db_inst_branch_taken on non-branch!\n");
		newpc = pc;	/* XXX */
	}

	return (newpc);
}

/*
 * Validate an address for use as a breakpoint.  We cannot let some
 * addresses have breakpoints as the ddb code itself uses that codepath.
 * Recursion and kernel stack space exhaustion will follow.
 */
int
db_valid_breakpoint(addr)
	db_addr_t addr;
{
	char *name;
	db_expr_t offset;

	db_find_sym_and_offset(addr, &name, &offset);
	if (name && strcmp(name, "alpha_pal_swpipl") == 0)
		return (0);
	return (1);
}

db_addr_t
next_instr_address(pc, branch)
	db_addr_t pc;
	int branch;
{
	if (!branch)
		return (pc + sizeof(int));
	return (branch_taken(*(u_int *)pc, pc, getreg_val, DDB_REGS));
}

#if defined(MULTIPROCESSOR)
void
db_mach_cpu(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
{
	struct cpu_info *ci;
	CPU_INFO_ITERATOR cii;

	if (have_addr == 0) {
		db_printf("addr               dev   id flg mtx ipis "
		    "curproc            fpcurproc\n");
		CPU_INFO_FOREACH(cii, ci)
			db_printf("%p %-5s %02lu %03lx %03d %04lx %p %p\n",
			    ci, ci->ci_dev->dv_xname, ci->ci_cpuid,
			    ci->ci_flags, ci->ci_mutex_level, ci->ci_ipis,
			    ci->ci_curproc, ci->ci_fpcurproc);
		return;
	}

	if (addr < 0 || addr >= ALPHA_MAXPROCS) {
		db_printf("CPU %ld out of range\n", addr);
		return;
	}

	ci = cpu_info[addr];
	if (ci == NULL) {
		db_printf("CPU %ld is not configured\n", addr);
		return;
	}

	if (ci != curcpu()) {
		if ((ci->ci_flags & CPUF_PAUSED) == 0) {
			db_printf("CPU %ld not paused\n", addr);
			return;
		}
	}

	if (ci->ci_db_regs == NULL) {
		db_printf("CPU %ld has no register state\n", addr);
		return;
	}

	db_printf("Using CPU %ld\n", addr);
	ddb_regs = *ci->ci_db_regs;	/* struct copy */
}
#endif /* MULTIPROCESSOR */

void
db_machine_init()
{
	db_machine_commands_install(db_machine_command_table);
}

license: unknown


code:
/*	$OpenBSD: db_trace.c,v 1.16 2014/01/30 20:11:14 miod Exp $	*/

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

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

#include <uvm/uvm_extern.h>

#include <machine/db_machdep.h>
#include <machine/frame.h>

#include <ddb/db_access.h>
#include <ddb/db_command.h>
#include <ddb/db_output.h>
#include <ddb/db_sym.h>
#include <ddb/db_variables.h>
#include <ddb/db_extern.h>
#include <ddb/db_interface.h>

extern int	etext;

struct opcode opcode[] = {
	{ OPC_PAL, "call_pal", 0 },	/* 00 */
	{ OPC_RES, "opc01", 0 },	/* 01 */
	{ OPC_RES, "opc02", 0 },	/* 02 */
	{ OPC_RES, "opc03", 0 },	/* 03 */
	{ OPC_RES, "opc04", 0 },	/* 04 */
	{ OPC_RES, "opc05", 0 },	/* 05 */
	{ OPC_RES, "opc06", 0 },	/* 06 */
	{ OPC_RES, "opc07", 0 },	/* 07 */
	{ OPC_MEM, "lda", 1 },		/* 08 */
	{ OPC_MEM, "ldah", 1 },		/* 09 */
	{ OPC_RES, "opc0a", 0 },	/* 0A */
	{ OPC_MEM, "ldq_u", 1 },	/* 0B */
	{ OPC_RES, "opc0c", 0 },	/* 0C */
	{ OPC_RES, "opc0d", 0 },	/* 0D */
	{ OPC_RES, "opc0e", 0 },	/* 0E */
	{ OPC_MEM, "stq_u", 1 },	/* 0F */
	{ OPC_OP, "inta", 0 },		/* 10 */
	{ OPC_OP, "intl", 0 },		/* 11 */
	{ OPC_OP, "ints", 0 },		/* 12 */
	{ OPC_OP, "intm", 0 },		/* 13 */
	{ OPC_RES, "opc14", 0 },	/* 14 */
	{ OPC_OP, "fltv", 1 },		/* 15 */
	{ OPC_OP, "flti", 1 },		/* 16 */
	{ OPC_OP, "fltl", 1 },		/* 17 */
	{ OPC_MEM, "misc", 0 },		/* 18 */
	{ OPC_PAL, "pal19", 0 },	/* 19 */
	{ OPC_MEM, "jsr", 0 },		/* 1A */
	{ OPC_PAL, "pal1b", 0 },	/* 1B */
	{ OPC_RES, "opc1c", 0 },	/* 1C */
	{ OPC_PAL, "pal1d", 0 },	/* 1D */
	{ OPC_PAL, "pal1e", 0 },	/* 1E */
	{ OPC_PAL, "pal1f", 0 },	/* 1F */
	{ OPC_MEM, "ldf", 1 },		/* 20 */
	{ OPC_MEM, "ldg", 1 },		/* 21 */
	{ OPC_MEM, "lds", 1 },		/* 22 */
	{ OPC_MEM, "ldt", 1 },		/* 23 */
	{ OPC_MEM, "stf", 1 },		/* 24 */
	{ OPC_MEM, "stg", 1 },		/* 25 */
	{ OPC_MEM, "sts", 1 },		/* 26 */
	{ OPC_MEM, "stt", 1 },		/* 27 */
	{ OPC_MEM, "ldl", 1 },		/* 28 */
	{ OPC_MEM, "ldq", 1 },		/* 29 */
	{ OPC_MEM, "ldl_l", 1 },	/* 2A */
	{ OPC_MEM, "ldq_l", 1 },	/* 2B */
	{ OPC_MEM, "stl", 1 },		/* 2C */
	{ OPC_MEM, "stq", 1 },		/* 2D */
	{ OPC_MEM, "stl_c", 1 },	/* 2E */
	{ OPC_MEM, "stq_c", 1 },	/* 2F */
	{ OPC_BR, "br", 1 },		/* 30 */
	{ OPC_BR, "fbeq", 1 },		/* 31 */
	{ OPC_BR, "fblt", 1 },		/* 32 */
	{ OPC_BR, "fble", 1 },		/* 33 */
	{ OPC_BR, "bsr", 1 },		/* 34 */
	{ OPC_BR, "fbne", 1 },		/* 35 */
	{ OPC_BR, "fbge", 1 },		/* 36 */
	{ OPC_BR, "fbgt", 1 },		/* 37 */
	{ OPC_BR, "blbc", 1 },		/* 38 */
	{ OPC_BR, "beq", 1 },		/* 39 */
	{ OPC_BR, "blt", 1 },		/* 3A */
	{ OPC_BR, "ble", 1 },		/* 3B */
	{ OPC_BR, "blbs", 1 },		/* 3C */
	{ OPC_BR, "bne", 1 },		/* 3D */
	{ OPC_BR, "bge", 1 },		/* 3E */
	{ OPC_BR, "bgt", 1 },		/* 3F */
};

static __inline int sext(u_int);
static __inline int rega(u_int);
static __inline int regb(u_int);
static __inline int regc(u_int);
static __inline int disp(u_int);

static __inline int
sext(x)
	u_int x;
{
	return ((x & 0x8000) ? -(-x & 0xffff) : (x & 0xffff));
}

static __inline int
rega(x)
	u_int x;
{
	return ((x >> 21) & 0x1f);
}

static __inline int
regb(x)
	u_int x;
{
	return ((x >> 16) & 0x1f);
}

static __inline int
regc(x)
	u_int x;
{
	return (x & 0x1f);
}

static __inline int
disp(x)
	u_int x;
{
	return (sext(x & 0xffff));
}

/*
 * XXX There are a couple of problems with this code:
 *
 *	The argument list printout code is likely to get confused.
 *
 *	It relies on the conventions of gcc code generation.
 *
 *	It uses heuristics to calculate the framesize, and might get it wrong.
 *
 *	It doesn't yet use the framepointer if available.
 *
 *	The address argument can only be used for pointing at trapframes
 *	since a frame pointer of its own serves no good on the alpha,
 *	you need a pc value too.
 *
 *	The heuristics used for tracing through a trap relies on having
 *	symbols available.
 */
void
db_stack_trace_print(addr, have_addr, count, modif, pr)
	db_expr_t       addr;
	int             have_addr;
	db_expr_t       count;
	char            *modif;
	int		(*pr)(const char *, ...);
{
	u_long		*frame;
	int		i, framesize;
	db_addr_t	pc, ra;
	u_int		inst;
	char		*name;
	db_expr_t	offset;
	db_regs_t	*regs;
	u_long		*slot[32];

	bzero(slot, sizeof(slot));
	if (count == -1)
		count = 65535;

	if (have_addr) {
		(*pr)("alpha trace requires a trap frame... giving up.\n");
		return;
	}
	regs = DDB_REGS;
trapframe:
	/* remember where various registers are stored */
	for (i = 0; i < 31; i++)
		slot[i] = &regs->tf_regs[0] +
		    ((u_long *)db_regs[i].valuep - &ddb_regs.tf_regs[0]);
	frame = (u_long *)regs->tf_regs[FRAME_SP];
	pc = (db_addr_t)regs->tf_regs[FRAME_PC];
	ra = (db_addr_t)regs->tf_regs[FRAME_RA];

	while (count-- && pc >= (db_addr_t)KERNBASE && pc < (db_addr_t)&etext) {
		db_find_sym_and_offset(pc, &name, &offset);
		if (!name) {
			name = "?";
			/* Limit the search for procedure start */
			offset = 65536;
		}
		(*pr)("%s(", name);

		framesize = 0;
		for (i = sizeof (int); i <= offset; i += sizeof (int)) {
			inst = *(u_int *)(pc - i);

			/*
			 * If by chance we don't have any symbols we have to
			 * get out somehow anyway.  Check for the preceding
			 * procedure return in that case.
			 */
			if (name[0] == '?' && inst_return(inst))
				break;

			/*
			 * Disassemble to get the needed info for the frame.
			 */
			if ((inst & 0xffff0000) == 0x23de0000)
				/* lda sp,n(sp) */
				framesize -= disp(inst) / sizeof (u_long);
			else if ((inst & 0xfc1f0000) == 0xb41e0000)
				/* stq X,n(sp) */
				slot[rega(inst)] =
				    frame + disp(inst) / sizeof (u_long);
			else if ((inst & 0xfc000fe0) == 0x44000400 &&
			    rega(inst) == regb(inst)) {
				/* bis X,X,Y (aka mov X,Y) */
				/* zero is hardwired */
				if (rega(inst) != 31)
					slot[rega(inst)] = slot[regc(inst)];
				slot[regc(inst)] = 0;
				/*
				 * XXX In here we might special case a frame
				 * pointer setup, i.e. mov sp, fp.
				 */
			} else if (db_inst_load(inst))
				/* clobbers a register */
				slot[rega(inst)] = 0;
			else if (opcode[inst >> 26].opc_fmt == OPC_OP)
				/* clobbers a register */
				slot[regc(inst)] = 0;
			/*
			 * XXX Recognize more reg clobbering instructions and
			 * set slot[reg] = 0 then too.
			 */
		}

		/*
		 * Try to print the 6 quads that might hold the args.
		 * We print 6 of them even if there are fewer, cause we don't
		 * know the number.  Maybe we could skip the last ones
		 * that never got used.  If we cannot know the value, print
		 * a question mark.
		 */
		for (i = 0; i < 6; i++) {
			if (i > 0)
				(*pr)(", ");
			if (slot[16 + i])
				(*pr)("%lx", *slot[16 + i]);
			else
				(*pr)("?");
		}

#if 0
		/*
		 * XXX This will go eventually when I trust the argument
		 * printout heuristics.
		 *
		 * Print the stack frame contents.
		 */
		(*pr)(") [%p: ", frame);
		if (framesize > 1) {
			for (i = 0; i < framesize - 1; i++)
				(*pr)("%lx, ", frame[i]);
			(*pr)("%lx", frame[i]);
		}
		(*pr)("] at ");
#else
		(*pr)(") at ");
#endif
		db_printsym(pc, DB_STGY_PROC, pr);
		(*pr)("\n");

		/*
		 * If we are looking at a Xent* routine we are in a trap
		 * context.
		 */
		if (strncmp(name, "Xent", sizeof("Xent") - 1) == 0) {
			regs = (db_regs_t *)frame;
			goto trapframe;
		}

		/* Look for the return address if recorded.  */
		if (slot[26])
			ra = *(db_addr_t *)slot[26];
		else
			break;

		/* Advance to the next frame, if any.  */
		frame += framesize;
		if (ra == pc)
			break;
		pc = ra;
	}
}


code:
/* $OpenBSD: debug.s,v 1.9 2015/06/27 10:51:46 dlg Exp $ */
/* $NetBSD: debug.s,v 1.5 1999/06/18 18:11:56 thorpej Exp $ */

/*-
 * Copyright (c) 1999 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
 * NASA Ames Research Center.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 defined (MULTIPROCESSOR)
.file	5 __FILE__
.loc	5 __LINE__
#else
.file	4 __FILE__
.loc	4 __LINE__
#endif

/*
 * Debugger glue.
 */

	.text

/*
 * Debugger stack.
 */
#define	DEBUG_STACK_SIZE	8192
BSS(debug_stack_bottom, DEBUG_STACK_SIZE)

#define	debug_stack_top	(debug_stack_bottom + DEBUG_STACK_SIZE)

/*
 * alpha_debug:
 *
 *	Single debugger entry point, handling the housekeeping
 *	chores we need to deal with.
 *
 *	Arguments are:
 *
 *		a0	a0 from trap
 *		a1	a1 from trap
 *		a2	a2 from trap
 *		a3	kernel trap entry point
 *		a4	frame pointer
 */
NESTED_NOPROFILE(alpha_debug, 5, 32, ra, IM_RA|IM_S0, 0)
	br	pv, 1f
1:	LDGP(pv)
	lda	t0, FRAME_SIZE*8(a4)	/* what would sp have been? */
	stq	t0, FRAME_SP*8(a4)	/* belatedly save sp for ddb view */
	lda	sp, -32(sp)		/* set up stack frame */
	stq	ra, (32-8)(sp)		/* save ra */
	stq	s0, (32-16)(sp)		/* save s0 */

	/* Remember our current stack pointer. */
	mov	sp, s0

#if defined(MULTIPROCESSOR)
	/* Pause all other CPUs. */
	ldiq	a0, 1
	CALL(cpu_pause_resume_all)
#endif

	/*
	 * Switch to the debug stack if we're not on it already.
	 */
	lda	t0, debug_stack_bottom
	cmpule	sp, t0, t1		/* sp <= debug_stack_bottom */
	bne	t1, 2f			/* yes, switch now */

	lda	t0, debug_stack_top
	cmpule	t0, sp, t1		/* debug_stack_top <= sp? */
	bne	t1, 3f			/* yes, we're on the debug stack */

2:	lda	sp, debug_stack_top	/* sp <- debug_stack_top */

3:	/* Dispatch to the debugger - arguments are already in place. */
	CALL(ddb_trap)

	/* Debugger return value in v0; switch back to our previous stack. */
	mov	s0, sp

#if defined(MULTIPROCESSOR)
	mov	v0, s0

	/* Resume all other CPUs. */
	mov	zero, a0
	CALL(cpu_pause_resume_all)

	mov	s0, v0
#endif

	ldq	ra, (32-8)(sp)		/* restore ra */
	ldq	s0, (32-16)(sp)		/* restore s0 */
	lda	sp, 32(sp)		/* pop stack frame */
	RET
	END(alpha_debug)

#if defined(MULTIPROCESSOR) && defined(MP_LOCKDEBUG)
NESTED(alpha_ipi_process_with_frame, 2, 8 * FRAME_SIZE, ra, IM_RA, 0)
	.set noat
	lda	sp, -(8 * FRAME_SIZE)(sp)		/* set up stack frame */

	stq	v0,(FRAME_V0*8)(sp)
	stq	t0,(FRAME_T0*8)(sp)
	stq	t1,(FRAME_T1*8)(sp)
	stq	t2,(FRAME_T2*8)(sp)
	stq	t3,(FRAME_T3*8)(sp)
	stq	t4,(FRAME_T4*8)(sp)
	stq	t5,(FRAME_T5*8)(sp)
	stq	t6,(FRAME_T6*8)(sp)
	stq	t7,(FRAME_T7*8)(sp)
	stq	s0,(FRAME_S0*8)(sp)
	stq	s1,(FRAME_S1*8)(sp)
	stq	s2,(FRAME_S2*8)(sp)
	stq	s3,(FRAME_S3*8)(sp)
	stq	s4,(FRAME_S4*8)(sp)
	stq	s5,(FRAME_S5*8)(sp)
	stq	s6,(FRAME_S6*8)(sp)
	stq	a3,(FRAME_A3*8)(sp)
	stq	a4,(FRAME_A4*8)(sp)
	stq	a5,(FRAME_A5*8)(sp)
	stq	t8,(FRAME_T8*8)(sp)
	stq	t9,(FRAME_T9*8)(sp)
	stq	t10,(FRAME_T10*8)(sp)
	stq	t11,(FRAME_T11*8)(sp)
	stq	ra,(FRAME_RA*8)(sp)
	stq	t12,(FRAME_T12*8)(sp)
	stq	at_reg,(FRAME_AT*8)(sp)
	lda	a1,(8*FRAME_SIZE)(sp)
	stq	a1,(FRAME_SP*8)(sp)

	stq	zero,(FRAME_PS*8)(sp)
	stq	zero,(FRAME_PC*8)(sp)
	stq	zero,(FRAME_GP*8)(sp)
	stq	zero,(FRAME_A0*8)(sp)
	stq	zero,(FRAME_A1*8)(sp)
	stq	zero,(FRAME_A2*8)(sp)

	mov	sp, a1
	CALL(alpha_ipi_process)

	ldq	ra,(FRAME_RA*8)(sp)
	lda	sp, (8 * FRAME_SIZE)(sp)		/* pop stack frame */
	RET
	END(alpha_ipi_process_with_frame)
	.set at
#endif


code:
/* $OpenBSD: dec_1000a.c,v 1.8 2014/05/08 20:46:49 miod Exp $ */
/* $NetBSD: dec_1000a.c,v 1.14 2001/06/05 04:53:11 thorpej Exp $ */

/*
 * Copyright (c) 1998 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is based on dec_kn20aa.c, written by Chris G. Demetriou at
 * Carnegie-Mellon University. Platform support for Noritake, Pintake, and
 * Corelle by Ross Harvey with copyright assignment by permission of Avalon
 * Computer Systems, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * Copyright (c) 1995, 1996, 1997 Carnegie-Mellon University.
 * All rights reserved.
 *
 * Author: Chris G. Demetriou
 *
 * Permission to use, copy, modify and distribute this software and
 * its documentation is hereby granted, provided that both the copyright
 * notice and this permission notice appear in all copies of the
 * software, derivative works or modified versions, and any portions
 * thereof, and that both notices appear in supporting documentation.
 *
 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
 *
 * Carnegie Mellon requests users of this software to return to
 *
 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
 *  School of Computer Science
 *  Carnegie Mellon University
 *  Pittsburgh PA 15213-3890
 *
 * any improvements or extensions that they make and grant Carnegie the
 * rights to redistribute these changes.
 */
/*
 * Additional Copyright (c) 1997 by Matthew Jacob for NASA/Ames Research Center
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/termios.h>
#include <dev/cons.h>

#include <machine/rpb.h>
#include <machine/autoconf.h>
#include <machine/cpuconf.h>
#include <machine/conf.h>
#include <machine/bus.h>

#include <dev/ic/comreg.h>
#include <dev/ic/comvar.h>

#include <dev/isa/isareg.h>
#include <dev/isa/isavar.h>
#include <dev/ic/i8042reg.h>
#include <dev/ic/pckbcvar.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>

#include <alpha/pci/apecsreg.h>
#include <alpha/pci/apecsvar.h>
#include <alpha/pci/ciareg.h>
#include <alpha/pci/ciavar.h>

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

#include "pckbd.h"

#ifndef CONSPEED
#define CONSPEED TTYDEF_SPEED
#endif
static int comcnrate = CONSPEED;

void _dec_1000a_init(void);
void dec_1000a_cons_init(void);
void dec_1000a_device_register(struct device *, void *);

#ifdef KGDB
#include <machine/db_machdep.h>

const char *kgdb_devlist[] = {
	"com",
	NULL,
};
#endif /* KGDB */

const struct alpha_variation_table dec_1000_variations[] = {
	{ 0, "AlphaServer 1000" },
	{ 0, NULL },
};

const struct alpha_variation_table dec_1000a_variations[] = {
	{ 0, "AlphaServer 1000A" },
	{ 0, NULL },
};

void
_dec_1000a_init()
{
	u_int64_t variation;

	platform.family = "AlphaServer 1000/1000A";

	if ((platform.model = alpha_dsr_sysname()) == NULL) {
		variation = hwrpb->rpb_variation & SV_ST_MASK;
		if ((platform.model = alpha_variation_name(variation,
		    cputype == ST_DEC_1000 ? dec_1000_variations
					   : dec_1000a_variations)) == NULL)
			platform.model = alpha_unknown_sysname();
	}

	switch(PCS_CPU_MAJORTYPE(LOCATE_PCS(hwrpb, 0))) {
	    case PCS_PROC_EV4:
	    case PCS_PROC_EV45:
		platform.iobus = "apecs";
		break;
	    default:
		platform.iobus = "cia";
		break;
	}
	platform.cons_init = dec_1000a_cons_init;
	platform.device_register = dec_1000a_device_register;
}

void
dec_1000a_cons_init()
{
	struct ctb *ctb;
	struct cia_config *ccp;
	struct apecs_config *acp;
	extern struct cia_config cia_configuration;
	extern struct apecs_config apecs_configuration;
	bus_space_tag_t iot, memt;
	struct alpha_pci_chipset *pcichipset;

	if(strcmp(platform.iobus, "cia") == 0) {
		ccp = &cia_configuration;
		cia_init(ccp, 0);
		iot = &ccp->cc_iot;
		memt = &ccp->cc_memt;
		pcichipset = &ccp->cc_pc;
	} else {
		acp = &apecs_configuration;
		apecs_init(acp, 0);
		iot = &acp->ac_iot;
		memt = &acp->ac_memt;
		pcichipset = &acp->ac_pc;
	}

	ctb = (struct ctb *)(((caddr_t)hwrpb) + hwrpb->rpb_ctb_off);

	switch (ctb->ctb_term_type) {
	case CTB_PRINTERPORT:
		/* serial console ... */
		/* XXX */
		{
			/*
			 * Delay to allow PROM putchars to complete.
			 * FIFO depth * character time,
			 * character time = (1000000 / (defaultrate / 10))
			 */
			DELAY(160000000 / comcnrate);

			if(comcnattach(iot, 0x3f8, comcnrate,
			    COM_FREQ,
			    (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8))
				panic("can't init serial console");

			break;
		}

	case CTB_GRAPHICS:
#if NPCKBD > 0
		/* display console ... */
		/* XXX */
		(void) pckbc_cnattach(iot, IO_KBD, KBCMDP, 0);

		/*
		 * AlphaServer 1000s have a firmware bug whereby the
		 * built-in ISA VGA is reported incorrectly -- ctb_turboslot
		 * is mostly 0.
		 */
		switch (CTB_TURBOSLOT_TYPE(ctb->ctb_turboslot)) {
		case CTB_TURBOSLOT_TYPE_PCI:
			pci_display_console(iot, memt, pcichipset,
			    CTB_TURBOSLOT_BUS(ctb->ctb_turboslot),
			    CTB_TURBOSLOT_SLOT(ctb->ctb_turboslot), 0);
			break;

		default:
			isa_display_console(iot, memt);
			break;
		}
#else
		panic("not configured to use display && keyboard console");
#endif
		break;

	default:
		printf("ctb->ctb_term_type = 0x%lx\n",
		    (unsigned long)ctb->ctb_term_type);
		printf("ctb->ctb_turboslot = 0x%lx\n",
		    (unsigned long)ctb->ctb_turboslot);

		panic("consinit: unknown console type %lu",
		    (unsigned long)ctb->ctb_term_type);
	}
#ifdef KGDB
	/* Attach the KGDB device. */
	alpha_kgdb_init(kgdb_devlist, iot);
#endif /* KGDB */
}

void
dec_1000a_device_register(dev, aux)
	struct device *dev;
	void *aux;
{
	static int found, initted, diskboot, netboot;
	static struct device *pcidev, *ctrlrdev;
	struct bootdev_data *b = bootdev_data;
	struct device *parent = dev->dv_parent;
	struct cfdata *cf = dev->dv_cfdata;
	struct cfdriver *cd = cf->cf_driver;

	if (found)
		return;

	if (!initted) {
		diskboot = (strncasecmp(b->protocol, "SCSI", 4) == 0);
		netboot = (strncasecmp(b->protocol, "BOOTP", 5) == 0) ||
		    (strncasecmp(b->protocol, "MOP", 3) == 0);
#if 0
		printf("diskboot = %d, netboot = %d\n", diskboot, netboot);
#endif
		initted =1;
	}

	if (pcidev == NULL) {
		if (strcmp(cd->cd_name, "pci"))
			return;
		else {
			struct pcibus_attach_args *pba = aux;

			if ((b->slot / 1000) != pba->pba_bus)
				return;

			pcidev = dev;
#if 0
			printf("\npcidev = %s\n", dev->dv_xname);
#endif
			return;
		}
	}

	if (ctrlrdev == NULL) {
		if (parent != pcidev)
			return;
		else {
			struct pci_attach_args *pa = aux;
			int slot;

			slot = pa->pa_bus * 1000 + pa->pa_function * 100 +
			    pa->pa_device;
			if (b->slot != slot)
				return;

			if (netboot) {
				booted_device = dev;
#if 0
				printf("\nbooted_device = %s\n", dev->dv_xname);
#endif
				found = 1;
			} else {
				ctrlrdev = dev;
#if 0
				printf("\nctrlrdev = %s\n", dev->dv_xname);
#endif
			}
			return;
		}
	}

	if (!diskboot)
		return;

	if (!strcmp(cd->cd_name, "sd") || !strcmp(cd->cd_name, "st") ||
	    !strcmp(cd->cd_name, "cd")) {
		struct scsi_attach_args *sa = aux;
		struct scsi_link *periph = sa->sa_sc_link;
		int unit;

		if (parent->dv_parent != ctrlrdev)
			return;

		unit = periph->target * 100 + periph->lun;
		if (b->unit != unit)
			return;

		/* we've found it! */
		booted_device = dev;
#if 0
		printf("\nbooted_device = %s\n", dev->dv_xname);
#endif
		found = 1;
	}
}


code:
/* $OpenBSD: dec_2100_a50.c,v 1.22 2014/05/08 20:46:49 miod Exp $ */
/* $NetBSD: dec_2100_a50.c,v 1.43 2000/05/22 20:13:31 thorpej Exp $ */

/*
 * Copyright (c) 1995, 1996, 1997 Carnegie-Mellon University.
 * All rights reserved.
 *
 * Author: Chris G. Demetriou
 *
 * Permission to use, copy, modify and distribute this software and
 * its documentation is hereby granted, provided that both the copyright
 * notice and this permission notice appear in all copies of the
 * software, derivative works or modified versions, and any portions
 * thereof, and that both notices appear in supporting documentation.
 *
 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
 *
 * Carnegie Mellon requests users of this software to return to
 *
 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
 *  School of Computer Science
 *  Carnegie Mellon University
 *  Pittsburgh PA 15213-3890
 *
 * any improvements or extensions that they make and grant Carnegie the
 * rights to redistribute these changes.
 */
/*
 * Additional Copyright (c) 1997 by Matthew Jacob for NASA/Ames Research Center
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/termios.h>
#include <dev/cons.h>
#include <sys/conf.h>

#include <machine/rpb.h>
#include <machine/autoconf.h>
#include <machine/bus.h>
#include <machine/cpuconf.h>
#include <machine/logout.h>

#include <dev/ic/comreg.h>
#include <dev/ic/comvar.h>

#include <dev/isa/isareg.h>
#include <dev/isa/isavar.h>
#include <dev/ic/i8042reg.h>
#include <dev/ic/pckbcvar.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>

#include <alpha/pci/apecsreg.h>
#include <alpha/pci/apecsvar.h>

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

#include "pckbd.h"

#ifndef CONSPEED
#define CONSPEED TTYDEF_SPEED
#endif
static int comcnrate = CONSPEED;

void dec_2100_a50_init(void);
static void dec_2100_a50_cons_init(void);
static void dec_2100_a50_device_register(struct device *, void *);

#ifndef SMALL_KERNEL
static void dec_2100_a50_mcheck_handler(unsigned long, struct trapframe *,
	    unsigned long, unsigned long);
static void dec_2100_a50_mcheck(unsigned long, unsigned long, unsigned long,
	    struct trapframe *);
#endif

const struct alpha_variation_table dec_2100_a50_variations[] = {
	{ SV_ST_AVANTI,	"AlphaStation 400 4/233 (\"Avanti\")" },
	{ SV_ST_MUSTANG2_4_166, "AlphaStation 200 4/166 (\"Mustang II\")" },
	{ SV_ST_MUSTANG2_4_233, "AlphaStation 200 4/233 (\"Mustang II\")" },
	{ SV_ST_AVANTI_4_266, "AlphaStation 250 4/266" },
	{ SV_ST_MUSTANG2_4_100, "AlphaStation 200 4/100 (\"Mustang II\")" },
	{ SV_ST_AVANTI_4_233, "AlphaStation 255/233" },
	{ 0, NULL },
};

void
dec_2100_a50_init()
{
	u_int64_t variation;

	platform.family = "AlphaStation 200/400 (\"Avanti\")";

	if ((platform.model = alpha_dsr_sysname()) == NULL) {
		variation = hwrpb->rpb_variation & SV_ST_MASK;
		if (variation == SV_ST_AVANTI_XXX) {
			/* XXX apparently the same? */
			variation = SV_ST_AVANTI;
		}
		if ((platform.model = alpha_variation_name(variation,
		    dec_2100_a50_variations)) == NULL)
			platform.model = alpha_unknown_sysname();
	}

	platform.iobus = "apecs";
	platform.cons_init = dec_2100_a50_cons_init;
	platform.device_register = dec_2100_a50_device_register;
#ifndef SMALL_KERNEL
	platform.mcheck_handler = dec_2100_a50_mcheck_handler;
#endif
}

static void
dec_2100_a50_cons_init()
{
	struct ctb *ctb;
	struct apecs_config *acp;
	extern struct apecs_config apecs_configuration;

	acp = &apecs_configuration;
	apecs_init(acp, 0);

	ctb = (struct ctb *)(((caddr_t)hwrpb) + hwrpb->rpb_ctb_off);

	switch (ctb->ctb_term_type) {
	case CTB_PRINTERPORT:
		/* serial console ... */
		/* XXX */
		{
			/*
			 * Delay to allow PROM putchars to complete.
			 * FIFO depth * character time,
			 * character time = (1000000 / (defaultrate / 10))
			 */
			DELAY(160000000 / comcnrate);

			if(comcnattach(&acp->ac_iot, 0x3f8, comcnrate,
			    COM_FREQ,
			    (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8))
				panic("can't init serial console");

			break;
		}

	case CTB_GRAPHICS:
#if NPCKBD > 0
		/* display console ... */
		/* XXX */
		(void) pckbc_cnattach(&acp->ac_iot, IO_KBD, KBCMDP, 0);

		if (CTB_TURBOSLOT_TYPE(ctb->ctb_turboslot) ==
		    CTB_TURBOSLOT_TYPE_ISA)
			isa_display_console(&acp->ac_iot, &acp->ac_memt);
		else
			pci_display_console(&acp->ac_iot, &acp->ac_memt,
			    &acp->ac_pc, CTB_TURBOSLOT_BUS(ctb->ctb_turboslot),
			    CTB_TURBOSLOT_SLOT(ctb->ctb_turboslot), 0);
#else
		panic("not configured to use display && keyboard console");
#endif
		break;

	default:
		printf("ctb->ctb_term_type = 0x%lx\n",
		    (unsigned long)ctb->ctb_term_type);
		printf("ctb->ctb_turboslot = 0x%lx\n",
		    (unsigned long)ctb->ctb_turboslot);

		panic("consinit: unknown console type %lu",
		    (unsigned long)ctb->ctb_term_type);
	}
}

static void
dec_2100_a50_device_register(dev, aux)
	struct device *dev;
	void *aux;
{
	static int found, initted, diskboot, netboot;
	static struct device *pcidev, *ctrlrdev;
	struct bootdev_data *b = bootdev_data;
	struct device *parent = dev->dv_parent;
	struct cfdata *cf = dev->dv_cfdata;
	struct cfdriver *cd = cf->cf_driver;

	if (found)
		return;

	if (!initted) {
		diskboot = (strncasecmp(b->protocol, "SCSI", 4) == 0);
		netboot = (strncasecmp(b->protocol, "BOOTP", 5) == 0) ||
		    (strncasecmp(b->protocol, "MOP", 3) == 0);
#if 0
		printf("diskboot = %d, netboot = %d\n", diskboot, netboot);
#endif
		initted =1;
	}

	if (pcidev == NULL) {
		if (strcmp(cd->cd_name, "pci"))
			return;
		else {
			struct pcibus_attach_args *pba = aux;

			if ((b->slot / 1000) != pba->pba_bus)
				return;

			pcidev = dev;
#if 0
			printf("\npcidev = %s\n", dev->dv_xname);
#endif
			return;
		}
	}

	if (ctrlrdev == NULL) {
		if (parent != pcidev)
			return;
		else {
			struct pci_attach_args *pa = aux;
			int slot;

			slot = pa->pa_bus * 1000 + pa->pa_function * 100 +
			    pa->pa_device;
			if (b->slot != slot)
				return;

			if (netboot) {
				booted_device = dev;
#if 0
				printf("\nbooted_device = %s\n", dev->dv_xname);
#endif
				found = 1;
			} else {
				ctrlrdev = dev;
#if 0
				printf("\nctrlrdev = %s\n", dev->dv_xname);
#endif
			}
			return;
		}
	}

	if (!diskboot)
		return;

	if (!strcmp(cd->cd_name, "sd") || !strcmp(cd->cd_name, "st") ||
	    !strcmp(cd->cd_name, "cd")) {
		struct scsi_attach_args *sa = aux;
		struct scsi_link *periph = sa->sa_sc_link;
		int unit;

		if (parent->dv_parent != ctrlrdev)
			return;

		unit = periph->target * 100 + periph->lun;
		if (b->unit != unit)
			return;

		/* we've found it! */
		booted_device = dev;
#if 0
		printf("\nbooted_device = %s\n", dev->dv_xname);
#endif
		found = 1;
	}
}

#ifndef SMALL_KERNEL
static void
dec_2100_a50_mcheck(mces, type, logout, framep)
	unsigned long mces;
	unsigned long type;
	unsigned long logout;
	struct trapframe *framep;
{
	struct mchkinfo *mcp;
	static const char *fmt1 = "        %-25s = 0x%016lx\n";
	int i, sysaddr;
	mc_hdr_avanti *hdr;
	mc_uc_avanti *ptr;

	/*
	 * If we expected a machine check, just go handle it in common code.
	 */
	mcp  = &curcpu()->ci_mcinfo;
	if (mcp->mc_expected) {
		machine_check(mces, framep, type, logout);
		return;
	}

	hdr = (mc_hdr_avanti *) logout;
	ptr = (mc_uc_avanti *) (logout + sizeof (*hdr));

	printf("      Processor Machine Check (%lx), Code 0x%x\n",
		   type, hdr->mcheck_code);
	printf("CPU state:\n");
	/* Print PAL fields */
	for (i = 0; i < 32; i += 2) {
		printf("\tPAL temp[%d-%d]\t\t= 0x%16lx 0x%16lx\n", i, i+1,
		    (unsigned long)ptr->paltemp[i],
		    (unsigned long)ptr->paltemp[i+1]);
	}
	printf(fmt1, "Excepting Instruction Addr", ptr->exc_addr);
	printf(fmt1, "Summary of arithmetic traps", ptr->exc_sum);
	printf(fmt1, "Exception mask", ptr->exc_mask);
	printf(fmt1, "ICCSR", ptr->iccsr);
	printf(fmt1, "Base address for PALcode", ptr->pal_base);
	printf(fmt1, "HIER", ptr->hier);
	printf(fmt1, "HIRR", ptr->hirr);
	printf(fmt1, "MM_CSR", ptr->mm_csr);
	printf(fmt1, "DC_STAT", ptr->dc_stat);
	printf(fmt1, "DC_ADDR", ptr->dc_addr);
	printf(fmt1, "ABOX_CTL", ptr->abox_ctl);
	printf(fmt1, "Bus Interface Unit status", ptr->biu_stat);
	printf(fmt1, "Bus Interface Unit addr", ptr->biu_addr);
	printf(fmt1, "Bus Interface Unit control", ptr->biu_ctl);
	printf(fmt1, "Fill Syndrome", ptr->fill_syndrome);
	printf(fmt1, "Fill Address", ptr->fill_addr);
	printf(fmt1, "Effective VA", ptr->va);
	printf(fmt1, "BC_TAG", ptr->bc_tag);

	printf("\nCache and Memory Controller (21071-CA) state:\n");
	printf(fmt1, "COMA_GCR", ptr->coma_gcr);
	printf(fmt1, "COMA_EDSR", ptr->coma_edsr);
	printf(fmt1, "COMA_TER", ptr->coma_ter);
	printf(fmt1, "COMA_ELAR", ptr->coma_elar);
	printf(fmt1, "COMA_EHAR", ptr->coma_ehar);
	printf(fmt1, "COMA_LDLR", ptr->coma_ldlr);
	printf(fmt1, "COMA_LDHR", ptr->coma_ldhr);
	printf(fmt1, "COMA_BASE0", ptr->coma_base0);
	printf(fmt1, "COMA_BASE1", ptr->coma_base1);
	printf(fmt1, "COMA_BASE2", ptr->coma_base2);
	printf(fmt1, "COMA_CNFG0", ptr->coma_cnfg0);
	printf(fmt1, "COMA_CNFG1", ptr->coma_cnfg1);
	printf(fmt1, "COMA_CNFG2", ptr->coma_cnfg2);

	printf("\nPCI bridge (21071-DA) state:\n");

	printf(fmt1, "EPIC Diag. control/status", ptr->epic_dcsr);
	printf(fmt1, "EPIC_PEAR", ptr->epic_pear);
	printf(fmt1, "EPIC_SEAR", ptr->epic_sear);
	printf(fmt1, "EPIC_TBR1", ptr->epic_tbr1);
	printf(fmt1, "EPIC_TBR2", ptr->epic_tbr2);
	printf(fmt1, "EPIC_PBR1", ptr->epic_pbr1);
	printf(fmt1, "EPIC_PBR2", ptr->epic_pbr2);
	printf(fmt1, "EPIC_PMR1", ptr->epic_pmr1);
	printf(fmt1, "EPIC_PMR2", ptr->epic_pmr2);
	printf(fmt1, "EPIC_HARX1", ptr->epic_harx1);
	printf(fmt1, "EPIC_HARX2", ptr->epic_harx2);
	printf(fmt1, "EPIC_PMLT", ptr->epic_pmlt);
	printf(fmt1, "EPIC_TAG0", ptr->epic_tag0);
	printf(fmt1, "EPIC_TAG1", ptr->epic_tag1);
	printf(fmt1, "EPIC_TAG2", ptr->epic_tag2);
	printf(fmt1, "EPIC_TAG3", ptr->epic_tag3);
	printf(fmt1, "EPIC_TAG4", ptr->epic_tag4);
	printf(fmt1, "EPIC_TAG5", ptr->epic_tag5);
	printf(fmt1, "EPIC_TAG6", ptr->epic_tag6);
	printf(fmt1, "EPIC_TAG7", ptr->epic_tag7);
	printf(fmt1, "EPIC_DATA0", ptr->epic_data0);
	printf(fmt1, "EPIC_DATA1", ptr->epic_data1);
	printf(fmt1, "EPIC_DATA2", ptr->epic_data2);
	printf(fmt1, "EPIC_DATA3", ptr->epic_data3);
	printf(fmt1, "EPIC_DATA4", ptr->epic_data4);
	printf(fmt1, "EPIC_DATA5", ptr->epic_data5);
	printf(fmt1, "EPIC_DATA6", ptr->epic_data6);
	printf(fmt1, "EPIC_DATA7", ptr->epic_data7);

	printf("\n");

	if (type == ALPHA_SYS_MCHECK) {
	  printf("\nPCI bridge fault\n");
	  switch(hdr->mcheck_code) {
	  case AVANTI_RETRY_TIMEOUT:
	    printf("\tRetry timeout error accessing 0x%08lx.\n",
		   (unsigned long)ptr->epic_pear & 0xffffffff);
	    break;

	  case AVANTI_DMA_DATA_PARITY:
	    printf("\tDMA data parity error accessing 0x%08lx.\n",
		   (unsigned long)ptr->epic_pear & 0xffffffff);
	    break;

	  case AVANTI_IO_PARITY:
	    printf("\tI/O parity error at 0x%08lx during PCI cycle 0x%0lx.\n",
		   (unsigned long)ptr->epic_pear & 0xffffffff,
		   (unsigned long)(ptr->epic_dcsr >> 18) & 0xf);
	    break;

	  case AVANTI_TARGET_ABORT:
	    printf("\tPCI target abort at 0x%08lx during PCI cycle 0x%0lx.\n",
		   (unsigned long)ptr->epic_pear & 0xffffffff,
		   (unsigned long)(ptr->epic_dcsr >> 18) & 0xf);
	    break;

	  case AVANTI_NO_DEVICE:
	    printf("\tNo device responded at 0x%08lx during PCI cycle 0x%0lx\n.",
		   (unsigned long)ptr->epic_pear & 0xffffffff,
		   (unsigned long)(ptr->epic_dcsr >> 18) & 0xf);
	    break;

	  case AVANTI_CORRRECTABLE_MEMORY:
	    printf("\tCorrectable memory error reported.\n"
		   "\tWARNING ECC not implemented on this system!\n"
		   "\tError is incorrect.\n");
	    break;

	  case AVANTI_UNCORRECTABLE_PCI_MEMORY:
	    printf("\tUncorrectable memory error at %016lx reported "
		   "during DMA read.\n",
		   (unsigned long)(ptr->epic_sear & 0xfffffff0) << 2);
	    break;

	  case AVANTI_INVALID_PT_LOOKUP:
	    printf("\tInvalid page table lookup during scatter/gather.\n" );
	    if (ptr->epic_dcsr & 0xf20)
	      printf("\tAddress lost.\n");
	    else
	      printf("\tBus address to 0x%08lx, PCI cycle 0x%0lx\n",
		     (unsigned long)ptr->epic_pear & 0xffffffff,
		     (unsigned long)(ptr->epic_dcsr >> 18) & 0xf);
	    break;

	  case AVANTI_MEMORY:
	    printf("\tMemory error at %016lx, ",
		   (unsigned long)(ptr->epic_sear & 0xfffffff0) << 2);
	    sysaddr = (ptr->epic_sear & 0xffffffff) >> 21;
	    if (sysaddr >= ((ptr->coma_base0 >> 5) & 0x7ff) &&
		sysaddr < (((ptr->coma_base0 >> 5) & 0x7ff) +
			   (1 << (7 - (ptr->coma_cnfg0 >> 1)))))
	      printf("SIMM bank 0\n");
	    else if (sysaddr >= ((ptr->coma_base1 >> 5) & 0x7ff) &&
		     sysaddr < (((ptr->coma_base1 >> 5) & 0x7ff) +
				(1 << (7 - (ptr->coma_cnfg1 >> 1)))))
	      printf("SIMM bank 1\n");
	    else if (sysaddr >= ((ptr->coma_base2 >> 5) & 0x7ff) &&
		     sysaddr < (((ptr->coma_base2 >> 5) & 0x7ff) +
				(1 << (7 - (ptr->coma_cnfg2 >> 1)))))
	      printf("SIMM bank 2\n");
	    else
	      printf("invalid memory bank?\n");
	    break;

	  case AVANTI_BCACHE_TAG_ADDR_PARITY:
	    printf("\tBcache tag address parity error, caused by ");
	    if (ptr->coma_edsr & 0x20)
	      printf("victim write\n");
	    else if (ptr->coma_edsr & 0x10)
	      printf("DMA. ioCmd<2:0> = %0lx\n",
	        (unsigned long)(ptr->coma_edsr >> 6) & 7);
	    else
	      printf("CPU. cpuCReq<2:0> = %0lx\n",
	        (unsigned long)(ptr->coma_edsr >> 6) & 7);
	    break;

	  case AVANTI_BCACHE_TAG_CTRL_PARITY:
	    printf("\tBcache tag control parity error, caused by ");
	    if (ptr->coma_edsr & 0x20)
	      printf("victim write\n");
	    else if (ptr->coma_edsr & 0x10)
	      printf("DMA. ioCmd<2:0> = %0lx\n",
	        (unsigned long)(ptr->coma_edsr >> 6) & 7);
	    else
	      printf("CPU. cpuCReq<2:0> = %0lx\n",
	        (unsigned long)(ptr->coma_edsr >> 6) & 7);
	    break;

	  case AVANTI_NONEXISTENT_MEMORY:
	    printf("\tNonexistent memory error, caused by ");
	    if (ptr->coma_edsr & 0x20)
	      printf("victim write\n");
	    else if (ptr->coma_edsr & 0x10)
	      printf("DMA. ioCmd<2:0> = %0lx\n",
	        (unsigned long)(ptr->coma_edsr >> 6) & 7);
	    else
	      printf("CPU. cpuCReq<2:0> = %0lx\n",
	        (unsigned long)(ptr->coma_edsr >> 6) & 7);
	    break;

	  case AVANTI_IO_BUS:
	    printf("\tI/O bus error at %08lx during PCI cycle %0lx\n",
		   (unsigned long)ptr->epic_pear & 0xffffffff,
		   (unsigned long)(ptr->epic_dcsr >> 18) & 0xf);
	    break;

	  case AVANTI_BCACHE_TAG_PARITY:
	    printf("\tBcache tag address parity error.\n"
		   "\tcReg_h cycle %0lx, address<7:0> 0x%02lx\n",
		   (unsigned long)(ptr->biu_stat >> 4) & 7,
		   (unsigned long)ptr->biu_addr & 0xff);
	    break;

	  case AVANTI_BCACHE_TAG_CTRL_PARITY2:
	    printf("\tBcache tag control parity error.\n"
		   "\tcReg_h cycle %0lx, address<7:0> 0x%02lx\n",
		   (unsigned long)(ptr->biu_stat >> 4) & 7,
		   (unsigned long)ptr->biu_addr & 0xff);
	    break;

	  }
	} else { /* ALPHA_PROC_MCHECK */
	  printf("\nProcessor fault\n");
	  switch(hdr->mcheck_code) {
	  case AVANTI_HARD_ERROR:
	    printf("\tHard error cycle.\n");
	    break;

	  case AVANTI_CORRECTABLE_ECC:
	    printf("\tCorrectable ECC error.\n"
		   "\tWARNING ECC not implemented on this system!\n"
		   "\tError is incorrect.\n");
	    break;

	  case AVANTI_NONCORRECTABLE_ECC:
	    printf("\tNoncorrectable ECC error.\n"
		   "\tWARNING ECC not implemented on this system!\n"
		   "\tError is incorrect.\n");
	    break;

	  case AVANTI_UNKNOWN_ERROR:
	    printf("\tUnknown error.\n");
	    break;

	  case AVANTI_SOFT_ERROR:
	    printf("\tSoft error cycle.\n");
	    break;

	  case AVANTI_BUGCHECK:
	    printf("\tBugcheck.\n");
	    break;

	  case AVANTI_OS_BUGCHECK:
	    printf("\tOS Bugcheck.\n");
	    break;

	  case AVANTI_DCACHE_FILL_PARITY:
	    printf("\tPrimary Dcache data fill parity error.\n"
		   "\tDcache Quadword %lx, address %08lx\n",
		   (unsigned long)(ptr->biu_stat >> 12) & 0x3,
		   (unsigned long)(ptr->fill_addr >> 8) & 0x7f);
	    break;

	  case AVANTI_ICACHE_FILL_PARITY:
	    printf("\tPrimary Icache data fill parity error.\n"
		   "\tDcache Quadword %lx, address %08lx\n",
		   (unsigned long)(ptr->biu_stat >> 12) & 0x3,
		   (unsigned long)(ptr->fill_addr >> 8) & 0x7f);
	    break;
	  }
	}

	/*
	 * Now that we've printed all sorts of useful information
	 * and have decided that we really can't do any more to
	 * respond to the error, go on to the common code for
	 * final disposition. Usually this means that we die.
	 */
	/*
	 * XXX: HANDLE PCI ERRORS HERE?
	 */
	machine_check(mces, framep, type, logout);
}

static void
dec_2100_a50_mcheck_handler(mces, framep, vector, param)
	unsigned long mces;
	struct trapframe *framep;
	unsigned long vector;
	unsigned long param;
{
	switch (vector) {
	case ALPHA_SYS_MCHECK:
	case ALPHA_PROC_MCHECK:
		dec_2100_a50_mcheck(mces, vector, param, framep);
		break;
	default:
		printf("2100_A50_MCHECK: unknown check vector 0x%lx\n", vector);
		machine_check(mces, framep, vector, param);
		break;
	}
}
#endif	/* !SMALL_KERNEL */


code:
/* $OpenBSD: dec_3000_300.c,v 1.13 2014/05/08 20:46:49 miod Exp $ */
/* $NetBSD: dec_3000_300.c,v 1.30 2000/05/22 20:13:32 thorpej Exp $ */

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

/*
 * Additional Copyright (c) 1997 by Matthew Jacob for NASA/Ames Research Center
 */

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

#include <machine/rpb.h>
#include <machine/autoconf.h>
#include <machine/cpuconf.h>

#include <dev/tc/tcvar.h>
#include <dev/tc/tcdsvar.h>
#include <alpha/tc/tc_3000_300.h>
#ifndef NEW_SCC_DRIVER
#include <alpha/tc/sccvar.h>
#endif

#if 0
#include <machine/z8530var.h>
#include <dev/dec/zskbdvar.h>
#endif

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

#include "wsdisplay.h"

void dec_3000_300_init(void);
static void dec_3000_300_cons_init(void);
static void dec_3000_300_device_register(struct device *, void *);

const struct alpha_variation_table dec_3000_300_variations[] = {
	{ SV_ST_PELICAN, "DEC 3000/300 (\"Pelican\")" },
	{ SV_ST_PELICA, "DEC 3000/300L (\"Pelica\")" },
	{ SV_ST_PELICANPLUS, "DEC 3000/300X (\"Pelican+\")" },
	{ SV_ST_PELICAPLUS, "DEC 3000/300LX (\"Pelica+\")" },
	{ 0, NULL },
};

void
dec_3000_300_init()
{
	u_int64_t variation;

	platform.family = "DEC 3000/300 (\"Pelican\")";

	if ((platform.model = alpha_dsr_sysname()) == NULL) {
		variation = hwrpb->rpb_variation & SV_ST_MASK;
		if ((platform.model = alpha_variation_name(variation,
		    dec_3000_300_variations)) == NULL)
			platform.model = alpha_unknown_sysname();
	}

	platform.iobus = "tcasic";
	platform.cons_init = dec_3000_300_cons_init;
	platform.device_register = dec_3000_300_device_register;
}

static void
dec_3000_300_cons_init()
{
	struct ctb *ctb;

	ctb = (struct ctb *)(((caddr_t)hwrpb) + hwrpb->rpb_ctb_off);

#ifndef NEW_SCC_DRIVER
	switch (ctb->ctb_term_type) {
	case CTB_GRAPHICS:
#if 0
		alpha_donot_kludge_scc = 1;
#endif
		return;
	case CTB_PRINTERPORT:
		return;
	default:
		goto badconsole;
	}
#else
	switch (ctb->ctb_term_type) {
	case CTB_GRAPHICS:
#if NWSDISPLAY > 0
		/* display console ... */
		if (zs_ioasic_lk201_cnattach(0x1a0000000, 0x00180000, 0) == 0 &&
		    tc_3000_300_fb_cnattach(
		     CTB_TURBOSLOT_SLOT(ctb->ctb_turboslot)) == 0) {
			break;
		}
#endif
		printf("consinit: Unable to init console on keyboard and ");
		printf("TURBOchannel slot 0x%lx.\n", ctb->ctb_turboslot);
		printf("Using serial console.\n");
		/* FALLTHROUGH */

	case CTB_PRINTERPORT:
		/* serial console ... */
		/*
		 * XXX This could stand some cleanup...
		 */
		{
			/*
			 * Delay to allow PROM putchars to complete.
			 * FIFO depth * character time.
			 * character time = (1000000 / (defaultrate / 10))
			 */
			DELAY(160000000 / 9600);	/* XXX */

			/*
			 * Console is channel B of the first SCC.
			 * XXX Should use ctb_line_off to get the
			 * XXX line parameters.
			 */
			if (zs_ioasic_cnattach(0x1a0000000, 0x00100000, 1,
			    9600, (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8))
				panic("can't init serial console");
			break;
		}

	default:
		goto badconsole;
	}
#endif
	return;
badconsole:
	printf("ctb->ctb_term_type = 0x%lx\n",
	    (unsigned long)ctb->ctb_term_type);
	printf("ctb->ctb_turboslot = 0x%lx\n",
	    (unsigned long)ctb->ctb_turboslot);

	panic("consinit: unknown console type %lu",
	    (unsigned long)ctb->ctb_term_type);
}

static void
dec_3000_300_device_register(dev, aux)
	struct device *dev;
	void *aux;
{
	static int found, initted, scsiboot, netboot;
	static struct device *scsidev;
	static struct device *tcdsdev;
	struct bootdev_data *b = bootdev_data;
	struct device *parent = dev->dv_parent;
	struct cfdata *cf = dev->dv_cfdata;
	struct cfdriver *cd = cf->cf_driver;

	if (found)
		return;

	if (!initted) {
		scsiboot = (strcmp(b->protocol, "SCSI") == 0);
		netboot = (strcmp(b->protocol, "BOOTP") == 0) ||
		    (strcmp(b->protocol, "MOP") == 0);
#if 0
		printf("scsiboot = %d, netboot = %d\n", scsiboot, netboot);
#endif
		initted = 1;
	}

	/*
	 * for scsi boot, we look for "tcds", make sure it has the
	 * right slot number, then find the "asc" on this tcds that
	 * as the right channel.  then we find the actual scsi
	 * device we came from.  note: no SCSI LUN support (yet).
	 */
	if (scsiboot && (strcmp(cd->cd_name, "tcds") == 0)) {
		struct tc_attach_args *tcargs = aux;

		if (b->slot != tcargs->ta_slot)
			return;

		tcdsdev = dev;
#if 0
		printf("\ntcdsdev = %s\n", dev->dv_xname);
#endif
	}
	if (scsiboot && tcdsdev &&
	    (strcmp(cd->cd_name, "asc") == 0)) {
		struct tcdsdev_attach_args *ta = aux;

		if (parent != (struct device *)tcdsdev)
			return;

		if (ta->tcdsda_chip != b->channel)
			return;

		scsidev = dev;
#if 0
		printf("\nscsidev = %s\n", dev->dv_xname);
#endif
	}

	if (scsiboot && scsidev &&
	    (strcmp(cd->cd_name, "sd") == 0 ||
	     strcmp(cd->cd_name, "st") == 0 ||
	     strcmp(cd->cd_name, "cd") == 0)) {
		struct scsi_attach_args *sa = aux;

		if (parent->dv_parent != scsidev)
			return;

		if (b->unit / 100 != sa->sa_sc_link->target)
			return;

		/* XXX LUN! */

		switch (b->boot_dev_type) {
		case 0:
			if (strcmp(cd->cd_name, "sd") &&
			    strcmp(cd->cd_name, "cd"))
				return;
			break;
		case 1:
			if (strcmp(cd->cd_name, "st"))
				return;
			break;
		default:
			return;
		}

		/* we've found it! */
		booted_device = dev;
#if 0
		printf("\nbooted_device = %s\n", booted_device->dv_xname);
#endif
		found = 1;
	}

	if (netboot) {
                if (b->slot == 5 && strcmp(cd->cd_name, "le") == 0 &&
		    strcmp(parent->dv_cfdata->cf_driver->cd_name, "ioasic")
		     == 0) {
			/*
			 * no need to check ioasic_attach_args, since only
			 * one le on ioasic.
			 */

			booted_device = dev;
#if 0
			printf("\nbooted_device = %s\n", booted_device->dv_xname);
#endif
			found = 1;
			return;
		}

		/*
		 * XXX GENERIC SUPPORT FOR TC NETWORK BOARDS
		 */
        }
}


code:
/* $OpenBSD: dec_3000_500.c,v 1.13 2014/05/08 20:46:49 miod Exp $ */
/* $NetBSD: dec_3000_500.c,v 1.29 2000/05/22 20:13:32 thorpej Exp $ */

/*
 * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
 * All rights reserved.
 *
 * Author: Chris G. Demetriou
 *
 * Permission to use, copy, modify and distribute this software and
 * its documentation is hereby granted, provided that both the copyright
 * notice and this permission notice appear in all copies of the
 * software, derivative works or modified versions, and any portions
 * thereof, and that both notices appear in supporting documentation.
 *
 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
 *
 * Carnegie Mellon requests users of this software to return to
 *
 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
 *  School of Computer Science
 *  Carnegie Mellon University
 *  Pittsburgh PA 15213-3890
 *
 * any improvements or extensions that they make and grant Carnegie the
 * rights to redistribute these changes.
 */
/*
 * Additional Copyright (c) 1997 by Matthew Jacob for NASA/Ames Research Center
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/termios.h>
#include <dev/cons.h>
#include <sys/conf.h>

#include <machine/rpb.h>
#include <machine/autoconf.h>
#include <machine/cpuconf.h>

#include <dev/tc/tcvar.h>
#include <dev/tc/tcdsvar.h>
#include <alpha/tc/tc_3000_500.h>
#ifndef NEW_SCC_DRIVER
#include <alpha/tc/sccvar.h>
#endif

#if 0
#include <machine/z8530var.h>
#include <dev/dec/zskbdvar.h>
#endif

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

#include "wsdisplay.h"

void dec_3000_500_init(void);
static void dec_3000_500_cons_init(void);
static void dec_3000_500_device_register(struct device *, void *);

static const char dec_3000_500_sp[] = "DEC 3000/400 (\"Sandpiper\")";
static const char dec_3000_500_sf[] = "DEC 3000/500 (\"Flamingo\")";

const struct alpha_variation_table dec_3000_500_variations[] = {
	{ SV_ST_SANDPIPER, dec_3000_500_sp },
	{ SV_ST_FLAMINGO, dec_3000_500_sf },
	{ SV_ST_HOTPINK, "DEC 3000/500X (\"Hot Pink\")" },
	{ SV_ST_FLAMINGOPLUS, "DEC 3000/800 (\"Flamingo+\")" },
	{ SV_ST_SANDPLUS, "DEC 3000/600 (\"Sandpiper+\")" },
	{ SV_ST_SANDPIPER45, "DEC 3000/700 (\"Sandpiper45\")" },
	{ SV_ST_FLAMINGO45, "DEC 3000/900 (\"Flamingo45\")" },
	{ 0, NULL },
};

void
dec_3000_500_init()
{
	u_int64_t variation;

	platform.family = "DEC 3000/500 (\"Flamingo\")";

	if ((platform.model = alpha_dsr_sysname()) == NULL) {
		variation = hwrpb->rpb_variation & SV_ST_MASK;
		if (variation == SV_ST_ULTRA) {
			/* These are really the same. */
			variation = SV_ST_FLAMINGOPLUS;
		}
		if ((platform.model = alpha_variation_name(variation,
		    dec_3000_500_variations)) == NULL) {
			/*
			 * This is how things used to be done.
			 */
			if (variation == SV_ST_RESERVED) {
				if (hwrpb->rpb_variation & SV_GRAPHICS)
					platform.model = dec_3000_500_sf;
				else
					platform.model = dec_3000_500_sp;
			} else
				platform.model = alpha_unknown_sysname();
		}
	}

	platform.iobus = "tcasic";
	platform.cons_init = dec_3000_500_cons_init;
	platform.device_register = dec_3000_500_device_register;
}

static void
dec_3000_500_cons_init()
{
	struct ctb *ctb;

	ctb = (struct ctb *)(((caddr_t)hwrpb) + hwrpb->rpb_ctb_off);

#ifndef NEW_SCC_DRIVER
	switch (ctb->ctb_term_type) {
	case CTB_GRAPHICS:
#ifdef notyet
		alpha_donot_kludge_scc = 1;
#endif
		return;
	case CTB_PRINTERPORT:
		return;
	default:
		goto badconsole;
	}
#else

	switch (ctb->ctb_term_type) {
	case CTB_GRAPHICS:
#if NWSDISPLAY > 0
		/* display console ... */
		if (zs_ioasic_lk201_cnattach(0x1e0000000, 0x00180000, 0) == 0 &&
		    tc_3000_500_fb_cnattach(
		     CTB_TURBOSLOT_SLOT(ctb->ctb_turboslot)) == 0) {
			break;
		}
#endif
		printf("consinit: Unable to init console on keyboard and ");
		printf("TURBOchannel slot 0x%lx.\n", ctb->ctb_turboslot);
		printf("Using serial console.\n");
		/* FALLTHROUGH */

	case CTB_PRINTERPORT:
		/* serial console ... */
		/*
		 * XXX This could stand some cleanup...
		 */
		{
			/*
			 * Delay to allow PROM putchars to complete.
			 * FIFO depth * character time,
			 * character time = (1000000 / (defaultrate / 10))
			 */
			DELAY(160000000 / 9600);	/* XXX */

			/*
			 * Console is channel B of the second SCC.
			 * XXX Should use ctb_line_off to get the
			 * XXX line parameters--these are the defaults.
			 */
			if (zs_ioasic_cnattach(0x1e0000000, 0x00180000, 1,
			    9600, (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8))
				panic("can't init serial console");
			break;
		}
	default:
		goto badconsole;
	}
#endif
	return;
badconsole:
	printf("ctb->ctb_term_type = 0x%lx\n",
	    (unsigned long)ctb->ctb_term_type);
	printf("ctb->ctb_turboslot = 0x%lx\n",
	    (unsigned long)ctb->ctb_turboslot);

	panic("consinit: unknown console type %lu",
	    (unsigned long)ctb->ctb_term_type);
}

static void
dec_3000_500_device_register(dev, aux)
	struct device *dev;
	void *aux;
{
	static int found, initted, scsiboot, netboot;
	static struct device *scsidev;
	static struct device *tcdsdev;
	struct bootdev_data *b = bootdev_data;
	struct device *parent = dev->dv_parent;
	struct cfdata *cf = dev->dv_cfdata;
	struct cfdriver *cd = cf->cf_driver;

	if (found)
		return;

	if (!initted) {
		scsiboot = (strcmp(b->protocol, "SCSI") == 0);
		netboot = (strcmp(b->protocol, "BOOTP") == 0) ||
		    (strcmp(b->protocol, "MOP") == 0);
#if 0
		printf("scsiboot = %d, netboot = %d\n", scsiboot, netboot);
#endif
		initted = 1;
	}

	/*
	 * for scsi boot, we look for "tcds", make sure it has the
	 * right slot number, then find the "asc" on this tcds that
	 * as the right channel.  then we find the actual scsi
	 * device we came from.  note: no SCSI LUN support (yet).
	 */
	if (scsiboot && (strcmp(cd->cd_name, "tcds") == 0)) {
		struct tc_attach_args *tcargs = aux;

		if (b->slot != tcargs->ta_slot)
			return;

		tcdsdev = dev;
#if 0
		printf("\ntcdsdev = %s\n", dev->dv_xname);
#endif
	}
	if (scsiboot && tcdsdev &&
	    (strcmp(cd->cd_name, "asc") == 0)) {
		struct tcdsdev_attach_args *ta = aux;

		if (parent != (struct device *)tcdsdev)
			return;

		if (ta->tcdsda_chip != b->channel)
			return;

		scsidev = dev;
#if 0
		printf("\nscsidev = %s\n", dev->dv_xname);
#endif
	}

	if (scsiboot && scsidev &&
	    (strcmp(cd->cd_name, "sd") == 0 ||
	     strcmp(cd->cd_name, "st") == 0 ||
	     strcmp(cd->cd_name, "cd") == 0)) {
		struct scsi_attach_args *sa = aux;

		if (parent->dv_parent != scsidev)
			return;

		if (b->unit / 100 != sa->sa_sc_link->target)
			return;

		/* XXX LUN! */

		switch (b->boot_dev_type) {
		case 0:
			if (strcmp(cd->cd_name, "sd") &&
			    strcmp(cd->cd_name, "cd"))
				return;
			break;
		case 1:
			if (strcmp(cd->cd_name, "st"))
				return;
			break;
		default:
			return;
		}

		/* we've found it! */
		booted_device = dev;
#if 0
		printf("\nbooted_device = %s\n", booted_device->dv_xname);
#endif
		found = 1;
	}

	if (netboot) {
                if (b->slot == 7 && strcmp(cd->cd_name, "le") == 0 &&
		    strcmp(parent->dv_cfdata->cf_driver->cd_name, "ioasic")
		     == 0) {
			/*
			 * no need to check ioasic_attach_args, since only
			 * one le on ioasic.
			 */

			booted_device = dev;
#if 0
			printf("\nbooted_device = %s\n", booted_device->dv_xname);
#endif
			found = 1;
			return;
		}

		/*
		 * XXX GENERIC SUPPORT FOR TC NETWORK BOARDS
		 */
        }
}


code:
/* $OpenBSD: dec_550.c,v 1.14 2014/05/08 20:46:49 miod Exp $ */
/* $NetBSD: dec_550.c,v 1.10 2000/06/20 03:48:53 matt Exp $ */

/*
 * Copyright (c) 1995, 1996, 1997 Carnegie-Mellon University.
 * All rights reserved.
 *
 * Author: Chris G. Demetriou
 *
 * Permission to use, copy, modify and distribute this software and
 * its documentation is hereby granted, provided that both the copyright
 * notice and this permission notice appear in all copies of the
 * software, derivative works or modified versions, and any portions
 * thereof, and that both notices appear in supporting documentation.
 *
 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
 *
 * Carnegie Mellon requests users of this software to return to
 *
 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
 *  School of Computer Science
 *  Carnegie Mellon University
 *  Pittsburgh PA 15213-3890
 *
 * any improvements or extensions that they make and grant Carnegie the
 * rights to redistribute these changes.
 */
/*
 * Additional Copyright (c) 1997 by Matthew Jacob for NASA/Ames Research Center
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/termios.h>
#include <dev/cons.h>
#include <sys/conf.h>

#include <machine/rpb.h>
#include <machine/autoconf.h>
#include <machine/cpuconf.h>
#include <machine/bus.h>

#include <dev/ic/comreg.h>
#include <dev/ic/comvar.h>

#include <dev/isa/isareg.h>
#include <dev/isa/isavar.h>
#include <dev/ic/i8042reg.h>

#include <dev/ic/pckbcvar.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>

#include <alpha/pci/ciareg.h>
#include <alpha/pci/ciavar.h>

#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
#include <dev/ata/atavar.h>

/* Write this to Pyxis General Purpose Output to turn off the power. */
#define	DEC_550_PYXIS_GPO_POWERDOWN	0x00000400

#include "pckbd.h"

#ifndef CONSPEED
#define CONSPEED TTYDEF_SPEED
#endif
static int comcnrate = CONSPEED;

#define	DR_VERBOSE(f) while (0)

void dec_550_init(void);
static void dec_550_cons_init(void);
static void dec_550_device_register(struct device *, void *);
static void dec_550_powerdown(void);

void
dec_550_init()
{

	platform.family = "Digital Personal Workstation";

	if ((platform.model = alpha_dsr_sysname()) == NULL) {
		/* XXX Don't know the system variations, yet. */
		platform.model = alpha_unknown_sysname();
	}

	platform.iobus = "cia";
	platform.cons_init = dec_550_cons_init;
	platform.device_register = dec_550_device_register;
	platform.powerdown = dec_550_powerdown;
}

static void
dec_550_cons_init()
{
	struct ctb *ctb;
	struct cia_config *ccp;
	extern struct cia_config cia_configuration;

	ccp = &cia_configuration;
	cia_init(ccp, 0);

	ctb = (struct ctb *)(((caddr_t)hwrpb) + hwrpb->rpb_ctb_off);

	switch (ctb->ctb_term_type) {
	case CTB_PRINTERPORT:
		/* serial console ... */
		/* XXX */
		{
			/*
			 * Delay to allow PROM putchars to complete.
			 * FIFO depth * character time,
			 * character time = (1000000 / (defaultrate / 10))
			 */
			DELAY(160000000 / comcnrate);

			if(comcnattach(&ccp->cc_iot, 0x3f8, comcnrate,
			    COM_FREQ,
			    (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8))
				panic("can't init serial console");

			break;
		}

	case CTB_GRAPHICS:
#if NPCKBD > 0
		/* display console ... */
		/* XXX */
		(void) pckbc_cnattach(&ccp->cc_iot, IO_KBD, KBCMDP, 0);

		if (CTB_TURBOSLOT_TYPE(ctb->ctb_turboslot) ==
		    CTB_TURBOSLOT_TYPE_ISA)
			isa_display_console(&ccp->cc_iot, &ccp->cc_memt);
		else
			pci_display_console(&ccp->cc_iot, &ccp->cc_memt,
			    &ccp->cc_pc, CTB_TURBOSLOT_BUS(ctb->ctb_turboslot),
			    CTB_TURBOSLOT_SLOT(ctb->ctb_turboslot), 0);
#else
		panic("not configured to use display && keyboard console");
#endif
		break;

	default:
		printf("ctb->ctb_term_type = 0x%lx\n",
		    (unsigned long)ctb->ctb_term_type);
		printf("ctb->ctb_turboslot = 0x%lx\n",
		    (unsigned long)ctb->ctb_turboslot);

		panic("consinit: unknown console type %lu",
		    (unsigned long)ctb->ctb_term_type);
	}
}

static void
dec_550_device_register(dev, aux)
	struct device *dev;
	void *aux;
{
	static int found, initted, diskboot, netboot;
	static struct device *pcidev, *ctrlrdev;
	struct bootdev_data *b = bootdev_data;
	struct device *parent = dev->dv_parent;
	struct cfdata *cf = dev->dv_cfdata;
	struct cfdriver *cd = cf->cf_driver;

	if (found)
		return;

	if (!initted) {
		diskboot = (strncasecmp(b->protocol, "SCSI", 4) == 0) ||
		    (strncasecmp(b->protocol, "IDE", 3) == 0);
		netboot = (strncasecmp(b->protocol, "BOOTP", 5) == 0) ||
		    (strncasecmp(b->protocol, "MOP", 3) == 0);
		DR_VERBOSE(printf("diskboot = %d, netboot = %d\n", diskboot,
		    netboot));
		initted = 1;
	}

	if (pcidev == NULL) {
		if (strcmp(cd->cd_name, "pci"))
			return;
		else {
			struct pcibus_attach_args *pba = aux;

			if ((b->slot / 1000) != pba->pba_bus)
				return;

			pcidev = dev;
			DR_VERBOSE(printf("\npcidev = %s\n", pcidev->dv_xname));
			return;
		}
	}

	if (ctrlrdev == NULL) {
		if (parent != pcidev)
			return;
		else {
			struct pci_attach_args *pa = aux;
			int slot;

			slot = pa->pa_bus * 1000 + pa->pa_function * 100 +
			    pa->pa_device;
			if (b->slot != slot)
				return;

			if (netboot) {
				booted_device = dev;
				DR_VERBOSE(printf("\nbooted_device = %s\n",
				    dev->dv_xname));
				found = 1;
			} else {
				ctrlrdev = dev;
				DR_VERBOSE(printf("\nctrlrdev = %s\n",
				    dev->dv_xname));
			}
			return;
		}
	}

	if (!diskboot)
		return;

	if (!strcmp(cd->cd_name, "sd") || !strcmp(cd->cd_name, "st") ||
	    !strcmp(cd->cd_name, "cd")) {
		struct scsi_attach_args *sa = aux;
		struct scsi_link *periph = sa->sa_sc_link;
		int unit;

		if (parent->dv_parent != ctrlrdev)
			return;

		unit = periph->target * 100 + periph->lun;
		if (b->unit != unit)
			return;

		/* we've found it! */
		booted_device = dev;
		DR_VERBOSE(printf("\nbooted_device = %s\n", dev->dv_xname));
		found = 1;
	}

	/*
	 * Support to boot from IDE drives.
	 */
	if (!strcmp(cd->cd_name, "wd")) {
		struct ata_atapi_attach *aa_link = aux;

		if ((strcmp("pciide", parent->dv_cfdata->cf_driver->cd_name) != 0))
			return;
		if (parent != ctrlrdev)
			return;

		DR_VERBOSE(printf("\nAtapi info: drive: %d, channel %d\n",
		    aa_link->aa_drv_data->drive, aa_link->aa_channel));
		DR_VERBOSE(printf("Bootdev info: unit: %d, channel: %d\n",
		    b->unit, b->channel));
		if (b->unit != aa_link->aa_drv_data->drive ||
		    b->channel != aa_link->aa_channel)
			return;

		/* we've found it! */
		booted_device = dev;
		DR_VERBOSE(printf("booted_device = %s\n", dev->dv_xname));
		found = 1;
	}
}

static void
dec_550_powerdown()
{

	REGVAL(PYXIS_GPO) = DEC_550_PYXIS_GPO_POWERDOWN;
	alpha_mb();
}