code:
/*	$OpenBSD: octeonreg.h,v 1.5 2015/07/20 19:44:32 pirofti Exp $	*/

/*
 * Copyright (c) 2003-2004 Opsycon AB (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_OCTEONREG_H_
#define _MACHINE_OCTEONREG_H_

#define OCTEON_CF_BASE		0x1D000800ULL
#define OCTEON_CIU_BASE		0x1070000000000ULL
#define OCTEON_CIU_SIZE		0xC10
#define OCTEON_MIO_BOOT_BASE	0x1180000000000ULL
#define OCTEON_UART0_BASE	0x1180000000800ULL
#define OCTEON_UART1_BASE	0x1180000000C00ULL
#define OCTEON_RNG_BASE		0x1400000000000ULL
#define OCTEON_AMDCF_BASE	0x1dc00000ULL

#define MIO_BOOT_REG_CFG0	0x0
#define MIO_BOOT_REG_CFG(x)	(MIO_BOOT_REG_CFG0+((x)*8))
#define BOOT_CFG_BASE_MASK	0xFFFF
#define BOOT_CFG_BASE_SHIFT	16
#define BOOT_CFG_WIDTH_MASK	0x10000000
#define BOOT_CFG_WIDTH_SHIFT	28

#define CIU_INT_WORKQ0		0
#define CIU_INT_WORKQ1		1
#define CIU_INT_WORKQ2		2
#define CIU_INT_WORKQ3		3
#define CIU_INT_WORKQ4		4
#define CIU_INT_WORKQ5		5
#define CIU_INT_WORKQ6		6
#define CIU_INT_WORKQ7		7
#define CIU_INT_WORKQ8		8
#define CIU_INT_WORKQ9		9
#define CIU_INT_WORKQ10		10
#define CIU_INT_WORKQ11		11
#define CIU_INT_WORKQ12		12
#define CIU_INT_WORKQ13		13
#define CIU_INT_WORKQ14		14
#define CIU_INT_WORKQ15		15
#define CIU_INT_GPIO0		16
#define CIU_INT_GPIO1		17
#define CIU_INT_GPIO2		18
#define CIU_INT_GPIO3		19
#define CIU_INT_GPIO4		20
#define CIU_INT_GPIO5		21
#define CIU_INT_GPIO6		22
#define CIU_INT_GPIO7		23
#define CIU_INT_GPIO8		24
#define CIU_INT_GPIO9		25
#define CIU_INT_GPIO10		26
#define CIU_INT_GPIO11		27
#define CIU_INT_GPIO12		28
#define CIU_INT_GPIO13		29
#define CIU_INT_GPIO14		30
#define CIU_INT_GPIO15		31
#define CIU_INT_MBOX0		32
#define CIU_INT_MBOX1		33
#define CIU_INT_MBOX(x)		(CIU_INT_MBOX0+(x))
#define CIU_INT_UART0		34
#define CIU_INT_UART1		35
#define CIU_INT_PCI_INTA	36
#define CIU_INT_PCI_INTB	37
#define CIU_INT_PCI_INTC	38
#define CIU_INT_PCI_INTD	39
#define CIU_INT_PCI_MSIA	40
#define CIU_INT_PCI_MSIB	41
#define CIU_INT_PCI_MSIC	42
#define CIU_INT_PCI_MSID	43
#define CIU_INT_44		44
#define CIU_INT_TWSI		45
#define CIU_INT_RML		46
#define CIU_INT_TRACE		47
#define CIU_INT_GMX_DRP0	48
#define CIU_INT_GMX_DRP1        49
#define CIU_INT_IPD_DRP		50
#define CIU_INT_KEY_ZERO	51
#define CIU_INT_TIMER0		52
#define CIU_INT_TIMER1		53
#define CIU_INT_TIMER2		54
#define CIU_INT_TIMER3		55
#define CIU_INT_USB		56
#define CIU_INT_PCM		57
#define CIU_INT_MPI		58
#define CIU_INT_TWSI2		59
#define CIU_INT_POWIQ		60
#define CIU_INT_IPDPPTHR	61
#define CIU_INT_MII0		62
#define CIU_INT_BOOTDMA		63

#define CIU_INT0_SUM0		0x00000000
#define CIU_INT1_SUM0		0x00000008
#define CIU_INT2_SUM0		0x00000010
#define CIU_INT3_SUM0		0x00000018
#define CIU_IP2_SUM0(x)		(CIU_INT0_SUM0+(0x10 * (x)))
#define CIU_IP3_SUM0(x)		(CIU_INT1_SUM0+(0x10 * (x)))
#define CIU_INT32_SUM0		0x00000100
#define CIU_INT32_SUM1		0x00000108
#define CIU_INT0_EN0		0x00000200
#define CIU_INT1_EN0		0x00000210
#define CIU_INT2_EN0		0x00000220
#define CIU_INT3_EN0		0x00000230
#define CIU_IP2_EN0(x)		(CIU_INT0_EN0+(0x20 * (x)))
#define CIU_IP3_EN0(x)		(CIU_INT1_EN0+(0x20 * (x)))
#define CIU_INT32_EN0		0x00000400
#define CIU_INT0_EN1		0x00000208
#define CIU_INT1_EN1		0x00000218
#define CIU_INT2_EN1		0x00000228
#define CIU_INT3_EN1		0x00000238
#define CIU_INT32_EN1		0x00000408
#define CIU_IP2_EN1(x)		(CIU_INT0_EN1+(0x20 * (x)))
#define CIU_IP3_EN1(x)		(CIU_INT1_EN1+(0x20 * (x)))
#define CIU_TIM0                0x00000480
#define CIU_TIM1                0x00000488
#define CIU_TIM2                0x00000490
#define CIU_TIM3                0x00000498
#define CIU_WDOG0               0x00000500
#define CIU_WDOG1               0x00000508
#define CIU_PP_POKE0            0x00000580
#define CIU_PP_POKE1            0x00000588
#define CIU_MBOX_SET0           0x00000600
#define CIU_MBOX_SET1           0x00000608
#define CIU_MBOX_SET(x)		(CIU_MBOX_SET0+(0x08 * (x)))
#define CIU_MBOX_CLR0           0x00000680
#define CIU_MBOX_CLR1           0x00000688
#define CIU_MBOX_CLR(x)		(CIU_MBOX_CLR0+(0x08 * (x)))
#define CIU_PP_RST              0x00000700
#define CIU_PP_DBG              0x00000708
#define CIU_GSTOP               0x00000710
#define CIU_NMI                 0x00000718
#define CIU_DINT                0x00000720
#define CIU_FUSE                0x00000728
#define CIU_BIST                0x00000730
#define CIU_SOFT_BIST           0x00000738
#define CIU_SOFT_RST            0x00000740
#define CIU_SOFT_PRST           0x00000748
#define CIU_PCI_INTA            0x00000750
#define CIU_INT0_SUM4           0x00000C00
#define CIU_INT1_SUM4           0x00000C08
#define CIU_INT0_EN4_0          0x00000C80
#define CIU_INT1_EN4_0          0x00000C90
#define CIU_INT0_EN4_1          0x00000C88
#define CIU_INT1_EN4_1          0x00000C98

#define MIO_RST_BOOT		0x1180000001600ULL
#define MIO_RST_BOOT_PNR_MUL_SHIFT	24
#define MIO_RST_BOOT_PNR_MUL_MASK	0x3f
#define OCTEON_IO_REF_CLOCK	50000000	/* 50MHz */

#endif /* !_MACHINE_OCTEONREG_H_ */


code:
/*	$OpenBSD: octeonvar.h,v 1.24 2015/07/20 19:44:32 pirofti Exp $	*/
/*	$NetBSD: maltavar.h,v 1.3 2002/03/18 10:10:16 simonb Exp $	*/

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

#ifndef _MIPS_OCTEON_OCTEONVAR_H_
#define _MIPS_OCTEON_OCTEONVAR_H_

#include <machine/bus.h>

/* XXX elsewhere */
#define	_ASM_PROLOGUE \
		"	.set push			\n" \
		"	.set noreorder			\n"
#define	_ASM_PROLOGUE_MIPS64 \
		_ASM_PROLOGUE				\
		"	.set mips64			\n"
#define	_ASM_PROLOGUE_OCTEON \
		_ASM_PROLOGUE				\
		"	.set arch=octeon		\n"
#define	_ASM_EPILOGUE \
		"	.set pop			\n"
/*
 * subbits = __BITS64_GET(XXX, bits);
 * bits = __BITS64_SET(XXX, subbits);
 */
