code:
/*	$OpenBSD: libsa.h,v 1.4 2014/07/14 10:23:58 jasper Exp $	*/

/*
 * Copyright (c) 2013 Jasper Lievisse Adriaanse <jasper@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.
 */

#include <lib/libsa/stand.h>

#define DEFAULT_KERNEL_ADDRESS	0

extern char *kernelfile;

/*
 * MD interfaces for MI boot(9)
 */
void    devboot(dev_t, char *);
void    machdep(void);
void    run_loadfile(u_long *, int);

/*
 * CN30XX UART
 */
void	cn30xxuartcnprobe(struct consdev *);
void	cn30xxuartcninit(struct consdev *);
void	cn30xxuartcnputc(dev_t, int);
int	cn30xxuartcngetc(dev_t);

/*
 * clock
 */
void	delay(int);
u_int	cp0_get_count(void);


code:
/*	$OpenBSD: machdep.c,v 1.7 2014/07/18 07:27:47 jasper Exp $	*/

/*
 * Copyright (c) 2009, 2010 Miodrag Vallat.
 * Copyright (c) 2013, 2014 Jasper Lievisse Adriaanse <jasper@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.
 */
/*
 * Copyright (c) 2003-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.
 *
 */

#include <sys/param.h>
#include <lib/libkern/libkern.h>
#include "libsa.h"
#include <stand/boot/cmd.h>
#include <machine/cpu.h>
#include <machine/octeonreg.h>
#include <machine/octeonvar.h>

struct boot_desc *boot_desc;
struct boot_info *boot_info;

char uboot_rootdev[OCTEON_ARGV_MAX];
char bootdev[16];

int parse_rootdev(void);

/*
 * We need to save the arguments u-boot setup for us, so we can pass them
 * onwards to the kernel later on.
 */
int
mips_init(__register_t a0, __register_t a1, __register_t a2 __unused,
	__register_t a3)
{
	boot_desc = (struct boot_desc *)a3;
	boot_info =
		(struct boot_info *)PHYS_TO_CKSEG0(boot_desc->boot_info_addr);

	boot(0);
	return 0;
}

/*
 * Console and TTY related functions
 */

int
cnspeed(dev_t dev, int s)
{
	return CONSPEED;
}

char *
ttyname(int fd)
{
	return "uboot console";
}

dev_t
ttydev(char *name)
{
	return (NODEV);
}

/*
 * Boot -devices and -path related functions.
 */

void
devboot(dev_t dev, char *path)
{
	int i;

	/*
	 * Decode the uboot 'rootdev' argument into a device and partition
	 * we can use to load the kernel off. We skip the first two arguments
	 * since they're always the same (bootoctlinux, $image).
	 * We expect the 'rootdev' argument to be 'octcf0a' or the like.
	 */
	for (i = 1; i < boot_desc->argc; i++) {
		const char *arg =
		    (const char*)PHYS_TO_CKSEG0(boot_desc->argv[i]);

		if (arg == NULL)
			continue;

		if (strncmp(arg, "rootdev=", 8) == 0) {
			if (*uboot_rootdev == '\0') {
				strlcpy(uboot_rootdev, arg,
					sizeof(uboot_rootdev));
				if (parse_rootdev() == 0) {
					strlcpy(path, bootdev, BOOTDEVLEN);
					return;
				}
			} else {
				break; /* No point in going on. */
			}
		}
	}

	/* No arguments given, or it couldn't be parsed. */
	strlcpy(path, "octcf0a", BOOTDEVLEN);
}

int
parse_rootdev(void)
{
	char *p;
	size_t len;

	/*
	 * Take 'rootdev=sd0a' and return the device.
         */
        p = strchr(uboot_rootdev, '=');
	if (p == NULL)
		return 1;
	p++;
	len = strlen(p);
        if (len <= 2 || len >= sizeof bootdev - 1)
                return 1;

	memcpy(bootdev, p, len);

	return 0;
}

time_t
getsecs(void)
{
	u_int ticks = cp0_get_count();
	uint32_t freq = boot_desc->eclock;

	return (time_t)((0xffffffff - ticks) / freq);
}

void
machdep()
{
	cninit();
}

__dead void
_rtt()
{
	octeon_xkphys_write_8(OCTEON_CIU_BASE + CIU_SOFT_RST, 1);
	for (;;) ;
}

license: unknown


code:
/*	$OpenBSD: start.S,v 1.3 2014/07/12 20:36:52 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.
 */

#include <machine/param.h>
#include <machine/asm.h>
#include <machine/cpu.h>
#include <mips64/mips_cpu.h>
#include <machine/regnum.h>
#include <machine/cpustate.h>

	.set	noreorder
	.set	mips64r2

	.globl	__start
	.globl	kernel_text
kernel_text = __start
LEAF(cp0_get_count, 0)
        MFC0    v0, COP_0_COUNT
        MFC0_HAZARD
        j       ra
        NOP
END(cp0_get_count)

__start:
/* initialize ebase */
	dla	t0, 0xffffffff80000000
	mtc0	t0, COP_0_EBASE

/* initialize cvmctl */
	dli	t0, 0x900043F0
	dmtc0	t0, COP_0_CVMCTL

/* initialize cvmmemctl */
	dli	t0, 0x1846104 # If you want to skip write buffer, use this
	dmtc0	t0, COP_0_CVMMEMCTL

/* initialize pagegrain */
	dli	t0, 0x20000000
	dmtc0	t0, COP_0_TLB_PG_GRAIN

	mfc0    v0, COP_0_STATUS_REG
	li	v1, ~(SR_INT_ENAB | SR_ERL | SR_EXL)
	and	v0, v1
	mtc0    v0, COP_0_STATUS_REG    # disable all interrupts

	mtc0	zero, COP_0_CAUSE_REG	# Clear soft interrupts

	LA	gp, _gp

	/*
	 * Initialize stack and call bootloader setup.
	 */
	LA	t0, __start - FRAMESZ(CF_SZ)
	PTR_S	ra, CF_RA_OFFS(t0)		# save uboot return address
	PTR_S	sp, 0(t0)			# and stack
	move	sp, t0
	jal	mips_init			# mips_init(argc, argv, envp,
	nop					#    callvec, esym)

	beqz	v0, 1f				# upon failure, return to uboot
	nop

	move	a0, zero
	PANIC("Startup failed!")

1:	PTR_L	ra, CF_RA_OFFS(sp)
	PTR_L	sp, 0(sp)
	jr	ra
	nop


code:
/*	$OpenBSD: uart.c,v 1.8 2014/07/12 14:15:06 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.
 *
 */

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

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

#include <dev/ic/comreg.h>
#include <dev/ic/comvar.h>
#include <dev/cons.h>
#include <machine/octeonvar.h>

#include "libsa.h"

#define  OCTEON_MIO_UART0_RBR           0x0001180000000800ull
#define  OCTEON_MIO_UART0_IER           0x0001180000000808ull
#define  OCTEON_MIO_UART0_IIR           0x0001180000000810ull
#define  OCTEON_MIO_UART0_LCR           0x0001180000000818ull
#define  OCTEON_MIO_UART0_MCR           0x0001180000000820ull
#define  OCTEON_MIO_UART0_LSR           0x0001180000000828ull
#define  OCTEON_MIO_UART0_MSR           0x0001180000000830ull
#define  OCTEON_MIO_UART0_THR           0x0001180000000840ull
#define  OCTEON_MIO_UART0_USR           0x0001180000000938ull
#define  OCTEON_MIO_UART0_FCR           0x0001180000000850ull
#define  OCTEON_MIO_UART0_DLL           0x0001180000000880ull
#define  OCTEON_MIO_UART0_DLH           0x0001180000000888ull

#define  USR_TXFIFO_NOTFULL		2

int cn30xxuart_delay(void);
void cn30xxuart_wait_txhr_empty(int);

/*
 * Early console routines.
 */
int
cn30xxuart_delay(void)
{
	int divisor;
	int lcr;
	lcr = octeon_xkphys_read_8(OCTEON_MIO_UART0_LCR);
	octeon_xkphys_write_8(OCTEON_MIO_UART0_LCR, lcr | LCR_DLAB);

	divisor = (octeon_xkphys_read_8(OCTEON_MIO_UART0_DLL) |
			    (octeon_xkphys_read_8(OCTEON_MIO_UART0_DLH) << 8));
	octeon_xkphys_write_8(OCTEON_MIO_UART0_LCR, lcr);

	return (10);
}

void
cn30xxuart_wait_txhr_empty(int d)
{
	while(((octeon_xkphys_read_8(OCTEON_MIO_UART0_LSR) & LSR_TXRDY) == 0) &&
	        ((octeon_xkphys_read_8(OCTEON_MIO_UART0_USR) & USR_TXFIFO_NOTFULL) == 0))
		delay(d);
}

void
cn30xxuartcninit(struct consdev *consdev)
{
	int ier;
	/* Disable interrupts */
	ier = octeon_xkphys_read_8(OCTEON_MIO_UART0_IER) & 0x0;
	octeon_xkphys_write_8(OCTEON_MIO_UART0_IER, ier);

	/* Enable RTS & DTR */
	octeon_xkphys_write_8(OCTEON_MIO_UART0_MCR, MCR_RTS | MCR_DTR);
}

void
cn30xxuartcnprobe(struct consdev *cn)
{
	cn->cn_pri = CN_HIGHPRI;
	cn->cn_dev = makedev(CONSMAJOR, 0);
}

void
cn30xxuartcnputc (dev_t dev, int c)
{
	int d;

	/* 1/10th the time to transmit 1 character (estimate). */
	d = cn30xxuart_delay();
        cn30xxuart_wait_txhr_empty(d);
	octeon_xkphys_write_8(OCTEON_MIO_UART0_THR, c);
        cn30xxuart_wait_txhr_empty(d);
}

int
cn30xxuartcngetc (dev_t dev)
{
	int c, d;

	/* 1/10th the time to transmit 1 character (estimate). */
	d = cn30xxuart_delay();

	if (dev & 0x80)
		return octeon_xkphys_read_8(OCTEON_MIO_UART0_LSR) & LSR_RXRDY;

	while ((octeon_xkphys_read_8(OCTEON_MIO_UART0_LSR) & LSR_RXRDY) == 0)
		delay(d);

	c = octeon_xkphys_read_8(OCTEON_MIO_UART0_RBR);
	if (c == '\r')
		c = '\n';

	return (c);
}


code:
/Makefile/1.4/Sun Jul 13 09:26:08 2014//TOPENBSD_5_8_BASE
D

path: sys/arch/octeon/stand/libsa/CVS/Entries


path: sys/arch/octeon/stand/libsa/CVS/Tag


code:
#	$OpenBSD: Makefile,v 1.4 2014/07/13 09:26:08 jasper Exp $

.include "${.CURDIR}/../Makefile.inc"

LIB=	sa

.PATH:	${.CURDIR}/../../../../lib/libsa

CLEANFILES += machine mips64

CFLAGS+= ${CEXTRAFLAGS} ${SAABI} -nostdinc -mno-abicalls -D_NO_ABICALLS \
	-fno-pie \
	-I${.CURDIR} -I${.CURDIR}/../include -I${.CURDIR}/../.. \
	-I${.CURDIR}/../../.. -I${.CURDIR}/../../../.. \
	-I${.CURDIR}/../../../../lib/libsa \
	-I${.OBJDIR}

# stand routines
SRCS=	alloc.c cons.c ctime.c exit.c getchar.c getfile.c gets.c globals.c \
	memcmp.c memcpy.c memset.c printf.c putchar.c \
	snprintf.c strchr.c strcmp.c strerror.c strncmp.c strncpy.c strtol.c

# io routines
SRCS+=	close.c closeall.c dev.c disklabel.c dkcksum.c fstat.c ioctl.c \
	lseek.c open.c read.c readdir.c stat.c write.c

#SRCS+=	cread.c
#CPPFLAGS+= -D__INTERNAL_LIBSA_CREAD

# boot filesystems
SRCS+=	ufs.c cd9660.c

CFLAGS+=-DNO_NET

SRCS+=	loadfile.c

${OBJS}:	${.CURDIR}/../Makefile.inc

NOPROFILE=
NOPIC=

.if !make(obj)
.BEGIN:
	@([ -h machine ] || ln -s ${.CURDIR}/../../include machine)
	@([ -h mips64 ] || ln -s ${.CURDIR}/../../../mips64/include mips64)
CLEANFILES+=	machine mips64
.endif

install:

.include <bsd.lib.mk>

path: sys/arch/octeon/stand/libsa/Makefile


code:
D/conf////
D/ddb////
D/include////
D/isa////
D/powerpc////

path: sys/arch/powerpc/CVS/Entries


code: src/sys/arch/powerpc

path: sys/arch/powerpc/CVS/Repository


code:
/files.powerpc/1.52/Fri Jul 17 22:52:29 2015//TOPENBSD_5_8_BASE
D

path: sys/arch/powerpc/conf/CVS/Entries


code: src/sys/arch/powerpc/conf

path: sys/arch/powerpc/conf/CVS/Repository


code:
#	$OpenBSD: files.powerpc,v 1.52 2015/07/17 22:52:29 tedu Exp $
#

file	arch/powerpc/powerpc/setjmp.S			ddb
file	arch/powerpc/powerpc/copystr.c
file	arch/powerpc/powerpc/cpu_subr.c
file	arch/powerpc/powerpc/fpu.c
file	arch/powerpc/powerpc/in_cksum.c
file	arch/powerpc/powerpc/bus_dma.c
file	arch/powerpc/powerpc/bus_space.c
file	arch/powerpc/powerpc/pmap.c
file	arch/powerpc/powerpc/process_machdep.c
file	arch/powerpc/powerpc/sys_machdep.c
file	arch/powerpc/powerpc/trap.c
file	arch/powerpc/powerpc/vm_machdep.c
file	arch/powerpc/powerpc/lock_machdep.c		multiprocessor
file	arch/powerpc/powerpc/mutex.S
file	arch/powerpc/powerpc/intr.c
file	arch/powerpc/powerpc/softintr.c

file	arch/powerpc/ddb/db_memrw.c			ddb
file	arch/powerpc/ddb/db_disasm.c			ddb
file	arch/powerpc/ddb/db_trace.c			ddb

