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

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

#ifndef _MACHINE_INTR_H_
#define _MACHINE_INTR_H_

/*
 * The interrupt level ipl is a logical level; per-platform interrupt
 * code will turn it into the appropriate hardware interrupt masks
 * values.
 *
 * Interrupt sources on the CPU are kept enabled regardless of the
 * current ipl value; individual hardware sources interrupting while
 * logically masked are masked on the fly, remembered as pending, and
 * unmasked at the first splx() opportunity.
 *
 * An exception to this rule is the clock interrupt. Clock interrupts
 * are always allowed to happen, but will (of course!) not be serviced
 * if logically masked.  The reason for this is that clocks usually sit on
 * INT5 and cannot be easily masked if external hardware masking is used.
 */

/* Interrupt priority `levels'; not mutually exclusive. */
#define	IPL_NONE	0	/* nothing */
#define	IPL_SOFTINT	1	/* soft interrupts */
#define	IPL_BIO		2	/* block I/O */
#define IPL_AUDIO	IPL_BIO
#define	IPL_NET		3	/* network */
#define	IPL_TTY		4	/* terminal */
#define	IPL_VM		5	/* memory allocation */
#define	IPL_CLOCK	6	/* clock */
#define	IPL_STATCLOCK	IPL_CLOCK
#define	IPL_SCHED	7	/* everything */
#define	IPL_HIGH	7	/* everything */
#define	NIPLS		8	/* Number of levels */

#define IPL_MPFLOOR	IPL_TTY

/* Interrupt priority 'flags'. */
#define	IPL_MPSAFE	0	/* no "mpsafe" interrupts */

/* Interrupt sharing types. */
#define	IST_NONE	0	/* none */
#define	IST_PULSE	1	/* pulsed */
#define	IST_EDGE	2	/* edge-triggered */
#define	IST_LEVEL	3	/* level-triggered */

#define	SINTBIT(q)	(q)
#define	SINTMASK(q)	(1 << SINTBIT(q))

/* Soft interrupt masks. */

#define	IPL_SOFT	0
#define	IPL_SOFTCLOCK	1
#define	IPL_SOFTNET	2
#define	IPL_SOFTTTY	3

#define	SI_SOFT		0	/* for IPL_SOFT */
#define	SI_SOFTCLOCK	1	/* for IPL_SOFTCLOCK */
#define	SI_SOFTNET	2	/* for IPL_SOFTNET */
#define	SI_SOFTTTY	3	/* for IPL_SOFTTTY */

#define	SI_NQUEUES	4

#ifndef _LOCORE

#include <machine/mutex.h>
#include <sys/queue.h>

struct soft_intrhand {
	TAILQ_ENTRY(soft_intrhand) sih_list;
	void	(*sih_func)(void *);
	void	*sih_arg;
	struct soft_intrq *sih_siq;
	int	sih_pending;
};

struct soft_intrq {
	TAILQ_HEAD(, soft_intrhand) siq_list;
	int siq_si;
	struct mutex siq_mtx;
};

void	 softintr_disestablish(void *);
void	 softintr_dispatch(int);
void	*softintr_establish(int, void (*)(void *), void *);
void	 softintr_init(void);
void	 softintr_schedule(void *);

#define	splsoft()	splraise(IPL_SOFTINT)
#define splbio()	splraise(IPL_BIO)
#define splnet()	splraise(IPL_NET)
#define spltty()	splraise(IPL_TTY)
#define splaudio()	splraise(IPL_AUDIO)
#define splclock()	splraise(IPL_CLOCK)
#define splvm()		splraise(IPL_VM)
#define splhigh()	splraise(IPL_HIGH)

#define splsoftclock()	splsoft()
#define splsoftnet()	splsoft()
#define splstatclock()	splhigh()

#define splsched()	splhigh()
#define spllock()	splhigh()
#define spl0()		spllower(0)

void	splinit(void);

#define	splassert(X)
#define	splsoftassert(X)

/* Inlines */
static __inline void register_splx_handler(void (*)(int));

typedef void (int_f)(int);
extern int_f *splx_hand;

static __inline void
register_splx_handler(void(*handler)(int))
{
	splx_hand = handler;
}

int	splraise(int);
void	splx(int);
int	spllower(int);

/*
 * Interrupt control struct used by interrupt dispatchers
 * to hold interrupt handler info.
 */

#include <sys/evcount.h>

struct intrhand {
	struct	intrhand	*ih_next;
	int			(*ih_fun)(void *);
	void			*ih_arg;
	int			 ih_level;
	int			 ih_irq;
	struct evcount		 ih_count;
};

/*
 * Low level interrupt dispatcher registration data.
 */

/* Schedule priorities for base interrupts (CPU) */
#define	INTPRI_CLOCK	0
/* other values are system-specific */

#define NLOWINT	4		/* Number of low level registrations possible */

extern uint32_t idle_mask;

struct trap_frame;
void	set_intr(int, uint32_t, uint32_t(*)(uint32_t, struct trap_frame *));

uint32_t updateimask(uint32_t);
void	dosoftint(void);

#endif /* _LOCORE */

#endif /* _MACHINE_INTR_H_ */


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

/*
 * Copyright (c) 2007 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, this permission notice, and the disclaimer below
 * appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef	_MACHINE_ISA_MACHDEP_H_
#define	_MACHINE_ISA_MACHDEP_H_

#include <machine/bus.h>

#define	__NO_ISA_INTR_CHECK

typedef	struct mips_isa_chipset *isa_chipset_tag_t;

struct mips_isa_chipset {
	void	*ic_v;

	void	(*ic_attach_hook)(struct device *, struct device *,
		    struct isabus_attach_args *);
	void	*(*ic_intr_establish)(void *, int, int, int, int (*)(void *),
		    void *, char *);
	void	(*ic_intr_disestablish)(void *, void *);
};

#define	isa_attach_hook(p, s, iba)					\
    (*(iba)->iba_ic->ic_attach_hook)((p), (s), (iba))
#define	isa_intr_establish(c, i, t, l, f, a, n)				\
    (*(c)->ic_intr_establish)((c)->ic_v, (i), (t), (l), (f), (a), (n))
#define	isa_intr_disestablish(c, h)					\
    (*(c)->ic_intr_disestablish)((c)->ic_v, (h))

void	loongson_generic_isa_attach_hook(struct device *, struct device *,
	    struct isabus_attach_args *);
void	loongson_isa_specific_eoi(int);
void	loongson_set_isa_imr(uint);

#endif

license: unknown


code:
/* $OpenBSD: kcore.h,v 1.1.1.1 2009/07/31 09:26:25 miod Exp $ */
/* public domain */
#include <mips64/kcore.h>


code:
/* $OpenBSD: limits.h,v 1.1.1.1 2009/07/31 09:26:25 miod Exp $ */
/* public domain */
#include <mips64/limits.h>


code:
/*	$OpenBSD: loadfile_machdep.h,v 1.2 2015/07/17 20:44:39 miod Exp $ */
/*	$NetBSD: loadfile_machdep.h,v 1.2 2001/10/31 17:20:49 thorpej Exp $	 */

/*-
 * Copyright (c) 1999 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Christos Zoulas.
 *
 * 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.
 */

#define BOOT_ELF
#define ELFSIZE	64

#define LOAD_KERNEL		LOAD_ALL
#define COUNT_KERNEL		COUNT_ALL

#define LOADADDR(a)		(((u_long)(a)) + offset)
#define ALIGNENTRY(a)		((u_long)(a))
#define READ(f, b, c)		read((f), (void *)LOADADDR(b), (c))
#define BCOPY(s, d, c)		memcpy((void *)LOADADDR(d), (void *)(s), (c))
#define BZERO(d, c)		memset((void *)LOADADDR(d), 0, (c))
#define	WARN(a)			(void)(printf a, \
				    printf((errno ? ": %s\n" : "\n"), \
				    strerror(errno)))
#define PROGRESS(a)		(void) printf a
#define ALLOC(a)		alloc(a)
#define FREE(a, b)		free(a, b)


code:
/* $OpenBSD: lock.h,v 1.1.1.1 2009/07/31 09:26:25 miod Exp $ */
/* public domain */
#include <mips64/lock.h>


code:
/* $OpenBSD: loongson2.h,v 1.1.1.1 2009/08/06 20:51:44 miod Exp $ */
/* public domain */
#include <mips64/loongson2.h>


code:
/* $OpenBSD: memconf.h,v 1.1.1.1 2009/07/31 09:26:25 miod Exp $ */
/* public domain */
#include <mips64/memconf.h>


code:
/* $OpenBSD: mips_opcode.h,v 1.1.1.1 2009/07/31 09:26:25 miod Exp $ */
/* public domain */
#include <mips64/mips_opcode.h>


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

#include <mips64/mutex.h>


code:
/*	$OpenBSD: param.h,v 1.3 2013/03/23 16:12:23 deraadt Exp $ */

/* Public Domain */

#ifndef	_MACHINE_PARAM_H_
#define	_MACHINE_PARAM_H_

#define	MACHINE		"loongson"
#define	_MACHINE	loongson
#define	MACHINE_ARCH	"mips64el"	/* not the canonical endianness */
#define	_MACHINE_ARCH	mips64el
#define	MACHINE_CPU	"mips64"
#define	_MACHINE_CPU	mips64
#define	MID_MACHINE	MID_MIPS64

#ifdef _KERNEL

/*
 * The Loongson level 1 cache expects software to prevent virtual
 * aliases. Unfortunately, since this cache is physically tagged,
 * this would require all virtual address to have the same bits 14
 * and 13 as their physical addresses, which is not something the
 * kernel can guarantee unless the page size is at least 16KB.
 */
#define	PAGE_SHIFT	14

#endif /* _KERNEL */

#include <mips64/param.h>

#endif /* _MACHINE_PARAM_H_ */


code:
/* $OpenBSD: pcb.h,v 1.1.1.1 2009/07/31 09:26:25 miod Exp $ */
/* public domain */
#include <mips64/pcb.h>


code:
/*	$OpenBSD: pci_machdep.h,v 1.9 2014/03/27 22:16:03 miod Exp $ */

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

typedef struct mips_pci_chipset *pci_chipset_tag_t;
typedef u_long pcitag_t;
typedef u_long pci_intr_handle_t;

struct pci_attach_args;

/*
 * mips-specific PCI structure and type definitions.
 * NOT TO BE USED DIRECTLY BY MACHINE INDEPENDENT CODE.
 */
struct mips_pci_chipset {
    void	*pc_conf_v;
    void	(*pc_attach_hook)(struct device *,
		    struct device *, struct pcibus_attach_args *);
    int		(*pc_bus_maxdevs)(void *, int);
    pcitag_t	(*pc_make_tag)(void *, int, int, int);
    void	(*pc_decompose_tag)(void *, pcitag_t, int *,
		    int *, int *);
    int		(*pc_conf_size)(void *, pcitag_t);
    pcireg_t	(*pc_conf_read)(void *, pcitag_t, int);
    void	(*pc_conf_write)(void *, pcitag_t, int, pcireg_t);

    void	*pc_intr_v;
    int		(*pc_intr_map)(struct pci_attach_args *, pci_intr_handle_t *);
    const char	*(*pc_intr_string)(void *, pci_intr_handle_t);
    void	*(*pc_intr_establish)(void *, pci_intr_handle_t,
		    int, int (*)(void *), void *, char *);
    void	(*pc_intr_disestablish)(void *, void *);
};

/*
 * Functions provided to machine-independent PCI code.
 */
#define	pci_attach_hook(p, s, pba)					\
    (*(pba)->pba_pc->pc_attach_hook)((p), (s), (pba))
#define	pci_bus_maxdevs(c, b)						\
    (*(c)->pc_bus_maxdevs)((c)->pc_conf_v, (b))
#define	pci_make_tag(c, b, d, f)					\
    (*(c)->pc_make_tag)((c)->pc_conf_v, (b), (d), (f))
#define	pci_decompose_tag(c, t, bp, dp, fp)				\
    (*(c)->pc_decompose_tag)((c)->pc_conf_v, (t), (bp), (dp), (fp))
#define	pci_conf_size(c, t)						\
    (*(c)->pc_conf_size)((c)->pc_conf_v, (t))
#define	pci_conf_read(c, t, r)						\
    (*(c)->pc_conf_read)((c)->pc_conf_v, (t), (r))
#define	pci_conf_write(c, t, r, v)					\
    (*(c)->pc_conf_write)((c)->pc_conf_v, (t), (r), (v))
#define	pci_intr_map(c, ihp)				\
    (*(c)->pa_pc->pc_intr_map)((c), (ihp))
#define	pci_intr_map_msi(c, ihp)	(-1)
#define	pci_intr_string(c, ih)						\
    (*(c)->pc_intr_string)((c)->pc_intr_v, (ih))
#define	pci_intr_establish(c, ih, l, h, a, nm)				\
    (*(c)->pc_intr_establish)((c)->pc_intr_v, (ih), (l), (h), (a), (nm))