#ifndef	__BITS64_GET
#define	__BITS64_GET(name, bits)	\
	    (((uint64_t)(bits) & name) >> name##_SHIFT)
#endif
#ifndef	__BITS64_SET
#define	__BITS64_SET(name, subbits)	\
	    (((uint64_t)(subbits) << name##_SHIFT) & name)
#endif

struct octeon_config {
	bus_space_tag_t mc_iobus_bust;
	bus_space_tag_t mc_bootbus_bust;

	bus_dma_tag_t mc_iobus_dmat;
	bus_dma_tag_t mc_bootbus_dmat;
/*
	struct mips_bus_dma_tag mc_core1_dmat;

	struct extent *mc_io_ex;
	struct extent *mc_mem_ex;

	int	mc_mallocsafe;
*/
};

/*
 * FPA map
 */

#define	OCTEON_POOL_NO_PKT	0
#define	OCTEON_POOL_NO_WQE	1
#define	OCTEON_POOL_NO_CMD	2
#define	OCTEON_POOL_NO_SG	3
#define	OCTEON_POOL_NO_XXX_4	4
#define	OCTEON_POOL_NO_XXX_5	5
#define	OCTEON_POOL_NO_XXX_6	6
#define	OCTEON_POOL_NO_DUMP	7	/* FPA debug dump */

#define	OCTEON_POOL_SIZE_PKT	2048	/* 128 x 16 */
#define	OCTEON_POOL_SIZE_WQE	128	/* 128 x 1 */
#define	OCTEON_POOL_SIZE_CMD	1024	/* 128 x 8 */
#define	OCTEON_POOL_SIZE_SG	512	/* 128 x 4 */
#define	OCTEON_POOL_SIZE_XXX_4	0
#define	OCTEON_POOL_SIZE_XXX_5	0
#define	OCTEON_POOL_SIZE_XXX_6	0
#define	OCTEON_POOL_SIZE_XXX_7	0

#define	OCTEON_POOL_NELEMS_PKT		4096
#define	OCTEON_POOL_NELEMS_WQE		4096
#define	OCTEON_POOL_NELEMS_CMD		32
#define	OCTEON_POOL_NELEMS_SG		1024
#define	OCTEON_POOL_NELEMS_XXX_4	0
#define	OCTEON_POOL_NELEMS_XXX_5	0
#define	OCTEON_POOL_NELEMS_XXX_6	0
#define	OCTEON_POOL_NELEMS_XXX_7	0

/*
 * CVMSEG (``scratch'') memory map
 */
struct octeon_cvmseg_map {
	/* 0-3 */
	uint64_t		csm_xxx_0;
	uint64_t		csm_xxx_1;
	uint64_t		csm_xxx_2;
	uint64_t		csm_pow_intr;

	/* 4-19 */
	struct octeon_cvmseg_ether_map {
		uint64_t	csm_ether_fau_req;
		uint64_t	csm_ether_fau_done;
		uint64_t	csm_ether_fau_cmdptr;
		uint64_t	csm_ether_xxx_3;
	} csm_ether[4/* XXX */];

	/* 20-32 */
	uint64_t	xxx_20_32[32 - 20];
} __packed;
#define	OCTEON_CVMSEG_OFFSET(entry) \
	offsetof(struct octeon_cvmseg_map, entry)
#define	OCTEON_CVMSEG_ETHER_OFFSET(n, entry) \
	(offsetof(struct octeon_cvmseg_map, csm_ether) + \
	 sizeof(struct octeon_cvmseg_ether_map) * (n) + \
	 offsetof(struct octeon_cvmseg_ether_map, entry))

/*
 * FAU register map
 *
 * => FAU registers exist in FAU unit
 * => devices (PKO) can access these registers
 * => CPU can read those values after loading them into CVMSEG
 */
struct octeon_fau_map {
	struct {
		/* PKO command index */
		uint64_t	_fau_map_port_pkocmdidx;
		/* send requested */
		uint64_t	_fau_map_port_txreq;
		/* send completed */
		uint64_t	_fau_map_port_txdone;
		/* XXX */
		uint64_t	_fau_map_port_pad;
	} __packed _fau_map_port[3];
};

/*
 * POW qos/group map
 */

#define	OCTEON_POW_QOS_PIP		0
#define	OCTEON_POW_QOS_CORE1		1
#define	OCTEON_POW_QOS_XXX_2		2
#define	OCTEON_POW_QOS_XXX_3		3
#define	OCTEON_POW_QOS_XXX_4		4
#define	OCTEON_POW_QOS_XXX_5		5
#define	OCTEON_POW_QOS_XXX_6		6
#define	OCTEON_POW_QOS_XXX_7		7

#define	OCTEON_POW_GROUP_PIP		0
#define	OCTEON_POW_GROUP_XXX_1		1
#define	OCTEON_POW_GROUP_XXX_2		2
#define	OCTEON_POW_GROUP_XXX_3		3
#define	OCTEON_POW_GROUP_XXX_4		4
#define	OCTEON_POW_GROUP_XXX_5		5
#define	OCTEON_POW_GROUP_XXX_6		6
#define	OCTEON_POW_GROUP_CORE1_SEND	7
#define	OCTEON_POW_GROUP_CORE1_TASK_0	8
#define	OCTEON_POW_GROUP_CORE1_TASK_1	9
#define	OCTEON_POW_GROUP_CORE1_TASK_2	10
#define	OCTEON_POW_GROUP_CORE1_TASK_3	11
#define	OCTEON_POW_GROUP_CORE1_TASK_4	12
#define	OCTEON_POW_GROUP_CORE1_TASK_5	13
#define	OCTEON_POW_GROUP_CORE1_TASK_6	14
#define	OCTEON_POW_GROUP_CORE1_TASK_7	15

/*
 * Octeon board types known to work with OpenBSD/octeon.
 * NB: BOARD_TYPE_UBIQUITI_E100 is also used by other vendors, but we don't run
 * on those boards yet.
 */
#define	BOARD_TYPE_UBIQUITI_E100	20002
#define	BOARD_TYPE_UBIQUITI_E200	20003
#define	BOARD_TYPE_DSR_500		20015

#if defined(_KERNEL) || defined(_STANDALONE)
#define OCTEON_ARGV_MAX 64

/* Maximum number of cores on <= CN52XX */
#define OCTEON_MAXCPUS	4

struct boot_desc {
	uint32_t	desc_ver;
	uint32_t	desc_size;
	uint64_t	stack_top;
	uint64_t 	heap_start;
	uint64_t	heap_end;
	uint64_t      	__unused17;
	uint64_t     	__unused16;
	uint32_t      	__unused18;
	uint32_t      	__unused15;
	uint32_t      	__unused14;
	uint32_t	argc;
	uint32_t	argv[OCTEON_ARGV_MAX];
	uint32_t	flags;
	uint32_t	core_mask;
	uint32_t	dram_size;
	uint32_t	phy_mem_desc_addr;
	uint32_t	debugger_flag_addr;
	uint32_t	eclock;
	uint32_t      	__unused10;
	uint32_t      	__unused9;
	uint16_t      	__unused8;
	uint8_t 	__unused7;
	uint8_t 	__unused6;
	uint16_t 	__unused5;
	uint8_t 	__unused4;
	uint8_t 	__unused3;
	uint8_t 	__unused2[20];
	uint8_t 	__unused1[6];
	uint8_t 	__unused0;
	uint64_t 	boot_info_addr;
};

struct boot_info {
	uint32_t ver_major;
	uint32_t ver_minor;
	uint64_t stack_top;
	uint64_t heap_start;
	uint64_t heap_end;
	uint64_t boot_desc_addr;
	uint32_t exception_base_addr;
	uint32_t stack_size;
	uint32_t flags;
	uint32_t core_mask;
	uint32_t dram_size;
	uint32_t phys_mem_desc_addr;
	uint32_t debugger_flags_addr;
	uint32_t eclock;
	uint32_t dclock;
	uint32_t __unused0;
	uint16_t board_type;
	uint8_t board_rev_major;
	uint8_t board_rev_minor;
	uint16_t __unused1;
	uint8_t __unused2;
	uint8_t __unused3;
	char board_serial[20];
	uint8_t mac_addr_base[6];
	uint8_t mac_addr_count;
	uint64_t cf_common_addr;
	uint64_t cf_attr_addr;
	uint64_t led_display_addr;
	uint32_t dfaclock;
	uint32_t config_flags;
};

extern struct boot_desc *octeon_boot_desc;
extern struct boot_info *octeon_boot_info;

#ifdef _KERNEL
/* Device capabilities advertised in boot_info->config_flags */
#define BOOTINFO_CFG_FLAG_PCI_HOST	(1ull << 0)
#define BOOTINFO_CFG_FLAG_PCI_TARGET	(1ull << 1)
#define BOOTINFO_CFG_FLAG_DEBUG		(1ull << 2)
#define BOOTINFO_CFG_FLAG_NO_MAGIC	(1ull << 3)

void	octeon_bus_io_init(bus_space_tag_t, void *);
void	octeon_bus_mem_init(bus_space_tag_t, void *);
void	octeon_cal_timer(int);
void	octeon_dma_init(struct octeon_config *);
void	octeon_intr_init(void);
int	octeon_get_ethaddr(int, u_int8_t *);

int	octeon_ioclock_speed(void);

#endif /* _KERNEL */
#endif /* _KERNEL || _STANDALONE */

static inline int
ffs64(uint64_t val)
{
	int ret;

	__asm volatile ( \
		_ASM_PROLOGUE_MIPS64
		"	dclz	%0, %1			\n"
		_ASM_EPILOGUE
		: "=r"(ret) : "r"(val));
	return 64 - ret;
}

static inline int
ffs32(uint32_t val)
{
	int ret;

	__asm __volatile ( \
		_ASM_PROLOGUE_MIPS64
		"	clz	%0, %1			\n"
		_ASM_EPILOGUE
		: "=r"(ret) : "r"(val));
	return 32 - ret;
}

static inline uint64_t
octeon_xkphys_read_8(paddr_t address)
{
	volatile uint64_t *p =
	    (volatile uint64_t *)(PHYS_TO_XKPHYS(address, CCA_NC));
	return (*p);
}

#define	MIO_BOOT_BIST_STAT			0x00011800000000f8ULL
static inline void
octeon_xkphys_write_8(paddr_t address, uint64_t value)
{
	*(volatile uint64_t *)(PHYS_TO_XKPHYS(address, CCA_NC)) = value;

	/*
	 * It seems an immediate read is necessary when doing a write to an RSL
	 * register in order to complete the write.
	 * We use MIO_BOOT_BIST_STAT because it's apparently the fastest
	 * write.
	 */

	/*
	 * XXX
	 * This if would be better writen as:
	 * if ((address & 0xffffff0000000000ULL) == OCTEON_MIO_BOOT_BASE) {
	 * but octeonreg.h can't be included here and we want this inlined
	 *
	 * Note that the SDK masks with 0x7ffff but that doesn't make sense.
	 * This is a physical address.
	 */
	if (((address >> 40) & 0xfffff) == (0x118)) {
		value = *(volatile uint64_t *)
		    (PHYS_TO_XKPHYS(MIO_BOOT_BIST_STAT, CCA_NC));
	}
}

static inline void
octeon_iobdma_write_8(uint64_t value)
{
	uint64_t addr = 0xffffffffffffa200ULL;

	*(volatile uint64_t *)addr = value;
}

static inline uint64_t
octeon_cvmseg_read_8(size_t offset)
{
	return octeon_xkphys_read_8(0xffffffffffff8000ULL + offset);
}

static inline void
octeon_cvmseg_write_8(size_t offset, uint64_t value)
{
	octeon_xkphys_write_8(0xffffffffffff8000ULL + offset, value);
}

/* XXX */
static inline uint32_t
octeon_disable_interrupt(uint32_t *new)
{
	uint32_t s, tmp;

	__asm volatile (
		_ASM_PROLOGUE
		"	mfc0	%[s], $12		\n"
		"	and	%[tmp], %[s], ~1	\n"
		"	mtc0	%[tmp], $12		\n"
		_ASM_EPILOGUE
		: [s]"=&r"(s), [tmp]"=&r"(tmp));
	if (new)
		*new = tmp;
	return s;
}

/* XXX */
static inline void
octeon_restore_status(uint32_t s)
{
	__asm volatile (
		_ASM_PROLOGUE
		"	mtc0	%[s], $12		\n"
		_ASM_EPILOGUE
		:: [s]"r"(s));
}

static inline uint64_t
octeon_get_cycles(void)
{
	uint64_t tmp;

	__asm volatile (
		_ASM_PROLOGUE_MIPS64
		"	dmfc0	%[tmp], $9, 6		\n"
		_ASM_EPILOGUE
		: [tmp]"=&r"(tmp));
	return tmp;
}

#endif	/* _MIPS_OCTEON_OCTEONVAR_H_ */

license: unknown


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

/* Public Domain */

#ifndef	_MACHINE_PARAM_H_
#define	_MACHINE_PARAM_H_

#define	MACHINE		"octeon"
#define	_MACHINE	octeon
#define	MACHINE_ARCH	"mips64"
#define	_MACHINE_ARCH	mips64
#define	MID_MACHINE	MID_MIPS64

#define	PAGE_SHIFT	14

#include <mips64/param.h>

#endif /* _MACHINE_PARAM_H_ */


code:
/* $OpenBSD: pcb.h,v 1.1 2010/09/20 06:32:30 syuu Exp $ */
/* public domain */
#include <mips64/pcb.h>


code:
/*	$OpenBSD: pci_machdep.h,v 1.7 2013/11/05 10:12:35 mpi 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.
 *
 */
#include <sys/systm.h>

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 DEBUG_PCI_CONF

#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))
#ifdef DEBUG_PCI_CONF
static inline pcireg_t pci_conf_read_db(void * c, pcitag_t t, int r,
				     char* f,char* func,int l)
{
  pcireg_t v;
  struct mips_pci_chipset *pc = c;
  v = (*(pc)->pc_conf_read)(pc->pc_conf_v, t, r);
  printf("%s:%s:%d:pci_conf_read(%x,%x) = %x\n",f,func,l,t,r,v);
  return v;
}

static inline void pci_conf_write_db(void * c, pcitag_t t, int r, pcireg_t v,
				     char* f,char* func,int l)
{
  struct mips_pci_chipset *pc = c;
  printf("%s:%s:%d:pci_conf_write(%x,%x,%x)\n",f,func,l,t,r,v);
  (*(pc)->pc_conf_write)(pc->pc_conf_v, t, r, v);
}

#define	pci_conf_read(c, t, r) pci_conf_read_db(c, t, r,__FILE__,__FUNCTION__,__LINE__)
#define	pci_conf_write(c, t, r, v) pci_conf_write_db(c, t, r, v,__FILE__,__FUNCTION__,__LINE__)
#else
#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))
#endif
#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)

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

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

#define	pci_dev_postattach(a, b)


code:
/* $OpenBSD: pmap.h,v 1.1 2010/09/20 06:32:30 syuu Exp $ */
/* public domain */
#include <mips64/pmap.h>


code:
/* $OpenBSD: proc.h,v 1.1 2010/09/20 06:32:30 syuu Exp $ */
/* public domain */
#include <mips64/proc.h>


code:
/* $OpenBSD: profile.h,v 1.1 2010/09/20 06:32:30 syuu Exp $ */
/* public domain */
#include <mips64/profile.h>


code:
/* $OpenBSD: pte.h,v 1.1 2010/09/20 06:32:30 syuu Exp $ */
/* public domain */
#include <mips64/pte.h>


code:
/* $OpenBSD: ptrace.h,v 1.1 2010/09/20 06:32:30 syuu Exp $ */
/* public domain */
#include <mips64/ptrace.h>


code:
/* $OpenBSD: reg.h,v 1.1 2010/09/20 06:32:30 syuu Exp $ */
/* public domain */
#include <mips64/reg.h>


code:
/* $OpenBSD: regdef.h,v 1.1 2010/09/20 06:32:30 syuu Exp $ */
/* public domain */
#include <mips64/regdef.h>


code:
/* $OpenBSD: regnum.h,v 1.1 2010/09/20 06:32:30 syuu Exp $ */
/* public domain */
#include <mips64/regnum.h>


code:
/* $OpenBSD: setjmp.h,v 1.1 2010/09/20 06:32:30 syuu Exp $ */
/* public domain */
#include <mips64/setjmp.h>


code:
/* $OpenBSD: signal.h,v 1.1 2010/09/20 06:32:30 syuu Exp $ */
/* public domain */
#include <mips64/signal.h>


code:
/* $OpenBSD: spinlock.h,v 1.1 2010/09/20 06:32:30 syuu Exp $ */
/* public domain */
#include <mips64/spinlock.h>


code:
/* $OpenBSD: stdarg.h,v 1.1 2010/09/20 06:32:30 syuu Exp $ */
/* public domain */
#include <mips64/stdarg.h>


code:
/*	$OpenBSD: sysarch.h,v 1.1 2010/09/20 06:32:30 syuu 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 2010/09/20 06:32:30 syuu Exp $ */
/* public domain */
#include <mips64/trap.h>


code:
/* $OpenBSD: varargs.h,v 1.1 2010/09/20 06:32:30 syuu Exp $ */
/* public domain */
#include <mips64/varargs.h>


code:
/*	$OpenBSD: vmparam.h,v 1.2 2014/08/12 19:35:28 miod Exp $ */
/* public domain */
#ifndef _MACHINE_VMPARAM_H_
#define _MACHINE_VMPARAM_H_

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

#include <mips64/vmparam.h>

#endif	/* _MACHINE_VMPARAM_H_ */


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


code: src/sys/arch/octeon/octeon

path: sys/arch/octeon/octeon/CVS/Repository


code:
/*	$OpenBSD: autoconf.c,v 1.7 2015/07/20 19:44:32 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 <machine/autoconf.h>

extern void dumpconf(void);
void parse_uboot_root(void);

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

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

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

	splinit();
	cold = 0;
}

void
parse_uboot_root(void)
{
	char *p;
	size_t len;

        /*
         * Turn the U-Boot root device (rootdev=/dev/octcf0) into a boot device.
         */
        p = strrchr(uboot_rootdev, '/');
        if (p == NULL)
                return;
	p++;

	len = strlen(p);
	if (len <= 2 || len >= sizeof bootdev - 1)
		return;

	memcpy(bootdev, p, len);
	bootdev[len] = '\0';
	bootdev_class = DV_DISK;
}

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

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

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

	const char *drvrname = dev->dv_cfdata->cf_driver->cd_name;
	const char *name = dev->dv_xname;

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

	switch (bootdev_class) {
	case DV_DISK:
		if ((strcmp(drvrname, "wd") == 0 ||
		    strcmp(drvrname, "sd") == 0 ||
		    strcmp(drvrname, "octcf") == 0 ||
		    strcmp(drvrname, "amdcf") == 0) &&
		    strcmp(name, bootdev) == 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;
	}
}

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


code:
/*	$OpenBSD: bus_dma.c,v 1.14 2014/11/16 12:30:58 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;
	struct cpu_info *ci = curcpu();

	nsegs = map->dm_nsegs;
	curseg = 0;

	while (size && nsegs) {
		paddr_t paddr;
		vaddr_t vaddr;
		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)
					Mips_IOSyncDCache(ci, vaddr,
					    ssize, CACHE_SYNC_X);
				else
					Mips_IOSyncDCache(ci, vaddr,
					    ssize, CACHE_SYNC_W);
			} else
			if (op & (BUS_DMASYNC_PREREAD | BUS_DMASYNC_POSTREAD)) {
				Mips_IOSyncDCache(ci, vaddr,
				    ssize, CACHE_SYNC_R);
			}
			size -= ssize;
		}
		curseg++;
		nsegs--;
	}

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

/*
 * 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: conf.c,v 1.15 2015/07/20 19:44:32 pirofti Exp $ */

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

#define NOCTCF 1
bdev_decl(octcf);

#define NAMDCF 1
bdev_decl(amdcf);

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_disk_init(NOCTCF,octcf),	/* 15: CF disk */
	bdev_notdef(),			/* 16:  */
	bdev_notdef(),			/* 17:  */
	bdev_notdef(),			/* 18:  */
	bdev_disk_init(NAMDCF,amdcf),	/* 19: CF disk */
};

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"
#if 0
#include "apm.h"
#endif
#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"
cdev_decl(octcf);
cdev_decl(amdcf);

#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 */
#if 0
	cdev_apm_init(NAPM,apm),	/* 14: apm */
#else
	cdev_notdef(),			/* 14: */
#endif
	cdev_disk_init(NOCTCF,octcf),	/* 15: CF disk */
	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_disk_init(NAMDCF,amdcf),	/* 19: CF disk */
	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(),			/* 43: */
	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_fuse_init(NFUSE,fuse),	/* 53: fuse */
	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(),			/* 68: */
	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 */
};

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 */	15,		/* octcf */
	/* 16 */	NODEV,
	/* 17 */	NODEV,
	/* 18 */	4,		/* wd */
	/* 19 */	19,		/* amdcf */
	/* 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: lock_machdep.c,v 1.7 2015/07/21 16:17:15 visa Exp $	*/

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

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

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

