code:
/*	$OpenBSD: mips_cpu.h,v 1.1 2012/10/03 11:18:23 miod Exp $	*/

/*-
 * 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.
 *
 *	Copyright (C) 1989 Digital Equipment Corporation.
 *	Permission to use, copy, modify, and distribute this software and
 *	its documentation for any purpose and without fee is hereby granted,
 *	provided that the above copyright notice appears in all copies.
 *	Digital Equipment Corporation makes no representations about the
 *	suitability of this software for any purpose.  It is provided "as is"
 *	without express or implied warranty.
 *
 *	from: @(#)cpu.h	8.4 (Berkeley) 1/4/94
 */

#ifndef _MIPS64_CPUREGS_H_
#define	_MIPS64_CPUREGS_H_

#if defined(_KERNEL) || defined(_STANDALONE)

/*
 * Status register.
 */

#define	SR_COP_USABILITY	0x30000000	/* CP0 and CP1 only */
#define	SR_COP_0_BIT		0x10000000
#define	SR_COP_1_BIT		0x20000000
#define	SR_RP			0x08000000
#define	SR_FR_32		0x04000000
#define	SR_RE			0x02000000
#define	SR_DSD			0x01000000	/* Only on R12000 */
#define	SR_BOOT_EXC_VEC		0x00400000
#define	SR_TLB_SHUTDOWN		0x00200000
#define	SR_SOFT_RESET		0x00100000
#define	SR_DIAG_CH		0x00040000
#define	SR_DIAG_CE		0x00020000
#define	SR_DIAG_DE		0x00010000
#define	SR_KX			0x00000080
#define	SR_SX			0x00000040
#define	SR_UX			0x00000020
#define	SR_ERL			0x00000004
#define	SR_EXL			0x00000002
#define	SR_INT_ENAB		0x00000001

#define	SOFT_INT_MASK_0		0x00000100
#define	SOFT_INT_MASK_1		0x00000200
#define	SR_INT_MASK_0		0x00000400
#define	SR_INT_MASK_1		0x00000800
#define	SR_INT_MASK_2		0x00001000
#define	SR_INT_MASK_3		0x00002000
#define	SR_INT_MASK_4		0x00004000
#define	SR_INT_MASK_5		0x00008000

/* R8000-specific bits */
#define	SR_SERIALIZE_FPU	0x0000010000000000
#define	SR_KPGSZ_SHIFT		36
#define	SR_UPGSZ_SHIFT		32
#define	SR_PGSZ_4K		0
#define	SR_PGSZ_8K		1
#define	SR_PGSZ_16K		2
#define	SR_PGSZ_64K		3
#define	SR_PGSZ_1M		4
#define	SR_PGSZ_4M		5
#define	SR_PGSZ_16M		6
#define	SR_PGSZ_MASK		0x0f

#define	SR_INT_MASK_6		0x00010000
#define	SR_INT_MASK_7		0x00020000
#define	SR_INT_MASK_8		0x00040000

#ifdef CPU_R8000
#define	SR_XX			0x00000040
#define	SR_KSU_MASK		0x00000010
#define	SR_KSU_KERNEL		0x00000000
#define	SR_INT_MASK		0x0007ff00
#else
#define	SR_XX			0x80000000
#define	SR_KSU_MASK		0x00000018
#define	SR_KSU_SUPER		0x00000008
#define	SR_KSU_KERNEL		0x00000000
#define	SR_INT_MASK		0x0000ff00
#endif
/* SR_KSU_USER is in <mips64/cpu.h> for CLKF_USERMODE() */
#ifndef SR_KSU_USER
#define	SR_KSU_USER		0x00000010
#endif

/*
 * Interrupt control register in RM7000. Expansion of interrupts.
 */

#define	IC_INT_MASK		0x00003f00	/* Two msb reserved */
#define	IC_INT_MASK_6		0x00000100
#define	IC_INT_MASK_7		0x00000200
#define	IC_INT_MASK_8		0x00000400
#define	IC_INT_MASK_9		0x00000800
#define	IC_INT_TIMR		0x00001000	/* 12 Timer */
#define	IC_INT_PERF		0x00002000	/* 13 Performance counter */
#define	IC_INT_TE		0x00000080	/* Timer on INT11 */

#define	SOFT_INT_MASK		(SOFT_INT_MASK_0 | SOFT_INT_MASK_1)

/*
 * Cause register.
 */

#ifdef CPU_R8000
#define	CR_BR_DELAY		0x8000000000000000
#define	CR_EXC_CODE		0x000000f8
#define	CR_EXC_CODE_SHIFT	3
#define	CR_COP_ERR		0x10000000
#else
#define	CR_BR_DELAY		0x80000000
#define	CR_EXC_CODE		0x0000007c
#define	CR_EXC_CODE_SHIFT	2
#define	CR_COP_ERR		0x30000000
#endif
#define	CR_COP1_ERR		0x10000000
#define	CR_COP2_ERR		0x20000000
#define	CR_COP3_ERR		0x20000000
#define	CR_INT_SOFT0		0x00000100
#define	CR_INT_SOFT1		0x00000200
#define	CR_INT_0		0x00000400
#define	CR_INT_1		0x00000800
#define	CR_INT_2		0x00001000
#define	CR_INT_3		0x00002000
#define	CR_INT_4		0x00004000
#define	CR_INT_5		0x00008000
/* Following on RM7000 and R8000 */
#define	CR_INT_6		0x00010000
#define	CR_INT_7		0x00020000
#define	CR_INT_8		0x00040000
/* Following on RM7000 */
#define	CR_INT_9		0x00080000
#define	CR_INT_HARD		0x000ffc00
#define	CR_INT_TIMR		0x00100000	/* 12 Timer */
#define	CR_INT_PERF		0x00200000	/* 13 Performance counter */
/* R8000 specific */
#define	CR_FPE			0x01000000
#define	CR_VCE			0x02000000
#define	CR_BERR			0x04000000
#define	CR_NMI			0x08000000

#ifdef CPU_R8000
#define	CR_INT_MASK		0x0407ff00	/* contains CR_BERR */
#else
#define	CR_INT_MASK		0x003fff00
#endif

/*
 * Config register.
 */

#define	CFGR_CCA_MASK		0x00000007
#define	CFGR_CU			0x00000008
#define	CFGR_ICE		0x0000000200000000
#define	CFGR_SMM		0x0000000400000000

/*
 * Location of exception vectors.
 */

#ifdef CPU_R8000
#define	RESET_EXC_VEC		PHYS_TO_XKPHYS(0x1fc00000, CCA_NC)
/* all the others are relative to COP_0_TRAPBASE */
/* #define	UTLB_MISS_EXC_VEC	0x00000000 */
/* #define	KV1TLB_MISS_EXC_VEC	0x00000400 */
/* #define	KV0TLB_MISS_EXC_VEC	0x00000800 */
/* #define	GEN_EXC_VEC		0x00000c00 */
#else
#define	RESET_EXC_VEC		(CKSEG1_BASE + 0x1fc00000)
#define	TLB_MISS_EXC_VEC	(CKSEG1_BASE + 0x00000000)
#define	XTLB_MISS_EXC_VEC	(CKSEG1_BASE + 0x00000080)
#define	CACHE_ERR_EXC_VEC	(CKSEG1_BASE + 0x00000100)
#define	GEN_EXC_VEC		(CKSEG1_BASE + 0x00000180)
#endif

/*
 * Coprocessor 0 registers
 */

/* Common subset */
#define	COP_0_COUNT		$9
#define	COP_0_TLB_HI		$10
#define	COP_0_STATUS_REG	$12
#define	COP_0_CAUSE_REG		$13
#define	COP_0_EXC_PC		$14
#define	COP_0_PRID		$15
#define	COP_0_CONFIG		$16

/* R4000/5000/10000 */
#define	COP_0_TLB_INDEX		$0
#define	COP_0_TLB_RANDOM	$1
#define	COP_0_TLB_LO0		$2
#define	COP_0_TLB_LO1		$3
#define	COP_0_TLB_CONTEXT	$4
#define	COP_0_TLB_PG_MASK	$5
#define	COP_0_TLB_WIRED		$6
#define	COP_0_BAD_VADDR		$8
#define	COP_0_COMPARE		$11
#define	COP_0_LLADDR		$17
#define	COP_0_WATCH_LO		$18
#define	COP_0_WATCH_HI		$19
#define	COP_0_TLB_XCONTEXT	$20
#define	COP_0_ECC		$26
#define	COP_0_CACHE_ERR		$27
#define	COP_0_TAG_LO		$28
#define	COP_0_TAG_HI		$29
#define	COP_0_ERROR_PC		$30

/* R8000 specific */
#define	COP_0_TLB_SET		$0
#define	COP_0_TLB_LO		$2
#define	COP_0_UBASE		$4
#define	COP_0_SHIFTAMT		$5
#define	COP_0_TRAPBASE		$6
#define	COP_0_BAD_PADDR		$7
#define	COP_0_VADDR		$8
#define	COP_0_WORK0		$18
#define	COP_0_WORK1		$19
#define	COP_0_PBASE		$20
#define	COP_0_GBASE		$21
#define	COP_0_TFP_TLB_WIRED	$24
#define	COP_0_DCACHE		$28
#define	COP_0_ICACHE		$29

/* RM7000 specific */
#define	COP_0_WATCH_1		$18
#define	COP_0_WATCH_2		$19
#define	COP_0_WATCH_M		$24
#define	COP_0_PC_COUNT		$25
#define	COP_0_PC_CTRL		$22

#define	COP_0_ICR		$20	/* Use cfc0/ctc0 to access */

/* R10000 specific */
#define	COP_0_TLB_FR_MASK	$21

/* Loongson-2 specific */
#define	COP_0_DIAG		$22

/* Octeon specific */
#define COP_0_TLB_PG_GRAIN	$5, 1
#define COP_0_CVMCTL		$9, 7
#define COP_0_CVMMEMCTL		$11, 7
#define COP_0_EBASE		$15, 1

/*
 * COP_0_COUNT speed divider.
 */
#if defined(CPU_OCTEON) || defined(CPU_R8000)
#define	CP0_CYCLE_DIVIDER	1
#else
#define	CP0_CYCLE_DIVIDER	2
#endif

/*
 * The floating point version and status registers.
 */
#define	FPC_ID			$0
#define	FPC_CSR			$31

#endif	/* _KERNEL || _STANDALONE */

#endif /* !_MIPS64_CPUREGS_H_ */


code:
/*      $OpenBSD: mips_opcode.h,v 1.8 2012/09/29 21:37:03 miod Exp $	*/

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

#ifndef _MIPS64_MIPS_OPCODE_H_
#define	_MIPS64_MIPS_OPCODE_H_

/*
 * Define the instruction formats and opcode values for the
 * MIPS instruction set.
 */

/*
 * Define the instruction formats.
 */
