code:
/*	$OpenBSD: scifcons.c,v 1.6 2014/07/17 13:14:06 miod Exp $	*/
/*	$NetBSD: scifcons.c,v 1.1 2006/09/01 21:26:18 uwe Exp $ */
/*	NetBSD: scif.c,v 1.38 2004/12/13 02:14:13 chs Exp */

/*-
 * Copyright (C) 1999 T.Horiuchi and SAITOH Masanobu.  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. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/*-
 * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Charles M. Hannum.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
/*
 * Copyright (c) 1991 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.
 *
 *	@(#)com.c	7.5 (Berkeley) 5/16/91
 */
/*
 * SH internal serial driver
 *
 * This code is derived from both z8530tty.c and com.c
 */

#include <libsa.h>
#include <dev/cons.h>

#include <arch/sh/dev/scifreg.h>

#define scif_smr_read()		SHREG_SCSMR2
#define scif_smr_write(v)	(SHREG_SCSMR2 = (v))

#define scif_brr_read()		SHREG_SCBRR2
#define scif_brr_write(v)	(SHREG_SCBRR2 = (v))

#define scif_scr_read()		SHREG_SCSCR2
#define scif_scr_write(v)	(SHREG_SCSCR2 = (v))

#define scif_ftdr_write(v)	(SHREG_SCFTDR2 = (v))

#define scif_ssr_read()		SHREG_SCSSR2
#define scif_ssr_write(v)	(SHREG_SCSSR2 = (v))

#define scif_frdr_read()	SHREG_SCFRDR2

#define scif_fcr_read()		SHREG_SCFCR2
#define scif_fcr_write(v)	(SHREG_SCFCR2 = (v))

#define scif_fdr_read()		SHREG_SCFDR2

#define scif_sptr_read()	SHREG_SCSPTR2
#define scif_sptr_write(v)	(SHREG_SCSPTR2 = (v))

#define scif_lsr_read()		SHREG_SCLSR2
#define scif_lsr_write(v)	(SHREG_SCLSR2 = (v))

#define	divrnd(n, q)	(((n)*2/(q)+1)/2)	/* divide and round off */

#define	SERBUFSIZE	16
static u_char serbuf[SERBUFSIZE];
static int serbuf_read = 0;
static int serbuf_write = 0;

void
scif_init(unsigned int bps)
{

	serbuf_read = 0;
	serbuf_write = 0;

	/* Initialize SCR */
	scif_scr_write(0x00);

	/* Clear FIFO */
	scif_fcr_write(SCFCR2_TFRST | SCFCR2_RFRST);

	/* Serial Mode Register */
	scif_smr_write(0x00);	/* 8bit,NonParity,Even,1Stop */

	/* Bit Rate Register */
	scif_brr_write(divrnd(PCLOCK, 32 * bps) - 1);

	delay(100);

	scif_sptr_write(SCSPTR2_RTSIO);

	scif_fcr_write(FIFO_RCV_TRIGGER_1 | FIFO_XMT_TRIGGER_8);

	/* Send permission, Receive permission ON */
	scif_scr_write(SCSCR2_TE | SCSCR2_RE);

	/* Serial Status Register */
	scif_ssr_write(scif_ssr_read() & SCSSR2_TDFE); /* Clear Status */
}

void
scif_cnprobe(struct consdev *cn)
{
	cn->cn_pri = CN_HIGHPRI;
}

void
scif_cninit(struct consdev *cn)
{
	scif_init(9600);
}

int
scif_cngetc(dev_t dev)
{
	unsigned char c, err_c;
	unsigned short err_c2;

	if (serbuf_read != serbuf_write) {
		if (dev & 0x80)
			return 1;
		c = serbuf[serbuf_read];
		serbuf_read = (serbuf_read + 1) % SERBUFSIZE;
		return (c);
	}

	for (;;) {
		/* wait for ready */
		if ((scif_fdr_read() & SCFDR2_RECVCNT) != 0) {
			c = scif_frdr_read();
			err_c = scif_ssr_read();
			scif_ssr_write(scif_ssr_read() &
			    ~(SCSSR2_ER | SCSSR2_BRK | SCSSR2_RDF | SCSSR2_DR));

			err_c2 = scif_lsr_read();
			scif_lsr_write(scif_lsr_read() & ~SCLSR2_ORER);

			if ((err_c & (SCSSR2_ER | SCSSR2_BRK | SCSSR2_FER |
			    SCSSR2_PER)) == 0) {
				if ((err_c2 & SCLSR2_ORER) == 0) {
					if ((dev & 0x80) == 0)
						return (c);
					/* stuff char into preread buffer */
					serbuf[serbuf_write] = (u_char)c;
					serbuf_write = (serbuf_write + 1) %
					    SERBUFSIZE;
					return (1);
				}
			}
		}
		if (dev & 0x80)
			return 0;
	}
}

void
scif_cnputc(dev_t dev, int c)
{

	/* wait for ready */
	while ((scif_fdr_read() & SCFDR2_TXCNT) == SCFDR2_TXF_FULL)
		continue;

	/* write send data to send register */
	scif_ftdr_write(c);

	/* clear ready flag */
	scif_ssr_write(scif_ssr_read() & ~(SCSSR2_TDFE | SCSSR2_TEND));
}


code:
/*	$OpenBSD: srt0.S,v 1.4 2014/07/17 13:14:06 miod Exp $	*/
/*	$NetBSD: boot.S,v 1.1 2006/09/01 21:26:18 uwe Exp $	*/

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

#include <machine/asm.h>

ENTRY(start)
	bra	boot_start1
	 nop
	.balign 4
ENTRY(boot_magic)
	.long	0x20041110
ENTRY(boot_params)
	.long	boot_start1 - boot_params

	. = start + 0x80
boot_start1:
	mov	r4, r0
	add	#-4, r0
	mov.l	@(0, r0), r0
	mov.l	.L.boot_magic1, r1
	cmp/eq	r0, r1
	bf	2f
	mov	r4, r0
	mov.l	.L.boot_params_size, r3
	mov.l	@r0, r2
	mov.l	.L.boot_params, r1
	cmp/hi	r3, r2
	bf	1f
	mov	r3, r2
1:	mov.b	@r0+, r3
	mov.b	r3, @r1
	dt	r2
	bf/s	1b
	 add	#1, r1
2:
	mov.l	.L._end, r0		/* zero bss */
	mov.l	.L.__bss_start, r1
	sub	r1, r0
	shlr2	r0			/* _end and __bss_start are aligned */
	mov	#0, r2
1:	mov.l	r2, @r1
	dt	r0
	bf/s	1b
	 add	#4, r1

	mov.l	.L.boot, r0
	jsr	@r0
	 mov	r5, r4

boot_fail:
	mov	r0, r1
	mova	.L.errtxt, r0
	mov	r0, r4
	mov	#32, r0
	trapa	#0x3f
	mov	r1, r4
	mov	#32, r0
	trapa	#0x3f
	mova	.L.crlf, r0
	mov	r0, r4
	mov	#32, r0
	trapa	#0x3f
99:	bra	99b
	 nop

ENTRY(halt)
	mova	.L.pwrctl, r0
	mov	#1, r1
	mov.b	@r1, r0
	rts
	 nop

ENTRY(reboot)
ENTRY(_rtt)
	mov	#1, r4			/* reboot */
	mov	#11, r0
	trapa	#0x3f
	mov.l	.L.start, r0
	jmp	@r0
	 nop

/*
 * int raise(int sig);
 */
ENTRY(raise)
	rts
	 nop

/*
 * int readsects(int dev, uint32_t lba, void *buf, size_t size);
 */
ENTRY(readsects)
	mov	#2, r0
	trapa	#0x3f
	rts
	 nop

/*
 * void cache_flush(void);
 */
ENTRY(cache_flush)
	/* flush cache */
	mov	#0, r4
	mov	#6, r0
	trapa	#0x3f
	rts
	 nop

/*
 * void cache_disable(void);
 */
ENTRY(cache_disable)
	mov     #1, r4
	mov     #6, r0
	trapa   #0x3f
	rts
	 nop

        .align  2
.L.boot_magic1:
	.long	0x20031125
.L.boot_params:
	.long	boot_params
.L.boot_params_size:
	.long	boot_start1 - boot_params
.L._end:
	.long   _end
.L.__bss_start:
	.long   __bss_start
.L.boot:
	.long   _C_LABEL(boot)
.L.start:
	.long	0xc0000000
.L.pwrctl:
	.long	0xb0000003

	.align	2
.L.errtxt:	.asciz  ">>BOOT FAILED: "
	.align	2
.L.crlf:	.asciz  "\r\n"

license: unknown


path: sys/arch/landisk/stand/mbr/CVS/Entries


path: sys/arch/landisk/stand/mbr/CVS/Tag


code:
#	$OpenBSD: Makefile,v 1.4 2012/09/02 16:21:05 deraadt Exp $

.include <bsd.own.mk>

MAN=	mbr.8

.if ${MACHINE} == "landisk"
PROG=	mbr
SRCS=	mbr.S
AFLAGS+=-nostdinc -I${.OBJDIR} -I${.CURDIR}/.. -I${.CURDIR}/../../.. #-Wa,a
AFLAGS+=-fno-pie
LDFLAGS+=-N -e start -Ttext 0x8c200200 -nopie
OBJCOPY?=objcopy

INSTALL_STRIP=
S=	${.CURDIR}/../../../..

# Uncomment this to make mbr talk to a serial port.
#CPPFLAGS+=-DSERIAL=0

${PROG}: $(OBJS) $(DPADD)
	$(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LDADD)
	@size $(PROG)
	@if [ -x ${.OBJDIR}/${PROG} ]; then \
		${OBJCOPY} -O binary ${PROG} ${.OBJDIR}/.tmp;\
		mv -f ${.OBJDIR}/.tmp ${.OBJDIR}/${PROG}; \
		ls -l ${.OBJDIR}/${PROG}; \
	fi

.else
NOPROG=
.endif

.include <bsd.prog.mk>

path: sys/arch/landisk/stand/mbr/Makefile


code:
/*	$OpenBSD: mbr.S,v 1.1 2006/10/06 21:48:50 mickey Exp $	*/
/*	$NetBSD: mbr.S,v 1.1 2006/09/01 21:26:19 uwe Exp $	*/

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

#include <machine/asm.h>

ENTRY(start)
	mova	mbr_end, r0
	mov	r0, r11			/* r11: relocate address */

	mov.w	mbr_size, r2
	sub	r2, r0
	mov	r0, r10			/* r10: loaded address */

	mov.w	stack_offset, r1
	add	r1, r0
	mov	r0, r15			/* r15: stack pointer */

	/* relocate code */
	mova	jmp_start, r0
	mov	r0, r13
	add	r2, r13			/* calc jump address */

	mov	r10, r0
	mov	r11, r1
1:	mov.b	@r0+, r3
	dt	r2
	mov.b	r3, @r1
	bf/s	1b
	 add	#1, r1

	jmp	@r13
	 nop

	.align	2
jmp_start:
	/* enable cache */
	mov	#0, r4
	mov	#6, r0
	trapa	#0x3f

	/* print banner */
	mova	banner, r0
	bsr	message
	 mov	r0, r4

	/* search bootable partition */
	mov.w	part_offset, r12
	add	r11, r12		/* r12: pointer to partition entry */
	mov	#4, r8			/* r8: partition loop counter */
loop_part:
	mov.b	@(4, r12), r0
	cmp/eq	#0x00, r0
	bt	next_part

	/* check active partition */
	mov.b	@(0, r12), r0
	cmp/eq	#0x80, r0
	bf	next_part

	/* found bootable partition */
	mov.w	@(8, r12), r0		/* load unaligned 32bit data */
	mov	r0, r1
	mov.w	@(10, r12), r0
	extu.w	r1, r1
	shll16	r0
	or	r1, r0

	mov	r0, r3
	mova	found_sector, r0
	bra	boot_lba
	 mov.l	r3, @r0

next_part:
	dt	r8
	bf/s	loop_part
	 add	#16, r12

noos_error:
	/* Not found bootable partition */
	mova	ERR_NOOS, r0
error:
	bsr	message
	 mov	r0, r4
99:	bra	99b
	 nop

read_error:
	bra	error
	 mova	ERR_READ, r0

message:
	mov	#32, r0
	trapa	#0x3f
	rts
	 nop

read_sector_lba:
	mov	#1, r7
	mov	#2, r0
	trapa	#0x3f
	tst	r0, r0
	bf	read_error
	rts
	 nop

boot_lba:
	/* read PBR sector */
	mova	found_sector, r0
	mov	#0x40, r4
	mov.l	@r0, r5
	bsr	read_sector_lba
	 mov	r10, r6

	/* flush cache */
	mov	#0, r4
	mov	#6, r0
	trapa	#0x3f

	/* check signature */
	mov.b	@(0, r10), r0
	tst	r0, r0
	bt	noos_error		/* first byte non-zero */
	mov.w	magic_offset, r0
	mov.w	@(r0, r10), r1
	mov.w	magic, r2
	cmp/eq	r1, r2
	bf	noos_error		/* magic */

	/* now jump to PBR */
	mov	r10, r0
	jmp	@r10
	 nop

	.align	1
mbr_size:	.word	mbr_end - _C_LABEL(start)
	.align	1
stack_offset:	.word	0x1000
	.align	1
part_offset:	.word	0x1be
	.align	1
magic_offset:	.word	0x1fe

	.align	2
found_sector:	.long	0

	.align	2
banner:		.asciz	"\r\nOpenBSD MBR\r\n"

	.align	2
ERR_INVPART:	.asciz	"No active partition\r\n"
	.align	2
ERR_READ:	.asciz	"Read error\r\n"
	.align	2
ERR_NOOS:	.asciz	"No O/S\r\n"

/* space for mbr_dsn */
	. = _C_LABEL(start) + 0x1b4
	.long	0

/* mbr_bootsel_magic */
	. = _C_LABEL(start) + 0x1b8
	.word	0

/*
 * MBR partition table
 */
	. = _C_LABEL(start) + 0x1be
_pbr_part0:
	.byte	0, 0, 0, 0, 0, 0, 0, 0
	.byte	0, 0, 0, 0, 0, 0, 0, 0
