code:
/*	$OpenBSD: conf.c,v 1.6 2013/12/28 02:53:03 deraadt Exp $	*/

/*
 * Copyright (c) 2005 Michael Shalayeff
 * All rights reserved.
 *
 * 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 MIND, USE, DATA OR PROFITS, WHETHER IN
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <sys/param.h>
#include <sys/types.h>
#include <libsa.h>
#include <lib/libsa/ufs.h>
#include <lib/libsa/cd9660.h>
#include <dev/cons.h>

const char version[] = "1.1";
int	debug = 0;

struct fs_ops file_system[] = {
	{ ufs_open,    ufs_close,    ufs_read,    ufs_write,    ufs_seek,
	  ufs_stat,    ufs_readdir    },
	{ cd9660_open, cd9660_close, cd9660_read, cd9660_write, cd9660_seek,
	  cd9660_stat, cd9660_readdir },
	{ lif_open,    lif_close,    lif_read,    lif_write,    lif_seek,
	  lif_stat,    lif_readdir    },
};
int nfsys = nitems(file_system);

struct devsw devsw[] = {
	{ "dk",	iodcstrategy, dkopen, dkclose, noioctl },
	{ "ct",	iodcstrategy, ctopen, ctclose, noioctl },
	{ "lf", iodcstrategy, lfopen, lfclose, noioctl }
};
int	ndevs = nitems(devsw);

struct consdev	constab[] = {
	{ ite_probe, ite_init, ite_getc, ite_putc },
	{ NULL }
};
struct consdev *cn_tab;


code:
/*	$OpenBSD: exec.c,v 1.1 2005/04/01 10:40:48 mickey Exp $	*/

/*
 * Copyright (c) 2005 Michael Shalayeff
 * All rights reserved.
 *
 * 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 MIND, USE, DATA OR PROFITS, WHETHER IN
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <sys/param.h>
#include <machine/pdc.h>
#include "libsa.h"
#include <lib/libsa/loadfile.h>
#include <stand/boot/bootarg.h>
#include "dev_hppa64.h"

typedef void (*startfuncp)(int, int, int, int, int, int, caddr_t)
    __attribute__ ((noreturn));

void
run_loadfile(u_long *marks, int howto)
{
	fcacheall();

	__asm("mtctl %r0, %cr17");
	__asm("mtctl %r0, %cr17");
	/* stack and the gung is ok at this point, so, no need for asm setup */
	(*(startfuncp)(marks[MARK_ENTRY]))((int)(long)(long)pdc, howto, bootdev,
	    marks[MARK_END], BOOTARG_APIVER, BOOTARG_LEN, (caddr_t)BOOTARG_OFF);

	/* not reached */
}

license: unknown


code:
/*	$OpenBSD: ld.script,v 1.1 2005/04/01 10:40:48 mickey Exp $	*/

OUTPUT_FORMAT("elf64-hppa")
OUTPUT_ARCH(hppa2.0w)
ENTRY(begin)

SECTIONS {

	/* Read-only sections, merged into text segment: */
	. = + SIZEOF_HEADERS;
	.text : {
		*(.text)
		*(.text.*)
		*(.rodata)
		*(.rodata1)
		*($CODE$)
		etext = .;
	} = 0x08000240

	/* Read-write sections, merged into data segment: */
	.data : {
		$global$ = .;
		*(.data)
		*(.data1)
		*(.sdata)
		*(.sdata2)
		*(.dynamic)
		CONSTRUCTORS
		edata = ABSOLUTE(.);
	} = 0

	.opd	: { *(.opd) }
	PROVIDE(__gp = .);
	.plt	: { *(.plt) }
	.dlt	: { *(.dlt) }

	.bss : {
		__bss_start = .;
		*(.dynbss)
		*(.bss)
		*(.sbss)
		*(.scommon)
		*(COMMON)
		end = ABSOLUTE(.);
		__bss_end = .;
	}

	/* don't need an unwind in the boot, unless we'll have a boot-ddb (; */
	/DISCARD/ :
	{
		*(.PARISC.unwind)
		*(.exitcall.exit)
		*(.interp)
		*(.dynsym)
		*(.dynstr)
		*(.dynamic)
		*(.hash)
		*(.stub)
	}
}


code:
/*	$OpenBSD: srt0.S,v 1.1 2005/04/01 10:40:48 mickey Exp $	*/

/*
 * Copyright (c) 2005 Michael Shalayeff
 * All rights reserved.
 *
 * 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 MIND, 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 1996 1995 by Open Software Foundation, Inc.
 *              All Rights Reserved
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notice appears in all copies and
 * that both the copyright notice and this permission notice appear in
 * supporting documentation.
 *
 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE.
 *
 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */
;
; Copyright (c) 1990 mt Xinu, Inc.  All rights reserved.
; Copyright (c) 1990 University of Utah.  All rights reserved.
;
; This file may be freely distributed in any form as long as
; this copyright notice is included.
; THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
; IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
; WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
;
;	Utah $Hdr: srt0.c 1.3 94/12/13$
;

#define	_LOCORE
#include <machine/iomod.h>
#include <machine/asm.h>
#include <machine/frame.h>

/*
 * This is the ending of the begin
 */
ENTRY(begin,0)

	blr	%r0,%r5			; Get address of 'boff' into 'r5',
	ldo	begin-boff(%r5),%r5	;   and subtract to get 'begin'.
boff
	ldil	L%RELOC,%r4
	ldo	R%RELOC(%r4),%r4
	ldo	start-begin(%r4),%rp
	ldil	L%edata,%r3
	ldo	R%edata(%r3),%r3	; Get address of edata.
	ldil	L%begin,%r1
	ldo	R%begin(%r1),%r1	; Get address of begin
	sub	%r3,%r1,%r3		; Subtract to get # of bytes to copy
copyloop				; do
	ldwm	4(%r5),%r1		;   *r4++ = *r5++;
	addib,>= -4,%r3,copyloop	; while (--r3 >= 0);
	stwm	%r1,4(%r4)

	; here we zero the .bss
	ldil	L%__bss_start, %r4
	ldo	R%__bss_start(%r4), %r4
	ldil	L%__bss_end, %r3
	ldo	R%__bss_end(%r3), %r3
zeroloop
	combf,<,n %r3,%r4, zeroloop	; while (r4 < r3);
	stwm	%r0,4(%r4)		;	*r4++ = 0;

	ldil	L%$global$,%dp
	ldo	R%$global$(%dp),%dp
	ldil	L%start,%r1
	ldo	R%start(%r1),%r1
	sub	%dp,%r1,%dp		; Subtract to get difference
	add	%rp,%dp,%dp		;   and relocate it.

;
; We have relocated ourself to RELOC.  If we are running on a machine
; with separate instruction and data caches, we must flush our data
; cache before trying to execute the code starting at rp.
;
	ldil	L%RELOC,%r22		; Set %t1 to start of relocated code.
	ldo	R%RELOC(%r22),%r22
	ldil	L%edata,%r21		; Set r21 to address of edata
	ldo	R%edata(%r21),%r21
	ldil	L%begin,%r1		; set %r1 to address of begin
	ldo	R%begin(%r1),%r1
	sub	%r21,%r1,%r21		; Subtract to get length
	mtsp	%r0,%sr0		; Set sr0 to kernel space.
	ldo	-1(%r21),%r21
	fdc	%r21(0,%r22)
loop	addib,>,n -16,%r21,loop		; Decrement by cache line size (16).
	fdc	%r21(%sr0,%r22)
	fdc	0(%sr0,%r22)		; Flush first word at addr to handle
	sync				;   arbitrary cache line boundary.
	nop				; Prevent prefetching.
	nop
	nop
	nop
	nop
	nop
	nop
	bv	0(%rp)
	nop
EXIT(begin)				/* jump to relocated code */

start
	ldil	L%HEAP_LIMIT, %sp
	ldo	R%HEAP_LIMIT(%sp), %sp

	.import	bootprompt, data
	ldil	L%bootprompt, %r1
	stw	%arg0, R%bootprompt(%r1)
	b	boot			; Call boot(),
	copy	%r0, %arg0		; use default boot device
	nop

/*
 * rtt - restart the box
 */
LEAF_ENTRY(_rtt)
	ldil    L%LBCAST_ADDR, %arg1
	ldi     CMD_RESET, %arg0
	stw     %arg0, R%iomod_command(%arg1)
forever                                 ; Loop until bus reset takes effect.
	b,n     forever

	bv	0(%rp)
	ldo     -48(%sp),%sp
EXIT(_rtt)

ENTRY(pdc_call,96)
	copy	%r3, %r1
	std	%rp, HPPA_FRAME_RP(%sp)
	copy	%sp, %r3
	std,ma	%r1, HPPA_FRAME_SIZE+8*4(%sp)

	copy	%arg0, %r1
	copy	%arg1, %arg0
	copy	%arg2, %arg1
	copy	%arg3, %arg2
	copy	arg4, %arg3
	stw	arg5, -(32 + 4*(4 + 1))(%sp)
	stw	arg6, -(32 + 4*(5 + 1))(%sp)
	stw	arg7, -(32 + 4*(6 + 1))(%sp)
	ldw	0(ap), arg5
	ldw	8(ap), arg6
	ldw	16(ap), arg7
	stw	arg5, -(32 + 4*(7 + 1))(%sp)
	stw	arg6, -(32 + 4*(8 + 1))(%sp)
	stw	arg7, -(32 + 4*(9 + 1))(%sp)

	.call
	blr	%r0, %rp
	bv,n	%r0(%r1)
	nop

	ldd	HPPA_FRAME_RP(%r3), %rp
	bv	%r0(%rp)
	ldd,mb	-(HPPA_FRAME_SIZE+8*4)(%sp), %r3
EXIT(pdc_call)

	.end


code:
#	$OpenBSD: Makefile,v 1.5 2014/07/13 21:18:26 miod Exp $

NOMAN=	no man
S	=${.CURDIR}/../../../..
CLEANFILES+=	cdboot.gdb cdboot.map

.if ${MACHINE} == "hppa64"

PROG=	cdboot

.PATH: ${.CURDIR}/../boot
SRCS+= srt0.S

SRCS=  srt0.S cdboot.c

.PATH: ${.CURDIR}/../libsa
SRCS+= pdc.c itecons.c dev_hppa64.c dk.c
CPPFLAGS+=-DCONSPEED=9600

.PATH: ${S}/lib/libkern/arch/hppa ${S}/lib/libkern
SRCS+= milli.S strlen.c strlcpy.c

LD?=	ld
LDFLAGS+=-Bstatic -nostartfiles -nostdlib -N -Ttext $(LINKADDR)
LDFLAGS+=-T ${.CURDIR}/ld.script -Map cdboot.map
SIZE?=	size
STRIP?=	strip
STANDIR=${.CURDIR}/..
CRTBEGIN=
CRTEND=

SAREL=
USE_LOADFILE=yes
.include "${S}/lib/libsa/Makefile.inc"
DPADD+= $(SALIB)
LDADD+=	$(SALIB)

all:	${PROG}

clean::
	rm -f a.out [Ee]rrs mklog *.core \
	    ${PROG} ${OBJS} ${LOBJS} ${CLEANFILES}