#define	pci_intr_disestablish(c, iv)					\
    (*(c)->pc_intr_disestablish)((c)->pc_intr_v, (iv))
#define	pci_probe_device_hook(c, a)	(0)

#define	pci_min_powerstate(c, t)	(PCI_PMCSR_STATE_D3)
#define	pci_set_powerstate_md(c, t, s, p)

/* PCI view of CPU memory */
extern paddr_t loongson_dma_base;

/*
 * Functions used during early system configuration.
 */

extern pcitag_t (*pci_make_tag_early)(int, int, int);
extern pcireg_t (*pci_conf_read_early)(pcitag_t, int);

#define	pci_dev_postattach(a, b)


code:
/* $OpenBSD: pmap.h,v 1.1.1.1 2009/07/31 09:26:26 miod Exp $ */
/* public domain */
#include <mips64/pmap.h>


code:
/*	$OpenBSD: pmon.h,v 1.3 2014/03/29 23:59:49 miod Exp $	*/

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

#ifndef	_MACHINE_PMON_H_
#define	_MACHINE_PMON_H_

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

/*
 * PMON2000 callvec definitions
 */

/* 32-bit compatible types */
typedef	uint32_t	pmon_size_t;
typedef	int32_t		pmon_ssize_t;
typedef int64_t		pmon_off_t;

int		pmon_open(const char *, int, ...);
int		pmon_close(int);
int		pmon_read(int, void *, pmon_size_t);
pmon_ssize_t	pmon_write(int, const void *, pmon_size_t);
pmon_off_t	pmon_lseek(int, pmon_off_t, int);
int		pmon_printf(const char *, ...);
void		pmon_cacheflush(void);
char *		pmon_gets(char *);

#define	PMON_MAXLN	256	/* internal gets() size limit */

extern int32_t pmon_callvec;

const char	*pmon_getarg(const int);
void		 pmon_init(int32_t, int32_t, int32_t, int32_t, uint32_t);

#define	PMON_ENVTYPE_ENVP	0
#define	PMON_ENVTYPE_EFI	1
int		 pmon_getenvtype(void);

/*
 * The new environment interface is a /salmigondis/ of badly thought-out
 * structs put together, pretending to be inspired by EFI but conveniently
 * omitting key EFI structs because they are deemed non-applicable to
 * MIPS systems.
 * Of course, some fields are absolute addresses, while others are relative
 * pointers, to add to the confusion.
 */

struct pmon_env_reset {
	void			(*cold_boot)(void);	/* not filled */
	void			(*warm_boot)(void);
	void			(*boot)(unsigned int);	/* not filled */
	void			(*poweroff)(void);
};

/* all values are offsets relative to the beginning of the struct */
struct pmon_env_ptr {
	uint64_t		offs_mem;
	uint64_t		offs_cpu;
	uint64_t		offs_sys;
	uint64_t		offs_irq;
	uint64_t		offs_iface;
	uint64_t		offs_special;
	uint64_t		offs_device;
};

struct pmon_env_smbios {
	uint16_t		version;
	uint64_t		vga_bios;
	struct pmon_env_ptr	ptrs;
};

struct pmon_env_efi {
	uint64_t		mps;		/* not filled */
	uint64_t		acpi;		/* not filled */
	uint64_t		acpi20;		/* not filled */
	struct pmon_env_smbios	bios;
	uint64_t		sal_systab;	/* not filled */
	uint64_t		bootinfo;	/* not filled */
};

struct pmon_env {
	struct pmon_env_efi	efi;
	struct pmon_env_reset	reset;
};

#define	PMON_MEM_MAX	128
struct pmon_env_mem_entry {
	uint32_t		node;
	uint32_t		type;
#define	PMON_MEM_SYSTEM_LOW	1	/* physical memory <= 256 MB */
#define	PMON_MEM_SYSTEM_HIGH	2	/* physical memory > 256 MB */
#define	PMON_MEM_RESERVED	3
#define	PMON_MEM_PCI_IO		4
#define	PMON_MEM_PCI_MEM	5
#define	PMON_MEM_CPU_REGISTERS	6
#define	PMON_MEM_VIDEO_ROM	7
#define	PMON_MEM_OTHER_ROM	8
#define	PMON_MEM_ACPI_TABLE	9
	uint64_t		address;
	uint32_t		size;
};
struct pmon_env_mem {
	uint16_t		version;	/* not filled */
	uint32_t		nentries;
	uint32_t		mem_freq;
	struct pmon_env_mem_entry mem_map[PMON_MEM_MAX];
} __packed;

struct pmon_env_cpu {
	uint16_t		version;	/* not filled */
	uint32_t		prid;		/* cop0 PrID */
	uint32_t		cputype;
/* 0 and 1 are supposedly intended for 2E and 2F, which do NOT provide this
   interface; moreover Linux and PMON disagree on the values and have 2E and
   2F swapped. */
#define	PMON_CPUTYPE_LS3A	2
#define	PMON_CPUTYPE_LS3B	3
#define	PMON_CPUTYPE_LS1A	4
#define	PMON_CPUTYPE_LS1B	5
	uint32_t		node;		/* total number of NUMA nodes */
	uint32_t		coreid;		/* boot CPU core id */
	uint32_t		speed;
	uint32_t		ncpus;
} __packed;

struct pmon_env_sys {
	uint16_t		version;	/* not filled */
	uint32_t		ccnuma_smp;
	uint32_t		double_channel;
} __packed;

struct pmon_env_irq {
	uint16_t		version;	/* not filled */
	uint16_t		size;		/* not filled */
	uint16_t		rtr_bus;	/* not filled */
	uint16_t		rtr_devfn;	/* not filled */
	uint32_t		vendor;		/* not filled */
	uint32_t		device;		/* not filled */
	uint32_t		pic_type;
#define	PMON_IRQ_PIC_HT		0
#define	PMON_IRQ_PIC_I8259	1
	uint64_t		ht_interrupt_bit;
	uint64_t		ht_enable;
	uint32_t		node;
	uint64_t		pci_memory_space_start;
	uint64_t		pci_memory_space_end;
	uint64_t		pci_io_space_start;	/* not filled */
	uint64_t		pci_io_space_end;	/* not filled */
	uint64_t		pci_cfg_space;	/* not filled */
} __packed;

struct pmon_env_iface {
	uint16_t		version;
#define	PMON_IFACE_VERSION	0x0001
	uint16_t		size;
	uint8_t			flag;
	char			description[64];	/* firmware version */
} __packed;

#define PMON_RESOURCE_MAX 128
struct pmon_env_resource {
	uint64_t		start;
	uint64_t		end;
	char			name[64];
	uint32_t		flags;
};
struct pmon_env_special {
	uint16_t		version;
	char			name[64];
	uint32_t		type;
	struct pmon_env_resource resource[PMON_RESOURCE_MAX];
};

struct pmon_env_device {
	char			name[64];	/* system description */
	uint32_t		nentries;
	struct pmon_env_resource resource[PMON_RESOURCE_MAX];
};

const char	*pmon_getenv(const char *);

const struct pmon_env_reset *pmon_get_env_reset(void);
const struct pmon_env_mem *pmon_get_env_mem(void);
const struct pmon_env_cpu *pmon_get_env_cpu(void);
const struct pmon_env_sys *pmon_get_env_sys(void);
const struct pmon_env_irq *pmon_get_env_irq(void);
const struct pmon_env_iface *pmon_get_env_iface(void);
const struct pmon_env_special *pmon_get_env_special(void);
const struct pmon_env_device *pmon_get_env_device(void);

#endif	/* _KERNEL || _STANDALONE */

#endif	/* _MACHINE_PMON_H_ */


code:
/* $OpenBSD: proc.h,v 1.1.1.1 2009/07/31 09:26:26 miod Exp $ */
/* public domain */
#include <mips64/proc.h>


code:
/* $OpenBSD: profile.h,v 1.1.1.1 2009/07/31 09:26:26 miod Exp $ */
/* public domain */
#include <mips64/profile.h>


code:
/* $OpenBSD: pte.h,v 1.1.1.1 2009/07/31 09:26:26 miod Exp $ */
/* public domain */
#include <mips64/pte.h>


code:
/* $OpenBSD: ptrace.h,v 1.1.1.1 2009/07/31 09:26:26 miod Exp $ */
/* public domain */
#include <mips64/ptrace.h>


code:
/* $OpenBSD: reg.h,v 1.1.1.1 2009/07/31 09:26:26 miod Exp $ */
/* public domain */
#include <mips64/reg.h>


code:
/* $OpenBSD: regdef.h,v 1.1.1.1 2009/07/31 09:26:26 miod Exp $ */
/* public domain */
#include <mips64/regdef.h>


code:
/* $OpenBSD: regnum.h,v 1.1.1.1 2009/07/31 09:26:26 miod Exp $ */
/* public domain */
#include <mips64/regnum.h>


code:
/* $OpenBSD: setjmp.h,v 1.1.1.1 2009/07/31 09:26:26 miod Exp $ */
/* public domain */
#include <mips64/setjmp.h>


code:
/* $OpenBSD: signal.h,v 1.1.1.1 2009/07/31 09:26:26 miod Exp $ */
/* public domain */
#include <mips64/signal.h>


code:
/* $OpenBSD: spinlock.h,v 1.1.1.1 2009/07/31 09:26:26 miod Exp $ */
/* public domain */
#include <mips64/spinlock.h>


code:
/* $OpenBSD: stdarg.h,v 1.1.1.1 2009/07/31 09:26:26 miod Exp $ */
/* public domain */
#include <mips64/stdarg.h>


code:
/*	$OpenBSD: sysarch.h,v 1.1.1.1 2009/11/22 18:12:44 miod Exp $	*/
/* public domain */
#include <mips64/sysarch.h>


code:
/*	$OpenBSD: tcb.h,v 1.2 2013/06/01 21:20:54 jasper Exp $	*/
/* public domain */
#include <mips64/tcb.h>


code:
/* $OpenBSD: trap.h,v 1.1.1.1 2009/07/31 09:26:26 miod Exp $ */
/* public domain */
#include <mips64/trap.h>


code:
/* $OpenBSD: varargs.h,v 1.1.1.1 2009/07/31 09:26:26 miod Exp $ */
/* public domain */
#include <mips64/varargs.h>


code:
/*	$OpenBSD: vmparam.h,v 1.4 2014/03/27 21:58:13 miod Exp $ */
/* public domain */
#ifndef _MACHINE_VMPARAM_H_
#define _MACHINE_VMPARAM_H_

#define	VM_PHYSSEG_MAX		3 /* Max number of physical memory segments */
#define	VM_PHYSSEG_STRAT	VM_PSTRAT_BIGFIRST

#include <mips64/vmparam.h>

#endif	/* _MACHINE_VMPARAM_H_ */


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


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


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

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

#include <machine/autoconf.h>

extern void dumpconf(void);
void	parsepmonbp(void);

int	cold = 1;
struct device *bootdv = NULL;
char    bootdev[16];
enum devclass bootdev_class = DV_DULL;

extern char pmon_bootp[];

void
cpu_configure(void)
{
	(void)splhigh();

	softintr_init();
	(void)config_rootfound("mainbus", NULL);

	splinit();
	cold = 0;
}

void
parsepmonbp(void)
{
	char *p, *q;
	size_t len;

	if (strncmp(pmon_bootp, "tftp://", 7) == 0) {
		bootdev_class = DV_IFNET;
		strlcpy(bootdev, "netboot", sizeof bootdev);
		return;
	}
	strlcpy(bootdev, "unknown", sizeof bootdev);

	if (strncmp(pmon_bootp, "/dev/disk/", 10) == 0) {
		/* kernel loaded by our boot blocks */
		p = pmon_bootp + 10;
		len = strlen(p);
	} else {
		/* kernel loaded by PMON */
		p = strchr(pmon_bootp, '@');
		if (p == NULL)
			return;
		p++;

		q = strchr(p, '/');
		if (q == NULL)
			return;
		len = q - p;
	}

	if (len <= 2 || len >= sizeof bootdev - 1)
		return;
	memcpy(bootdev, p, len);
	bootdev[len] = '\0';
	bootdev_class = DV_DISK;
}

void
diskconf(void)
{
	if (*pmon_bootp != '\0')
		printf("pmon bootpath: %s\n", pmon_bootp);

	if (bootdv != NULL)
		printf("boot device: %s\n", bootdv->dv_xname);

	setroot(bootdv, 0, RB_USERREQ);
	dumpconf();

#ifdef HIBERNATE
	hibernate_resume();
#endif /* HIBERNATE */
}

void
device_register(struct device *dev, void *aux)
{
	if (bootdv != NULL)
		return;

	(*sys_platform->device_register)(dev, aux);
}