_pbr_part1:
	.byte	0, 0, 0, 0, 0, 0, 0, 0
	.byte	0, 0, 0, 0, 0, 0, 0, 0
_pbr_part2:
	.byte	0, 0, 0, 0, 0, 0, 0, 0
	.byte	0, 0, 0, 0, 0, 0, 0, 0
_pbr_part3:
	.byte	0x80, 0, 1, 0, 0xa6, 255, 255, 255
	.word	0, 0, 0xffff, 0x7fff

	. = _C_LABEL(start) + 0x1fe
magic:
	.word	0xaa55
mbr_end:


code: src/sys/arch/landisk/stand/xxboot


path: sys/arch/landisk/stand/xxboot/CVS/Tag


code:
#	$OpenBSD: Makefile,v 1.8 2015/06/14 19:08:59 miod Exp $

MAN=	xxboot.8

.if ${MACHINE} == "landisk"
PROG=	xxboot
LINKS=	${BINDIR}/xxboot ${BINDIR}/sdboot
LINKS+=	${BINDIR}/xxboot ${BINDIR}/wdboot
SRCS=	pbr.S xxboot.S boot1.c
LDFLAGS=-nostdlib -Ttext 0x8c201000 -N -x -Bstatic -e start -nopie

INSTALL_STRIP=

XXBOOT_SECTORS?= 15
XXBOOT_MAXSIZE?= (( ${XXBOOT_SECTORS} * 512 ))

CPPFLAGS+=-D_STANDALONE
CPPFLAGS+=-nostdinc -I${.OBJDIR} -I${.CURDIR}/.. -I${.CURDIR}/../../../..
CPPFLAGS+=-DLOADADDRESS=0x8ff00000 -DXXBOOT_SECTORS=${XXBOOT_SECTORS}
CFLAGS+=-m4-nofpu -fno-pie
AFLAGS+= -fno-pie

OBJCOPY?=objcopy

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

.PATH:	${S}/lib/libkern/arch/sh ${S}/lib/libkern
SRCS+=	strlen.c
SRCS+=	ashrdi3.c sdivsi3.S udivsi3.S

${PROG}: ${OBJS} ${DPADD}
	${LD} -o ${PROG}.sym ${LDFLAGS} \
		-Map ${PROG}.map -cref ${OBJS} ${LDADD}
	${OBJCOPY} -O binary ${PROG}.sym ${PROG}
	@ sz=$$(ls -ln ${PROG} | tr -s ' ' | cut -d' ' -f5); \
	if [ "$$sz" -gt "$$${XXBOOT_MAXSIZE}" ]; then \
		echo "### ${PROG} size $$sz is larger than ${XXBOOT_MAXSIZE}" >&2 \
		rm -f ${PROG}; \
		! :; \
	else \
		: pad to sector boundary; \
		pad=$$(( 512 - ( $$sz & 511 ) )); \
		[ $$pad = 512 ] || \
		    dd if=/dev/zero bs=1 count=$$pad >>${PROG} 2>/dev/null; \
		echo "${PROG} size $$sz, $$((${XXBOOT_MAXSIZE} - $$sz)) free"; \
	fi
.else
NOPROG=
.endif

.include <bsd.prog.mk>

path: sys/arch/landisk/stand/xxboot/Makefile


code:
/*	$OpenBSD: boot1.c,v 1.7 2011/04/10 12:21:07 miod Exp $	*/
/*	$NetBSD: boot1.c,v 1.1 2006/09/01 21:26:19 uwe Exp $	*/

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

#include <sys/param.h>
#include <lib/libsa/stand.h>
#include <lib/libsa/ufs.h>

#include <sys/disklabel.h>

#define	XSTR(x)	#x
#define	STR(x)	XSTR(x)

static uint32_t bios_sector;

const char *boot1(uint32_t *);
void putstr(const char *str);
int raise(int sig);
int blkdevstrategy(void *, int, daddr32_t, size_t, void *, size_t *);
int blkdevopen(struct open_file *, ...);
int blkdevclose(struct open_file *);

extern struct disklabel ptn_disklabel;

struct fs_ops file_system[] = {
	{ ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek,
	  ufs_stat, ufs_readdir },
};
int nfsys = nitems(file_system);

struct devsw devsw[] = {
	{ "dk", blkdevstrategy, blkdevopen, blkdevclose, noioctl },
};
int     ndevs = nitems(devsw);

const char *
boot1(uint32_t *sector)
{
        struct stat sb;
	int fd = -1;

	bios_sector = *sector;

	putstr("\r\nOpenBSD/" MACHINE " Primary Bootstrap\r\n");

	do {
		/*
		 * Nothing at the start of the MBR partition, fallback on
		 * partition 'a' from the disklabel in this MBR partition.
		 */
		if (ptn_disklabel.d_magic != DISKMAGIC)
			break;
		if (ptn_disklabel.d_magic2 != DISKMAGIC)
			break;
		if (ptn_disklabel.d_partitions[0].p_fstype == FS_UNUSED)
			break;

		bios_sector = ptn_disklabel.d_partitions[0].p_offset;
		*sector = bios_sector;
		fd = open("boot", 0);
	} while (0);

	if (fd == -1 || fstat(fd, &sb) == -1)
		return "Can't open /boot.\r\n";

#if 0
	if (sb.st_size > SECONDARY_MAX_LOAD)
		return "/boot too large.\r\n";
#endif

	if (read(fd, (void *)LOADADDRESS, sb.st_size) != sb.st_size)
		return "/boot load failed.\r\n";

	if (*(uint32_t *)(LOADADDRESS + 4) != 0x20041110)
		return "Invalid /boot file format.\r\n";

	return 0;
}

int
blkdevopen(struct open_file *f, ...)
{
	return 0;
}
int
blkdevclose(struct open_file *f)
{
	return 0;
}

int
blkdevstrategy(void *devdata, int flag, daddr32_t dblk, size_t size, void *buf, size_t *rsize)
{

	if (flag != F_READ)
		return EROFS;

	if (size & (DEV_BSIZE - 1))
		return EINVAL;

	if (rsize)
		*rsize = size;

	if (size != 0 && readsects(0x40, bios_sector + dblk, buf,
				   size / DEV_BSIZE) != 0)
		return EIO;

	return 0;
}

/* ARGUSED */
int
raise(int sig)
{

	return 0;
}

void
twiddle(void)
{
	static int pos;

	putchar("|/-\\"[pos++ & 3]);
	putchar('\b');
}

int
devopen(struct open_file *f, const char *fname, char **file)
{
	*file = (char *)fname;
	f->f_flags |= F_NODEV;
	f->f_dev = &devsw[0];
	return (0);
}


code:
/*	$OpenBSD: pbr.S,v 1.1 2006/11/08 17:46:56 deraadt Exp $	*/
/*	$NetBSD: pbr.S,v 1.1 2006/09/01 21:26:19 uwe Exp $	*/

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

#include <machine/asm.h>

#ifdef BOOT_FROM_FAT
#define MBR_AFTERBPB	90		/* BPB size in FAT32 partition BR */
#else
#define MBR_AFTERBPB	62		/* BPB size in floppy master BR */
#endif

ENTRY(start)
	bra	start0
	 .byte	0x11			/* 0x4f11: cmp/pz r15... */
	.asciz	"OpenBSD"

	. = _C_LABEL(start) + 0x0b	/* move to start of BPB */

	. = _C_LABEL(start) + 0x1c	/* skip BPB */
start0:
	mova	pbr_end, r0
	mov.w	pbr_size, r2
	sub	r2, r0
	mov	r0, r11			/* r11: own loaded address */

	mov.w	stack_offset, r1
	add	r1, r0
	mov	r0, r15			/* r15: stack pointer */
	mov	r0, r10			/* r10: load address */

	/* enable/flush cache */
	mov	#0, r4
	mov	#6, r0
	trapa	#0x3f

	/* Read from start of disk */
	mov	#0x40, r4		/* LBA */
	mov	#0, r5			/* LBA #0 */
	mov	r10, r6			/* buffer address */
	bsr	read_sectors_lba
	 mov	#XXBOOT_SECTORS, r7	/* number of sectors */

	mov.l	@r11, r1
	mov.l	@r10, r2
	cmp/eq	r1, r2
	bt/s	pbr_read_ok
	 mov	#0, r9			/* r9: sector # */

	/* Search bootable partition */
	mov.w	part_offset, r12
	add	r10, r12		/* r12: pointer to partition entry */
	mov	#4, r8			/* r8: partition loop counter */
loop_part:
	mov.b	@(4, r12), r0
#ifdef BOOT_FROM_FAT
	cmp/eq	#MBR_PTYPE_FAT12, r0
	bt	found
	cmp/eq	#MBR_PTYPE_FAT16S, r0
	bt	found
	cmp/eq	#MBR_PTYPE_FAT16B, r0
	bt	found
	cmp/eq	#MBR_PTYPE_FAT32, r0
	bt	found
	cmp/eq	#MBR_PTYPE_FAT32L, r0
	bt	found
	cmp/eq	#MBR_PTYPE_FAT16L, r0
	bt	found
#else
	cmp/eq	#0xa6, r0
#endif
	bf	next_part

found:
	/* found boot partition */
	mov.w	@(8, r12), r0
	mov	r0, r1
	mov.w	@(10, r12), r0
	extu.w	r1, r1
	shll16	r0
	or	r1, r0
	tst	r0, r0
	bt	next_part		/* start LBA == 0 ? */

	bra	boot_lba
	 mov	r0, r9

next_part:
	dt	r8
	bf/s	loop_part
	 add	#16, r12

ptn_error:
	/* Not found NetBSD partition */
	mova	ERR_PTN, r0
error:
	bsr	message_crlf
	 mov	r0, r4
99:	bra	99b
	 nop

read_error:
	bra	error
	 mova	ERR_READ, r0

magic_error:
	bra	error
	 mova	ERR_NO_XXBOOT, r0

message_crlf:
	mov	#32, r0
	trapa	#0x3f
	mova	crlf, r0
	mov	r0, r4
	mov	#32, r0
	trapa	#0x3f
	rts
	 nop

read_sectors_lba:
	mov	#2, r0
	trapa	#0x3f
	tst	r0, r0
	bf	read_error
	rts
	 nop

boot_lba:
	mov	#0x40, r4		/* LBA */
	mov	r9, r5			/* LBA # */
	mov	r10, r6			/* buffer address */
	bsr	read_sectors_lba
	 mov	#XXBOOT_SECTORS, r7	/* number of sectors */

pbr_read_ok:
	mov.l	.L.xxboot_magic1, r1
	mov.l	.L.xxboot_magic, r2
	mov.l	@r2, r2
	cmp/eq	r1, r2
	bf	magic_error

	/* flush cache */
	mov	#0, r4
	mov	#6, r0
	trapa	#0x3f

	mov.l	.L.xxboot_start, r13
	jmp	@r13			/* jump to xxboot */
	 mov	r9, r4			/* pass sector address to xxboot */

	.align	1
pbr_size:	.word	pbr_end - _C_LABEL(start)
	.align	1
stack_offset:	.word	0x1000
	.align	1
part_offset:	.word	0x1be
	.align	1
magic_offset:	.word	0x1fe

	.align	2
.L.xxboot_magic1:
	.long	0x20031125
.L.xxboot_magic:
	.long	_C_LABEL(xxboot_magic)
.L.xxboot_start:
	.long	_C_LABEL(xxboot_start)

	.align	2
crlf:		.asciz	"\r\n"

	.align	2
ERR_READ:	.asciz  "Disk read"
	.align	2
ERR_NO_XXBOOT:	.asciz  "Not a xxboot image"
	.align	2
ERR_PTN:	.asciz  "No OpenBSD partition"

	. = _C_LABEL(start) + 0x1fe
magic:
	.word	0xaa55
pbr_end:

	.global	_C_LABEL(ptn_disklabel)
_C_LABEL(ptn_disklabel):
	.fill	512


code:
/*	$OpenBSD: xxboot.S,v 1.1 2006/11/08 17:46:56 deraadt Exp $	*/
/*	$NetBSD: xxboot.S,v 1.1 2006/09/01 21:26:19 uwe Exp $	*/

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

#include <machine/asm.h>

ENTRY(xxboot_start)
	bra	xxboot_start1
	 nop
	.balign 4
ENTRY(xxboot_magic)
	.long	0x20031125
boot_params:
	.long	1f - boot_params

	. = xxboot_start + 0x80
xxboot_start1:
	mov.l	.L._end, r0		/* zero bss */
	mov.l	.L.__bss_start, r1
	sub	r1, r0
	shlr2	r0			/* _end and __bss_start are aligned */
	mov	#0, r2
1:	mov.l	r2, @r1
	dt	r0
	bf/s	1b
	 add	#4, r1

	mov.l	.L.2nd_loadaddr, r15	/* new stack pointer */
	mov.l	r4, @-r15
	mov.l	.L.boot1, r0
	jsr	@r0
	 mov	r15, r4

	tst	r0, r0
	bf/s	boot_fail
	 mov.l	@r15+, r5		/* pass boot sector to boot */

	/* flush cache */
	mov	#0, r4
	mov	#6, r0
	trapa	#0x3f

	mov.l	.L.2nd_loadaddr, r0
	mov.l	.L.boot_params, r4
	jmp	@r0
	 nop

boot_fail:
	mov	r0, r1
	mova	.L.errtxt, r0
	mov	r0, r4
	mov	#32, r0
	trapa	#0x3f
	mov	r1, r4
	mov	#32, r0
	trapa	#0x3f
	mova	.L.crlf, r0
	mov	r0, r4
	mov	#32, r0
	trapa	#0x3f
99:	bra	99b
	 nop

	.align	2
.L._end:
	.long	_end
.L.__bss_start:
	.long	__bss_start
.L.boot1:
	.long	_C_LABEL(boot1)
.L.2nd_loadaddr:
	.long	LOADADDRESS
.L.boot_params:
	.long	boot_params

	.align	2
.L.errtxt:	.asciz	"Error: "
	.align	2
.L.crlf:	.asciz	"\r\n"

/*
 * int readsects(int dev, uint32_t lba, void *buf, size_t size);
 */