realinstall:
	${INSTALL} ${INSTALL_COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
	    ${PROG} ${DESTDIR}${BINDIR}

# TODO check for <=32k
${PROG}: $(OBJS) $(DPADD)
	$(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LDADD)
	@cp ${PROG} ${PROG}.gdb
	${STRIP} ${PROG}
	@${SIZE} $(PROG)
	@${MKBOOT} -v ${PROG} ${PROG}.lif
	@mv ${PROG}.lif ${PROG}
.else
NOPROG=
.endif

.include <bsd.prog.mk>

CPPFLAGS+=-DRELOC=${LOADADDR} -DHEAP_LIMIT=${HEAP_LIMIT}
CFLAGS+=$(SACFLAGS) -I../.. -I${.CURDIR}/../libsa -I${S}/stand/boot
CFLAGS+=${NOPIE_FLAGS}
AFLAGS+=${NOPIE_FLAGS}


code:
/*	$OpenBSD: cdboot.c,v 1.4 2010/12/06 22:51:45 jasper Exp $	*/

/*
 * Copyright (c) 2005 Michael Shalayeff
 * All rights reserved.
 *
 * 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 MIND, USE, DATA OR PROFITS, WHETHER IN
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <sys/param.h>
#include <sys/reboot.h>
#include <sys/stat.h>
#include <libsa.h>
#include <lib/libsa/cd9660.h>
#include <lib/libsa/loadfile.h>
#include <dev/cons.h>
#include <machine/pdc.h>
#include <stand/boot/bootarg.h>
#include "dev_hppa64.h"
#include "cmd.h"

dev_t bootdev;
int debug = 1;
int bootprompt = 1;

struct fs_ops file_system[] = {
	{ cd9660_open, cd9660_close, cd9660_read, cd9660_write, cd9660_seek,
	  cd9660_stat, cd9660_readdir },
};
int nfsys = nitems(file_system);

struct devsw devsw[] = {
	{ "dk",	iodcstrategy, dkopen, dkclose, noioctl },
};
int	ndevs = nitems(devsw);

struct consdev	constab[] = {
	{ ite_probe, ite_init, ite_getc, ite_putc },
	{ NULL }
};
struct consdev *cn_tab;

typedef void (*startfuncp)(int, int, int, int, int, int, caddr_t)
    __attribute__ ((noreturn));

void
boot(dev_t dev)
{
	u_long marks[MARK_MAX];
	char path[128];

	pdc_init();
	cninit();
	devboot(dev, path);
	strncpy(path + strlen(path), ":/bsd.rd", 9);
	printf(">> OpenBSD/" MACHINE " CDBOOT 0.1\n"
	    "booting %s: ", path);

	marks[MARK_START] = (u_long)DEFAULT_KERNEL_ADDRESS;
	if (!loadfile(path, marks, LOAD_KERNEL)) {
		marks[MARK_END] = ALIGN(marks[MARK_END] -
		    (u_long)DEFAULT_KERNEL_ADDRESS);
		fcacheall();

		__asm("mtctl %r0, %cr17");
		__asm("mtctl %r0, %cr17");
		(*(startfuncp)(marks[MARK_ENTRY]))((int)(long)pdc, 0, bootdev,
		    marks[MARK_END], BOOTARG_APIVER, BOOTARG_LEN,
		    (caddr_t)BOOTARG_OFF);
		/* not reached */
	}
}


code:
/*	$OpenBSD: ld.script,v 1.1 2005/04/01 10:40:48 mickey Exp $	*/

OUTPUT_FORMAT("elf64-hppa")
OUTPUT_ARCH(hppa2.0w)
ENTRY(begin)

SECTIONS {

	/* Read-only sections, merged into text segment: */
	. = + SIZEOF_HEADERS;
	.text : {
		*(.text)
		*(.text.*)
		*(.rodata)
		*(.rodata1)
		*($CODE$)
		etext = .;
	} = 0x08000240

	/* Read-write sections, merged into data segment: */
	.data : {
		$global$ = .;
		*(.data)
		*(.data1)
		*(.sdata)
		*(.sdata2)
		*(.dynamic)
		CONSTRUCTORS
		edata = ABSOLUTE(.);
	} = 0

	.bss : {
		__bss_start = .;
		*(.dynbss)
		*(.bss)
		*(.sbss)
		*(.scommon)
		*(COMMON)
		end = ABSOLUTE(.);
		__bss_end = .;
	}

	/* don't need an unwind in the boot, unless we'll have a boot-ddb (; */
	/DISCARD/ :
	{
		*(.PARISC.unwind)
	}
}


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

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

LIB=	sa

S=${.CURDIR}/../../../..
SADIR=${.CURDIR}/..
DIR_SA=	$S/lib/libsa

NOPROFILE=noprofile
NOPIC=nopic
NOPIE=

#AS=cat ;
#AS+=	-R
#AS+=	-a

# hppa64 stuff
SRCS=	machdep.c pdc.c itecons.c dev_hppa64.c time.c \
	ct.c dk.c lf.c lif.c cmd_hppa64.c

# stand routines
SRCS+=	alloc.c exit.c getfile.c gets.c getchar.c globals.c \
	printf.c putchar.c strerror.c strtol.c strchr.c ctime.c loadfile.c \
	snprintf.c

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

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

.PATH:  ${DIR_SA}

all: ${SALIB}

install:

.include <bsd.lib.mk>

CPPFLAGS+=-DHEAP_LIMIT=${HEAP_LIMIT} ${DEBUGFLAGS} -DNO_NET
CPPFLAGS+=-I${S}/stand/boot
CFLAGS+=${SACFLAGS} -D__INTERNAL_LIBSA_CREAD -DCOMPAT_UFS -DCONSPEED=9600


code:
/*	$OpenBSD: cmd_hppa64.c,v 1.4 2010/12/06 22:51:45 jasper Exp $	*/

/*
 * Copyright (c) 2002 Miodrag Vallat
 * 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 OR HIS RELATIVES 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 MIND, 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.
 */

/*#define	DEBUG*/

#include <sys/param.h>
/* would come from <sys/param.h> if -D_KERNEL */
#define offsetof(s, e) ((size_t)&((s *)0)->e)

#include <machine/iomod.h>
#include <machine/pdc.h>

#include <arch/hppa/dev/cpudevs.h>

#include <libsa.h>
#include "cmd.h"
#include "dev_hppa64.h"	/* pdc */

extern struct stable_storage sstor;
extern int sstorsiz;

/* storage sizes we're interested in */
#define	CONSOLEOFFSET \
	offsetof(struct stable_storage, ss_console)
#define	CONSOLESIZE \
	(offsetof(struct stable_storage, ss_console) + \
	 sizeof(struct device_path))

#define	KEYBOARDOFFSET \
	offsetof(struct stable_storage, ss_keyboard)
#define	KEYBOARDSIZE \
	(offsetof(struct stable_storage, ss_keyboard) + \
	 sizeof(struct device_path))

/*
 * Table for the possible console devices found during the device walk.
 */
struct consoledev {
	struct device_path dp;
	int	type;
	int	iodc_type;
	int	iodc_model;
};

#define	PS2		1
#define	HIL		2
#define	SERIAL		3
#define	GRAPHICS	4

/* max. serial ports */
#define	MAX_SERIALS	4
/* max. HIL and PS2 */
#define	MAX_KEYBOARDS	2
/* max. heads */
#define	MAX_GRAPHICS	4

struct consoledev serials[MAX_SERIALS];
struct consoledev keyboards[MAX_KEYBOARDS];
struct consoledev graphics[MAX_GRAPHICS];

/* Relaxed device comparison */
#define	MATCH(dev1, dev2) \
	(dev1).dp_mod == (dev2).dp_mod && \
	(dev1).dp_bc[0] == (dev2).dp_bc[0] && \
	(dev1).dp_bc[1] == (dev2).dp_bc[1] && \
	(dev1).dp_bc[2] == (dev2).dp_bc[2] && \
	(dev1).dp_bc[3] == (dev2).dp_bc[3] && \
	(dev1).dp_bc[4] == (dev2).dp_bc[4] && \
	(dev1).dp_bc[5] == (dev2).dp_bc[5]

int walked;

void bus_walk(struct device_path *);
void register_device(struct consoledev *, int,
			  struct device_path *, struct iodc_data *, int, int);

int Xconsole(void);
void print_console(void);
int set_graphics(struct device_path *, int, char *);
int set_serial(struct device_path *, int, char *);
int set_console(struct device_path *);

int Xkeyboard(void);
void print_keyboard(void);
int set_keyboard(struct device_path *);

struct cmd_table cmd_machine[] = {
	{ "console",	CMDT_CMD,	Xconsole },
	{ "keyboard",	CMDT_CMD,	Xkeyboard },
	{ NULL, },
};

/* value to console speed table */
int i_speeds[] = {
	50,
	75,
	110,
	150,
	300,
	600,
	1200,
	2400,
	4800,
	7200,
	9600,
	19200,
	38400,
	57600,
	115200,
	230400,
};

char *c_speeds[] = {
	"50",
	"75",
	"110",
	"150",
	"300",
	"600",
	"1200",
	"2400",
	"4800",
	"7200",
	"9600",
	"19200",
	"38400",
	"57600",
	"115200",
	"230400",
};

/* values to console parity table */
char *parities[] = {
	"none",
	"odd",
	"<unknown parity>",
	"even",
};

/*
 * C O N S O L E   S E T T I N G S
 */

void
print_console()
{
	int port, mode, speed, parity, bits;
	int i;

#ifdef DEBUG
	printf("console flags %x mod %x bc %d/%d/%d/%d/%d/%d\n",
	    sstor.ss_console.dp_flags,
	    sstor.ss_console.dp_mod,
	    sstor.ss_console.dp_bc[0],
	    sstor.ss_console.dp_bc[1],
	    sstor.ss_console.dp_bc[2],
	    sstor.ss_console.dp_bc[3],
	    sstor.ss_console.dp_bc[4],
	    sstor.ss_console.dp_bc[5]);

	printf("console path %x/%x/%x/%x/%x/%x\n",
	    sstor.ss_console.dp_layers[0],
	    sstor.ss_console.dp_layers[1],
	    sstor.ss_console.dp_layers[2],
	    sstor.ss_console.dp_layers[3],
	    sstor.ss_console.dp_layers[4],
	    sstor.ss_console.dp_layers[5]);
#endif

	printf("Console path: ");

	/* look for a serial console */
	for (port = i = 0; i < MAX_SERIALS; i++)
		if (MATCH(serials[i].dp, sstor.ss_console)) {
			port = i + 1;
			break;
		}

	if (port == 0) {
		/*
		 * Graphics console
		 */

		for (port = i = 0; i < MAX_GRAPHICS; i++)
			if (MATCH(graphics[i].dp, sstor.ss_console)) {
				port = i;
				break;
			}

		/*
		 * If the console could still not be identified, consider
		 * it is a simplified encoding for the default graphics
		 * console. Hence port == 0, no need to check.
		 */
		if (port == 0)
			printf("graphics");
		else
			printf("graphics_%d", port);

		mode = sstor.ss_console.dp_layers[0];
		if (mode != 0)
			printf(".%d", mode);
	} else {
		/*
		 * Serial console
		 */

		if (port == 1)
			printf("rs232");
		else
			printf("rs232_%d", port);

		speed = PZL_SPEED(sstor.ss_console.dp_layers[0]);
		printf(".%d", i_speeds[speed]);

		bits = PZL_BITS(sstor.ss_console.dp_layers[0]);
		printf(".%d", bits);

		parity = PZL_PARITY(sstor.ss_console.dp_layers[0]);
		printf(".%s", parities[parity]);
	}

	printf("\n");
}

int
set_graphics(console, port, arg)
	struct device_path *console;
	int port;
	char *arg;
{
	int maxmode, mode = 0;
	char *digit;

	/* head */
	if (graphics[port].type == 0) {
		printf("no such device found\n");
		return 0;
	}

	/* mode */
	if (arg != NULL) {
		for (digit = arg; *digit != '\0'; digit++) {
			if (*digit >= '0' && *digit <= '9')
				mode = 10 * mode + (*digit - '0');
			else {
				printf("invalid mode specification, %s\n",
				    arg);
				return 0;
			}
		}

		if (mode <= 0) {
			printf("invalid mode specification, %s\n",
			    arg);
			return 0;
		}
	}

	/*
	 * If we are just changing the mode of the same graphics
	 * console, check that our mode is in the valid range.
	 */
	if (MATCH(graphics[port].dp, sstor.ss_console)) {
		maxmode = sstor.ss_console.dp_layers[1];

		/* pick back same mode if unspecified */
		if (mode == 0)
			mode = sstor.ss_console.dp_layers[0];

		if (mode > maxmode) {
			printf("invalid mode value, available range is 1-%d\n",
			    maxmode);
			return 0;
		}
	} else {
		if (mode == 0)
			mode = 1;
		maxmode = mode;
	}

	*console = graphics[port].dp;
	console->dp_layers[0] = mode;
	console->dp_layers[1] = maxmode;
	console->dp_layers[2] = console->dp_layers[3] =
	console->dp_layers[4] = console->dp_layers[5] = 0;

	return 1;
}