struct nam2blk nam2blk[] = {
	{ "sd",		0 },
	{ "cd",		3 },
	{ "wd",		4 },
	{ "rd",		8 },
	{ "vnd",	2 },
	{ NULL,		-1 }
};


code:
/*	$OpenBSD: bus_dma.c,v 1.18 2014/11/16 12:30:57 deraadt Exp $ */

/*
 * Copyright (c) 2003-2004 Opsycon AB  (www.opsycon.se / www.opsycon.com)
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */
/*-
 * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
 * NASA Ames Research Center.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>

#include <uvm/uvm_extern.h>

#include <mips64/cache.h>
#include <machine/cpu.h>
#include <machine/autoconf.h>

#include <machine/bus.h>

/*
 * Common function for DMA map creation.  May be called by bus-specific
 * DMA map creation functions.
 */
int
_dmamap_create(bus_dma_tag_t t, bus_size_t size, int nsegments,
    bus_size_t maxsegsz, bus_size_t boundary, int flags, bus_dmamap_t *dmamp)
{
	struct machine_bus_dmamap *map;
	void *mapstore;
	size_t mapsize;

	/*
	 * Allocate and initialize the DMA map.  The end of the map
	 * is a variable-sized array of segments, so we allocate enough
	 * room for them in one shot.
	 *
	 * Note we don't preserve the WAITOK or NOWAIT flags.  Preservation
	 * of ALLOCNOW notifies others that we've reserved these resources,
	 * and they are not to be freed.
	 *
	 * The bus_dmamap_t includes one bus_dma_segment_t, hence
	 * the (nsegments - 1).
	 */
	mapsize = sizeof(struct machine_bus_dmamap) +
	    (sizeof(bus_dma_segment_t) * (nsegments - 1));
	if ((mapstore = malloc(mapsize, M_DEVBUF, (flags & BUS_DMA_NOWAIT) ?
	    (M_NOWAIT | M_ZERO) : (M_WAITOK | M_ZERO))) == NULL)
		return (ENOMEM);

	map = (struct machine_bus_dmamap *)mapstore;
	map->_dm_size = size;
	map->_dm_segcnt = nsegments;
	map->_dm_maxsegsz = maxsegsz;
	map->_dm_boundary = boundary;
	map->_dm_flags = flags & ~(BUS_DMA_WAITOK|BUS_DMA_NOWAIT);

	*dmamp = map;
	return (0);
}

/*
 * Common function for DMA map destruction.  May be called by bus-specific
 * DMA map destruction functions.
 */
void
_dmamap_destroy(bus_dma_tag_t t, bus_dmamap_t map)
{
	free(map, M_DEVBUF, 0);
}

/*
 * Common function for loading a DMA map with a linear buffer.  May
 * be called by bus-specific DMA map load functions.
 */
int
_dmamap_load(bus_dma_tag_t t, bus_dmamap_t map, void *buf, bus_size_t buflen,
    struct proc *p, int flags)
{
	paddr_t lastaddr;
	int seg, error;

	/*
	 * Make sure that on error condition we return "no valid mappings".
	 */
	map->dm_nsegs = 0;
	map->dm_mapsize = 0;

	if (buflen > map->_dm_size)
		return (EINVAL);

	seg = 0;
	error = (*t->_dmamap_load_buffer)(t, map, buf, buflen, p, flags,
	    &lastaddr, &seg, 1);
	if (error == 0) {
		map->dm_nsegs = seg + 1;
		map->dm_mapsize = buflen;
	}

	return (error);
}

/*
 * Like _bus_dmamap_load(), but for mbufs.
 */
int
_dmamap_load_mbuf(bus_dma_tag_t t, bus_dmamap_t map, struct mbuf *m0, int flags)
{
	paddr_t lastaddr;
	int seg, error, first;
	struct mbuf *m;

	/*
	 * Make sure that on error condition we return "no valid mappings".
	 */
	map->dm_nsegs = 0;
	map->dm_mapsize = 0;

#ifdef DIAGNOSTIC
	if ((m0->m_flags & M_PKTHDR) == 0)
		panic("_dmamap_load_mbuf: no packet header");
#endif

	if (m0->m_pkthdr.len > map->_dm_size)
		return (EINVAL);

	first = 1;
	seg = 0;
	error = 0;
	for (m = m0; m != NULL && error == 0; m = m->m_next) {
		if (m->m_len == 0)
			continue;
		error = (*t->_dmamap_load_buffer)(t, map, m->m_data, m->m_len,
		    NULL, flags, &lastaddr, &seg, first);
		first = 0;
	}
	if (error == 0) {
		map->dm_nsegs = seg + 1;
		map->dm_mapsize = m0->m_pkthdr.len;
	}

	return (error);
}

/*
 * Like _dmamap_load(), but for uios.
 */
int
_dmamap_load_uio(bus_dma_tag_t t, bus_dmamap_t map, struct uio *uio, int flags)
{
	paddr_t lastaddr;
	int seg, i, error, first;
	bus_size_t minlen, resid;
	struct proc *p = NULL;
	struct iovec *iov;
	void *addr;

	/*
	 * Make sure that on error condition we return "no valid mappings".
	 */
	map->dm_nsegs = 0;
	map->dm_mapsize = 0;

	resid = uio->uio_resid;
	iov = uio->uio_iov;

	if (uio->uio_segflg == UIO_USERSPACE) {
		p = uio->uio_procp;
#ifdef DIAGNOSTIC
		if (p == NULL)
			panic("_dmamap_load_uio: USERSPACE but no proc");
#endif
	}

	first = 1;
	seg = 0;
	error = 0;
	for (i = 0; i < uio->uio_iovcnt && resid != 0 && error == 0; i++) {
		/*
		 * Now at the first iovec to load.  Load each iovec
		 * until we have exhausted the residual count.
		 */
		minlen = resid < iov[i].iov_len ? resid : iov[i].iov_len;
		addr = (void *)iov[i].iov_base;

		error = (*t->_dmamap_load_buffer)(t, map, addr, minlen,
		    p, flags, &lastaddr, &seg, first);
		first = 0;

		resid -= minlen;
	}
	if (error == 0) {
		map->dm_nsegs = seg + 1;
		map->dm_mapsize = uio->uio_resid;
	}

	return (error);
}

/*
 * Like _dmamap_load(), but for raw memory allocated with
 * bus_dmamem_alloc().
 */
int
_dmamap_load_raw(bus_dma_tag_t t, bus_dmamap_t map, bus_dma_segment_t *segs,
    int nsegs, bus_size_t size, int flags)
{
	if (nsegs > map->_dm_segcnt || size > map->_dm_size)
		return (EINVAL);

	/*
	 * Make sure we don't cross any boundaries.
	 */
	if (map->_dm_boundary) {
		bus_addr_t bmask = ~(map->_dm_boundary - 1);
		int i;

		if (t->_dma_mask != 0)
			bmask &= t->_dma_mask;
		for (i = 0; i < nsegs; i++) {
			if (segs[i].ds_len > map->_dm_maxsegsz)
				return (EINVAL);
			if ((segs[i].ds_addr & bmask) !=
			    ((segs[i].ds_addr + segs[i].ds_len - 1) & bmask))
				return (EINVAL);
		}
	}

	bcopy(segs, map->dm_segs, nsegs * sizeof(*segs));
	map->dm_nsegs = nsegs;
	map->dm_mapsize = size;
	return (0);
}

/*
 * Common function for unloading a DMA map.  May be called by
 * bus-specific DMA map unload functions.
 */
void
_dmamap_unload(bus_dma_tag_t t, bus_dmamap_t map)
{
	/*
	 * No resources to free; just mark the mappings as
	 * invalid.
	 */
	map->dm_nsegs = 0;
	map->dm_mapsize = 0;
}

/*
 * Common function for DMA map synchronization.  May be called
 * by bus-specific DMA map synchronization functions.
 */
void
_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t addr,
    bus_size_t size, int op)
{
	int nsegs;
	int curseg;
	int cacheop;
	struct cpu_info *ci = curcpu();

	nsegs = map->dm_nsegs;
	curseg = 0;

	while (size && nsegs) {
		vaddr_t vaddr;
		paddr_t paddr;
		bus_size_t ssize;

		ssize = map->dm_segs[curseg].ds_len;
		paddr = map->dm_segs[curseg]._ds_paddr;
		vaddr = map->dm_segs[curseg]._ds_vaddr;

		if (addr != 0) {
			if (addr >= ssize) {
				addr -= ssize;
				ssize = 0;
			} else {
				vaddr += addr;
				paddr += addr;
				ssize -= addr;
				addr = 0;
			}
		}
		if (ssize > size)
			ssize = size;

		if (IS_XKPHYS(vaddr) && XKPHYS_TO_CCA(vaddr) == CCA_NC) {
			size -= ssize;
			ssize = 0;
		}

		if (ssize != 0) {
			/*
			 * If only PREWRITE is requested, writeback.
			 * PREWRITE with PREREAD writebacks
			 * and invalidates (if noncoherent) *all* cache levels.
			 * Otherwise, just invalidate (if noncoherent).
			 */
			if (op & BUS_DMASYNC_PREWRITE) {
				if (op & BUS_DMASYNC_PREREAD)
					cacheop = CACHE_SYNC_X;
				else
					cacheop = CACHE_SYNC_W;
			} else {
				if (op & BUS_DMASYNC_PREREAD)
					cacheop = CACHE_SYNC_R;
				else if (op & BUS_DMASYNC_POSTREAD)
					cacheop = CACHE_SYNC_R;
				else
					cacheop = -1;
			}

			if (cacheop >= 0)
				Mips_IOSyncDCache(ci, vaddr, ssize, cacheop);
			size -= ssize;
		}
		curseg++;
		nsegs--;
	}

#ifdef DIAGNOSTIC
	if (size != 0) {
		panic("_dmamap_sync: ran off map!");
	}
#endif
}

/*
 * Common function for DMA-safe memory allocation.  May be called
 * by bus-specific DMA memory allocation functions.
 */
int
_dmamem_alloc(bus_dma_tag_t t, bus_size_t size, bus_size_t alignment,
    bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs,
    int flags)
{
	return _dmamem_alloc_range(t, size, alignment, boundary,
	    segs, nsegs, rsegs, flags, (paddr_t)0, (paddr_t)-1);
}

/*
 * Common function for freeing DMA-safe memory.  May be called by
 * bus-specific DMA memory free functions.
 */
void
_dmamem_free(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs)
{
	vm_page_t m;
	bus_addr_t addr;
	struct pglist mlist;
	int curseg;

	/*
	 * Build a list of pages to free back to the VM system.
	 */
	TAILQ_INIT(&mlist);
	for (curseg = 0; curseg < nsegs; curseg++) {
		for (addr = segs[curseg].ds_addr;
		    addr < (segs[curseg].ds_addr + segs[curseg].ds_len);
		    addr += PAGE_SIZE) {
			m = PHYS_TO_VM_PAGE((*t->_device_to_pa)(addr));
			TAILQ_INSERT_TAIL(&mlist, m, pageq);
		}
	}

	uvm_pglistfree(&mlist);
}

/*
 * Common function for mapping DMA-safe memory.  May be called by
 * bus-specific DMA memory map functions.
 */
int
_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs, size_t size,
    caddr_t *kvap, int flags)
{
	vaddr_t va, sva;
	size_t ssize;
	paddr_t pa;
	bus_addr_t addr;
	int curseg, error, pmap_flags;
	const struct kmem_dyn_mode *kd;

	if (nsegs == 1) {
		pa = (*t->_device_to_pa)(segs[0].ds_addr);
		if (flags & (BUS_DMA_COHERENT | BUS_DMA_NOCACHE))
			*kvap = (caddr_t)PHYS_TO_XKPHYS(pa, CCA_NC);
		else
			*kvap = (caddr_t)PHYS_TO_XKPHYS(pa, CCA_CACHED);
		return (0);
	}

	size = round_page(size);
	kd = flags & BUS_DMA_NOWAIT ? &kd_trylock : &kd_waitok;
	va = (vaddr_t)km_alloc(size, &kv_any, &kp_none, kd);
	if (va == 0)
		return (ENOMEM);

	*kvap = (caddr_t)va;

	sva = va;
	ssize = size;
	pmap_flags = PMAP_WIRED | PMAP_CANFAIL;
	if (flags & (BUS_DMA_COHERENT | BUS_DMA_NOCACHE))
		pmap_flags |= PMAP_NOCACHE;
	for (curseg = 0; curseg < nsegs; curseg++) {
		for (addr = segs[curseg].ds_addr;
		    addr < (segs[curseg].ds_addr + segs[curseg].ds_len);
		    addr += NBPG, va += NBPG, size -= NBPG) {
			if (size == 0)
				panic("_dmamem_map: size botch");
			pa = (*t->_device_to_pa)(addr);
			error = pmap_enter(pmap_kernel(), va, pa,
			    PROT_READ | PROT_WRITE,
			    PROT_READ | PROT_WRITE | pmap_flags);
			if (error) {
				pmap_update(pmap_kernel());
				km_free((void *)sva, ssize, &kv_any, &kp_none);
				return (error);
			}

			/*
			 * This is redundant with what pmap_enter() did
			 * above, but will take care of forcing other
			 * mappings of the same page (if any) to be
			 * uncached.
			 * If there are no multiple mappings of that
			 * page, this amounts to a noop.
			 */
			if (flags & (BUS_DMA_COHERENT | BUS_DMA_NOCACHE))
				pmap_page_cache(PHYS_TO_VM_PAGE(pa),
				    PGF_UNCACHED);
		}
		pmap_update(pmap_kernel());
	}

	return (0);
}