# quad support is necessary for 32 bit architectures
file	lib/libkern/adddi3.c
file	lib/libkern/anddi3.c
file	lib/libkern/ashldi3.c
file	lib/libkern/ashrdi3.c
file	lib/libkern/cmpdi2.c
file	lib/libkern/divdi3.c
file	lib/libkern/iordi3.c
file	lib/libkern/lshldi3.c
file	lib/libkern/lshrdi3.c
file	lib/libkern/moddi3.c
file	lib/libkern/muldi3.c
file	lib/libkern/negdi2.c
file	lib/libkern/notdi2.c
file	lib/libkern/qdivrem.c
file	lib/libkern/subdi3.c
file	lib/libkern/ucmpdi2.c
file	lib/libkern/udivdi3.c
file	lib/libkern/umoddi3.c
file	lib/libkern/xordi3.c


code: src/sys/arch/powerpc/ddb

path: sys/arch/powerpc/ddb/CVS/Repository


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

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

#include <machine/db_machdep.h>

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

enum opf {
	Opf_INVALID,
	Opf_A,
	Opf_A0,
	Opf_B,
	Opf_BI,
	Opf_BI1,
	Opf_BO,
	Opf_CRM,
	Opf_D,
	Opf_S,
	Opf_FM,
	Opf_LK,
	Opf_RC,
	Opf_AA,
	Opf_LI,
	Opf_OE,
	Opf_SR,
	Opf_TO,
	Opf_SIMM,
	Opf_UIMM,
	Opf_d,
	Opf_crbA,
	Opf_crbB,
	Opf_crbD,
	Opf_crfD,
	Opf_crfS,
	Opf_spr,
	Opf_tbr,

	Opf_BD,
	Opf_C,

	Opf_NB,

	Opf_sh,
	Opf_SH,
	Opf_mb,
	Opf_MB,
	Opf_ME,
};

struct db_field {
	char *name;
	enum opf opf;
} db_fields[] = {
	{ "A",		Opf_A },
	{ "A0",		Opf_A0 },
	{ "B",		Opf_B },
	{ "D",		Opf_D },
	{ "S",		Opf_S },
	{ "AA",		Opf_AA },
	{ "LI",		Opf_LI },
	{ "BD",		Opf_BD },
	{ "BI",		Opf_BI },
	{ "BI1",	Opf_BI1 },
	{ "BO",		Opf_BO },
	{ "CRM",	Opf_CRM },
	{ "FM",		Opf_FM },
	{ "LK",		Opf_LK },
	{ "MB",		Opf_MB },
	{ "ME",		Opf_ME },
	{ "NB",		Opf_NB },
	{ "OE",		Opf_OE },
	{ "RC",		Opf_RC },
	{ "SH",		Opf_SH },
	{ "SR",		Opf_SR },
	{ "TO",		Opf_TO },
	{ "SIMM",	Opf_SIMM },
	{ "UIMM",	Opf_UIMM },
	{ "crbA",	Opf_crbA },
	{ "crbB",	Opf_crbB },
	{ "crbD",	Opf_crbD },
	{ "crfD",	Opf_crfD },
	{ "crfS",	Opf_crfS },
	{ "d",		Opf_d },
	{ "mb",		Opf_mb },
	{ "sh",		Opf_sh },
	{ "spr",	Opf_spr },
	{ "tbr",	Opf_tbr },
	{ NULL,		0 }
};

struct opcode {
	char *name;
	u_int32_t mask;
	u_int32_t code;
	char *decode_str;
};

typedef u_int32_t instr_t;
typedef void (op_class_func) (u_int32_t addr, instr_t instr);

u_int32_t extract_field(u_int32_t value, u_int32_t base, u_int32_t width);
void disasm_fields(u_int32_t addr, const struct opcode *popcode, instr_t instr,
    char *disasm_str, size_t bufsize);
void disasm_process_field(u_int32_t addr, instr_t instr, char **ppfmt,
    char *ppoutput, size_t bufsize);
void dis_ppc(u_int32_t addr, const struct opcode *opcodeset, instr_t instr);

op_class_func op_ill, op_base;
op_class_func op_cl_x13, op_cl_x1e, op_cl_x1f;
op_class_func op_cl_x3a, op_cl_x3b;
op_class_func op_cl_x3e, op_cl_x3f;

op_class_func *opcodes_base[] = {
/*x00*/	op_ill,		op_ill,		op_base,	op_ill,
/*x04*/	op_ill,		op_ill,		op_ill,		op_base,
/*x08*/	op_base,	op_base,	op_base,	op_base,
/*x0C*/	op_base,	op_base,	op_base/*XXX*/,	op_base/*XXX*/,
/*x10*/	op_base,	op_base,	op_base,	op_cl_x13,
/*x14*/	op_base,	op_base,	op_ill,		op_base,
/*x18*/	op_base,	op_base,	op_base,	op_base,
/*x1C*/	op_base,	op_base,	op_cl_x1e,	op_cl_x1f,
/*x20*/	op_base,	op_base,	op_base,	op_base,
/*x24*/	op_base,	op_base,	op_base,	op_base,
/*x28*/	op_base,	op_base,	op_base,	op_base,
/*x2C*/	op_base,	op_base,	op_base,	op_base,
/*x30*/	op_base,	op_base,	op_base,	op_base,
/*x34*/	op_base,	op_base,	op_base,	op_base,
/*x38*/	op_ill,		op_ill,		op_cl_x3a,	op_cl_x3b,
/*x3C*/	op_ill,		op_ill,		op_cl_x3e,	op_cl_x3f
};

/* This table could be modified to make significant the "reserved" fields
 * of the opcodes, But I didn't feel like it when typing in the table,
 * I would recommend that this table be looked over for errors,
 * This was derived from the table in Appendix A.2 of (Mot part # MPCFPE/AD)
 * PowerPC Microprocessor Family: The Programming Environments
 */

const struct opcode opcodes[] = {
	{ "tdi",	0xfc000000, 0x08000000, " %{TO},%{A},%{SIMM}" },
	{ "twi",	0xfc000000, 0x0c000000, " %{TO},%{A},%{SIMM}" },

	{ "mulli",	0xfc000000, 0x1c000000, " %{D},%{A},%{SIMM}" },
	{ "subfic",	0xfc000000, 0x20000000, " %{D},%{A},%{SIMM}" },
	{ "cmpli",	0xff800000, 0x28000000, " %{A},%{UIMM}" },
	{ "cmpli",	0xfc400000, 0x28000000, " %{crfD}%{A}, %{UIMM}" },
	{ "cmpi",	0xff800000, 0x2c000000, " %{A},%{SIMM}"},
	{ "cmpi",	0xfc400000, 0x2c000000, " %{crfD}%{A},%{SIMM}" },
	{ "addic",	0xfc000000, 0x30000000, " %{D},%{A},%{SIMM}" },
	{ "addic.",	0xfc000000, 0x34000000, " %{D},%{A},%{SIMM}" },
	{ "addi",	0xfc000000, 0x38000000, " %{D},%{A0}%{SIMM}" },
	{ "addis",	0xfc000000, 0x3c000000, " %{D},%{A0}%{SIMM}" },
	{ "sc",		0xffffffff, 0x44000002, "" },
	{ "b",		0xfc000000, 0x40000000, "%{BO}%{LK}%{AA} %{BI}%{BD}" },
	{ "b",		0xfc000000, 0x48000000, "%{LK}%{AA} %{LI}" },

	{ "rlwimi",	0xfc000000, 0x50000000, "%{RC} %{A},%{S},%{SH},%{MB},%{ME}" },
	{ "rlwinm",	0xfc000000, 0x54000000, "%{RC} %{A},%{S},%{SH},%{MB},%{ME}" },
	{ "rlwnm",	0xfc000000, 0x5c000000, "%{RC} %{A},%{S},%{SH},%{MB},%{ME}" },

	{ "ori",	0xfc000000, 0x60000000, " %{A},%{S},%{UIMM}" },
	{ "oris",	0xfc000000, 0x64000000, " %{A},%{S},%{UIMM}" },
	{ "xori",	0xfc000000, 0x68000000, " %{A},%{S},%{UIMM}" },
	{ "xoris",	0xfc000000, 0x6c000000, " %{A},%{S},%{UIMM}" },

	{ "andi.",	0xfc000000, 0x70000000, " %{A},%{S},%{UIMM}" },
	{ "andis.",	0xfc000000, 0x74000000, " %{A},%{S},%{UIMM}" },

	{ "lwz",	0xfc000000, 0x80000000, " %{D},%{d}(%{A})" },
	{ "lwzu",	0xfc000000, 0x84000000, " %{D},%{d}(%{A})" },
	{ "lbz",	0xfc000000, 0x88000000, " %{D},%{d}(%{A})" },
	{ "lbzu",	0xfc000000, 0x8c000000, " %{D},%{d}(%{A})" },
	{ "stw",	0xfc000000, 0x90000000, " %{S},%{d}(%{A})" },
	{ "stwu",	0xfc000000, 0x94000000, " %{S},%{d}(%{A})" },
	{ "stb",	0xfc000000, 0x98000000, " %{S},%{d}(%{A})" },
	{ "stbu",	0xfc000000, 0x9c000000, " %{S},%{d}(%{A})" },

	{ "lhz",	0xfc000000, 0xa0000000, " %{D},%{d}(%{A})" },
	{ "lhzu",	0xfc000000, 0xa4000000, " %{D},%{d}(%{A})" },
	{ "lha",	0xfc000000, 0xa8000000, " %{D},%{d}(%{A})" },
	{ "lhau",	0xfc000000, 0xac000000, " %{D},%{d}(%{A})" },
	{ "sth",	0xfc000000, 0xb0000000, " %{S},%{d}(%{A})" },
	{ "sthu",	0xfc000000, 0xb4000000, " %{S},%{d}(%{A})" },
	{ "lmw",	0xfc000000, 0xb8000000, " %{D},%{d}(%{A})" },
	{ "stmw",	0xfc000000, 0xbc000000, " %{S},%{d}(%{A})" },

	{ "lfs",	0xfc000000, 0xc0000000, " %{D},%{d}(%{A})" },
	{ "lfsu",	0xfc000000, 0xc4000000, " %{D},%{d}(%{A})" },
	{ "lfd",	0xfc000000, 0xc8000000, " %{D},%{d}(%{A})" },
	{ "lfdu",	0xfc000000, 0xcc000000, " %{D},%{d}(%{A})" },

	{ "stfs",	0xfc000000, 0xd0000000, " %{S},%{d}(%{A})" },
	{ "stfsu",	0xfc000000, 0xd4000000, " %{S},%{d}(%{A})" },
	{ "stfd",	0xfc000000, 0xd8000000, " %{S},%{d}(%{A})" },
	{ "stfdu",	0xfc000000, 0xdc000000, " %{S},%{d}(%{A})" },
	{ "",		0x0,		0x0, "" }

};

/* 13 * 4 = 4c */
const struct opcode opcodes_13[] = {
/* 0x13 << 2 */
	{ "mcrf",	0xfc0007fe, 0x4c000000, " %{crfD},%{crfS}" },
	{ "b",/*bclr*/	0xfc0007fe, 0x4c000020, "%{BO}lr%{LK} %{BI1}" },
	{ "crnor",	0xfc0007fe, 0x4c000042, " %{crbD},%{crbA},%{crbB}" },
	{ "rfi",	0xfc0007fe, 0x4c000064, "" },
	{ "crandc",	0xfc0007fe, 0x4c000102, " %{crbD},%{crbA},%{crbB}" },
	{ "isync",	0xfc0007fe, 0x4c00012c, "" },
	{ "crxor",	0xfc0007fe, 0x4c000182, " %{crbD},%{crbA},%{crbB}" },
	{ "crnand",	0xfc0007fe, 0x4c0001c2, " %{crbD},%{crbA},%{crbB}" },
	{ "crand",	0xfc0007fe, 0x4c000202, " %{crbD},%{crbA},%{crbB}" },
	{ "creqv",	0xfc0007fe, 0x4c000242, " %{crbD},%{crbA},%{crbB}" },
	{ "crorc",	0xfc0007fe, 0x4c000342, " %{crbD},%{crbA},%{crbB}" },
	{ "cror",	0xfc0007fe, 0x4c000382, " %{crbD},%{crbA},%{crbB}" },
	{ "b"/*bcctr*/,	0xfc0007fe, 0x4c000420, "%{BO}ctr%{LK} %{BI1}" },
	{ "",		0x0,		0x0, "" }
};

/* 1e * 4 = 78 */
const struct opcode opcodes_1e[] = {
	{ "rldicl",	0xfc00001c, 0x78000000, " %{A},%{S},%{sh},%{mb}" },
	{ "rldicr",	0xfc00001c, 0x78000004, " %{A},%{S},%{sh},%{mb}" },
	{ "rldic",	0xfc00001c, 0x78000008, " %{A},%{S},%{sh},%{mb}" },
	{ "rldimi",	0xfc00001c, 0x7800000c, " %{A},%{S},%{sh},%{mb}" },
	{ "rldcl",	0xfc00003e, 0x78000010, " %{A},%{S},%{B},%{mb}" },
	{ "rldcr",	0xfc00003e, 0x78000012, " %{A},%{S},%{B},%{mb}" },
	{ "",		0x0,		0x0, "" }
};