int
set_serial(console, port, arg)
	struct device_path *console;
	int port;
	char *arg;
{
	char *dot;
	int i;
	int speed, parity, bits;

	/* port */
	port--;
	if (serials[port].type == 0) {
		printf("no such device found\n");
		return 0;
	}

	/* speed */
	dot = strchr(arg, '.');
	if (dot != NULL)
		*dot++ = '\0';

	speed = 0;
	if (arg == NULL || *arg == '\0') {
		for (i = 0; i < nitems(i_speeds); i++)
			if (i_speeds[i] == 9600) {
				speed = i;
				break;
			}
	} else {
		for (i = 0; i < nitems(c_speeds); i++)
			if (strcmp(arg, c_speeds[i]) == 0) {
				speed = i;
				break;
			}
		if (speed == 0) {
			printf("invalid speed specification, %s\n", arg);
			return 0;
		}
	}

	/* data bits */
	arg = dot;
	dot = strchr(arg, '.');

	if (arg == NULL || *arg == '\0')
		bits = 8;
	else {
		if (dot == arg + 1)
			bits = *arg - '0';
		else
			bits = 0;

		if (bits < 5 || bits > 8) {
			printf("invalid bits specification, %s\n", arg);
			return 0;
		}
	}
	if (dot != NULL)
		*dot++ = '\0';

	/* parity */
	arg = dot;
	if (arg == NULL || *arg == '\0')
		parity = 0;	/* none */
	else {
		parity = -1;
		for (i = 0; i <= 3; i++)
			if (strcmp(arg, parities[i]) == 0) {
				parity = i;
				break;
			}
		if (parity == 2)
			parity = -1;	/* unknown parity */
	}
	if (parity < 0) {
		printf("invalid parity specification, %s\n", arg);
		return 0;
	}

	*console = serials[port].dp;
	console->dp_layers[0] = PZL_ENCODE(bits, parity, speed);

	return 1;
}

int
set_console(console)
	struct device_path *console;
{
	char *arg = cmd.argv[1], *dot;
	int port;

	/* extract first word */
	dot = strchr(arg, '.');
	if (dot != NULL)
		*dot++ = '\0';

	/*
	 * Graphics console
	 */
	if (strcmp(arg, "graphics") == 0)
		return set_graphics(console, 0, dot);
	if (strncmp(arg, "graphics_", 9) == 0) {
		port = arg[9] - '0';
		if (port > 0 && port < MAX_GRAPHICS)
			return set_graphics(console, port, dot);
	}

	/*
	 * Serial console
	 */
	if (strcmp(arg, "rs232") == 0)
		return set_serial(console, 1, dot);
	if (strncmp(arg, "rs232_", 6) == 0) {
		port = arg[6] - '0';
		if (port > 0 && port <= MAX_SERIALS)
			return set_serial(console, port, dot);
	}

	printf("invalid device specification, %s\n", arg);
	return 0;
}

int
Xconsole()
{
	struct device_path console;
	int rc;

	/* walk the device list if not already done */
	if (walked == 0) {
		bus_walk(NULL);
		walked++;
	}

	if (sstorsiz < CONSOLESIZE) {
		printf("no console information in stable storage\n");
		return 0;
	}

	if (cmd.argc == 1) {
		print_console();
	} else {
		console = sstor.ss_console;
		if (set_console(&console)) {
			if (memcmp(&sstor.ss_console, &console,
			    sizeof console) != 0) {
				sstor.ss_console = console;

				/* alea jacta est */
				rc = (*pdc)(PDC_STABLE, PDC_STABLE_WRITE,
				    CONSOLEOFFSET, &sstor.ss_console,
				    sizeof(sstor.ss_console));
				if (rc != 0) {
					printf("failed to save console settings, error %d\n",
					    rc);
					/* read sstor again for safety */
					(*pdc)(PDC_STABLE, PDC_STABLE_READ,
					    CONSOLEOFFSET, &sstor.ss_console,
					    sizeof(sstor.ss_console));
				} else
					printf("you will need to power-cycle "
					       "your machine for the changes "
					       "to take effect.\n");
			}
			print_console();
		}
	}

	return 0;
}

/*
 * K E Y B O A R D   S E T T I N G S
 */

void
print_keyboard()
{
	int type;
	int i;

#ifdef DEBUG
	printf("keyboard flags %x mod %x bc %d/%d/%d/%d/%d/%d\n",
	    sstor.ss_keyboard.dp_flags,
	    sstor.ss_keyboard.dp_mod,
	    sstor.ss_keyboard.dp_bc[0],
	    sstor.ss_keyboard.dp_bc[1],
	    sstor.ss_keyboard.dp_bc[2],
	    sstor.ss_keyboard.dp_bc[3],
	    sstor.ss_keyboard.dp_bc[4],
	    sstor.ss_keyboard.dp_bc[5]);

	printf("keyboard path %x/%x/%x/%x/%x/%x\n",
	    sstor.ss_keyboard.dp_layers[0],
	    sstor.ss_keyboard.dp_layers[1],
	    sstor.ss_keyboard.dp_layers[2],
	    sstor.ss_keyboard.dp_layers[3],
	    sstor.ss_keyboard.dp_layers[4],
	    sstor.ss_keyboard.dp_layers[5]);
#endif

	printf("Keyboard path: ");

	for (type = i = 0; i < MAX_KEYBOARDS; i++)
		if (MATCH(keyboards[i].dp, sstor.ss_keyboard)) {
			type = keyboards[i].type;
			break;
		}

	switch (type) {
	case HIL:
		printf("hil");
		break;
	case PS2:
		printf("ps2");
		break;
	default:
		printf("unknown");
		break;
	}

	printf("\n");
}

int
set_keyboard(keyboard)
	struct device_path *keyboard;
{
	int i;
	char *arg = cmd.argv[1];
	int type;

	if (strcmp(arg, "hil") == 0)
		type = HIL;
	else if (strcmp(arg, "ps2") == 0)
		type = PS2;
	else {
		printf("invalid device specification, %s\n", arg);
		return 0;
	}

	for (i = 0; i < MAX_KEYBOARDS; i++)
		if (keyboards[i].type == type) {
			*keyboard = keyboards[i].dp;
			return 1;
		}

	printf("no such device found\n");
	return 0;
}

int
Xkeyboard()
{
	struct device_path keyboard;
	int rc;

	/* walk the device list if not already done */
	if (walked == 0) {
		bus_walk(NULL);
		walked++;
	}

	if (sstorsiz < KEYBOARDSIZE) {
		printf("no keyboard information in stable storage\n");
		return 0;
	}

	if (cmd.argc == 1) {
		print_keyboard();
	} else {
		keyboard = sstor.ss_keyboard;
		if (set_keyboard(&keyboard)) {
			if (memcmp(&sstor.ss_keyboard, &keyboard,
			    sizeof keyboard) != 0) {
				sstor.ss_keyboard = keyboard;

				/* alea jacta est */
				rc = (*pdc)(PDC_STABLE, PDC_STABLE_WRITE,
				    KEYBOARDOFFSET, &sstor.ss_keyboard,
				    sizeof(sstor.ss_keyboard));
				if (rc != 0) {
					printf("failed to save keyboard settings, error %d\n",
					    rc);
					/* read sstor again for safety */
					(*pdc)(PDC_STABLE, PDC_STABLE_READ,
					    KEYBOARDOFFSET, &sstor.ss_keyboard,
					    sizeof(sstor.ss_keyboard));
				} else
					printf("you will need to power-cycle "
					       "your machine for the changes "
					       "to take effect.\n");
			}
			print_keyboard();
		}
	}

	return 0;
}

/*
 * U T I L I T I E S
 */

/*
 * Bus walker.
 * This routine will walk all the modules on a given bus, registering
 * serial ports, keyboard and graphics devices as they are found.
 */
void
bus_walk(struct device_path *idp)
{
	struct device_path dp;
	struct pdc_memmap memmap;
	struct iodc_data mptr;
	int err, i, kluge_ps2 = 0;	/* kluge, see below */

	for (i = 0; i < MAXMODBUS; i++) {

		if (idp) {
			dp.dp_bc[0] = idp->dp_bc[1];
			dp.dp_bc[1] = idp->dp_bc[2];
			dp.dp_bc[2] = idp->dp_bc[3];
			dp.dp_bc[3] = idp->dp_bc[4];
			dp.dp_bc[4] = idp->dp_bc[5];
			dp.dp_bc[5] = idp->dp_mod;
		} else {
			dp.dp_bc[0] = dp.dp_bc[1] = dp.dp_bc[2] =
			dp.dp_bc[3] = dp.dp_bc[4] = dp.dp_bc[5] = -1;
		}

		dp.dp_mod = i;
		if ((pdc)(PDC_MEMMAP, PDC_MEMMAP_HPA, &memmap, &dp) < 0 &&
		    (pdc)(PDC_SYSMAP, PDC_SYSMAP_HPA, &memmap, &dp) < 0)
			continue;

		if ((err = (pdc)(PDC_IODC, PDC_IODC_READ, &pdcbuf, memmap.hpa,
		    IODC_DATA, &mptr, sizeof(mptr))) < 0)
			continue;

#ifdef DEBUG
		printf("device %d/%d/%d/%d/%d/%d "
		    "flags %d mod %x type %x model %x\n",
		    dp.dp_bc[0], dp.dp_bc[1], dp.dp_bc[2], dp.dp_bc[3],
		    dp.dp_bc[4], dp.dp_bc[5], dp.dp_flags, dp.dp_mod,
		    mptr.iodc_type, mptr.iodc_sv_model);
#endif
		/*
		 * If the device can be considered as a valid rs232,
		 * graphics console or keyboard, register it.
		 *
		 * Unfortunately, devices which should be considered as
		 * ``main'' aren't necessarily seen first.
		 * The rules we try to enforce here are as follows:
		 * - GIO PS/2 ports wins over any other PS/2 port.
		 * - the first GIO serial found wins over any other
		 *   serial port.
		 * The second rule is a bit tricky to achieve, since on
		 * some machines (for example, 715/100XC), the two serial
		 * ports are not seen as attached to the same busses...
		 */
		switch (mptr.iodc_type) {
		case HPPA_TYPE_BCPORT:
			bus_walk(&dp);
			break;
		case HPPA_TYPE_BHA:
		case HPPA_TYPE_BRIDGE:
			/* if there was no phantomas here */
			if (dp.dp_bc[5] == -1) {
				dp.dp_bc[0] = dp.dp_bc[1];
				dp.dp_bc[1] = dp.dp_bc[2];
				dp.dp_bc[2] = dp.dp_bc[3];
				dp.dp_bc[3] = dp.dp_bc[4];
				dp.dp_bc[4] = dp.dp_bc[5];
				dp.dp_bc[5] = dp.dp_mod;
				dp.dp_mod = 0;
			}
			bus_walk(&dp);
			break;
		case HPPA_TYPE_ADIRECT:
			switch (mptr.iodc_sv_model) {
			case HPPA_ADIRECT_RS232:
				register_device(serials, MAX_SERIALS,
				    &dp, &mptr, SERIAL, 0);
				break;
			case HPPA_ADIRECT_HIL:
				register_device(keyboards, MAX_KEYBOARDS,
				    &dp, &mptr, HIL, 0);
				break;
			case HPPA_ADIRECT_PEACOCK:
			case HPPA_ADIRECT_LEONARDO:
				register_device(graphics, MAX_GRAPHICS,
				    &dp, &mptr, GRAPHICS, 0);
				break;
			}
			break;
		case HPPA_TYPE_FIO:
			switch (mptr.iodc_sv_model) {
			case HPPA_FIO_HIL:
				register_device(keyboards, MAX_KEYBOARDS,
				    &dp, &mptr, HIL, 0);
				break;
			case HPPA_FIO_RS232:
				register_device(serials, MAX_SERIALS,
				    &dp, &mptr, SERIAL, 0);
				break;
			case HPPA_FIO_DINOPCK:
				register_device(keyboards, MAX_KEYBOARDS,
				    &dp, &mptr, PS2, 0);
				break;
			case HPPA_FIO_GPCIO:
				/*
				 * KLUGE! At this point, there is no way to
				 * know if this port is the keyboard port or
				 * the mouse port.
				 * Let's assume the first port found is the
				 * keyboard, and ignore the others.
				 */
				if (kluge_ps2 != 0)
					break;
				register_device(keyboards, MAX_KEYBOARDS,
				    &dp, &mptr, PS2, 1);
				kluge_ps2++;
				break;
			case HPPA_FIO_GRS232:
			{
				int j, first;

				/*
				 * If a GIO serial port is already registered,
				 * register as extra port...
				 */
				first = 1;
				for (j = 0; j < MAX_SERIALS; j++)
					if (serials[j].type == SERIAL &&
					    serials[j].iodc_type ==
					      HPPA_TYPE_FIO &&
					    serials[j].iodc_model ==
					      HPPA_FIO_GRS232) {
						first = 0;
						break;
					}

				register_device(serials, MAX_SERIALS,
				    &dp, &mptr, SERIAL, first);
			}
				break;
			case HPPA_FIO_SGC:
				register_device(graphics, MAX_GRAPHICS,
				    &dp, &mptr, GRAPHICS, 0);
				break;
			case HPPA_FIO_GSGC:
				register_device(graphics, MAX_GRAPHICS,
				    &dp, &mptr, GRAPHICS, 1);
				break;
			}
			break;
		}
	}
}