/*
 * Common function for unmapping DMA-safe memory.  May be called by
 * bus-specific DMA memory unmapping functions.
 */
void
_dmamem_unmap(bus_dma_tag_t t, caddr_t kva, size_t size)
{
	if (IS_XKPHYS((vaddr_t)kva))
		return;

	km_free(kva, round_page(size), &kv_any, &kp_none);
}

/*
 * Common function for mmap(2)'ing DMA-safe memory.  May be called by
 * bus-specific DMA mmap(2)'ing functions.
 */
paddr_t
_dmamem_mmap(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs, off_t off,
    int prot, int flags)
{
	int i;

	for (i = 0; i < nsegs; i++) {
#ifdef DIAGNOSTIC
		if (off & PGOFSET)
			panic("_dmamem_mmap: offset unaligned");
		if (segs[i].ds_addr & PGOFSET)
			panic("_dmamem_mmap: segment unaligned");
		if (segs[i].ds_len & PGOFSET)
			panic("_dmamem_mmap: segment size not multiple"
			    " of page size");
#endif
		if (off >= segs[i].ds_len) {
			off -= segs[i].ds_len;
			continue;
		}

		return ((*t->_device_to_pa)(segs[i].ds_addr) + off);
	}

	/* Page not found. */
	return (-1);
}

/**********************************************************************
 * DMA utility functions
 **********************************************************************/

/*
 * Utility function to load a linear buffer.  lastaddrp holds state
 * between invocations (for multiple-buffer loads).  segp contains
 * the starting segment on entrance, and the ending segment on exit.
 * first indicates if this is the first invocation of this function.
 */
int
_dmamap_load_buffer(bus_dma_tag_t t, bus_dmamap_t map, void *buf,
    bus_size_t buflen, struct proc *p, int flags, paddr_t *lastaddrp,
    int *segp, int first)
{
	bus_size_t sgsize;
	bus_addr_t lastaddr, baddr, bmask;
	paddr_t curaddr;
	vaddr_t vaddr = (vaddr_t)buf;
	int seg;
	pmap_t pmap;

	if (p != NULL)
		pmap = p->p_vmspace->vm_map.pmap;
	else
		pmap = pmap_kernel();

	lastaddr = *lastaddrp;
	bmask  = ~(map->_dm_boundary - 1);
	if (t->_dma_mask != 0)
		bmask &= t->_dma_mask;

	for (seg = *segp; buflen > 0; ) {
		/*
		 * Get the physical address for this segment.
		 */
		if (pmap_extract(pmap, vaddr, &curaddr) == FALSE)
			panic("_dmapmap_load_buffer: pmap_extract(%p, %lx) "
			    "failed!", pmap, vaddr);

		/*
		 * Compute the segment size, and adjust counts.
		 */
		sgsize = NBPG - ((u_long)vaddr & PGOFSET);
		if (buflen < sgsize)
			sgsize = buflen;

		/*
		 * Make sure we don't cross any boundaries.
		 */
		if (map->_dm_boundary > 0) {
			baddr = ((bus_addr_t)curaddr + map->_dm_boundary) &
			    bmask;
			if (sgsize > (baddr - (bus_addr_t)curaddr))
				sgsize = (baddr - (bus_addr_t)curaddr);
		}

		/*
		 * Insert chunk into a segment, coalescing with
		 * previous segment if possible.
		 */
		if (first) {
			map->dm_segs[seg].ds_addr =
			    (*t->_pa_to_device)(curaddr);
			map->dm_segs[seg].ds_len = sgsize;
			map->dm_segs[seg]._ds_paddr = curaddr;
			map->dm_segs[seg]._ds_vaddr = vaddr;
			first = 0;
		} else {
			if ((bus_addr_t)curaddr == lastaddr &&
			    (map->dm_segs[seg].ds_len + sgsize) <=
			     map->_dm_maxsegsz &&
			     (map->_dm_boundary == 0 ||
			     (map->dm_segs[seg].ds_addr & bmask) ==
			     ((bus_addr_t)curaddr & bmask)))
				map->dm_segs[seg].ds_len += sgsize;
			else {
				if (++seg >= map->_dm_segcnt)
					break;
				map->dm_segs[seg].ds_addr =
				    (*t->_pa_to_device)(curaddr);
				map->dm_segs[seg].ds_len = sgsize;
				map->dm_segs[seg]._ds_paddr = curaddr;
				map->dm_segs[seg]._ds_vaddr = vaddr;
			}
		}

		lastaddr = (bus_addr_t)curaddr + sgsize;
		vaddr += sgsize;
		buflen -= sgsize;
	}

	*segp = seg;
	*lastaddrp = lastaddr;

	/*
	 * Did we fit?
	 */
	if (buflen != 0)
		return (EFBIG);		/* XXX better return value here? */

	return (0);
}

/*
 * Allocate physical memory from the given physical address range.
 * Called by DMA-safe memory allocation methods.
 */
int
_dmamem_alloc_range(bus_dma_tag_t t, bus_size_t size, bus_size_t alignment,
    bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs,
    int flags, paddr_t low, paddr_t high)
{
	paddr_t curaddr, lastaddr;
	vm_page_t m;
	struct pglist mlist;
	int curseg, error, plaflag;

	/* Always round the size. */
	size = round_page(size);

	/*
	 * Allocate pages from the VM system.
	 */
	plaflag = flags & BUS_DMA_NOWAIT ? UVM_PLA_NOWAIT : UVM_PLA_WAITOK;
	if (flags & BUS_DMA_ZERO)
		plaflag |= UVM_PLA_ZERO;

	TAILQ_INIT(&mlist);
	error = uvm_pglistalloc(size, low, high, alignment, boundary,
	    &mlist, nsegs, plaflag);
	if (error)
		return (error);

	/*
	 * Compute the location, size, and number of segments actually
	 * returned by the VM code.
	 */
	m = TAILQ_FIRST(&mlist);
	curseg = 0;
	lastaddr = segs[curseg].ds_addr =
	    (*t->_pa_to_device)(VM_PAGE_TO_PHYS(m));
	segs[curseg].ds_len = PAGE_SIZE;
	m = TAILQ_NEXT(m, pageq);

	for (; m != NULL; m = TAILQ_NEXT(m, pageq)) {
		curaddr = VM_PAGE_TO_PHYS(m);
#ifdef DIAGNOSTIC
		if (curaddr < low || curaddr >= high) {
			printf("vm_page_alloc_memory returned non-sensical"
			    " address 0x%lx\n", curaddr);
			panic("_dmamem_alloc_range");
		}
#endif
		curaddr = (*t->_pa_to_device)(curaddr);
		if (curaddr == (lastaddr + PAGE_SIZE))
			segs[curseg].ds_len += PAGE_SIZE;
		else {
			curseg++;
			segs[curseg].ds_addr = curaddr;
			segs[curseg].ds_len = PAGE_SIZE;
		}
		lastaddr = curaddr;
	}

	*rsegs = curseg + 1;

	return (0);
}


code:
/*	$OpenBSD: bus_space.c,v 1.2 2014/05/24 21:11:01 miod Exp $ */

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

/*
 * Simple generic bus access primitives.
 */

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

#include <machine/bus.h>

uint8_t
generic_space_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
{
	return *(volatile uint8_t *)(h + o);
}

uint16_t
generic_space_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
{
	return *(volatile uint16_t *)(h + o);
}

uint32_t
generic_space_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
{
	return *(volatile uint32_t *)(h + o);
}

uint64_t
generic_space_read_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
{
	return *(volatile uint64_t *)(h + o);
}

void
generic_space_write_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
    uint8_t v)
{
	*(volatile uint8_t *)(h + o) = v;
}

void
generic_space_write_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
    uint16_t v)
{
	*(volatile uint16_t *)(h + o) = v;
}

void
generic_space_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
    uint32_t v)
{
	*(volatile uint32_t *)(h + o) = v;
}

void
generic_space_write_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
    uint64_t v)
{
	*(volatile uint64_t *)(h + o) = v;
}

void
generic_space_read_raw_2(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
    uint8_t *buf, bus_size_t len)
{
	volatile uint16_t *addr = (volatile uint16_t *)(h + o);
	len >>= 1;
	while (len-- != 0) {
		*(uint16_t *)buf = *addr;
		buf += 2;
	}
}

void
generic_space_write_raw_2(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
    const uint8_t *buf, bus_size_t len)
{
	volatile uint16_t *addr = (volatile uint16_t *)(h + o);
	len >>= 1;
	while (len-- != 0) {
		*addr = *(uint16_t *)buf;
		buf += 2;
	}
}

void
generic_space_read_raw_4(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
    uint8_t *buf, bus_size_t len)
{
	volatile uint32_t *addr = (volatile uint32_t *)(h + o);
	len >>= 2;
	while (len-- != 0) {
		*(uint32_t *)buf = *addr;
		buf += 4;
	}
}

void
generic_space_write_raw_4(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
    const uint8_t *buf, bus_size_t len)
{
	volatile uint32_t *addr = (volatile uint32_t *)(h + o);
	len >>= 2;
	while (len-- != 0) {
		*addr = *(uint32_t *)buf;
		buf += 4;
	}
}

void
generic_space_read_raw_8(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
    uint8_t *buf, bus_size_t len)
{
	volatile uint64_t *addr = (volatile uint64_t *)(h + o);
	len >>= 3;
	while (len-- != 0) {
		*(uint64_t *)buf = *addr;
		buf += 8;
	}
}

void
generic_space_write_raw_8(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
    const uint8_t *buf, bus_size_t len)
{
	volatile uint64_t *addr = (volatile uint64_t *)(h + o);
	len >>= 3;
	while (len-- != 0) {
		*addr = *(uint64_t *)buf;
		buf += 8;
	}
}

int
generic_space_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size,
    int flags, bus_space_handle_t *bshp)
{
	*bshp = t->bus_base + offs;
	return 0;
}

void
generic_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
{
}