typedef union {
	unsigned word;

#if BYTE_ORDER == BIG_ENDIAN
	struct {
		unsigned op: 6;
		unsigned rs: 5;
		unsigned rt: 5;
		unsigned imm: 16;
	} IType;

	struct {
		unsigned op: 6;
		unsigned target: 26;
	} JType;

	struct {
		unsigned op: 6;
		unsigned rs: 5;
		unsigned rt: 5;
		unsigned rd: 5;
		unsigned shamt: 5;
		unsigned func: 6;
	} RType;

	struct {
		unsigned op: 6;		/* COP1 */
		unsigned : 1;		/* always '1' */
		unsigned fmt: 4;
		unsigned ft: 5;
		unsigned fs: 5;
		unsigned fd: 5;
		unsigned func: 6;
	} FRType;

	struct {
		unsigned op: 6;		/* COP1X */
		unsigned fr: 5;
		unsigned ft: 5;
		unsigned fs: 5;
		unsigned fd: 5;
		unsigned op4: 3;
		unsigned fmt3: 3;
	} FQType;
#endif
#if BYTE_ORDER == LITTLE_ENDIAN
	struct {
		unsigned imm: 16;
		unsigned rt: 5;
		unsigned rs: 5;
		unsigned op: 6;
	} IType;

	struct {
		unsigned target: 26;
		unsigned op: 6;
	} JType;

	struct {
		unsigned func: 6;
		unsigned shamt: 5;
		unsigned rd: 5;
		unsigned rt: 5;
		unsigned rs: 5;
		unsigned op: 6;
	} RType;

	struct {
		unsigned func: 6;
		unsigned fd: 5;
		unsigned fs: 5;
		unsigned ft: 5;
		unsigned fmt: 4;
		unsigned : 1;		/* always '1' */
		unsigned op: 6;		/* COP1 */
	} FRType;

	struct {
		unsigned fmt3: 3;
		unsigned op4: 3;
		unsigned fd: 5;
		unsigned fs: 5;
		unsigned ft: 5;
		unsigned fr: 5;
		unsigned op: 6;		/* COP1X */
	} FQType;
#endif
} InstFmt;

/*
 * Values for the 'op' field.
 */
#define	OP_SPECIAL	000
#define	OP_BCOND	001
#define	OP_J		002
#define	OP_JAL		003
#define	OP_BEQ		004
#define	OP_BNE		005
#define	OP_BLEZ		006
#define	OP_BGTZ		007

#define	OP_ADDI		010
#define	OP_ADDIU	011
#define	OP_SLTI		012
#define	OP_SLTIU	013
#define	OP_ANDI		014
#define	OP_ORI		015
#define	OP_XORI		016
#define	OP_LUI		017

#define	OP_COP0		020
#define	OP_COP1		021
#define	OP_COP2		022
#define	OP_COP3		023
#define	OP_COP1X	023
#define	OP_BEQL		024
#define	OP_BNEL		025
#define	OP_BLEZL	026
#define	OP_BGTZL	027

#define	OP_DADDI	030
#define	OP_DADDIU	031
#define	OP_LDL		032
#define	OP_LDR		033

#define	OP_LB		040
#define	OP_LH		041
#define	OP_LWL		042
#define	OP_LW		043
#define	OP_LBU		044
#define	OP_LHU		045
#define	OP_LWR		046
#define	OP_LWU		047

#define	OP_SB		050
#define	OP_SH		051
#define	OP_SWL		052
#define	OP_SW		053
#define	OP_SDL		054
#define	OP_SDR		055
#define	OP_SWR		056
#define	OP_CACHE	057

#define	OP_LL		060
#define	OP_LWC1		061
#define	OP_LWC2		062
#define	OP_LWC3		063
#define	OP_PREF		063
#define	OP_LLD		064
#define	OP_LDC1		065
#define	OP_LDC2		066
#define	OP_LD		067

#define	OP_SC		070
#define	OP_SWC1		071
#define	OP_SWC2		072
#define	OP_SWC3		073
#define	OP_SCD		074
#define	OP_SDC1		075
#define	OP_SDC2		076
#define	OP_SD		077

/*
 * Values for the 'func' field when 'op' == OP_SPECIAL.
 */
#define	OP_SLL		000
#define	OP_MOVCI	001
#define	OP_SRL		002
#define	OP_SRA		003
#define	OP_SLLV		004
#define	OP_SRLV		006
#define	OP_SRAV		007

#define	OP_JR		010
#define	OP_JALR		011
#define	OP_MOVZ		012
#define	OP_MOVN		013
#define	OP_SYSCALL	014
#define	OP_BREAK	015
#define	OP_SYNC		017

#define	OP_MFHI		020
#define	OP_MTHI		021
#define	OP_MFLO		022
#define	OP_MTLO		023
#define	OP_DSLLV	024
#define	OP_DSRLV	026
#define	OP_DSRAV	027

#define	OP_MULT		030
#define	OP_MULTU	031
#define	OP_DIV		032
#define	OP_DIVU		033
#define	OP_DMULT	034
#define	OP_DMULTU	035
#define	OP_DDIV		036
#define	OP_DDIVU	037

#define	OP_ADD		040
#define	OP_ADDU		041
#define	OP_SUB		042
#define	OP_SUBU		043
#define	OP_AND		044
#define	OP_OR		045
#define	OP_XOR		046
#define	OP_NOR		047

#define	OP_SLT		052
#define	OP_SLTU		053
#define	OP_DADD		054
#define	OP_DADDU	055
#define	OP_DSUB		056
#define	OP_DSUBU	057

#define	OP_TGE		060
#define	OP_TGEU		061
#define	OP_TLT		062
#define	OP_TLTU		063
#define	OP_TEQ		064
#define	OP_TNE		066

#define	OP_DSLL		070
#define	OP_DSRL		072
#define	OP_DSRA		073
#define	OP_DSLL32	074
#define	OP_DSRL32	076
#define	OP_DSRA32	077

/*
 * Values for the 'rt' field when 'op' == OP_BCOND.
 */
#define	OP_BLTZ		000
#define	OP_BGEZ		001
#define	OP_BLTZL	002
#define	OP_BGEZL	003

#define	OP_TGEI		010
#define	OP_TGEIU	011
#define	OP_TLTI		012
#define	OP_TLTIU	013
#define	OP_TEQI		014
#define	OP_TNEI		016

#define	OP_BLTZAL	020
#define	OP_BGEZAL	021
#define	OP_BLTZALL	022
#define	OP_BGEZALL	023

/*
 * Values for the 'rs' field when 'op' == OP_COPz.
 */
#define	OP_MF		000
#define	OP_DMF		001
#define	OP_CF		002
#define	OP_MFH		003
#define	OP_MT		004
#define	OP_DMT		005
#define	OP_CT		006
#define	OP_MTH		007
#define	OP_BC		010
#define	OP_C0MISC	020	/* cop0 only */
#define	OP_TFP_C0MISC	030	/* cop0 only on R8000 */

/*
 * Values for the 'rt' field when 'op' == OP_COPz.
 */
#define	COPz_BC_TF_MASK		0x01
#define	COPz_BC_TRUE		0x01
#define	COPz_BC_FALSE		0x00
#define	COPz_BCL_TF_MASK	0x02
#define	COPz_BCL_TRUE		0x02
#define	COPz_BCL_FALSE		0x00
#define	COPz_BC_CC_MASK		0x1c
#define	COPz_BC_CC_SHIFT	2

/*
 * Values for the 'func' field when 'op' == OP_COP1X.
 */
#define	OP_LWXC1	000
#define	OP_LDXC1	001
#define	OP_SWXC1	010
#define	OP_SDXC1	011
#define	OP_PREFX	017

/*
 * Values for the 'op4' field when 'op' == OP_COP1X.
 */
#define	OP_MADD		04
#define	OP_MSUB		05
#define	OP_NMADD	06
#define	OP_NMSUB	07

#endif /* !_MIPS64_MIPS_OPCODE_H_ */

license: unknown


code:
/*	$OpenBSD: mutex.h,v 1.1 2015/07/08 13:37:31 dlg Exp $	*/

/*
 * Copyright (c) 2004 Artur Grabowski <art@openbsd.org>
 * 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. 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 ``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_MUTEX_H_
#define _MACHINE_MUTEX_H_

struct mutex {
	void *mtx_owner;
	int mtx_wantipl;
	int mtx_oldipl;
};

/*
 * To prevent lock ordering problems with the kernel lock, we need to
 * make sure we block all interrupts that can grab the kernel lock.
 * The simplest way to achieve this is to make sure mutexes always
 * raise the interrupt priority level to the highest level that has
 * interrupts that grab the kernel lock.
 */
#ifdef MULTIPROCESSOR
#define __MUTEX_IPL(ipl) \
    (((ipl) > IPL_NONE && (ipl) < IPL_MPFLOOR) ? IPL_MPFLOOR : (ipl))
#else
#define __MUTEX_IPL(ipl) (ipl)
#endif

#define MUTEX_INITIALIZER(ipl) { NULL, __MUTEX_IPL((ipl)), IPL_NONE }

void __mtx_init(struct mutex *, int);
#define mtx_init(mtx, ipl) __mtx_init((mtx), __MUTEX_IPL((ipl)))

#ifdef DIAGNOSTIC
#define MUTEX_ASSERT_LOCKED(mtx) do {					\
	if ((mtx)->mtx_owner != curcpu())				\
		panic("mutex %p not held in %s", (mtx), __func__);	\
} while (0)

#define MUTEX_ASSERT_UNLOCKED(mtx) do {					\
	if ((mtx)->mtx_owner == curcpu())				\
		panic("mutex %p held in %s", (mtx), __func__);		\
} while (0)
#else
#define MUTEX_ASSERT_LOCKED(mtx) do { } while (0)
#define MUTEX_ASSERT_UNLOCKED(mtx) do { } while (0)
#endif

#define MUTEX_OLDIPL(mtx)	(mtx)->mtx_oldipl

#endif


code:
/*      $OpenBSD: param.h,v 1.33 2013/03/26 05:04:10 deraadt Exp $ */

/*
 * Copyright (c) 1988 University of Utah.
 * Copyright (c) 1992, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * the Systems Programming Group of the University of Utah Computer
 * Science Department and Ralph Campbell.
 *
 * 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.
 */

#ifndef	_MIPS64_PARAM_H_
#define	_MIPS64_PARAM_H_

#ifdef _KERNEL
#include <machine/cpu.h>
#endif

#define	PAGE_SIZE	(1 << PAGE_SHIFT)
#define	PAGE_MASK	(PAGE_SIZE - 1)

#define	KERNBASE	0xffffffff80000000L	/* start of kernel virtual */

#ifdef _KERNEL

#define	NBPG		PAGE_SIZE
#define	PGSHIFT		PAGE_SHIFT
#define	PGOFSET		PAGE_MASK

#define	USPACE		16384
#define	UPAGES		(USPACE >> PAGE_SHIFT)
#if PAGE_SHIFT > 12
#define	USPACE_ALIGN	0
#else
#define	USPACE_ALIGN	(2 * PAGE_SIZE)	/* align to an even TLB boundary */
#endif

#define	NMBCLUSTERS	4096		/* map size, max cluster allocation */

#ifndef MSGBUFSIZE
#if PAGE_SHIFT > 12
#define	MSGBUFSIZE	PAGE_SIZE
#else
#define	MSGBUFSIZE	8192
#endif
#endif

/*
 * Maximum size of the kernel malloc arena in PAGE_SIZE-sized
 * logical pages.
 */