void
register_device(devlist, cnt, dp, mptr, type, first)
	struct consoledev *devlist;
	int cnt;
	struct device_path *dp;
	struct iodc_data *mptr;
	int type;
	int first;
{
	int i;
	struct consoledev *dev;

	for (i = 0, dev = devlist; i < cnt; i++, dev++)
		if (dev->type == 0)
			break;

	if (i == cnt) {
#ifdef DEBUG
		printf("can't register device, need more room!\n");
#endif
		return;
	}

	/*
	 * If this is supposedly the main device, insert on top
	 */
	if (first != 0) {
		memcpy(devlist + 1, devlist,
		    (cnt - 1) * sizeof(struct consoledev));
		dev = devlist;
	}

	dev->dp = *dp;
	dev->type = type;
	dev->iodc_type = mptr->iodc_type;
	dev->iodc_model = mptr->iodc_sv_model;

#ifdef DEBUG
	printf("(registered as type %d)\n", type);
#endif
}


code:
/*	$OpenBSD: ct.c,v 1.1 2005/04/01 10:40:48 mickey Exp $	*/

/*
 * Copyright (c) 2005 Michael Shalayeff
 * All rights reserved.
 *
 * 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 MIND, 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 1996 1995 by Open Software Foundation, Inc.
 *              All Rights Reserved
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notice appears in all copies and
 * that both the copyright notice and this permission notice appear in
 * supporting documentation.
 *
 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE.
 *
 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "libsa.h"

#include <sys/param.h>
#include <sys/disklabel.h>
#include <sys/reboot.h>

#include <machine/pdc.h>
#include <machine/iomod.h>

#include "dev_hppa64.h"

int
ctopen(struct open_file *f, ...)
{
	struct hppa_dev *dp = f->f_devdata;

	if (!(dp->pz_dev = pdc_findev(-1, PCL_SEQU)))
		return (ENXIO);

	return (0);
}

/*ARGSUSED*/
int
ctclose(f)
	struct open_file *f;
{
	free (f->f_devdata, sizeof(struct hppa_dev));
	f->f_devdata = NULL;
	return 0;
}


code:
/*	$OpenBSD: dev_hppa64.c,v 1.8 2014/07/13 09:26:08 jasper Exp $	*/

/*
 * Copyright (c) 2005 Michael Shalayeff
 * All rights reserved.
 *
 * 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 MIND, 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 "libsa.h"
#include <sys/param.h>
#include <sys/disklabel.h>
#include <sys/reboot.h>
#include <dev/cons.h>

#include <machine/iomod.h>

#include "dev_hppa64.h"

extern int debug;

const char cdevs[][4] = {
	"ite", "", "", "", "", "", "", "",
	"", "", "", "", ""
};
const int ncdevs = nitems(cdevs);

const struct pdc_devs {
	char	name[3];
	int	dev_type;
} pdc_devs[] = {
	{ "dk",  0 },
	{ "ct",  1 },
	{ "lf",  2 },
	{ "",   -1 },
	{ "rd", -1 },
	{ "sw", -1 },
	{ "fl", -1 },
};

/* pass dev_t to the open routines */
int
devopen(f, fname, file)
	struct open_file *f;
	const char *fname;
	char **file;
{
	struct hppa_dev *hpd;
	const struct pdc_devs *dp = pdc_devs;
	int rc = 1;

	if (!(*file = strchr(fname, ':')))
		return ENODEV;
	else
		(*file)++;

#ifdef DEBUG
	if (debug)
		printf("devopen: ");
#endif

	for (dp = pdc_devs; dp < &pdc_devs[nitems(pdc_devs)]; dp++)
		if (!strncmp(fname, dp->name, sizeof(dp->name)-1))
			break;

	if (dp >= &pdc_devs[nitems(pdc_devs)] || dp->dev_type < 0)
		return ENODEV;
#ifdef DEBUG
	if (debug)
		printf("%s\n", dp->name);
#endif

	if (!(hpd = alloc(sizeof *hpd))) {
#ifdef DEBUG
		printf ("devopen: no mem\n");
#endif
	} else {
		bzero(hpd, sizeof *hpd);
		hpd->bootdev = bootdev;
		hpd->buf = (char *)(((u_long)hpd->ua_buf + IODC_MINIOSIZ-1) &
			~(IODC_MINIOSIZ-1));
		f->f_devdata = hpd;
		if ((rc = (*devsw[dp->dev_type].dv_open)(f, file)) == 0) {
			f->f_dev = &devsw[dp->dev_type];
			return 0;
		}
		free (hpd, 0);
		f->f_devdata = NULL;
	}

	if (!(f->f_flags & F_NODEV))
		f->f_dev = &devsw[dp->dev_type];

	if (!f->f_devdata)
		*file = NULL;

	return rc;
}

void
devboot(dev, p)
	dev_t dev;
	char *p;
{
	const char *q;
	int unit;

	if (!dev) {
		int type;

		switch (PAGE0->mem_boot.pz_class) {
		case PCL_RANDOM:
			type = 0;
			unit = PAGE0->mem_boot.pz_layers[0];
			break;
		case PCL_SEQU:
			type = 1;
			unit = PAGE0->mem_boot.pz_layers[0];
			break;
		case PCL_NET_MASK|PCL_SEQU:
			type = 2;
			unit = 0;
			break;
		default:
			type = 0;
			unit = 0;
			break;
		}
		dev = bootdev = MAKEBOOTDEV(type, 0, 0, unit, B_PARTITION(dev));
	}
#ifdef _TEST
	*p++ = '/';
	*p++ = 'd';
	*p++ = 'e';
	*p++ = 'v';
	*p++ = '/';
	*p++ = 'r';
#endif
	/* quick copy device name */
	for (q = pdc_devs[B_TYPE(dev)].name; (*p++ = *q++););
	unit = B_UNIT(dev);
	if (unit >= 10) {
		p[-1] = '0' + unit / 10;
		*p++ = '0' + (unit % 10);
	} else
		p[-1] = '0' + unit;
	*p++ = 'a' + B_PARTITION(dev);
	*p = '\0';
}

char ttyname_buf[8];
char *
ttyname(fd)
	int fd;
{
	snprintf(ttyname_buf, sizeof ttyname_buf, "%s%d",
	    cdevs[major(cn_tab->cn_dev)],
	    minor(cn_tab->cn_dev));
	return (ttyname_buf);
}

dev_t
ttydev(name)
	char *name;
{
	int i, unit = -1;
	char *no = name + strlen(name) - 1;

	while (no >= name && *no >= '0' && *no <= '9')
		unit = (unit < 0 ? 0 : (unit * 10)) + *no-- - '0';
	if (no < name || unit < 0)
		return (NODEV);
	for (i = 0; i < ncdevs; i++)
		if (strncmp(name, cdevs[i], no - name + 1) == 0)
			return (makedev(i, unit));
	return (NODEV);
}


code:
/*	$OpenBSD: dev_hppa64.h,v 1.2 2011/03/13 00:13:52 deraadt Exp $	*/

#define IOPGSHIFT	11
#define	IONBPG		(1 << IOPGSHIFT)
#define IOPGOFSET	(IONBPG - 1)

struct disklabel;
struct hppa_dev {
	dev_t	bootdev;
	struct pz_device *pz_dev;	/* device descriptor */
	daddr32_t fsoff;			/* offset to the file system */
	daddr32_t	last_blk;		/* byte offset for last read blk */
	size_t	last_read;		/* amount read last time */
	struct disklabel *label;
	/* buffer to cache data (aligned properly) */
	char	*buf;
	char	ua_buf[IODC_IOSIZ + IODC_MINIOSIZ];
};

#ifdef PDCDEBUG
#define	DEVPATH_PRINT(dp) \
	printf("%x, %d.%d.%d.%d.%d.%d, 0x%x, %x.%x.%x.%x.%x.%x\n", \
	       (dp)->dp_flags, (dp)->dp_bc[0], (dp)->dp_bc[1], (dp)->dp_bc[2], \
	       (dp)->dp_bc[3], (dp)->dp_bc[4], (dp)->dp_bc[5], (dp)->dp_mod, \
	       (dp)->dp_layers[0], (dp)->dp_layers[1], (dp)->dp_layers[2], \
	       (dp)->dp_layers[3], (dp)->dp_layers[4], (dp)->dp_layers[5]);
#define	PZDEV_PRINT(dp) \
	printf("devpath={%x, %d.%d.%d.%d.%d.%d, 0x%x, %x.%x.%x.%x.%x.%x}," \
	       "\n\thpa=%p, spa=%p, io=%p, class=%u\n", \
	       (dp)->pz_flags, (dp)->pz_bc[0], (dp)->pz_bc[1], (dp)->pz_bc[2], \
	       (dp)->pz_bc[3], (dp)->pz_bc[4], (dp)->pz_bc[5], (dp)->pz_mod, \
	       (dp)->pz_layers[0], (dp)->pz_layers[1], (dp)->pz_layers[2], \
	       (dp)->pz_layers[3], (dp)->pz_layers[4], (dp)->pz_layers[5], \
	       (dp)->pz_hpa, (dp)->pz_spa, (dp)->pz_iodc_io, (dp)->pz_class);
#endif

extern pdcio_t pdc;
extern int pdcbuf[];			/* PDC returns, pdc.c */

int iodc_rw(char *, u_int, u_int, int func, struct pz_device *);
const char *dk_disklabel(struct hppa_dev *dp, struct disklabel *label);
int pdc_call(void *, ...);


code:
/*	$OpenBSD: dk.c,v 1.2 2012/02/25 20:12:00 miod Exp $	*/

/*
 * Copyright 1996 1995 by Open Software Foundation, Inc.
 *              All Rights Reserved
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notice appears in all copies and
 * that both the copyright notice and this permission notice appear in
 * supporting documentation.
 *
 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE.
 *
 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "libsa.h"

#include <sys/param.h>
#include <sys/disklabel.h>
#include <sys/reboot.h>
#include <machine/pdc.h>
#include <machine/iomod.h>

#include "dev_hppa64.h"

const char *
dk_disklabel(struct hppa_dev *dp, struct disklabel *label)
{
	char buf[DEV_BSIZE];
	size_t ret;

	if (iodcstrategy(dp, F_READ, LABELSECTOR, DEV_BSIZE, buf, &ret))
		if (ret != DEV_BSIZE)
			return "cannot read disklabel";

	return (getdisklabel(buf, label));
}

int
dkopen(struct open_file *f, ...)
{
	struct disklabel *lp;
	struct hppa_dev *dp = f->f_devdata;
	const char *st;

#ifdef	DEBUG
	if (debug)
		printf("dkopen(%p)\n", f);
#endif

	if (!(dp->pz_dev = pdc_findev(-1, PCL_RANDOM)))
		return ENXIO;

	lp = dp->label;
	st = NULL;

#ifdef DEBUG
	if (debug)
		printf ("disklabel\n");
#endif

	if ((st = dk_disklabel(dp, lp)) != NULL) {
#ifdef DEBUG
		if (debug)
			printf ("dkopen: %s\n", st);
#endif
		/* we do not know if it's a disk or net, but do not fail */
	} else {
		u_int i;

		i = B_PARTITION(dp->bootdev);
		if (i >= lp->d_npartitions || !lp->d_partitions[i].p_size)
			return (EPART);

		dp->fsoff = lp->d_partitions[i].p_offset;
	}

#ifdef DEBUG
	if (debug)
		printf ("dkopen() ret\n");