int
generic_space_region(bus_space_tag_t t, bus_space_handle_t bsh,
    bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
{
	*nbshp = bsh + offset;
	return 0;
}

void *
generic_space_vaddr(bus_space_tag_t t, bus_space_handle_t h)
{
	return (void *)h;
}

paddr_t
generic_space_mmap(bus_space_tag_t t, bus_addr_t addr, off_t off, int prot,
    int flags)
{
	return (paddr_t)-1;
}


code:
/*	$OpenBSD: conf.c,v 1.19 2014/12/11 19:44:17 tedu Exp $ */

/*
 * Copyright (c) 1992, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Ralph Campbell.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. 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.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/ioctl.h>
#include <sys/proc.h>
#include <sys/vnode.h>
#include <sys/tty.h>

#include <machine/conf.h>

/*
 *	Block devices.
 */

#include "vnd.h"
#include "sd.h"
#include "cd.h"
#include "st.h"
#include "wd.h"
bdev_decl(wd);
#include "rd.h"
#include "hotplug.h"

struct bdevsw	bdevsw[] =
{
	bdev_disk_init(NSD,sd),		/* 0: SCSI disk */
	bdev_swap_init(1,sw),		/* 1: should be here swap pseudo-dev */
	bdev_disk_init(NVND,vnd),	/* 2: vnode disk driver */
	bdev_disk_init(NCD,cd),		/* 3: SCSI CD-ROM */
	bdev_disk_init(NWD,wd),		/* 4: ST506/ESDI/IDE disk */
	bdev_notdef(),			/* 5:  */
	bdev_notdef(),			/* 6: was: concatenated disk driver */
	bdev_notdef(),			/* 7:  */
	bdev_disk_init(NRD,rd),		/* 8: RAM disk (for install) */
	bdev_notdef(),			/* 9:  */
	bdev_tape_init(NST,st),		/* 10: SCSI tape */
	bdev_notdef(),			/* 11:  */
	bdev_notdef(),			/* 12:  */
	bdev_notdef(),			/* 13:  */
	bdev_notdef(),			/* 14:  */
	bdev_notdef(),			/* 15:  */
};

int	nblkdev = nitems(bdevsw);

/*
 *	Character devices.
 */

#define mmread mmrw
#define mmwrite mmrw
dev_type_read(mmrw);
cdev_decl(mm);
#include "bio.h"
#include "pty.h"
cdev_decl(fd);
#include "st.h"
#include "bpfilter.h"
#include "tun.h"
#include "apm.h"
#include "com.h"
cdev_decl(com);
#include "lpt.h"
cdev_decl(lpt);
#include "ch.h"
#include "uk.h"
cdev_decl(wd);
#include "audio.h"
#include "video.h"
#include "ksyms.h"

#include "wsdisplay.h"
#include "wskbd.h"
#include "wsmouse.h"
#include "wsmux.h"
#include "pci.h"
cdev_decl(pci);

#include "pf.h"
#include "systrace.h"

#include "usb.h"
#include "uhid.h"
#include "ugen.h"
#include "ulpt.h"
#include "ucom.h"

#include "vscsi.h"
#include "pppx.h"
#include "fuse.h"

struct cdevsw	cdevsw[] =
{
	cdev_cn_init(1,cn),		/* 0: virtual console */
	cdev_notdef(),			/* 1: was /dev/drum */
	cdev_ctty_init(1,ctty),		/* 2: controlling terminal */
	cdev_mm_init(1,mm),		/* 3: /dev/{null,mem,kmem,...} */
	cdev_tty_init(NPTY,pts),	/* 4: pseudo-tty slave */
	cdev_ptc_init(NPTY,ptc),	/* 5: pseudo-tty master */
	cdev_log_init(1,log),		/* 6: /dev/klog */
	cdev_fd_init(1,filedesc),	/* 7: file descriptor pseudo-dev */
	cdev_disk_init(NCD,cd),		/* 8: SCSI CD */
	cdev_disk_init(NSD,sd),		/* 9: SCSI disk */
	cdev_tape_init(NST,st),		/* 10: SCSI tape */
	cdev_disk_init(NVND,vnd),	/* 11: vnode disk */
	cdev_bpf_init(NBPFILTER,bpf),	/* 12: berkeley packet filter */
	cdev_tun_init(NTUN,tun),	/* 13: network tunnel */
	cdev_apm_init(NAPM,apm),	/* 14: apm */
	cdev_notdef(),			/* 15: */
	cdev_lpt_init(NLPT,lpt),	/* 16: Parallel printer interface */
	cdev_tty_init(NCOM,com),	/* 17: 16C450 serial interface */
	cdev_disk_init(NWD,wd),		/* 18: ST506/ESDI/IDE disk */
	cdev_notdef(),			/* 19: */
	cdev_notdef(),			/* 20: */
	cdev_notdef(),			/* 21: */
	cdev_disk_init(NRD,rd),		/* 22: ramdisk device */
	cdev_notdef(),			/* 23: was: concatenated disk driver */
	cdev_notdef(),			/* 24: */
	cdev_wsdisplay_init(NWSDISPLAY, wsdisplay),	/* 25: */
	cdev_mouse_init(NWSKBD, wskbd),	/* 26: */
	cdev_mouse_init(NWSMOUSE, wsmouse),	/* 27: */
	cdev_mouse_init(NWSMUX, wsmux),	/* 28: */
#ifdef USER_PCICONF
	cdev_pci_init(NPCI,pci),	/* 29: PCI user */
#else
	cdev_notdef(),			/* 29 */
#endif
	cdev_notdef(),			/* 30: */
	cdev_pf_init(NPF,pf),		/* 31: packet filter */
	cdev_uk_init(NUK,uk),		/* 32: unknown SCSI */
	cdev_random_init(1,random),	/* 33: random data source */
	cdev_notdef(),			/* 34: */
	cdev_ksyms_init(NKSYMS,ksyms),	/* 35: Kernel symbols device */
	cdev_ch_init(NCH,ch),		/* 36: SCSI autochanger */
	cdev_notdef(),			/* 37: */
	cdev_notdef(),			/* 38: */
	cdev_notdef(),			/* 39: */
	cdev_notdef(),			/* 40: */
	cdev_notdef(),			/* 41: */
	cdev_notdef(),			/* 42: */
	cdev_notdef(),			/* 33: */
	cdev_audio_init(NAUDIO,audio),	/* 44: /dev/audio */
	cdev_video_init(NVIDEO,video),	/* 45: generic video I/O */
	cdev_notdef(),			/* 46: */
	cdev_notdef(),			/* 47: was: /dev/crypto */
	cdev_notdef(),			/* 48: */
	cdev_bio_init(NBIO,bio),	/* 49: ioctl tunnel */
	cdev_systrace_init(NSYSTRACE,systrace),	/* 50: system call tracing */
	cdev_notdef(),			/* 51: */
	cdev_ptm_init(NPTY,ptm),	/* 52: pseudo-tty ptm device */
	cdev_notdef(),			/* 53: */
	cdev_notdef(),			/* 54: */
	cdev_notdef(),			/* 55: */
	cdev_notdef(),			/* 56: */
	cdev_notdef(),			/* 57: */
	cdev_notdef(),			/* 58: */
	cdev_notdef(),			/* 59: */
	cdev_notdef(),			/* 60: */
	cdev_usb_init(NUSB,usb),	/* 61: USB controller */
	cdev_usbdev_init(NUHID,uhid),	/* 62: USB generic HID */
	cdev_usbdev_init(NUGEN,ugen),	/* 63: USB generic driver */
	cdev_ulpt_init(NULPT,ulpt),	/* 64: USB printers */
	cdev_notdef(),			/* 65: */
	cdev_tty_init(NUCOM,ucom),	/* 66: USB tty */
	cdev_hotplug_init(NHOTPLUG,hotplug), /* 67: devices hotplugging */
	cdev_notdef(),
	cdev_vscsi_init(NVSCSI,vscsi),	/* 69: vscsi */
	cdev_disk_init(1,diskmap),	/* 70: disk mapper */
	cdev_pppx_init(NPPPX,pppx),	/* 71: pppx */
	cdev_notdef(),			/* 72: was USB scanners */
	cdev_fuse_init(NFUSE,fuse),	/* 73: fuse */
};

int	nchrdev = nitems(cdevsw);

/*
 * Swapdev is a fake device implemented
 * in sw.c used only internally to get to swstrategy.
 * It cannot be provided to the users, because the
 * swstrategy routine munches the b_dev and b_blkno entries
 * before calling the appropriate driver.  This would horribly
 * confuse, e.g. the hashing routines. Instead, /dev/drum is
 * provided as a character (raw) device.
 */
dev_t	swapdev = makedev(1, 0);

/*
 * Routine that identifies /dev/mem and /dev/kmem.
 *
 * A minimal stub routine can always return 0.
 */
int
iskmemdev(dev)
	dev_t dev;
{

	if (major(dev) == 3 && (minor(dev) == 0 || minor(dev) == 1))
		return (1);
	return (0);
}

/*
 * Returns true if def is /dev/zero
 */
int
iszerodev(dev)
	dev_t dev;
{
	return (major(dev) == 3 && minor(dev) == 12);
}

dev_t
getnulldev()
{
	return(makedev(3, 2));
}

int chrtoblktbl[] =  {
	/* VCHR         VBLK */
	/* 0 */		NODEV,
	/* 1 */		NODEV,
	/* 2 */		NODEV,
	/* 3 */		NODEV,
	/* 4 */		NODEV,
	/* 5 */		NODEV,
	/* 6 */		NODEV,
	/* 7 */		NODEV,
	/* 8 */		3,		/* cd */
	/* 9 */		0,		/* sd */
	/* 10 */	10,		/* st */
	/* 11 */	2,		/* vnd */
	/* 12 */	NODEV,
	/* 13 */	NODEV,
	/* 14 */	NODEV,
	/* 15 */	NODEV,
	/* 16 */	NODEV,
	/* 17 */	NODEV,
	/* 18 */	4,		/* wd */
	/* 19 */	NODEV,
	/* 20 */	NODEV,
	/* 21 */	NODEV,
	/* 22 */	8		/* rd */
};

int nchrtoblktbl = nitems(chrtoblktbl);

#include <dev/cons.h>

cons_decl(ws);
cons_decl(com);

struct	consdev constab[] = {
#if NWSDISPLAY > 0
	cons_init(ws),
#endif
#if NCOM > 0
	cons_init(com),
#endif
	{ 0 },
};


code:
/*	$OpenBSD: disksubr.c,v 1.8 2013/10/19 09:32:14 krw Exp $	*/
/*	$NetBSD: disksubr.c,v 1.21 1996/05/03 19:42:03 christos Exp $	*/

/*
 * Copyright (c) 1996 Theo de Raadt
 * Copyright (c) 1982, 1986, 1988 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.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/disklabel.h>
#include <sys/disk.h>

/*
 * Attempt to read a disk label from a device
 * using the indicated strategy routine.
 * The label must be partly set up before this:
 * secpercyl, secsize and anything required for a block i/o read
 * operation in the driver's strategy/start routines
 * must be filled in before calling us.
 *
 * If dos partition table requested, attempt to load it and
 * find disklabel inside a DOS partition.
 *
 * We would like to check if each MBR has a valid DOSMBR_SIGNATURE, but
 * we cannot because it doesn't always exist. So.. we assume the
 * MBR is valid.
 */
int
readdisklabel(dev_t dev, void (*strat)(struct buf *),
    struct disklabel *lp, int spoofonly)
{
	struct buf *bp = NULL;
	int error;

	if ((error = initdisklabel(lp)))
		goto done;

	/* get a buffer and initialize it */
	bp = geteblk((int)lp->d_secsize);
	bp->b_dev = dev;

	error = readdoslabel(bp, strat, lp, NULL, spoofonly);
	if (error == 0)
		goto done;

#if defined(CD9660)
	error = iso_disklabelspoof(dev, strat, lp);
	if (error == 0)
		goto done;
#endif
#if defined(UDF)
	error = udf_disklabelspoof(dev, strat, lp);
	if (error == 0)
		goto done;
#endif

done:
	if (bp) {
		bp->b_flags |= B_INVAL;
		brelse(bp);
	}
	disk_change = 1;
	return (error);
}

/*
 * Write disk label back to device after modification.
 */
int
writedisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp)
{
	daddr_t partoff = -1;
	int error = EIO;
	int offset;
	struct disklabel *dlp;
	struct buf *bp = NULL;

	/* get a buffer and initialize it */
	bp = geteblk((int)lp->d_secsize);
	bp->b_dev = dev;

	if (readdoslabel(bp, strat, lp, &partoff, 1) != 0)
		goto done;

	/* Read it in, slap the new label in, and write it back out */
	bp->b_blkno = DL_BLKTOSEC(lp, partoff + DOS_LABELSECTOR) *
	    DL_BLKSPERSEC(lp);
	offset = DL_BLKOFFSET(lp, partoff + DOS_LABELSECTOR);
	bp->b_bcount = lp->d_secsize;
	CLR(bp->b_flags, B_READ | B_WRITE | B_DONE);
	SET(bp->b_flags, B_BUSY | B_READ | B_RAW);
	(*strat)(bp);
	if ((error = biowait(bp)) != 0)
		goto done;

	dlp = (struct disklabel *)(bp->b_data + offset);
	*dlp = *lp;
	CLR(bp->b_flags, B_READ | B_WRITE | B_DONE);
	SET(bp->b_flags, B_BUSY | B_WRITE | B_RAW);
	(*strat)(bp);
	error = biowait(bp);

done:
	if (bp) {
		bp->b_flags |= B_INVAL;
		brelse(bp);
	}
	disk_change = 1;
	return (error);
}


code:
/*	$OpenBSD: gdium_machdep.c,v 1.8 2014/03/27 22:16:03 miod Exp $	*/

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

/*
 * Gdium Liberty specific code and configuration data.
 */

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

#include <machine/autoconf.h>

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

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

int	gdium_revision = 0;

void	gdium_attach_hook(pci_chipset_tag_t);
void	gdium_device_register(struct device *, void *);
int	gdium_intr_map(int, int, int);
void	gdium_powerdown(void);
void	gdium_reset(void);
void	gdium_setup(void);

const struct bonito_config gdium_bonito = {
	.bc_adbase = 11,

	.bc_gpioIE = LOONGSON_INTRMASK_GPIO,
	.bc_intEdge = LOONGSON_INTRMASK_PCI_SYSERR |
	    LOONGSON_INTRMASK_PCI_PARERR,
	.bc_intSteer = 0,
	.bc_intPol = LOONGSON_INTRMASK_DRAM_PARERR |
	    LOONGSON_INTRMASK_PCI_SYSERR | LOONGSON_INTRMASK_PCI_PARERR,

	.bc_attach_hook = gdium_attach_hook,
	.bc_intr_map = gdium_intr_map
};

const struct platform gdium_platform = {
	.system_type = LOONGSON_GDIUM,
	.vendor = "EMTEC",
	.product = "Gdium",

	.bonito_config = &gdium_bonito,
	.isa_chipset = NULL,
	.legacy_io_ranges = NULL,

	.setup = gdium_setup,
	.device_register = gdium_device_register,

	.powerdown = gdium_powerdown,
	.reset = gdium_reset
};