/* 1f * 4 = 7c */
const struct opcode opcodes_1f[] = {
/* 1f << 2 */
	{ "cmpd",	0xfc2007fe, 0x7c200000, " %{crfD}%{A},%{B}" },
	{ "cmpw",	0xfc2007fe, 0x7c000000, " %{crfD}%{A},%{B}" },
	{ "tw",		0xfc0007fe, 0x7c000008, " %{TO},%{A},%{B}" },
	{ "subfc",	0xfc0003fe, 0x7c000010, "%{OE}%{RC} %{D},%{A},%{B}" },
	{ "mulhdu",	0xfc0007fe, 0x7c000012, "%{RC} %{D},%{A},%{B}" },
	{ "addc",	0xfc0003fe, 0x7c000014, "%{OE}%{RC} %{D},%{A},%{B}" },
	{ "mulhwu",	0xfc0007fe, 0x7c000016, "%{RC} %{D},%{A},%{B}" },

	{ "mfcr",	0xfc0007fe, 0x7c000026, " %{D}" },
	{ "lwarx",	0xfc0007fe, 0x7c000028, " %{D},%{A0}%{B}" },
	{ "ldx",	0xfc0007fe, 0x7c00002a, " %{D},%{A0}%{B}" },
	{ "lwzx",	0xfc0007fe, 0x7c00002e, " %{D},%{A0}%{B}" },
	{ "slw",	0xfc0007fe, 0x7c000030, "%{RC} %{A},%{S},%{B}" },
	{ "cntlzw",	0xfc0007fe, 0x7c000034, "%{RC} %{A},%{S}" },
	{ "sld",	0xfc0007fe, 0x7c000036, "%{RC} %{A},%{S},%{B}" },
	{ "and",	0xfc0007fe, 0x7c000038, "%{RC} %{A},%{S},%{B}" },
	{ "cmpld",	0xfc2007fe, 0x7c200040, " %{crfD}%{A},%{B}" },
	{ "cmplw",	0xfc2007fe, 0x7c000040, " %{crfD}%{A},%{B}" },
	{ "subf",	0xfc0003fe, 0x7c000050, "%{OE}%{RC} %{D},%{A},%{B}" },
	{ "ldux",	0xfc0007fe, 0x7c00006a, " %{D},%{A},%{B}" },
	{ "dcbst",	0xfc0007fe, 0x7c00006c, " %{A0}%{B}" },
	{ "lwzux",	0xfc0007fe, 0x7c00006e, " %{D},%{A},%{B}" },
	{ "cntlzd",	0xfc0007fe, 0x7c000074, "%{RC} %{A},%{S}" },
	{ "andc",	0xfc0007fe, 0x7c000078, "%{RC} %{A},%{S},%{B}" },
	{ "td",		0xfc0007fe, 0x7c000088, " %{TO},%{A},%{B}" },
	{ "mulhd",	0xfc0007fe, 0x7c000092, "%{RC} %{D},%{A},%{B}" },
	{ "mulhw",	0xfc0007fe, 0x7c000096, "%{RC} %{D},%{A},%{B}" },
	{ "mfmsr",	0xfc0007fe, 0x7c0000a6, " %{D}" },
	{ "ldarx",	0xfc0007fe, 0x7c0000a8, " %{D},%{A0}%{B}" },
	{ "dcbf",	0xfc0007fe, 0x7c0000ac, " %{A0}%{B}" },
	{ "lbzx",	0xfc0007fe, 0x7c0000ae, " %{D},%{A0}%{B}" },
	{ "neg",	0xfc0003fe, 0x7c0000d0, "%{OE}%{RC} %{D},%{A}" },
	{ "lbzux",	0xfc0007fe, 0x7c0000ee, " %{D},%{A},%{B}" },
	{ "nor",	0xfc0007fe, 0x7c0000f8, "%{RC} %{A},%{S}" },
	{ "subfe",	0xfc0003fe, 0x7c000110, "%{OE}%{RC} %{D},%{A}" },
	{ "adde",	0xfc0003fe, 0x7c000114, "%{OE}%{RC} %{D},%{A}" },
	{ "mtcrf",	0xfc0007fe, 0x7c000120, " %{S},%{CRM}" },
	{ "mtmsr",	0xfc0007fe, 0x7c000124, " %{S}" },
	{ "stdx",	0xfc0007fe, 0x7c00012a, " %{S},%{A0}%{B}" },
	{ "stwcx.",	0xfc0007ff, 0x7c00012d, " %{S},%{A},%{B}" },
	{ "stwx",	0xfc0007fe, 0x7c00012e, " %{S},%{A},%{B}" },
	{ "stdux",	0xfc0007fe, 0x7c00016a, " %{S},%{A},%{B}" },
	{ "stwux",	0xfc0007fe, 0x7c00016e, " %{S},%{A},%{B}" },
	{ "subfze",	0xfc0003fe, 0x7c000190, "%{OE}%{RC} %{D},%{A}" },
	{ "addze",	0xfc0003fe, 0x7c000194, "%{OE}%{RC} %{D},%{A}" },
	{ "mtsr",	0xfc0007fe, 0x7c0001a4, " %{SR},%{S}" },
	{ "stdcx.",	0xfc0007ff, 0x7c0001ad, " %{S},%{A0}%{B}" },
	{ "stbx",	0xfc0007fe, 0x7c0001ae, " %{S},%{A0}%{B}" },
	{ "subfme",	0xfc0003fe, 0x7c0001d0, "%{OE}%{RC} %{D},%{A}" },
	{ "mulld",	0xfc0003fe, 0x7c0001d2, "%{OE}%{RC} %{D},%{A},%{B}" },
	{ "addme",	0xfc0003fe, 0x7c0001d4, "%{OE}%{RC} %{D},%{A}" },
	{ "mullw",	0xfc0003fe, 0x7c0001d6, "%{OE}%{RC} %{D},%{A},%{B}" },
	{ "mtsrin",	0xfc0007fe, 0x7c0001e4, " %{S},%{B}" },
	{ "dcbtst",	0xfc0007fe, 0x7c0001ec, " %{A0}%{B}" },
	{ "stbux",	0xfc0007fe, 0x7c0001ee, " %{S},%{A},%{B}" },
	{ "add",	0xfc0003fe, 0x7c000214, "" },
	{ "dcbt",	0xfc0007fe, 0x7c00022c, " %{A0}%{B}" },
	{ "lhzx",	0xfc0007ff, 0x7c00022e, " %{D},%{A0}%{B}" },
	{ "eqv",	0xfc0007fe, 0x7c000238, "%{RC} %{A},%{S},%{B}" },
	{ "tlbie",	0xfc0007fe, 0x7c000264, " %{B}" },
	{ "eciwx",	0xfc0007fe, 0x7c00026c, " %{D},%{A0}%{B}" },
	{ "lhzux",	0xfc0007fe, 0x7c00026e, " %{D},%{A},%{B}" },
	{ "xor",	0xfc0007fe, 0x7c000278, "%{RC} %{A},%{S},%{B}" },
	{ "mfspr",	0xfc0007fe, 0x7c0002a6, " %{D},%{spr}" },
	{ "lwax",	0xfc0007fe, 0x7c0002aa, " %{D},%{A0}%{B}" },
	{ "lhax",	0xfc0007fe, 0x7c0002ae, " %{D},%{A},%{B}" },
	{ "tlbia",	0xfc0007fe, 0x7c0002e4, "" },
	{ "mftb",	0xfc0007fe, 0x7c0002e6, " %{D},%{tbr}" },
	{ "lwaux",	0xfc0007fe, 0x7c0002ea, " %{D},%{A},%{B}" },
	{ "lhaux",	0xfc0007fe, 0x7c0002ee, " %{D},%{A},%{B}" },
	{ "sthx",	0xfc0007fe, 0x7c00032e, " %{S},%{A0}%{B}" },
	{ "orc",	0xfc0007fe, 0x7c000338, "%{RC} %{A},%{S},%{B}" },
	{ "ecowx",	0xfc0007fe, 0x7c00036c, "%{RC} %{S},%{A0}%{B}" },
	{ "slbie",	0xfc0007fc, 0x7c000364, " %{B}" },
	{ "sthux",	0xfc0007fe, 0x7c00036e, " %{S},%{A0}%{B}" },
	{ "or",		0xfc0007fe, 0x7c000378, "%{RC} %{A},%{S},%{B}" },
	{ "divdu",	0xfc0003fe, 0x7c000392, "%{OE}%{RC} %{S},%{A},%{B}" },
	{ "divwu",	0xfc0003fe, 0x7c000396, "%{OE}%{RC} %{S},%{A},%{B}" },
	{ "mtspr",	0xfc0007fe, 0x7c0003a6, " %{spr},%{S}" },
	{ "dcbi",	0xfc0007fe, 0x7c0003ac, " %{A0}%{B}" },
	{ "nand",	0xfc0007fe, 0x7c0003b8, "%{RC} %{A},%{S},%{B}" },
	{ "divd",	0xfc0003fe, 0x7c0003d2, "%{OE}%{RC} %{S},%{A},%{B}" },
	{ "divw",	0xfc0003fe, 0x7c0003d6, "%{OE}%{RC} %{S},%{A},%{B}" },
	{ "slbia",	0xfc0003fe, 0x7c0003e4, "%{OE}%{RC} %{S},%{A},%{B}" },
	{ "mcrxr",	0xfc0007fe, 0x7c000400, "crfD1" },
	{ "lswx",	0xfc0007fe, 0x7c00042a, " %{D},%{A0}%{B}" },
	{ "lwbrx",	0xfc0007fe, 0x7c00042c, " %{D},%{A0}%{B}" },
	{ "lfsx",	0xfc0007fe, 0x7c00042e, " %{D},%{A},%{B}" },
	{ "srw",	0xfc0007fe, 0x7c000430, "%{RC} %{A},%{S},%{B}" },
	{ "srd",	0xfc0007fe, 0x7c000436, "%{RC} %{A},%{S},%{B}" },
	{ "tlbsync",	0xffffffff, 0x7c00046c, "" },
	{ "lfsux",	0xfc0007fe, 0x7c00046e, " %{D},%{A},%{B}" },
	{ "mfsr",	0xfc0007fe, 0x7c0004a6, " %{D},%{SR}" },
	{ "lswi",	0xfc0007fe, 0x7c0004aa, " %{D},%{A},%{NB}" },
	{ "sync",	0xfc0007fe, 0x7c0004ac, "" },
	{ "lfdx",	0xfc0007fe, 0x7c0004ae, " %{D},%{A},%{B}" },
	{ "lfdux",	0xfc0007fe, 0x7c0004ee, " %{D},%{A},%{B}" },
	{ "mfsrin",	0xfc0007fe, 0x7c000526, "" },
	{ "stswx",	0xfc0007fe, 0x7c00052a, " %{S},%{A0}%{B}" },
	{ "stwbrx",	0xfc0007fe, 0x7c00052c, " %{S},%{A0}%{B}" },
	{ "stfsx",	0xfc0007fe, 0x7c00052e, " %{S},%{A0}%{B}" },
	{ "stfsux",	0xfc0007fe, 0x7c00056e, " %{S},%{A},%{B}" },
	{ "stswi",	0xfc0007fe, 0x7c0005aa, "%{S},%{A0}%{NB}" },
	{ "stfdx",	0xfc0007fe, 0x7c0005ae, " %{S},%{A0}%{B}" },
	{ "stfdux",	0xfc0007fe, 0x7c0005ee, " %{S},%{A},%{B}" },
	{ "lhbrx",	0xfc0007fe, 0x7c00062c, " %{D},%{A0}%{B}" },
	{ "sraw",	0xfc0007fe, 0x7c000630, " %{A},%{S},%{B}" },
	{ "srad",	0xfc0007fe, 0x7c000634, "%{RC} %{A},%{S},%{B}" },
	{ "srawi",	0xfc0007fe, 0x7c000670, "%{RC} %{A},%{SH}" },
	{ "sradi",	0xfc0007fc, 0x7c000674, " %{A},%{S},%{sh}" },
	{ "eieio",	0xfc0007fe, 0x7c0006ac, "" }, /* MASK? */
	{ "sthbrx",	0xfc0007fe, 0x7c00072c, " %{S},%{A0}%{B}" },
	{ "extsh",	0xfc0007fe, 0x7c000734, "%{RC} %{A},%{S}" },
	{ "extsb",	0xfc0007fe, 0x7c000774, "%{RC} %{A},%{S}" },
	{ "icbi",	0xfc0007fe, 0x7c0007ac, " %{A0}%{B}" },

	{ "stfiwx",	0xfc0007fe, 0x7c0007ae, " %{S},%{A0}%{B}" },
	{ "extsw",	0xfc0007fe, 0x7c0007b4, "%{RC} %{A},%{S}" },
	{ "dcbz",	0xfc0007fe, 0x7c0007ec, " %{A0}%{B}" },
	{ "",		0x0,		0x0, 0, }
};

/* 3a * 4 = e8 */
const struct opcode opcodes_3a[] = {
	{ "ld",		0xfc000003, 0xe8000000, " %{D},${ds}${A}" },
	{ "ldu",	0xfc000003, 0xe8000001, " %{D},${ds}${A}" },
	{ "lwa",	0xfc000003, 0xe8000002, " %{D},${ds}${A}" },
	{ "",		0x0,		0x0, "" }
};