#endif
	return (0);
}

int
dkclose(f)
	struct open_file *f;
{
	free (f->f_devdata, sizeof(struct hppa_dev));
	f->f_devdata = NULL;
	return 0;
}


code:
/*	$OpenBSD: itecons.c,v 1.4 2014/07/17 12:37:46 miod Exp $	*/

/*
 * Copyright (c) 2005 Michael Shalayeff
 * All rights reserved.
 *
 * 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 MIND, 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 1996 1995 by Open Software Foundation, Inc.
 *              All Rights Reserved
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notice appears in all copies and
 * that both the copyright notice and this permission notice appear in
 * supporting documentation.
 *
 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE.
 *
 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "libsa.h"

#include <sys/param.h>
#include <sys/disklabel.h>
#include <machine/pdc.h>
#include <machine/iomod.h>
#include <dev/cons.h>

#include "dev_hppa64.h"

iodcio_t cniodc;	/* console IODC entry point */
iodcio_t kyiodc;	/* keyboard IODC entry point */
pz_device_t *cons_pzdev, *kbd_pzdev;

/*
 * Console.
 */

char cnbuf[IODC_MINIOSIZ] __attribute__ ((aligned (IODC_MINIOSIZ)));
int kycode[IODC_MAXSIZE/sizeof(int)];

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

void
ite_probe(cn)
	struct consdev *cn;
{
	cniodc = (iodcio_t)(u_long)PAGE0->mem_free;
	cons_pzdev = &PAGE0->mem_cons;
	kbd_pzdev = &PAGE0->mem_kbd;

	if (pdc_call(pdc, PDC_IODC, PDC_IODC_READ, pdcbuf, cons_pzdev->pz_hpa,
		      IODC_INIT, cniodc, IODC_MAXSIZE) < 0 ||
	    pdc_call(cniodc, cons_pzdev->pz_hpa,
		      (cons_pzdev->pz_hpa==PAGE0->mem_boot.pz_hpa)?
			IODC_INIT_DEV: IODC_INIT_ALL, cons_pzdev->pz_spa,
			cons_pzdev->pz_layers, pdcbuf, 0,0,0,0) < 0 ||
	    pdc_call(pdc, PDC_IODC, PDC_IODC_READ, pdcbuf, cons_pzdev->pz_hpa,
		      IODC_IO, cniodc, IODC_MAXSIZE) < 0) {
		/* morse code with the LED's?!! */
		cons_pzdev->pz_iodc_io = kbd_pzdev->pz_iodc_io = NULL;
	} else {
		cn->cn_pri = CN_MIDPRI;
		cn->cn_dev = makedev(0, 0);
	}
}

void
ite_init(cn)
	struct consdev *cn;
{
	/*
	 * If the keyboard is separate from the console output device,
	 * we load the keyboard code at `kycode'.
	 *
	 * N.B. In this case, since the keyboard code is part of the
	 * boot code, it will be overwritten when we load a kernel.
	 */
	if (cons_pzdev->pz_class != PCL_DUPLEX ||
	    kbd_pzdev->pz_class == PCL_KEYBD) {

		kyiodc = (iodcio_t)kycode;

		if (pdc_call(pdc, PDC_IODC, PDC_IODC_READ, pdcbuf, kbd_pzdev->pz_hpa,
			      IODC_INIT, kyiodc, IODC_MAXSIZE) < 0 ||
		    pdc_call(kyiodc, kbd_pzdev->pz_hpa,
			      (kbd_pzdev->pz_hpa == PAGE0->mem_boot.pz_hpa ||
			       kbd_pzdev->pz_hpa == cons_pzdev->pz_hpa)?
			      IODC_INIT_DEV: IODC_INIT_ALL, kbd_pzdev->pz_spa,
			      kbd_pzdev->pz_layers, pdcbuf, 0, 0, 0, 0) < 0 ||
		    pdc_call(pdc, PDC_IODC, PDC_IODC_READ, pdcbuf, kbd_pzdev->pz_hpa,
			      IODC_IO, kyiodc, IODC_MAXSIZE))
			kyiodc = NULL;
	} else {
		kyiodc = cniodc;

		bcopy((char *)&PAGE0->mem_cons, (char *)&PAGE0->mem_kbd,
		      sizeof(struct pz_device));
	}

	cons_pzdev->pz_iodc_io = (u_long)cniodc;
	kbd_pzdev->pz_iodc_io = (u_long)kyiodc;
#ifdef DEBUG
	if (!kyiodc)
		printf("ite_init: no kbd\n");
#endif
}

void
ite_putc(dev, c)
	dev_t dev;
	int c;
{
	if (cniodc == NULL)
		return;

	*cnbuf = c;

	pdc_call(cniodc, cons_pzdev->pz_hpa, IODC_IO_CONSOUT,
	    cons_pzdev->pz_spa, cons_pzdev->pz_layers, pdcbuf, 0, cnbuf, 1, 0);
}

/*
 * since i don't know how to 'just check the char available'
 * i store the key into the stash removing on read op later;
 */
int
ite_getc(dev)
	dev_t dev;
{
	static int stash = 0;
	int err, c, l, i;

	if (kyiodc == NULL)
		return(0x100);

	if (stash) {
		c = stash;
		if (!(dev & 0x80))
			stash = 0;
		return c;
	}

	i = 16;
	do {
		err = pdc_call(kyiodc, kbd_pzdev->pz_hpa, IODC_IO_CONSIN,
		    kbd_pzdev->pz_spa, kbd_pzdev->pz_layers, pdcbuf,
		    0, cnbuf, 1, 0);
		l = pdcbuf[0];
		c = cnbuf[0];
#ifdef DEBUG
		if (debug && err < 0)
			printf("KBD input error: %d", err);
#endif

		/* if we are doing ischar() report immediately */
		if (!i-- && (dev & 0x80) && l == 0) {
#ifdef DEBUG
			if (debug > 2)
				printf("ite_getc(0x%x): no char %d(%x)\n",
				       dev, l, c);
#endif
			return (0);
		}
	} while(!l);

#if DEBUG
	if (debug && l > 1)
		printf("KBD input got too much (%d)\n", l);

	if (debug > 3)
		printf("kbd: \'%c\' (0x%x)\n", c, c);
#endif
	if (dev & 0x80)
		stash = c;

	return (c);
}

void
ite_pollc(dev, on)
	dev_t dev;
	int on;
{

}


code:
/*	$OpenBSD: lf.c,v 1.4 2014/07/12 21:03:38 tedu Exp $	*/

/*
 * Copyright (c) 2005 Michael Shalayeff
 * All rights reserved.
 *
 * 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 MIND, USE, DATA OR PROFITS, WHETHER IN
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <sys/param.h>
#include "libsa.h"
#include <machine/pdc.h>
#include <machine/iomod.h>

#include "dev_hppa64.h"

int
lfopen(struct open_file *f, ...)
{
	struct hppa_dev *dp = f->f_devdata;

	if (!(dp->pz_dev = pdc_findev(-1, PCL_NET_MASK|PCL_SEQU)))
		return ENXIO;

	return 0;
}

int
lfclose(struct open_file *f)
{
	free(f->f_devdata, sizeof(struct hppa_dev));
	f->f_devdata = NULL;
	return 0;
}


code:
/*	$OpenBSD: libsa.h,v 1.2 2011/03/13 00:13:52 deraadt Exp $	*/

/*
 * Copyright (c) 2005 Michael Shalayeff
 * All rights reserved.
 *
 * 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 MIND, 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	EXEC_ELF
#define	EXEC_SOM

#define	DEFAULT_KERNEL_ADDRESS	0

extern dev_t bootdev;

void pdc_init(void);
struct pz_device;
struct pz_device *pdc_findev(int, int);

int iodcstrategy(void *, int, daddr32_t, size_t, void *, size_t *);

int ctopen(struct open_file *, ...);
int ctclose(struct open_file *);

int dkopen(struct open_file *, ...);
int dkclose(struct open_file *);

int lfopen(struct open_file *, ...);
int lfstrategy(void *, int, daddr32_t, size_t, void *, size_t *);
int lfclose(struct open_file *);

void ite_probe(struct consdev *);
void ite_init(struct consdev *);
int ite_getc(dev_t);
void ite_putc(dev_t, int);
void ite_pollc(dev_t, int);

void machdep(void);
void devboot(dev_t, char *);
void fcacheall(void);
void run_loadfile(u_long *marks, int howto);

int lif_open(char *path, struct open_file *f);
int lif_close(struct open_file *f);
int lif_read(struct open_file *f, void *buf, size_t size, size_t *resid);
int lif_write(struct open_file *f, void *buf, size_t size, size_t *resid);
off_t lif_seek(struct open_file *f, off_t offset, int where);
int lif_stat(struct open_file *f, struct stat *sb);
int lif_readdir(struct open_file *f, char *name);

union x_header;
struct x_param;
int som_probe(int, union x_header *);
int som_load(int, struct x_param *);
int som_ldsym(int, struct x_param *);

extern int debug;

#define	MACHINE_CMD	cmd_machine	/* we have hppa specific commands */


code:
/*	$OpenBSD: lif.c,v 1.1 2005/04/01 10:40:48 mickey Exp $	*/

/*
 * Copyright (c) 2005 Michael Shalayeff
 * All rights reserved.
 *
 * 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 MIND, USE, DATA OR PROFITS, WHETHER IN
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <sys/param.h>
#include <sys/disklabel.h>
#include "libsa.h"

extern int debug;

struct file {
	char f_buf[LIF_FILESTART];/* buffer for lif volume header and dir */
	struct lifvol *f_lp;	/* lif volume header pointer */
	struct lifdir *f_ld;	/* lif dir pointer */
	int	f_nfiles;	/* gross number for lif dir entries */

	off_t	f_seek;		/* seek pointer for file read */
	struct lifdir *f_rd;	/* lif dir pointer for readdir */

	int	f_isdir;	/* special hacky flag for '.' dir */
	int	f_count;	/* this file length */
	int	f_off;		/* this file offset */
};

int
lif_open (path, f)
	char *path;
	struct open_file *f;
{
	struct file *fp;
	struct lifdir *dp;
	char *p, *q;
	struct lif_load load;
	size_t buf_size;
	int err, l;

#ifdef LIFDEBUG
	if (debug)
		printf("lif_open(%s, %p)\n", path, f);
#endif

	fp = alloc(sizeof(*fp));
	/* XXX we're assuming here that sizeof(fp->f_buf) >= LIF_FILESTART */
	if ((err = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, 0,
	    sizeof(fp->f_buf), &fp->f_buf, &buf_size)) ||
	    buf_size != sizeof(fp->f_buf)) {
#ifdef LIFDEBUG
		if (debug)
			printf("lif_open: unable to read LIF header (%d)\n", err);
#endif
	} else if ((fp->f_lp = (struct lifvol *)fp->f_buf)->vol_id == LIF_VOL_ID) {
		f->f_fsdata = fp;
		fp->f_ld = (struct lifdir *)(fp->f_buf + LIF_DIRSTART);
		fp->f_seek = 0;
		fp->f_rd = fp->f_ld;
		fp->f_nfiles = lifstob(fp->f_lp->vol_dirsize) /
			sizeof(struct lifdir);

		/* no dirs on the lif */
		for (p = path + (l = strlen(path)); p >= path; p--)
			if (*p == '/') {
				p++;
				break;
			}
		if (p > path)
			path = p;
	} else
		err = EINVAL;

	if (!err && *path != '.') {
		fp->f_isdir = 0;
		err = ENOENT;
		for (dp = fp->f_ld; dp < &fp->f_ld[fp->f_nfiles]; dp++) {
#ifdef LIFDEBUG
			if (debug)
				printf("lif_open: "
				       "%s <--> '%c%c%c%c%c%c%c%c%c%c'\n",
				       path, dp->dir_name[0], dp->dir_name[1],
				       dp->dir_name[2], dp->dir_name[3],
				       dp->dir_name[4], dp->dir_name[5],
				       dp->dir_name[6], dp->dir_name[7],
				       dp->dir_name[8], dp->dir_name[9]);
#endif
			for (p = path, q = dp->dir_name;
			     *q && *q != ' '; q++, p++)
				if (tolower(*q) != tolower(*p))
					break;
			if ((!*q || *q == ' ') && !*p) {
				err = 0;
				break;
			}
		}
		if (!err) {
			fp->f_off = lifstodb(dp->dir_addr);
			if (!(err =(f->f_dev->dv_strategy)(f->f_devdata, F_READ,
			      fp->f_off, sizeof(load), &load, &buf_size)) &&
			    buf_size == sizeof(load)) {
				/* no checksum */
				fp->f_count = load.count - sizeof(int);
				fp->f_off = dbtob(fp->f_off) + sizeof(load);
#ifdef LIFDEBUG
				if (debug)
					printf("lif_open: %u @ %u [%x]\n",
					       fp->f_count, fp->f_off,
					       load.address);
#endif
			} else if (!err)
				err = EIO;
		}
	} else
		fp->f_isdir = 1;

	if (err) {
		free (fp, sizeof(*fp));
		f->f_fsdata = NULL;
	}