void
gdium_attach_hook(pci_chipset_tag_t pc)
{
	pcireg_t id;
	pcitag_t tag;
#ifdef notyet
	int bar;
#endif
#if 0
	pcireg_t reg;
	int dev, func;
#endif

#ifdef notyet
	/*
	 * Clear all BAR of the mini PCI slot; PMON did not initialize
	 * it, and we do not want it to conflict with anything.
	 */
	tag = pci_make_tag(pc, 0, 13, 0);
	for (bar = PCI_MAPREG_START; bar < PCI_MAPREG_END; bar += 4)
		pci_conf_write(pc, tag, bar, 0);
#else
	/*
	 * Force a non conflicting BAR for the wireless controller,
	 * until proper resource configuration code is added to
	 * bonito (work in progress).
	 */
	tag = pci_make_tag(pc, 0, 13, 0);
	pci_conf_write(pc, tag, PCI_MAPREG_START, 0x06228000);
#endif

	/*
	 * Figure out which motherboard we are running on.
	 * Might not be good enough...
	 */
	tag = pci_make_tag(pc, 0, 17, 0);
	id = pci_conf_read(pc, tag, PCI_ID_REG);
	if (id == PCI_ID_CODE(PCI_VENDOR_NEC, PCI_PRODUCT_NEC_USB))
		gdium_revision = 1;

#if 0
	/*
	 * Tweak the usb controller capabilities.
	 */
	for (dev = pci_bus_maxdevs(pc, 0); dev >= 0; dev--) {
		tag = pci_make_tag(pc, 0, dev, 0);
		id = pci_conf_read(pc, tag, PCI_ID_REG);
		if (id != PCI_ID_CODE(PCI_VENDOR_NEC, PCI_PRODUCT_NEC_USB))
			continue;
		if (gdium_revision != 0) {
			reg = pci_conf_read(pc, tag, 0xe0);
			/* enable ports 1 and 2 */
			reg |= 0x00000003;
			pci_conf_write(pc, tag, 0xe0, reg);
		} else {
			for (func = 0; func < 2; func++) {
				tag = pci_make_tag(pc, 0, dev, func);
				id = pci_conf_read(pc, tag, PCI_ID_REG);
				if (PCI_VENDOR(id) != PCI_VENDOR_NEC)
					continue;
				if (PCI_PRODUCT(id) != PCI_PRODUCT_NEC_USB &&
				    PCI_PRODUCT(id) != PCI_PRODUCT_NEC_USB2)
					continue;

				reg = pci_conf_read(pc, tag, 0xe0);
				/* enable ports 1 and 3, disable port 2 */
				reg &= ~0x00000007;
				reg |= 0x00000005;
				pci_conf_write(pc, tag, 0xe0, reg);
				pci_conf_write(pc, tag, 0xe4, 0x00000020);
			}
		}
	}
#endif
}

int
gdium_intr_map(int dev, int fn, int pin)
{
	switch (dev) {
	/* mini-PCI slot */
	case 13:	/* C D A B */
		return BONITO_DIRECT_IRQ(LOONGSON_INTR_PCIA + (pin + 1) % 4);
	/* Frame buffer */
	case 14:
		return BONITO_DIRECT_IRQ(LOONGSON_INTR_PCIA);
	/* USB */
	case 15:
		if (gdium_revision == 0)
			return BONITO_DIRECT_IRQ(LOONGSON_INTR_PCIA +
			    (pin - 1));
		else
			return BONITO_DIRECT_IRQ(LOONGSON_INTR_PCIB);
	/* Ethernet */
	case 16:
		return BONITO_DIRECT_IRQ(LOONGSON_INTR_PCID);
	/* USB, not present in old motherboard revision */
	case 17:
		if (gdium_revision != 0)
			return BONITO_DIRECT_IRQ(LOONGSON_INTR_PCIC);
		else
			break;
	default:
		break;
	}

	return -1;
}

/*
 * Due to PMON limitations on the Gdium Liberty, we do not get boot device
 * information from PMON.
 *
 * Because of this, we always pretend the G-Key port is the boot device.
 *
 * Note that, unlike on the Lemote machines, other USB devices gets a fixed
 * numbering (USB0 and USB1).
 */

extern struct cfdriver bonito_cd;
extern struct cfdriver pci_cd;
extern struct cfdriver ehci_cd;
extern struct cfdriver usb_cd;
extern struct cfdriver uhub_cd;
extern struct cfdriver umass_cd;
extern struct cfdriver scsibus_cd;
extern struct cfdriver sd_cd;

#include <dev/pci/pcivar.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>

void
gdium_device_register(struct device *dev, void *aux)
{
	struct cfdriver *cf = dev->dv_cfdata->cf_driver;
	static int gkey_chain_pos = 0;
	static struct device *lastparent = NULL;

	if (dev->dv_parent != lastparent && gkey_chain_pos != 0)
		return;

	switch (gkey_chain_pos) {
	case 0:	/* bonito at mainbus */
		if (cf == &bonito_cd)
			goto advance;
		break;
	case 1:	/* pci at bonito */
		if (cf == &pci_cd)
			goto advance;
		break;
	case 2:	/* ehci at pci dev 15 */
		if (cf == &ehci_cd) {
			struct pci_attach_args *paa = aux;
			if (paa->pa_device == 15)
				goto advance;
		}
		break;
	case 3:	/* usb at ehci */
		if (cf == &usb_cd)
			goto advance;
		break;
	case 4:	/* uhub at usb */
		if (cf == &uhub_cd)
			goto advance;
		break;
	case 5:	/* umass at uhub port 3 */
		if (cf == &umass_cd) {
			struct usb_attach_arg *uaa = aux;
			if (uaa->port == 3)
				goto advance;
		}
		break;
	case 6:	/* scsibus at umass */
		if (cf == &scsibus_cd)
			goto advance;
		break;
	case 7:	/* sd at scsibus */
		bootdv = dev;
		break;
	}

	return;

advance:
	gkey_chain_pos++;
	lastparent = dev;
}

void
gdium_powerdown()
{
	REGVAL(BONITO_GPIODATA) |= 0x00000002;
	REGVAL(BONITO_GPIOIE) &= ~0x00000002;
}

void
gdium_reset()
{
	REGVAL(BONITO_GPIODATA) &= ~0x00000002;
	REGVAL(BONITO_GPIOIE) &= ~0x00000002;
}

void
gdium_setup()
{
	bonito_early_setup();
}


code:
/*	$OpenBSD: generic2e_machdep.c,v 1.6 2014/03/27 22:16:03 miod Exp $	*/

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

/*
 * Generic Loongson 2E code and configuration data.
 */

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

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

#include <dev/ic/i8259reg.h>

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

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

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

#include "com.h"

#if NCOM > 0
#include <sys/termios.h>
#include <dev/ic/comvar.h>
extern struct mips_bus_space bonito_pci_io_space_tag;
#endif

void	generic2e_device_register(struct device *, void *);
void	generic2e_reset(void);

void	generic2e_setup(void);

void	generic2e_pci_attach_hook(pci_chipset_tag_t);
int	generic2e_intr_map(int, int, int);

void	 generic2e_isa_attach_hook(struct device *, struct device *,
	    struct isabus_attach_args *);
void	*generic2e_isa_intr_establish(void *, int, int, int, int (*)(void *),
	    void *, char *);
void	 generic2e_isa_intr_disestablish(void *, void *);

uint32_t generic2e_isa_intr(uint32_t, struct trap_frame *);

void	via686sb_setup(pci_chipset_tag_t, int);

/* PnP IRQ assignment for VIA686 SuperIO components */
#define	VIA686_IRQ_PCIA		9
#define	VIA686_IRQ_PCIB		10
#define	VIA686_IRQ_PCIC		11
#define	VIA686_IRQ_PCID		13

static int generic2e_via686sb_dev = -1;

const struct bonito_config generic2e_bonito = {
	.bc_adbase = 11,

	.bc_gpioIE = 0xffffffff,
	.bc_intEdge = BONITO_INTRMASK_SYSTEMERR | BONITO_INTRMASK_MASTERERR |
	    BONITO_INTRMASK_RETRYERR | BONITO_INTRMASK_MBOX,
	.bc_intSteer = 0,
	.bc_intPol = 0,

	.bc_attach_hook = generic2e_pci_attach_hook,
	.bc_intr_map = generic2e_intr_map
};

const struct legacy_io_range generic2e_legacy_ranges[] = {
	/* no isa space access restrictions */
	{ 0,		BONITO_PCIIO_LEGACY },

	{ 0 }
};

struct mips_isa_chipset generic2e_isa_chipset = {
	.ic_v = NULL,

	.ic_attach_hook = generic2e_isa_attach_hook,
	.ic_intr_establish = generic2e_isa_intr_establish,
	.ic_intr_disestablish = generic2e_isa_intr_disestablish
};

const struct platform generic2e_platform = {
	.system_type = LOONGSON_2E,
	.vendor = "Generic",
	.product = "Loongson2E",

	.bonito_config = &generic2e_bonito,
	.isa_chipset = &generic2e_isa_chipset,
	.legacy_io_ranges = generic2e_legacy_ranges,

	.setup = generic2e_setup,
	.device_register = generic2e_device_register,

	.powerdown = NULL,
	.reset = generic2e_reset
};

/*
 * PCI model specific routines
 */

void
generic2e_pci_attach_hook(pci_chipset_tag_t pc)
{
	pcireg_t id;
	pcitag_t tag;
	int dev;

	/*
	 * Check for a VIA 686 southbridge; if one is found, remember
	 * its location, needed by generic2e_intr_map().
	 */

	for (dev = pci_bus_maxdevs(pc, 0); dev >= 0; dev--) {
		tag = pci_make_tag(pc, 0, dev, 0);
		id = pci_conf_read(pc, tag, PCI_ID_REG);
		if (id == PCI_ID_CODE(PCI_VENDOR_VIATECH,
		    PCI_PRODUCT_VIATECH_VT82C686A_ISA)) {
			generic2e_via686sb_dev = dev;
			break;
		}
	}

	if (generic2e_via686sb_dev != 0)
		via686sb_setup(pc, generic2e_via686sb_dev);
}

int
generic2e_intr_map(int dev, int fn, int pin)
{
	if (dev == generic2e_via686sb_dev) {
		switch (fn) {
		case 1:	/* PCIIDE */
			/* will use compat interrupt */
			break;
		case 2:	/* USB */
			return BONITO_ISA_IRQ(VIA686_IRQ_PCIB);
		case 3:	/* USB */
			return BONITO_ISA_IRQ(VIA686_IRQ_PCIC);
		case 4:	/* power management, SMBus */
			break;
		case 5:	/* Audio */
			return BONITO_ISA_IRQ(VIA686_IRQ_PCIA);
		case 6:	/* Modem */
			break;
		default:
			break;
		}
	} else {
		return BONITO_DIRECT_IRQ(BONITO_INTR_GPIN +
		    pin - PCI_INTERRUPT_PIN_A);
	}

	return -1;
}

/*
 * ISA model specific routines
 */

void
generic2e_isa_attach_hook(struct device *parent, struct device *self,
    struct isabus_attach_args *iba)
{
	set_intr(INTPRI_ISA, CR_INT_3, generic2e_isa_intr);
	loongson_generic_isa_attach_hook(parent, self, iba);
}

void *
generic2e_isa_intr_establish(void *v, int irq, int type, int level,
    int (*handler)(void *), void *arg, char *name)
{
	/* XXX check type, update elcr */
	return bonito_intr_establish(BONITO_ISA_IRQ(irq), type, level,
	    handler, arg, name);
}

void
generic2e_isa_intr_disestablish(void *v, void *ih)
{
	/* XXX update elcr */
	bonito_intr_disestablish(ih);
}