/* 3b * 4 = ec */
const struct opcode opcodes_3b[] = {
	{ "fdivs",	0xfc00003e, 0xec000024, "%{RC} f%{D},f%{A},f%{B}" },
	{ "fsubs",	0xfc00003e, 0xec000028, "%{RC} f%{D},f%{A},f%{B}" },

	{ "fadds",	0xfc00003e, 0xec00002a, "%{RC} f%{D},f%{A},f%{B}" },
	{ "fsqrts",	0xfc00003e, 0xec00002c, "" },
	{ "fres",	0xfc00003e, 0xec000030, "" },
	{ "fmuls",	0xfc00003e, 0xec000032, "%{RC} f%{D},f%{A},f%{C}" },
	{ "fmsubs",	0xfc00003e, 0xec000038, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
	{ "fmadds",	0xfc00003e, 0xec00003a, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
	{ "fnmsubs",	0xfc00003e, 0xec00003c, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
	{ "fnmadds",	0xfc00003e, 0xec00003e, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
	{ "",		0x0,		0x0, "" }
};

/* 3e * 4 = f8 */
const struct opcode opcodes_3e[] = {
	{ "std",	0xfc000003, 0xf8000000, " %{D},${ds}${A}" },
	{ "stdu",	0xfc000003, 0xf8000001, " %{D},${ds}${A}" },
	{ "",		0x0,		0x0, "" }
};

/* 3f * 4 = fc */
const struct opcode opcodes_3f[] = {
	{ "fcmpu",	0xfc0007fe, 0xfc000000, " %{crfD},f%{A},f%{B}" },
	{ "frsp",	0xfc0007fe, 0xfc000018, "%{RC} f%{D},f%{B}" },
	{ "fctiw",	0xfc0007fe, 0xfc00001c, "%{RC} f%{D},f%{B}" },
	{ "fctiwz",	0xfc0007fe, 0xfc00001e, "%{RC} f%{D},f%{B}" },

	{ "fdiv",	0xfc00003e, 0xfc000024, "%{RC} f%{D},f%{A},f%{B}" },
	{ "fsub",	0xfc00003e, 0xfc000028, "%{RC} f%{D},f%{A},f%{B}" },
	{ "fadd",	0xfc00003e, 0xfc00002a, "%{RC} f%{D},f%{A},f%{B}" },
	{ "fsqrt",	0xfc00003e, 0xfc00002c, "%{RC} f%{D},f%{B}" },
	{ "fsel",	0xfc00003e, 0xfc00002e, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
	{ "fmul",	0xfc00003e, 0xfc000032, "%{RC} f%{D},f%{A},f%{C}" },
	{ "frsqrte",	0xfc00003e, 0xfc000034, "%{RC} f%{D},f%{B}" },
	{ "fmsub",	0xfc00003e, 0xfc000038, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
	{ "fmadd",	0xfc00003e, 0xfc00003a, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
	{ "fnmsub",	0xfc00003e, 0xfc00003c, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
	{ "fnmadd",	0xfc00003e, 0xfc00003e, "%{RC} f%{D},f%{A},f%{C},f%{B}" },

	{ "fcmpo",	0xfc0007fe, 0xfc000040, "%{RC} f%{D},f%{A},f%{C}" },
	{ "mtfsb1",	0xfc0007fe, 0xfc00004c, "%{RC} f%{D},f%{A},f%{C}" },
	{ "fneg",	0xfc0007fe, 0xfc000050, "%{RC} f%{D},f%{A},f%{C}" },
	{ "mcrfs",	0xfc0007fe, 0xfc000080, "%{RC} f%{D},f%{A},f%{C}" },
	{ "mtfsb0",	0xfc0007fe, 0xfc00008c, "%{RC} %{crfD},f%{C}" },
	{ "fmr",	0xfc0007fe, 0xfc000090, "%{RC} f%{D},f%{B}" },
	{ "mtfsfi",	0xfc0007fe, 0xfc00010c, "%{RC} %{crfD},f%{C},%{IMM}" },

	{ "fnabs",	0xfc0007fe, 0xfc000110, "%{RC} f%{D},f%{B}" },
	{ "fabs",	0xfc0007fe, 0xfc000210, "%{RC} f%{D},f%{B}" },
	{ "mffs",	0xfc0007fe, 0xfc00048e, "%{RC} f%{D},f%{B}" },
	{ "mtfsf",	0xfc0007fe, 0xfc00058e, "%{RC} %{FM},f%{B}" },
	{ "fctid",	0xfc0007fe, 0xfc00065c, "%{RC} f%{D},f%{B}" },
	{ "fctidz",	0xfc0007fe, 0xfc00065e, "%{RC} f%{D},f%{B}" },
	{ "fcfid",	0xfc0007fe, 0xfc00069c, "%{RC} f%{D},f%{B}" },
	{ "",		0x0,		0x0, "" }
};

void
op_ill(u_int32_t addr, instr_t instr)
{
	db_printf("illegal instruction %x\n", instr);
}

/*
 * Extracts bits out of an instruction opcode, base indicates the lsb
 * to keep.
 * Note that this uses the PowerPC bit number for base, MSb == 0
 * because all of the documentation is written that way.
 */
u_int32_t
extract_field(u_int32_t value, u_int32_t base, u_int32_t width)
{
	u_int32_t mask = (1 << width) - 1;
	return ((value >> (31 - base)) & mask);
}

const struct opcode * search_op(const struct opcode *);

char *db_BOBI_cond[] = {
	"ge",
	"le",
	"ne",
	"ns",
	"lt",
	"gt",
	"eq",
	"so"
};
/* what about prediction directions? */
char *db_BO_op[] = {
	"dnzf",
	"dnzf-",
	"dzf",
	"dzf-",
	"",
	"",
	"",
	"",
	"dnzt",
	"dnzt-",
	"dzt",
	"dzt-",
	"",
	"",
	"",
	"",
	"dnz",
	"dnz",
	"dz",
	"dz",
	"",
	"",
	"",
	"",
	"dnz",
	"dnz",
	"dz",
	"dz",
	"",
	"",
	"",
	""
};

char *BItbl[] = {
	"", "gt", "eq", "so"
};

char BO_uses_tbl[32] = {
	/* 0 */ 1,
	/* 1 */ 1,
	/* 2 */ 1,
	/* 3 */ 1,
	/* 4 */ 0,
	/* 5 */ 0,
	/* 6 */ 0, /* invalid */
	/* 7 */ 0, /* invalid */
	/* 8 */ 1,
	/* 9 */ 1,
	/* a */ 1,
	/* b */ 1,
	/* c */ 0,
	/* d */ 0,
	/* e */ 0, /* invalid */
	/* f */ 1,
	/* 10 */        1,
	/* 11 */        1,
	/* 12 */        1,
	/* 13 */        1,
	/* 14 */        1,
	/* 15 */        0, /* invalid */
	/* 16 */        0, /* invalid */
	/* 17 */        0, /* invalid */
	/* 18 */        0, /* invalid */
	/* 19 */        0, /* invalid */
	/* 1a */        0, /* invalid */
	/* 1b */        0, /* invalid */
	/* 1c */        0, /* invalid */
	/* 1d */        0, /* invalid */
	/* 1e */        0, /* invalid */
	/* 1f */        0, /* invalid */
};

void
disasm_process_field(u_int32_t addr, instr_t instr, char **ppfmt,
    char *disasm_buf, size_t bufsize)
{
	char field [8];
	char lbuf[50];
	int i;
	char *pfmt = *ppfmt;
	enum opf opf;
	char *name;
	db_expr_t offset;

	/* find field */
	if (pfmt[0] != '%' || pfmt[1] != '{') {
		printf("error in disasm fmt [%s]\n", pfmt);
	}
	pfmt = &pfmt[2];
	for (i = 0;
	    pfmt[i] != '\0' && pfmt[i] != '}' && i < sizeof(field);
	    i++) {
		field[i] = pfmt[i];
	}
	if (i == sizeof(field)) {
		printf("error in disasm fmt [%s]\n", pfmt);
		return;
	}
	field[i] = 0;
	if (pfmt[i] == '\0') {
		/* match following close paren { */
		printf("disasm_process_field: missing } in [%s]\n", pfmt);
	}
	*ppfmt = &pfmt[i+1];
	opf = Opf_INVALID;
	for (i = 0; db_fields[i].name != NULL; i++) {
		if (strcmp(db_fields[i].name, field) == 0) {
			opf = db_fields[i].opf;
			break;
		}
	}
	switch (opf) {
	case Opf_INVALID:
		{
			printf("unable to find variable [%s]\n", field);
		}
	case Opf_A:
		{
			u_int A;
			A = extract_field(instr, 15, 5);
			snprintf(lbuf, sizeof (lbuf), "r%d", A);
			strlcat (disasm_buf, lbuf, bufsize);
		}
		break;
	case Opf_A0:
		{
			u_int A;
			A = extract_field(instr, 15, 5);
			if (A != 0) {
				snprintf(lbuf, sizeof (lbuf), "r%d,", A);
				strlcat (disasm_buf, lbuf, bufsize);
			}
		}
		break;
	case Opf_AA:
		if (instr & 0x2) {
			strlcat (disasm_buf, "a", bufsize);
		}
		break;
	case Opf_LI:
		{
			u_int LI;
			LI = extract_field(instr, 29, 24);
			LI = LI << 2;
			if (LI & 0x02000000) {
				LI |= ~0x03ffffff;
			}
			if ((instr & (1 << 1)) == 0) {
				/* CHECK AA bit */
				LI = addr + LI;
			}
			db_find_sym_and_offset(LI, &name, &offset);
			if (name) {
				if (offset == 0) {
					snprintf(lbuf, sizeof (lbuf),
					    "0x%x (%s)", LI, name);
					strlcat (disasm_buf, lbuf, bufsize);
				} else {
					snprintf(lbuf, sizeof (lbuf),
					    "0x%x (%s+0x%lx)", LI, name,
					    offset);
					strlcat (disasm_buf, lbuf, bufsize);
				}
			} else {
				snprintf(lbuf, sizeof (lbuf), "0x%x", LI);
				strlcat (disasm_buf, lbuf, bufsize);
			}
		}
		break;
	case Opf_B:
		{
			u_int B;
			B = extract_field(instr, 20, 5);
			snprintf(lbuf, sizeof (lbuf), "r%d", B);
			strlcat (disasm_buf, lbuf, bufsize);
		}
		break;
	case Opf_BD:
		{
			u_int BD;
			BD = extract_field(instr, 29, 14);
			BD = BD << 2;
			if (BD & 0x00008000) {
				BD &= ~0x00007fff;
			}
			if ((instr & (1 << 1)) == 0) {
				/* CHECK AA bit */
				BD = addr + BD;
			}
			db_find_sym_and_offset(BD, &name, &offset);
			if (name) {
				if (offset == 0) {
					snprintf(lbuf, sizeof (lbuf),
					    "0x%x (%s)", BD, name);
					strlcat (disasm_buf, lbuf, bufsize);
				} else {
					snprintf(lbuf, sizeof (lbuf),
					    "0x%x (%s+0x%lx)", BD, name, offset);
					strlcat (disasm_buf, lbuf, bufsize);
				}
			} else {
				snprintf(lbuf, sizeof (lbuf), "0x%x", BD);
				strlcat (disasm_buf, lbuf, bufsize);
			}
		}
		break;
	case Opf_BI1:
	case Opf_BI:
		{
			int BO, BI, cr, printcomma = 0;
			BO = extract_field(instr, 10, 5);
			BI = extract_field(instr, 15, 5);
			cr =  (BI >> 2) & 7;
			if (cr != 0) {
				snprintf(lbuf, sizeof (lbuf), "cr%d", cr);
				strlcat (disasm_buf, lbuf, bufsize);
				printcomma = 1;
			}
			if (BO_uses_tbl[BO]) {
				if ((cr != 0) && ((BI & 3) != 0) &&
				    BO_uses_tbl[BO] != 0)
					strlcat (disasm_buf, "+", bufsize);

				snprintf(lbuf, sizeof (lbuf), "%s",
				    BItbl[BI & 3]);
				strlcat (disasm_buf, lbuf, bufsize);
				printcomma = 1;
			}
			if ((opf == Opf_BI) && printcomma)
				strlcat (disasm_buf, ",", bufsize);
		}
		break;
	case Opf_BO:
		{
			int BO, BI;
			BO = extract_field(instr, 10, 5);
			strlcat (disasm_buf, db_BO_op[BO], bufsize);
			if ((BO & 4) != 0) {
				BI = extract_field(instr, 15, 5);
				strlcat (disasm_buf,
				    db_BOBI_cond[(BI & 0x3)| (((BO & 8) >> 1))],
				    bufsize);

				if (BO & 1)
					strlcat (disasm_buf, "-", bufsize);
			}
		}
		break;
	case Opf_C:
		{
			u_int C;
			C = extract_field(instr, 25, 5);
			snprintf(lbuf, sizeof (lbuf), "r%d, ", C);
			strlcat (disasm_buf, lbuf, bufsize);
		}
		break;
	case Opf_CRM:
		{
			u_int CRM;
			CRM = extract_field(instr, 19, 8);
			snprintf(lbuf, sizeof (lbuf), "0x%x", CRM);
			strlcat (disasm_buf, lbuf, bufsize);
		}
		break;
	case Opf_FM:
		{
			u_int FM;
			FM = extract_field(instr, 10, 8);
			snprintf(lbuf, sizeof (lbuf), "%d", FM);
			strlcat (disasm_buf, lbuf, bufsize);
		}
		break;
	case Opf_LK:
		if (instr & 0x1) {
			strlcat (disasm_buf, "l", bufsize);
		}
		break;
	case Opf_MB:
		{
			u_int MB;
			MB = extract_field(instr, 20, 5);
			snprintf(lbuf, sizeof (lbuf), "%d", MB);
			strlcat (disasm_buf, lbuf, bufsize);
		}
		break;
	case Opf_ME:
		{
			u_int ME;
			ME = extract_field(instr, 25, 5);
			snprintf(lbuf, sizeof (lbuf), "%d", ME);
			strlcat (disasm_buf, lbuf, bufsize);
		}
		break;
	case Opf_NB:
		{
			u_int NB;
			NB = extract_field(instr, 20, 5);
			if (NB == 0 ) {
				NB=32;
			}
			snprintf(lbuf, sizeof (lbuf), "%d", NB);
			strlcat (disasm_buf, lbuf, bufsize);
		}
		break;
	case Opf_OE:
		if (instr & (1 << (31-21))) {
			strlcat (disasm_buf, "o", bufsize);
		}
		break;
	case Opf_RC:
		if (instr & 0x1) {
			strlcat (disasm_buf, ".", bufsize);
		}
		break;
	case Opf_S:
	case Opf_D:
		{
			u_int D;
			/* S and D are the same */
			D = extract_field(instr, 10, 5);
			snprintf(lbuf, sizeof (lbuf), "r%d", D);
			strlcat (disasm_buf, lbuf, bufsize);
		}
		break;
	case Opf_SH:
		{
			u_int SH;
			SH = extract_field(instr, 20, 5);
			snprintf(lbuf, sizeof (lbuf), "%d", SH);
			strlcat (disasm_buf, lbuf, bufsize);
		}
		break;
	case Opf_SIMM:
	case Opf_d:
		{
			int32_t IMM;
			IMM = extract_field(instr, 31, 16);
			if (IMM & 0x8000)
				IMM |= ~0x7fff;
			snprintf(lbuf, sizeof (lbuf), "%d", IMM);
			strlcat (disasm_buf, lbuf, bufsize);
		}
		break;
	case Opf_UIMM:
		{
			u_int32_t IMM;
			IMM = extract_field(instr, 31, 16);
			snprintf(lbuf, sizeof (lbuf), "0x%x", IMM);
			strlcat (disasm_buf, lbuf, bufsize);
		}
		break;
	case Opf_SR:
		{
			u_int SR;
			SR = extract_field(instr, 15, 3);
			snprintf(lbuf, sizeof (lbuf), "sr%d", SR);
			strlcat (disasm_buf, lbuf, bufsize);
		}
		break;
	case Opf_TO:
		{
			u_int TO;
			TO = extract_field(instr, 10, 1);
			snprintf(lbuf, sizeof (lbuf), "%d", TO);
			strlcat (disasm_buf, lbuf, bufsize);
		}
		break;
	case Opf_crbA:
		{
			u_int crbA;
			crbA = extract_field(instr, 15, 5);
			snprintf(lbuf, sizeof (lbuf), "%d", crbA);
			strlcat (disasm_buf, lbuf, bufsize);
		}
		break;
	case Opf_crbB:
		{
			u_int crbB;
			crbB = extract_field(instr, 20, 5);
			snprintf(lbuf, sizeof (lbuf), "%d", crbB);
			strlcat (disasm_buf, lbuf, bufsize);
		}
		break;
	case Opf_crbD:
		{
			u_int crfD;
			crfD = extract_field(instr, 8, 3);
			snprintf(lbuf, sizeof (lbuf), "crf%d", crfD);
			strlcat (disasm_buf, lbuf, bufsize);
		}
		break;
	case Opf_crfD:
		{
			u_int crfD;
			crfD = extract_field(instr, 8, 3);
			snprintf(lbuf, sizeof (lbuf), "crf%d", crfD);
			strlcat (disasm_buf, lbuf, bufsize);
		}
		break;
	case Opf_crfS:
		{
			u_int crfS;
			crfS = extract_field(instr, 13, 3);
			snprintf(lbuf, sizeof (lbuf), "%d", crfS);
			strlcat (disasm_buf, lbuf, bufsize);
		}
		break;
	case Opf_mb:
		{
			u_int mb, mbl, mbh;
			mbl = extract_field(instr, 25, 4);
			mbh = extract_field(instr, 26, 1);
			mb = mbh << 4 | mbl;
			snprintf(lbuf, sizeof (lbuf), ", %d", mb);
			strlcat (disasm_buf, lbuf, bufsize);
		}
		break;
	case Opf_sh:
		{
			u_int sh, shl, shh;
			shl = extract_field(instr, 19, 4);
			shh = extract_field(instr, 20, 1);
			sh = shh << 4 | shl;
			snprintf(lbuf, sizeof (lbuf), ", %d", sh);
			strlcat (disasm_buf, lbuf, bufsize);
		}
		break;
	case Opf_spr:
		{
			u_int spr;
			u_int sprl;
			u_int sprh;
			char *reg;
			sprl = extract_field(instr, 15, 5);
			sprh = extract_field(instr, 20, 5);
			spr = sprh << 5 | sprl;

			/* this table could be written better */
			switch (spr) {
			case	1:
				reg = "xer";
				break;
			case	8:
				reg = "lr";
				break;
			case	9:
				reg = "ctr";
				break;
			case	18:
				reg = "dsisr";
				break;
			case	19:
				reg = "dar";
				break;
			case	22:
				reg = "dec";
				break;
			case	25:
				reg = "sdr1";
				break;
			case	26:
				reg = "srr0";
				break;
			case	27:
				reg = "srr1";
				break;
			case	272:
				reg = "SPRG0";
				break;
			case	273:
				reg = "SPRG1";
				break;
			case	274:
				reg = "SPRG3";
				break;
			case	275:
				reg = "SPRG3";
				break;
			case	280:
				reg = "asr";
				break;
			case	282:
				reg = "aer";
				break;
			case	287:
				reg = "pvr";
				break;
			case	528:
				reg = "ibat0u";
				break;
			case	529:
				reg = "ibat0l";
				break;
			case	530:
				reg = "ibat1u";
				break;
			case	531:
				reg = "ibat1l";
				break;
			case	532:
				reg = "ibat2u";
				break;
			case	533:
				reg = "ibat2l";
				break;
			case	534:
				reg = "ibat3u";
				break;
			case	535:
				reg = "ibat3l";
				break;
			case	536:
				reg = "dbat0u";
				break;
			case	537:
				reg = "dbat0l";
				break;
			case	538:
				reg = "dbat1u";
				break;
			case	539:
				reg = "dbat1l";
				break;
			case	540:
				reg = "dbat2u";
				break;
			case	541:
				reg = "dbat2l";
				break;
			case	542:
				reg = "dbat3u";
				break;
			case	543:
				reg = "dbat3l";
				break;
			case	1013:
				reg = "dabr";
				break;
			default:
				reg = 0;
			}
			if (reg == 0) {
				snprintf(lbuf, sizeof (lbuf), "spr%d", spr);
				strlcat (disasm_buf, lbuf, bufsize);
			} else {
				snprintf(lbuf, sizeof (lbuf), "%s", reg);
				strlcat (disasm_buf, lbuf, bufsize);
			}
		}
		break;
	case Opf_tbr:
		{
			u_int tbr;
			u_int tbrl;
			u_int tbrh;
			char *reg = NULL;
			tbrl = extract_field(instr, 15, 5);
			tbrh = extract_field(instr, 20, 5);
			tbr = tbrh << 5 | tbrl;

			switch (tbr) {
			case 268:
				reg = "tbl";
				break;
			case 269:
				reg = "tbu";
				break;
			default:
				reg = 0;
			}
			if (reg == NULL) {
				snprintf(lbuf, sizeof (lbuf), "tbr%d", tbr);
				strlcat (disasm_buf, lbuf, bufsize);
			} else {
				snprintf(lbuf, sizeof (lbuf), "%s", reg);
				strlcat (disasm_buf, lbuf, bufsize);
			}
		}
		break;
	}
}

void
disasm_fields(u_int32_t addr, const struct opcode *popcode, instr_t instr,
    char *disasm_str, size_t bufsize)
{
	char *pfmt;
	char cbuf[2];
	if (popcode->decode_str == NULL || popcode->decode_str[0] == '0') {
		return;
	}
	pfmt = popcode->decode_str;
	disasm_str[0] = '\0';

	while (*pfmt != '\0')  {
		if (*pfmt == '%') {
			disasm_process_field(addr, instr, &pfmt, disasm_str,
			    bufsize);
		} else {
			cbuf[0] = *pfmt;
			cbuf[1] = '\0';
			strlcat(disasm_str, cbuf, bufsize);
			pfmt++;
		}
	}
}

void
op_base(u_int32_t addr, instr_t instr)
{
	dis_ppc(addr, opcodes, instr);
}

void
op_cl_x13(u_int32_t addr, instr_t instr)
{
	dis_ppc(addr, opcodes_13, instr);
}

void
op_cl_x1e(u_int32_t addr, instr_t instr)
{
	dis_ppc(addr, opcodes_1e, instr);
}

void
op_cl_x1f(u_int32_t addr, instr_t instr)
{
	dis_ppc(addr, opcodes_1f, instr);
}

void
op_cl_x3a(u_int32_t addr, instr_t instr)
{
	dis_ppc(addr, opcodes_3a, instr);
}

void
op_cl_x3b(u_int32_t addr, instr_t instr)
{
	dis_ppc(addr, opcodes_3b, instr);
}

void
op_cl_x3e(u_int32_t addr, instr_t instr)
{
	dis_ppc(addr, opcodes_3e, instr);
}

void
op_cl_x3f(u_int32_t addr, instr_t instr)
{
	dis_ppc(addr, opcodes_3f, instr);
}

void
dis_ppc(u_int32_t addr, const struct opcode *opcodeset, instr_t instr)
{
	const struct opcode *op;
	int i;
	char disasm_str[80];

	for (i=0; opcodeset[i].mask != 0; i++) {
		op = &opcodeset[i];
		if ((instr & op->mask) == op->code) {
			disasm_fields(addr, op, instr, disasm_str,
			    sizeof disasm_str);
			db_printf("%s%s\n", op->name, disasm_str);
			return;
		}
	}
	op_ill(addr, instr);
}

db_addr_t
db_disasm(db_addr_t loc, boolean_t extended)
{
	int class;
	instr_t opcode;
	opcode = *(instr_t *)(loc);
	class = opcode >> 26;
	(opcodes_base[class])(loc, opcode);

	return loc + 4;
}


code:
/*	$NetBSD: db_memrw.c,v 1.4 2001/05/18 20:38:27 matt Exp $	*/
/*	$OpenBSD: db_memrw.c,v 1.5 2003/10/15 01:06:13 drahn Exp $	*/

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

/*
 * Interface to the debugger for virtual memory read/write.
 * This is a simple version for kernels with writable text.
 * For an example of read-only kernel text, see the file:
 * sys/arch/sun3/sun3/db_memrw.c
 *
 * ALERT!  If you want to access device registers with a
 * specific size, then the read/write functions have to
 * make sure to do the correct sized pointer access.
 */

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

#include <uvm/uvm_extern.h>

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

#include <ddb/db_access.h>

/*
 * Read bytes from kernel address space for debugger.
 */
void
db_read_bytes(addr, size, data)
	vaddr_t		addr;
	size_t	size;
	char	*data;
{
	char	*src = (char *)addr;
	faultbuf env;
	faultbuf *old_onfault = curpcb->pcb_onfault;
	if (setfault(&env)) {
		curpcb->pcb_onfault = old_onfault;
		return;
	}

	if (size == 4) {
		*((int *)data) = *((int *)src);
	} else if (size == 2) {
		*((short *)data) = *((short *)src);
	} else {
		while (size > 0) {
			--size;
			*data++ = *src++;
		}
	}
	curpcb->pcb_onfault = old_onfault;
}

/*
 * Write bytes to kernel address space for debugger.
 */
void
db_write_bytes(addr, size, data)
	vaddr_t		addr;
	size_t	size;
	char	*data;
{
	char	*dst = (char *)addr;
	faultbuf env;
	faultbuf *old_onfault = curpcb->pcb_onfault;

	if (setfault(&env)) {
		curpcb->pcb_onfault = old_onfault;
		return;
	}

	if (size == 4) {
		*((int *)dst) = *((int *)data);
	} else if (size == 2) {
		*((short *)dst) = *((short *)data);
	} else  {
		while (size > 0) {
			--size;
			*dst++ = *data++;
		}
	}
	syncicache((void *)addr, size);
	curpcb->pcb_onfault = old_onfault;
}


code:
/*	$OpenBSD: db_trace.c,v 1.6 2014/09/06 09:42:23 mpi Exp $	*/
/*	$NetBSD: db_trace.c,v 1.15 1996/02/22 23:23:41 gwr Exp $	*/

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

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

#include <uvm/uvm_extern.h>

#include <machine/db_machdep.h>
#include <machine/signal.h>
#include <machine/pcb.h>
#include <machine/pmap.h>

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

db_regs_t ddb_regs;

struct db_variable db_regs[] = {
	{ "r0",  (long *)&(DDB_REGS->tf.fixreg[0]),	FCN_NULL },
	{ "r1",  (long *)&(DDB_REGS->tf.fixreg[1]),	FCN_NULL },
	{ "r2",  (long *)&(DDB_REGS->tf.fixreg[2]),	FCN_NULL },
	{ "r3",  (long *)&(DDB_REGS->tf.fixreg[3]),	FCN_NULL },
	{ "r4",  (long *)&(DDB_REGS->tf.fixreg[4]),	FCN_NULL },
	{ "r5",  (long *)&(DDB_REGS->tf.fixreg[5]),	FCN_NULL },
	{ "r6",  (long *)&(DDB_REGS->tf.fixreg[6]),	FCN_NULL },
	{ "r7",  (long *)&(DDB_REGS->tf.fixreg[7]),	FCN_NULL },
	{ "r8",  (long *)&(DDB_REGS->tf.fixreg[8]),	FCN_NULL },
	{ "r9",  (long *)&(DDB_REGS->tf.fixreg[9]),	FCN_NULL },
	{ "r10", (long *)&(DDB_REGS->tf.fixreg[10]),	FCN_NULL },
	{ "r11", (long *)&(DDB_REGS->tf.fixreg[11]),	FCN_NULL },
	{ "r12", (long *)&(DDB_REGS->tf.fixreg[12]),	FCN_NULL },
	{ "r13", (long *)&(DDB_REGS->tf.fixreg[13]),	FCN_NULL },
	{ "r14", (long *)&(DDB_REGS->tf.fixreg[13]),	FCN_NULL },
	{ "r15", (long *)&(DDB_REGS->tf.fixreg[13]),	FCN_NULL },
	{ "r16", (long *)&(DDB_REGS->tf.fixreg[13]),	FCN_NULL },
	{ "r17", (long *)&(DDB_REGS->tf.fixreg[17]),	FCN_NULL },
	{ "r18", (long *)&(DDB_REGS->tf.fixreg[18]),	FCN_NULL },
	{ "r19", (long *)&(DDB_REGS->tf.fixreg[19]),	FCN_NULL },
	{ "r20", (long *)&(DDB_REGS->tf.fixreg[20]),	FCN_NULL },
	{ "r21", (long *)&(DDB_REGS->tf.fixreg[21]),	FCN_NULL },
	{ "r22", (long *)&(DDB_REGS->tf.fixreg[22]),	FCN_NULL },
	{ "r23", (long *)&(DDB_REGS->tf.fixreg[23]),	FCN_NULL },
	{ "r24", (long *)&(DDB_REGS->tf.fixreg[24]),	FCN_NULL },
	{ "r25", (long *)&(DDB_REGS->tf.fixreg[25]),	FCN_NULL },
	{ "r26", (long *)&(DDB_REGS->tf.fixreg[26]),	FCN_NULL },
	{ "r27", (long *)&(DDB_REGS->tf.fixreg[27]),	FCN_NULL },
	{ "r28", (long *)&(DDB_REGS->tf.fixreg[28]),	FCN_NULL },
	{ "r29", (long *)&(DDB_REGS->tf.fixreg[29]),	FCN_NULL },
	{ "r30", (long *)&(DDB_REGS->tf.fixreg[30]),	FCN_NULL },
	{ "r31", (long *)&(DDB_REGS->tf.fixreg[31]),	FCN_NULL },
	{ "lr", (long *)&(DDB_REGS->tf.lr),	FCN_NULL },
	{ "cr", (long *)&(DDB_REGS->tf.cr),	FCN_NULL },
	{ "xer", (long *)&(DDB_REGS->tf.xer),	FCN_NULL },
	{ "ctr", (long *)&(DDB_REGS->tf.ctr),	FCN_NULL },
	{ "iar", (long *)&(DDB_REGS->tf.srr0),	FCN_NULL },
	{ "msr", (long *)&(DDB_REGS->tf.srr1),	FCN_NULL },
};

struct db_variable *db_eregs = db_regs + nitems(db_regs);

/*
 * this is probably hackery.
 */
void
db_save_regs(struct trapframe *frame)
{
	bcopy(frame, &(ddb_regs.tf), sizeof (struct trapframe));
}

/* from locore.S */
extern db_addr_t trapexit;
extern db_addr_t esym;
#define	INTSTK		(8*1024)	/* 8K interrupt stack */

#define	INKERNEL(va)	(((vaddr_t)(va)) >= VM_MIN_KERNEL_ADDRESS &&	\
			((vaddr_t)(va)) < VM_MAX_KERNEL_ADDRESS)

#define	ININTSTK(va)	(((vaddr_t)(va)) >= round_page(esym) &&		\
			((vaddr_t)(va)) < (round_page(esym) + INTSTK))

/*
 *	Frame tracing.
 */
void
db_stack_trace_print(db_expr_t addr, int have_addr, db_expr_t count,
    char *modif, int (*pr)(const char *, ...))
{
	db_addr_t	 lr, sp, lastsp;
	db_expr_t	 offset;
	db_sym_t	 sym;
	char		*name;
	char		 c, *cp = modif;
	int		 trace_proc = 0;

	while ((c = *cp++) != 0) {
		if (c == 'p')
			trace_proc = 1;
	}

	if (!have_addr) {
		sp = ddb_regs.tf.fixreg[1];
		lr = ddb_regs.tf.srr0;
	} else {
		if (trace_proc) {
			struct proc *p = pfind((pid_t)addr);
			if (p == NULL) {
				(*pr) ("db_trace.c: process not found\n");
				return;
			}
			addr = p->p_addr->u_pcb.pcb_sp;
		}
		sp = addr;
		db_read_bytes(sp + 4, sizeof(db_addr_t), (char *)&lr);
	}

	while (count && sp != 0) {
		/*
		 * lr contains the return address, so adjust its value
		 * to display the offset of the calling address.
		 */
		sym = db_search_symbol(lr - 4, DB_STGY_ANY, &offset);
		db_symbol_values(sym, &name, NULL);

		if (name == NULL || strcmp(name, "end") == 0) {
			(*pr)("at 0x%lx", lr - 4);
		} else {
			(*pr)("%s() at ", name);
			db_printsym(lr - 4, DB_STGY_PROC, pr);
		}
		(*pr)("\n");

		lastsp = sp;

		/*
		 * Abuse the fact that the return address of the trap()
		 * function is always 'trapexit'.
		 */
		if (lr == (db_addr_t)&trapexit) {
			struct trapframe *tf = (struct trapframe *)(sp + 8);
			uint32_t code = tf->fixreg[0];
			uint32_t type = tf->exc;

			if (tf->srr1 & PSL_PR)
				type |= EXC_USER;

			if (type == (EXC_SC|EXC_USER))
				(*pr)("--- syscall (number %d) ---\n", code);
			else
				(*pr)("--- trap (type 0x%x) ---\n", type);
		}

		db_read_bytes(sp, sizeof(db_addr_t), (char *)&sp);
		if (sp == 0)
			break;

		db_read_bytes(sp + 4, sizeof(db_addr_t), (char *)&lr);

		if (INKERNEL(sp)) {
			if (sp <= lastsp) {
				(*pr)("Bad frame pointer: 0x%lx\n", sp);
				break;
			}

			if (ININTSTK(lastsp))
				(*pr)("--- interrupt ---\n");

		} else  {
			if (!ININTSTK(sp)) {
				(*pr)("End of kernel: 0x%lx\n", sp);
				break;
			}
		}
		--count;
	}
	(*pr)("end trace frame: 0x%lx, count: %d\n", sp, count);
}


path: sys/arch/powerpc/include/CVS/Entries


code: src/sys/arch/powerpc/include

path: sys/arch/powerpc/include/CVS/Repository


code:
/*	$OpenBSD: _float.h,v 1.1 2012/06/26 16:12:44 deraadt Exp $	*/

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

#ifndef _MACHINE__FLOAT_H_
#define _MACHINE__FLOAT_H_

#define __FLT_RADIX		2		/* b */
#define __FLT_ROUNDS		__flt_rounds()
#define __FLT_EVAL_METHOD	0		/* no promotions */

#define __FLT_MANT_DIG		24		/* p */
#define __FLT_EPSILON		1.19209290E-07F	/* b**(1-p) */
#define __FLT_DIG		6		/* floor((p-1)*log10(b))+(b == 10) */
#define __FLT_MIN_EXP		(-125)		/* emin */
#define __FLT_MIN		1.17549435E-38F	/* b**(emin-1) */
#define __FLT_MIN_10_EXP	(-37)		/* ceil(log10(b**(emin-1))) */
#define __FLT_MAX_EXP		128		/* emax */
#define __FLT_MAX		3.40282347E+38F	/* (1-b**(-p))*b**emax */
#define __FLT_MAX_10_EXP	38		/* floor(log10((1-b**(-p))*b**emax)) */

#define __DBL_MANT_DIG		53
#define __DBL_EPSILON		2.2204460492503131E-16
#define __DBL_DIG		15
#define __DBL_MIN_EXP		(-1021)
#define __DBL_MIN		2.2250738585072014E-308
#define __DBL_MIN_10_EXP	(-307)
#define __DBL_MAX_EXP		1024
#define __DBL_MAX		1.7976931348623157E+308
#define __DBL_MAX_10_EXP	308

#define __LDBL_MANT_DIG		DBL_MANT_DIG
#define __LDBL_EPSILON		DBL_EPSILON
#define __LDBL_DIG		DBL_DIG
#define __LDBL_MIN_EXP		DBL_MIN_EXP
#define __LDBL_MIN		DBL_MIN
#define __LDBL_MIN_10_EXP	DBL_MIN_10_EXP
#define __LDBL_MAX_EXP		DBL_MAX_EXP
#define __LDBL_MAX		DBL_MAX
#define __LDBL_MAX_10_EXP	DBL_MAX_10_EXP

#define __DECIMAL_DIG		17

#endif /* _MACHINE__FLOAT_H_ */


code:
/*	$OpenBSD: _types.h,v 1.21 2015/04/21 01:38:41 guenther Exp $	*/

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

#ifndef _POWERPC__TYPES_H_
#define _POWERPC__TYPES_H_

#if defined(_KERNEL)
typedef struct label_t {
	long val[25];
} label_t;
#endif

/*
 * _ALIGN(p) rounds p (pointer or byte index) up to a correctly-aligned
 * value for all data types (int, long, ...).   The result is an
 * unsigned long and must be cast to any desired pointer type.
 *
 * _ALIGNED_POINTER is a boolean macro that checks whether an address
 * is valid to fetch data elements of type t from on this architecture.
 * This does not reflect the optimal alignment, just the possibility
 * (within reasonable limits).
 */
#define	_ALIGNBYTES		(sizeof(double) - 1)
#define	_STACKALIGNBYTES	15
#define	_ALIGN(p)		(((unsigned long)(p) + _ALIGNBYTES) & ~_ALIGNBYTES)
#define	_ALIGNED_POINTER(p,t)	((((unsigned long)(p)) & (sizeof(t) - 1)) == 0)

/* 7.18.1.1 Exact-width integer types */
typedef	signed char		__int8_t;
typedef	unsigned char		__uint8_t;
typedef	short			__int16_t;
typedef	unsigned short		__uint16_t;
typedef	int			__int32_t;
typedef	unsigned int		__uint32_t;
/* LONGLONG */
typedef	long long		__int64_t;
/* LONGLONG */
typedef	unsigned long long	__uint64_t;

/* 7.18.1.2 Minimum-width integer types */
typedef	__int8_t		__int_least8_t;
typedef	__uint8_t		__uint_least8_t;
typedef	__int16_t		__int_least16_t;
typedef	__uint16_t		__uint_least16_t;
typedef	__int32_t		__int_least32_t;
typedef	__uint32_t		__uint_least32_t;
typedef	__int64_t		__int_least64_t;
typedef	__uint64_t		__uint_least64_t;

/* 7.18.1.3 Fastest minimum-width integer types */
typedef	__int32_t		__int_fast8_t;
typedef	__uint32_t		__uint_fast8_t;
typedef	__int32_t		__int_fast16_t;
typedef	__uint32_t		__uint_fast16_t;
typedef	__int32_t		__int_fast32_t;
typedef	__uint32_t		__uint_fast32_t;
typedef	__int64_t		__int_fast64_t;
typedef	__uint64_t		__uint_fast64_t;
#define	__INT_FAST8_MIN		INT32_MIN
#define	__INT_FAST16_MIN	INT32_MIN
#define	__INT_FAST32_MIN	INT32_MIN
#define	__INT_FAST64_MIN	INT64_MIN
#define	__INT_FAST8_MAX		INT32_MAX
#define	__INT_FAST16_MAX	INT32_MAX
#define	__INT_FAST32_MAX	INT32_MAX
#define	__INT_FAST64_MAX	INT64_MAX
#define	__UINT_FAST8_MAX	UINT32_MAX
#define	__UINT_FAST16_MAX	UINT32_MAX
#define	__UINT_FAST32_MAX	UINT32_MAX
#define	__UINT_FAST64_MAX	UINT64_MAX

/* 7.18.1.4 Integer types capable of holding object pointers */
typedef	long			__intptr_t;
typedef	unsigned long		__uintptr_t;

/* 7.18.1.5 Greatest-width integer types */
typedef	__int64_t		__intmax_t;
typedef	__uint64_t		__uintmax_t;

/* Register size */
typedef long			__register_t;

/* VM system types */
typedef unsigned long		__vaddr_t;
typedef unsigned long		__paddr_t;
typedef unsigned long		__vsize_t;
typedef unsigned long		__psize_t;

/* Standard system types */
typedef double			__double_t;
typedef float			__float_t;
typedef long			__ptrdiff_t;
typedef	unsigned long		__size_t;
typedef	long			__ssize_t;
#if defined(__GNUC__) && __GNUC__ >= 3
typedef	__builtin_va_list	__va_list;
#else
struct __va_list_tag;
typedef	struct __va_list_tag *	__va_list;
#endif

/* Wide character support types */
#ifndef __cplusplus
typedef	int			__wchar_t;
#endif
typedef int			__wint_t;
typedef	int			__rune_t;
typedef	void *			__wctrans_t;
typedef	void *			__wctype_t;

#endif	/* _POWERPC__TYPES_H_ */


code:
/*	$OpenBSD: asm.h,v 1.11 2013/10/17 15:58:23 deraadt Exp $	*/
/*	$NetBSD: asm.h,v 1.1 1996/09/30 16:34:20 ws Exp $	*/

/*
 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
 * Copyright (C) 1995, 1996 TooLs GmbH.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by TooLs GmbH.
 * 4. The name of TooLs GmbH may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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 _POWERPC_ASM_H_
#define _POWERPC_ASM_H_

/* XXX */
#define TARGET_ELF

#ifdef __PIC__
#define PIC_PROLOGUE	XXX
#define PIC_EPILOGUE	XXX
#ifdef	__STDC__
#define PIC_PLT(x)	x ## @plt
#define PIC_GOT(x)	XXX
#define PIC_GOTOFF(x)	XXX
#else	/* not __STDC__ */
#define PIC_PLT(x)	x/**/@plt
#define PIC_GOT(x)	XXX
#define PIC_GOTOFF(x)	XXX
#endif	/* __STDC__ */
#else
#define PIC_PROLOGUE
#define PIC_EPILOGUE
#define PIC_PLT(x)	x
#define PIC_GOT(x)	x
#define PIC_GOTOFF(x)	x
#endif

#ifdef TARGET_ELF
# define _C_LABEL(x)	x
#endif
#define	_ASM_LABEL(x)	x

#ifdef __STDC__
# define _TMP_LABEL(x)	.L_ ## x
#else
# define _TMP_LABEL(x)	.L_/**/x
#endif

#define _ENTRY(x) \
	.text; .align 2; .globl x; .type x,@function; x:

#ifdef PROF
# define _PROF_PROLOGUE(y)	\
	.section ".data"; \
	.align 2; \
_TMP_LABEL(y):; \
	.long 0; \
	.section ".text"; \
	mflr 0; \
	addis 11, 11, _TMP_LABEL(y)@ha; \
	stw 0, 4(1); \
	addi 0, 11,_TMP_LABEL(y)@l; \
	bl _mcount;
#else
# define _PROF_PROLOGUE(y)
#endif

#define	ENTRY(y)	_ENTRY(_C_LABEL(y)); _PROF_PROLOGUE(y)
#define	ASENTRY(y)	_ENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE(y)

#define	ASMSTR		.asciz

#define RCSID(x)	.text; .asciz x

#define STRONG_ALIAS(alias,sym) \
	.global alias; .set alias,sym
#define WEAK_ALIAS(alias,sym) \
	.weak alias; .set alias,sym

#endif /* !_POWERPC_ASM_H_ */


code:
/*	$OpenBSD: atomic.h,v 1.10 2015/05/06 03:30:03 dlg Exp $	*/

/*
 * Copyright (c) 2015 Martin Pieuchot
 *
 * 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 _POWERPC_ATOMIC_H_
#define _POWERPC_ATOMIC_H_

#if defined(_KERNEL)

static __inline void
atomic_setbits_int(volatile unsigned int *uip, unsigned int v)
{
	unsigned int tmp;

	__asm volatile (
	    "1:	lwarx	%0, 0, %2	\n"
	    "	or	%0, %1, %0	\n"
	    "	stwcx.	%0, 0, %2	\n"
	    "	bne-	1b		\n"
	    "	sync" : "=&r" (tmp) : "r" (v), "r" (uip) : "cc", "memory");
}

static __inline void
atomic_clearbits_int(volatile unsigned int *uip, unsigned int v)
{
	unsigned int tmp;

	__asm volatile (
	    "1:	lwarx	%0, 0, %2	\n"
	    "	andc	%0, %0, %1	\n"
	    "	stwcx.	%0, 0, %2	\n"
	    "	bne-	1b		\n"
	    "	sync" : "=&r" (tmp) : "r" (v), "r" (uip) : "cc", "memory");
}

static inline unsigned int
_atomic_cas_uint(volatile unsigned int *p, unsigned int o, unsigned int n)
{
	unsigned int rv;

	__asm volatile (
	    "1:	lwarx	%0, 0, %2	\n"
	    "	cmpw	0, %0, %4	\n"
	    "	bne-	2f		\n"
	    "	stwcx.	%3, 0, %2	\n"
	    "	bne-	1b		\n"
	    "2:				\n"
	    : "=&r" (rv), "+m" (*p)
	    : "r" (p), "r" (n), "r" (o)
	    : "cc");

	return (rv);
}
#define atomic_cas_uint(_p, _o, _n) _atomic_cas_uint((_p), (_o), (_n))

static inline unsigned long
_atomic_cas_ulong(volatile unsigned long *p, unsigned long o, unsigned long n)
{
	unsigned long rv;

	__asm volatile (
	    "1:	lwarx	%0, 0, %2	\n"
	    "	cmpw	0, %0, %4	\n"
	    "	bne-	2f		\n"
	    "	stwcx.	%3, 0, %2	\n"
	    "	bne-	1b		\n"
	    "2:				\n"
	    : "=&r" (rv), "+m" (*p)
	    : "r" (p), "r" (n), "r" (o)
	    : "cc");

	return (rv);
}
#define atomic_cas_ulong(_p, _o, _n) _atomic_cas_ulong((_p), (_o), (_n))

static inline void *
_atomic_cas_ptr(volatile void *pp, void *o, void *n)
{
	void * volatile *p = pp;
	void *rv;

	__asm volatile (
	    "1:	lwarx	%0, 0, %2	\n"
	    "	cmpw	0, %0, %4	\n"
	    "	bne-	2f		\n"
	    "	stwcx.	%3, 0, %2	\n"
	    "	bne-	1b		\n"
	    "2:				\n"
	    : "=&r" (rv), "+m" (*p)
	    : "r" (p), "r" (n), "r" (o)
	    : "cc");

	return (rv);
}
#define atomic_cas_ptr(_p, _o, _n) _atomic_cas_ptr((_p), (_o), (_n))

static inline unsigned int
_atomic_swap_uint(volatile unsigned int *p, unsigned int v)
{
	unsigned int rv;

	__asm volatile (
	    "1:	lwarx	%0, 0, %2	\n"
	    "	stwcx.	%3, 0, %2	\n"
	    "	bne-	1b		\n"
	    : "=&r" (rv), "+m" (*p)
	    : "r" (p), "r" (v)
	    : "cc");

	return (rv);
}
#define atomic_swap_uint(_p, _v) _atomic_swap_uint((_p), (_v))

static inline unsigned long
_atomic_swap_ulong(volatile unsigned long *p, unsigned long v)
{
	unsigned long rv;

	__asm volatile (
	    "1:	lwarx	%0, 0, %2	\n"
	    "	stwcx.	%3, 0, %2	\n"
	    "	bne-	1b		\n"
	    : "=&r" (rv), "+m" (*p)
	    : "r" (p), "r" (v)
	    : "cc");

	return (rv);
}
#define atomic_swap_ulong(_p, _v) _atomic_swap_ulong((_p), (_v))

static inline void *
_atomic_swap_ptr(volatile void *pp, void *v)
{
	void * volatile *p = pp;
	void *rv;

	__asm volatile (
	    "1:	lwarx	%0, 0, %2	\n"
	    "	stwcx.	%3, 0, %2	\n"
	    "	bne-	1b		\n"
	    : "=&r" (rv), "+m" (*p)
	    : "r" (p), "r" (v)
	    : "cc");

	return (rv);
}
#define atomic_swap_ptr(_p, _v) _atomic_swap_ptr((_p), (_v))

static inline unsigned int
_atomic_add_int_nv(volatile unsigned int *p, unsigned int v)
{
	unsigned int rv;

	__asm volatile (
	    "1:	lwarx	%0, 0, %2	\n"
	    "	add	%0, %3,	%0	\n"
	    "	stwcx.	%0, 0, %2	\n"
	    "	bne-	1b		\n"
	    : "=&r" (rv), "+m" (*p)
	    : "r" (p), "r" (v)
	    : "cc", "xer");

	return (rv);
}
#define atomic_add_int_nv(_p, _v) _atomic_add_int_nv((_p), (_v))

static inline unsigned long
_atomic_add_long_nv(volatile unsigned long *p, unsigned long v)
{
	unsigned long rv;

	__asm volatile (
	    "1:	lwarx	%0, 0, %2	\n"
	    "	add	%0, %3,	%0	\n"
	    "	stwcx.	%0, 0, %2	\n"
	    "	bne-	1b		\n"
	    : "=&r" (rv), "+m" (*p)
	    : "r" (p), "r" (v)
	    : "cc", "xer");

	return (rv);
}
#define atomic_add_long_nv(_p, _v) _atomic_add_long_nv((_p), (_v))

static inline unsigned int
_atomic_sub_int_nv(volatile unsigned int *p, unsigned int v)
{
	unsigned int rv;

	__asm volatile (
	    "1:	lwarx	%0, 0, %2	\n"
	    "	subf	%0, %3,	%0	\n"
	    "	stwcx.	%0, 0, %2	\n"
	    "	bne-	1b		\n"
	    : "=&r" (rv), "+m" (*p)
	    : "r" (p), "r" (v)
	    : "cc", "xer");

	return (rv);
}
#define atomic_sub_int_nv(_p, _v) _atomic_sub_int_nv((_p), (_v))

static inline unsigned long
_atomic_sub_long_nv(volatile unsigned long *p, unsigned long v)
{
	unsigned long rv;

	__asm volatile (
	    "1:	lwarx	%0, 0, %2	\n"
	    "	subf	%0, %3,	%0	\n"
	    "	stwcx.	%0, 0, %2	\n"
	    "	bne-	1b		\n"
	    : "=&r" (rv), "+m" (*p)
	    : "r" (p), "r" (v)
	    : "cc", "xer");

	return (rv);
}
#define atomic_sub_long_nv(_p, _v) _atomic_sub_long_nv((_p), (_v))

static inline unsigned int
_atomic_addic_int_nv(volatile unsigned int *p, unsigned int v)
{
	unsigned int rv;

	__asm volatile (
	    "1:	lwarx	%0, 0, %2	\n"
	    "	addic	%0, %0,	%3	\n"
	    "	stwcx.	%0, 0, %2	\n"
	    "	bne-	1b		\n"
	    : "=&r" (rv), "+m" (*p)
	    : "r" (p), "n" (v)
	    : "cc", "xer");

	return (rv);
}
#define atomic_inc_int_nv(_p) _atomic_addic_int_nv((_p), 1)
#define atomic_dec_int_nv(_p) _atomic_addic_int_nv((_p), -1)

static inline unsigned long
_atomic_addic_long_nv(volatile unsigned long *p, unsigned long v)
{
	unsigned long rv;

	__asm volatile (
	    "1:	lwarx	%0, 0, %2	\n"
	    "	addic	%0, %0,	%3	\n"
	    "	stwcx.	%0, 0, %2	\n"
	    "	bne-	1b		\n"
	    : "=&r" (rv), "+m" (*p)
	    : "r" (p), "n" (v)
	    : "cc", "xer");

	return (rv);
}
#define atomic_inc_long_nv(_p) _atomic_addic_long_nv((_p), 1)
#define atomic_dec_long_nv(_p) _atomic_addic_long_nv((_p), -1)

#define __membar(_f) do { __asm __volatile(_f ::: "memory"); } while (0)

#ifdef MULTIPROCESSOR
#define membar_enter()		__membar("isync")
#define membar_exit()		__membar("sync")
#define membar_producer()	__membar("sync")
#define membar_consumer()	__membar("isync")
#define membar_sync()		__membar("sync")
#else
#define membar_enter()		__membar("")
#define membar_exit()		__membar("")
#define membar_producer()	__membar("")
#define membar_consumer()	__membar("")
#define membar_sync()		__membar("")
#endif

#endif /* defined(_KERNEL) */
#endif /* _POWERPC_ATOMIC_H_ */


code:
/*	$OpenBSD: bat.h,v 1.6 2015/03/31 16:00:38 mpi Exp $	*/

/*
 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
 * Copyright (C) 1995, 1996 TooLs GmbH.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by TooLs GmbH.
 * 4. The name of TooLs GmbH may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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	_POWERPC_BAT_H_
#define	_POWERPC_BAT_H_

struct bat {
	u_int32_t batu;
	u_int32_t batl;
};

#define	BATU(vaddr,len)		(((vaddr)&0xf0000000)|(len)|0x2)
#define	BATL(raddr,wimg)	(((raddr)&0xf0000000)|(wimg)|0x2)

#define	BAT_W		0x40
#define	BAT_I		0x20
#define	BAT_M		0x10
#define	BAT_G		0x08

#define BAT_BL_128K     0x00000000
#define BAT_BL_256K     0x00000004
#define BAT_BL_512K     0x0000000c
#define BAT_BL_1M       0x0000001c
#define BAT_BL_2M       0x0000003c
#define BAT_BL_4M       0x0000007c
#define BAT_BL_8M       0x000000fc
#define BAT_BL_16M      0x000001fc
#define BAT_BL_32M      0x000003fc
#define BAT_BL_64M      0x000007fc
#define BAT_BL_128M     0x00000ffc
#define BAT_BL_256M     0x00001ffc
/* Extended Block Lengths (7455+) */
#define	BAT_BL_512M	0x00003ffc
#define	BAT_BL_1G	0x00007ffc
#define	BAT_BL_2G	0x0000fffc
#define	BAT_BL_4G	0x0001fffc

#ifdef	_KERNEL
extern struct bat battable[16];
#endif

#endif	/* _POWERPC_BAT_H_ */


code:
/*	$OpenBSD: cdefs.h,v 1.7 2013/03/28 17:30:45 martynas Exp $	*/

/*
 * Written by J.T. Conklin <jtc@wimsey.com> 01/17/95.
 * Public domain.
 */

#ifndef	_POWERPC_CDEFS_H_
#define	_POWERPC_CDEFS_H_

#define __strong_alias(alias,sym)			\
	__asm__(".global " __STRING(alias) " ; "	\
	    __STRING(alias) " = " __STRING(sym))
#define __weak_alias(alias,sym)				\
	__asm__(".weak " __STRING(alias) " ; "		\
	    __STRING(alias) " = " __STRING(sym))
#define	__warn_references(sym,msg)			\
	__asm__(".section .gnu.warning." __STRING(sym)	\
	    " ; .ascii \"" msg "\" ; .text")

#endif /* !_POWERPC_CDEFS_H_ */


code:
/*	$OpenBSD: cpu.h,v 1.62 2015/07/02 01:33:59 dlg Exp $	*/
/*	$NetBSD: cpu.h,v 1.1 1996/09/30 16:34:21 ws Exp $	*/

/*
 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
 * Copyright (C) 1995, 1996 TooLs GmbH.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by TooLs GmbH.
 * 4. The name of TooLs GmbH may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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	_POWERPC_CPU_H_
#define	_POWERPC_CPU_H_

#include <machine/frame.h>

#include <sys/device.h>
#include <sys/sched.h>

struct cpu_info {
	struct device *ci_dev;		/* our device */
	struct schedstate_percpu ci_schedstate; /* scheduler state */

	struct proc *ci_curproc;

	struct pcb *ci_curpcb;
	struct pmap *ci_curpm;
	struct proc *ci_fpuproc;
	struct proc *ci_vecproc;
	int ci_cpuid;

	volatile int ci_want_resched;
	volatile int ci_cpl;
	volatile int ci_ipending;

	volatile int	ci_flags;
#define	CI_FLAGS_SLEEPING		2

#if defined(MULTIPROCESSOR)
	struct srp_hazard ci_srp_hazards[SRP_HAZARD_NUM];
#endif

	int ci_intrdepth;
	char *ci_intstk;
#define CPUSAVE_LEN	8
	register_t ci_tempsave[CPUSAVE_LEN];
	register_t ci_ddbsave[CPUSAVE_LEN];
#define DISISAVE_LEN	4
	register_t ci_disisave[DISISAVE_LEN];

	volatile u_int64_t ci_nexttimerevent;
	volatile u_int64_t ci_prevtb;
	volatile u_int64_t ci_lasttb;
	volatile u_int64_t ci_nextstatevent;
	int ci_statspending;

	volatile int    ci_ddb_paused;
#define	CI_DDB_RUNNING	0
#define	CI_DDB_SHOULDSTOP	1
#define	CI_DDB_STOPPED		2
#define	CI_DDB_ENTERDDB		3
#define	CI_DDB_INDDB		4

	u_int32_t ci_randseed;

#ifdef DIAGNOSTIC
	int	ci_mutex_level;
#endif
#ifdef GPROF
	struct gmonparam *ci_gmon;
#endif
};

static __inline struct cpu_info *
curcpu(void)
{
	struct cpu_info *ci;

	__asm volatile ("mfsprg %0,0" : "=r"(ci));
	return ci;
}

#define	curpcb			(curcpu()->ci_curpcb)
#define	curpm			(curcpu()->ci_curpm)

#define CPU_INFO_UNIT(ci)	((ci)->ci_dev ? (ci)->ci_dev->dv_unit : 0)

#ifdef MULTIPROCESSOR

#define PPC_MAXPROCS		4

static __inline int
cpu_number(void)
{
	int pir;

	pir = curcpu()->ci_cpuid;
	return pir;
}

void	cpu_boot_secondary_processors(void);

#define CPU_IS_PRIMARY(ci)	((ci)->ci_cpuid == 0)
#define CPU_INFO_ITERATOR		int
#define CPU_INFO_FOREACH(cii, ci)					\
	for (cii = 0, ci = &cpu_info[0]; cii < ncpusfound; cii++, ci++)

void cpu_unidle(struct cpu_info *);

#else

#define PPC_MAXPROCS		1

#define cpu_number()		0

#define CPU_IS_PRIMARY(ci)	1
#define CPU_INFO_ITERATOR		int
#define CPU_INFO_FOREACH(cii, ci)					\
	for (cii = 0, ci = curcpu(); ci != NULL; ci = NULL)

#define cpu_unidle(ci)

#endif

#define CPU_BUSY_CYCLE()	do {} while (0)

#define MAXCPUS	PPC_MAXPROCS

extern struct cpu_info cpu_info[PPC_MAXPROCS];

#define	CLKF_USERMODE(frame)	(((frame)->srr1 & PSL_PR) != 0)
#define	CLKF_PC(frame)		((frame)->srr0)
#define	CLKF_INTR(frame)	((frame)->depth != 0)

extern int ppc_cpuidle;
extern int ppc_proc_is_64b;
extern int ppc_nobat;

void	cpu_bootstrap(void);

/*
 * This is used during profiling to integrate system time.
 */
#define	PROC_PC(p)		(trapframe(p)->srr0)
#define	PROC_STACK(p)		(trapframe(p)->fixreg[1])

void	delay(unsigned);
#define	DELAY(n)		delay(n)

#define	aston(p)		((p)->p_md.md_astpending = 1)

/*
 * Preempt the current process if in interrupt from user mode,
 * or after the current trap/syscall if in system mode.
 */
#define	need_resched(ci) \
do {									\
	ci->ci_want_resched = 1;					\
	if (ci->ci_curproc != NULL)					\
		aston(ci->ci_curproc);					\
} while (0)
#define clear_resched(ci) (ci)->ci_want_resched = 0

#define	need_proftick(p)	aston(p)

void	signotify(struct proc *);

extern char *bootpath;

#ifndef	CACHELINESIZE
#define	CACHELINESIZE	32			/* For now		XXX */
#endif

static __inline void
syncicache(void *from, int len)
{
	int l;
	char *p = from;

	len = len + (((u_int32_t) from) & (CACHELINESIZE - 1));
	l = len;

	do {
		__asm volatile ("dcbst 0,%0" :: "r"(p));
		p += CACHELINESIZE;
	} while ((l -= CACHELINESIZE) > 0);
	__asm volatile ("sync");
	p = from;
	l = len;
	do {
		__asm volatile ("icbi 0,%0" :: "r"(p));
		p += CACHELINESIZE;
	} while ((l -= CACHELINESIZE) > 0);
	__asm volatile ("isync");
}

static __inline void
invdcache(void *from, int len)
{
	int l;
	char *p = from;

	len = len + (((u_int32_t) from) & (CACHELINESIZE - 1));
	l = len;

	do {
		__asm volatile ("dcbi 0,%0" :: "r"(p));
		p += CACHELINESIZE;
	} while ((l -= CACHELINESIZE) > 0);
	__asm volatile ("sync");
}

#define FUNC_SPR(n, name) \
static __inline u_int32_t ppc_mf ## name (void)			\
{								\
	u_int32_t ret;						\
	__asm volatile ("mfspr %0," # n : "=r" (ret));		\
	return ret;						\
}								\
static __inline void ppc_mt ## name (u_int32_t val)		\
{								\
	__asm volatile ("mtspr "# n ",%0" :: "r" (val));	\
}								\

FUNC_SPR(0, mq)
FUNC_SPR(1, xer)
FUNC_SPR(4, rtcu)
FUNC_SPR(5, rtcl)
FUNC_SPR(8, lr)
FUNC_SPR(9, ctr)
FUNC_SPR(18, dsisr)
FUNC_SPR(19, dar)
FUNC_SPR(22, dec)
FUNC_SPR(25, sdr1)
FUNC_SPR(26, srr0)
FUNC_SPR(27, srr1)
FUNC_SPR(256, vrsave)
FUNC_SPR(272, sprg0)
FUNC_SPR(273, sprg1)
FUNC_SPR(274, sprg2)
FUNC_SPR(275, sprg3)
FUNC_SPR(280, asr)
FUNC_SPR(282, ear)
FUNC_SPR(287, pvr)
FUNC_SPR(311, hior)
FUNC_SPR(528, ibat0u)
FUNC_SPR(529, ibat0l)
FUNC_SPR(530, ibat1u)
FUNC_SPR(531, ibat1l)
FUNC_SPR(532, ibat2u)
FUNC_SPR(533, ibat2l)
FUNC_SPR(534, ibat3u)
FUNC_SPR(535, ibat3l)
FUNC_SPR(560, ibat4u)
FUNC_SPR(561, ibat4l)
FUNC_SPR(562, ibat5u)
FUNC_SPR(563, ibat5l)
FUNC_SPR(564, ibat6u)
FUNC_SPR(565, ibat6l)
FUNC_SPR(566, ibat7u)
FUNC_SPR(567, ibat7l)
FUNC_SPR(536, dbat0u)
FUNC_SPR(537, dbat0l)
FUNC_SPR(538, dbat1u)
FUNC_SPR(539, dbat1l)
FUNC_SPR(540, dbat2u)
FUNC_SPR(541, dbat2l)
FUNC_SPR(542, dbat3u)
FUNC_SPR(543, dbat3l)
FUNC_SPR(568, dbat4u)
FUNC_SPR(569, dbat4l)
FUNC_SPR(570, dbat5u)
FUNC_SPR(571, dbat5l)
FUNC_SPR(572, dbat6u)
FUNC_SPR(573, dbat6l)
FUNC_SPR(574, dbat7u)
FUNC_SPR(575, dbat7l)
FUNC_SPR(1009, hid1)
FUNC_SPR(1010, iabr)
FUNC_SPR(1017, l2cr)
FUNC_SPR(1018, l3cr)
FUNC_SPR(1013, dabr)
FUNC_SPR(1023, pir)

static __inline u_int32_t
ppc_mftbl (void)
{
	int ret;
	__asm volatile ("mftb %0" : "=r" (ret));
	return ret;
}

static __inline u_int64_t
ppc_mftb(void)
{
	u_long scratch;
	u_int64_t tb;

	__asm volatile ("1: mftbu %0; mftb %0+1; mftbu %1;"
	    " cmpw 0,%0,%1; bne 1b" : "=r"(tb), "=r"(scratch));
	return tb;
}

static __inline void
ppc_mttb(u_int64_t tb)
{
	__asm volatile ("mttbl %0" :: "r"(0));
	__asm volatile ("mttbu %0" :: "r"((u_int32_t)(tb >> 32)));
	__asm volatile ("mttbl %0" :: "r"((u_int32_t)(tb & 0xffffffff)));
}

static __inline u_int32_t
ppc_mfmsr (void)
{
	int ret;
        __asm volatile ("mfmsr %0" : "=r" (ret));
	return ret;
}

static __inline void
ppc_mtmsr (u_int32_t val)
{
        __asm volatile ("mtmsr %0" :: "r" (val));
}

static __inline void
ppc_mtsrin(u_int32_t val, u_int32_t sn_shifted)
{
	__asm volatile ("mtsrin %0,%1" :: "r"(val), "r"(sn_shifted));
}

u_int64_t ppc64_mfscomc(void);
void ppc_mtscomc(u_int32_t);
void ppc64_mtscomc(u_int64_t);
u_int64_t ppc64_mfscomd(void);
void ppc_mtscomd(u_int32_t);
u_int32_t ppc_mfhid0(void);
void ppc_mthid0(u_int32_t);
u_int64_t ppc64_mfhid1(void);
void ppc64_mthid1(u_int64_t);
u_int64_t ppc64_mfhid4(void);
void ppc64_mthid4(u_int64_t);
u_int64_t ppc64_mfhid5(void);
void ppc64_mthid5(u_int64_t);

#include <machine/psl.h>

/*
 * General functions to enable and disable interrupts
 * without having inlined assembly code in many functions.
 */
static __inline void
ppc_intr_enable(int enable)
{
	u_int32_t msr;
	if (enable != 0) {
		msr = ppc_mfmsr();
		msr |= PSL_EE;
		ppc_mtmsr(msr);
	}
}

static __inline int
ppc_intr_disable(void)
{
	u_int32_t emsr, dmsr;
	emsr = ppc_mfmsr();
	dmsr = emsr & ~PSL_EE;
	ppc_mtmsr(dmsr);
	return (emsr & PSL_EE);
}

int ppc_cpuspeed(int *);

/*
 * PowerPC CPU types
 */
#define	PPC_CPU_MPC601		1
#define	PPC_CPU_MPC603		3
#define	PPC_CPU_MPC604		4
#define	PPC_CPU_MPC603e		6
#define	PPC_CPU_MPC603ev	7
#define	PPC_CPU_MPC750		8
#define	PPC_CPU_MPC604ev	9
#define	PPC_CPU_MPC7400		12
#define	PPC_CPU_IBM970		0x0039
#define	PPC_CPU_IBM970FX	0x003c
#define	PPC_CPU_IBM970MP	0x0044
#define	PPC_CPU_IBM750FX	0x7000
#define	PPC_CPU_MPC7410		0x800c
#define	PPC_CPU_MPC7447A	0x8003
#define	PPC_CPU_MPC7448		0x8004
#define	PPC_CPU_MPC7450		0x8000
#define	PPC_CPU_MPC7455		0x8001
#define	PPC_CPU_MPC7457		0x8002
#define	PPC_CPU_MPC83xx		0x8083

/*
 * This needs to be included late since it relies on definitions higher
 * up in this file.
 */
#if defined(MULTIPROCESSOR) && defined(_KERNEL)
#include <sys/mplock.h>
#endif

#endif	/* _POWERPC_CPU_H_ */


code:
/*	$OpenBSD: db_machdep.h,v 1.25 2014/03/16 20:31:46 guenther Exp $	*/
/*	$NetBSD: db_machdep.h,v 1.13 1996/04/29 20:50:08 leo Exp $	*/

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

/*
 * Machine-dependent defines for new kernel debugger.
 */
#ifndef	_POWERPC_DB_MACHDEP_H_
#define	_POWERPC_DB_MACHDEP_H_

#include <sys/types.h>
#include <uvm/uvm_param.h>
#include <machine/trap.h>

typedef	vaddr_t	db_addr_t;	/* address - unsigned */
typedef	long		db_expr_t;	/* expression - signed */
struct powerpc_saved_state {
	struct trapframe tf;
};
typedef struct powerpc_saved_state db_regs_t;
extern	db_regs_t ddb_regs;		/* register state */
#define DDB_REGS	(&ddb_regs)

#define	PC_REGS(regs)	((regs)->tf.srr0)
#define	SET_PC_REGS(regs, value)	PC_REGS(regs) = (value)

#define	BKPT_INST	0x7C810808	/* breakpoint instruction */

#define	BKPT_SIZE	(4)		/* size of breakpoint inst */
#define	BKPT_SET(inst)	(BKPT_INST)

#define	FIXUP_PC_AFTER_BREAK(regs)	((regs)->tf.srr0 -= 4)

#define SR_SINGLESTEP 0x8000
#define	db_clear_single_step(regs)	((regs)->tf.srr1 &= ~SR_SINGLESTEP)
#define	db_set_single_step(regs)	((regs)->tf.srr1 |=  SR_SINGLESTEP)

#define T_BREAKPOINT	0xffff
#define	IS_BREAKPOINT_TRAP(type, code)	((type) == T_BREAKPOINT)

#ifdef T_WATCHPOINT
#define	IS_WATCHPOINT_TRAP(type, code)	((type) == T_WATCHPOINT)
#else
#define	IS_WATCHPOINT_TRAP(type, code)	0
#endif

#define	M_RTS		0xfc0007fe
#define I_RTS		0x4c000020
#define M_BC		0xfc000000
#define I_BC		0x40000000
#define M_B		0xfc000000
#define I_B		0x50000000
#define	M_RFI		0xfc0007fe
#define	I_RFI		0x4c000064

#define	inst_trap_return(ins)	(((ins)&M_RFI) == I_RFI)
#define	inst_return(ins)	(((ins)&M_RTS) == I_RTS)
#define	inst_call(ins)		(((ins)&M_BC ) == I_BC  || \
				 ((ins)&M_B  ) == I_B )

#ifdef _KERNEL

int db_enter_ddb(void);
void db_startcpu(int);
void db_stopcpu(int);
void ppc_ipi_db(struct cpu_info *);

void	kdb_kintr(void *);
int	kdb_trap(int, void *);
void	db_save_regs(struct trapframe *frame);
void	ddb_trap(void);
db_expr_t db_dumpframe(u_int32_t pframe, int (*pr)(const char *, ...));

extern struct mutex ddb_mp_mutex;

#define DDB_STATE_NOT_RUNNING	0
#define DDB_STATE_RUNNING	1
#define DDB_STATE_EXITING	2

#endif /* _KERNEL */

#endif	/* _POWERPC_DB_MACHDEP_H_ */


code:
/*	$OpenBSD: endian.h,v 1.21 2014/10/22 23:56:47 dlg Exp $ */

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

#ifndef _POWERPC_ENDIAN_H_
#define _POWERPC_ENDIAN_H_

#ifdef _KERNEL

static inline __uint16_t
__mswap16(volatile const __uint16_t *m)
{
	__uint16_t v;

	__asm("lhbrx %0, 0, %1"
	    : "=r" (v)
            : "r" (m), "m" (*m));

	return (v);
}

static inline __uint32_t
__mswap32(volatile const __uint32_t *m)
{
	__uint32_t v;

	__asm("lwbrx %0, 0, %1"
	    : "=r" (v)
            : "r" (m), "m" (*m));

	return (v);
}

static inline __uint64_t
__mswap64(volatile const __uint64_t *m)
{
	__uint32_t *a = (__uint32_t *)m;
	__uint64_t v;

	v = (__uint64_t)__mswap32(a + 1) << 32 |
	    (__uint64_t)__mswap32(a);

	return (v);
}

static inline void
__swapm16(volatile __uint16_t *m, __uint16_t v)
{
	__asm("sthbrx %1, 0, %2"
	    : "=m" (*m)
	    : "r" (v), "r" (m));
}

static inline void
__swapm32(volatile __uint32_t *m, __uint32_t v)
{
	__asm("stwbrx %1, 0, %2"
	    : "=m" (*m)
	    : "r" (v), "r" (m));
}

static inline void
__swapm64(volatile __uint64_t *m, __uint64_t v)
{
	__uint32_t *a = (__uint32_t *)m;

	__swapm32(a + 1, v >> 32);
	__swapm32(a, v);
}

#define __HAVE_MD_SWAPIO
#endif /* _KERNEL */

#undef _BIG_ENDIAN	/* XXX - gcc may define _BIG_ENDIAN too */
#define _BYTE_ORDER _BIG_ENDIAN

#ifndef __FROM_SYS__ENDIAN
#include <sys/endian.h>
#endif

#endif /* _POWERPC_ENDIAN_H_ */


code:
/*	$OpenBSD: exec.h,v 1.12 2013/02/09 19:25:13 miod Exp $ */

/*
 * Copyright (c) 1997 Per Fogelstrom, Opsycon AB.
 *
 * 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.
 *
 *	$Id: exec.h,v 1.12 2013/02/09 19:25:13 miod Exp $
 */

#ifndef _POWERPC_EXEC_H_
#define _POWERPC_EXEC_H_

#define __LDPGSZ	4096	/* linker page size */

#define ARCH_ELFSIZE		32

#define ELF_TARG_CLASS          ELFCLASS32
#define ELF_TARG_DATA           ELFDATA2MSB
#define ELF_TARG_MACH           EM_PPC

#define _NLIST_DO_ELF

#define _KERN_DO_ELF

#endif  /* _POWERPC_EXEC_H_ */