#include <ddb/db_output.h>

void
__mp_lock_init(struct __mp_lock *lock)
{
	lock->mpl_cpu = NULL;
	lock->mpl_count = 0;
}

#if defined(MP_LOCKDEBUG)
#ifndef DDB
#error "MP_LOCKDEBUG requires DDB"
#endif

/* CPU-dependent timing, needs this to be settable from ddb. */
extern int __mp_lock_spinout;
#endif

#define SPINLOCK_SPIN_HOOK	/**/

static __inline void
__mp_lock_spin(struct __mp_lock *mpl)
{
#ifndef MP_LOCKDEBUG
	while (mpl->mpl_count != 0)
		SPINLOCK_SPIN_HOOK;
#else
	int ticks = __mp_lock_spinout;

	while (mpl->mpl_count != 0 && --ticks > 0)
		SPINLOCK_SPIN_HOOK;

	if (ticks == 0) {
		db_printf("__mp_lock(%p): lock spun out", mpl);
		Debugger();
	}
#endif
}

void
__mp_lock(struct __mp_lock *mpl)
{
	register_t sr;
	struct cpu_info *ci = curcpu();

	/*
	 * Please notice that mpl_count gets incremented twice for the
	 * first lock. This is on purpose. The way we release the lock
	 * in mp_unlock is to decrement the mpl_count and then check if
	 * the lock should be released. Since mpl_count is what we're
	 * spinning on, decrementing it in mpl_unlock to 0 means that
	 * we can't clear mpl_cpu, because we're no longer holding the
	 * lock. In theory mpl_cpu doesn't need to be cleared, but it's
	 * safer to clear it and besides, setting mpl_count to 2 on the
	 * first lock makes most of this code much simpler.
	 */
	while (1) {
		sr = disableintr();
		if (__cpu_cas(&mpl->mpl_count, 0, 1) == 0) {
			mips_sync();
			mpl->mpl_cpu = ci;
		}

		if (mpl->mpl_cpu == ci) {
			mpl->mpl_count++;
			setsr(sr);
			break;
		}
		setsr(sr);

		__mp_lock_spin(mpl);
	}
}