uint32_t
generic2e_isa_intr(uint32_t hwpend, struct trap_frame *frame)
{
	struct intrhand *ih;
	uint64_t isr, mask = 0;
	int rc, irq, ret;
	uint8_t ocw1, ocw2;
	extern uint loongson_isaimr;

	for (;;) {
		REGVAL8(BONITO_PCIIO_BASE + IO_ICU1 + PIC_OCW3) =
		    OCW3_SELECT | OCW3_POLL;
		ocw1 = REGVAL8(BONITO_PCIIO_BASE + IO_ICU1 + PIC_OCW3);
		if ((ocw1 & OCW3_POLL_PENDING) == 0)
			break;

		irq = OCW3_POLL_IRQ(ocw1);

		if (irq == 2) /* cascade */ {
			REGVAL8(BONITO_PCIIO_BASE + IO_ICU2 + PIC_OCW3) =
			    OCW3_SELECT | OCW3_POLL;
			ocw2 = REGVAL8(BONITO_PCIIO_BASE + IO_ICU2 + PIC_OCW3);
			if (ocw2 & OCW3_POLL_PENDING)
				irq = OCW3_POLL_IRQ(ocw2);
			else
				irq = 2;
		} else
			ocw2 = 0;

		/*
		 * Mask the interrupt before servicing it.
		 */
		isr = 1UL << irq;
		loongson_set_isa_imr(loongson_isaimr & ~isr);

		/*
		 * If interrupt is spl-masked, wait for splx()
		 * to reenable it when necessary.
		 */
		if ((isr & BONITO_ISA_MASK(bonito_imask[frame->ipl])) != 0)
			continue;
		else
			mask |= isr;

		rc = 0;
		for (ih = bonito_intrhand[BONITO_ISA_IRQ(irq)]; ih != NULL;
		    ih = ih->ih_next) {
			splraise(ih->ih_level);

			ret = (*ih->ih_fun)(ih->ih_arg);
			if (ret) {
				rc = 1;
				ih->ih_count.ec_count++;
			}

			__asm__ (".set noreorder\n");
			curcpu()->ci_ipl = frame->ipl;
			mips_sync();
			__asm__ (".set reorder\n");
			if (ret == 1)
				break;
		}

		/* Send a specific EOI to the 8259. */
		loongson_isa_specific_eoi(irq);

		if (rc == 0) {
			printf("spurious isa interrupt %d\n", irq);
#ifdef DEBUG
			printf("ICU1 %02x ICU2 %02x ipl %d mask %08x"
			    " isaimr %08x\n", ocw1, ocw2, frame->ipl,
			    bonito_imask[frame->ipl], loongson_isaimr);
#ifdef DDB
			Debugger();
#endif
#endif
		}
	}

	/*
	 * Reenable interrupts which have been serviced.
	 */
	if (mask != 0)
		loongson_set_isa_imr(loongson_isaimr | mask);

	return mask == 0 ? 0 : hwpend;
}

/*
 * Other model specific routines
 */

void
generic2e_reset()
{
	REGVAL(LOONGSON_GENCFG) &= ~BONITO_GENCFG_CPUSELFRESET;
	REGVAL(LOONGSON_GENCFG) |= BONITO_GENCFG_CPUSELFRESET;
	delay(1000000);
}

void
generic2e_setup(void)
{
#if NCOM > 0
	const char *envvar;
	int serial;

	envvar = pmon_getenv("nokbd");
	serial = envvar != NULL;
	envvar = pmon_getenv("novga");
	serial = serial && envvar != NULL;

	if (serial) {
                comconsiot = &bonito_pci_io_space_tag;
                comconsaddr = 0x3f8;
                comconsrate = 115200; /* default PMON console speed */
	}
#endif

	bonito_early_setup();
}

void
generic2e_device_register(struct device *dev, void *aux)
{
	const char *drvrname = dev->dv_cfdata->cf_driver->cd_name;
	const char *name = dev->dv_xname;

	if (dev->dv_class != bootdev_class)
		return;

	/*
	 * The device numbering must match. There's no way
	 * pmon tells us more info. Depending on the usb slot
	 * and hubs used you may be lucky. Also, assume umass/sd for usb
	 * attached devices.
	 */
	switch (bootdev_class) {
	case DV_DISK:
		if (strcmp(drvrname, "wd") == 0 && strcmp(name, bootdev) == 0)
			bootdv = dev;
		else {
			/* XXX this really only works safely for usb0... */
		    	if ((strcmp(drvrname, "sd") == 0 ||
			    strcmp(drvrname, "cd") == 0) &&
			    strncmp(bootdev, "usb", 3) == 0 &&
			    strcmp(name + 2, bootdev + 3) == 0)
				bootdv = dev;
		}
		break;
	case DV_IFNET:
		/*
		 * This relies on the onboard Ethernet interface being
		 * attached before any other (usb) interface.
		 */
		bootdv = dev;
		break;
	default:
		break;
	}
}

/*
 * Initialize a VIA686 south bridge.
 *
 * PMON apparently does not perform enough initialization; one may argue this
 * could be done with a specific pcib(4) driver, but then no other system
 * will hopefully need this, so keep it local to the 2E setup code.
 */

#define	VIA686_ISA_ROM_CONTROL		0x40
#define	VIA686_ROM_WRITE_ENABLE			0x00000001
#define	VIA686_NO_ROM_WAIT_STATE		0x00000002
#define	VIA686_EXTEND_ALE			0x00000004
#define	VIA686_IO_RECOVERY_TIME			0x00000008
#define	VIA686_CHIPSET_EXTRA_WAIT_STATES	0x00000010
#define	VIA686_ISA_EXTRA_WAIT_STATES		0x00000020
#define	VIA686_ISA_EXTENDED_BUS_READY		0x00000040
#define	VIA686_ISA_EXTRA_COMMAND_DELAY		0x00000080
#define	VIA686_ISA_REFRESH			0x00000100
#define	VIA686_DOUBLE_DMA_CLOCK			0x00000800
#define	VIA686_PORT_92_FAST_RESET		0x00002000
#define	VIA686_IO_MEDIUM_RECOVERY_TIME		0x00004000
#define	VIA686_KBC_DMA_MISC12		0x44
#define	VIA686_ISA_MASTER_TO_LINE_BUFFER	0x00008000
#define	VIA686_POSTED_MEMORY_WRITE_ENABLE	0x00010000
#define	VIA686_PCI_BURST_INTERRUPTABLE		0x00020000
#define	VIA686_FLUSH_LINE_BUFFER_ON_INTR	0x00200000
#define	VIA686_GATE_INTR			0x00400000
#define	VIA686_PCI_MASTER_WRITE_WAIT_STATE	0x00800000
#define	VIA686_PCI_RESET			0x01000000
#define	VIA686_PCI_READ_DELAY_TRANSACTION_TMO	0x02000000
#define	VIA686_PCI_WRITE_DELAY_TRANSACTION_TMO	0x04000000
#define	VIA686_ICR_SHADOW_ENABLE		0x10000000
#define	VIA686_EISA_PORT_4D0_4D1_ENABLE		0x20000000
#define	VIA686_PCI_DELAY_TRANSACTION_ENABLE	0x40000000
#define	VIA686_CPU_RESET_SOURCE_INIT		0x80000000
#define	VIA686_MISC3_IDE_INTR		0x48
#define	VIA686_IDE_PRIMARY_CHAN_MASK		0x00030000
#define	VIA686_IDE_PRIMARY_CHAN_SHIFT			16
#define	VIA686_IDE_SECONDARY_CHAN_MASK		0x000c0000
#define	VIA686_IDE_SECONDARY_CHAN_SHIFT			18
#define	VIA686_IDE_IRQ14	00
#define	VIA686_IDE_IRQ15	01
#define	VIA686_IDE_IRQ10	02
#define	VIA686_IDE_IRQ11	03
#define	VIA686_IDE_PGNT				0x00800000
#define	VIA686_PNP_DMA_IRQ		0x50
#define	VIA686_DMA_FDC_MASK			0x00000003
#define	VIA686_DMA_FDC_SHIFT				0
#define	VIA686_DMA_LPT_MASK			0x0000000c
#define	VIA686_DMA_LPT_SHIFT				2
#define	VIA686_IRQ_FDC_MASK			0x00000f00
#define	VIA686_IRQ_FDC_SHIFT				8
#define	VIA686_IRQ_LPT_MASK			0x0000f000
#define	VIA686_IRQ_LPT_SHIFT				12
#define	VIA686_IRQ_COM0_MASK			0x000f0000
#define	VIA686_IRQ_COM0_SHIFT				16
#define	VIA686_IRQ_COM1_MASK			0x00f00000
#define	VIA686_IRQ_COM1_SHIFT				20
#define	VIA686_PCI_LEVEL_PNP_IRQ2	0x54
#define	VIA686_PCI_IRQD_EDGE			0x00000001
#define	VIA686_PCI_IRQC_EDGE			0x00000002
#define	VIA686_PCI_IRQB_EDGE			0x00000004
#define	VIA686_PCI_IRQA_EDGE			0x00000008
#define	VIA686_IRQ_PCIA_MASK			0x0000f000
#define	VIA686_IRQ_PCIA_SHIFT				12
#define	VIA686_IRQ_PCIB_MASK			0x000f0000
#define	VIA686_IRQ_PCIB_SHIFT				16
#define	VIA686_IRQ_PCIC_MASK			0x00f00000
#define	VIA686_IRQ_PCIC_SHIFT				20
#define	VIA686_IRQ_PCID_MASK			0xf0000000
#define	VIA686_IRQ_PCID_SHIFT				28

void
via686sb_setup(pci_chipset_tag_t pc, int dev)
{
	pcitag_t tag;
	pcireg_t reg;
	uint elcr;

	tag = pci_make_tag(pc, 0, dev, 0);

	/*
	 * Generic ISA bus initialization.
	 */

	reg = pci_conf_read(pc, tag, VIA686_ISA_ROM_CONTROL);
	reg |= VIA686_IO_RECOVERY_TIME | VIA686_ISA_REFRESH;
	pci_conf_write(pc, tag, VIA686_ISA_ROM_CONTROL, reg);

	reg = pci_conf_read(pc, tag, VIA686_KBC_DMA_MISC12);
	reg |= VIA686_CPU_RESET_SOURCE_INIT |
	    VIA686_PCI_DELAY_TRANSACTION_ENABLE |
	    VIA686_EISA_PORT_4D0_4D1_ENABLE |
	    VIA686_PCI_WRITE_DELAY_TRANSACTION_TMO |
	    VIA686_PCI_READ_DELAY_TRANSACTION_TMO |
	    VIA686_PCI_MASTER_WRITE_WAIT_STATE | VIA686_GATE_INTR |
	    VIA686_FLUSH_LINE_BUFFER_ON_INTR;
	reg &= ~VIA686_ISA_MASTER_TO_LINE_BUFFER;
	pci_conf_write(pc, tag, VIA686_KBC_DMA_MISC12, reg);

	/*
	 * SuperIO devices interrupt and DMA setup.
	 */

	reg = pci_conf_read(pc, tag, VIA686_MISC3_IDE_INTR);
	reg &= ~(VIA686_IDE_PRIMARY_CHAN_MASK | VIA686_IDE_SECONDARY_CHAN_MASK);
	reg |= (VIA686_IDE_IRQ14 << VIA686_IDE_PRIMARY_CHAN_SHIFT);
	reg |= (VIA686_IDE_IRQ15 << VIA686_IDE_SECONDARY_CHAN_SHIFT);
	reg |= VIA686_IDE_PGNT;
	pci_conf_write(pc, tag, VIA686_MISC3_IDE_INTR, reg);

	reg = pci_conf_read(pc, tag, VIA686_PNP_DMA_IRQ);
	reg &= ~(VIA686_DMA_FDC_MASK | VIA686_DMA_LPT_MASK);
	reg |= (2 << VIA686_DMA_FDC_SHIFT) | (3 << VIA686_DMA_LPT_SHIFT);
	reg &= ~(VIA686_IRQ_FDC_MASK | VIA686_IRQ_LPT_MASK);
	reg |= (6 << VIA686_IRQ_FDC_SHIFT) | (7 << VIA686_IRQ_LPT_SHIFT);
	reg &= ~(VIA686_IRQ_COM0_MASK | VIA686_IRQ_COM1_MASK);
	reg |= (4 << VIA686_IRQ_COM0_SHIFT) | (3 << VIA686_IRQ_COM1_SHIFT);

	reg = pci_conf_read(pc, tag, VIA686_PCI_LEVEL_PNP_IRQ2);
	reg &= ~(VIA686_PCI_IRQA_EDGE | VIA686_PCI_IRQB_EDGE |
	    VIA686_PCI_IRQB_EDGE | VIA686_PCI_IRQD_EDGE);
	reg &= ~(VIA686_IRQ_PCIA_MASK | VIA686_IRQ_PCIB_MASK |
	    VIA686_IRQ_PCIC_MASK | VIA686_IRQ_PCID_MASK);
	reg |= (VIA686_IRQ_PCIA << VIA686_IRQ_PCIA_SHIFT) |
	    (VIA686_IRQ_PCIB << VIA686_IRQ_PCIB_SHIFT) |
	    (VIA686_IRQ_PCIC << VIA686_IRQ_PCIC_SHIFT) |
	    (VIA686_IRQ_PCID << VIA686_IRQ_PCID_SHIFT);

	/*
	 * Interrupt controller setup.
	 */

	/* reset; program device, four bytes */
	REGVAL8(BONITO_PCIIO_BASE + IO_ICU1 + PIC_ICW1) =
	    ICW1_SELECT | ICW1_IC4;
	REGVAL8(BONITO_PCIIO_BASE + IO_ICU1 + PIC_ICW2) = ICW2_VECTOR(0);
	REGVAL8(BONITO_PCIIO_BASE + IO_ICU1 + PIC_ICW3) = ICW3_CASCADE(2);
	REGVAL8(BONITO_PCIIO_BASE + IO_ICU1 + PIC_ICW4) = ICW4_8086;
	/* leave interrupts masked */
	REGVAL8(BONITO_PCIIO_BASE + IO_ICU1 + PIC_OCW1) = 0xff;
	/* special mask mode (if available) */
	REGVAL8(BONITO_PCIIO_BASE + IO_ICU1 + PIC_OCW3) =
	    OCW3_SELECT | OCW3_SSMM | OCW3_SMM;
	/* read IRR by default. */
	REGVAL8(BONITO_PCIIO_BASE + IO_ICU1 + PIC_OCW3) = OCW3_SELECT | OCW3_RR;

	/* reset; program device, four bytes */
	REGVAL8(BONITO_PCIIO_BASE + IO_ICU2 + PIC_ICW1) =
	    ICW1_SELECT | ICW1_IC4;
	REGVAL8(BONITO_PCIIO_BASE + IO_ICU2 + PIC_ICW2) = ICW2_VECTOR(8);
	REGVAL8(BONITO_PCIIO_BASE + IO_ICU2 + PIC_ICW3) = ICW3_SIC(2);
	REGVAL8(BONITO_PCIIO_BASE + IO_ICU2 + PIC_ICW4) = ICW4_8086;
	/* leave interrupts masked */
	REGVAL8(BONITO_PCIIO_BASE + IO_ICU2 + PIC_OCW1) = 0xff;
	/* special mask mode (if available) */
	REGVAL8(BONITO_PCIIO_BASE + IO_ICU2 + PIC_OCW3) =
	    OCW3_SELECT | OCW3_SSMM | OCW3_SMM;
	/* read IRR by default. */
	REGVAL8(BONITO_PCIIO_BASE + IO_ICU2 + PIC_OCW3) = OCW3_SELECT | OCW3_RR;

	/* setup ELCR: PCI interrupts are level-triggered. */
	elcr = (1 << VIA686_IRQ_PCIA) | (1 << VIA686_IRQ_PCIB) |
	    (1 << VIA686_IRQ_PCIC) | (1 << VIA686_IRQ_PCID);
	REGVAL8(BONITO_PCIIO_BASE + 0x4d0) = (elcr >> 0) & 0xff;
	REGVAL8(BONITO_PCIIO_BASE + 0x4d1) = (elcr >> 8) & 0xff;

	mips_sync();

	/*
	 * Update interrupt information for secondary functions.
	 * Although this information is not used by pci_intr_establish()
	 * because of generic2e_intr_map() behaviour, it seems to be
	 * required to complete proper interrupt routing.
	 */

	tag = pci_make_tag(pc, 0, dev, 2);
	reg = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
	reg &= ~(PCI_INTERRUPT_LINE_MASK << PCI_INTERRUPT_LINE_SHIFT);
	reg |= VIA686_IRQ_PCIB << PCI_INTERRUPT_LINE_SHIFT;
	pci_conf_write(pc, tag, PCI_INTERRUPT_REG, reg);

	tag = pci_make_tag(pc, 0, dev, 3);
	reg = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
	reg &= ~(PCI_INTERRUPT_LINE_MASK << PCI_INTERRUPT_LINE_SHIFT);
	reg |= VIA686_IRQ_PCIC << PCI_INTERRUPT_LINE_SHIFT;
	pci_conf_write(pc, tag, PCI_INTERRUPT_REG, reg);

	tag = pci_make_tag(pc, 0, dev, 5);
	reg = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
	reg &= ~(PCI_INTERRUPT_LINE_MASK << PCI_INTERRUPT_LINE_SHIFT);
	reg |= VIA686_IRQ_PCIA << PCI_INTERRUPT_LINE_SHIFT;
	pci_conf_write(pc, tag, PCI_INTERRUPT_REG, reg);
}