#define	NKMEMPAGES_MAX_DEFAULT  ((128 * 1024 * 1024) >> PAGE_SHIFT)

#ifndef _LOCORE
#define	DELAY(n)	delay(n)
void delay(int);
#endif

#endif /* _KERNEL */

#endif /* _MIPS64_PARAM_H_ */


code:
/*      $OpenBSD: pcb.h,v 1.7 2015/05/05 02:13:47 guenther Exp $	*/

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

#ifndef _MIPS64_PCB_H_
#define _MIPS64_PCB_H_

#include <machine/frame.h>

/*
 * MIPS process control block. This is first in the U-area.
 */
struct pcb {
	struct trap_frame pcb_regs;	/* saved CPU and registers */
	struct {
		register_t val[13];
	} pcb_context;			/* kernel context for resume */
	int	pcb_onfault;		/* for copyin/copyout faults */
	void	*pcb_segtab;		/* copy of pmap pm_segtab */
	uint	pcb_nwired;		/* number of extra wired TLB entries */
	vaddr_t	pcb_wiredva;		/* va of above */
	vaddr_t	pcb_wiredpc;		/* last tracked pc value within above */
};

#endif	/* !_MIPS64_PCB_H_ */


code:
/*      $OpenBSD: pmap.h,v 1.38 2015/02/15 21:34:33 miod Exp $ */

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

#ifndef	_MIPS64_PMAP_H_
#define	_MIPS64_PMAP_H_

#ifdef	_KERNEL

#include <machine/pte.h>

/*
 * The user address space is currently limited to 2Gb (0x0 - 0x80000000).
 *
 * The user address space is mapped using a two level structure where
 * the virtual addresses bits are split in three groups:
 *   segment:page:offset
 * where:
 * - offset are the in-page offsets (PAGE_SHIFT bits)
 * - page are the second level page table index
 *   (PMAP_L2SHIFT - Log2(pt_entry_t) bits)
 * - segment are the first level page table (segment) index
 *   (PMAP_L2SHIFT - Log2(void *) bits)
 *
 * This scheme allows Segment and page tables have the same size
 * (1 << PMAP_L2SHIFT bytes, regardless of the pt_entry_t size) to be able to
 * share the same allocator.
 *
 * Note: The kernel doesn't use the same data structures as user programs.
 * All the PTE entries are stored in a single array in Sysmap which is
 * dynamically allocated at boot time.
 */

/*
 * Size of second level page structs (page tables, and segment table) used
 * by this pmap.
 */

#ifdef MIPS_PTE64
#define	PMAP_L2SHIFT		14
#else
#define	PMAP_L2SHIFT		12
#endif
#define	PMAP_L2SIZE		(1UL << PMAP_L2SHIFT)

#define	NPTEPG			(PMAP_L2SIZE / sizeof(pt_entry_t))

/*
 * Segment sizes
 */

#ifdef MIPS_PTE64
#define	SEGSHIFT		(PAGE_SHIFT + PMAP_L2SHIFT - 3)
#else
#define	SEGSHIFT		(PAGE_SHIFT + PMAP_L2SHIFT - 2)
#endif
#define	NBSEG			(1UL << SEGSHIFT)
#define	SEGOFSET		(NBSEG - 1)

#define	mips_trunc_seg(x)	((vaddr_t)(x) & ~SEGOFSET)
#define	mips_round_seg(x)	(((vaddr_t)(x) + SEGOFSET) & ~SEGOFSET)
#define	pmap_segmap(m, v)	((m)->pm_segtab->seg_tab[((v) >> SEGSHIFT)])

/* number of segments entries */
#define	PMAP_SEGTABSIZE		(PMAP_L2SIZE / sizeof(void *))

struct segtab {
	pt_entry_t	*seg_tab[PMAP_SEGTABSIZE];
};

struct pmap_asid_info {
	u_int			pma_asid;	/* address space tag */
	u_int			pma_asidgen;	/* TLB PID generation number */
};

/*
 * Machine dependent pmap structure.
 */
typedef struct pmap {
	int			pm_count;	/* pmap reference count */
	struct pmap_statistics	pm_stats;	/* pmap statistics */
	struct segtab		*pm_segtab;	/* pointers to pages of PTEs */
	struct pmap_asid_info	pm_asid[1];	/* ASID information */
} *pmap_t;

/*
 * Compute the sizeof of a pmap structure.  Subtract one because one
 * ASID info structure is already included in the pmap structure itself.
 */
#define	PMAP_SIZEOF(x)							\
	(ALIGN(sizeof(struct pmap) +					\
	       (sizeof(struct pmap_asid_info) * ((x) - 1))))

/* machine-dependent pg_flags */
#define	PGF_UNCACHED	PG_PMAP0	/* Page is explicitely uncached */
#define	PGF_CACHED	PG_PMAP1	/* Page is currently cached */
#define	PGF_ATTR_MOD	PG_PMAP2
#define	PGF_ATTR_REF	PG_PMAP3
#define	PGF_EOP_CHECKED	PG_PMAP4
#define	PGF_EOP_VULN	PG_PMAP5
#define	PGF_PRESERVE	(PGF_ATTR_MOD | PGF_ATTR_REF)

#define	PMAP_NOCACHE	PMAP_MD0

extern	struct pmap *const kernel_pmap_ptr;

#define	pmap_resident_count(pmap)       ((pmap)->pm_stats.resident_count)
#define	pmap_wired_count(pmap)		((pmap)->pm_stats.wired_count)
#define	pmap_kernel()			(kernel_pmap_ptr)

#define	PMAP_STEAL_MEMORY		/* Enable 'stealing' during boot */

#define	PMAP_PREFER(pa, va)		pmap_prefer(pa, va)

extern vaddr_t pmap_prefer_mask;
/* pmap prefer alignment */
#define	PMAP_PREFER_ALIGN()						\
	(pmap_prefer_mask ? pmap_prefer_mask + 1 : 0)
/* pmap prefer offset in alignment */
#define	PMAP_PREFER_OFFSET(of)		((of) & pmap_prefer_mask)

void	pmap_bootstrap(void);
int	pmap_is_page_ro( pmap_t, vaddr_t, pt_entry_t);
void	pmap_kenter_cache(vaddr_t va, paddr_t pa, vm_prot_t prot, int cache);
vaddr_t	pmap_prefer(vaddr_t, vaddr_t);
void	pmap_set_modify(vm_page_t);
void	pmap_page_cache(vm_page_t, u_int);

#define	pmap_collect(x)			do { /* nothing */ } while (0)
#define	pmap_unuse_final(p)		do { /* nothing yet */ } while (0)
#define	pmap_remove_holes(vm)		do { /* nothing */ } while (0)

void	pmap_update_user_page(pmap_t, vaddr_t, pt_entry_t);
#ifdef MULTIPROCESSOR
void	pmap_update_kernel_page(vaddr_t, pt_entry_t);
#else
#define	pmap_update_kernel_page(va, entry)	tlb_update(va, entry)
#endif

/*
 * Most R5000 processors (and related families) have a silicon bug preventing
 * the ll/sc (and lld/scd) instructions from honouring the caching mode
 * when accessing XKPHYS addresses.
 *
 * Since pool memory is allocated with pmap_map_direct() if __HAVE_PMAP_DIRECT,
 * and many structures containing fields which will be used with
 * <machine/atomic.h> routines are allocated from pools, __HAVE_PMAP_DIRECT can
 * not be defined on systems which may use flawed processors.
 */
#if !defined(CPU_R5000) && !defined(CPU_RM7000)
#define	__HAVE_PMAP_DIRECT
vaddr_t	pmap_map_direct(vm_page_t);
vm_page_t pmap_unmap_direct(vaddr_t);
#endif

/*
 * MD flags to pmap_enter:
 */

#define	PMAP_PA_MASK	~((paddr_t)PAGE_MASK)

/* Kernel virtual address to page table entry */
#define	kvtopte(va) \
	(Sysmap + (((vaddr_t)(va) - VM_MIN_KERNEL_ADDRESS) >> PAGE_SHIFT))
/* User virtual address to pte page entry */
#define	uvtopte(va)	(((va) >> PAGE_SHIFT) & (NPTEPG -1))

extern	pt_entry_t *Sysmap;		/* kernel pte table */
extern	u_int Sysmapsize;		/* number of pte's in Sysmap */

#endif	/* _KERNEL */

#if !defined(_LOCORE)
typedef struct pv_entry {
	struct pv_entry	*pv_next;	/* next pv_entry */
	struct pmap	*pv_pmap;	/* pmap where mapping lies */
	vaddr_t		pv_va;		/* virtual address for mapping */
} *pv_entry_t;

struct vm_page_md {
	struct pv_entry pv_ent;		/* pv list of this seg */
};

#define	VM_MDPAGE_INIT(pg) \
	do { \
		(pg)->mdpage.pv_ent.pv_next = NULL; \
		(pg)->mdpage.pv_ent.pv_pmap = NULL; \
		(pg)->mdpage.pv_ent.pv_va = 0; \
	} while (0)

#endif	/* !_LOCORE */

#endif	/* !_MIPS64_PMAP_H_ */


code:
/*	$OpenBSD: proc.h,v 1.8 2011/03/23 16:54:36 pirofti Exp $	*/

/*
 * 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.
 *
 * 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.
 *
 *	@(#)proc.h	8.1 (Berkeley) 6/10/93
 */

#ifndef	_MIPS64_PROC_H_
#define	_MIPS64_PROC_H_

/*
 * Machine-dependent part of the proc structure.
 */
struct mdproc {
	struct trap_frame *md_regs;	/* registers on current frame */
	volatile int md_astpending;	/* AST pending for this process */
	int	md_flags;		/* machine-dependent flags */
	vaddr_t	md_uarea;		/* allocated uarea virtual addr */

	/* ptrace fields */
	vaddr_t	md_ss_addr;		/* single step address */
	uint32_t md_ss_instr;		/* saved single step instruction */

	/* fpu emulation fields */
	vaddr_t	md_fppgva;		/* vaddr of the branch emulation page */
	vaddr_t	md_fpbranchva;		/* vaddr of fp branch destination */
	vaddr_t	md_fpslotva;		/* initial vaddr of delay slot */

/* The following is RM7000 dependent, but kept in for compatibility */
	int	md_pc_ctrl;		/* performance counter control */
	int	md_pc_count;		/* performance counter */
	int	md_pc_spill;		/* performance counter spill */
	quad_t	md_watch_1;
	quad_t	md_watch_2;
	int	md_watch_m;
};

/*
 * Values for md_flags.
 * MDP_FPUSED has two meanings: if the floating point hardware (coprocessor
 * #1) is available, it means it has been used; if there is no floating
 * point hardware, it means the process is currently running a duplicated
 * delay slot, created by the branch emulation logic.
 */
#define	MDP_FPUSED	0x00000001	/* floating point coprocessor used */
#define	MDP_PERF	0x00010000	/* Performance counter used */
#define	MDP_WATCH1	0x00020000	/* Watch register 1 used */
#define	MDP_WATCH2	0x00040000	/* Watch register 1 used */
#define	MDP_FORKSAVE	0x0000ffff	/* Flags to save when forking */

#endif	/* !_MIPS64_PROC_H_ */