ENTRY(readsects)
	mov	#2, r0
	trapa	#0x3f
	rts
	 nop
argerror:
	rts
	 mov	#-1, r0

/*
 * void putstr(const char *str);
 */
ENTRY(putstr)
	mov	#32, r0
	trapa	#0x3f
	rts
	 nop

/*
 * void putchar(int c);
 */
ENTRY(putchar)
	mov	#31, r0
	trapa	#0x3f
	rts
	 nop


code:
/Makefile/1.6/Sun Dec  8 14:46:39 2013//TOPENBSD_5_8_BASE
D/compile////
D/conf////
D/dev////
D/include////
D/loongson////
D/stand////

path: sys/arch/loongson/CVS/Entries


code: src/sys/arch/loongson

path: sys/arch/loongson/CVS/Repository


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

S=	${.CURDIR}/../..
KFILE=	GENERIC
.if exists(conf/GENERIC.MP)
KFILE=	GENERIC.MP
.endif
TDIRS=	${_arch} include
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>

path: sys/arch/loongson/Makefile


path: sys/arch/loongson/compile/CVS/Entries


path: sys/arch/loongson/compile/CVS/Tag


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


code: src/sys/arch/loongson/conf

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


code:
#	$OpenBSD: GENERIC,v 1.50 2015/04/16 09:09:49 mpi Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
#
# For further information on hardware support for this architecture, see
# the intro(4) man page.  For further information about kernel options
# for this architecture, see the options(4) man page.  For an explanation
# of each device driver in this file see the section 4 man page for the
# device.

machine		loongson mips64
include		"../../../conf/GENERIC"
maxusers	32

option		CPU_LOONGSON2
makeoption	LINK_ADDRESS="0xffffffff80200000"

option		USER_PCICONF
option		WSDISPLAY_COMPAT_RAWKBD	# provide raw scancodes; needed for X11

option		PCIVERBOSE
option		USBVERBOSE

config	bsd	swap generic

#
# Definition of system
#
mainbus0	at root
cpu0		at mainbus0
clock0		at mainbus0
apm0		at mainbus0

# Main local buses
bonito*		at mainbus0
pci*		at bonito?

# Lemote Lynloong, Lemote Fuloong 2F and Lemote Yeeloong devices
glxpcib*	at pci?
gpio*		at glxpcib?
isa0		at glxpcib?
glxclk*		at glxpcib?
mcclock0	at isa? port 0x70
pckbc0		at isa?				# Yeeloong only
pckbd*		at pckbc?			# Yeeloong only
wskbd*		at pckbd? mux 1			# Yeeloong only
pms*		at pckbc?			# Yeeloong only
wsmouse*	at pms? mux 0			# Yeeloong only
ykbec0		at isa? port 0x381		# Yeeloong only
com0		at isa? port 0x2f8 irq 3	# Fuloong 2F only
com1		at isa? port 0x3f8 irq 4	# Fuloong 2F only (IR port)
pciide*		at pci?
wd*		at pciide? flags 0x0000
sisfb*		at pci?				# Lynloong/Fuloong 2F only
wsdisplay*	at sisfb?
smfb*		at pci?				# Yeeloong only
wsdisplay*	at smfb?
auglx*		at pci?
audio*		at auglx?

# Gdium Liberty specific devices
voyager*	at pci?
gpio0		at voyager?
gdiumiic0	at gpio0 offset 6 mask 0x81	# pins 6 and 13
gdiumiic0	at gpio0 offset 46 mask 0x03	# pins 46 and 47
iic0		at gdiumiic0
stsec0		at iic0				# ST7 Embedded Controller
lmtemp0		at iic0 			# National Semiconductor LM75
mfokclock0	at iic0				# M41T8x todclock
#iic*		at voyager?
ohci*		at voyager?
smfb*		at voyager?
wsdisplay*	at smfb?

# Generic 2E systems (in addition to the Fuloong devices)
pcib*		at pci?
isa0		at pcib?
vga*		at pci?
wsdisplay*	at vga?
auvia*		at pci?
audio*		at auvia?
viapm*		at pci?

# USB Controllers
ohci*		at pci?
uhci*		at pci?
ehci*		at pci?

# USB bus support
usb*		at ohci?
usb*		at uhci?
usb*		at ehci?

# USB devices
uhub*		at usb?		# USB Hubs
uhub*		at uhub?	# USB Hubs
ualea*		at uhub?	# Araneus Alea II TRNG
umodem*		at uhub?	# USB Modems/Serial
ucom*		at umodem?
uvisor*		at uhub?	# Handspring Visor
ucom*		at uvisor?
uvscom*		at uhub?	# SUNTAC Slipper U VS-10U serial
ucom*		at uvscom?
ubsa*		at uhub?	# Belkin serial adapter
ucom*		at ubsa?
uftdi*		at uhub?	# FTDI FT8U100AX serial adapter
ucom*		at uftdi?
uplcom* 	at uhub?	# I/O DATA USB-RSAQ2 serial adapter
ucom*		at uplcom?
umct*		at uhub?	# MCT USB-RS232 serial adapter
ucom*		at umct?
uslcom*		at uhub?	# Silicon Laboratories CP210x serial
ucom*		at uslcom?
uark*		at uhub?	# Arkmicro ARK3116 serial
ucom*		at uark?
moscom*		at uhub?	# MosChip MCS7703 serial
ucom*		at moscom?
umcs*		at uhub?	# MosChip MCS78x0 serial
ucom*		at umcs?
uipaq*		at uhub?	# iPAQ serial adapter
ucom*		at uipaq?
umsm*		at uhub?	# Qualcomm MSM EVDO
ucom*		at umsm?
uchcom*		at uhub?	# WinChipHead CH341/340 serial
ucom*		at uchcom?
ulpt*		at uhub?	# USB Printers
umass*		at uhub?	# USB Mass Storage devices
uhidev*		at uhub?	# Human Interface Devices
ums*		at uhidev?	# USB mouse
wsmouse*	at ums? mux 0
ukbd*		at uhidev?	# USB keyboard
wskbd*		at ukbd? mux 1
uslhcom* 	at uhidev?	# Silicon Labs CP2110 USB HID UART
ucom*		at uslhcom?
uhid*		at uhidev?	# USB generic HID support
upd*		at uhidev?	# USB Power Devices sensors
atu*		at uhub?	# Atmel AT76c50x based 802.11b
aue*		at uhub?	# ADMtek AN986 Pegasus Ethernet
axe*		at uhub?	# ASIX Electronics AX88172 USB Ethernet
axen*		at uhub?	# ASIX Electronics AX88179 USB Ethernet
cdce*		at uhub?	# CDC Ethernet
urndis*		at uhub?	# Remote NDIS Ethernet
cue*		at uhub?	# CATC USB-EL1201A based Ethernet
kue*		at uhub?	# Kawasaki KL5KUSB101B based Ethernet
mos*		at uhub?	# MOSCHIP MCS7730/7830 10/100 Ethernet
smsc*		at uhub?	# SMSC LAN95xx Ethernet
otus*		at uhub?	# Atheros AR9001U
athn*		at uhub?	# Atheros AR9002U
rum*		at uhub?	# Ralink RT2501USB/RT2601USB
run*		at uhub?	# Ralink RT2700U/RT2800U/RT3000U
uath*		at uhub?	# Atheros AR5005UG/AR5005UX
udav*		at uhub?	# Davicom DM9601 based Ethernet
upgt*		at uhub?	# Conexant/Intersil PrismGT SoftMAC USB
upl*		at uhub?	# Prolific PL2301/PL2302 host-to-host `network'
ugl*		at uhub?	# Genesys Logic GL620USB-A host-to-host `network'
ural*		at uhub?	# Ralink RT2500USB
url*		at uhub?	# Realtek RTL8150L based adapters
urtw*		at uhub?	# Realtek 8187
rsu*		at uhub?	# Realtek RTL8188SU/RTL8191SU/RTL8192SU
urtwn*		at uhub?	# Realtek RTL8188CU/RTL8192CU
wi*		at uhub?	# WaveLAN IEEE 802.11DS
zyd*		at uhub?	# Zydas ZD1211
uberry*		at uhub?	# Research In Motion BlackBerry
udcf*		at uhub?	# Gude Expert mouseCLOCK
uthum*		at uhidev?	# TEMPerHUM sensor
ugold*		at uhidev?	# gold TEMPer sensor
utwitch*	at uhidev?	# YUREX BBU sensor
ugen*		at uhub?	# USB Generic driver

# USB Audio
uaudio*		at uhub?
audio*		at uaudio?
umidi*		at uhub?	# USB MIDI
midi*		at umidi?

# USB Video
uvideo*		at uhub?
video*		at uvideo?

udl*		at uhub?
wsdisplay*	at udl?

# NICs
ral*		at pci?
re*		at pci?
rl*		at pci?

# Media Independent Interface (mii) drivers
acphy*		at mii?		# Altima AC101 PHYs
amphy*		at mii?		# AMD 79C873 PHYs
bmtphy*		at mii?		# Broadcom 10/100 PHYs
eephy*		at mii?		# Marvell 88E1000 series PHY
rgephy*		at mii?		# Realtek 8169S/8110S PHY
rlphy*		at mii?		# Realtek 8139 internal PHYs
urlphy*		at mii?		# Realtek RTL8150L internal PHY
ukphy*		at mii?		# "unknown" PHYs

# SCSI Bus devices
scsibus*	at scsi?
sd*		at scsibus?
st*		at scsibus?
cd*		at scsibus?
ch*		at scsibus?
uk*		at scsibus?

pseudo-device	hotplug	1	# devices hot plugging
pseudo-device	wsmux	2	# mouse & keyboard multiplexor

path: sys/arch/loongson/conf/GENERIC


code:
#	$OpenBSD: Makefile.loongson,v 1.45 2015/01/13 01:12:49 deraadt Exp $

# For instructions on building kernels consult the config(8) and options(4)
# manual pages.
#
# N.B.: NO DEPENDENCIES ON FOLLOWING FLAGS ARE VISIBLE TO MAKEFILE
#	IF YOU CHANGE THE DEFINITION OF ANY OF THESE RECOMPILE EVERYTHING
# DEBUG is set to -g by config if debugging is requested (config -g).
# PROF is set to -pg by config if profiling is requested (config -p).

.include <bsd.own.mk>

SIZE?=	size
STRIP?=	strip
AS?=	as
CC?=	cc
LD?=	ld ${ENDIAN}

AS+=${ENDIAN}
CC+=${ENDIAN}
LD+=${ENDIAN}

# source tree is located via $S relative to the compilation directory
.ifndef S
S!=	cd ../../../..; pwd
.endif

_machdir?=	$S/arch/${_mach}
_archdir?=	$S/arch/${_arch}

INCLUDES=	-nostdinc -I$S -I. -I$S/arch
CPPFLAGS=	${INCLUDES} ${IDENT} ${PARAM} -D_KERNEL -D__${_mach}__ -MD -MP
CWARNFLAGS=	-Werror -Wall -Wimplicit-function-declaration \
		-Wno-main -Wno-uninitialized \
		-Wframe-larger-than=2047

CMACHFLAGS=	-mno-abicalls ${ABI} -msoft-float -Wa,-mfix-loongson2f-btb -G 0
CMACHFLAGS+=	-fno-builtin-printf -fno-builtin-snprintf \
		-fno-builtin-vsnprintf -fno-builtin-log \
		-fno-builtin-log2 -fno-builtin-malloc ${NOPIE_FLAGS}
.if ${IDENT:M-DNO_PROPOLICE}
CMACHFLAGS+=	-fno-stack-protector
.endif

COPTS?=		-O2
CFLAGS=		${DEBUG} ${CWARNFLAGS} ${CMACHFLAGS} ${COPTS} ${PIPE}
AFLAGS=		-D_LOCORE -x assembler-with-cpp ${CWARNFLAGS} ${CMACHFLAGS}
LDSCRIPT=	${_machdir}/conf/ld.script
LINKFLAGS=	-e start -T ${LDSCRIPT} -Ttext=${LINK_ADDRESS} -warn-common -nopie

.if ${IDENT:M-DDDB_STRUCT}
DB_STRUCTINFO=	db_structinfo.h
.else
DB_STRUCTINFO=
.endif