#ifdef LIFDEBUG
	if (debug)
		printf("ret(%d)\n", err);
#endif
	return err;
}

int
lif_close(f)
	struct open_file *f;
{
	free (f->f_fsdata, sizeof(struct file));
	f->f_fsdata = NULL;
	return 0;
}

int
lif_read(f, buf, size, resid)
	struct open_file *f;
	void *buf;
	size_t size;
	size_t *resid;
{
	struct file *fp = (struct file *)f->f_fsdata;
	char *p;
	char bbuf[DEV_BSIZE];
	size_t bsize, count = sizeof(bbuf);
	int err = 0;
	int foff;

#ifdef LIFDEBUG
	if (debug)
		printf("lif_read(%p, %p, %u, %p)\n", f, buf, size, resid);
#endif

	for (p = bbuf; size; fp->f_seek += bsize, p += bsize) {
		twiddle();
		foff = fp->f_off + fp->f_seek;
		if (fp->f_seek >= fp->f_count ||
		    (err = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
		     btodb(foff), count, p, &bsize)))
			break;
		if (p == bbuf) {
			bsize = sizeof(bbuf) - (foff & (sizeof(bbuf) - 1));
			bsize = min(bsize, size);
			bcopy(bbuf + (foff & (sizeof(bbuf) - 1)), buf, bsize);
			p = buf;
		}
		count = size -= bsize;
	}
	if (resid)
		*resid = size;

	return err;
}

int
lif_write(f, buf, size, resid)
	struct open_file *f;
	void *buf;
	size_t size;
	size_t *resid;
{
	return EOPNOTSUPP;
}

off_t
lif_seek(f, offset, where)
	struct open_file *f;
	off_t offset;
	int where;
{
	struct file *fp = (struct file *)f->f_fsdata;

	switch (where) {
	case SEEK_SET:
		fp->f_seek = offset;
		break;
	case SEEK_CUR:
		fp->f_seek += offset;
		break;
	case SEEK_END:
		fp->f_seek = fp->f_count - offset;
		break;
	default:
		return (-1);
	}
	return (fp->f_seek);
}

int
lif_stat(f, sb)
	struct open_file *f;
	struct stat *sb;
{
	struct file *fp = (struct file *)f->f_fsdata;

	sb->st_mode = 0755 | (fp->f_isdir? S_IFDIR: 0);	/* XXX */
	sb->st_uid = 0;
	sb->st_gid = 0;
	sb->st_size = fp->f_count;
	return 0;
}

int
lif_readdir(f, name)
	struct open_file *f;
	char *name;
{
	struct file *fp = (struct file *)f->f_fsdata;
	char *p;

	if (name) {
		while ((fp->f_rd->dir_name[0] == ' ' ||
			!fp->f_rd->dir_name[0]) &&
		       (fp->f_rd - fp->f_ld) < fp->f_nfiles)
			fp->f_rd++;
		if ((fp->f_rd - fp->f_ld) >= fp->f_nfiles) {
			*name = '\0';
			return -1;
		}
		strncpy(name, fp->f_rd->dir_name, sizeof(fp->f_rd->dir_name));
		if ((p = strchr(name, ' ')))
			*p = '\0';
		fp->f_rd++;
	} else
		fp->f_rd = fp->f_ld;

	return 0;
}


code:
/*	$OpenBSD: machdep.c,v 1.1 2005/04/01 10:40:48 mickey Exp $	*/

/*
 * Copyright (c) 2005 Michael Shalayeff
 * All rights reserved.
 *
 * 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 MIND, USE, DATA OR PROFITS, WHETHER IN
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <sys/param.h>
#include <sys/disklabel.h>
#include <sys/reboot.h>
#include "libsa.h"
#include <machine/iomod.h>
#include <machine/pdc.h>

#include "dev_hppa64.h"

extern struct	stable_storage sstor;	/* contents of Stable Storage */
int howto;
dev_t bootdev;

void
machdep()
{
	pdc_init();
#ifdef notyet
	debug_init();
#endif
	cninit();

#ifdef PDCDEBUG
	if (debug) {
		int i;

		printf("SSTOR:\n");
		printf("pri_boot=");	DEVPATH_PRINT(&sstor.ss_pri_boot);
		printf("alt_boot=");	DEVPATH_PRINT(&sstor.ss_alt_boot);
		printf("console =");	DEVPATH_PRINT(&sstor.ss_console);
		printf("keyboard=");	DEVPATH_PRINT(&sstor.ss_keyboard);
		printf("mem=%d, fn=%s, osver=%d\nos={",
		       sstor.ss_fast_size, sstor.ss_filenames,
		       sstor.ss_os_version);
		for (i = 0; i < sizeof(sstor.ss_os); i++)
			printf ("%x%c", sstor.ss_os[i], (i%8)? ',' : '\n');

		printf("}\nPAGE0:\n");
		printf("ivec=%x, pf=%p[%u], toc=%p[%u], rndz=%p, clk/10ms=%u\n",
		       PAGE0->ivec_special, PAGE0->ivec_mempf,
		       PAGE0->ivec_mempflen, PAGE0->ivec_toc,
		       PAGE0->ivec_toclen, PAGE0->ivec_rendz,
		       PAGE0->mem_10msec);
		printf ("mem: cont=%u, phys=%u, pdc_spa=%u, resv=%u, free=%x\n"
			"cpu_hpa=%x, pdc=%p, imm_hpa=%p[%u,%u], soft=%u\n",
		       PAGE0->memc_cont, PAGE0->memc_phsize, PAGE0->memc_adsize,
		       PAGE0->memc_resv, PAGE0->mem_free, PAGE0->mem_hpa,
		       PAGE0->mem_pdc, PAGE0->imm_hpa, PAGE0->imm_spa_size,
		       PAGE0->imm_max_mem, PAGE0->imm_soft_boot);

		printf("console:  ");	PZDEV_PRINT(&PAGE0->mem_cons);
		printf("boot:     ");	PZDEV_PRINT(&PAGE0->mem_boot);
		printf("keyboard: ");	PZDEV_PRINT(&PAGE0->mem_kbd);
	}
#endif
}


code:
/*	$OpenBSD: pdc.c,v 1.3 2013/03/23 16:08:28 deraadt Exp $	*/

/*
 * Copyright (c) 2005 Michael Shalayeff
 * All rights reserved.
 *
 * 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 MIND, 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 1996 1995 by Open Software Foundation, Inc.
 *              All Rights Reserved
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notice appears in all copies and
 * that both the copyright notice and this permission notice appear in
 * supporting documentation.
 *
 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE.
 *
 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */
/*
 * Copyright (c) 1990 mt Xinu, Inc.  All rights reserved.
 * Copyright (c) 1990 University of Utah.  All rights reserved.
 *
 * This file may be freely distributed in any form as long as
 * this copyright notice is included.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 *	Utah $Hdr: pdc.c 1.8 92/03/14$
 */

#include <sys/param.h>
#include <sys/time.h>
#include "libsa.h"
#include <sys/reboot.h>
#include <sys/disklabel.h>

#include <machine/trap.h>
#include <machine/pdc.h>
#include <machine/iomod.h>
#include <machine/nvm.h>
#include <machine/cpufunc.h>

#include "dev_hppa64.h"

/*
 * Interface routines to initialize and access the PDC.
 */

pdcio_t pdc;
int	pdcbuf[64] PDC_ALIGNMENT;/* PDC return buffer */
struct	stable_storage sstor;	/* contents of Stable Storage */
int	sstorsiz;		/* size of Stable Storage */
struct bootdata bd;
int bdsize = sizeof(struct bootdata);

/*
 * Initialize PDC and related variables.
 */
void
pdc_init()
{
	int err;

	/*
	 * Initialize important global variables (defined above).
	 */
	pdc = (pdcio_t)(u_long)PAGE0->mem_pdc;

	err = pdc_call(pdc, PDC_STABLE, PDC_STABLE_SIZE, pdcbuf, 0, 0);
	if (err >= 0) {
		sstorsiz = min(pdcbuf[0],sizeof(sstor));
		err = (*pdc)(PDC_STABLE, PDC_STABLE_READ, 0, &sstor, sstorsiz);
	}

	/*
	 * Now that we (may) have an output device, if we encountered
	 * an error reading Stable Storage (above), let them know.
	 */
#ifdef DEBUG
	if (debug && err)
		printf("Stable storage PDC_STABLE Read Ret'd %d\n", err);
#endif

	/*
	 * Clear the FAULT light (so we know when we get a real one)
	 */
	pdc_call(pdc, PDC_CHASSIS, PDC_CHASSIS_DISP,
	    PDC_OSTAT(PDC_OSTAT_BOOT) | 0xCEC0);
}

/*
 * Generic READ/WRITE through IODC.  Takes pointer to PDC device
 * information, returns (positive) number of bytes actually read or
 * the (negative) error condition, or zero if at "EOF".
 */
int
iodcstrategy(devdata, rw, blk, size, buf, rsize)
	void *devdata;
	int rw;
	daddr32_t blk;
	size_t size;
	void *buf;
	size_t *rsize;
{
	struct hppa_dev *dp = devdata;
	struct pz_device *pzdev = dp->pz_dev;
	iodcio_t iodc = (iodcio_t)(u_long)pzdev->pz_iodc_io;
	int	offset, xfer, ret;

#ifdef PDCDEBUG
	if (debug)
		printf("iodcstrategy(%p, %s, %u, %u, %p, %p)\n", devdata,
		    rw==F_READ? "READ" : "WRITE", blk, size, buf, rsize);

	if (debug > 1)
		PZDEV_PRINT(pzdev);
#endif

	blk += dp->fsoff;
	blk *= DEV_BSIZE;
	if ((pzdev->pz_class & PCL_CLASS_MASK) == PCL_SEQU) {
		/* rewind and re-read to seek */
		if (blk < dp->last_blk) {
#ifdef PDCDEBUG
			if (debug)
				printf("iodc: rewind ");
#endif
			if ((ret = ((iodcio_t)(long)pzdev->pz_iodc_io)(
			    pzdev->pz_hpa, IODC_IO_READ, pzdev->pz_spa,
			    pzdev->pz_layers, pdcbuf, 0, dp->buf, 0, 0)) < 0) {
#ifdef DEBUG
				if (debug)
					printf("IODC_IO: %d\n", ret);
#endif
				return (EIO);
			} else {
				dp->last_blk = 0;
				dp->last_read = 0;
			}
		}

#ifdef PDCDEBUG
		if (debug)
			printf("seek %d ", dp->last_blk);
#endif
		for (; (dp->last_blk + dp->last_read) <= blk;
		     dp->last_read = ret) {
			twiddle();
			dp->last_blk += dp->last_read;
			if ((ret = (iodc)(pzdev->pz_hpa,
			    IODC_IO_READ, pzdev->pz_spa, pzdev->pz_layers,
			    pdcbuf, dp->last_blk, dp->buf, IODC_IOSIZ,
			    IODC_IOSIZ)) < 0) {
#ifdef DEBUG
				if (debug)
					printf("IODC_IO: %d\n", ret);
#endif
				return (EIO);
			}
			if ((ret = pdcbuf[0]) == 0)
				break;
#ifdef PDCDEBUG
			if (debug)
				printf("-");
#endif
		}
#ifdef PDCDEBUG
		if (debug)
			printf("> %d[%d]\n", dp->last_blk, dp->last_read);
#endif
	}

	xfer = 0;
	/* see if we can scratch anything from buffer */
	if (dp->last_blk <= blk && (dp->last_blk + dp->last_read) > blk) {
		twiddle();
		offset = blk - dp->last_blk;
		xfer = min(dp->last_read - offset, size);
		size -= xfer;
		blk += xfer;
#ifdef PDCDEBUG
		if (debug)
			printf("off=%d,xfer=%d,size=%d,blk=%d\n",
			    offset, xfer, size, blk);
#endif
		bcopy(dp->buf + offset, buf, xfer);
		buf += xfer;
	}

	/*
	 * double buffer it all the time, to cache
	 */
	for (; size; size -= ret, buf += ret, blk += ret, xfer += ret) {
		offset = blk & IOPGOFSET;
		if ((ret = (iodc)(pzdev->pz_hpa,
		    (rw == F_READ? IODC_IO_READ: IODC_IO_WRITE),
		    pzdev->pz_spa, pzdev->pz_layers, pdcbuf,
		    blk - offset, dp->buf, IODC_IOSIZ, IODC_IOSIZ)) < 0) {
#ifdef DEBUG
			if (debug)
				printf("iodc_read(%d,%d): %d\n",
				    blk - offset, IODC_IOSIZ, ret);
#endif
			if (xfer)
				break;
			else
				return (EIO);
		}
		if ((ret = pdcbuf[0]) <= 0)
			break;
		dp->last_blk = blk - offset;
		dp->last_read = ret;
		if ((ret -= offset) > size)
			ret = size;
		bcopy(dp->buf + offset, buf, ret);
#ifdef PDCDEBUG
		if (debug)
			printf("read %d(%d,%d)@%x ", ret,
			    dp->last_blk, dp->last_read, (u_int)buf);
#endif
	    }

#ifdef PDCDEBUG
	if (debug)
		printf("\n");
#endif

	if (rsize)
		*rsize = xfer;
	return (0);
}