void
__mp_unlock(struct __mp_lock *mpl)
{
	register_t sr;

#ifdef MP_LOCKDEBUG
	if (mpl->mpl_cpu != curcpu()) {
		db_printf("__mp_unlock(%p): not held lock\n", mpl);
		Debugger();
	}
#endif

	sr = disableintr();
	if (--mpl->mpl_count == 1) {
		mpl->mpl_cpu = NULL;
		mips_sync();
		mpl->mpl_count = 0;
	}

	setsr(sr);
}

int
__mp_release_all(struct __mp_lock *mpl)
{
	int rv = mpl->mpl_count - 1;
	register_t sr;

#ifdef MP_LOCKDEBUG
	if (mpl->mpl_cpu != curcpu()) {
		db_printf("__mp_release_all(%p): not held lock\n", mpl);
		Debugger();
	}
#endif

	sr = disableintr();
	mpl->mpl_cpu = NULL;
	mips_sync();
	mpl->mpl_count = 0;
	setsr(sr);

	return (rv);
}

int
__mp_release_all_but_one(struct __mp_lock *mpl)
{
	int rv = mpl->mpl_count - 2;
#ifdef MP_LOCKDEBUG
	if (mpl->mpl_cpu != curcpu()) {
		db_printf("__mp_release_all_but_one(%p): not held lock\n", mpl);
		Debugger();
	}
#endif

	mpl->mpl_count = 2;

	return (rv);
}

void
__mp_acquire_count(struct __mp_lock *mpl, int count)
{
	while (count--)
		__mp_lock(mpl);
}

int
__mp_lock_held(struct __mp_lock *mpl)
{
	return mpl->mpl_cpu == curcpu();
}


code:
/*	$OpenBSD: locore.S,v 1.6 2014/03/13 02:17:13 yasuoka 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 <octeon/dev/cn30xxcorereg.h>

#include "assym.h"

	.set	noreorder		# Noreorder is default style!
	.set	mips64r2
	.globl	start
	.globl	kernel_text
kernel_text = start
start:
/* initialize ebase */
	dla	t0, 0xffffffff80000000
	mtc0	t0, COP_0_EBASE

/* initialize cvmctl */
	dli     t0, COP_0_CVMCTL_FUSE_START_BIT|COP_0_CVMCTL_NOFDA_CP2|\
		    COP_0_CVMCTL_IPPCI|COP_0_CVMCTL_IPTI
	dmtc0	t0, COP_0_CVMCTL

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

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

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

	mtc0	zero, COP_0_CAUSE_REG	# Clear soft interrupts

	LA	gp, _gp

#if defined(MULTIPROCESSOR)
	rdhwr	t2, $0
	beqz	t2, 2f
	nop
1:	ll	t0, cpu_spinup_mask
	bne	t2, t0, 1b
	nop
	move	t0, zero
	sc	t0, cpu_spinup_mask
	beqz	t0, 1b
	nop
	j	hw_cpu_spinup_trampoline
	nop
2:
#endif
	/*
	 * Initialize stack and call machine startup.
	 */
	LA	t0, start - FRAMESZ(CF_SZ)
	PTR_S	ra, CF_RA_OFFS(t0)		# save uboot return address
	PTR_S	sp, 0(t0)			# and stack
	move	sp, t0
	jal	mips_init			# mips_init(argc, argv, envp,
	nop					#    callvec, esym)

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

	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

LEAF(get_cvmctl, 0)
	.set push
	.set mips64r2
	dmfc0	v0, $9, 7
	jr	ra
	nop
END(get_cvmctl)

LEAF(get_cvmmemctl, 0)
	.set push
	.set mips64r2
	dmfc0	v0, $11, 7
	jr	ra
	nop
END(get_cvmmemctl)

#if defined(MULTIPROCESSOR)
LEAF(hw_cpu_spinup_trampoline, 0)
	LA	t0, cpu_spinup_a0
	ld	a0, 0(t0)
	LA	t0, cpu_spinup_sp
	ld	sp, 0(t0)
	jal	hw_cpu_hatch
	nop
END(hw_cpu_spinup_trampoline)

LEAF(hw_getcurcpu, 0)
	GET_CPU_INFO(v0, v1)
	jr	ra
	nop
END(hw_getcurcpu)

LEAF(hw_setcurcpu, 0)
	dmtc0	a0, COP_0_ERROR_PC
	j	ra
	nop
END(hw_setcurcpu)
#endif /* MULTIPROCESSOR */


code:
/*	$OpenBSD: machdep.c,v 1.67 2015/07/19 16:48:38 visa Exp $ */