HOSTCC?=	${CC}
HOSTED_CPPFLAGS=${CPPFLAGS:S/^-nostdinc$//}
HOSTED_CFLAGS=	${CFLAGS}
HOSTED_C=	${HOSTCC} ${HOSTED_CFLAGS} ${HOSTED_CPPFLAGS} -c $<

NORMAL_C_NOP=	${CC} ${CFLAGS} ${CPPFLAGS} -c $<
NORMAL_C=	${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c $<
NORMAL_S=	${CC} ${AFLAGS} ${CPPFLAGS} -c $<

%OBJS

%CFILES

%SFILES

# load lines for config "xxx" will be emitted as:
# xxx: ${SYSTEM_DEP} swapxxx.o
#	${SYSTEM_LD_HEAD}
#	${SYSTEM_LD} swapxxx.o
#	${SYSTEM_LD_TAIL}
SYSTEM_HEAD=	locore.o param.o ioconf.o
SYSTEM_OBJ=	${SYSTEM_HEAD} ${OBJS}
SYSTEM_DEP=	Makefile ${SYSTEM_OBJ} ${LDSCRIPT}
SYSTEM_LD_HEAD=	@rm -f $@
SYSTEM_LD=	@echo ${LD} ${LINKFLAGS} -o $@ '$${SYSTEM_HEAD} vers.o $${OBJS}'; \
		${LD} ${LINKFLAGS} -o $@ ${SYSTEM_HEAD} vers.o ${OBJS}
SYSTEM_LD_TAIL=	@${SIZE} $@; chmod 755 $@

DEBUG?=
.if ${DEBUG} == "-g"
LINKFLAGS+=	-X
STRIPFLAGS=	-g -x
SYSTEM_LD_TAIL+=; \
		echo mv $@ $@.gdb; rm -f $@.gdb; mv $@ $@.gdb; \
		echo ${STRIP} ${STRIPFLAGS} -o $@ $@.gdb; \
		${STRIP} ${STRIPFLAGS} -o $@ $@.gdb
.else
LINKFLAGS+=	-x
.endif

%LOAD

# cc's -MD puts the source and output paths in the dependency file;
# since those are temp files here we need to fix it up.  It also
# puts the file in /tmp, so we use -MF to put it in the current
# directory as assym.P and then generate assym.d from it with a
# good target name
assym.h: $S/kern/genassym.sh Makefile \
	 ${_archdir}/${_arch}/genassym.cf ${_machdir}/${_mach}/genassym.cf
	cat ${_archdir}/${_arch}/genassym.cf ${_machdir}/${_mach}/genassym.cf | \
	    sh $S/kern/genassym.sh ${CC} ${CFLAGS} ${CPPFLAGS} -MF assym.P > assym.h.tmp
	sed '1s/.*/assym.h: \\/' assym.P > assym.d
	sort -u assym.h.tmp > assym.h

param.c: $S/conf/param.c
	rm -f param.c
	cp $S/conf/param.c .

param.o: param.c Makefile
	${NORMAL_C}

mcount.o: $S/lib/libkern/mcount.c Makefile
	${NORMAL_C_NOP}

ioconf.o: ioconf.c
	${NORMAL_C}

vers.o: ${SYSTEM_DEP} ${SYSTEM_SWAP_DEP}
	sh $S/conf/newvers.sh
	${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c vers.c

clean::
	rm -f eddep *bsd *bsd.gdb tags *.[dio] [a-z]*.s \
	    [Ee]rrs linterrs assym.h ${DB_STRUCTINFO}

lint:
	@lint -hbxncez -Dvolatile= ${CPPFLAGS} -UKGDB \
	    ${CFILES} ioconf.c param.c | \
	    grep -v 'static function .* unused'

symbols.sort: ${_machdir}/${_mach}/symbols.raw
	grep -v '^#' ${_machdir}/${_mach}/symbols.raw \
	    | sed 's/^	//' | sort -u > symbols.sort

depend:
	@touch $@

tags:
	@echo "see $S/kern/Makefile for tags"

db_structinfo.h: $S/ddb/db_structinfo.c $S/ddb/parse_structinfo.pl
	${CC} ${CFLAGS} ${CPPFLAGS} -MT $@ -gstabs -c $S/ddb/db_structinfo.c
	objdump -g db_structinfo.o | perl $S/ddb/parse_structinfo.pl > $@
	rm -f db_structinfo.o

locore.o: ${_machdir}/${_mach}/locore.S assym.h
context.o cp0access.o exception.o: assym.h
lcore_access.o lcore_ddb.o lcore_float.o tlbhandler.o: assym.h
pmon32.o: assym.h

# The install target can be redefined by putting a
# install-kernel-${MACHINE_NAME} target into /etc/mk.conf
MACHINE_NAME!=  uname -n
install: install-kernel-${MACHINE_NAME}
.if !target(install-kernel-${MACHINE_NAME}})
install-kernel-${MACHINE_NAME}:
	cmp -s bsd /bsd || ln -f /bsd /obsd
	cp bsd /nbsd
	mv /nbsd /bsd
.endif

# pull in the dependency information
.if !empty(DB_STRUCTINFO) && !exists(${DB_STRUCTINFO})
 ${SYSTEM_OBJ}: ${DB_STRUCTINFO}
.endif
.ifnmake clean
. for o in ${SYSTEM_OBJ} assym.h ${DB_STRUCTINFO}
.  if exists(${o:R}.d)
.   include "${o:R}.d"
.  elif exists($o)
    .PHONY: $o
.  endif
. endfor
.endif

%RULES


code:
#	$OpenBSD: RAMDISK,v 1.26 2015/07/17 22:52:28 tedu Exp $

machine		loongson mips64
maxusers	4

option		TIMEZONE=0
option		DST=0
option		SMALL_KERNEL
option		NO_PROPOLICE
option		BOOT_CONFIG

option		MINIROOTSIZE=8192
option		RAMDISK_HOOKS

option		PCIVERBOSE
option		USBVERBOSE

option		FFS
option		FFS2
option		NFSCLIENT
option		CD9660
option		UDF
option		EXT2FS
option		MSDOSFS
option		INET6

option		CPU_LOONGSON2
makeoption	LINK_ADDRESS="0xffffffff80200000"

config		bsd root on rd0a swap on rd0b

mainbus0	at root
cpu0		at mainbus0
clock0		at mainbus0

bonito*		at mainbus0
pci*		at bonito?

glxpcib*	at pci?
isa0		at glxpcib?
mcclock0	at isa? port 0x70
pckbc0		at isa?				# Yeeloong only
pckbd*		at pckbc?			# Yeeloong only
wskbd*		at pckbd? mux 1			# Yeeloong only
com0		at isa? port 0x2f8 irq 3	# Fuloong 2F only
com1		at isa? port 0x3f8 irq 3	# Fuloong 2E only
pciide*		at pci?
wd*		at pciide? flags 0x0000
sisfb*		at pci?				# Lynloong/Fuloong 2F only
wsdisplay*	at sisfb?
smfb*		at pci?				# Yeeloong only
wsdisplay*	at smfb?

voyager*	at pci?
gpio0		at voyager?
gdiumiic0	at gpio0 offset 6 mask 0x81	# pins 6 and 13
gdiumiic0	at gpio0 offset 46 mask 0x03	# pins 46 and 47
iic0		at gdiumiic0
mfokclock0	at iic0				# M41T8x todclock
ohci*		at voyager?
smfb*		at voyager?
wsdisplay*	at smfb?

pcib*		at pci?
isa0		at pcib?
vga*		at pci?
wsdisplay*	at vga?

ohci*		at pci?
uhci*		at pci?
ehci*		at pci?
usb*		at ohci?
usb*		at uhci?
usb*		at ehci?

uhub*		at usb?
uhub*		at uhub?
umodem*		at uhub?		# USB Modems/Serial
ucom*		at umodem?
uvscom*		at uhub?		# SUNTAC Slipper U VS-10U serial
ucom*		at uvscom?
ubsa*		at uhub?		# Belkin serial adapter
ucom*		at ubsa?
uplcom*		at uhub?		# I/O DATA USB-RSAQ2 serial adapter
ucom*		at uplcom?
umass*		at uhub?
uhidev*		at uhub?		# Human Interface Devices
ukbd*		at uhidev?		# USB keyboard
wskbd*		at ukbd? mux 1
uslhcom* 	at uhidev?		# Silicon Labs CP2110 USB HID UART
ucom*		at uslhcom?
uhid*		at uhidev?		# USB generic HID support
atu*		at uhub?		# Atmel AT76c50x based 802.11b
aue*		at uhub?		# ADMtek AN986 Pegasus Ethernet
axe*		at uhub?		# ASIX Electronics AX88172 USB Ethernet
axen*		at uhub?		# ASIX Electronics AX88179 USB Ethernet
cdce*		at uhub?		# CDC Ethernet
cue*		at uhub?		# CATC USB-EL1201A based Ethernet
kue*		at uhub?		# Kawasaki KL5KUSB101B based Ethernet
mos*		at uhub?		# MOSCHIP MCS7730/7830 10/100 Ethernet
smsc*		at uhub?		# SMSC LAN95xx Ethernet
otus*		at uhub?		# Atheros AR9001U
rum*		at uhub?		# Ralink RT2501USB/RT2601USB
run*		at uhub?		# Ralink RT2700U/RT2800U/RT3000U
uath*		at uhub?		# Atheros AR5005UG/AR5005UX
udav*		at uhub?		# Davicom DM9601 based Ethernet
upgt*		at uhub?		# Conexant/Intersil PrismGT SoftMAC USB
upl*		at uhub?		# Prolific PL2301/PL2302 host-to-host
ugl*		at uhub?		# Genesys Logic GL620USB-A host-to-host
ural*		at uhub?		# Ralink RT2500USB
url*		at uhub?		# Realtek RTL8150L based adapters
urtw*		at uhub?		# Realtek 8187
wi*		at uhub?		# WaveLAN IEEE 802.11DS
zyd*		at uhub?		# Zydas ZD1211
ugen*		at uhub?		# USB Generic driver

ral*		at pci?
re*		at pci?
rl*		at pci?

acphy*		at mii?			# Altima AC101 PHYs
amphy*		at mii?			# AMD 79C873 PHYs
bmtphy*		at mii?			# Broadcom 10/100 PHYs
eephy*		at mii?			# Marvell 88E1000 series PHY
rgephy*		at mii?			# Realtek 8169S/8110S PHY
rlphy*		at mii?			# Realtek 8139 internal PHYs
urlphy*		at mii?			# Realtek RTL8150L internal PHY
ukphy*		at mii?			# "unknown" PHYs

scsibus*	at scsi?
sd*		at scsibus?
cd*		at scsibus?

pseudo-device	loop 1
pseudo-device	bpfilter 1
pseudo-device	rd 1
pseudo-device	wsmux 2

path: sys/arch/loongson/conf/RAMDISK


code:
#	$OpenBSD: files.loongson,v 1.19 2015/07/08 13:37:31 dlg Exp $

# Standard stanzas config(8) can't run without
maxpartitions 16
maxusers 2 8 64

# Major number for block devices, for ``root on'' lines
major	{ sd = 0 }
major	{ cd = 3 }
major	{ wd = 4 }
major	{ rd = 8 }

file	dev/cninit.c

file	arch/loongson/loongson/autoconf.c
file	arch/loongson/loongson/bus_dma.c
file	arch/loongson/loongson/bus_space.c
file	arch/loongson/loongson/conf.c
file	arch/loongson/loongson/disksubr.c		disk
file	arch/loongson/loongson/gdium_machdep.c
file	arch/loongson/loongson/generic2e_machdep.c
file	arch/loongson/loongson/isa_machdep.c		isa
file	arch/loongson/loongson/loongson2_machdep.c
file	arch/loongson/loongson/machdep.c
file	arch/loongson/loongson/hibernate_machdep.c	hibernate
file	arch/loongson/loongson/pciide_machdep.c		pciide
file	arch/loongson/loongson/pmon.c
file	arch/loongson/loongson/pmon32.S
file	arch/loongson/loongson/wscons_machdep.c		wsdisplay
file	arch/loongson/loongson/yeeloong_machdep.c

include "dev/ata/files.ata"
include "dev/atapiscsi/files.atapiscsi"
include	"dev/i2c/files.i2c"
include	"dev/gpio/files.gpio"
include	"dev/isa/files.isa"
include	"dev/isa/files.isapnp"
include	"dev/mii/files.mii"
include	"dev/pci/files.pci"
include	"dev/pckbc/files.pckbc"
include	"dev/usb/files.usb"
include "dev/rasops/files.rasops"
include "dev/wscons/files.wscons"
include "dev/wsfont/files.wsfont"
include	"scsi/files.scsi"

define	mainbus {}
device	mainbus
attach	mainbus at root
file	arch/loongson/dev/mainbus.c			mainbus

device	cpu
attach	cpu at mainbus

device	clock
attach	clock at mainbus

device	bonito {}: pcibus
attach	bonito at mainbus
file	arch/loongson/dev/bonito.c			bonito

# AMD Geode CS5536 companion chip
file	arch/loongson/dev/glx.c				bonito & pci

# Other PCI-ISA bridges
device	pcib: isabus
attach	pcib at pci
file	arch/loongson/dev/pcib.c			pcib | glxpcib

# Lemote Yeeloong RTC
device	mcclock
attach	mcclock at isa with mcclock_isa
file	arch/loongson/dev/mcclock.c			mcclock
file	arch/loongson/dev/mcclock_isa.c			mcclock_isa

# Lemote Yeeloong KB3310B Embedded Controller
device	ykbec
attach	ykbec at isa
file	arch/loongson/dev/kb3310.c			ykbec needs-flag

# Silicon Motion SM502 master device
device	voyager {}: gpiobus
attach	voyager at pci
file	arch/loongson/dev/voyager.c			voyager

# SM502 specific I2C bus bit-banging
device	gdiumiic: i2cbus, i2c_bitbang
attach	gdiumiic at gpio
file	arch/loongson/dev/gdiumiic.c			gdiumiic

# Gdium ST7 controller
device	stsec
attach	stsec at i2c
file	arch/loongson/dev/stsec.c			stsec

# Gdium M41T8x RTC
device	mfokclock
attach	mfokclock at i2c
file	arch/loongson/dev/m41t8xclock.c			mfokclock

# SM502 OHCI
attach	ohci at voyager with ohci_voyager
file	arch/loongson/dev/ohci_voyager.c		ohci_voyager

# Silicon Motion SM502/SM712 frame buffer
device	smfb: wsemuldisplaydev, rasops16
attach	smfb at pci with smfb_pci
attach	smfb at voyager with smfb_voyager
file	arch/loongson/dev/smfb.c			smfb	needs-flag

# SIS 315 Pro frame buffer
device	sisfb: wsemuldisplaydev, rasops8, rasops15, rasops16, rasops32
attach	sisfb at pci
file	arch/loongson/dev/sisfb.c			sisfb	needs-flag

device	apm
attach	apm at mainbus
file	arch/loongson/dev/apm.c				apm	needs-flag

device	glxclk
attach	glxclk at glxpcib
file	arch/loongson/dev/glxclk.c			glxclk


code:
OUTPUT_FORMAT("elf64-tradlittlemips")
OUTPUT_ARCH(mips)
ENTRY(__start)

SECTIONS
{
	.text :		{ *(.text .text.* .gnu.linkonce.t.*) }
	PROVIDE (etext = .);
	.rodata :	{ *(.rodata .rodata.* .gnu.linkonce.r.*) }
	_gp = ALIGN(16) + 0x7ff0;
	.data :		{ *(.data .data.* .gnu.linkonce.d.*) }
	PROVIDE (edata = .);
	.sbss :		{ *(.sbss .sbss.* .gnu.linkonce.sb.* .scommon) }
	.bss :		{ *(.bss .bss.* .gnu.linkonce.b.* COMMON) }
	PROVIDE (_end = .);
	PROVIDE (end = .);
	/DISCARD/ :
	{
		*(.pdr)
		*(.mdebug.abi64)
		*(.MIPS.options)
	}
}


path: sys/arch/loongson/dev/CVS/Entries


code: src/sys/arch/loongson/dev

path: sys/arch/loongson/dev/CVS/Repository


code:
/*	$OpenBSD: apm.c,v 1.28 2015/02/07 01:19:40 deraadt Exp $	*/

/*-
 * Copyright (c) 2001 Alexander Guy.  All rights reserved.
 * Copyright (c) 1998-2001 Michael Shalayeff. All rights reserved.
 * Copyright (c) 1995 John T. Kohl.  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 names of the authors nor the names of contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS 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 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.
 *
 */

#include "apm.h"
#include "wsdisplay.h"

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/device.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <sys/buf.h>
#include <sys/event.h>
#include <sys/reboot.h>
#include <sys/hibernate.h>
#include <dev/rndvar.h>

#include <machine/autoconf.h>
#include <machine/conf.h>
#include <machine/cpu.h>
#include <machine/apmvar.h>

#include <dev/pci/pcivar.h>    /* pci_dopm */

#include <dev/wscons/wsdisplayvar.h>

#include <loongson/dev/kb3310var.h>

#if defined(APMDEBUG)
#define DPRINTF(x)	printf x
#else
#define	DPRINTF(x)	/**/
#endif

struct apm_softc {
	struct device sc_dev;
	struct klist sc_note;
	int    sc_flags;
};

int apmmatch(struct device *, void *, void *);
void apmattach(struct device *, struct device *, void *);

struct cfattach apm_ca = {
	sizeof(struct apm_softc), apmmatch, apmattach
};

struct cfdriver apm_cd = {
	NULL, "apm", DV_DULL
};

#define	APMUNIT(dev)	(minor(dev)&0xf0)
#define	APMDEV(dev)	(minor(dev)&0x0f)
#define APMDEV_NORMAL	0
#define APMDEV_CTL	8

void filt_apmrdetach(struct knote *kn);
int filt_apmread(struct knote *kn, long hint);
int apmkqfilter(dev_t dev, struct knote *kn);
int apm_getdefaultinfo(struct apm_power_info *);

int apm_suspend(int state);

struct filterops apmread_filtops =
	{ 1, NULL, filt_apmrdetach, filt_apmread};

int (*get_apminfo)(struct apm_power_info *) = apm_getdefaultinfo;

/*
 * Flags to control kernel display
 *	SCFLAG_NOPRINT:		do not output APM power messages due to
 *				a power change event.
 *
 *	SCFLAG_PCTPRINT:	do not output APM power messages due to
 *				to a power change event unless the battery
 *				percentage changes.
 */

#define SCFLAG_NOPRINT	0x0008000
#define SCFLAG_PCTPRINT	0x0004000
#define SCFLAG_PRINT	(SCFLAG_NOPRINT|SCFLAG_PCTPRINT)

#define	SCFLAG_OREAD 	(1 << 0)
#define	SCFLAG_OWRITE	(1 << 1)
#define	SCFLAG_OPEN	(SCFLAG_OREAD|SCFLAG_OWRITE)

int
apmmatch(struct device *parent, void *match, void *aux)
{
	struct mainbus_attach_args *maa = aux;

	/*
	 * It only makes sense to attach on a 2F system, since 2E do not
	 * feature speed throttling, and we do not support 2E-based
	 * notebooks yet (assuming there are any).
	 */
	if (strcmp(maa->maa_name, apm_cd.cd_name) == 0 && loongson_ver == 0x2f)
		return (1);
	return (0);
}

void
apmattach(struct device *parent, struct device *self, void *aux)
{
	/* Enable PCI Power Management. */
	pci_dopm = 1;

	printf("\n");
}

int
apmopen(dev_t dev, int flag, int mode, struct proc *p)
{
	struct apm_softc *sc;
	int error = 0;

	/* apm0 only */
	if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 ||
	    !(sc = apm_cd.cd_devs[APMUNIT(dev)]))
		return ENXIO;

	DPRINTF(("apmopen: dev %d pid %d flag %x mode %x\n",
	    APMDEV(dev), p->p_pid, flag, mode));

	switch (APMDEV(dev)) {
	case APMDEV_CTL:
		if (!(flag & FWRITE)) {
			error = EINVAL;
			break;
		}
		if (sc->sc_flags & SCFLAG_OWRITE) {
			error = EBUSY;
			break;
		}
		sc->sc_flags |= SCFLAG_OWRITE;
		break;
	case APMDEV_NORMAL:
		if (!(flag & FREAD) || (flag & FWRITE)) {
			error = EINVAL;
			break;
		}
		sc->sc_flags |= SCFLAG_OREAD;
		break;
	default:
		error = ENXIO;
		break;
	}
	return error;
}

int
apmclose(dev_t dev, int flag, int mode, struct proc *p)
{
	struct apm_softc *sc;

	/* apm0 only */
	if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 ||
	    !(sc = apm_cd.cd_devs[APMUNIT(dev)]))
		return ENXIO;

	DPRINTF(("apmclose: pid %d flag %x mode %x\n", p->p_pid, flag, mode));

	switch (APMDEV(dev)) {
	case APMDEV_CTL:
		sc->sc_flags &= ~SCFLAG_OWRITE;
		break;
	case APMDEV_NORMAL:
		sc->sc_flags &= ~SCFLAG_OREAD;
		break;
	}
	return 0;
}