/*
 * Find a device with specified unit number
 * (any if unit == -1), and of specified class (PCL_*).
 */
struct pz_device *
pdc_findev(unit, class)
	int unit, class;
{
	static struct pz_device pz;
	int layers[sizeof(pz.pz_layers)/sizeof(pz.pz_layers[0])];
	iodcio_t iodc;
	int err = 0;
	u_int hpa, spa;

#ifdef	PDCDEBUG
	if (debug)
		printf("pdc_finddev(%d, %x)\n", unit, class);
#endif
	iodc = (iodcio_t)((u_long)PAGE0->mem_free + IODC_MAXSIZE);
	hpa = PAGE0->mem_boot.pz_hpa;
	spa = ((struct iomod *)(u_long)hpa)->io_spa;

	/* quick hack for boot device */
	if (PAGE0->mem_boot.pz_class == class &&
	    (unit == -1 || PAGE0->mem_boot.pz_layers[0] == unit)) {

		bcopy (&PAGE0->mem_boot.pz_dp, &pz.pz_dp, sizeof(pz.pz_dp));
		bcopy (pz.pz_layers, layers, sizeof(layers));
		if ((err = (pdc)(PDC_IODC, PDC_IODC_READ, pdcbuf, hpa,
		    IODC_INIT, iodc, IODC_MAXSIZE)) < 0) {
#ifdef DEBUG
			if (debug)
				printf("IODC_READ: %d\n", err);
#endif
			return NULL;
		}
	} else {
		struct pdc_memmap memmap;
		struct iodc_data mptr;
		int i, stp;

		for (i = 0; i < 0xf; i++) {
			pz.pz_bc[0] = pz.pz_bc[1] =
			pz.pz_bc[2] = pz.pz_bc[3] = -1;
			pz.pz_bc[4] = 2;
			pz.pz_bc[5] = 0;	/* core bus */
			pz.pz_mod = i;
			if ((pdc)(PDC_MEMMAP, PDC_MEMMAP_HPA, &memmap,
			    &pz.pz_dp) < 0)
				continue;
#ifdef PDCDEBUG
			if (debug)
				printf("memap: %d.%d.%d, hpa=%x, mpgs=%x\n",
				    pz.pz_bc[4], pz.pz_bc[5], pz.pz_mod,
				    memmap.hpa, memmap.morepages);
#endif
			hpa = memmap.hpa;

			if ((err = (pdc)(PDC_IODC, PDC_IODC_READ, &pdcbuf, hpa,
			    IODC_DATA, &mptr, sizeof(mptr))) < 0) {
#ifdef DEBUG
				if (debug)
					printf("IODC_DATA: %d\n", err);
#endif
				continue;
			}

			if ((err = (pdc)(PDC_IODC, PDC_IODC_READ, pdcbuf, hpa,
			    IODC_INIT, iodc, IODC_MAXSIZE)) < 0) {
#ifdef DEBUG
				if (debug)
					printf("IODC_READ: %d\n", err);
#endif
				continue;
			}

			stp = IODC_INIT_FIRST;
			do {
				if ((err = (iodc)(hpa, stp, spa, layers,
				    pdcbuf, 0, 0, 0, 0)) < 0) {
#ifdef DEBUG
					if (debug && err != PDC_ERR_EOD)
						printf("IODC_INIT_%s: %d\n",
						    stp==IODC_INIT_FIRST?
						    "FIRST":"NEXT", err);
#endif
					break;
				}
#ifdef PDCDEBUG
				if (debug)
					printf("[%x,%x,%x,%x,%x,%x], "
					    "[%x,%x,%x,%x,%x,%x]\n",
					    pdcbuf[0], pdcbuf[1], pdcbuf[2],
					    pdcbuf[3], pdcbuf[4], pdcbuf[5],
					    layers[0], layers[1], layers[2],
					    layers[3], layers[4], layers[5]);
#endif
				stp = IODC_INIT_NEXT;

			} while (pdcbuf[1] != class &&
				 unit != -1 && unit != layers[0]);

			if (err >= 0)
				break;
		}
	}

	if (err >= 0) {
		/* init device */
		if (0  && (err = (iodc)(hpa, IODC_INIT_DEV, spa,
		    layers, pdcbuf, 0, 0, 0, 0)) < 0) {
#ifdef DEBUG
			if (debug)
				printf("INIT_DEV: %d\n", err);
#endif
			return NULL;
		}

		/* read i/o entry code */
		if ((err = (pdc)(PDC_IODC, PDC_IODC_READ, pdcbuf, hpa,
		    IODC_IO, iodc, IODC_MAXSIZE)) < 0) {
#ifdef DEBUG
			if (debug)
				printf("IODC_READ: %d\n", err);
#endif
			return NULL;
		}

		pz.pz_flags = 0;
		bcopy(layers, pz.pz_layers, sizeof(pz.pz_layers));
		pz.pz_hpa = hpa;
/* XXX		pz.pz_spa = spa; */
		pz.pz_iodc_io = (u_long)iodc;
		pz.pz_class = class;

		return &pz;
	}

	return NULL;
}

static __inline void
fall(int c_base, int c_count, int c_loop, int c_stride, int data)
{
        int loop;                  /* Internal vars */

        for (; c_count--; c_base += c_stride)
                for (loop = c_loop; loop--; )
			if (data)
				fdce(0, c_base);
			else
				fice(0, c_base);
}

/*
 * fcacheall - Flush all caches.
 *
 * This routine is just a wrapper around the real cache flush routine.
 */
struct pdc_cache pdc_cacheinfo PDC_ALIGNMENT;

void
fcacheall()
{
	int err;

        if ((err = (*pdc)(PDC_CACHE, PDC_CACHE_DFLT, &pdc_cacheinfo)) < 0) {
#ifdef DEBUG
		if (debug)
			printf("fcacheall: PDC_CACHE failed (%d).\n", err);
#endif
		return;
        }
#if PDCDEBUG
	if (debug)
		printf("pdc_cache:\nic={%u,%x,%x,%u,%u,%u}\n"
		       "dc={%u,%x,%x,%u,%u,%u}\n",
		       pdc_cacheinfo.ic_size, *(u_int *)&pdc_cacheinfo.ic_conf,
		       pdc_cacheinfo.ic_base, pdc_cacheinfo.ic_stride,
		       pdc_cacheinfo.ic_count, pdc_cacheinfo.ic_loop,
		       pdc_cacheinfo.dc_size, *(u_int *)&pdc_cacheinfo.ic_conf,
		       pdc_cacheinfo.dc_base, pdc_cacheinfo.dc_stride,
		       pdc_cacheinfo.dc_count, pdc_cacheinfo.dc_loop);
#endif
        /*
         * Flush the instruction, then data cache.
         */
        fall(pdc_cacheinfo.ic_base, pdc_cacheinfo.ic_count,
	     pdc_cacheinfo.ic_loop, pdc_cacheinfo.ic_stride, 0);
	sync_caches();
        fall(pdc_cacheinfo.dc_base, pdc_cacheinfo.dc_count,
	     pdc_cacheinfo.dc_loop, pdc_cacheinfo.dc_stride, 1);
	sync_caches();
}


code:
/*	$OpenBSD: time.c,v 1.1 2005/04/01 10:40:48 mickey Exp $	*/

/*
 * Copyright (c) 2005 Michael Shalayeff
 * All rights reserved.
 *
 * 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 MIND, USE, DATA OR PROFITS, WHETHER IN
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <sys/types.h>
#include <machine/pdc.h>
#include <sys/disklabel.h>
#include "libsa.h"
#include "dev_hppa64.h"

time_t
getsecs()
{
	time_t tt;
	int err;

	if ((err = (*pdc)(PDC_TOD, PDC_TOD_READ, &pdcbuf)) < 0) {
		tt = 0;
#ifdef DEBUG
		if (debug)
			printf("getsecs: TOD read failed (%d)\n", err);
#endif
	} else {
		tt = ((struct pdc_tod *)pdcbuf)->sec;
#ifdef DEBUG
		if (debug && tt < 800000000)
			printf("getsecs: got %u seconds\n", tt);
#endif
	}

	return tt;
}


code:
/Makefile/1.2/Tue Aug 21 14:46:18 2012//TOPENBSD_5_8_BASE
D


code:
#	$OpenBSD: Makefile,v 1.2 2012/08/21 14:46:18 pascal Exp $

S=${.CURDIR}/../../../..
ZDST=${.OBJDIR}
SADIR=${.CURDIR}/..

NOPIE=

.PATH: ${S}/lib/libz

.include "${S}/lib/libz/Makefile"
CFLAGS+=${SACFLAGS} -I${S}/lib/libsa


code:
#	$OpenBSD: Makefile,v 1.1 2005/04/01 10:40:49 mickey Exp $

MAN=	mkboot.8
MANSUBDIR=hppa64

.if ${MACHINE} == "hppa64"
PROG=	mkboot
CC=	${HOSTCC}
LDSTATIC=	-static
.else
NOPROG=
.endif

.include <bsd.prog.mk>


code:
/*	$OpenBSD: mkboot.c,v 1.5 2014/09/24 00:13:13 doug 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.
 *
 *	@(#)mkboot.c	8.1 (Berkeley) 7/15/93
 */

#include <sys/param.h>
#include <sys/exec.h>
#include <sys/exec_elf.h>
#include <sys/file.h>
#include <sys/stat.h>

#include <ctype.h>
#include <err.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#ifndef hppa
/* hack for cross compile XXX */
#include "../../include/disklabel.h"
#else
#include <sys/disklabel.h>
#endif

int putfile(char *, int);
void __dead usage(void);
void bcddate(char *, char *);
char *lifname(char *);
int cksum(int, int *, int);

char *to_file;
int loadpoint, verbose;
u_long entry;

/*
 * Old Format:
 *	sector 0:	LIF volume header (40 bytes)
 *	sector 1:	<unused>
 *	sector 2:	LIF directory (8 x 32 == 256 bytes)
 *	sector 3-:	LIF file 0, LIF file 1, etc.
 * where sectors are 256 bytes.
 *
 * New Format:
 *	sector 0:	LIF volume header (40 bytes)
 *	sector 1:	<unused>
 *	sector 2:	LIF directory (8 x 32 == 256 bytes)
 *	sector 3:	<unused>
 *	sector 4-31:	disklabel (~300 bytes right now)
 *	sector 32-:	LIF file 0, LIF file 1, etc.
 */