/*
 * Copyright (c) 2009, 2010 Miodrag Vallat.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
/*
 * Copyright (c) 2003-2004 Opsycon AB  (www.opsycon.se / www.opsycon.com)
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/buf.h>
#include <sys/reboot.h>
#include <sys/conf.h>
#include <sys/file.h>
#include <sys/msgbuf.h>
#include <sys/tty.h>
#include <sys/user.h>
#include <sys/exec.h>
#include <sys/sysctl.h>
#include <sys/mount.h>
#include <sys/syscallargs.h>
#include <sys/exec_elf.h>
#ifdef SYSVSHM
#include <sys/shm.h>
#endif
#ifdef SYSVSEM
#include <sys/sem.h>
#endif

#include <net/if.h>

#include <uvm/uvm_extern.h>

#include <machine/db_machdep.h>
#include <ddb/db_interface.h>

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

#include <dev/cons.h>

#include <octeon/dev/iobusvar.h>
#include <machine/octeonreg.h>
#include <machine/octeonvar.h>
#include <machine/octeon_model.h>

/* The following is used externally (sysctl_hw) */
char	machine[] = MACHINE;		/* Machine "architecture" */
char	cpu_model[64];

struct uvm_constraint_range  dma_constraint = { 0x0, 0xffffffffUL };
struct uvm_constraint_range *uvm_md_constraints[] = { NULL };

vm_map_t exec_map;
vm_map_t phys_map;

struct boot_desc *octeon_boot_desc;
struct boot_info *octeon_boot_info;

char uboot_rootdev[OCTEON_ARGV_MAX];

/*
 * safepri is a safe priority for sleep to set for a spin-wait
 * during autoconfiguration or after a panic.
 */
int   safepri = 0;

caddr_t	msgbufbase;

int	physmem;		/* Max supported memory, changes to actual. */
int	ncpu = 1;		/* At least one CPU in the system. */
struct	user *proc0paddr;

struct cpu_hwinfo bootcpu_hwinfo;

/* Pointers to the start and end of the symbol table. */
caddr_t	ssym;
caddr_t	esym;
caddr_t	ekern;

struct phys_mem_desc mem_layout[MAXMEMSEGS];

void		dumpsys(void);
void		dumpconf(void);
vaddr_t		mips_init(__register_t, __register_t, __register_t, __register_t);
boolean_t 	is_memory_range(paddr_t, psize_t, psize_t);
void		octeon_memory_init(struct boot_info *);
int		octeon_cpuspeed(int *);
static void	process_bootargs(void);
static uint64_t	get_ncpusfound(void);

#ifdef MULTIPROCESSOR
uint32_t	ipi_intr(uint32_t, struct trap_frame *);
#endif

extern void 	parse_uboot_root(void);

cons_decl(cn30xxuart);
struct consdev uartcons = cons_init(cn30xxuart);

#define btoc(x) (((x)+PAGE_MASK)>>PAGE_SHIFT)

#define OCTEON_DRAM_FIRST_256_END	0xfffffffull

void
octeon_memory_init(struct boot_info *boot_info)
{
	uint64_t phys_avail[10 + 2] = {0,};
	uint64_t startpfn, endpfn;
	uint32_t realmem;
	extern char end[];
	int i;
	uint32_t realmem_bytes;

	startpfn = atop(CKSEG0_TO_PHYS((vaddr_t)&end) + PAGE_SIZE);
	endpfn = atop(96 << 20);
	mem_layout[0].mem_first_page = startpfn;
	mem_layout[0].mem_last_page = endpfn;

	physmem = endpfn - startpfn;

	realmem_bytes = ((boot_info->dram_size << 20) - PAGE_SIZE);
	realmem_bytes &= ~(PAGE_SIZE - 1);

	/* phys_avail regions are in bytes */
	phys_avail[0] =
	    (CKSEG0_TO_PHYS((uint64_t)&end) + PAGE_SIZE) & ~(PAGE_SIZE - 1);

	if (realmem_bytes > OCTEON_DRAM_FIRST_256_END) {
		phys_avail[1] = OCTEON_DRAM_FIRST_256_END;
		realmem_bytes -= OCTEON_DRAM_FIRST_256_END;
		realmem_bytes &= ~(PAGE_SIZE - 1);
	} else
		phys_avail[1] = realmem_bytes;

	mem_layout[0].mem_last_page = atop(phys_avail[1]);

	/*-
	 * Octeon Memory looks as follows:
         *   PA
	 * First 256 MB DR0
	 * 0000 0000 0000 0000     to  0000 0000 0FFF FFFF
	 * Second 256 MB DR1
	 * 0000 0004 1000 0000     to  0000 0004 1FFF FFFF
	 * Over 512MB Memory DR2  15.5GB
	 * 0000 0000 2000 0000     to  0000 0003 FFFF FFFF
	 */
	physmem = atop(phys_avail[1] - phys_avail[0]);

	if (realmem_bytes > OCTEON_DRAM_FIRST_256_END) {
		/* take out the upper non-cached 1/2 */
		phys_avail[2] = 0x410000000ULL;
		phys_avail[3] =
		    (0x410000000ULL + OCTEON_DRAM_FIRST_256_END);
		physmem += btoc(phys_avail[3] - phys_avail[2]);
		mem_layout[2].mem_first_page = atop(phys_avail[2]);
		mem_layout[2].mem_last_page = atop(phys_avail[3] - 1);
		realmem_bytes -= OCTEON_DRAM_FIRST_256_END;

		/* Now map the rest of the memory */
		phys_avail[4] = 0x20000000ULL;
		phys_avail[5] = (0x20000000ULL + realmem_bytes);
		physmem += btoc(phys_avail[5] - phys_avail[4]);
		mem_layout[1].mem_first_page = atop(phys_avail[4]);
		mem_layout[1].mem_last_page = atop(phys_avail[5] - 1);
		realmem_bytes = 0;
	}

 	realmem = physmem;

	printf("Total DRAM Size 0x%016X\n",
	    (uint32_t)(boot_info->dram_size << 20));

	for (i = 0; phys_avail[i]; i += 2) {
		printf("Bank %d = 0x%016lX   ->  0x%016lX\n", i >> 1,
		    (long)phys_avail[i], (long)phys_avail[i + 1]);
	}
	for (i = 0; mem_layout[i].mem_last_page; i++) {
		printf("mem_layout[%d] page 0x%016llX -> 0x%016llX\n", i,
		    mem_layout[i].mem_first_page, mem_layout[i].mem_last_page);
	}
}

/*
 * Do all the stuff that locore normally does before calling main().
 * Reset mapping and set up mapping to hardware and init "wired" reg.
 */