int
apmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
{
	struct apm_softc *sc;
	struct apm_power_info *power;
	int error = 0;

	/* apm0 only */
	if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 ||
	    !(sc = apm_cd.cd_devs[APMUNIT(dev)]))
		return ENXIO;

	switch (cmd) {
		/* some ioctl names from linux */
	case APM_IOC_STANDBY:
	case APM_IOC_STANDBY_REQ:
	case APM_IOC_SUSPEND:
	case APM_IOC_SUSPEND_REQ:
		if ((flag & FWRITE) == 0)
			error = EBADF;
		else if (sys_platform->suspend == NULL ||
		    sys_platform->resume == NULL)
			error = EOPNOTSUPP;
		else
			error = apm_suspend(APM_IOC_SUSPEND);
		break;
#ifdef HIBERNATE
	case APM_IOC_HIBERNATE:
		if ((flag & FWRITE) == 0)
			error = EBADF;
		else if (sys_platform->suspend == NULL ||
		    sys_platform->resume == NULL)
			error = EOPNOTSUPP;
		else
			error = apm_suspend(APM_IOC_HIBERNATE);
		break;
#endif
	case APM_IOC_PRN_CTL:
		if ((flag & FWRITE) == 0)
			error = EBADF;
		else {
			int flag = *(int *)data;
			DPRINTF(( "APM_IOC_PRN_CTL: %d\n", flag ));
			switch (flag) {
			case APM_PRINT_ON:	/* enable printing */
				sc->sc_flags &= ~SCFLAG_PRINT;
				break;
			case APM_PRINT_OFF: /* disable printing */
				sc->sc_flags &= ~SCFLAG_PRINT;
				sc->sc_flags |= SCFLAG_NOPRINT;
				break;
			case APM_PRINT_PCT: /* disable some printing */
				sc->sc_flags &= ~SCFLAG_PRINT;
				sc->sc_flags |= SCFLAG_PCTPRINT;
				break;
			default:
				error = EINVAL;
				break;
			}
		}
		break;
	case APM_IOC_DEV_CTL:
		if ((flag & FWRITE) == 0)
			error = EBADF;
		else
			error = EOPNOTSUPP; /* XXX */
		break;
	case APM_IOC_GETPOWER:
	        power = (struct apm_power_info *)data;
		error = (*get_apminfo)(power);
		break;
	default:
		error = ENOTTY;
	}

	return error;
}

void
filt_apmrdetach(struct knote *kn)
{
	struct apm_softc *sc = (struct apm_softc *)kn->kn_hook;

	SLIST_REMOVE(&sc->sc_note, kn, knote, kn_selnext);
}

int
filt_apmread(struct knote *kn, long hint)
{
	/* XXX weird kqueue_scan() semantics */
	if (hint && !kn->kn_data)
		kn->kn_data = (int)hint;

	return (1);
}

int
apmkqfilter(dev_t dev, struct knote *kn)
{
	struct apm_softc *sc;

	/* apm0 only */
	if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 ||
	    !(sc = apm_cd.cd_devs[APMUNIT(dev)]))
		return ENXIO;

	switch (kn->kn_filter) {
	case EVFILT_READ:
		kn->kn_fop = &apmread_filtops;
		break;
	default:
		return (EINVAL);
	}

	kn->kn_hook = (caddr_t)sc;
	SLIST_INSERT_HEAD(&sc->sc_note, kn, kn_selnext);

	return (0);
}

int
apm_getdefaultinfo(struct apm_power_info *info)
{
	info->battery_state = APM_BATT_UNKNOWN;
	info->ac_state = APM_AC_UNKNOWN;
	info->battery_life = 0;
	info->minutes_left = -1;
	return (0);
}

void
apm_setinfohook(int (*hook)(struct apm_power_info *))
{
	get_apminfo = hook;
}

int
apm_record_event(u_int event, const char *src, const char *msg)
{
	static int apm_evindex;
	struct apm_softc *sc;

	/* apm0 only */
	if (apm_cd.cd_ndevs == 0 || (sc = apm_cd.cd_devs[0]) == NULL)
		return ENXIO;

	if ((sc->sc_flags & SCFLAG_NOPRINT) == 0)
		printf("%s: %s %s\n", sc->sc_dev.dv_xname, src, msg);

	/* skip if no user waiting */
	if ((sc->sc_flags & SCFLAG_OPEN) == 0)
		return (1);

	apm_evindex++;
	KNOTE(&sc->sc_note, APM_EVENT_COMPOSE(event, apm_evindex));

	return (0);
}

int
apm_suspend(int state)
{
	int rv;
	int s;

#if NWSDISPLAY > 0
	wsdisplay_suspend();
#endif

	resettodr();

	config_suspend_all(DVACT_QUIESCE);
	bufq_quiesce();

	s = splhigh();
	(void)disableintr();
	cold = 1;

	rv = config_suspend_all(DVACT_SUSPEND);

	suspend_randomness();

#ifdef HIBERNATE
	if (state == APM_IOC_HIBERNATE) {
		uvm_pmr_zero_everything();
		if (hibernate_suspend()) {
			printf("apm: hibernate_suspend failed");
			hibernate_free();
			uvm_pmr_dirty_everything();
			return (ECANCELED);
		}
	}
#endif

	/* XXX
	 * Flag to disk drivers that they should "power down" the disk
	 * when we get to DVACT_POWERDOWN.
	 */
	boothowto |= RB_POWERDOWN;
	config_suspend_all(DVACT_POWERDOWN);
	boothowto &= ~RB_POWERDOWN;

	if (rv == 0) {
		rv = sys_platform->suspend();
		if (rv == 0)
			rv = sys_platform->resume();
	}
	inittodr(time_second);	/* Move the clock forward */
	config_suspend_all(DVACT_RESUME);

	cold = 0;
	(void)enableintr();
	splx(s);

	resume_randomness(NULL, 0);	/* force RNG upper level reseed */
	bufq_restart();

	config_suspend_all(DVACT_WAKEUP);

#if NWSDISPLAY > 0
	wsdisplay_resume();
#endif

	return rv;
}


code:
/*	$OpenBSD: bonito.c,v 1.28 2014/09/26 14:32:07 jsing Exp $	*/
/*	$NetBSD: bonito_mainbus.c,v 1.11 2008/04/28 20:23:10 martin Exp $	*/
/*	$NetBSD: bonito_pci.c,v 1.5 2008/04/28 20:23:28 martin Exp $	*/

/*
 * Copyright (c) 2009, 2010 Miodrag Vallat.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
/*-
 * Copyright (c) 2001 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Jason R. Thorpe.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * PCI configuration space support for the Loongson PCI and memory controller
 * chip, which is derived from the Algorithmics BONITO chip.
 */

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

#include <machine/autoconf.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <mips64/mips_cpu.h>
#include <machine/intr.h>

#include <dev/pci/pcidevs.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/ppbreg.h>

#include <loongson/dev/bonitoreg.h>
#include <loongson/dev/bonitovar.h>
#include <loongson/dev/bonito_irq.h>

#include <uvm/uvm_extern.h>

#if 0
#define	BONITO_DEBUG
#endif

int	bonito_match(struct device *, void *, void *);
void	bonito_attach(struct device *, struct device *, void *);

const struct cfattach bonito_ca = {
	sizeof(struct bonito_softc), bonito_match, bonito_attach
};

struct cfdriver bonito_cd = {
	NULL, "bonito", DV_DULL
};

#define	wbflush()	mips_sync()

bus_addr_t	bonito_pa_to_device(paddr_t);
paddr_t		bonito_device_to_pa(bus_addr_t);

void	 bonito_intr_makemasks(void);
uint32_t bonito_intr_2e(uint32_t, struct trap_frame *);
uint32_t bonito_intr_2f(uint32_t, struct trap_frame *);
void	 bonito_intr_dispatch(uint64_t, int, struct trap_frame *);

void	 bonito_attach_hook(struct device *, struct device *,
	    struct pcibus_attach_args *);
int	 bonito_bus_maxdevs(void *, int);
pcitag_t bonito_make_tag(void *, int, int, int);
void	 bonito_decompose_tag(void *, pcitag_t, int *, int *, int *);
int	 bonito_conf_size(void *, pcitag_t);
pcireg_t bonito_conf_read(void *, pcitag_t, int);
pcireg_t bonito_conf_read_internal(const struct bonito_config *, pcitag_t, int);
void	 bonito_conf_write(void *, pcitag_t, int, pcireg_t);
int	 bonito_pci_intr_map(struct pci_attach_args *, pci_intr_handle_t *);
const char *
	 bonito_pci_intr_string(void *, pci_intr_handle_t);
void	*bonito_pci_intr_establish(void *, pci_intr_handle_t, int,
	    int (*)(void *), void *, char *);
void	 bonito_pci_intr_disestablish(void *, void *);

int	 bonito_conf_addr(const struct bonito_config *, pcitag_t, int,
	    u_int32_t *, u_int32_t *);

void	 bonito_splx(int);

/*
 * Bonito interrupt handling declarations.
 * See <loongson/dev/bonito_irq.h> for details.
 */