code:
/*	$OpenBSD: hibernate_machdep.c,v 1.8 2015/05/05 02:13:46 guenther Exp $	*/

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

#include <sys/param.h>
#include <sys/buf.h>
#include <sys/conf.h>
#include <sys/device.h>
#include <sys/disk.h>
#include <sys/disklabel.h>
#include <sys/hibernate.h>
#include <sys/timeout.h>
#include <sys/malloc.h>

#include <uvm/uvm_extern.h>
#include <uvm/uvm_pmemrange.h>

#include <mips64/cache.h>

#include <machine/hibernate.h>
#include <machine/hibernate_var.h>
#include <machine/kcore.h>
#include <machine/pmap.h>
#include <machine/memconf.h>

#include "wd.h"
#include "ahci.h"
#include "softraid.h"
#include "sd.h"

#if NWD > 0
#include <dev/ata/atavar.h>
#include <dev/ata/wdvar.h>
#endif

/*
 * Loongson MD Hibernate functions
 *
 * see Loongson hibernate.h for lowmem layout used during hibernate
 */

/*
 * Returns the hibernate write I/O function to use on this machine
 */
hibio_fn
get_hibernate_io_function(dev_t dev)
{
	char *blkname = findblkname(major(dev));

	if (blkname == NULL)
		return NULL;

#if NWD > 0
	if (strcmp(blkname, "wd") == 0)
		return wd_hibernate_io;
#endif
#if NSD > 0
	if (strcmp(blkname, "sd") == 0) {
		extern struct cfdriver sd_cd;
		extern int ahci_hibernate_io(dev_t dev, daddr_t blkno,
		    vaddr_t addr, size_t size, int op, void *page);
		extern int sr_hibernate_io(dev_t dev, daddr_t blkno,
		    vaddr_t addr, size_t size, int op, void *page);
		struct device *dv = disk_lookup(&sd_cd, DISKUNIT(dev));

#if NAHCI > 0
		if (dv && dv->dv_parent && dv->dv_parent->dv_parent &&
		    strcmp(dv->dv_parent->dv_parent->dv_cfdata->cf_driver->cd_name,
		    "ahci") == 0)
			return ahci_hibernate_io;
#endif
#if NSOFTRAID > 0
		if (dv && dv->dv_parent && dv->dv_parent->dv_parent &&
		    strcmp(dv->dv_parent->dv_parent->dv_cfdata->cf_driver->cd_name,
		    "softraid") == 0)
			return sr_hibernate_io;
	}
#endif
#endif /* NSD > 0 */
	return NULL;
}

/*
 * Gather MD-specific data and store into hiber_info
 */
int
get_hibernate_info_md(union hibernate_info *hiber_info)
{
	int i;

	/* Calculate memory ranges */
	hiber_info->nranges = 0;
	hiber_info->image_size = 0;

	for (i = 0; i < MAXMEMSEGS && mem_layout[i].mem_last_page != 0; i++) {
		/* XXX: Adjust for stolen pages later */
		hiber_info->ranges[i].base =
		    mem_layout[i].mem_first_page >> PAGE_SHIFT;
		hiber_info->ranges[i].end =
		    mem_layout[i].mem_last_page >> PAGE_SHIFT;
		hiber_info->image_size +=
		    hiber_info->ranges[i].end - hiber_info->ranges[i].base;
		hiber_info->nranges++;
	}

	return (0);
}

/*
 * Enter a mapping for va->pa in the resume pagetable
 */
void
hibernate_enter_resume_mapping(vaddr_t va, paddr_t pa, int size)
{
	/* XXX TBD */
}

/*
 * Create the resume-time page table. This table maps the image(pig) area,
 * the kernel text area, and various utility pages for use during resume,
 * since we cannot overwrite the resuming kernel's page table during inflate
 * and expect things to work properly.
 */
void
hibernate_populate_resume_pt(union hibernate_info *hib_info,
    paddr_t image_start, paddr_t image_end)
{
	/* XXX TBD */
}

/*
 * During inflate, certain pages that contain our bookkeeping information
 * (eg, the chunk table, scratch pages, etc) need to be skipped over and
 * not inflated into.
 *
 * Returns 1 if the physical page at dest should be skipped, 0 otherwise
 */
int
hibernate_inflate_skip(union hibernate_info *hib_info, paddr_t dest)
{
	if (dest >= hib_info->piglet_pa &&
	    dest <= (hib_info->piglet_pa + 4 * HIBERNATE_CHUNK_SIZE))
		return (1);

	return (0);
}

void
hibernate_enable_intr_machdep(void)
{
	enableintr();
}

void
hibernate_disable_intr_machdep(void)
{
	disableintr();
}

void
hibernate_flush(void)
{
	Mips_SyncCache(curcpu());
}


code:
/*	$OpenBSD: isa_machdep.c,v 1.3 2012/09/29 19:24:31 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.
 */

/*
 * Legacy device support.
 */

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

#include <machine/autoconf.h>
#include <machine/cpu.h>
#include <machine/intr.h>

#include <dev/ic/i8259reg.h>

#include <dev/pci/pcivar.h>

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

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

void	 loongson_set_isa_imr(uint);
void	 loongson_isa_splx(int);
void	 loongson_isa_setintrmask(int);

uint	loongson_isaimr;

void
loongson_set_isa_imr(uint newimr)
{
	uint imr1, imr2;

	imr1 = 0xff & ~newimr;
	imr1 &= ~(1 << 2);	/* enable cascade */
	imr2 = 0xff & ~(newimr >> 8);

	/*
	 * For some reason, trying to write the same value to the PIC
	 * registers causes an immediate system freeze (at least on the
	 * 2F and CS5536 based Lemote Yeeloong), so we only do this if
	 * the value changes.
	 * Note that interrupts have been disabled by the caller.
	 */
	if ((newimr ^ loongson_isaimr) & 0xff00)
		REGVAL8(BONITO_PCIIO_BASE + IO_ICU2 + 1) = imr2;
	if ((newimr ^ loongson_isaimr) & 0x00ff)
		REGVAL8(BONITO_PCIIO_BASE + IO_ICU1 + 1) = imr1;
	loongson_isaimr = newimr;
}

void
loongson_isa_specific_eoi(int bit)
{
	if (bit & 8) {
		REGVAL8(BONITO_PCIIO_BASE + IO_ICU2 + PIC_OCW2) =
		    OCW2_SELECT | OCW2_EOI | OCW2_SL | OCW2_ILS(bit & 7);
		bit = 2;
	}
	REGVAL8(BONITO_PCIIO_BASE + IO_ICU1 + PIC_OCW2) =
	    OCW2_SELECT | OCW2_EOI | OCW2_SL | OCW2_ILS(bit);
}

void
loongson_isa_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");
	loongson_isa_setintrmask(newipl);
	/* If we still have softints pending trigger processing. */
	if (ci->ci_softpending != 0 && newipl < IPL_SOFTINT)
		setsoftintr0();
}

void
loongson_isa_setintrmask(int level)
{
	uint64_t active;
	register_t sr;

	active = bonito_intem & ~bonito_imask[level];

	sr = disableintr();
	bonito_setintrmask(level);
	loongson_set_isa_imr(BONITO_ISA_MASK(active));
	setsr(sr);
}

void
loongson_generic_isa_attach_hook(struct device *parent, struct device *self,
    struct isabus_attach_args *iba)
{
	loongson_isaimr = 0;
	/* overrides bonito callback */
	register_splx_handler(loongson_isa_splx);
}


code:
/*	$OpenBSD: locore.S,v 1.5 2013/06/05 01:28:04 pirofti Exp $ */

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

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

#include "assym.h"

	.set	noreorder		# Noreorder is default style!

	.globl	start
	.globl	kernel_text
kernel_text = start
start:
	mfc0    v0, COP_0_STATUS_REG
	li	v1, ~SR_INT_ENAB
	and	v0, v1
	mtc0    v0, COP_0_STATUS_REG    # disable all interrupts

	mtc0	zero, COP_0_CAUSE_REG	# Clear soft interrupts

	/*
	 * Initialize stack and call machine startup.
	 */
	LA	t0, start - FRAMESZ(CF_SZ)
	LA	gp, _gp
	PTR_S	ra, CF_RA_OFFS(t0)		# save pmon return address
	PTR_S	sp, 0(t0)			# and stack
	move	sp, t0
	jal	mips_init			# mips_init(argc, argv, envp,
	nop					#    callvec, esym)

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

	PTR_S	zero, CF_RA_OFFS(sp)		# Zero out old ra for debugger
	move	sp, v0				# switch to new stack
	jal	main				# main(regs)
	move	a0, zero
	PANIC("Startup failed!")

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

#ifdef HIBERNATE

	/* Switch to hibernate resume pagetable */
LEAF(hibernate_activate_resume_pt_machdep, 0)				/* { */
	/* XXX TBD */
	j	ra
END(hibernate_activate_resume_pt_machdep)				/* } */

LEAF(hibernate_switch_stack_machdep, 0)					/* { */
	/* XXX TBD */
	j	ra
END(hibernate_switch_stack_machdep)					/* } */

LEAF(hibernate_resume_machdep, 0)					/* { */
	j	ra
END(hibernate_resume_machdep)					/* } */

#endif /* HIBERNATE */