int
main(int argc, char **argv)
{
	int to;
	register int n, pos, c;
	char buf[LIF_FILESTART];
	struct lifvol *lifv = (struct lifvol *)buf;
	struct lifdir *lifd = (struct lifdir *)(buf + LIF_DIRSTART);

	while ((c = getopt(argc, argv, "vl:")) != -1) {
		switch (c) {
		case 'v':
			verbose++;
			break;
		case 'l':
			sscanf(optarg, "0x%x", &loadpoint);
			break;
		default:
			usage();
		}
	}
	if (argc - optind < 2)
		usage();
	else if (argc - optind > 8)
		errx(1, "too many boot programs (max 8 supported)");

	to_file = argv[--argc];
	if ((to = open(to_file, O_RDWR | O_TRUNC | O_CREAT, 0644)) < 0)
		err(1, "%s: open", to_file);

	bzero(buf, sizeof(buf));
	/* clear possibly unused directory entries */
	memset(lifd[1].dir_name, ' ', sizeof lifd[1].dir_name);
	lifd[1].dir_type = -1;
	lifd[1].dir_addr = 0;
	lifd[1].dir_length = 0;
	lifd[1].dir_flag = 0xFF;
	lifd[1].dir_implement = 0;
	lifd[7] = lifd[6] = lifd[5] = lifd[4] = lifd[3] = lifd[2] = lifd[1];

	/* record volume info */
	lifv->vol_id = htobe16(LIF_VOL_ID);
	strncpy(lifv->vol_label, "BOOT44", 6);
	lifv->vol_addr = htobe32(btolifs(LIF_DIRSTART));
	lifv->vol_oct = htobe16(LIF_VOL_OCT);
	lifv->vol_dirsize = htobe32(btolifs(LIF_DIRSIZE));
	lifv->vol_version = htobe16(1);
	lifv->vol_lastvol = lifv->vol_number =  htobe16(1);
	lifv->vol_length = LIF_FILESTART;
	bcddate(to_file, lifv->vol_toc);
	lifv->ipl_addr = htobe32(LIF_FILESTART);
	lifv->ipl_size = 0;
	lifv->ipl_entry = 0;

	argv += optind;
	argc -= optind;
	optind = 0;
	for (pos = LIF_FILESTART; optind < argc; optind++) {

		/* output bootfile */
		lseek(to, pos, 0);
		lifd[optind].dir_addr = htobe32(btolifs(pos));
		n = btolifs(putfile(argv[optind], to));
		if (lifv->ipl_entry == 0) {
			lifv->ipl_entry = htobe32(loadpoint + entry);
			lifv->ipl_size = htobe32(lifstob(n));
			lifd[optind].dir_type = htobe16(LIF_DIR_ISL);
			lifd[optind].dir_implement = 0;
		} else {
			lifd[optind].dir_type = htobe16(LIF_DIR_TYPE);
			lifd[1].dir_implement = htobe32(loadpoint + entry);
		}

		strlcpy(lifd[optind].dir_name, lifname(argv[optind]),
		    sizeof lifd[optind].dir_name);
		lifd[optind].dir_length = htobe32(n);
		bcddate(argv[optind], lifd[optind].dir_toc);
		lifd[optind].dir_flag = htobe16(LIF_DIR_FLAG);

		lifv->vol_length += n;
		pos += lifstob(n);
	}

	lifv->vol_length = htobe32(lifv->vol_length);

	/* output volume/directory header info */
	lseek(to, LIF_VOLSTART, 0);
	if (write(to, buf, sizeof(buf)) != sizeof(buf))
		err(1, "%s: write LIF volume", to_file);
	lseek(to, 0, SEEK_END);

	if (close(to) < 0)
		err(1, "%s", to_file);

	return (0);
}

int
putfile(char *from_file, int to)
{
	struct exec ex;
	register int n, total;
	char buf[2048];
	int from, check_sum = 0;
	struct lif_load load;

	if ((from = open(from_file, O_RDONLY)) < 0)
		err(1, "%s", from_file);

	n = read(from, &ex, sizeof(ex));
	if (n != sizeof(ex))
		err(1, "%s: reading file header", from_file);

	entry = ex.a_entry;
	if (N_GETMAGIC(ex) == OMAGIC || N_GETMAGIC(ex) == NMAGIC)
		entry += sizeof(ex);
	else if (IS_ELF(*(Elf64_Ehdr *)&ex)) {
		Elf64_Ehdr elf_header;
		Elf64_Phdr *elf_segments;
		int i,header_count, memory_needed, elf_load_image_segment;

		(void) lseek(from, 0, SEEK_SET);
		n = read(from, &elf_header, sizeof (elf_header));
		if (n != sizeof (elf_header))
			err(1, "%s: reading ELF header", from_file);
		header_count = betoh32(elf_header.e_phnum);
		elf_segments = reallocarray(NULL, header_count,
		    sizeof(*elf_segments));
		if (elf_segments == NULL)
			err(1, "malloc");
		memory_needed = header_count * sizeof(*elf_segments);
		(void) lseek(from, betoh32(elf_header.e_phoff), SEEK_SET);
		n = read(from, elf_segments, memory_needed);
		if (n != memory_needed)
			err(1, "%s: reading ELF segments", from_file);
		elf_load_image_segment = -1;
		for (i = 0; i < header_count; i++) {
			if (elf_segments[i].p_filesz &&
			    elf_segments[i].p_type == htobe32(PT_LOAD) &&
			    elf_segments[i].p_flags & htobe32(PF_X)) {
				if (elf_load_image_segment != -1)
					warnx("%s: more than one ELF program segment", from_file);
				else
					elf_load_image_segment = i;
			}
		}
		if (elf_load_image_segment == -1)
			errx(1, "%s: no suitable ELF program segment", from_file);
		entry = betoh32(elf_header.e_entry) +
			betoh32(elf_segments[elf_load_image_segment].p_offset) -
			betoh32(elf_segments[elf_load_image_segment].p_vaddr);
	} else if (*(u_char *)&ex == 0x1f && ((u_char *)&ex)[1] == 0x8b) {
		entry = 0;
	} else
		errx(1, "%s: bad magic number", from_file);

	entry += sizeof(load);
	lseek(to, sizeof(load), SEEK_CUR);
	total = 0;
	n = sizeof(buf) - sizeof(load);
	/* copy the whole file */
	for (lseek(from, 0, 0); ; n = sizeof(buf)) {
		bzero(buf, sizeof(buf));
		if ((n = read(from, buf, n)) < 0)
			err(1, "%s", from_file);
		else if (n == 0)
			break;

		if (write(to, buf, n) != n)
			err(1, "%s", to_file);

		total += n;
		check_sum = cksum(check_sum, (int *)buf, n);
	}

	/* load header */
	load.address = htobe32(loadpoint + sizeof(load));
	load.count = htobe32(4 + total);
	check_sum = cksum(check_sum, (int *)&load, sizeof(load));

	if (verbose)
		warnx("wrote %d bytes of file \'%s\'", total, from_file);

	total += sizeof(load);
	/* insert the header */
	lseek(to, -total, SEEK_CUR);
	if (write(to, &load, sizeof(load)) != sizeof(load))
		err(1, "%s", to_file);
	lseek(to, total - sizeof(load), SEEK_CUR);

	bzero(buf, sizeof(buf));
	/* pad to int */
	n = sizeof(int) - total % sizeof(int);
	if (total % sizeof(int)) {
		if (write(to, buf, n) != n)
			err(1, "%s", to_file);
		else
			total += n;
	}

	/* pad to the blocksize */
	n = sizeof(buf) - total % sizeof(buf);

	if (n < sizeof(int)) {
		n += sizeof(buf);
		total += sizeof(buf);
	} else
		total += n;

	/* TODO should pad here to the 65k boundary for tape boot */

	if (verbose)
		warnx("checksum is 0x%08x", -check_sum);

	check_sum = htobe32(-check_sum);
	if (write(to, &check_sum, sizeof(int)) != sizeof(int))
		err(1, "%s", to_file);

	n -= sizeof(int);

	if (write(to, buf, n) != n)
		err(1, "%s", to_file);

	if (close(from) < 0 )
		err(1, "%s", from_file);

	return total;
}

int
cksum(int ck, int *p, int size)
{
	/* we assume size is int-aligned */
	for (size = (size + sizeof(int) - 1) / sizeof(int); size--; p++ )
		ck += betoh32(*p);

	return ck;
}

void __dead
usage(void)
{
	extern char *__progname;
	fprintf(stderr,
		"usage: %s [-v] [-l loadpoint] prog1 {progN} outfile\n",
		__progname);
	exit(1);
}

char *
lifname(char *str)
{
	static char lname[10] = "XXXXXXXXXX";
	register int i;

	for (i = 0; i < 9; i++) {
		if (islower(*str))
			lname[i] = toupper(*str);
		else if (isalnum(*str) || *str == '_')
			lname[i] = *str;
		else
			break;
		str++;
	}
	for ( ; i < 10; i++)
		lname[i] = ' ';
	return(lname);
}

void
bcddate(char *file, char *toc)
{
	struct stat statb;
	struct tm *tm;

	stat(file, &statb);
	tm = localtime(&statb.st_ctime);
	*toc = (tm->tm_year / 10) << 4;
	*toc++ |= tm->tm_year % 10;
	*toc = ((tm->tm_mon+1) / 10) << 4;
	*toc++ |= (tm->tm_mon+1) % 10;
	*toc = (tm->tm_mday / 10) << 4;
	*toc++ |= tm->tm_mday % 10;
	*toc = (tm->tm_hour / 10) << 4;
	*toc++ |= tm->tm_hour % 10;
	*toc = (tm->tm_min / 10) << 4;
	*toc++ |= tm->tm_min % 10;
	*toc = (tm->tm_sec / 10) << 4;
	*toc |= tm->tm_sec % 10;
}


code:
#	$OpenBSD: Makefile,v 1.21 2013/12/08 14:46:39 espie Exp $

S=	${.CURDIR}/../..
KFILE=	GENERIC
.if exists(conf/GENERIC.MP)
KFILE=	GENERIC.MP
.endif
TDIRS=	${_arch} include pci isa eisa
TAGS=	${.CURDIR}/tags

NOPROG=
NOMAN=
NOOBJ=
SUBDIR=	stand

# config the fattest kernel we can find into a temporary dir
# to create a Makefile.  Then use make to pull some variables
# out and push them into the sub-shell to expand the paths,
# and finally run ctags.
tags::
	TDIR=`mktemp -d /tmp/_tagXXXXXXXXXX` || exit 1; \
	eval "S=${S}" && \
	config -s ${S} -b $${TDIR} ${.CURDIR}/conf/${KFILE} && \
	eval "_arch=\"`make -V _arch -f $${TDIR}/Makefile`\"" && \
	eval "_mach=\"`make -V _mach -f $${TDIR}/Makefile`\"" && \
	eval "_machdir=\$S/arch/$${_mach}" && \
	eval "_archdir=\$S/arch/$${_arch}" && \
	eval "HFILES=\"`find $S \( -path $S/'arch' -o -path $S/stand -o -path $S/lib/libsa -o -path $S'/lib/libkern/arch' \) -prune -o -name '*.h'; find $${_machdir} $${_archdir} $S/lib/libkern/arch/$${_mach} \( -name boot -o -name stand \) -prune -o -name '*.h'`\"" && \
	eval "SFILES=\"`make -V SFILES -f $${TDIR}/Makefile`\"" && \
	eval "CFILES=\"`make -V CFILES -f $${TDIR}/Makefile`\"" && \
	eval "AFILES=\"`make -V AFILES -f $${TDIR}/Makefile`\"" && \
	ctags -wd -f ${TAGS} $${CFILES} $${HFILES} && \
	egrep "^[_A-Z]*ENTRY[_A-Z]*\(.*\)" $${SFILES} $${AFILES} | \
	    sed "s;\\([^:]*\\):\\([^(]*\\)(\\([^, )]*\\)\\(.*\\);\\3	\\1	/^\\2(\\3\\4$$/;" \
	    >> ${TAGS} && \
	sort -o ${TAGS} ${TAGS} && \
	rm -rf $${TDIR}

links:
	-for i in conf ${TDIRS}; do \
	    (cd $$i && rm -f tags; ln -s tags tags); done

obj:	_SUBDIRUSE

.include <bsd.prog.mk>


code:
GENERIC
GENERIC.MP
RAMDISK
RAMDISK_CD