struct intrhand *bonito_intrhand[BONITO_NINTS];
uint64_t bonito_intem;
uint64_t bonito_imask[NIPLS];

struct machine_bus_dma_tag bonito_bus_dma_tag = {
	._dmamap_create = _dmamap_create,
	._dmamap_destroy = _dmamap_destroy,
	._dmamap_load = _dmamap_load,
	._dmamap_load_mbuf = _dmamap_load_mbuf,
	._dmamap_load_uio = _dmamap_load_uio,
	._dmamap_load_raw = _dmamap_load_raw,
	._dmamap_load_buffer = _dmamap_load_buffer,
	._dmamap_unload = _dmamap_unload,
	._dmamap_sync = _dmamap_sync,

	._dmamem_alloc = _dmamem_alloc,
	._dmamem_free = _dmamem_free,
	._dmamem_map = _dmamem_map,
	._dmamem_unmap = _dmamem_unmap,
	._dmamem_mmap = _dmamem_mmap,

	._pa_to_device = bonito_pa_to_device,
	._device_to_pa = bonito_device_to_pa
};

int     bonito_io_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
	    bus_space_handle_t *);
int     bonito_mem_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
	    bus_space_handle_t *);

struct mips_bus_space bonito_pci_io_space_tag = {
	.bus_base = PHYS_TO_XKPHYS(BONITO_PCIIO_BASE, CCA_NC),
	._space_read_1 = generic_space_read_1,
	._space_write_1 = generic_space_write_1,
	._space_read_2 = generic_space_read_2,
	._space_write_2 = generic_space_write_2,
	._space_read_4 = generic_space_read_4,
	._space_write_4 = generic_space_write_4,
	._space_read_8 = generic_space_read_8,
	._space_write_8 = generic_space_write_8,
	._space_read_raw_2 = generic_space_read_raw_2,
	._space_write_raw_2 = generic_space_write_raw_2,
	._space_read_raw_4 = generic_space_read_raw_4,
	._space_write_raw_4 = generic_space_write_raw_4,
	._space_read_raw_8 = generic_space_read_raw_8,
	._space_write_raw_8 = generic_space_write_raw_8,
	._space_map = bonito_io_map,
	._space_unmap = generic_space_unmap,
	._space_subregion = generic_space_region,
	._space_vaddr = generic_space_vaddr,
	._space_mmap = generic_space_mmap
};

struct mips_bus_space bonito_pci_mem_space_tag = {
	.bus_base = PHYS_TO_XKPHYS(0, CCA_NC),
	._space_read_1 = generic_space_read_1,
	._space_write_1 = generic_space_write_1,
	._space_read_2 = generic_space_read_2,
	._space_write_2 = generic_space_write_2,
	._space_read_4 = generic_space_read_4,
	._space_write_4 = generic_space_write_4,
	._space_read_8 = generic_space_read_8,
	._space_write_8 = generic_space_write_8,
	._space_read_raw_2 = generic_space_read_raw_2,
	._space_write_raw_2 = generic_space_write_raw_2,
	._space_read_raw_4 = generic_space_read_raw_4,
	._space_write_raw_4 = generic_space_write_raw_4,
	._space_read_raw_8 = generic_space_read_raw_8,
	._space_write_raw_8 = generic_space_write_raw_8,
	._space_map = bonito_mem_map,
	._space_unmap = generic_space_unmap,
	._space_subregion = generic_space_region,
	._space_vaddr = generic_space_vaddr,
	._space_mmap = generic_space_mmap
};

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

	if (loongson_ver >= 0x3a)
		return (0);

	if (strcmp(maa->maa_name, bonito_cd.cd_name) == 0)
		return (1);

	return (0);
}

void
bonito_attach(struct device *parent, struct device *self, void *aux)
{
	struct bonito_softc *sc = (struct bonito_softc *)self;
	struct pcibus_attach_args pba;
	pci_chipset_tag_t pc = &sc->sc_pc;
	const struct bonito_config *bc;
	uint32_t reg;

	/*
	 * Loongson 2F processors do not use a real Bonito64 chip but
	 * their own derivative, which is no longer 100% compatible.
	 * We need to make sure we never try to access an unimplemented
	 * register...
	 */
	if (loongson_ver >= 0x2f)
		sc->sc_compatible = 0;
	else
		sc->sc_compatible = 1;

	reg = PCI_REVISION(REGVAL(BONITO_PCI_REG(PCI_CLASS_REG)));
	if (sc->sc_compatible) {
		printf(": BONITO Memory and PCI controller, %s rev %d.%d\n",
		    BONITO_REV_FPGA(reg) ? "FPGA" : "ASIC",
		    BONITO_REV_MAJOR(reg), BONITO_REV_MINOR(reg));
	} else {
		printf(": memory and PCI-X controller, rev %d\n",
		    PCI_REVISION(REGVAL(BONITO_PCI_REG(PCI_CLASS_REG))));
	}

	bc = sys_platform->bonito_config;
	sc->sc_bonito = bc;
	SLIST_INIT(&sc->sc_hook);

#ifdef BONITO_DEBUG
	if (!sc->sc_compatible)
		printf("ISR4C: %08x\n", REGVAL(BONITO_PCI_REG(0x4c)));
	printf("PCIMAP: %08x\n", REGVAL(BONITO_PCIMAP));
	printf("MEMWIN: %08x.%08x - %08x.%08x\n",
	    REGVAL(BONITO_MEM_WIN_BASE_H), REGVAL(BONITO_MEM_WIN_BASE_L),
	    REGVAL(BONITO_MEM_WIN_MASK_H), REGVAL(BONITO_MEM_WIN_MASK_L));
	if (!sc->sc_compatible) {
		printf("HITSEL0: %08x.%08x\n",
		    REGVAL(LOONGSON_PCI_HIT0_SEL_H),
		    REGVAL(LOONGSON_PCI_HIT0_SEL_L));
		printf("HITSEL1: %08x.%08x\n",
		    REGVAL(LOONGSON_PCI_HIT1_SEL_H),
		    REGVAL(LOONGSON_PCI_HIT1_SEL_L));
		printf("HITSEL2: %08x.%08x\n",
		    REGVAL(LOONGSON_PCI_HIT2_SEL_H),
		    REGVAL(LOONGSON_PCI_HIT2_SEL_L));
	}
	printf("PCI BAR 0:%08x 1:%08x 2:%08x 3:%08x 4:%08x 5:%08x\n",
	    REGVAL(BONITO_PCI_REG(PCI_MAPREG_START + 0 * 4)),
	    REGVAL(BONITO_PCI_REG(PCI_MAPREG_START + 1 * 4)),
	    REGVAL(BONITO_PCI_REG(PCI_MAPREG_START + 2 * 4)),
	    REGVAL(BONITO_PCI_REG(PCI_MAPREG_START + 3 * 4)),
	    REGVAL(BONITO_PCI_REG(PCI_MAPREG_START + 4 * 4)),
	    REGVAL(BONITO_PCI_REG(PCI_MAPREG_START + 5 * 4)));
#endif

	/*
	 * Setup proper abitration.
	 */

	if (!sc->sc_compatible) {
		/*
		 * According to Linux, changing the value of this register
		 * ``avoids deadlock of PCI reading/writing lock operation''.
		 *
		 * Unfortunately, documentation for the Implementation
		 * Specific Registers (ISR40 to ISR5C) is only found in the
		 * chinese version of the Loongson 2F documentation.
		 *
		 * The particular bit we set here is ``mas_read_defer''.
		 */
		/* c2000001 -> d2000001 */
		REGVAL(BONITO_PCI_REG(0x4c)) |= 0x10000000;

		/* all pci devices may need to hold the bus */
		reg = REGVAL(LOONGSON_PXARB_CFG);
		reg &= ~LOONGSON_PXARB_RUDE_DEV_MSK;
		reg |= 0xfe << LOONGSON_PXARB_RUDE_DEV_SHFT;
		REGVAL(LOONGSON_PXARB_CFG) = reg;
		(void)REGVAL(LOONGSON_PXARB_CFG);
	}

	/*
	 * Setup interrupt handling.
	 */

	REGVAL(BONITO_GPIOIE) = bc->bc_gpioIE;
	REGVAL(BONITO_INTEDGE) = bc->bc_intEdge;
	if (sc->sc_compatible)
		REGVAL(BONITO_INTSTEER) = bc->bc_intSteer;
	REGVAL(BONITO_INTPOL) = bc->bc_intPol;

	REGVAL(BONITO_INTENCLR) = 0xffffffff;
	(void)REGVAL(BONITO_INTENCLR);

	if (sc->sc_compatible) {
		bonito_intem |= BONITO_INTRMASK_MASTERERR;
	}

	if (loongson_ver >= 0x2f)
		set_intr(INTPRI_BONITO, CR_INT_4, bonito_intr_2f);
	else
		set_intr(INTPRI_BONITO, CR_INT_0, bonito_intr_2e);
	register_splx_handler(bonito_splx);

	/*
	 * Attach PCI bus.
	 */

	pc->pc_conf_v = sc;
	pc->pc_attach_hook = bonito_attach_hook;
	pc->pc_bus_maxdevs = bonito_bus_maxdevs;
	pc->pc_make_tag = bonito_make_tag;
	pc->pc_decompose_tag = bonito_decompose_tag;
	pc->pc_conf_size = bonito_conf_size;
	pc->pc_conf_read = bonito_conf_read;
	pc->pc_conf_write = bonito_conf_write;

	pc->pc_intr_v = sc;
	pc->pc_intr_map = bonito_pci_intr_map;
	pc->pc_intr_string = bonito_pci_intr_string;
	pc->pc_intr_establish = bonito_pci_intr_establish;
	pc->pc_intr_disestablish = bonito_pci_intr_disestablish;

	bzero(&pba, sizeof pba);
	pba.pba_busname = "pci";
	pba.pba_iot = &bonito_pci_io_space_tag;
	pba.pba_memt = &bonito_pci_mem_space_tag;
	pba.pba_dmat = &bonito_bus_dma_tag;
	pba.pba_pc = pc;
	pba.pba_domain = pci_ndomains++;
	pba.pba_bus = 0;
#ifdef notyet
	pba.pba_ioex = bonito_get_resource_extent(pc, 1);
	pba.pba_memex = bonito_get_resource_extent(pc, 0);
#endif

	config_found(&sc->sc_dev, &pba, bonito_print);
}

bus_addr_t
bonito_pa_to_device(paddr_t pa)
{
	return pa ^ loongson_dma_base;
}

paddr_t
bonito_device_to_pa(bus_addr_t addr)
{
	return addr ^ loongson_dma_base;
}

int
bonito_print(void *aux, const char *pnp)
{
	struct pcibus_attach_args *pba = aux;

	if (pnp)
		printf("%s at %s", pba->pba_busname, pnp);
	printf(" bus %d", pba->pba_bus);

	return UNCONF;
}

/*
 * Bonito interrupt handling
 */

void *
bonito_intr_establish(int irq, int type, int level, int (*handler)(void *),
    void *arg, const char *name)
{
	struct intrhand **p, *q, *ih;
	int s;

#ifdef DIAGNOSTIC
	if (irq >= BONITO_NINTS || irq == BONITO_ISA_IRQ(2) || irq < 0)
		panic("bonito_intr_establish: illegal irq %d", irq);
#endif

	ih = malloc(sizeof *ih, M_DEVBUF, M_NOWAIT);
	if (ih == NULL)
		return NULL;

	ih->ih_next = NULL;
	ih->ih_fun = handler;
	ih->ih_arg = arg;
	ih->ih_level = level;
	ih->ih_irq = irq;
	evcount_attach(&ih->ih_count, name, &ih->ih_irq);

	s = splhigh();

	/*
	 * Figure out where to put the handler.
	 * This is O(N^2), but we want to preserve the order, and N is
	 * generally small.
	 */
	for (p = &bonito_intrhand[irq]; (q = *p) != NULL; p = &q->ih_next)
		;
	*p = ih;

	bonito_intem |= 1UL << irq;
	bonito_intr_makemasks();

	splx(s);	/* causes hw mask update */

	return (ih);
}

void
bonito_intr_disestablish(void *vih)
{
	struct intrhand *ih = (struct intrhand *)vih;
	struct intrhand **p, *q;
	int irq = ih->ih_irq;
	int s;

#ifdef DIAGNOSTIC
	if (irq >= BONITO_NINTS || irq == BONITO_ISA_IRQ(2) || irq < 0)
		panic("bonito_intr_disestablish: illegal irq %d", irq);
#endif

	s = splhigh();

	evcount_detach(&ih->ih_count);

	for (p = &bonito_intrhand[irq]; (q = *p) != NULL; p = &q->ih_next)
		if (q == ih)
			break;
#ifdef DIAGNOSTIC
	if (q == NULL)
		panic("bonito_intr_disestablish: never registered");
#endif
	*p = ih->ih_next;

	if (ih->ih_next == NULL && p == &bonito_intrhand[irq]) {
		bonito_intem &= ~(1UL << irq);
		bonito_intr_makemasks();
		/*
		 * No need to clear a bit in INTEN through INTCLR,
		 * splhigh() took care of disabling everything and
		 * splx() will not reenable this source after the
		 * mask update.
		 */
	}

	splx(s);

	free(ih, M_DEVBUF, 0);
}

/*
 * Update interrupt masks. This is for designs without legacy PIC.
 */

void
bonito_splx(int newipl)
{
	struct cpu_info *ci = curcpu();

	/* Update masks to new ipl. Order highly important! */
	__asm__ (".set noreorder\n");
	ci->ci_ipl = newipl;
	mips_sync();
	__asm__ (".set reorder\n");
	bonito_setintrmask(newipl);
	/* If we still have softints pending trigger processing. */
	if (ci->ci_softpending != 0 && newipl < IPL_SOFTINT)
		setsoftintr0();
}