code:
/*      $OpenBSD: profile.h,v 1.4 2011/03/23 16:54:36 pirofti Exp $	*/

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

#define	_MCOUNT_DECL static void ___mcount

/*XXX The cprestore instruction is a "dummy" to shut up as(1). */

#define	MCOUNT \
	__asm(".globl _mcount;"		\
	".type _mcount,@function;"	\
	"_mcount:;"			\
	".set noreorder;"		\
	".set noat;"			\
	".cpload $25;"			\
	".cprestore 4;"			\
	"sd $4,16($29);"		\
	"sd $5,24($29);"		\
	"sd $6,32($29);"		\
	"sd $7,40($29);"		\
	"sd $1,0($29);"			\
	"sd $31,8($29);"		\
	"move $5,$31;"			\
	"jal ___mcount;"		\
	"move $4,$1;"			\
	"ld $4,16($29);"		\
	"ld $5,24($29);"		\
	"ld $6,32($29);"		\
	"ld $7,40($29);"		\
	"ld $31,8($29);"		\
	"ld $1,0($29);"			\
	"daddu $29,$29,16;"		\
	"j $31;"			\
	"move $31,$1;"			\
	".set reorder;"			\
	".set at");

#ifdef _KERNEL
/*
 * The following two macros do splhigh and splx respectively.
 * They have to be defined this way because these are real
 * functions on the MIPS, and we do not want to invoke mcount
 * recursively.
 */
#define	MCOUNT_ENTER	s = _splhigh()

#define	MCOUNT_EXIT	_splx(s)
#endif /* _KERNEL */

#endif /* !_MIPS64_PROFILE_H_ */


code:
/*	$OpenBSD: pte.h,v 1.18 2014/03/22 00:00:38 miod Exp $	*/

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

/*
 * R4000 and R8000 hardware page table entries
 */

#ifndef _LOCORE

/*
 * Structure defining a TLB entry data set.
 */
struct tlb_entry {
	u_int64_t	tlb_mask;
	u_int64_t	tlb_hi;
	u_int64_t	tlb_lo0;
	u_int64_t	tlb_lo1;
};

u_int	tlb_get_pid(void);
void	tlb_read(unsigned int, struct tlb_entry *);

#ifdef MIPS_PTE64
typedef u_int64_t pt_entry_t;
#else
typedef u_int32_t pt_entry_t;
#endif

#endif /* _LOCORE */

/* entryhi values */

#ifndef CPU_R8000
#define	PG_HVPN		(-2 * PAGE_SIZE)	/* Hardware page number mask */
#define	PG_ODDPG	PAGE_SIZE
#endif	/* !R8000 */

/* Address space ID */
#ifdef CPU_R8000
#define	PG_ASID_MASK		0x0000000000000ff0
#define	PG_ASID_SHIFT		4
#define	ICACHE_ASID_SHIFT	40
#define	MIN_USER_ASID		0
#else
#define	PG_ASID_MASK		0x00000000000000ff
#define	PG_ASID_SHIFT		0
#define	MIN_USER_ASID		1
#endif
#define	PG_ASID_COUNT		256	/* Number of available ASID */

/* entrylo values */

#ifdef CPU_R8000
#define	PG_FRAME	0xfffff000
#define	PG_SHIFT	0
#else
#ifdef MIPS_PTE64
#define	PG_FRAMEBITS	61
#else
#define	PG_FRAMEBITS	29
#endif
#define	PG_FRAME	((1ULL << PG_FRAMEBITS) - (1ULL << PG_SHIFT))
#define	PG_SHIFT	6
#endif

/* software pte bits - not put in entrylo */
#ifdef CPU_R8000
#define	PG_WIRED	0x00000010
#define	PG_RO		0x00000020
#else
#define	PG_WIRED	(1ULL << (PG_FRAMEBITS + 2))
#define	PG_RO		(1ULL << (PG_FRAMEBITS + 1))
#define	PG_SP		(1ULL << (PG_FRAMEBITS + 0))	/* ``special'' bit */
#endif

#define	PG_NV		0x00000000
#ifdef CPU_R8000
#define	PG_G		0x00000000	/* no such concept for R8000 */
#define	PG_V		0x00000080
#define	PG_M		0x00000100
#define	PG_CCA_SHIFT	9
#else
#define	PG_G		0x00000001
#define	PG_V		0x00000002
#define	PG_M		0x00000004
#define	PG_CCA_SHIFT	3
#endif
#define	PG_NV		0x00000000

#define	PG_UNCACHED	(CCA_NC << PG_CCA_SHIFT)
#define	PG_CACHED_NC	(CCA_NONCOHERENT << PG_CCA_SHIFT)
#define	PG_CACHED_CE	(CCA_COHERENT_EXCL << PG_CCA_SHIFT)
#define	PG_CACHED_CEW	(CCA_COHERENT_EXCLWRITE << PG_CCA_SHIFT)
#define	PG_CACHED	(CCA_CACHED << PG_CCA_SHIFT)
#define	PG_CACHEMODE	(7 << PG_CCA_SHIFT)

#define	PG_ATTR		(PG_CACHEMODE | PG_M | PG_V | PG_G)
#define	PG_ROPAGE	(PG_V | PG_RO | PG_CACHED) /* Write protected */
#define	PG_RWPAGE	(PG_V | PG_M | PG_CACHED)  /* Not w-prot not clean */
#define	PG_CWPAGE	(PG_V | PG_CACHED)	   /* Not w-prot but clean */
#define	PG_IOPAGE	(PG_G | PG_V | PG_M | PG_UNCACHED)

#define	pfn_to_pad(pa)	((((paddr_t)pa) & PG_FRAME) << PG_SHIFT)
#define	vad_to_pfn(va)	(((va) >> PG_SHIFT) & PG_FRAME)

#ifndef CPU_R8000
#define	PG_SIZE_4K	0x00000000
#define	PG_SIZE_16K	0x00006000
#define	PG_SIZE_64K	0x0001e000
#define	PG_SIZE_256K	0x0007e000
#define	PG_SIZE_1M	0x001fe000
#define	PG_SIZE_4M	0x007fe000
#define	PG_SIZE_16M	0x01ffe000
#if PAGE_SHIFT == 12
#define	TLB_PAGE_MASK	PG_SIZE_4K
#elif PAGE_SHIFT == 14
#define	TLB_PAGE_MASK	PG_SIZE_16K
#endif
#endif	/* !R8000 */


code:
/*      $OpenBSD: ptrace.h,v 1.3 2011/03/23 16:54:36 pirofti Exp $	*/

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

#ifndef _MIPS64_PTRACE_H_
#define _MIPS64_PTRACE_H_

/*
 * Machine dependent trace commands.
 *
 */

#define	PT_GETREGS	 (PT_FIRSTMACH+0)
#define	PT_SETREGS	 (PT_FIRSTMACH+1)
#define	PT_STEP		 (PT_FIRSTMACH+2)

#endif /* !_MIPS64_PTRACE_H_ */


code:
/*	$OpenBSD: reg.h,v 1.3 2011/03/23 16:54:36 pirofti Exp $	*/

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

#ifndef _MIPS64_REG_H_
#define _MIPS64_REG_H_
/*
 * Location of the users' stored
 * registers relative to ZERO.
 * Usage is p->p_regs[XX].
 *
 * must be visible to assembly code.
 */
#include <machine/regnum.h>

/*
 * Register set accessible via /proc/$pid/reg
 */
struct reg {
        register_t     r_regs[NREGS];	/* numbered as above */
};
#endif /* !_MIPS64_REG_H_ */


code:
/*	$OpenBSD: regdef.h,v 1.5 2014/03/10 21:10:36 miod Exp $	*/

/*
 * 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. This file is derived from the MIPS RISC
 * Architecture book by Gerry Kane.
 *
 * 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.
 *
 *	@(#)regdef.h	8.1 (Berkeley) 6/10/93
 */
#ifndef _MIPS64_REGDEF_H_
#define _MIPS64_REGDEF_H_

#define zero	$0	/* always zero */
#define AT	$at	/* assembler temp */
#define v0	$2	/* return value */
#define v1	$3
#define a0	$4	/* argument registers */
#define a1	$5
#define a2	$6
#define a3	$7
#define a4	$8
#define a5	$9
#define a6	$10
#define a7	$11
#define ta0	$8	/* alias */
#define ta1	$9
#define ta2	$10
#define ta3	$11
#define t0	$12	/* temp registers (not saved across subroutine calls) */
#define t1	$13
#define t2	$14
#define t3	$15
#define s0	$16	/* saved across subroutine calls (callee saved) */
#define s1	$17
#define s2	$18
#define s3	$19
#define s4	$20
#define s5	$21
#define s6	$22
#define s7	$23
#define t8	$24	/* two more temp registers */
#define t9	$25
#define k0	$26	/* kernel temporary */
#define k1	$27
#define gp	$28	/* global pointer */
#define sp	$29	/* stack pointer */
#define s8	$30	/* one more callee saved */
#define ra	$31	/* return address */

#endif /* !_MIPS64_REGDEF_H_ */


code:
/*	$OpenBSD: regnum.h,v 1.4 2014/07/09 12:58:08 miod Exp $ */

/*
 * Copyright (c) 2001-2002 Opsycon AB  (www.opsycon.se / www.opsycon.com)
 *
 * 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.
 *
 */

#ifndef _MIPS64_REGNUM_H_
#define _MIPS64_REGNUM_H_

/*
 * Location of the saved registers relative to ZERO.
 * Usage is p->p_regs[XX].
 */
#define ZERO	0
#define AST	1
#define V0	2
#define V1	3
#define A0	4
#define A1	5
#define A2	6
#define A3	7
#define A4	8
#define A5	9
#define A6	10
#define A7	11
#define T0	12
#define T1	13
#define T2	14
#define T3	15
#define S0	16
#define S1	17
#define S2	18
#define S3	19
#define S4	20
#define S5	21
#define S6	22
#define S7	23
#define T8	24
#define T9	25
#define K0	26
#define K1	27
#define GP	28
#define SP	29
#define S8	30
#define RA	31
#define	SR	32
#define	PS	SR	/* alias for SR */
#define MULLO	33
#define MULHI	34
#define BADVADDR 35
#define CAUSE	36
#define	PC	37
#define	IC	38
#define	CPL	39

#define	NUMSAVEREGS 40		/* Number of registers saved in trap */

#define FPBASE	NUMSAVEREGS
#define F0	(FPBASE+0)
#define F1	(FPBASE+1)
#define F2	(FPBASE+2)
#define F3	(FPBASE+3)
#define F4	(FPBASE+4)
#define F5	(FPBASE+5)
#define F6	(FPBASE+6)
#define F7	(FPBASE+7)
#define F8	(FPBASE+8)
#define F9	(FPBASE+9)
#define F10	(FPBASE+10)
#define F11	(FPBASE+11)
#define F12	(FPBASE+12)
#define F13	(FPBASE+13)
#define F14	(FPBASE+14)
#define F15	(FPBASE+15)
#define F16	(FPBASE+16)
#define F17	(FPBASE+17)
#define F18	(FPBASE+18)
#define F19	(FPBASE+19)
#define F20	(FPBASE+20)
#define F21	(FPBASE+21)
#define F22	(FPBASE+22)
#define F23	(FPBASE+23)
#define F24	(FPBASE+24)
#define F25	(FPBASE+25)
#define F26	(FPBASE+26)
#define F27	(FPBASE+27)
#define F28	(FPBASE+28)
#define F29	(FPBASE+29)
#define F30	(FPBASE+30)
#define F31	(FPBASE+31)
#define	FSR	(FPBASE+32)