vaddr_t
mips_init(__register_t a0, __register_t a1, __register_t a2 __unused,
	__register_t a3)
{
	uint prid;
	vaddr_t xtlb_handler;
	int i;
	struct boot_desc *boot_desc;
	struct boot_info *boot_info;

	extern char start[], edata[], end[];
	extern char exception[], e_exception[];
	extern void xtlb_miss;

	boot_desc = (struct boot_desc *)a3;
	boot_info = (struct boot_info *)
	    PHYS_TO_XKPHYS(boot_desc->boot_info_addr, CCA_CACHED);

#ifdef MULTIPROCESSOR
	/*
	 * Set curcpu address on primary processor.
	 */
	setcurcpu(&cpu_info_primary);
#endif
	/*
	 * Clear the compiled BSS segment in OpenBSD code.
	 */

	bzero(edata, end - edata);

	/*
	 * Set up early console output.
	 */
	cn_tab = &uartcons;

	/*
	 * Reserve space for the symbol table, if it exists.
	 */
	ssym = (char *)(vaddr_t)*(int32_t *)end;
	if (((long)ssym - (long)end) >= 0 &&
	    ((long)ssym - (long)end) <= 0x1000 &&
	    ssym[0] == ELFMAG0 && ssym[1] == ELFMAG1 &&
	    ssym[2] == ELFMAG2 && ssym[3] == ELFMAG3) {
		/* Pointers exist directly after kernel. */
		esym = (char *)(vaddr_t)*((int32_t *)end + 1);
		ekern = esym;
	} else {
		/* Pointers aren't setup either... */
		ssym = NULL;
		esym = NULL;
		ekern = end;
	}

	prid = cp0_get_prid();

	bootcpu_hwinfo.clock = boot_desc->eclock;

	/*
	 * Look at arguments passed to us and compute boothowto.
	 */
	boothowto = RB_AUTOBOOT;

	octeon_memory_init(boot_info);

	/*
	 * Set pagesize to enable use of page macros and functions.
	 * Commit available memory to UVM system.
	 */

	uvmexp.pagesize = PAGE_SIZE;
	uvm_setpagesize();

	for (i = 0; i < MAXMEMSEGS && mem_layout[i].mem_last_page != 0; i++) {
		uint64_t fp, lp;
		uint64_t firstkernpage, lastkernpage;
		paddr_t firstkernpa, lastkernpa;

		/* kernel is linked in CKSEG0 */
		firstkernpa = CKSEG0_TO_PHYS((vaddr_t)start);
		lastkernpa = CKSEG0_TO_PHYS((vaddr_t)ekern);

		firstkernpage = atop(trunc_page(firstkernpa));
		lastkernpage = atop(round_page(lastkernpa));

		fp = mem_layout[i].mem_first_page;
		lp = mem_layout[i].mem_last_page;

		/* Account for kernel and kernel symbol table. */
		if (fp >= firstkernpage && lp < lastkernpage)
			continue;	/* In kernel. */

		if (lp < firstkernpage || fp > lastkernpage) {
			uvm_page_physload(fp, lp, fp, lp, 0);
			continue;	/* Outside kernel. */
		}

		if (fp >= firstkernpage)
			fp = lastkernpage;
		else if (lp < lastkernpage)
			lp = firstkernpage;
		else { /* Need to split! */
			uint64_t xp = firstkernpage;
			uvm_page_physload(fp, xp, fp, xp, 0);
			fp = lastkernpage;
		}
		if (lp > fp) {
			uvm_page_physload(fp, lp, fp, lp, 0);
		}
	}

	bootcpu_hwinfo.c0prid = prid;
	bootcpu_hwinfo.type = (prid >> 8) & 0xff;
	bootcpu_hwinfo.c1prid = 0;	/* No FPU */
	bootcpu_hwinfo.tlbsize = 1 + ((cp0_get_config_1() >> 25) & 0x3f);
	bcopy(&bootcpu_hwinfo, &curcpu()->ci_hw, sizeof(struct cpu_hwinfo));

	/*
	 * Configure cache.
	 */

	Octeon_ConfigCache(curcpu());
	Octeon_SyncCache(curcpu());

	tlb_init(bootcpu_hwinfo.tlbsize);

	/*
	 * Save the the boot information for future reference since we can't
	 * retrieve it anymore after we've fully bootstrapped the kernel.
	 */

	bcopy(&boot_info, &octeon_boot_info, sizeof(octeon_boot_info));
	bcopy(&boot_desc, &octeon_boot_desc, sizeof(octeon_boot_desc));

	snprintf(cpu_model, sizeof(cpu_model), "Cavium OCTEON (rev %d.%d) @ %d MHz",
		 (bootcpu_hwinfo.c0prid >> 4) & 0x0f,
		 bootcpu_hwinfo.c0prid & 0x0f,
		 bootcpu_hwinfo.clock / 1000000);

	cpu_cpuspeed = octeon_cpuspeed;

	ncpusfound = get_ncpusfound();

	process_bootargs();

	/*
	 * Get a console, very early but after initial mapping setup.
	 */

	consinit();
	printf("Initial setup done, switching console.\n");

#define DEBUG
#ifdef DEBUG
#define DUMP_BOOT_DESC(field, format) \
	printf("boot_desc->" #field ":" #format "\n", boot_desc->field)
#define DUMP_BOOT_INFO(field, format) \
	printf("boot_info->" #field ":" #format "\n", boot_info->field)

	DUMP_BOOT_DESC(desc_ver, %d);
	DUMP_BOOT_DESC(desc_size, %d);
	DUMP_BOOT_DESC(stack_top, %llx);
	DUMP_BOOT_DESC(heap_start, %llx);
	DUMP_BOOT_DESC(heap_end, %llx);
	DUMP_BOOT_DESC(argc, %d);
	DUMP_BOOT_DESC(flags, %#x);
	DUMP_BOOT_DESC(core_mask, %#x);
	DUMP_BOOT_DESC(dram_size, %d);
	DUMP_BOOT_DESC(phy_mem_desc_addr, %#x);
	DUMP_BOOT_DESC(debugger_flag_addr, %#x);
	DUMP_BOOT_DESC(eclock, %d);
	DUMP_BOOT_DESC(boot_info_addr, %#llx);

	DUMP_BOOT_INFO(ver_major, %d);
	DUMP_BOOT_INFO(ver_minor, %d);
	DUMP_BOOT_INFO(stack_top, %llx);
	DUMP_BOOT_INFO(heap_start, %llx);
	DUMP_BOOT_INFO(heap_end, %llx);
	DUMP_BOOT_INFO(boot_desc_addr, %#llx);
	DUMP_BOOT_INFO(exception_base_addr, %#x);
	DUMP_BOOT_INFO(stack_size, %d);
	DUMP_BOOT_INFO(flags, %#x);
	DUMP_BOOT_INFO(core_mask, %#x);
	DUMP_BOOT_INFO(dram_size, %d);
	DUMP_BOOT_INFO(phys_mem_desc_addr, %#x);
	DUMP_BOOT_INFO(debugger_flags_addr, %#x);
	DUMP_BOOT_INFO(eclock, %d);
	DUMP_BOOT_INFO(dclock, %d);
	DUMP_BOOT_INFO(board_type, %d);
	DUMP_BOOT_INFO(board_rev_major, %d);
	DUMP_BOOT_INFO(board_rev_minor, %d);
	DUMP_BOOT_INFO(mac_addr_count, %d);
	DUMP_BOOT_INFO(cf_common_addr, %#llx);
	DUMP_BOOT_INFO(cf_attr_addr, %#llx);
	DUMP_BOOT_INFO(led_display_addr, %#llx);
	DUMP_BOOT_INFO(dfaclock, %d);
	DUMP_BOOT_INFO(config_flags, %#x);
#endif

	/*
	 * Init message buffer.
	 */
	msgbufbase = (caddr_t)pmap_steal_memory(MSGBUFSIZE, NULL,NULL);
	initmsgbuf(msgbufbase, MSGBUFSIZE);

	/*
	 * Allocate U page(s) for proc[0], pm_tlbpid 1.
	 */

	proc0.p_addr = proc0paddr = curcpu()->ci_curprocpaddr =
	    (struct user *)pmap_steal_memory(USPACE, NULL, NULL);
	proc0.p_md.md_regs = (struct trap_frame *)&proc0paddr->u_pcb.pcb_regs;
	tlb_set_pid(MIN_USER_ASID);

	/*
	 * Bootstrap VM system.
	 */

	pmap_bootstrap();

	/*
	 * Copy down exception vector code.
	 */

	bcopy(exception, (char *)CACHE_ERR_EXC_VEC, e_exception - exception);
	bcopy(exception, (char *)GEN_EXC_VEC, e_exception - exception);

	/*
	 * Build proper TLB refill handler trampolines.
	 */

	xtlb_handler = (vaddr_t)&xtlb_miss;
	build_trampoline(TLB_MISS_EXC_VEC, xtlb_handler);
	build_trampoline(XTLB_MISS_EXC_VEC, xtlb_handler);

	/*
	 * Turn off bootstrap exception vectors.
	 * (this is done by PMON already, but it doesn't hurt to be safe)
	 */

	setsr(getsr() & ~SR_BOOT_EXC_VEC);
	proc0.p_md.md_regs->sr = getsr();

#ifdef DDB
	db_machine_init();
	if (boothowto & RB_KDB)
		Debugger();
#endif

#ifdef MULTIPROCESSOR
	set_intr(INTPRI_IPI, CR_INT_1, ipi_intr);
#endif

	/*
	 * Return the new kernel stack pointer.
	 */
	return ((vaddr_t)proc0paddr + USPACE - 64);
}

/*
 * Console initialization: called early on from main, before vm init or startup.
 * Do enough configuration to choose and initialize a console.
 */
void
consinit()
{
	static int console_ok = 0;

	if (console_ok == 0) {
		cninit();
		console_ok = 1;
	}
}

/*
 * cpu_startup: allocate memory for variable-sized tables, initialize CPU, and
 * do auto-configuration.
 */
void
cpu_startup()
{
	vaddr_t minaddr, maxaddr;

	/*
	 * Good {morning,afternoon,evening,night}.
	 */
	printf(version);
	printf("real mem = %lu (%luMB)\n", ptoa((psize_t)physmem),
	    ptoa((psize_t)physmem)/1024/1024);

	/*
	 * Allocate a submap for exec arguments. This map effectively
	 * limits the number of processes exec'ing at any time.
	 */
	minaddr = vm_map_min(kernel_map);
	exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
	    16 * NCARGS, VM_MAP_PAGEABLE, FALSE, NULL);
	/* Allocate a submap for physio. */
	phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
	    VM_PHYS_SIZE, 0, FALSE, NULL);

	printf("avail mem = %lu (%luMB)\n", ptoa(uvmexp.free),
	    ptoa(uvmexp.free)/1024/1024);

	/*
	 * Set up buffers, so they can be used to read disk labels.
	 */
	bufinit();

	/*
	 * Configure the system.
	 */
	if (boothowto & RB_CONFIG) {
#ifdef BOOT_CONFIG
		user_config();
#else
		printf("kernel does not support -c; continuing..\n");
#endif
	}
}

int
octeon_cpuspeed(int *freq)
{
	extern struct boot_info *octeon_boot_info;
	*freq = octeon_boot_info->eclock / 1000000;
	return (0);
}

int
octeon_ioclock_speed(void)
{
	extern struct boot_info *octeon_boot_info;
	int chipid;
	u_int64_t mio_rst_boot;

	chipid = octeon_get_chipid();
	switch (octeon_model_family(chipid)) {
	case OCTEON_MODEL_FAMILY_CN61XX:
		mio_rst_boot = octeon_xkphys_read_8(MIO_RST_BOOT);
		return OCTEON_IO_REF_CLOCK * ((mio_rst_boot >>
		    MIO_RST_BOOT_PNR_MUL_SHIFT) & MIO_RST_BOOT_PNR_MUL_MASK);
		break;
	default:
		return octeon_boot_info->eclock;
	}
}

static u_int64_t
get_ncpusfound(void)
{
	extern struct boot_desc *octeon_boot_desc;
	uint64_t core_mask = octeon_boot_desc->core_mask;
	uint64_t i, m, ncpus = 0;

	for (i = 0, m = 1 ; i < OCTEON_MAXCPUS; i++, m <<= 1)
		if (core_mask & m)
			ncpus++;

	return ncpus;
}

static void
process_bootargs(void)
{
	int i;
	extern struct boot_desc *octeon_boot_desc;

	/*
	 * The kernel is booted via a bootoctlinux command. Thus we need to skip
	 * argv[0] when we start to decode the boot arguments (${bootargs}).
	 * Note that U-Boot doesn't pass us anything by default, we need to
	 * explicitly pass the rootdevice.
	 */
	for (i = 1; i < octeon_boot_desc->argc; i++ ) {
		const char *arg = (const char*)
		    PHYS_TO_XKPHYS(octeon_boot_desc->argv[i], CCA_CACHED);

		if (octeon_boot_desc->argv[i] == 0)
			continue;

#ifdef DEBUG
		printf("boot_desc->argv[%d] = %s\n", i, arg);
#endif

		/*
		 * XXX: We currently only expect one other argument,
		 * argv[1], rootdev=ROOTDEV.
		 */
		if (strncmp(arg, "rootdev=", 8) == 0) {
			if (*uboot_rootdev == '\0') {
				strlcpy(uboot_rootdev, arg,
					sizeof(uboot_rootdev));
				parse_uboot_root();
                        }
		}
	}
}

/*
 * Machine dependent system variables.
 */
int
cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
	int *name;
	u_int namelen;
	void *oldp;
	size_t *oldlenp;
	void *newp;
	size_t newlen;
	struct proc *p;
{
	/* All sysctl names at this level are terminal. */
	if (namelen != 1)
		return ENOTDIR;		/* Overloaded */

	switch (name[0]) {
	default:
		return EOPNOTSUPP;
	}
}

int	waittime = -1;

__dead void
boot(int howto)
{
	if (curproc)
		savectx(curproc->p_addr, 0);

	if (cold) {
		if ((howto & RB_USERREQ) == 0)
			howto |= RB_HALT;
		goto haltsys;
	}

	boothowto = howto;
	if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
		waittime = 0;
		vfs_shutdown();

		if ((howto & RB_TIMEBAD) == 0) {
			resettodr();
		} else {
			printf("WARNING: not updating battery clock\n");
		}
	}
	if_downall();

	uvm_shutdown();
	splhigh();
	cold = 1;

	if ((howto & RB_DUMP) != 0)
		dumpsys();

haltsys:
	config_suspend_all(DVACT_POWERDOWN);

	if ((howto & RB_HALT) != 0) {
		if ((howto & RB_POWERDOWN) != 0)
			printf("System Power Down not supported,"
			" halting system.\n");
		else
			printf("System Halt.\n");
	} else {
		printf("System restart.\n");
		(void)disableintr();
		tlb_set_wired(0);
		tlb_flush(bootcpu_hwinfo.tlbsize);
		octeon_xkphys_write_8(OCTEON_CIU_BASE + CIU_SOFT_RST, 1);
	}

	for (;;) ;
	/* NOTREACHED */
}

u_long	dumpmag = 0x8fca0101;	/* Magic number for savecore. */
int	dumpsize = 0;			/* Also for savecore. */
long	dumplo = 0;

void
dumpconf(void)
{
	int nblks;

	if (dumpdev == NODEV ||
	    (nblks = (bdevsw[major(dumpdev)].d_psize)(dumpdev)) == 0)
		return;
	if (nblks <= ctod(1))
		return;

	dumpsize = ptoa(physmem);
	if (dumpsize > atop(round_page(dbtob(nblks - dumplo))))
		dumpsize = atop(round_page(dbtob(nblks - dumplo)));
	else if (dumplo == 0)
		dumplo = nblks - btodb(ptoa(physmem));

	/*
	 * Don't dump on the first page in case the dump device includes a
	 * disk label.
	 */
	if (dumplo < btodb(PAGE_SIZE))
		dumplo = btodb(PAGE_SIZE);
}

void
dumpsys()
{
	/* XXX TBD */
}

boolean_t
is_memory_range(paddr_t pa, psize_t len, psize_t limit)
{
	struct phys_mem_desc *seg;
	uint64_t fp, lp;
	int i;

	fp = atop(pa);
	lp = atop(round_page(pa + len));

	if (limit != 0 && lp > atop(limit))
		return FALSE;

	for (i = 0, seg = mem_layout; i < MAXMEMSEGS; i++, seg++)
		if (fp >= seg->mem_first_page && lp <= seg->mem_last_page)
			return TRUE;

	return FALSE;
}

#ifdef MULTIPROCESSOR
uint32_t cpu_spinup_mask = 0;
uint64_t cpu_spinup_a0, cpu_spinup_sp;
static int (*ipi_handler)(void *);

extern bus_space_t iobus_tag;
extern bus_space_handle_t iobus_h;

void
hw_cpu_boot_secondary(struct cpu_info *ci)
{
	vaddr_t kstack;

	kstack = alloc_contiguous_pages(USPACE);
	if (kstack == 0)
		panic("unable to allocate idle stack\n");
	ci->ci_curprocpaddr = (void *)kstack;
	cpu_spinup_a0 = (uint64_t)ci;
	cpu_spinup_sp = (uint64_t)(kstack + USPACE);
	cpu_spinup_mask = (uint32_t)ci->ci_cpuid;

	while (!cpuset_isset(&cpus_running, ci))
		;
}

void
hw_cpu_hatch(struct cpu_info *ci)
{
	int s;

	/*
	 * Set curcpu address on this processor.
	 */
	setcurcpu(ci);

	/*
	 * Make sure we can access the extended address space.
	 * Note that r10k and later do not allow XUSEG accesses
	 * from kernel mode unless SR_UX is set.
	 */
	setsr(getsr() | SR_KX | SR_UX);

	tlb_init(64);
	tlb_set_pid(0);

	/*
	 * Turn off bootstrap exception vectors.
	 */
	setsr(getsr() & ~SR_BOOT_EXC_VEC);

	/*
	 * Clear out the I and D caches.
	 */
	Octeon_ConfigCache(ci);
	Mips_SyncCache(ci);

	printf("cpu%lu launched\n", cpu_number());

	(*md_startclock)(ci);
	ncpus++;
	cpuset_add(&cpus_running, ci);
	octeon_intr_init();
	mips64_ipi_init();
	octeon_setintrmask(0);
	spl0();
	(void)updateimask(0);

	SCHED_LOCK(s);
	cpu_switchto(NULL, sched_chooseproc());
}

/*
 * IPI dispatcher.
 */
uint32_t
ipi_intr(uint32_t hwpend, struct trap_frame *frame)
{
	u_long cpuid = cpu_number();

	/*
	 * Mask all pending interrupts.
	 */
	bus_space_write_8(&iobus_tag, iobus_h, CIU_IP3_EN0(cpuid), 0);

	if (ipi_handler == NULL)
		return hwpend;

	ipi_handler((void *)cpuid);

	/*
	 * Reenable interrupts which have been serviced.
	 */
	bus_space_write_8(&iobus_tag, iobus_h, CIU_IP3_EN0(cpuid),
		(1ULL << CIU_INT_MBOX0)|(1ULL << CIU_INT_MBOX1));
	return hwpend;
}

int
hw_ipi_intr_establish(int (*func)(void *), u_long cpuid)
{
	if (cpuid == 0)
		ipi_handler = func;

	bus_space_write_8(&iobus_tag, iobus_h, CIU_MBOX_CLR(cpuid),
		0xffffffff);
	bus_space_write_8(&iobus_tag, iobus_h, CIU_IP3_EN0(cpuid),
		(1ULL << CIU_INT_MBOX0)|(1ULL << CIU_INT_MBOX1));

	return 0;
};

void
hw_ipi_intr_set(u_long cpuid)
{
	bus_space_write_8(&iobus_tag, iobus_h, CIU_MBOX_SET(cpuid), 1);
}

void
hw_ipi_intr_clear(u_long cpuid)
{
	uint64_t clr =
		bus_space_read_8(&iobus_tag, iobus_h, CIU_MBOX_CLR(cpuid));
	bus_space_write_8(&iobus_tag, iobus_h, CIU_MBOX_CLR(cpuid), clr);
}
#endif /* MULTIPROCESSOR */


code:
/*	$OpenBSD: pciide_machdep.c,v 1.1 2010/10/28 22:52:10 syuu Exp $	*/
/*	$NetBSD: pciide_machdep.c,v 1.2 1999/02/19 18:01:27 mycroft Exp $	*/

/*
 * Copyright (c) 1998 Christopher G. Demetriou.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by Christopher G. Demetriou
 *	for the NetBSD Project.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * PCI IDE controller driver
 */

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

#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pciidereg.h>
#include <dev/pci/pciidevar.h>

#include <machine/autoconf.h>

void *
pciide_machdep_compat_intr_establish(struct device *dev,
    struct pci_attach_args *pa, int chan, int (*func)(void *), void *arg)
{
	void *cookie = NULL;

	printf("%s:%d\n",__FUNCTION__,__LINE__);

	return (cookie);
}

void
pciide_machdep_compat_intr_disestablish(pci_chipset_tag_t pc, void *cookie)
{
	printf("%s:%d\n",__FUNCTION__,__LINE__);
}


code:
/Makefile/1.2/Wed Jun  5 01:32:10 2013//TOPENBSD_5_8_BASE
/Makefile.inc/1.1/Wed Jun  5 01:02:29 2013//TOPENBSD_5_8_BASE
D/boot////
D/libsa////

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


code: src/sys/arch/octeon/stand

path: sys/arch/octeon/stand/CVS/Repository


code:
#	$OpenBSD: Makefile,v 1.2 2013/06/05 01:32:10 jasper Exp $

.if ${MACHINE} == "octeon"
SUBDIR +=	libsa
.endif

SUBDIR +=	boot

.include <bsd.subdir.mk>

path: sys/arch/octeon/stand/Makefile


code:
#	$OpenBSD: Makefile.inc,v 1.1 2013/06/05 01:02:29 jasper Exp $

BINDIR=		/usr/mdec

STANDALONE?=	-D_STANDALONE

.if ${MACHINE} == "octeon"
CPPFLAGS+=	${STANDALONE}
CPPFLAGS+=	-I.
CFLAGS+=	-fno-stack-protector -Wall
CFLAGS+=	-fno-builtin-vprintf -fno-builtin-printf -fno-builtin-putchar
# Silence warnings
CFLAGS+=	-fno-builtin-snprintf
CFLAGS+=	-fno-builtin-memcpy
CFLAGS+=	-fno-builtin-memcmp
CFLAGS+=	-fno-builtin-memset
CFLAGS+=	-fno-builtin-strncpy
CFLAGS+=	-fno-builtin-strncmp
CFLAGS+=	-fno-builtin-exit
SAABI=		-mips3 -mno-abicalls -G 0 -fno-pic -fno-common
AS?=		as
LD?=		ld
.endif

### Figure out what to use for libsa
LIBSADIR?=               ${.CURDIR}/../libsa

.if exists(${LIBSADIR}/${__objdir})
LIBSAOBJDIR=            ${LIBSADIR}/${__objdir}
.else
LIBSAOBJDIR=            ${LIBSADIR}
.endif

LIBSA=                  ${LIBSAOBJDIR}/libsa.a

### Figure out what to use for libz
LIBZDIR?=                ${.CURDIR}/../libz

.if exists(${LIBZDIR}/${__objdir})
LIBZOBJDIR=             ${LIBZDIR}/${__objdir}
.else
LIBZOBJDIR=             ${LIBZDIR}
.endif

LIBZ=                   ${LIBZOBJDIR}/libz.a


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


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


code:
#	$OpenBSD: Makefile,v 1.2 2014/07/12 23:45:33 jasper Exp $

NOMAN=
#MAN=		boot.8
#MLINKS=	boot.8 boot.conf.5

.if ${MACHINE} == "octeon"
PROG=		boot
.include	"${.CURDIR}/Makefile.inc"
.else
NOPROG=
.endif

CFLAGS+=-fno-pie -DCONSPEED=15200
AFLAGS+=-fno-pie
LDFLAGS+=-nopie

.include <bsd.prog.mk>

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


code:
#	$OpenBSD: Makefile.inc,v 1.2 2013/06/05 01:09:09 jasper Exp $

NOMAN=
S=		${.CURDIR}/../../../..
BOOTDIR=	${S}/arch/octeon/stand/boot

CPPFLAGS+=	${SAABI} -mno-abicalls -D_NO_ABICALLS -Werror \
		-nostdinc -D__octeon__ -msoft-float \
		-I${S} -I${S}/lib/libsa \
		-I${.OBJDIR} -I${BOOTDIR}

LDSCRIPT=	${.CURDIR}/../../conf/ld.script
LDFLAGS+=	${SALDFLAGS} -T ${LDSCRIPT} -Ttext=0xffffffff81000000 -e __start

AFLAGS+=	${SAABI}

.PATH:		${BOOTDIR}
SRCS=		start.S
SRCS+=		conf.c clock.c devopen.c exec.c machdep.c uart.c

#### MI boot code
.PATH:		${S}/stand/boot
SRCS+=		boot.c cmd.c vars.c

#### libkern
.PATH:		${S}/lib/libkern/arch/mips64 ${S}/lib/libkern
SRCS+=		strlcat.c strlcpy.c strlen.c
SRCS+=		udivdi3.c qdivrem.c

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

${PROG}: ${OBJS} ${LIBSA}
	${LD} ${LDFLAGS} -o ${PROG} ${OBJS} ${LIBSA}


code:
/*	$OpenBSD: clock.c,v 1.3 2014/07/12 19:47:38 jasper Exp $	*/

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

#include <sys/types.h>

#include "libsa.h"

/* Arbitrarily chosen value, needs talking to cp0 for a delay loop. */
#define DELAY_MULTIPLIER 10000

void
delay(int ms)
{
	volatile int i = ms * DELAY_MULTIPLIER;
	for (; --i;)
		;
}


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

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

#include <sys/param.h>
#include <dev/cons.h>

#include "libsa.h"
#include <lib/libsa/ufs.h>
#include <lib/libsa/cd9660.h>

const char version[] = "0.2";

/*
 * Device configuration
 */
struct devsw devsw[] = {
	/* ATA storage device */
	/* XXX */
	{ "wd",		NULL, NULL, NULL, noioctl }
};
int ndevs = nitems(devsw);

/*
 * Filesystem configuration
 */
struct fs_ops file_system[] = {
	/* ufs filesystem */
	{	ufs_open,	ufs_close,	ufs_read,	ufs_write,
		ufs_seek,	ufs_stat,	ufs_readdir	},
	/* cd9660 filesystem - in case a cd image is dd'ed on non USB media */
	{	cd9660_open,	cd9660_close,	cd9660_read,	cd9660_write,
		cd9660_seek,	cd9660_stat,	cd9660_readdir	}
};
int nfsys = nitems(file_system);

/*
 * Console configuration
 */
struct consdev constab[] = {
	{ cn30xxuartcnprobe, cn30xxuartcninit, cn30xxuartcngetc, cn30xxuartcnputc },
	{ NULL }
};
struct consdev *cn_tab;


code:
/*	$OpenBSD: devopen.c,v 1.1 2013/06/05 01:02:29 jasper Exp $	*/

/*-
 * Copyright (c) 2003 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Rolf Grossmann.
 *
 * 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 "libsa.h"

#define MAXDEVNAME      16

/*
 * Parse a device spec.
 *
 * [A-Za-z]*[0-9]*[A-Za-z]:file
 *    dev   uint    part
 */
int
devparse(const char *fname, int *dev, int *unit, int *part, const char **file)
{
	const char *s;

	*unit = 0;	/* default to wd0a */
	*part = 0;
	*dev  = 0;

	s = strchr(fname, ':');
	if (s != NULL) {
		int devlen;
		int i, u, p = 0;
		struct devsw *dp;
		char devname[MAXDEVNAME];

		devlen = s - fname;
		if (devlen > MAXDEVNAME)
			return (EINVAL);

		/* extract device name */
		for (i = 0; isalpha(fname[i]) && (i < devlen); i++)
			devname[i] = fname[i];
		devname[i] = 0;

		if (!isdigit(fname[i]))
			return (EUNIT);

		/* device number */
		for (u = 0; isdigit(fname[i]) && (i < devlen); i++)
			u = u * 10 + (fname[i] - '0');

		if (!isalpha(fname[i]))
			return (EPART);

		/* partition number */
		if (i < devlen)
			p = fname[i++] - 'a';

		if (i != devlen)
			return (ENXIO);

		/* check device name */
		for (dp = devsw, i = 0; i < ndevs; dp++, i++) {
			if (dp->dv_name && !strcmp(devname, dp->dv_name))
				break;
		}

		if (i >= ndevs)
			return (ENXIO);

		*unit = u;
		*part = p;
		*dev  = i;
		fname = ++s;
	}

	*file = fname;

	return (0);
}

int
devopen(struct open_file *f, const char *fname, char **file)
{
	struct devsw *dp;
	int dev, unit, part, error;

	error = devparse(fname, &dev, &unit, &part, (const char **)file);
	if (error)
		return (error);

	dp = &devsw[dev];
	if ((void *)dp->dv_open == (void *)nodev)
		return (ENXIO);

	f->f_dev = dp;

	return (*dp->dv_open)(f, unit, part);
}


code:
/*	$OpenBSD: exec.c,v 1.2 2015/01/20 04:41:01 krw Exp $	*/
#include <sys/param.h>
#include "libsa.h"
#include <lib/libsa/loadfile.h>

void
run_loadfile(u_long *marks, int howto)
{}