void
bonito_setintrmask(int level)
{
	uint64_t active;
	uint32_t clear, set;
	register_t sr;

	active = bonito_intem & ~bonito_imask[level];
	/* be sure to mask high bits, there may be other interrupt sources */
	clear = BONITO_DIRECT_MASK(bonito_imask[level]);
	set = BONITO_DIRECT_MASK(active);

	sr = disableintr();

	if (clear != 0) {
		REGVAL(BONITO_INTENCLR) = clear;
		(void)REGVAL(BONITO_INTENCLR);
	}
	if (set != 0) {
		REGVAL(BONITO_INTENSET) = set;
		(void)REGVAL(BONITO_INTENSET);
	}

	setsr(sr);
}

/*
 * Recompute interrupt masks.
 */
void
bonito_intr_makemasks()
{
	int irq, level;
	struct intrhand *q;
	uint intrlevel[BONITO_NINTS];

	/* First, figure out which levels each IRQ uses. */
	for (irq = 0; irq < BONITO_NINTS; irq++) {
		uint levels = 0;
		for (q = bonito_intrhand[irq]; q != NULL; q = q->ih_next)
			levels |= 1 << q->ih_level;
		intrlevel[irq] = levels;
	}

	/*
	 * Then figure out which IRQs use each level.
	 * Note that we make sure never to overwrite imask[IPL_HIGH], in
	 * case an interrupt occurs during intr_disestablish() and causes
	 * an unfortunate splx() while we are here recomputing the masks.
	 */
	for (level = IPL_NONE; level < IPL_HIGH; level++) {
		uint64_t irqs = 0;
		for (irq = 0; irq < BONITO_NINTS; irq++)
			if (intrlevel[irq] & (1 << level))
				irqs |= 1UL << irq;
		bonito_imask[level] = irqs;
	}

	/*
	 * There are tty, network and disk drivers that use free() at interrupt
	 * time, so vm > (tty | net | bio).
	 *
	 * Enforce a hierarchy that gives slow devices a better chance at not
	 * dropping data.
	 */
	bonito_imask[IPL_NET] |= bonito_imask[IPL_BIO];
	bonito_imask[IPL_TTY] |= bonito_imask[IPL_NET];
	bonito_imask[IPL_VM] |= bonito_imask[IPL_TTY];
	bonito_imask[IPL_CLOCK] |= bonito_imask[IPL_VM];

	/*
	 * These are pseudo-levels.
	 */
	bonito_imask[IPL_NONE] = 0;
	bonito_imask[IPL_HIGH] = -1UL;
}

/*
 * Process native interrupts
 */

uint32_t
bonito_intr_2e(uint32_t hwpend, struct trap_frame *frame)
{
	uint64_t imr, isr, mask;

	isr = REGVAL(BONITO_INTISR);

	/*
	 * According to Linux code, Bonito64 - at least on Loongson
	 * systems - triggers an interrupt during DMA, which is to be
	 * ignored. Smells like a chip errata to me.
	 */
	while (ISSET(isr, BONITO_INTRMASK_MASTERERR)) {
		delay(1);
		isr = REGVAL(BONITO_INTISR);
	}

	isr &= BONITO_INTRMASK_GPIN;
	imr = REGVAL(BONITO_INTEN);
	isr &= imr;
#ifdef DEBUG
	printf("pci interrupt: imr %04x isr %04x\n", imr, isr);
#endif
	if (isr == 0)
		return 0;	/* not for us */

	/*
	 * Mask all pending interrupts.
	 */
	REGVAL(BONITO_INTENCLR) = isr;
	(void)REGVAL(BONITO_INTENCLR);

	/*
	 * If interrupts are spl-masked, mask them and wait for splx()
	 * to reenable them when necessary.
	 */
	if ((mask = isr & bonito_imask[frame->ipl]) != 0) {
		isr &= ~mask;
		imr &= ~mask;
	}

	/*
	 * Now process allowed interrupts.
	 */
	if (isr != 0) {
		bonito_intr_dispatch(isr, 30, frame);

		/*
		 * Reenable interrupts which have been serviced.
		 */
		REGVAL(BONITO_INTENSET) = imr;
		(void)REGVAL(BONITO_INTENSET);
	}

	return hwpend;
}

uint32_t
bonito_intr_2f(uint32_t hwpend, struct trap_frame *frame)
{
	uint64_t imr, isr, mask;

	isr = REGVAL(BONITO_INTISR) & LOONGSON_INTRMASK_LVL4;
	imr = REGVAL(BONITO_INTEN);
	isr &= imr;
#ifdef DEBUG
	printf("pci interrupt: imr %04x isr %04x\n", imr, isr);
#endif
	if (isr == 0)
		return 0;	/* not for us */

	/*
	 * Mask all pending interrupts.
	 */
	REGVAL(BONITO_INTENCLR) = isr;
	(void)REGVAL(BONITO_INTENCLR);

	/*
	 * If interrupts are spl-masked, mask them and wait for splx()
	 * to reenable them when necessary.
	 */
	if ((mask = isr & bonito_imask[frame->ipl]) != 0) {
		isr &= ~mask;
		imr &= ~mask;
	}

	/*
	 * Now process allowed interrupts.
	 */
	if (isr != 0) {
		bonito_intr_dispatch(isr,
		    LOONGSON_INTR_DRAM_PARERR /* skip non-pci interrupts */,
		    frame);

		/*
		 * Reenable interrupts which have been serviced.
		 */
		REGVAL(BONITO_INTENSET) = imr;
		(void)REGVAL(BONITO_INTENSET);
	}

	return hwpend;
}

void
bonito_intr_dispatch(uint64_t isr, int startbit, struct trap_frame *frame)
{
	int lvl, bitno;
	uint64_t tmpisr, mask;
	struct intrhand *ih;
	int rc;

	/* Service higher level interrupts first */
	for (lvl = IPL_HIGH - 1; lvl != IPL_NONE; lvl--) {
		tmpisr = isr & (bonito_imask[lvl] ^ bonito_imask[lvl - 1]);
		if (tmpisr == 0)
			continue;
		for (bitno = startbit, mask = 1UL << bitno; mask != 0;
		    bitno--, mask >>= 1) {
			if ((tmpisr & mask) == 0)
				continue;

			rc = 0;
			for (ih = bonito_intrhand[bitno]; ih != NULL;
			    ih = ih->ih_next) {
				splraise(ih->ih_level);
				if ((*ih->ih_fun)(ih->ih_arg) != 0) {
					rc = 1;
					ih->ih_count.ec_count++;
				}
				__asm__ (".set noreorder\n");
				curcpu()->ci_ipl = frame->ipl;
				mips_sync();
				__asm__ (".set reorder\n");
			}
			if (rc == 0) {
				printf("spurious interrupt %d\n", bitno);
#ifdef DEBUG
				printf("ISR %08x IMR %08x ipl %d mask %08x\n",
				    REGVAL(BONITO_INTISR), REGVAL(BONITO_INTEN),
				    frame->ipl, bonito_imask[frame->ipl]);
#ifdef DDB
				Debugger();
#endif
#endif
			}

			if ((isr ^= mask) == 0)
				return;
			if ((tmpisr ^= mask) == 0)
				break;
		}
	}
}

/*
 * various PCI helpers
 */

void
bonito_attach_hook(struct device *parent, struct device *self,
    struct pcibus_attach_args *pba)
{
	pci_chipset_tag_t pc = pba->pba_pc;
	struct bonito_softc *sc = pc->pc_conf_v;
	const struct bonito_config *bc = sc->sc_bonito;

	if (pba->pba_bus != 0)
		return;

	(*bc->bc_attach_hook)(pc);
}

/*
 * PCI configuration space access routines
 */

int
bonito_bus_maxdevs(void *v, int busno)
{
	struct bonito_softc *sc = v;
	const struct bonito_config *bc = sc->sc_bonito;

	return busno == 0 ? 32 - bc->bc_adbase : 32;
}

pcitag_t
bonito_make_tag(void *unused, int b, int d, int f)
{
	return (b << 16) | (d << 11) | (f << 8);
}

void
bonito_decompose_tag(void *unused, pcitag_t tag, int *bp, int *dp, int *fp)
{
	if (bp != NULL)
		*bp = (tag >> 16) & 0xff;
	if (dp != NULL)
		*dp = (tag >> 11) & 0x1f;
	if (fp != NULL)
		*fp = (tag >> 8) & 0x7;
}

int
bonito_conf_addr(const struct bonito_config *bc, pcitag_t tag, int offset,
    u_int32_t *cfgoff, u_int32_t *pcimap_cfg)
{
	int b, d, f;

	bonito_decompose_tag(NULL, tag, &b, &d, &f);

	if (b == 0) {
		d += bc->bc_adbase;
		if (d > 31)
			return 1;
		*cfgoff = (1 << d) | (f << 8) | offset;
		*pcimap_cfg = 0;
	} else {
		*cfgoff = tag | offset;
		*pcimap_cfg = BONITO_PCIMAPCFG_TYPE1;
	}

	return 0;
}

/* PCI Configuration Space access hook structure */
struct bonito_cfg_hook {
	SLIST_ENTRY(bonito_cfg_hook) next;
	int	(*read)(void *, pci_chipset_tag_t, pcitag_t, int, pcireg_t *);
	int	(*write)(void *, pci_chipset_tag_t, pcitag_t, int, pcireg_t);
	void	*cookie;
};

int
bonito_pci_hook(pci_chipset_tag_t pc, void *cookie,
    int (*r)(void *, pci_chipset_tag_t, pcitag_t, int, pcireg_t *),
    int (*w)(void *, pci_chipset_tag_t, pcitag_t, int, pcireg_t))
{
	struct bonito_softc *sc = pc->pc_conf_v;
	struct bonito_cfg_hook *bch;

	bch = malloc(sizeof *bch, M_DEVBUF, M_NOWAIT);
	if (bch == NULL)
		return ENOMEM;

	bch->read = r;
	bch->write = w;
	bch->cookie = cookie;
	SLIST_INSERT_HEAD(&sc->sc_hook, bch, next);
	return 0;
}

int
bonito_conf_size(void *v, pcitag_t tag)
{
	return PCI_CONFIG_SPACE_SIZE;
}

pcireg_t
bonito_conf_read(void *v, pcitag_t tag, int offset)
{
	struct bonito_softc *sc = v;
	struct bonito_cfg_hook *hook;
	pcireg_t data;

	SLIST_FOREACH(hook, &sc->sc_hook, next) {
		if (hook->read != NULL &&
		    (*hook->read)(hook->cookie, &sc->sc_pc, tag, offset,
		      &data) != 0)
			return data;
	}

	return bonito_conf_read_internal(sc->sc_bonito, tag, offset);
}

pcireg_t
bonito_conf_read_internal(const struct bonito_config *bc, pcitag_t tag,
    int offset)
{
	pcireg_t data;
	u_int32_t cfgoff, pcimap_cfg;
	register_t sr;
	uint64_t imr;

	if (bonito_conf_addr(bc, tag, offset, &cfgoff, &pcimap_cfg))
		return (pcireg_t)-1;

	sr = disableintr();
	imr = REGVAL(BONITO_INTEN);
	REGVAL(BONITO_INTENCLR) = 0xffffffff;
	(void)REGVAL(BONITO_INTENCLR);

	/* clear aborts */
	REGVAL(BONITO_PCI_REG(PCI_COMMAND_STATUS_REG)) |=
	    PCI_STATUS_MASTER_ABORT | PCI_STATUS_MASTER_TARGET_ABORT;

	/* high 16 bits of address go into PciMapCfg register */
	REGVAL(BONITO_PCIMAP_CFG) = (cfgoff >> 16) | pcimap_cfg;
	(void)REGVAL(BONITO_PCIMAP_CFG);
	wbflush();

	/* low 16 bits of address are offset into config space */
	data = REGVAL(BONITO_PCICFG_BASE + (cfgoff & 0xfffc));

	/* check for error */
	if (REGVAL(BONITO_PCI_REG(PCI_COMMAND_STATUS_REG)) &
	    (PCI_STATUS_MASTER_ABORT | PCI_STATUS_MASTER_TARGET_ABORT)) {
		REGVAL(BONITO_PCI_REG(PCI_COMMAND_STATUS_REG)) |=
		    PCI_STATUS_MASTER_ABORT | PCI_STATUS_MASTER_TARGET_ABORT;
		data = (pcireg_t) -1;
	}

	REGVAL(BONITO_INTENSET) = imr;
	(void)REGVAL(BONITO_INTENSET);
	setsr(sr);

	return data;
}

void
bonito_conf_write(void *v, pcitag_t tag, int offset, pcireg_t data)
{
	struct bonito_softc *sc = v;
	u_int32_t cfgoff, pcimap_cfg;
	struct bonito_cfg_hook *hook;
	register_t sr;
	uint64_t imr;

	SLIST_FOREACH(hook, &sc->sc_hook, next) {
		if (hook->write != NULL &&
		    (*hook->write)(hook->cookie, &sc->sc_pc, tag, offset,
		      data) != 0)
			return;
	}

	if (bonito_conf_addr(sc->sc_bonito, tag, offset, &cfgoff, &pcimap_cfg))
		panic("bonito_conf_write");

	sr = disableintr();
	imr = REGVAL(BONITO_INTEN);
	REGVAL(BONITO_INTENCLR) = 0xffffffff;
	(void)REGVAL(BONITO_INTENCLR);

	/* clear aborts */
	REGVAL(BONITO_PCI_REG(PCI_COMMAND_STATUS_REG)) |=
	    PCI_STATUS_MASTER_ABORT | PCI_STATUS_MASTER_TARGET_ABORT;

	/* high 16 bits of address go into PciMapCfg register */
	REGVAL(BONITO_PCIMAP_CFG) = (cfgoff >> 16) | pcimap_cfg;
	(void)REGVAL(BONITO_PCIMAP_CFG);
	wbflush();

	/* low 16 bits of address are offset into config space */
	REGVAL(BONITO_PCICFG_BASE + (cfgoff & 0xfffc)) = data;

	REGVAL(BONITO_INTENSET) = imr;
	(void)REGVAL(BONITO_INTENSET);
	setsr(sr);
}

/*
 * PCI Interrupt handling
 */