#define	NUMFPREGS 33

#define	NREGS	(NUMSAVEREGS + NUMFPREGS)

#endif /* !_MIPS64_REGNUM_H_ */


code:
/*	$OpenBSD: rm7000.h,v 1.3 2010/03/01 22:41:09 jasper Exp $ */

/*
 * Copyright (c) 2001-2004 Opsycon AB  (www.opsycon.se / www.opsycon.com)
 *
 * 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.
 *
 */

#ifndef _MIPS64_RM7000_H_
#define _MIPS64_RM7000_H_

/*
 *  QED RM7000 specific defines.
 */

/*
 *  Performance counters.
 */

#define	PCNT_SRC_CLOCKS		0x00	/* Clock cycles */
#define	PCNT_SRC_INSTR		0x01	/* Total instructions issued */
#define	PCNT_SRC_FPINSTR	0x02	/* Float instructions issued */
#define	PCNT_SRC_IINSTR		0x03	/* Integer instructions issued */
#define	PCNT_SRC_LOAD		0x04	/* Load instructions issued */
#define	PCNT_SRC_STORE		0x05	/* Store instructions issued */
#define	PCNT_SRC_DUAL		0x06	/* Dual issued pairs */
#define	PCNT_SRC_BRPREF		0x07	/* Branch prefetches */
#define	PCNT_SRC_EXTMISS	0x08	/* External cache misses */
#define	PCNT_SRC_STALL		0x09	/* Stall cycles */
#define	PCNT_SRC_SECMISS	0x0a	/* Secondary cache misses */
#define	PCNT_SRC_INSMISS	0x0b	/* Instruction cache misses */
#define	PCNT_SRC_DTAMISS	0x0c	/* Data cache misses */
#define	PCNT_SRC_DTLBMISS	0x0d	/* Data TLB misses */
#define	PCNT_SRC_ITLBMISS	0x0e	/* Instruction TLB misses */
#define	PCNT_SRC_JTLBIMISS	0x0f	/* Joint TLB instruction misses */
#define	PCNT_SRC_JTLBDMISS	0x10	/* Joint TLB data misses */
#define	PCNT_SRC_BRTAKEN	0x11	/* Branches taken */
#define	PCNT_SRC_BRISSUED	0x12	/* Branches issued */
#define	PCNT_SRC_SECWBACK	0x13	/* Secondary cache writebacks */
#define	PCNT_SRC_PRIWBACK	0x14	/* Primary cache writebacks */
#define	PCNT_SRC_DCSTALL	0x15	/* Dcache miss stall cycles */
#define	PCNT_SRC_MISS		0x16	/* Cache misses */
#define	PCNT_SRC_FPEXC		0x17	/* FP possible exception cycles */
#define	PCNT_SRC_MULSLIP	0x18	/* Slip cycles due to mult. busy */
#define	PCNT_SRC_CP0SLIP	0x19	/* CP0 Slip cycles */
#define	PCNT_SRC_LDSLIP		0x1a	/* Slip cycles  due to pend. non-b ld */
#define	PCNT_SRC_WBFULL		0x1b	/* Write buffer full stall cycles  */
#define	PCNT_SRC_CISTALL	0x1c	/* Cache instruction stall cycles  */
#define	PCNT_SRC_MULSTALL	0x1d	/* Multiplier stall cycles  */
#define	PCNT_SRC_ELDSTALL	0x1d	/* Excepion stall due to non-b ld */
#define	PCNT_SRC_MAX		0x1d	/* Maximum PCNT select code */

/*
 *  Counter control bits.
 */

#define	PCNT_CE			0x0400	/* Count enable */
#define	PCNT_UM			0x0200	/* Count in User mode */
#define	PCNT_KM			0x0100	/* Count in kernel mode */

/*
 *  Performance counter system call function codes.
 */
#define	PCNT_FNC_SELECT		0x0001	/* Select counter source */
#define	PCNT_FNC_READ		0x0002	/* Read current value of counter */

#ifdef _KERNEL
__BEGIN_DECLS
int	rm7k_perfcntr(int, long, long, long);
void	rm7k_perfintr(struct trap_frame *);
int	rm7k_watchintr(struct trap_frame *);
void	cp0_setperfcount(int);
void	cp0_setperfctrl(int);
int	cp0_getperfcount(void);
__END_DECLS
#endif /* _KERNEL */

#endif /* _MIPS64_RM7000_H_ */


code:
/*	$OpenBSD: setjmp.h,v 1.3 2011/03/23 16:54:36 pirofti Exp $	*/

/* Public domain */

#ifndef _MIPS64_SETJMP_H_
#define _MIPS64_SETJMP_H_

#define	_JBLEN	83		/* size, in longs, of a jmp_buf */

#endif /* !_MIPS64_SETJMP_H_ */


code:
/*	$OpenBSD: signal.h,v 1.10 2012/12/02 07:03:31 guenther Exp $	*/

/*
 * 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.
 *
 * 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.
 *
 *	@(#)signal.h	8.1 (Berkeley) 6/10/93
 */

#ifndef _MIPS64_SIGNAL_H_
#define _MIPS64_SIGNAL_H_

#include <sys/cdefs.h>

#if !defined(__LANGUAGE_ASSEMBLY)
#include <sys/types.h>

/*
 * Machine-dependent signal definitions
 */
typedef int sig_atomic_t;

#if __BSD_VISIBLE || __XPG_VISIBLE >= 420
/*
 * Information pushed on stack when a signal is delivered.
 * This is used by the kernel to restore state following
 * execution of the signal handler.  It is also made available
 * to the handler to allow it to restore state properly if
 * a non-standard exit is performed.
 */
struct	sigcontext {
	long	__sc_unused;
	long	 sc_mask;	/* signal mask to restore */
	__register_t sc_pc;	/* pc at time of signal */
	__register_t sc_regs[32]; /* processor regs 0 to 31 */
	__register_t mullo;	/* mullo and mulhi registers... */
	__register_t mulhi;	/* mullo and mulhi registers... */
	f_register_t sc_fpregs[33]; /* fp regs 0 to 31 and csr */
	long	sc_fpused;	/* fp has been used */
	long	sc_fpc_eir;	/* floating point exception instruction reg */
	long	xxx[8];		/* XXX reserved */
};
#endif /* __BSD_VISIBLE || __XPG_VISIBLE >= 420 */

#else /* __LANGUAGE_ASSEMBLY */
#define SC_ONSTACK	(0 * REGSZ)
#define	SC_MASK		(1 * REGSZ)
#define	SC_PC		(2 * REGSZ)
#define	SC_REGS		(3 * REGSZ)
#define	SC_MULLO	(35 * REGSZ)
#define	SC_MULHI	(36 * REGSZ)
#define	SC_FPREGS	(37 * REGSZ)
#define	SC_FPUSED	(70 * REGSZ)
#define	SC_FPC_EIR	(71 * REGSZ)
#endif /* __LANGUAGE_ASSEMBLY */

#endif	/* !_MIPS64_SIGNAL_H_ */


code:
/*	$OpenBSD: spinlock.h,v 1.4 2013/06/01 20:47:40 tedu Exp $	*/
 /* Public domain */

#ifndef _MIPS64_SPINLOCK_H_
#define _MIPS64_SPINLOCK_H_

#define _ATOMIC_LOCK_UNLOCKED	(0)
#define _ATOMIC_LOCK_LOCKED	(1)
typedef int _atomic_lock_t;

#ifndef _KERNEL
int _atomic_lock(volatile _atomic_lock_t *);
#endif

#endif /* !_MIPS64_SPINLOCK_H_ */


code:
/*	$OpenBSD: stdarg.h,v 1.8 2011/03/23 16:54:36 pirofti Exp $	*/

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

#ifndef _MIPS64_STDARG_H_
#define	_MIPS64_STDARG_H_

#include <sys/cdefs.h>
#include <machine/_types.h>

typedef __va_list	va_list;

#ifndef __GNUC_VA_LIST
#define __GNUC_VA_LIST
#if defined (__mips_eabi) && ! defined (__mips_soft_float) && ! defined (__mips_single_float)

typedef struct {
  /* Pointer to FP regs.  */
  char *__fp_regs;
  /* Number of FP regs remaining.  */
  int __fp_left;
  /* Pointer to GP regs followed by stack parameters.  */
  char *__gp_regs;
} __gnuc_va_list;

#else /* ! (defined (__mips_eabi) && ! defined (__mips_soft_float) && ! defined (__mips_single_float)) */

typedef char * __gnuc_va_list;

#endif /* ! (defined (__mips_eabi) && ! defined (__mips_soft_float) && ! defined (__mips_single_float)) */
#endif /* not __GNUC_VA_LIST */

/* If this is for internal libc use, don't define anything but __gnuc_va_list */

#ifndef _MIPS64_STDARG_H_
#define _MIPS64_STDARG_H_
enum {
  __no_type_class = -1,
  __void_type_class,
  __integer_type_class,
  __char_type_class,
  __enumeral_type_class,
  __boolean_type_class,
  __pointer_type_class,
  __reference_type_class,
  __offset_type_class,
  __real_type_class,
  __complex_type_class,
  __function_type_class,
  __method_type_class,
  __record_type_class,
  __union_type_class,
  __array_type_class,
  __string_type_class,
  __set_type_class,
  __file_type_class,
  __lang_type_class
};
#endif

#define __va_ellipsis ...

#ifdef __mips64__
#define __va_rounded_size(__TYPE)  \
  (((sizeof (__TYPE) + 8 - 1) / 8) * 8)
#else
#define __va_rounded_size(__TYPE)  \
  (((sizeof (__TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
#endif

#ifdef __mips64__
#define __va_reg_size 8
#else
#define __va_reg_size 4
#endif

#if defined (__mips_eabi)
#if ! defined (__mips_soft_float) && ! defined (__mips_single_float)
#ifdef __mips64__
#define va_start(__AP, __LASTARG)					\
  (__AP.__gp_regs = ((char *) __builtin_next_arg (__LASTARG)		\
		     - (__builtin_args_info (2) < 8			\
			? (8 - __builtin_args_info (2)) * __va_reg_size	\
			: 0)),						\
   __AP.__fp_left = 8 - __builtin_args_info (3),			\
   __AP.__fp_regs = __AP.__gp_regs - __AP.__fp_left * __va_reg_size)
#else /* ! defined (__mips64__) */
#define va_start(__AP, __LASTARG)					\
  (__AP.__gp_regs = ((char *) __builtin_next_arg (__LASTARG)		\
		     - (__builtin_args_info (2) < 8			\
			? (8 - __builtin_args_info (2)) * __va_reg_size	\
			: 0)),						\
   __AP.__fp_left = (8 - __builtin_args_info (3)) / 2,			\
   __AP.__fp_regs = __AP.__gp_regs - __AP.__fp_left * 8,		\
   __AP.__fp_regs = (char *) ((int) __AP.__fp_regs & -8))
#endif /* ! defined (__mips64__) */
#else /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float) ) */
#define va_start(__AP, __LASTARG)					\
  (__AP = ((__gnuc_va_list) __builtin_next_arg (__LASTARG)		\
	   - (__builtin_args_info (2) >= 8 ? 0				\
	      : (8 - __builtin_args_info (2)) * __va_reg_size)))
#endif /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float) ) */
#else /* ! defined (__mips_eabi) */
#define va_start(__AP, __LASTARG) \
  (__AP = (__gnuc_va_list) __builtin_next_arg (__LASTARG))
#endif /* ! (defined (__mips_eabi) && ! defined (__mips_soft_float) && ! defined (__mips_single_float)) */

#ifndef va_end
void va_end (__gnuc_va_list);		/* Defined in libgcc.a */
#endif
#define va_end(__AP)

#if defined (__mips_eabi)

#if ! defined (__mips_soft_float) && ! defined (__mips_single_float)
#ifdef __mips64__
#define __va_next_addr(__AP, __type)					\
  ((__builtin_classify_type (*(__type *) 0) == __real_type_class	\
    && __AP.__fp_left > 0)						\
   ? (--__AP.__fp_left, (__AP.__fp_regs += 8) - 8)			\
   : (__AP.__gp_regs += __va_reg_size) - __va_reg_size)
#else
#define __va_next_addr(__AP, __type)					\
  ((__builtin_classify_type (*(__type *) 0) == __real_type_class	\
    && __AP.__fp_left > 0)						\
   ? (--__AP.__fp_left, (__AP.__fp_regs += 8) - 8)			\
   : (((__builtin_classify_type (* (__type *) 0) < __record_type_class	\
	&& __alignof__ (__type) > 4)					\
       ? __AP.__gp_regs = (char *) (((int) __AP.__gp_regs + 8 - 1) & -8) \
       : (char *) 0),							\
      (__builtin_classify_type (* (__type *) 0) >= __record_type_class	\
       ? (__AP.__gp_regs += __va_reg_size) - __va_reg_size		\
       : ((__AP.__gp_regs += __va_rounded_size (__type))		\
	  - __va_rounded_size (__type)))))
#endif
#else /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float)) */
#ifdef __mips64__
#define __va_next_addr(__AP, __type)					\
  ((__AP += __va_reg_size) - __va_reg_size)
#else
#define __va_next_addr(__AP, __type)					\
  (((__builtin_classify_type (* (__type *) 0) < __record_type_class	\
     && __alignof__ (__type) > 4)					\
    ? __AP = (char *) (((__PTRDIFF_TYPE__) __AP + 8 - 1) & -8)		\
    : (char *) 0),							\
   (__builtin_classify_type (* (__type *) 0) >= __record_type_class	\
    ? (__AP += __va_reg_size) - __va_reg_size				\
    : ((__AP += __va_rounded_size (__type))				\
       - __va_rounded_size (__type))))
#endif
#endif /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float)) */

#ifdef __MIPSEB__
#define va_arg(__AP, __type)						\
  ((__va_rounded_size (__type) <= __va_reg_size)			\
   ? *(__type *) (void *) (__va_next_addr (__AP, __type)		\
			   + __va_reg_size				\
			   - sizeof (__type))				\
   : (__builtin_classify_type (*(__type *) 0) >= __record_type_class	\
      ? **(__type **) (void *) (__va_next_addr (__AP, __type)		\
				+ __va_reg_size				\
				- sizeof (char *))			\
      : *(__type *) (void *) __va_next_addr (__AP, __type)))
#else
#define va_arg(__AP, __type)						\
  ((__va_rounded_size (__type) <= __va_reg_size)			\
   ? *(__type *) (void *) __va_next_addr (__AP, __type)		\
   : (__builtin_classify_type (* (__type *) 0) >= __record_type_class	\
      ? **(__type **) (void *) __va_next_addr (__AP, __type)		\
      : *(__type *) (void *) __va_next_addr (__AP, __type)))
#endif

#else /* ! defined (__mips_eabi) */

/* We cast to void * and then to TYPE * because this avoids
   a warning about increasing the alignment requirement.  */
/* The __mips64__ cases are reversed from the 32 bit cases, because the standard
   32 bit calling convention left-aligns all parameters smaller than a word,
   whereas the __mips64__ calling convention does not (and hence they are
   right aligned).  */
#ifdef __mips64__
#ifdef __MIPSEB__
#define va_arg(__AP, __type)                                    \
  ((__type *) (void *) (__AP = (char *)                         \
                       ((((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8) \
			   + __va_rounded_size (__type))))[-1]
#else
#define va_arg(__AP, __type)                                    \
  ((__AP = (char *) ((((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8)	\
		     + __va_rounded_size (__type))),		\
   *(__type *) (void *) (__AP - __va_rounded_size (__type)))
#endif

#else /* not __mips64__ */

#ifdef __MIPSEB__
/* For big-endian machines.  */
#define va_arg(__AP, __type)					\
  ((__AP = (char *) ((__alignof__ (__type) > 4			\
		      ? ((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8	\
		      : ((__PTRDIFF_TYPE__)__AP + 4 - 1) & -4)	\
		     + __va_rounded_size (__type))),		\
   *(__type *) (void *) (__AP - __va_rounded_size (__type)))
#else
/* For little-endian machines.  */
#define va_arg(__AP, __type)						    \
  ((__type *) (void *) (__AP = (char *) ((__alignof__(__type) > 4	    \
				? ((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8	    \
				: ((__PTRDIFF_TYPE__)__AP + 4 - 1) & -4)    \
					 + __va_rounded_size(__type))))[-1]
#endif
#endif
#endif /* ! defined (__mips_eabi)  */

/* Copy __gnuc_va_list into another variable of this type.  */
#define __va_copy(dest, src) (dest) = (src)

#endif /* !_MIPS64_STDARG_H_ */


code:
/*	$OpenBSD: sysarch.h,v 1.2 2012/12/05 23:20:13 deraadt Exp $	*/

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

#ifndef	_MIPS64_SYSARCH_H_
#define	_MIPS64_SYSARCH_H_

/*
 * Architecture specific syscalls (mips64)
 */

#define	MIPS64_CACHEFLUSH	0

/*
 * Argument structure and defines to mimic IRIX cacheflush() system call
 */

struct	mips64_cacheflush_args {
	vaddr_t	va;
	size_t	sz;
	int	which;
#define	ICACHE	0x01
#define	DCACHE	0x02
#define	BCACHE	(ICACHE | DCACHE)
};

#ifndef _KERNEL

#include <sys/cdefs.h>

__BEGIN_DECLS
int	cacheflush(void *, int, int);
int	_flush_cache(char *, int, int);
int	sysarch(int, void *);
__END_DECLS
#endif	/* _KERNEL */

#endif	/* _MIPS64_SYSARCH_H_ */


code:
/*	$OpenBSD: tcb.h,v 1.1 2011/10/27 04:01:17 guenther Exp $	*/

/*
 * Copyright (c) 2011 Philip Guenther <guenther@openbsd.org>
 *
 * 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.
 */

#ifndef _MACHINE_TCB_H_
#define _MACHINE_TCB_H_

#ifdef _KERNEL

#error "not yet"

#else /* _KERNEL */

/* ELF TLS ABI calls for small TCB, with static TLS data after it */
#define TLS_VARIANT	1

#endif /* _KERNEL */

#endif /* _MACHINE_TCB_H_ */


code:
/*	$OpenBSD: trap.h,v 1.16 2014/04/09 21:10:34 miod Exp $	*/

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

#ifndef _MIPS64_TRAP_H_
#define _MIPS64_TRAP_H_

/*
 * Trap codes (ExcCode in the cause register); also known in trap.c for
 * name strings.
 */

#define T_INT			0	/* Interrupt pending */
#define T_TLB_MOD		1	/* TLB modified fault */
#define T_TLB_LD_MISS		2	/* TLB miss on load or ifetch */
#define T_TLB_ST_MISS		3	/* TLB miss on a store */
#define T_ADDR_ERR_LD		4	/* Address error on a load or ifetch */
#define T_ADDR_ERR_ST		5	/* Address error on a store */
#define T_BUS_ERR_IFETCH	6	/* Bus error on an ifetch */
#define T_BUS_ERR_LD_ST		7	/* Bus error on a load or store */
#define T_SYSCALL		8	/* System call */
#define T_BREAK			9	/* Breakpoint */
#define T_RES_INST		10	/* Reserved instruction exception */
#define T_COP_UNUSABLE		11	/* Coprocessor unusable */
#define T_OVFLOW		12	/* Arithmetic overflow */
#define	T_TRAP			13	/* Trap instruction */
#define	T_VCEI			14	/* R4k Virtual coherency instruction */
#define	T_FPE			15	/* Floating point exception */
#define	T_IWATCH		16	/* R4k Inst. Watch address reference */
#define	T_C2E			18	/* R5k Coprocessor 2 exception */
#define	T_MDMX			22	/* R5k MDMX unusable */
#define	T_DWATCH		23	/* Data Watch address reference */
#define	T_MCHECK		24	/* Machine check */
#define	T_CACHEERR		30	/* Cache error */
#define T_VCED			31	/* R4k Virtual coherency data */

#define	T_USER			0x20	/* user-mode flag or'ed with type */

/*
 *  Defines for trap handler catching kernel accessing memory.
 */
#define	KT_COPYERR	1		/* User space copy error */
#define	KT_KCOPYERR	2		/* Kernel space copy error */
#define	KT_DDBERR	3		/* DDB access error */
#define	KT_GUARDERR	4		/* guarded access error */

#ifndef _LOCORE

#if defined(DDB) || defined(DEBUG)

struct trapdebug {			/* trap history buffer for debugging */
	register_t status;
	register_t cause;
	register_t vadr;
	register_t pc;
	register_t ra;
	register_t sp;
	u_int	code;
	u_int	ipl;
};

#define	trapdebug_enter(ci, frame, cd)					\
do {									\
	register_t sr = disableintr();					\
	u_long cpuid = ci->ci_cpuid;					\
	struct trapdebug *t;						\
									\
	t = trapdebug + TRAPSIZE * cpuid + trppos[cpuid];		\
	t->status = frame->sr;						\
	t->cause = frame->cause;					\
	t->vadr = frame->badvaddr;					\
	t->pc = frame->pc;						\
	t->sp = frame->sp;						\
	t->ra = frame->ra;						\
	t->ipl = frame->ipl;						\
	t->code = cd;							\
	if (++trppos[cpuid] == TRAPSIZE)				\
		trppos[cpuid] = 0;					\
	setsr(sr);							\
} while (0)

#define TRAPSIZE 10		/* Trap log buffer length */
extern struct trapdebug trapdebug[MAXCPUS * TRAPSIZE];
extern uint trppos[MAXCPUS];

void trapDump(const char *, int (*)(const char *, ...));

#else
#define	trapdebug_enter(ci, frame, code)
#endif
#endif /* _LOCORE */

#endif /* !_MIPS64_TRAP_H_ */


code:
/*	$OpenBSD: varargs.h,v 1.3 2011/03/23 16:54:36 pirofti Exp $	*/

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

#ifndef _MIPS64_VARARGS_H_
#define	_MIPS64_VARARGS_H_

#include <machine/stdarg.h>

#define	va_dcl	int va_alist; ...

#undef  va_start
#define	va_start(ap) \
	ap = (char *)&va_alist

#endif /* !_MIPS64_VARARGS_H_ */


code:
/*	$OpenBSD: vmparam.h,v 1.27 2014/01/30 18:16:41 miod Exp $	*/
/*	$NetBSD: vmparam.h,v 1.5 1994/10/26 21:10:10 cgd Exp $	*/

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

#ifndef _MIPS64_VMPARAM_H_
#define _MIPS64_VMPARAM_H_

/*
 * Machine dependent constants mips processors.
 */

#define	USRSTACK	VM_MAXUSER_ADDRESS	/* Start of user stack */

/*
 * Virtual memory related constants, all in bytes
 */
#ifndef MAXTSIZ
#define	MAXTSIZ		(64*1024*1024)		/* max text size */
#endif
#ifndef DFLDSIZ
#define	DFLDSIZ		(128*1024*1024)		/* initial data size limit */
#endif
#ifndef MAXDSIZ
#define	MAXDSIZ		(1*1024*1024*1024)	/* max data size */
#endif
#ifndef BRKSIZ
#define	BRKSIZ		MAXDSIZ			/* heap gap size */
#endif
#ifndef	DFLSSIZ
#define	DFLSSIZ		(2*1024*1024)		/* initial stack size limit */
#endif
#ifndef	MAXSSIZ
#define	MAXSSIZ		(32*1024*1024)		/* max stack size */
#endif

#define STACKGAP_RANDOM	256*1024

/*
 * PTEs for mapping user space into the kernel for physio operations.
 * 16 pte's are enough to cover 8 disks * MAXBSIZE.
 */
#ifndef USRIOSIZE
#define USRIOSIZE	32
#endif

/*
 * PTEs for system V style shared memory.
 * This is basically slop for kmempt which we actually allocate (malloc) from.
 */
#ifndef SHMMAXPGS
#define SHMMAXPGS	8192		/* 8mb */
#endif

#ifndef	VM_PHYSSEG_MAX
#define	VM_PHYSSEG_MAX	8	/* Max number of physical memory segments */
#endif
#ifndef	VM_PHYSSEG_STRAT
#define VM_PHYSSEG_STRAT VM_PSTRAT_BSEARCH
#endif
#define VM_PHYSSEG_NOADD

/* user/kernel map constants */
#define VM_MIN_ADDRESS		((vaddr_t)0x0000000000004000L)
#define VM_MAXUSER_ADDRESS	((vaddr_t)0x0000000080000000L)
#define VM_MAX_ADDRESS		VM_MAXUSER_ADDRESS
#define	VM_MIN_KERNEL_ADDRESS	((vaddr_t)0xc000000000000000L)
#define	VM_MAX_KERNEL_ADDRESS	((vaddr_t)0xc000000040000000L)

/* map PIE below 256MB (non-pie link address) to avoid mmap pressure */
#define VM_PIE_MIN_ADDR		PAGE_SIZE
#define VM_PIE_MAX_ADDR		(0x10000000UL)

/* virtual sizes (bytes) for various kernel submaps */
#define VM_PHYS_SIZE		(USRIOSIZE*PAGE_SIZE)

#endif /* !_MIPS64_VMPARAM_H_ */


code:
/*	$OpenBSD: arcbios.c,v 1.35 2014/03/29 18:09:30 guenther Exp $	*/
/*-
 * Copyright (c) 1996 M. Warner Losh.  All rights reserved.
 * Copyright (c) 1996-2004 Opsycon AB.  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 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.
 */

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

#include <machine/autoconf.h>
#include <machine/cpu.h>
#include <machine/memconf.h>
#include <machine/vmparam.h>

#include <mips64/arcbios.h>
#include <mips64/archtype.h>

#include <uvm/uvm_extern.h>

#ifdef TGT_ORIGIN
#include <machine/mnode.h>
#endif

int bios_is_32bit;
void	*bios_base;

/*
 * If we cannot get the onboard Ethernet address to override this bogus
 * value, ether_ifattach() will pick a valid address.
 */
char bios_enaddr[20] = "ff:ff:ff:ff:ff:ff";

int bios_consrate;			/* Serial console speed. */
char bios_console[30];			/* Primary console. */
char bios_graphics[6];			/* Graphics state. */
char bios_keyboard[6];			/* Keyboard layout. */

void (*bios_halt)(void);
void (*bios_powerdown)(void);
void (*bios_restart)(void);
void (*bios_reboot)(void);
void (*bios_eim)(void);

extern int	physmem;		/* Total physical memory size */
extern int	rsvdmem;		/* Total reserved memory size */

void bios_configure_memory(void);
int bios_get_system_type(void);

arc_dsp_stat_t	displayinfo;		/* Save area for display status info. */

static struct systypes {
	char *sys_vend;		/* Vendor ID if name is ambiguous */
	char *sys_name;		/* May be left NULL if name is sufficient */
	int  sys_type;
} sys_types[] = {
#if 0
    { NULL,		"PICA-61",			ACER_PICA_61 },
    { NULL,		"NEC-R94",			ACER_PICA_61 },
    { NULL,		"DESKTECH-TYNE",		DESKSTATION_TYNE },
    { NULL,		"DESKTECH-ARCStation I",	DESKSTATION_RPC44 },
    { NULL,		"Microsoft-Jazz",		MAGNUM },
    { NULL,		"RM200PCI",			SNI_RM200 },
#endif
    { NULL,		"SGI-IP17",			SGI_IP17 },
    { NULL,		"SGI-IP19",			SGI_IP19 },
    { NULL,		"SGI-IP20",			SGI_IP20 },
    { NULL,		"SGI-IP21",			SGI_IP21 },
    { NULL,		"SGI-IP22",			SGI_IP22 },
    { NULL,		"SGI-IP25",			SGI_IP25 },
    { NULL,		"SGI-IP26",			SGI_IP26 },
    { NULL,		"SGI-IP28",			SGI_IP28 },
    { NULL,		"SGI-IP30",			SGI_OCTANE },
    { NULL,		"SGI-IP32",			SGI_O2 }
};

#define KNOWNSYSTEMS (sizeof(sys_types) / sizeof(struct systypes))

/*
 *	ARC Bios trampoline code.
 */

#define ARC_Call(Name,Offset)	\
__asm__("\n"			\
"	.text\n"		\
"	.ent	" #Name "\n"	\
"	.align	3\n"		\
"	.set	noreorder\n"	\
"	.globl	" #Name "\n"	\
#Name":\n"			\
"	lw	$3, bios_is_32bit\n"\
"	ld	$2, bios_base\n"\
"	beqz	$3, 1f\n"	\
"	 nop\n"			\
"	lw	$3, 0x20($2)\n"	\
"       lw      $2," #Offset "($3)\n"\
"	jr	$2\n"		\
"	 nop\n"			\
"1:\n"				\
"	ld	$3, 2*0x20($2)\n"\
"	ld	$2, 2*" #Offset "($3)\n"\
"	jr	$2\n"		\
"	 nop\n"			\
"	.end	" #Name "\n"	);

/*
 * Invoke an ARC routine through a function pointer (set up in bios_ident()),
 * also forcing the stack to be in CKSEG0 (actually, whatever area proc0 stack
 * was allocated in) if this is a 32-bit ARCBios; used by restart functions,
 * which aren't supposed to return anyway.
 */
#define ARC_Call_Via_Pointer(Name,fnptr) \
__asm__("\n"	\
"	.text\n"		\
"	.ent	" #Name "\n"	\
"	.align	3\n"		\
"	.set	noreorder\n"	\
"	.globl	" #Name "\n"	\
#Name":\n"			\
"	lw	$3, bios_is_32bit\n"\
"	beqz	$3, 1f\n"	\
"	 nop\n"			\
"	ld	$3, proc0paddr\n" \
"	addi	$29, $3, 16384 - 64\n"		/* assumes USPACE >= 16384 */ \
"1:\n"				\
"	ld	$2, " #fnptr "\n"\
"	jr	$2\n"		\
"	 nop\n"			\
"	.end	" #Name "\n");

#if 0
ARC_Call(Bios_Load,			0x00);
ARC_Call(Bios_Invoke,			0x04);
ARC_Call(Bios_Execute,			0x08);
#endif
ARC_Call_Via_Pointer(Bios_Halt,			bios_halt);
ARC_Call_Via_Pointer(Bios_PowerDown,		bios_powerdown);
ARC_Call_Via_Pointer(Bios_Restart,		bios_restart);
ARC_Call_Via_Pointer(Bios_Reboot,		bios_reboot);
ARC_Call_Via_Pointer(Bios_EnterInteractiveMode,	bios_eim);
#if 0
ARC_Call(Bios_Unused1,			0x20);
#endif
ARC_Call(Bios_GetPeer,			0x24);
ARC_Call(Bios_GetChild,			0x28);
#if 0
ARC_Call(Bios_GetParent,		0x2c);
#endif
#if 0
ARC_Call(Bios_GetConfigurationData,	0x30);
#endif
#if 0
ARC_Call(Bios_AddChild,			0x34);
ARC_Call(Bios_DeleteComponent,		0x38);
#endif
#if 0
ARC_Call(Bios_GetComponent,		0x3c);
ARC_Call(Bios_SaveConfiguration,	0x40);
#endif
ARC_Call(Bios_GetSystemId,		0x44);
ARC_Call(Bios_GetMemoryDescriptor,	0x48);
#if 0
ARC_Call(Bios_Unused2,			0x4c);
#endif
ARC_Call(Bios_GetTime,			0x50);
#if 0
ARC_Call(Bios_GetRelativeTime,		0x54);
ARC_Call(Bios_GetDirectoryEntry,	0x58);
ARC_Call(Bios_Open,			0x5c);
ARC_Call(Bios_Close,			0x60);
ARC_Call(Bios_Read,			0x64);
ARC_Call(Bios_GetReadStatus,		0x68);
#endif
ARC_Call(Bios_Write,			0x6c);
#if 0
ARC_Call(Bios_Seek,			0x70);
ARC_Call(Bios_Mount,			0x74);
#endif
ARC_Call(Bios_GetEnvironmentVariable,	0x78);
#if 0
ARC_Call(Bios_SetEnvironmentVariable,	0x7c);
ARC_Call(Bios_GetFileInformation,	0x80);
ARC_Call(Bios_SetFileInformation,	0x84);
#endif
ARC_Call(Bios_FlushAllCaches,		0x88);
#if 0
ARC_Call(Bios_TestUnicodeCharacter,	0x8c);
ARC_Call(Bios_GetDisplayStatus,		0x90);
#endif

/*
 *	Simple getchar/putchar interface.
 */

#if 0
int
bios_getchar()
{
	char buf[4];
	long  cnt;

	if (Bios_Read(0, &buf[0], 1, &cnt) != 0)
		return(-1);
	return(buf[0] & 255);
}
#endif

void
bios_putchar(c)
char c;
{
	char buf[4];
	long  cnt;

	if (c == '\n') {
		buf[0] = '\r';
		buf[1] = c;
		cnt = 2;
#ifdef __arc__
		if (displayinfo.CursorYPosition < displayinfo.CursorMaxYPosition)
			displayinfo.CursorYPosition++;
#endif
	}
	else {
		buf[0] = c;
		cnt = 1;
	}
	Bios_Write(1, &buf[0], cnt, &cnt);
}

void
bios_putstring(s)
char *s;
{
	while (*s) {
		bios_putchar(*s++);
	}
}

void
bios_printf(const char *fmt, ...)
{
	va_list ap;
	char buf[1024];

	va_start(ap, fmt);
	vsnprintf(buf, sizeof(buf), fmt, ap);
	bios_putstring(buf);
	va_end(ap);
}

/*
 * Get memory descriptor for the memory configuration and
 * create a layout database used by pmap init to set up
 * the memory system.
 *
 * Concatenate obvious adjacent segments.
 */
void
bios_configure_memory()
{
	arc_mem_t *descr = NULL;
	uint64_t start, count, prevend = 0;
	MEMORYTYPE type, prevtype = BadMemory;
	uint64_t seg_start, seg_end;
#ifdef TGT_ORIGIN
	int seen_free = 0;
#endif
#ifdef ARCBIOS_DEBUG
	int i;
#endif

	descr = (arc_mem_t *)Bios_GetMemoryDescriptor(descr);
	while (descr != NULL) {
		if (bios_is_32bit) {
			start = descr->BasePage;
			count = descr->PageCount;
			type = descr->Type;
		} else {
			start = ((arc_mem64_t *)descr)->BasePage;
			count = ((arc_mem64_t *)descr)->PageCount;
			type = descr->Type;

#ifdef TGT_OCTANE
			/*
			 * Memory above 1GB physical (address 1.5GB)
			 * gets reported as reserved on Octane, while
			 * it isn't.
			 * Abort scan at this point, platform dependent
			 * code will add the remaining memory, if any.
			 */
			if (sys_config.system_type == SGI_OCTANE &&
			    type == FirmwarePermanent &&
			    start >= 0x60000)
				break;
#endif

#ifdef TGT_ORIGIN
			if (sys_config.system_type == SGI_IP27) {
				/*
				 * For the lack of a better way to tell
				 * IP27 apart from IP35, look at the
				 * start of the first chunk of free
				 * memory. On IP27, it starts under
				 * 0x20000 (which allows us to link
				 * kernels at 0xa800000000020000).
				 * On IP35, it starts at 0x40000.
				 */
				if (type == FreeMemory && seen_free == 0) {
					seen_free = 1;
					if (start >= 0x20)	/* IP35 */
						sys_config.system_type =
						    SGI_IP35;
				}

				/*
				 * On IP27 and IP35 systems, data after the
				 * first FirmwarePermanent entry is not
				 * reliable (entries conflict with each other),
				 * and memory after 32MB (or 64MB on IP35) is
				 * not listed anyway.
				 * So, break from the loop as soon as a
				 * FirmwarePermanent entry is found, after
				 * making it span the end of the first 32MB
				 * (64MB on IP35).
				 *
				 * The rest of the memory will be gathered
				 * from the node structures.  This loses some
				 * of the first few MB (well... all of them
				 * but the kernel image), but at least we're
				 * safe to use ARCBios after going virtual.
				 */
				if (type == FirmwarePermanent) {
					descr = NULL; /* abort loop */
					count = ((sys_config.system_type ==
					    SGI_IP27 ?  32 : 64) << (20 - 12)) -
					    start;
				}
			}
#endif	/* O200 || O300 */
		}

		switch (type) {
		case BadMemory:		/* have no use for these */
			break;
		case LoadedProgram:
			/*
			 * LoadedProgram areas are either the boot loader,
			 * if the kernel has not been directly loaded by
			 * ARCBios, or the kernel image itself.
			 * Since we will move the kernel image out of the
			 * memory segments later anyway, it makes sense to
			 * claim this memory as free.
			 */
			/* FALLTHROUGH */
		case FreeMemory:
		case FreeContigous:
			/*
			 * Convert from ARCBios page size to kernel page size.
			 * As this can yield a smaller range due to possible
			 * different page size, we try to force coalescing
			 * with the previous range if this is safe.
			 */
			seg_start = atop(round_page(start * ARCBIOS_PAGE_SIZE));
			seg_end = atop(trunc_page((start + count) *
			    ARCBIOS_PAGE_SIZE));
			if (start == prevend)
				switch (prevtype) {
				case LoadedProgram:
				case FreeMemory:
				case FreeContigous:
					seg_start = atop(trunc_page(start *
					    ARCBIOS_PAGE_SIZE));
					break;
				default:
					break;
				}
			if (seg_start < seg_end)
				memrange_register(seg_start, seg_end, 0);
			break;
		case ExceptionBlock:
		case SystemParameterBlock:
		case FirmwareTemporary:
		case FirmwarePermanent:
			rsvdmem += count;
			break;
		default:		/* Unknown type, leave it alone... */
			break;
		}
		prevtype = type;
		prevend = start + count;
#ifdef TGT_ORIGIN
		if (descr == NULL)
			break;
#endif
		descr = (arc_mem_t *)Bios_GetMemoryDescriptor(descr);
	}

	/* convert rsvdmem to kernel pages, and count it in physmem */
	rsvdmem = atop(round_page(rsvdmem * ARCBIOS_PAGE_SIZE));
	physmem += rsvdmem;

#ifdef ARCBIOS_DEBUG
	for (i = 0; i < MAXMEMSEGS; i++) {
		if (mem_layout[i].mem_last_page) {
			bios_printf("MEM %d, %p to  %p\n", i,
			    ptoa(mem_layout[i].mem_first_page),
			    ptoa(mem_layout[i].mem_last_page));
	    }
	}
#endif
}

/*
 * Find out system type.
 */
int
bios_get_system_type()
{
	arc_config_t	*cf;
	arc_sid_t	*sid;
	register_t	prid;
	char		*sysid;
	int		sysid_len;
	int		i;

	/*
	 * Figure out where ARCBios can be addressed. On R8000, we can not
	 * use compatibility space, but on IP27/IP35, we can not blindly
	 * use XKPHYS due to subspacing, while compatibility space works.
	 * Fortunately we can get the processor ID to tell these apart, even
	 * though 32-bit coprocessor 0 instructions are not supposed to be
	 * supported on the R8000 (they probably misbehave somehow if the
	 * register has bits sets in the upper 32 bits, which is not the
	 * case of the R8000 PrId register).
	 */
	__asm__ volatile ("mfc0 %0, $15" /* COP_0_PRID */ : "=r" (prid));
	if ((prid & 0xff00) == (MIPS_R8000 << 8))
		bios_base = (void *)PHYS_TO_XKPHYS(ARCBIOS_BASE, CCA_CACHED);
	else
		bios_base = (void *)PHYS_TO_CKSEG0(ARCBIOS_BASE);

	/*
	 * Figure out if this is an ARCBios machine and if it is, see if we're
	 * dealing with a 32 or 64 bit version.
	 */
	if ((ArcBiosBase32->magic == ARC_PARAM_BLK_MAGIC) ||
	    (ArcBiosBase32->magic == ARC_PARAM_BLK_MAGIC_BUG)) {
		bios_is_32bit = 1;
		bios_printf("ARCS32 Firmware Version %d.%d\n",
		    ArcBiosBase32->version, ArcBiosBase32->revision);
	} else if ((ArcBiosBase64->magic == ARC_PARAM_BLK_MAGIC) ||
	    (ArcBiosBase64->magic == ARC_PARAM_BLK_MAGIC_BUG)) {
		bios_is_32bit = 0;
		bios_printf("ARCS64 Firmware\n");
	} else {
		return -1; /* Today is not your lucky day */
	}

	sid = (arc_sid_t *)Bios_GetSystemId();

	cf = (arc_config_t *)Bios_GetChild(NULL);
	if (cf != NULL) {
		if (bios_is_32bit) {
			sysid = (char *)(long)cf->id;
			sysid_len = cf->id_len;
		} else {
			sysid = (char *)((arc_config64_t *)cf)->id;
			sysid_len = ((arc_config64_t *)cf)->id_len;
		}

		if (sysid_len > 0 && sysid != NULL) {
			sysid_len--;
			for (i = 0; i < KNOWNSYSTEMS; i++) {
				if (strlen(sys_types[i].sys_name) !=sysid_len)
					continue;
				if (strncmp(sys_types[i].sys_name, sysid,
				    sysid_len) != 0)
					continue;
				if (sys_types[i].sys_vend &&
				    strncmp(sys_types[i].sys_vend, sid->vendor,
				      8) != 0)
					continue;
				return (sys_types[i].sys_type);	/* Found it. */
			}
		}
	} else {
#ifdef TGT_ORIGIN
		if (IP27_KLD_KLCONFIG(0)->magic == IP27_KLDIR_MAGIC) {
			/*
			 * If we find a kldir assume IP27 for now.
			 * We'll decide whether this is IP27 or IP35 later.
			 */
			return SGI_IP27;
		}
#endif
	}

	bios_printf("UNRECOGNIZED SYSTEM '%s' VENDOR '%8.8s' PRODUCT '%8.8s'\n",
	    cf == NULL ? "??" : sysid, sid->vendor, sid->prodid);
	bios_printf("Halting system!\n");
	Bios_Halt();
	bios_printf("Halting failed, use manual reset!\n");
	while(1);
}

/*
 * Incomplete version of bios_ident
 */
void
bios_ident()
{
	sys_config.system_type = bios_get_system_type();

	if (bios_is_32bit) {
#define bios_fnptr(slot) \
    (int64_t)*(int32_t *)((int64_t)ArcBiosBase32->firmware_vect + (slot) * 4)
		bios_halt = (void (*)(void))bios_fnptr(3);
		bios_powerdown = (void (*)(void))bios_fnptr(4);
		bios_restart = (void (*)(void))bios_fnptr(5);
		bios_reboot = (void (*)(void))bios_fnptr(6);
		bios_eim = (void (*)(void))bios_fnptr(7);
#undef bios_fnptr
	} else {
#define bios_fnptr(slot) \
    *(int64_t *)(ArcBiosBase64->firmware_vect + (slot) * 8)
		bios_halt = (void (*)(void))bios_fnptr(3);
		bios_powerdown = (void (*)(void))bios_fnptr(4);
		bios_restart = (void (*)(void))bios_fnptr(5);
		bios_reboot = (void (*)(void))bios_fnptr(6);
		bios_eim = (void (*)(void))bios_fnptr(7);
#undef bios_fnptr
	}

	bios_configure_memory();
#ifdef __arc__
	displayinfo = *(arc_dsp_stat_t *)Bios_GetDisplayStatus(1);
#endif
}

#if 0
/*
 * Return geometry of the display. Used by pccons.c to set up the
 * display configuration.
 */
void
bios_display_info(xpos, ypos, xsize, ysize)
    int	*xpos;
    int	*ypos;
    int *xsize;
    int *ysize;
{
#ifdef __arc__
	*xpos = displayinfo.CursorXPosition;
	*ypos = displayinfo.CursorYPosition;
	*xsize = displayinfo.CursorMaxXPosition;
	*ysize = displayinfo.CursorMaxYPosition;
#endif
}
#endif