int
bonito_pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
{
	struct bonito_softc *sc = pa->pa_pc->pc_intr_v;
	const struct bonito_config *bc = sc->sc_bonito;
	int bus, dev, fn, pin;

	*ihp = (pci_intr_handle_t)-1;

	if (pa->pa_intrpin == 0)	/* no interrupt needed */
		return 1;

#ifdef DIAGNOSTIC
	if (pa->pa_intrpin > 4) {
		printf("%s: bad interrupt pin %d\n", __func__, pa->pa_intrpin);
		return 1;
	}
#endif

	pci_decompose_tag(pa->pa_pc, pa->pa_tag, &bus, &dev, &fn);
	if (pa->pa_bridgetag) {
		pin = PPB_INTERRUPT_SWIZZLE(pa->pa_rawintrpin, dev);
		*ihp = pa->pa_bridgeih[pin - 1];
	} else {
		if (bus == 0)
			*ihp = (*bc->bc_intr_map)(dev, fn, pa->pa_intrpin);

		if (*ihp == (pci_intr_handle_t)-1)
			return 1;
	}

	return 0;
}

const char *
bonito_pci_intr_string(void *cookie, pci_intr_handle_t ih)
{
	static char irqstr[1 + 12];

	if (BONITO_IRQ_IS_ISA(ih))
		snprintf(irqstr, sizeof irqstr, "isa irq %lu",
		    BONITO_IRQ_TO_ISA(ih));
	else
		snprintf(irqstr, sizeof irqstr, "irq %lu", ih);
	return irqstr;
}

void *
bonito_pci_intr_establish(void *cookie, pci_intr_handle_t ih, int level,
    int (*cb)(void *), void *cbarg, char *name)
{
	return bonito_intr_establish(ih, IST_LEVEL, level, cb, cbarg, name);
}

void
bonito_pci_intr_disestablish(void *cookie, void *ihp)
{
	bonito_intr_disestablish(ihp);
}

/*
 * bus_space mapping routines.
 */

/*
 * Legacy I/O access protection.
 * Since MI ISA code does not expect bus access to cause any failure when
 * accessing missing hardware, but only receive bogus data in return, we
 * force bus_space_map() to fail if there is no hardware there.
 */

int
bonito_io_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size, int flags,
    bus_space_handle_t *bshp)
{
	const struct legacy_io_range *r;
	bus_addr_t rend;

	if (offs < BONITO_PCIIO_LEGACY) {
		if ((r = sys_platform->legacy_io_ranges) == NULL)
			return ENXIO;

		rend = offs + size - 1;
		for (; r->start != 0; r++)
			if (offs >= r->start && rend <= r->end)
				break;

		if (r->end == 0)
			return ENXIO;
	}

	*bshp = t->bus_base + offs;
	return 0;
}

/*
 * PCI memory access.
 * Things are a bit complicated here, as we can either use one of the 64MB
 * windows in PCILO space (making sure ranges spanning multiple windows will
 * turn contiguous), or a direct access within the PCIHI space.
 * Note that, on 2F systems, only the PCIHI range for which CPU->PCI accesses
 * are enabled in the crossbar is usable.
 */

int
bonito_mem_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size, int flags,
    bus_space_handle_t *bshp)
{
	uint32_t pcimap;
	bus_addr_t pcilo_w[3];
	bus_addr_t ws, we, w;
	bus_addr_t end = offs + size - 1;
	int pcilo_window;

	pcimap = REGVAL(BONITO_PCIMAP);

	/*
	 * Try a PCIHI mapping first.
	 */

	if (loongson_ver >= 0x2f) {
		if (offs >= LS2F_PCIHI_BASE && end <= LS2F_PCIHI_TOP) {
			*bshp = t->bus_base + offs;
			return 0;
		}
	} else {
		/*
		 * Only try HI space if we do not have memory setup there.
		 */
		if (physmem <= atop(BONITO_PCILO_BASE)) {
			/* PCI1.5 */
			if (offs >= BONITO_PCIHI_BASE &&
			    end <= BONITO_PCIHI_TOP) {
				*bshp = t->bus_base + offs;
				return 0;
			}

			/* PCI2 */
			w = pcimap & BONITO_PCIMAP_PCIMAP_2 ? 0x80000000UL : 0;
			if (offs >= w && end < (w + 0x80000000UL)) {
				*bshp = t->bus_base + 0x80000000UL + (offs - w);
				return 0;
			}
		}
	}

	/*
	 * No luck, try a PCILO mapping.
	 */

	/*
	 * Decode PCIMAP, and figure out what PCILO mappings are
	 * possible.
	 */

	pcilo_w[0] = (pcimap & BONITO_PCIMAP_PCIMAP_LO0) >>
	    BONITO_PCIMAP_PCIMAP_LO0_SHIFT;
	pcilo_w[1] = (pcimap & BONITO_PCIMAP_PCIMAP_LO1) >>
	    BONITO_PCIMAP_PCIMAP_LO1_SHIFT;
	pcilo_w[2] = (pcimap & BONITO_PCIMAP_PCIMAP_LO2) >>
	    BONITO_PCIMAP_PCIMAP_LO2_SHIFT;

	/*
	 * Check if the 64MB areas we want to span are all available as
	 * contiguous PCILO mappings.
	 */

	ws = offs >> 26;
	we = end >> 26;

	pcilo_window = -1;
	if (ws == pcilo_w[0])
		pcilo_window = 0;
	else if (ws == pcilo_w[1])
		pcilo_window = 1;
	else if (ws == pcilo_w[2])
		pcilo_window = 2;

	if (pcilo_window >= 0) {
		/* contiguous area test */
		for (w = ws + 1; w <= we; w++) {
			if (pcilo_window + (w - ws) > 2 ||
			    w != pcilo_w[pcilo_window + (w - ws)]) {
				pcilo_window = -1;
				break;
			}
		}
	}

	if (pcilo_window >= 0) {
		*bshp = t->bus_base + BONITO_PCILO_BASE +
		    BONITO_PCIMAP_WINBASE(pcilo_window) +
		    BONITO_PCIMAP_WINOFFSET(offs);
		return 0;
	}

	return EINVAL;
}

/*
 * PCI resource handling
 */

struct extent *
bonito_get_resource_extent(pci_chipset_tag_t pc, int io)
{
	struct bonito_softc *sc = pc->pc_conf_v;
	struct extent *ex;
	char *exname;
	size_t exnamesz;
	uint32_t reg;
	int errors;

	exnamesz = 1 + 16 + 4;
	exname = (char *)malloc(exnamesz, M_DEVBUF, M_NOWAIT);
	if (exname == NULL)
		return NULL;
	snprintf(exname, exnamesz, "%s%s", sc->sc_dev.dv_xname,
	    io ? "_io" : "_mem");

	ex = extent_create(exname, 0, 0xffffffff, M_DEVBUF, NULL, 0,
	    EX_NOWAIT | EX_FILLED);
	if (ex == NULL)
		goto out;

	errors = 0;
	if (io) {
		/*
		 * Reserve the low 16KB of I/O space to the legacy hardware,
		 * if any.
		 */
		if (extent_free(ex, BONITO_PCIIO_LEGACY, BONITO_PCIIO_SIZE,
		    EX_NOWAIT) != 0)
			errors++;
	} else {
		reg = REGVAL(BONITO_PCIMAP);
		if (extent_free(ex,
		    BONITO_PCIMAP_WINBASE((reg & BONITO_PCIMAP_PCIMAP_LO0) >>
		      BONITO_PCIMAP_PCIMAP_LO0_SHIFT),
		    BONITO_PCIMAP_WINSIZE, EX_NOWAIT) != 0)
			errors++;
		if (extent_free(ex,
		    BONITO_PCIMAP_WINBASE((reg & BONITO_PCIMAP_PCIMAP_LO1) >>
		      BONITO_PCIMAP_PCIMAP_LO1_SHIFT),
		    BONITO_PCIMAP_WINSIZE, EX_NOWAIT) != 0)
			errors++;
		if (extent_free(ex,
		    BONITO_PCIMAP_WINBASE((reg & BONITO_PCIMAP_PCIMAP_LO2) >>
		      BONITO_PCIMAP_PCIMAP_LO2_SHIFT),
		    BONITO_PCIMAP_WINSIZE, EX_NOWAIT) != 0)
			errors++;

		if (sc->sc_compatible) {
			/* XXX make PCIMAP_HI available if PCIMAP_2 set */
		}
	}

	if (errors != 0) {
		extent_destroy(ex);
		ex = NULL;
	}

#ifdef BONITO_DEBUG
	extent_print(ex);
#endif

out:
	if (exname != NULL)
		free(exname, M_DEVBUF, 0);

	return ex;
}

/*
 * Functions used during early system configuration (before bonito attaches).
 */

pcitag_t bonito_make_tag_early(int, int, int);
pcireg_t bonito_conf_read_early(pcitag_t, int);

pcitag_t
bonito_make_tag_early(int b, int d, int f)
{
	return bonito_make_tag(NULL, b, d, f);
}

pcireg_t
bonito_conf_read_early(pcitag_t tag, int reg)
{
	return bonito_conf_read_internal(sys_platform->bonito_config, tag, reg);
}

void
bonito_early_setup()
{
	pci_make_tag_early = bonito_make_tag_early;
	pci_conf_read_early = bonito_conf_read_early;

	early_mem_t = &bonito_pci_mem_space_tag;
	early_io_t = &bonito_pci_io_space_tag;
}


code:
/*	$OpenBSD: bonito_irq.h,v 1.2 2010/05/08 21:59:56 miod Exp $	*/

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

/*
 * Bonito interrupt assignments
 */

/*
 * Loongson 2F assignments
 */

#define	LOONGSON_INTR_GPIO0		0
#define	LOONGSON_INTR_GPIO1		1
#define	LOONGSON_INTR_GPIO2		2
#define	LOONGSON_INTR_GPIO3		3

/* pci interrupts */
#define	LOONGSON_INTR_PCIA		4
#define	LOONGSON_INTR_PCIB		5
#define	LOONGSON_INTR_PCIC		6
#define	LOONGSON_INTR_PCID		7

#define	LOONGSON_INTR_PCI_PARERR	8
#define	LOONGSON_INTR_PCI_SYSERR	9
#define	LOONGSON_INTR_DRAM_PARERR	10

/* non-PCI interrupts */
#define	LOONGSON_INTR_INT0		11
#define	LOONGSON_INTR_INT1		12
#define	LOONGSON_INTR_INT2		13
#define	LOONGSON_INTR_INT3		14

#define	LOONGSON_INTRMASK_GPIO0		0x00000001	/* can't interrupt */
#define	LOONGSON_INTRMASK_GPIO1		0x00000002
#define	LOONGSON_INTRMASK_GPIO2		0x00000004
#define	LOONGSON_INTRMASK_GPIO3		0x00000008

#define	LOONGSON_INTRMASK_GPIO		0x0000000f

/* pci interrupts */
#define	LOONGSON_INTRMASK_PCIA		0x00000010
#define	LOONGSON_INTRMASK_PCIB		0x00000020
#define	LOONGSON_INTRMASK_PCIC		0x00000040
#define	LOONGSON_INTRMASK_PCID		0x00000080

#define	LOONGSON_INTRMASK_PCI_PARERR	0x00000100
#define	LOONGSON_INTRMASK_PCI_SYSERR	0x00000200
#define	LOONGSON_INTRMASK_DRAM_PARERR	0x00000400

/* non-PCI interrupts */
#define	LOONGSON_INTRMASK_INT0		0x00000800
#define	LOONGSON_INTRMASK_INT1		0x00001000
#define	LOONGSON_INTRMASK_INT2		0x00002000
#define	LOONGSON_INTRMASK_INT3		0x00004000

#define	LOONGSON_INTRMASK_LVL0		0x00007800 /* not maskable in bonito */
#define	LOONGSON_INTRMASK_LVL4		0x000007ff

/*
 * Loongson 2E (Bonito64) assignments
 */

#define	BONITO_INTRMASK_MBOX		0x0000000f
#define	BONITO_INTR_MBOX		0
#define	BONITO_INTRMASK_DMARDY		0x00000010
#define	BONITO_INTRMASK_DMAEMPTY	0x00000020
#define	BONITO_INTRMASK_COPYRDY		0x00000040
#define	BONITO_INTRMASK_COPYEMPTY	0x00000080
#define	BONITO_INTRMASK_COPYERR		0x00000100
#define	BONITO_INTRMASK_PCIIRQ		0x00000200
#define	BONITO_INTRMASK_MASTERERR	0x00000400
#define	BONITO_INTRMASK_SYSTEMERR	0x00000800
#define	BONITO_INTRMASK_DRAMPERR	0x00001000
#define	BONITO_INTRMASK_RETRYERR	0x00002000
#define	BONITO_INTRMASK_GPIO		0x01ff0000
#define	BONITO_INTR_GPIO		16
#define	BONITO_INTRMASK_GPIN		0x7e000000
#define	BONITO_INTR_GPIN		25

/*
 * Bonito interrupt handling recipes:
 * - we have up to 32 interrupts at the Bonito level.
 * - systems with ISA devices also have 16 (well, 15) ISA interrupts with the
 *   usual 8259 pair. Bonito and ISA interrupts happen on two different levels.
 *
 * These arbitrary values may be changed as long as interrupt mask variables
 * use large enough integer types and always use the following macros to
 * handle interrupt masks.
 */

#define	INTPRI_BONITO		(INTPRI_CLOCK + 1)
#define	INTPRI_ISA		(INTPRI_BONITO + 1)

#define	BONITO_NDIRECT		32
#define	BONITO_NISA		16
#define	BONITO_NINTS		(BONITO_NDIRECT + BONITO_NISA)
#define	BONITO_ISA_IRQ(i)	((i) + BONITO_NDIRECT)
#define	BONITO_DIRECT_IRQ(i)	(i)
#define	BONITO_IRQ_IS_ISA(i)	((i) >= BONITO_NDIRECT)
#define	BONITO_IRQ_TO_ISA(i)	((i) - BONITO_NDIRECT)

#define	BONITO_DIRECT_MASK(imask)	((imask) & ((1L << BONITO_NDIRECT) - 1))
#define	BONITO_ISA_MASK(imask)		((imask) >> BONITO_NDIRECT)

extern struct intrhand *bonito_intrhand[BONITO_NINTS];
extern uint64_t bonito_intem;
extern uint64_t bonito_imask[NIPLS];