code:
/*	$OpenBSD: armv7_machdep.c,v 1.24 2015/05/19 03:30:54 jsg Exp $ */
/*	$NetBSD: lubbock_machdep.c,v 1.2 2003/07/15 00:25:06 lukem Exp $ */

/*
 * Copyright (c) 2002, 2003  Genetec Corporation.  All rights reserved.
 * Written by Hiroyuki Bessho for Genetec Corporation.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of Genetec Corporation may not be used to endorse or
 *    promote products derived from this software without specific prior
 *    written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``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 GENETEC CORPORATION
 * 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.
 *
 * Machine dependant functions for kernel setup for
 * Intel DBPXA250 evaluation board (a.k.a. Lubbock).
 * Based on iq80310_machhdep.c
 */
/*
 * Copyright (c) 2001 Wasabi Systems, Inc.
 * All rights reserved.
 *
 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
 *
 * 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 for the NetBSD Project by
 *	Wasabi Systems, Inc.
 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
 *    or promote products derived from this software without specific prior
 *    written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
 * 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) 1997,1998 Mark Brinicombe.
 * Copyright (c) 1997,1998 Causality Limited.
 * 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 Mark Brinicombe
 *	for the NetBSD Project.
 * 4. The name of the company nor the name of the author may 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 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.
 *
 * Machine dependant functions for kernel setup for Intel IQ80310 evaluation
 * boards using RedBoot firmware.
 */

/*
 * DIP switches:
 *
 * S19: no-dot: set RB_KDB.  enter kgdb session.
 * S20: no-dot: set RB_SINGLE. don't go multi user mode.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/reboot.h>
#include <sys/termios.h>
#include <sys/socket.h>

#include <machine/db_machdep.h>
#include <machine/bootconfig.h>
#include <machine/machine_reg.h>
#include <machine/bus.h>

#include <arm/undefined.h>
#include <arm/machdep.h>
#include <arm/armv7/armv7var.h>
#include <armv7/armv7/armv7_machdep.h>

#include <dev/cons.h>

#include <net/if.h>

#include <ddb/db_extern.h>

/* Kernel text starts 2MB in from the bottom of the kernel address space. */
#define	KERNEL_TEXT_BASE	(KERNEL_BASE + 0x00000000)
#define	KERNEL_VM_BASE		(KERNEL_BASE + 0x04000000)
#define KERNEL_VM_SIZE		VM_KERNEL_SPACE_SIZE

/*
 * Address to call from cpu_reset() to reset the machine.
 * This is machine architecture dependant as it varies depending
 * on where the ROM appears when you turn the MMU off.
 */

/* Define various stack sizes in pages */
#define IRQ_STACK_SIZE	1
#define ABT_STACK_SIZE	1
#define UND_STACK_SIZE	1

BootConfig bootconfig;		/* Boot config storage */
char *boot_args = NULL;
char *boot_file = "";
u_int cpu_reset_address = 0;

vaddr_t physical_start;
vaddr_t physical_freestart;
vaddr_t physical_freeend;
vaddr_t physical_end;
u_int free_pages;
int physmem = 0;

/*int debug_flags;*/
#ifndef PMAP_STATIC_L1S
int max_processes = 64;			/* Default number */
#endif	/* !PMAP_STATIC_L1S */

/* Physical and virtual addresses for some global pages */
pv_addr_t systempage;
pv_addr_t irqstack;
pv_addr_t undstack;
pv_addr_t abtstack;
extern pv_addr_t kernelstack;

vaddr_t msgbufphys;

extern u_int data_abort_handler_address;
extern u_int prefetch_abort_handler_address;
extern u_int undefined_handler_address;

uint32_t	board_id;

#define KERNEL_PT_SYS		0	/* Page table for mapping proc0 zero page */
#define KERNEL_PT_KERNEL	1	/* Page table for mapping kernel */
#define	KERNEL_PT_KERNEL_NUM	32
#define KERNEL_PT_VMDATA	(KERNEL_PT_KERNEL+KERNEL_PT_KERNEL_NUM)
				        /* Page tables for mapping kernel VM */
#define	KERNEL_PT_VMDATA_NUM	8	/* start with 16MB of KVM */
#define NUM_KERNEL_PTS		(KERNEL_PT_VMDATA + KERNEL_PT_VMDATA_NUM)

pv_addr_t kernel_pt_table[NUM_KERNEL_PTS];

extern struct user *proc0paddr;

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

/* Prototypes */

char	bootargs[MAX_BOOT_STRING];
int	bootstrap_bs_map(void *, bus_addr_t, bus_size_t, int,
    bus_space_handle_t *);
void	process_kernel_args(char *);
void	parse_uboot_tags(void *);
void	consinit(void);
void	bootconfig_dram(BootConfig *, psize_t *, psize_t *);

bs_protos(bs_notimpl);

#ifndef CONSPEED
#define CONSPEED B115200	/* What u-boot */
#endif
#ifndef CONMODE
#define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
#endif

int comcnspeed = CONSPEED;
int comcnmode = CONMODE;

/*
 * void boot(int howto, char *bootstr)
 *
 * Reboots the system
 *
 * Deal with any syncing, unmounting, dumping and shutdown hooks,
 * then reset the CPU.
 */
__dead void
boot(int howto)
{
#ifdef DIAGNOSTIC
	/* info */
	printf("boot: howto=%08x curproc=%p\n", howto, curproc);
#endif

	if (cold) {
		config_suspend_all(DVACT_POWERDOWN);
		if ((howto & (RB_HALT | RB_USERREQ)) != RB_USERREQ) {
			printf("The operating system has halted.\n");
			printf("Please press any key to reboot.\n\n");
			cngetc();
		}
		printf("rebooting...\n");
		delay(500000);
		platform_watchdog_reset();
		printf("reboot failed; spinning\n");
		while(1);
		/*NOTREACHED*/
	}

	/* Disable console buffering */
/*	cnpollc(1);*/

	/*
	 * If RB_NOSYNC was not specified sync the discs.
	 * Note: Unless cold is set to 1 here, syslogd will die during the
	 * unmount.  It looks like syslogd is getting woken up only to find
	 * that it cannot page part of the binary in as the filesystem has
	 * been unmounted.
	 */
	if ((howto & RB_NOSYNC) == 0)
		bootsync(howto);

	if_downall();

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

	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
		dumpsys();

	config_suspend_all(DVACT_POWERDOWN);

	/* Make sure IRQ's are disabled */
	IRQdisable;

	if ((howto & RB_HALT) != 0) {
		if ((howto & RB_POWERDOWN) != 0) {
			printf("\nAttempting to power down...\n");
			delay(500000);
			platform_powerdown();
		}

		printf("The operating system has halted.\n");
		printf("Please press any key to reboot.\n\n");
		cngetc();
	}

	printf("rebooting...\n");
	delay(500000);
	platform_watchdog_reset();
	printf("reboot failed; spinning\n");
	for (;;) ;
	/* NOTREACHED */
}

static __inline
pd_entry_t *
read_ttb(void)
{
  long ttb;

  __asm volatile("mrc	p15, 0, %0, c2, c0, 0" : "=r" (ttb));

  return (pd_entry_t *)(ttb & ~((1<<14)-1));
}

#define VERBOSE_INIT_ARM

/*
 * simple memory mapping function used in early bootstrap stage
 * before pmap is initialized.
 * ignores cacheability and does map the sections with nocache.
 */
static vaddr_t section_free = 0xfd000000; /* XXX - huh */

int
bootstrap_bs_map(void *t, bus_addr_t bpa, bus_size_t size,
    int flags, bus_space_handle_t *bshp)
{
	u_long startpa, pa, endpa;
	vaddr_t va;
	pd_entry_t *pagedir = read_ttb();
	/* This assumes PA==VA for page directory */

	va = section_free;

	startpa = bpa & ~L1_S_OFFSET;
	endpa = (bpa + size) & ~L1_S_OFFSET;
	if ((bpa + size) & L1_S_OFFSET)
		endpa += L1_S_SIZE;

	*bshp = (bus_space_handle_t)(va + (bpa - startpa));

	for (pa = startpa; pa < endpa; pa += L1_S_SIZE, va += L1_S_SIZE)
		pmap_map_section((vaddr_t)pagedir, va, pa,
		    PROT_READ | PROT_WRITE, PTE_NOCACHE);

	cpu_tlb_flushD();

	section_free = va;

	return 0;
}

static void
copy_io_area_map(pd_entry_t *new_pd)
{
	pd_entry_t *cur_pd = read_ttb();
	vaddr_t va;

	for (va = MACHINE_IO_AREA_VBASE;
	     (cur_pd[va>>L1_S_SHIFT] & L1_TYPE_MASK) == L1_TYPE_S;
	     va += L1_S_SIZE) {

		new_pd[va>>L1_S_SHIFT] = cur_pd[va>>L1_S_SHIFT];
		if (va == (ARM_VECTORS_HIGH & ~(0x00400000 - 1)))
			break; /* STUPID */

	}
}

/*
 * u_int initarm(...)
 *
 * Initial entry point on startup. This gets called before main() is
 * entered.
 * It should be responsible for setting up everything that must be
 * in place when main is called.
 * This includes
 *   Taking a copy of the boot configuration structure.
 *   Initialising the physical console so characters can be printed.
 *   Setting up page tables for the kernel
 *   Relocating the kernel to the bottom of physical memory
 */
u_int
initarm(void *arg0, void *arg1, void *arg2)
{
	int loop, loop1, i, physsegs;
	u_int l1pagetable;
	pv_addr_t kernel_l1pt;
	paddr_t memstart;
	psize_t memsize;
	extern uint32_t esym; /* &_end if no symbols are loaded */

	/* early bus_space_map support */
	struct bus_space tmp_bs_tag;
	int	(*map_func_save)(void *, bus_addr_t, bus_size_t, int,
	    bus_space_handle_t *);

	board_id = (uint32_t)arg1;

	/*
	 * Heads up ... Setup the CPU / MMU / TLB functions
	 */
	if (set_cpufuncs())
		panic("cpu not recognized!");

	/*
	 * Temporarily replace bus_space_map() functions so that
	 * console devices can get mapped.
	 *
	 * Note that this relies upon the fact that both regular
	 * and a4x bus_space tags use the same map function.
	 */
	tmp_bs_tag = armv7_bs_tag;
	map_func_save = armv7_bs_tag.bs_map;
	armv7_bs_tag.bs_map = bootstrap_bs_map;
	armv7_a4x_bs_tag.bs_map = bootstrap_bs_map;
	tmp_bs_tag.bs_map = bootstrap_bs_map;

	platform_init();
	platform_disable_l2_if_needed();

	/* setup a serial console for very early boot */
	consinit();

	/* Talk to the user */
	printf("\n%s booting ...\n", platform_boot_name());

	printf("arg0 %p arg1 %p arg2 %p\n", arg0, arg1, arg2);
	parse_uboot_tags(arg2);

	/*
	 * Examine the boot args string for options we need to know about
	 * now.
	 */
	process_kernel_args(bootconfig.bootstring);
#ifdef RAMDISK_HOOKS
        boothowto |= RB_DFLTROOT;
#endif /* RAMDISK_HOOKS */

	/* normally u-boot will set up bootconfig.dramblocks */
	bootconfig_dram(&bootconfig, &memstart, &memsize);

	/*
	 * Set up the variables that define the availablilty of
	 * physical memory.  For now, we're going to set
	 * physical_freestart to 0xa0200000 (where the kernel
	 * was loaded), and allocate the memory we need downwards.
	 * If we get too close to the page tables that RedBoot
	 * set up, we will panic.  We will update physical_freestart
	 * and physical_freeend later to reflect what pmap_bootstrap()
	 * wants to see.
	 *
	 * XXX pmap_bootstrap() needs an enema.
	 */
	physical_start = bootconfig.dram[0].address;
	physical_end = MIN((uint64_t)physical_start +
	    (bootconfig.dram[0].pages * PAGE_SIZE), (paddr_t)-PAGE_SIZE);

	{
		physical_freestart = (((unsigned long)esym - KERNEL_TEXT_BASE +0xfff) & ~0xfff) + memstart;
		physical_freeend = MIN((uint64_t)memstart+memsize,
		    (paddr_t)-PAGE_SIZE);
	}

	physmem = (physical_end - physical_start) / PAGE_SIZE;

#ifdef DEBUG
	/* Tell the user about the memory */
	printf("physmemory: %d pages at 0x%08lx -> 0x%08lx\n", physmem,
	    physical_start, physical_end - 1);
#endif

	/*
	 * Okay, the kernel starts 2MB in from the bottom of physical
	 * memory.  We are going to allocate our bootstrap pages downwards
	 * from there.
	 *
	 * We need to allocate some fixed page tables to get the kernel
	 * going.  We allocate one page directory and a number of page
	 * tables and store the physical addresses in the kernel_pt_table
	 * array.
	 *
	 * The kernel page directory must be on a 16K boundary.  The page
	 * tables must be on 4K bounaries.  What we do is allocate the
	 * page directory on the first 16K boundary that we encounter, and
	 * the page tables on 4K boundaries otherwise.  Since we allocate
	 * at least 3 L2 page tables, we are guaranteed to encounter at
	 * least one 16K aligned region.
	 */

#ifdef VERBOSE_INIT_ARM
	printf("Allocating page tables\n");
#endif

	free_pages = (physical_freeend - physical_freestart) / PAGE_SIZE;

#ifdef VERBOSE_INIT_ARM
	printf("freestart = 0x%08lx, free_pages = %d (0x%08x)\n",
	       physical_freestart, free_pages, free_pages);
#endif

	/* Define a macro to simplify memory allocation */
#define	valloc_pages(var, np)				\
	alloc_pages((var).pv_pa, (np));			\
	(var).pv_va = KERNEL_BASE + (var).pv_pa - physical_start;

#define alloc_pages(var, np)				\
	(var) = physical_freestart;			\
	physical_freestart += ((np) * PAGE_SIZE);	\
	if (physical_freeend < physical_freestart)	\
		panic("initarm: out of memory");	\
	free_pages -= (np);				\
	memset((char *)(var), 0, ((np) * PAGE_SIZE));

	loop1 = 0;
	kernel_l1pt.pv_pa = 0;
	for (loop = 0; loop <= NUM_KERNEL_PTS; ++loop) {
		/* Are we 16KB aligned for an L1 ? */
		if (((physical_freestart) & (L1_TABLE_SIZE - 1)) == 0
		    && kernel_l1pt.pv_pa == 0) {
			valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
		} else {
			valloc_pages(kernel_pt_table[loop1],
			    L2_TABLE_SIZE / PAGE_SIZE);
			++loop1;
		}
	}

	/* This should never be able to happen but better confirm that. */
	if (!kernel_l1pt.pv_pa || (kernel_l1pt.pv_pa & (L1_TABLE_SIZE-1)) != 0)
		panic("initarm: Failed to align the kernel page directory");

	/*
	 * Allocate a page for the system page mapped to V0x00000000
	 * This page will just contain the system vectors and can be
	 * shared by all processes.
	 */
	vector_page = ARM_VECTORS_HIGH;
	alloc_pages(systempage.pv_pa, 1);
	systempage.pv_va = vector_page;

	/* Allocate stacks for all modes */
	valloc_pages(irqstack, IRQ_STACK_SIZE);
	valloc_pages(abtstack, ABT_STACK_SIZE);
	valloc_pages(undstack, UND_STACK_SIZE);
	valloc_pages(kernelstack, UPAGES);

	/* Allocate enough pages for cleaning the Mini-Data cache. */

#ifdef VERBOSE_INIT_ARM
	printf("IRQ stack: p0x%08lx v0x%08lx\n", irqstack.pv_pa,
	    irqstack.pv_va);
	printf("ABT stack: p0x%08lx v0x%08lx\n", abtstack.pv_pa,
	    abtstack.pv_va);
	printf("UND stack: p0x%08lx v0x%08lx\n", undstack.pv_pa,
	    undstack.pv_va);
	printf("SVC stack: p0x%08lx v0x%08lx\n", kernelstack.pv_pa,
	    kernelstack.pv_va);
#endif

	/*
	 * XXX Defer this to later so that we can reclaim the memory
	 * XXX used by the RedBoot page tables.
	 */
	alloc_pages(msgbufphys, round_page(MSGBUFSIZE) / PAGE_SIZE);

	/*
	 * Ok we have allocated physical pages for the primary kernel
	 * page tables
	 */

#ifdef VERBOSE_INIT_ARM
	printf("Creating L1 page table at 0x%08lx\n", kernel_l1pt.pv_pa);
#endif

	/*
	 * Now we start construction of the L1 page table
	 * We start by mapping the L2 page tables into the L1.
	 * This means that we can replace L1 mappings later on if necessary
	 */
	l1pagetable = kernel_l1pt.pv_pa;

	/* Map the L2 pages tables in the L1 page table */
	pmap_link_l2pt(l1pagetable, vector_page & ~(0x00400000 - 1),
	    &kernel_pt_table[KERNEL_PT_SYS]);

	for (loop = 0; loop < KERNEL_PT_KERNEL_NUM; loop++)
		pmap_link_l2pt(l1pagetable, KERNEL_BASE + loop * 0x00400000,
		    &kernel_pt_table[KERNEL_PT_KERNEL + loop]);

	for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; loop++)
		pmap_link_l2pt(l1pagetable, KERNEL_VM_BASE + loop * 0x00400000,
		    &kernel_pt_table[KERNEL_PT_VMDATA + loop]);

	/* update the top of the kernel VM */
	pmap_curmaxkvaddr =
	    KERNEL_VM_BASE + (KERNEL_PT_VMDATA_NUM * 0x00400000);

#ifdef VERBOSE_INIT_ARM
	printf("Mapping kernel\n");
#endif

	/* Now we fill in the L2 pagetable for the kernel static code/data */
	{
		extern char etext[];
		size_t textsize = (u_int32_t) etext - KERNEL_TEXT_BASE;
		size_t totalsize = (u_int32_t) esym - KERNEL_TEXT_BASE;
		u_int logical;

		textsize = (textsize + PGOFSET) & ~PGOFSET;
		totalsize = (totalsize + PGOFSET) & ~PGOFSET;

		logical = 0x00000000;	/* offset of kernel in RAM */

		logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical,
		    physical_start + logical, textsize,
		    PROT_READ | PROT_WRITE | PROT_EXEC, PTE_CACHE);
		logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical,
		    physical_start + logical, totalsize - textsize,
		    PROT_READ | PROT_WRITE, PTE_CACHE);
	}

#ifdef VERBOSE_INIT_ARM
	printf("Constructing L2 page tables\n");
#endif

	/* Map the stack pages */
	pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa,
	    IRQ_STACK_SIZE * PAGE_SIZE, PROT_READ | PROT_WRITE, PTE_CACHE);
	pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa,
	    ABT_STACK_SIZE * PAGE_SIZE, PROT_READ | PROT_WRITE, PTE_CACHE);
	pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa,
	    UND_STACK_SIZE * PAGE_SIZE, PROT_READ | PROT_WRITE, PTE_CACHE);
	pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa,
	    UPAGES * PAGE_SIZE, PROT_READ | PROT_WRITE, PTE_CACHE);

	pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa,
	    L1_TABLE_SIZE, PROT_READ | PROT_WRITE, PTE_PAGETABLE);

	for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
		pmap_map_chunk(l1pagetable, kernel_pt_table[loop].pv_va,
		    kernel_pt_table[loop].pv_pa, L2_TABLE_SIZE,
		    PROT_READ | PROT_WRITE, PTE_PAGETABLE);
	}

	/* Map the Mini-Data cache clean area. */

	/* Map the vector page. */
	pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa,
	    PROT_READ | PROT_WRITE | PROT_EXEC, PTE_CACHE);

	/*
	 * map integrated peripherals at same address in l1pagetable
	 * so that we can continue to use console.
	 */
	copy_io_area_map((pd_entry_t *)l1pagetable);

	/*
	 * Now we have the real page tables in place so we can switch to them.
	 * Once this is done we will be running with the REAL kernel page
	 * tables.
	 */

	/* be a client to all domains */
	cpu_domains(0x55555555);
	/* Switch tables */

	cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
	setttb(kernel_l1pt.pv_pa);
	cpu_tlb_flushID();
	cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));

	/*
	 * Moved from cpu_startup() as data_abort_handler() references
	 * this during uvm init
	 */
	proc0paddr = (struct user *)kernelstack.pv_va;
	proc0.p_addr = proc0paddr;

	arm32_vector_init(vector_page, ARM_VEC_ALL);

	/*
	 * Pages were allocated during the secondary bootstrap for the
	 * stacks for different CPU modes.
	 * We must now set the r13 registers in the different CPU modes to
	 * point to these stacks.
	 * Since the ARM stacks use STMFD etc. we must set r13 to the top end
	 * of the stack memory.
	 */

	set_stackptr(PSR_IRQ32_MODE,
	    irqstack.pv_va + IRQ_STACK_SIZE * PAGE_SIZE);
	set_stackptr(PSR_ABT32_MODE,
	    abtstack.pv_va + ABT_STACK_SIZE * PAGE_SIZE);
	set_stackptr(PSR_UND32_MODE,
	    undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE);

	/*
	 * Well we should set a data abort handler.
	 * Once things get going this will change as we will need a proper
	 * handler.
	 * Until then we will use a handler that just panics but tells us
	 * why.
	 * Initialisation of the vectors will just panic on a data abort.
	 * This just fills in a slighly better one.
	 */

	data_abort_handler_address = (u_int)data_abort_handler;
	prefetch_abort_handler_address = (u_int)prefetch_abort_handler;
	undefined_handler_address = (u_int)undefinedinstruction_bounce;

	/* Initialise the undefined instruction handlers */
#ifdef VERBOSE_INIT_ARM
	printf("undefined ");
#endif
	undefined_init();

	/* Load memory into UVM. */
#ifdef VERBOSE_INIT_ARM
	printf("page ");
#endif
	uvm_setpagesize();        /* initialize PAGE_SIZE-dependent variables */
	uvm_page_physload(atop(physical_freestart), atop(physical_freeend),
	    atop(physical_freestart), atop(physical_freeend), 0);

	physsegs = MIN(bootconfig.dramblocks, VM_PHYSSEG_MAX);

	for (i = 1; i < physsegs; i++) {
		paddr_t dramstart = bootconfig.dram[i].address;
		paddr_t dramend =  MIN((uint64_t)dramstart +
		    bootconfig.dram[i].pages * PAGE_SIZE, (paddr_t)-PAGE_SIZE);
		physmem += (dramend - dramstart) / PAGE_SIZE;
		uvm_page_physload(atop(dramstart), atop(dramend),
		    atop(dramstart), atop(dramend), 0);
	}

	/* Boot strap pmap telling it where the kernel page table is */
#ifdef VERBOSE_INIT_ARM
	printf("pmap ");
#endif
	pmap_bootstrap((pd_entry_t *)kernel_l1pt.pv_va, KERNEL_VM_BASE,
	    KERNEL_VM_BASE + KERNEL_VM_SIZE);

	/*
	 * Restore proper bus_space operation, now that pmap is initialized.
	 */
	armv7_bs_tag.bs_map = map_func_save;
	armv7_a4x_bs_tag.bs_map = map_func_save;

#ifdef DDB
	db_machine_init();

	/* Firmware doesn't load symbols. */
	ddb_init();

	if (boothowto & RB_KDB)
		Debugger();
#endif
	printf("board type: %u\n", board_id);

	/* We return the new stack pointer address */
	return(kernelstack.pv_va + USPACE_SVC_STACK_TOP);
}

void
process_kernel_args(char *args)
{
	char *cp = args;

	if (cp == NULL) {
		boothowto = RB_AUTOBOOT;
		return;
	}

	boothowto = 0;

	/* Make a local copy of the bootargs */
	strncpy(bootargs, cp, MAX_BOOT_STRING - sizeof(int));

	cp = bootargs;
	boot_file = bootargs;

	/* Skip the kernel image filename */
	while (*cp != ' ' && *cp != 0)
		++cp;

	if (*cp != 0)
		*cp++ = 0;

	while (*cp == ' ')
		++cp;

	boot_args = cp;

	printf("bootfile: %s\n", boot_file);
	printf("bootargs: %s\n", boot_args);

	/* Setup pointer to boot flags */
	while (*cp != '-')
		if (*cp++ == '\0')
			return;

	for (;*++cp;) {
		int fl;

		fl = 0;
		switch(*cp) {
		case 'a':
			fl |= RB_ASKNAME;
			break;
		case 'c':
			fl |= RB_CONFIG;
			break;
		case 'd':
			fl |= RB_KDB;
			break;
		case 's':
			fl |= RB_SINGLE;
			break;
		default:
			printf("unknown option `%c'\n", *cp);
			break;
		}
		boothowto |= fl;
	}
}

void
consinit(void)
{
	static int consinit_called = 0;

	if (consinit_called != 0)
		return;

	consinit_called = 1;

	platform_init_cons();
}

void
board_startup(void)
{
        if (boothowto & RB_CONFIG) {
#ifdef BOOT_CONFIG
		user_config();
#else
		printf("kernel does not support -c; continuing..\n");
#endif
	}
}

void
bootconfig_dram(BootConfig *bootconfig, psize_t *memstart, psize_t *memsize)
{
	int loop;

	if (bootconfig->dramblocks == 0)
		panic("%s: dramblocks not set up!", __func__);

	*memstart = bootconfig->dram[0].address;
	*memsize = bootconfig->dram[0].pages * PAGE_SIZE;
	printf("memory size derived from u-boot\n");
	for (loop = 0; loop < bootconfig->dramblocks; loop++) {
		printf("bootconf.mem[%d].address = %08x pages %d/0x%08x\n",
		    loop, bootconfig->dram[loop].address, bootconfig->dram[loop].pages,
			bootconfig->dram[loop].pages * PAGE_SIZE);
	}
}


code:
/*	$OpenBSD: armv7_machdep.h,v 1.5 2015/07/15 21:09:40 jsg Exp $	*/
/*
 * Copyright (c) 2013 Sylvestre Gallon <ccna.syl@gmail.com>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef __PLATFORMVAR_H__
#define __PLATFORMVAR_H__

void platform_init(void);
void platform_powerdown(void);
void platform_watchdog_reset(void);
void platform_init_cons(void);
void platform_disable_l2_if_needed(void);
const char *platform_boot_name(void);
const char *platform_board_name(void);
struct board_dev *platform_board_devs();

struct armv7_platform {
	const char *boot_name;
	const char *(*board_name)(void);
	struct board_dev *devs;
	void (*board_init)(void);
	void (*smc_write)(bus_space_tag_t, bus_space_handle_t, bus_size_t,
	    uint32_t, uint32_t);
	void (*init_cons)(void);
	void (*watchdog_reset)(void);
	void (*powerdown)(void);
	void (*disable_l2_if_needed)(void);
};

#endif /* __PLATFORMVAR_H__ */

license: unknown


code:
/*	$OpenBSD: armv7_start.S,v 1.3 2015/05/18 23:56:47 jsg Exp $	*/
/*	$NetBSD: lubbock_start.S,v 1.1 2003/06/18 10:51:15 bsh Exp $ */

/*
 * Copyright (c) 2002, 2003  Genetec Corporation.  All rights reserved.
 * Written by Hiroyuki Bessho for Genetec Corporation.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of Genetec Corporation may not be used to endorse or
 *    promote products derived from this software without specific prior
 *    written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``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 GENETEC CORPORATION
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <machine/asm.h>
#include <arm/armreg.h>
#include <arm/pte.h>

#undef	DOMAIN_CLIENT	/* XXX */
#include "assym.h"

/*
 * CPWAIT -- Canonical method to wait for CP15 update.
 * NOTE: Clobbers the specified temp reg.
 * copied from arm/arm/cpufunc_asm_xscale.S
 * XXX: better be in a common header file.
 */
#define	CPWAIT_BRANCH							 \
	sub	pc, pc, #4

#define	CPWAIT(tmp)							 \
	mrc	p15, 0, tmp, c2, c0, 0	/* arbitrary read of CP15 */	;\
	mov	tmp, tmp		/* wait for it to complete */	;\
	CPWAIT_BRANCH			/* branch to next insn */

/*
 * Kernel start routine for OMAP
 * this code is excuted at the very first after the kernel is loaded
 * by U-Boot.
 *
 * This code makes a number of assumptions.
 * 1) it is running in RAM.
 * 2) it is run at a fairly well known offset from the beginning of
 *    a ram section.
 * 3) the memory region around the kernel will be at least about 32MB
 * 4) memory just below the kernel can be used by the kernel
 * 5) memory at the start of the ram section may not be useable
 *    it may contain bootloader/u-boot
 * 6) the fdt/kernel parameters in arg r0-r2 may point outside the
 *    32MB of ram (it likely should be copied very early)
 *
 */
	.text

	.global	_C_LABEL(bootstrap_start)
_C_LABEL(bootstrap_start):
	/* Save U-Boot arguments */
	mov	r6, r0
	mov	r7, r1
	mov	r8, r2

	/*
	 *  Kernel is loaded in SDRAM (0xX0200000..), and is expected to run
	 *  in VA 0xc0200000..
	 *
	 * which base memory address the kernel is located is unknown
	 * however the kernel should be located at 0x00300000 offset
	 * from that ram area. copy the PC into a register and strip
	 * the low bits
	 */

	mov r9, pc
	and r9, r9, #0xf0000000	// Leave the memory base in r9

	/* create the bootstrap MMU table at offset 0x00200000 */

	/* build page table from scratch */
	orr	r0, r9, #0x00200000
	adr	r4, mmu_init_table

	mov	r2, r9, lsr #18
	ldr	r3, [r4, #8]
	bic	r3, r3, #0xf0000000
	orr	r3, r3, r9
	str	r2, [r4, #4]
	str	r3, [r4, #8]
	str	r3, [r4, #0x14] // ram address for 0xc0000000
	add	r3, r3, #0x01000000
	str	r3, [r4, #0x20] // ram address for 0x00000000 (vectors)

	/*
	 * the first entry has two fields that need to be updated for
	 * specific ram configuration of this board.
	 */
	b	3f

2:
	str	r3, [r0, r2]
	add	r2, r2, #4
	add	r3, r3, #(L1_S_SIZE)
	adds	r1, r1, #-1
	bhi	2b
3:
	ldmia	r4!, {r1,r2,r3}   /* # of sections, PA|attr, VA */
	cmp	r1, #0
	bne	2b

	mcr	p15, 0, r0, c2, c0, 0	/* Set TTB */
	mcr	p15, 0, r0, c8, c7, 0	/* Flush TLB */

	/* Set the Domain Access register.  Very important! */
        mov     r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT)
	mcr	p15, 0, r0, c3, c0, 0

	/* Enable MMU */
	mrc	p15, 0, r0, c1, c0, 0
	orr	r0, r0, #CPU_CONTROL_MMU_ENABLE
	mcr	p15, 0, r0, c1, c0, 0
	CPWAIT(r0)

	/* Restore U-Boot arguments */
	mov	r0, r6
	mov	r1, r7
	mov	r2, r8

	/* Jump to kernel code in TRUE VA */
	adr	r6, Lstart
	ldr	pc, [r6]

Lstart:
	.word	start

#define MMU_INIT(va,pa,n_sec,attr) \
	.word	n_sec					    ; \
	.word	4*((va)>>L1_S_SHIFT)			    ; \
	.word	(pa)|(attr)				    ;

mmu_init_table:
	/* map SDRAM VA==PA, WT cacheable */
	MMU_INIT(0x00000000, 0x00000000, 64, L1_TYPE_S|L1_S_C|L1_S_V7_AP(AP_KRW))
mmu_init_table2:
	/* map VA 0xc0000000..0xc3ffffff to PA 0xa0000000..0xa3ffffff */
	MMU_INIT(0xc0000000, 0x00000000, 64, L1_TYPE_S|L1_S_C|L1_S_V7_AP(AP_KRW))
	MMU_INIT(0x00000000, 0x00000000, 1, L1_TYPE_S|L1_S_C|L1_S_V7_AP(AP_KRW))

	.word 0	/* end of table */

	.text

/*-
 * Copyright (c) 2011
 *	Ben Gray <ben.r.gray@gmail.com>.
 * All rights reserved.
 *
 * Based heavily on the Linux OMAP secure API
 *    Copyright (C) 2010 Texas Instruments, Inc.
 *    Written by Santosh Shilimkar <santosh.shilimkar@ti.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.
 * 3. The name of the author may 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.
 */

/**
 *	omap4_smc_call - issues a secure monitor API call
 *	@r0: contains the monitor API number
 *	@r1: contains the value to set
 *
 *	This function will send a secure monitor call to the internal rom code in
 *	the trust mode. The rom code expects that r0 will contain the value and
 *	r12 will contain the API number, so internally the function swaps the
 *	register settings around.  The trust mode code may also alter all the cpu
 *	registers so everything (including the lr register) is saved on the stack
 *	before the call.
 *
 *	RETURNS:
 *	nothing
 */
ENTRY(omap4_smc_call)
	stmfd   sp!, {r2-r12, lr}
	mov     r12, r0
	mov     r0, r1
#if 0
	dsb
#else
	.word	0xf57ff040
#endif
#if 0
	smc     #0	/* XXX or #1 ??? */
#else
	.word	0xe1600070
#endif
	ldmfd   sp!, {r2-r12, pc}


code:
/* $OpenBSD: armv7var.h,v 1.9 2015/06/08 06:33:16 jsg Exp $ */
/*
 * Copyright (c) 2005,2008 Dale Rahn <drahn@openbsd.com>
 * Copyright (c) 2012-2013 Patrick Wildt <patrick@blueri.se>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef __ARMV7VAR_H__
#define __ARMV7VAR_H__

/* Boards device list */
struct board_dev {
	char	*name;
	int	unit;
};

struct armv7_board {
	uint32_t		board_id;
	const char		*name;
	struct board_dev	*devs;
	void			(*init)(void);
};

/* Needed by omap, imx, sunxi */
struct armv7_softc {
	struct device sc_dv;

	struct board_dev *sc_board_devs;
};

/* Physical memory range for on-chip devices. */

struct armv7mem {
	bus_addr_t	addr;
	bus_size_t	size;
};

#define ARMV7_DEV_NMEM 6
#define ARMV7_DEV_NIRQ 4
#define ARMV7_DEV_NDMA 4

/* Descriptor for all on-chip devices. */
struct armv7_dev {
	char	*name;			/* driver name or made up name */
	int	unit;			/* driver instance number or -1 */
	struct	armv7mem mem[ARMV7_DEV_NMEM]; /* memory ranges */
	int	irq[ARMV7_DEV_NIRQ];	/* IRQ number(s) */
	int	dma[ARMV7_DEV_NDMA];	/* DMA chan number(s) */
};

/* Passed as third arg to attach functions. */
struct armv7_attach_args {
	struct armv7_dev	*aa_dev;
	bus_space_tag_t		aa_iot;
	bus_dma_tag_t		aa_dmat;
};

extern struct armv7_dev *armv7_devs;

void	armv7_set_devs(struct armv7_dev *);
struct	armv7_dev *armv7_find_dev(const char *, int);
int	armv7_match(struct device *, void *, void *);
void	armv7_attach(struct device *, struct device *, void *);
int	armv7_submatch(struct device *, void *, void *);

/* board identification - from uboot */
#define BOARD_ID_OMAP3_BEAGLE 1546
#define BOARD_ID_OMAP3_OVERO 1798
#define BOARD_ID_VEXPRESS 2272
#define BOARD_ID_OMAP4_PANDA 2791
#define BOARD_ID_EXYNOS4_SMDKC210 2838
#define BOARD_ID_EXYNOS4_NURI 3379
#define BOARD_ID_IMX6_PHYFLEX 3529
#define BOARD_ID_AM335X_BEAGLEBONE 3589
#define BOARD_ID_IMX6_SABRELITE 3769
#define BOARD_ID_EXYNOS5_CHROMEBOOK 3774
#define BOARD_ID_IMX6_SABRESD 3980
#define BOARD_ID_SUN4I_A10 4104
#define BOARD_ID_IMX6_NOVENA 4269
#define BOARD_ID_IMX6_UTILITE 4273
#define BOARD_ID_SUN7I_A20 4283
#define BOARD_ID_IMX6_WANDBOARD 4412
#define BOARD_ID_IMX6_HUMMINGBOARD 4773
#define BOARD_ID_IMX6_UDOO 4800
#define BOARD_ID_IMX6_CUBOXI 4821
extern uint32_t board_id;

#endif /* __ARMV7VAR_H__ */


code:
/*	$OpenBSD: autoconf.c,v 1.3 2015/05/19 03:30:54 jsg Exp $	*/
/*	$NetBSD: autoconf.c,v 1.2 2001/09/05 16:17:36 matt Exp $	*/

/*
 * Copyright (c) 1994-1998 Mark Brinicombe.
 * Copyright (c) 1994 Brini.
 * 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 Mark Brinicombe for
 *      the NetBSD project.
 * 4. The name of the company nor the name of the author may 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 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.
 *
 * RiscBSD kernel project
 *
 * autoconf.c
 *
 * Autoconfiguration functions
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/reboot.h>
#include <sys/disklabel.h>
#include <sys/device.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/malloc.h>

#include <machine/bootconfig.h>
#include <machine/intr.h>
#include <machine/bus.h>

#include <armv7/armv7/armv7_machdep.h>

struct device *bootdv = NULL;
extern char *hw_prod;

void dumpconf(void);

void
device_register(struct device *dev, void *aux)
{
}

/*
 * void cpu_configure()
 *
 * Configure all the root devices
 * The root devices are expected to configure their own children
 */
void
cpu_configure(void)
{
	int len;
	const char *name = platform_board_name();
	if (name) {
		len = strlen(name) + 1;
		hw_prod = malloc(len, M_DEVBUF, M_NOWAIT);
		if (hw_prod)
			strlcpy(hw_prod, name, len);
	}

	softintr_init();

	/*
	 * Since various PCI interrupts could be routed via the ICU
	 * (for PCI devices in the bridge) we need to set up the ICU
	 * now so that these interrupts can be established correctly
	 * i.e. This is a hack.
	 */

	config_rootfound("mainbus", NULL);

	/*
	 * We can not know which is our root disk, defer
	 * until we can checksum blocks to figure it out.
	 */
	cold = 0;

	/* Time to start taking interrupts so lets open the flood gates .... */
	(void)spl0();

}

/*
 * Now that we are fully operational, we can checksum the
 * disks, and using some heuristics, hopefully are able to
 * always determine the correct root disk.
 */
void
diskconf(void)
{
	dev_t tmpdev;

#if 0
	/*
	 * Configure root, swap, and dump area.  This is
	 * currently done by running the same checksum
	 * algorithm over all known disks, as was done in
	 * /boot.  Then we basically fixup the *dev vars
	 * from the info we gleaned from this.
	 */
	dkcsumattach();
#endif

	/* Lookup boot device from boot if not set by configuration */
	if (bootdv == NULL) {
		int len;
		char *p;

		/* boot_file is of the form wd0a:/bsd, we want 'wd0a' */
		if ((p = strchr(boot_file, ':')) != NULL)
			len = p - boot_file;
		else
			len = strlen(boot_file);

		bootdv = parsedisk(boot_file, len, 0, &tmpdev);
	}
	if (bootdv == NULL)
		printf("boot device: lookup '%s' failed.\n", boot_file);
	else
		printf("boot device: %s\n", bootdv->dv_xname);
	setroot(bootdv, 0, RB_USERREQ);
	dumpconf();
}

struct nam2blk nam2blk[] = {
	{ "wd",		16 },
	{ "sd",		24 },
	{ "cd",		26 },
	{ "rd",		18 },
	{ "raid",	71 },
	{ NULL,		-1 }
};


code: #	$OpenBSD: genassym.cf,v 1.1 2013/09/04 14:38:25 patrick Exp $


code:
/* $OpenBSD: intr.c,v 1.3 2015/06/13 07:16:37 jsg Exp $ */
/*
 * Copyright (c) 2011 Dale Rahn <drahn@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 <sys/systm.h>
#include <sys/param.h>
#include <sys/timetc.h>

#include <dev/clock_subr.h>
#include <arm/cpufunc.h>
#include <machine/cpu.h>
#include <machine/intr.h>

int arm_dflt_splraise(int);
int arm_dflt_spllower(int);
void arm_dflt_splx(int);
void arm_dflt_setipl(int);
void *arm_dflt_intr_establish(int irqno, int level, int (*func)(void *),
    void *cookie, char *name);
void arm_dflt_intr_disestablish(void *cookie);
const char *arm_dflt_intr_string(void *cookie);

void arm_dflt_intr(void *);
void arm_intr(void *);

#define SI_TO_IRQBIT(x) (1 << (x))
uint32_t arm_smask[NIPL];

struct arm_intr_func arm_intr_func = {
	arm_dflt_splraise,
	arm_dflt_spllower,
	arm_dflt_splx,
	arm_dflt_setipl,
	arm_dflt_intr_establish,
	arm_dflt_intr_disestablish,
	arm_dflt_intr_string
};

void (*arm_intr_dispatch)(void *) = arm_dflt_intr;

void
arm_intr(void *frame)
{
	/* XXX - change this to have irq_dispatch use function pointer */
	(*arm_intr_dispatch)(frame);
}
void
arm_dflt_intr(void *frame)
{
	panic("arm_dflt_intr() called");
}

void *arm_intr_establish(int irqno, int level, int (*func)(void *),
    void *cookie, char *name)
{
	return arm_intr_func.intr_establish(irqno, level, func, cookie, name);
}
void arm_intr_disestablish(void *cookie)
{
	arm_intr_func.intr_disestablish(cookie);
}
const char *arm_intr_string(void *cookie)
{
	return arm_intr_func.intr_string(cookie);
}

int
arm_dflt_splraise(int newcpl)
{
	struct cpu_info *ci = curcpu();
	int oldcpl;

	oldcpl = ci->ci_cpl;

	if (newcpl < oldcpl)
		newcpl = oldcpl;

	ci->ci_cpl = newcpl;

	return oldcpl;
}

int
arm_dflt_spllower(int newcpl)
{
	struct cpu_info *ci = curcpu();
	int oldcpl;

	oldcpl = ci->ci_cpl;

	splx(newcpl);

	return oldcpl;
}

void
arm_dflt_splx(int newcpl)
{
	struct cpu_info *ci = curcpu();

	if (ci->ci_ipending & arm_smask[newcpl])
		arm_do_pending_intr(newcpl);
	ci->ci_cpl = newcpl;
}

void
arm_dflt_setipl(int newcpl)
{
	struct cpu_info *ci = curcpu();

	ci->ci_cpl = newcpl;
}

void *arm_dflt_intr_establish(int irqno, int level, int (*func)(void *),
    void *cookie, char *name)
{
	panic("arm_dflt_intr_establish called");
}

void arm_dflt_intr_disestablish(void *cookie)
{
	panic("arm_dflt_intr_disestablish called");
}

const char *
arm_dflt_intr_string(void *cookie)
{
	panic("arm_dflt_intr_string called");
}

void
arm_setsoftintr(int si)
{
	struct cpu_info *ci = curcpu();
	int oldirqstate;

	/* XXX atomic? */
	oldirqstate = disable_interrupts(I32_bit);
	ci->ci_ipending |= SI_TO_IRQBIT(si);

	restore_interrupts(oldirqstate);

	/* Process unmasked pending soft interrupts. */
	if (ci->ci_ipending & arm_smask[ci->ci_cpl])
		arm_do_pending_intr(ci->ci_cpl);
}

void
arm_do_pending_intr(int pcpl)
{
	struct cpu_info *ci = curcpu();
	static int processing = 0;
	int oldirqstate;

	oldirqstate = disable_interrupts(I32_bit);

	if (processing == 1) {
		/* Don't use splx... we are here already! */
		arm_intr_func.setipl(pcpl);
		restore_interrupts(oldirqstate);
		return;
	}

#define DO_SOFTINT(si, ipl) \
	if ((ci->ci_ipending & arm_smask[pcpl]) &	\
	    SI_TO_IRQBIT(si)) {						\
		ci->ci_ipending &= ~SI_TO_IRQBIT(si);			\
		arm_intr_func.setipl(ipl);				\
		restore_interrupts(oldirqstate);			\
		softintr_dispatch(si);					\
		oldirqstate = disable_interrupts(I32_bit);		\
	}

	do {
		DO_SOFTINT(SI_SOFTTTY, IPL_SOFTTTY);
		DO_SOFTINT(SI_SOFTNET, IPL_SOFTNET);
		DO_SOFTINT(SI_SOFTCLOCK, IPL_SOFTCLOCK);
		DO_SOFTINT(SI_SOFT, IPL_SOFT);
	} while (ci->ci_ipending & arm_smask[pcpl]);

	/* Don't use splx... we are here already! */
	arm_intr_func.setipl(pcpl);
	processing = 0;
	restore_interrupts(oldirqstate);
}

void arm_set_intr_handler(int (*raise)(int), int (*lower)(int),
    void (*x)(int), void (*setipl)(int),
	void *(*intr_establish)(int irqno, int level, int (*func)(void *),
	    void *cookie, char *name),
	void (*intr_disestablish)(void *cookie),
	const char *(intr_string)(void *cookie),
	void (*intr_handle)(void *))
{
	arm_intr_func.raise		= raise;
	arm_intr_func.lower		= lower;
	arm_intr_func.x			= x;
	arm_intr_func.setipl		= setipl;
	arm_intr_func.intr_establish	= intr_establish;
	arm_intr_func.intr_disestablish	= intr_disestablish;
	arm_intr_func.intr_string	= intr_string;
	arm_intr_dispatch		= intr_handle;
}

void
arm_init_smask(void)
{
	static int inited = 0;
	int i;

	if (inited)
		return;
	inited = 1;

	for (i = IPL_NONE; i <= IPL_HIGH; i++)  {
		arm_smask[i] = 0;
		if (i < IPL_SOFT)
			arm_smask[i] |= SI_TO_IRQBIT(SI_SOFT);
		if (i < IPL_SOFTCLOCK)
			arm_smask[i] |= SI_TO_IRQBIT(SI_SOFTCLOCK);
		if (i < IPL_SOFTNET)
			arm_smask[i] |= SI_TO_IRQBIT(SI_SOFTNET);
		if (i < IPL_SOFTTTY)
			arm_smask[i] |= SI_TO_IRQBIT(SI_SOFTTTY);
	}
}

/* provide functions for asm */
#undef splraise
#undef spllower
#undef splx

int
splraise(int ipl)
{
	return arm_intr_func.raise(ipl);
}

int _spllower(int ipl); /* XXX - called from asm? */
int
_spllower(int ipl)
{
	return arm_intr_func.lower(ipl);
}
int
spllower(int ipl)
{
	return arm_intr_func.lower(ipl);
}

void
splx(int ipl)
{
	arm_intr_func.x(ipl);
}

#ifdef DIAGNOSTIC
void
arm_splassert_check(int wantipl, const char *func)
{
	int oldipl = curcpu()->ci_cpl;

	if (oldipl < wantipl) {
		splassert_fail(wantipl, oldipl, func);
		/*
		 * If the splassert_ctl is set to not panic, raise the ipl
		 * in a feeble attempt to reduce damage.
		 */
		arm_intr_func.setipl(wantipl);
	}

	if (wantipl == IPL_NONE && curcpu()->ci_idepth != 0) {
		splassert_fail(-1, curcpu()->ci_idepth, func);
	}
}
#endif

void arm_dflt_delay(u_int usecs);

struct {
	void	(*delay)(u_int);
	void	(*initclocks)(void);
	void	(*setstatclockrate)(int);
	void	(*mpstartclock)(void);
} arm_clock_func = {
	arm_dflt_delay,
	NULL,
	NULL,
	NULL
};

void
arm_clock_register(void (*initclock)(void), void (*delay)(u_int),
    void (*statclock)(int), void(*mpstartclock)(void))
{
	arm_clock_func.initclocks = initclock;
	arm_clock_func.delay = delay;
	arm_clock_func.setstatclockrate = statclock;
	arm_clock_func.mpstartclock = mpstartclock;
}

void
delay(u_int usec)
{
	arm_clock_func.delay(usec);
}

void
cpu_initclocks(void)
{
	if (arm_clock_func.initclocks == NULL)
		panic("initclocks function not initialized yet");

	arm_clock_func.initclocks();
}

void
arm_dflt_delay(u_int usecs)
{
	int j;
	/* BAH - there is no good way to make this close */
	/* but this isn't supposed to be used after the real clock attaches */
	for (; usecs > 0; usecs--)
		for (j = 100; j > 0; j--)
			;

}

todr_chip_handle_t todr_handle;

/*
 * inittodr:
 *
 *      Initialize time from the time-of-day register.
 */
#define MINYEAR         2003    /* minimum plausible year */
void
inittodr(time_t base)
{
	time_t deltat;
	struct timeval rtctime;
	struct timespec ts;
	int badbase;

	if (base < (MINYEAR - 1970) * SECYR) {
		printf("WARNING: preposterous time in file system\n");
		/* read the system clock anyway */
		base = (MINYEAR - 1970) * SECYR;
		badbase = 1;
	} else
		badbase = 0;

	if (todr_handle == NULL ||
	    todr_gettime(todr_handle, &rtctime) != 0 ||
	    rtctime.tv_sec == 0) {
		/*
		 * Believe the time in the file system for lack of
		 * anything better, resetting the TODR.
		 */
		rtctime.tv_sec = base;
		rtctime.tv_usec = 0;
		if (todr_handle != NULL && !badbase) {
			printf("WARNING: preposterous clock chip time\n");
			resettodr();
		}
		ts.tv_sec = rtctime.tv_sec;
		ts.tv_nsec = rtctime.tv_usec * 1000;
		tc_setclock(&ts);
		goto bad;
	} else {
		ts.tv_sec = rtctime.tv_sec;
		ts.tv_nsec = rtctime.tv_usec * 1000;
		tc_setclock(&ts);
	}

	if (!badbase) {
		/*
		 * See if we gained/lost two or more days; if
		 * so, assume something is amiss.
		 */
		deltat = rtctime.tv_sec - base;
		if (deltat < 0)
			deltat = -deltat;
		if (deltat < 2 * SECDAY)
			return;         /* all is well */
		printf("WARNING: clock %s %ld days\n",
		    rtctime.tv_sec < base ? "lost" : "gained",
		    (long)deltat / SECDAY);
	}
 bad:
	printf("WARNING: CHECK AND RESET THE DATE!\n");
}

/*
 * resettodr:
 *
 *      Reset the time-of-day register with the current time.
 */
void
resettodr(void)
{
	struct timeval rtctime;

	if (time_second == 1)
		return;

	microtime(&rtctime);

	if (todr_handle != NULL &&
	   todr_settime(todr_handle, &rtctime) != 0)
		printf("resettodr: failed to set time\n");
}

void
setstatclockrate(int new)
{
	if (arm_clock_func.setstatclockrate == NULL) {
		panic("arm_clock_func.setstatclockrate not intialized");
	}
	arm_clock_func.setstatclockrate(new);
}


code:
/*	$OpenBSD: platform.c,v 1.4 2015/07/15 21:09:40 jsg Exp $	*/
/*
 * Copyright (c) 2014 Patrick Wildt <patrick@blueri.se>
 *
 * 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/types.h>
#include <sys/systm.h>

#include <machine/bus.h>

#include <armv7/armv7/armv7var.h>
#include <armv7/armv7/armv7_machdep.h>
#include <arm/cortex/smc.h>

#include "imx.h"
#include "omap.h"
#include "sunxi.h"
#include "exynos.h"
#include "vexpress.h"

static struct armv7_platform *platform;

struct armv7_platform *imx_platform_match(void);
struct armv7_platform *omap_platform_match(void);
struct armv7_platform *sunxi_platform_match(void);
struct armv7_platform *exynos_platform_match(void);
struct armv7_platform *vexpress_platform_match(void);

struct armv7_platform * (*plat_match[])(void) = {
#if NIMX > 0
	imx_platform_match,
#endif
#if NOMAP > 0
	omap_platform_match,
#endif
#if NSUNXI > 0
	sunxi_platform_match,
#endif
#if NEXYNOS > 0
	exynos_platform_match,
#endif
#if NVEXPRESS > 0
	vexpress_platform_match,
#endif
};

void
platform_init(void)
{
	int i;

	for (i = 0; i < nitems(plat_match); i++) {
		platform = plat_match[i]();
		if (platform != NULL)
			break;
	}
	if (platform == NULL)
		panic("no matching armv7 platform");
	platform->board_init();
}

const char *
platform_boot_name(void)
{
	return platform->boot_name;
}

void
platform_smc_write(bus_space_tag_t iot, bus_space_handle_t ioh, bus_size_t off,
    uint32_t op, uint32_t val)
{
	platform->smc_write(iot, ioh, off, op, val);
}

void
platform_init_cons(void)
{
	platform->init_cons();
}

void
platform_watchdog_reset(void)
{
	platform->watchdog_reset();
}

void
platform_powerdown(void)
{
	platform->powerdown();
}

const char *
platform_board_name(void)
{
	return (platform->board_name());
}

void
platform_disable_l2_if_needed(void)
{
	platform->disable_l2_if_needed();
}

struct board_dev *
platform_board_devs()
{
	return (platform->devs);
}


code:
/* $OpenBSD: uboot_tags.c,v 1.1 2013/09/04 14:38:25 patrick Exp $ */
/*
 * Copyright (c) 2011 Dale Rahn <drahn@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 <sys/param.h>
#include <sys/systm.h>

#include <machine/bootconfig.h>

struct uboot_tag_header {
	uint32_t	size;
	uint32_t	tag;
};
struct uboot_tag_core {
	uint32_t	flags;
	uint32_t	pagesize;
	uint32_t	rootdev;
};
struct uboot_tag_serialnr {
	uint32_t	low;
	uint32_t	high;
};
struct uboot_tag_revision {
	uint32_t	rev;
};
struct uboot_tag_mem32 {
	uint32_t	size;
	uint32_t	start;
};
struct uboot_tag_cmdline {
	char		cmdline[1];
};

#define ATAG_CORE	0x54410001
#define	ATAG_MEM	0x54410002
#define	ATAG_CMDLINE	0x54410009
#define	ATAG_SERIAL	0x54410006
#define	ATAG_REVISION	0x54410007
#define	ATAG_NONE	0x00000000
struct uboot_tag {
	struct uboot_tag_header hdr;
	union {
		struct uboot_tag_core		core;
		struct uboot_tag_mem32		mem;
		struct uboot_tag_revision	rev;
		struct uboot_tag_serialnr	serialnr;
		struct uboot_tag_cmdline	cmdline;
	} u;
};

int parse_uboot_tags(void *handle);
int
parse_uboot_tags(void *handle)
{
	uint32_t *p;
	struct uboot_tag *tag;
	int i;

	p = handle;
	tag = (struct uboot_tag *)p;

	while(tag != NULL && tag->hdr.size < 4096 &&
	    tag->hdr.tag != ATAG_NONE) {
		switch (tag->hdr.tag) {
		case ATAG_CORE:
			printf("atag core flags %x pagesize %x rootdev %x\n",
			    tag->u.core.flags,
			    tag->u.core.pagesize,
			    tag->u.core.rootdev);
			break;
		case ATAG_MEM:
			printf("atag mem start 0x%08x size 0x%x\n",
			    tag->u.mem.start,
			    tag->u.mem.size);

			i = bootconfig.dramblocks -1;
			if (bootconfig.dramblocks != 0 &&
			    (tag->u.mem.start == bootconfig.dram[i].address +
			    (bootconfig.dram[i].pages * PAGE_SIZE))) {
				bootconfig.dram[i].pages =
				    bootconfig.dram[i].pages +
				    tag->u.mem.size / PAGE_SIZE;
			} else {
				i = bootconfig.dramblocks;
				bootconfig.dram[i].address = tag->u.mem.start;
				bootconfig.dram[i].pages = tag->u.mem.size
				    / PAGE_SIZE;
				bootconfig.dramblocks = i + 1;
			}

			break;
		case ATAG_CMDLINE:
			printf("atag cmdline [%s]\n",
			    tag->u.cmdline.cmdline);
			strncpy(bootconfig.bootstring, tag->u.cmdline.cmdline,
			    sizeof(bootconfig.bootstring));
			break;
		case ATAG_SERIAL:
			printf("atag serial 0x%08x:%08x\n",
			    tag->u.serialnr.high,
			    tag->u.serialnr.low);
			break;
		case ATAG_REVISION:
			printf("atag revision %08x\n",
			    tag->u.rev.rev);
			break;
		default:
			printf("uboot tag unknown 0x%08x size %d\n",
			    tag->hdr.tag,
			    tag->hdr.size);
		}
		p = p + tag->hdr.size;
		tag = (struct uboot_tag *)p;
	}

	return 0;
}


code:
/.cvsignore/1.5/Wed May 20 01:44:20 2015//TOPENBSD_5_8_BASE
D


code:
#	$OpenBSD: GENERIC,v 1.6 2015/07/17 17:02:52 jsg Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
#
# For further information on hardware support for this architecture, see
# the intro(4) man page.  For further information about kernel options
# for this architecture, see the options(4) man page.  For an explanation
# of each device driver in this file see the section 4 man page for the
# device.

machine		armv7 arm
include		"../../../conf/GENERIC"

makeoptions	KERNEL_BASE_VIRT="0xc0300000"

maxusers	32			# estimated number of users
option		CPU_ARMv7		# Support the ARMv7

#option WSDISPLAY_COMPAT_USL		# VT handling
option WSDISPLAY_COMPAT_RAWKBD		# can get raw scancodes
option WSDISPLAY_DEFAULTSCREENS=1
#option WSDISPLAY_COMPAT_PCVT		# emulate some ioctls

option		CONF_HAVE_GPIO
option		USBVERBOSE

config		bsd	swap generic

# The main bus device
mainbus0	at root
cpu0		at mainbus?

# Cortex-A9
cortex0		at mainbus?
ampintc*	at cortex?
amptimer*	at cortex?
agtimer*	at cortex?
armliicc*	at cortex?

# iMX
imx0		at mainbus?		# iMX SoC
imxccm*		at imx?			# clock control module
imxiomuxc*	at imx?			# iomux controller
imxdog*		at imx?			# watchdog timer
imxocotp*	at imx?			# on-chip otp controller
imxgpio*	at imx?			# user-visible GPIO pins?
imxenet*	at imx?			# ethernet
imxuart*	at imx?			# onboard uarts
imxiic*		at imx?			# i2c
iic*		at imxiic?
imxesdhc*	at imx?			# SDHC controller
sdmmc*		at imxesdhc?		# SD/MMC bus
ahci*		at imx?			# AHCI/SATA
ehci*		at imx?			# EHCI (shim)
usb*		at ehci?

# OMAP3xxx/OMAP4xxx SoC
omap0		at mainbus?
omapid*		at omap?

# OMAP on-chip devices
intc*		at omap?		# OMAP3 interrupt controller
edma*		at omap?		# OMAP3 dma controller
prcm*		at omap?		# power/clock controller
sitaracm*	at omap?		# sitara control module
omdog*		at omap?		# watchdog timer
omgpio*		at omap?		# user-visible GPIO pins?
gpio*		at omgpio?
#tiiic*		at omap?
#iic*		at tiiic?
gptimer*	at omap?		# general purpose timers
dmtimer*	at omap?		# am335x dual mode timers
omusbtll*	at omap?
cpsw*		at omap?
com*		at omap?		# onboard uarts
ommmc*		at omap?		# SD/MMC card controller
sdmmc*		at ommmc?		# SD/MMC bus

ehci*		at omap?		# EHCI (shim)
usb*		at ehci?

# Sunxi A1x/A20 SoC
sunxi0		at mainbus?

# Sunxi on-chip devices
a1xintc*	at sunxi?		# A1x interrupt controller
sxipio*		at sunxi?		# GPIO pins for leds & PHYs
gpio*		at sxipio?
sxiccmu*	at sunxi?		# Clock Control Module/Unit
sxitimer*	at sunxi?
sxidog*		at sunxi?		# watchdog timer
sxirtc*		at sunxi?		# Real Time Clock
sxiuart*	at sunxi?		# onboard UARTs
sxie*		at sunxi?
ahci*		at sunxi?		# AHCI/SATA (shim)
ehci*		at sunxi?		# EHCI (shim)
usb*		at ehci?	#flags 0x1
#ohci*		at sunxi?
#usb*		at ohci?

# ARM Versatile Express
vexpress0	at mainbus?
sysreg*		at vexpress?
pluart*		at vexpress?
plrtc*		at vexpress?
virtio*		at vexpress?

# Exynos
exynos0		at mainbus?
exdisplay*	at exynos?
wsdisplay*	at exdisplay? console ?
exclock*	at exynos?
expower*	at exynos?
exsysreg*	at exynos?
exmct*		at exynos?
exdog*		at exynos?
exgpio*		at exynos?
exiic*		at exynos?
iic*		at exiic?
exehci*		at exynos?
ehci*		at exehci?
exesdhc*	at exynos?
sdmmc*		at exesdhc?
exuart*		at exynos?

crosec*		at iic?
wskbd*		at crosec? mux 1
tpspmic*	at iic?

# virtio devices
vioblk*		at virtio?
vio*		at virtio?
viomb*		at virtio?
viornd*		at virtio?
vioscsi*	at virtio?

# USB bus support
usb*		at ehci?	flags 0x1

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

atphy*		at mii?			# Attansic F1 PHYs
rgephy*		at mii?			# Realtek 8169S/8110S PHY
rlphy*		at mii?			# Realtek 8139 internal PHYs
ukphy*		at mii?			# "unknown" PHYs

scsibus*	at scsi?
sd*		at scsibus?
cd*		at scsibus?
st*		at scsibus?
ch*		at scsibus?
uk*		at scsibus?

# GPIO "pin bus" drivers
gpioiic*	at gpio?		# I2C bus bit-banging
iic*		at gpioiic?
gpioow*		at gpio?		# 1-Wire bus bit-banging
onewire*	at gpioow?

# 1-Wire devices
option	ONEWIREVERBOSE
owid*		at onewire?		# ID
owsbm*		at onewire?		# Smart Battery Monitor
owtemp*		at onewire?		# Temperature
owctr*		at onewire?		# Counter device

# Pseudo-Devices
pseudo-device hotplug         1       # devices hot plugging

# mouse & keyboard multiplexor pseudo-devices
pseudo-device   wsmux           2


code:
#	$OpenBSD: Makefile.armv7,v 1.12 2015/06/08 06:33:16 jsg Exp $

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

.include <bsd.own.mk>

SIZE?=	size
STRIP?=	strip

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

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

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

CMACHFLAGS=	-ffreestanding -msoft-float -march=armv6 -Wa,-march=armv7a
CMACHFLAGS+=	-fno-builtin-printf -fno-builtin-snprintf \
		-fno-builtin-vsnprintf -fno-builtin-log \
		-fno-builtin-log2 -fno-builtin-malloc ${NOPIE_FLAGS}
.if ${IDENT:M-DNO_PROPOLICE}
CMACHFLAGS+=	-fno-stack-protector
.endif

COPTS?=		-O2
CFLAGS=		${DEBUG} ${CWARNFLAGS} ${CMACHFLAGS} ${COPTS} ${PIPE}
AFLAGS=		-D_LOCORE -x assembler-with-cpp ${CWARNFLAGS} ${CMACHFLAGS}
LINKFLAGS=	-T ldscript --warn-common -nopie

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

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

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

%OBJS

%CFILES

%SFILES

# load lines for config "xxx" will be emitted as:
# xxx: ${SYSTEM_DEP} swapxxx.o
#	${SYSTEM_LD_HEAD}
#	${SYSTEM_LD} swapxxx.o
#	${SYSTEM_LD_TAIL}
SYSTEM_HEAD=	${_mach}_start.o locore.o param.o ioconf.o
SYSTEM_OBJ=	${SYSTEM_HEAD} ${OBJS}
SYSTEM_DEP=	Makefile ${SYSTEM_OBJ}
SYSTEM_LD_HEAD=	@rm -f $@
SYSTEM_LD_HEAD+=; \
		cat ${_archdir}/conf/ldscript.head ${_archdir}/conf/ldscript.tail | \
		    sed -e 's/@KERNEL_BASE_PHYS@/0/' \
		    -e 's/@KERNEL_BASE_VIRT@/${KERNEL_BASE_VIRT}/' \
		    -e 's/(KERNEL_BASE_phys)/(KERNEL_BASE_virt)/' > ldscript

SYSTEM_LD=	@echo ${LD} ${LINKFLAGS} -o $@ '$${SYSTEM_HEAD} vers.o $${OBJS}'; \
		${LD} ${LINKFLAGS} -o $@ ${SYSTEM_HEAD} vers.o ${OBJS}
SYSTEM_LD_TAIL=	@${SIZE} $@; chmod 755 $@

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

%LOAD

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

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

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

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

ioconf.o: ioconf.c
	${NORMAL_C}

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

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

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

depend:
	@touch $@

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

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

${_mach}_start.o: ${_machdir}/${_mach}/${_mach}_start.S
locore.o: ${_archdir}/${_arch}/locore.S assym.h
in_cksum_arm.o fiq_subr.o bcopyinout.o copystr.o sigcode.o: assym.h
vectors.o cpuswitch7.o exception.o bcopy_page.o irq_dispatch.o: assym.h
armv7_start.o: assym.h

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

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

# until we get native booting working, put this in the tree.
KERNADDR_OMAP=0x80300000
KERNADDR_IMX=0x10300000
KERNADDR_SUNXI=0x40300000
KERNADDR_EXYNOS=0x40300000
KERNADDR_VEXPRESSA15=0x80300000
KERNADDR_VEXPRESSA9=0x60300000

.for SOC in IMX OMAP SUNXI EXYNOS VEXPRESSA9 VEXPRESSA15
bsd.${SOC}.umg: bsd
	mkuboot -a arm -o linux -e ${KERNADDR_${SOC}} -l ${KERNADDR_${SOC}} \
	    bsd bsd.${SOC}.umg
.endfor

bsd.rd: bsd
	cp bsd bsd.rd
	$S/../distrib/${_mach}/ramdisk/rdsetroot < $S/../distrib/${_mach}/ramdisk/mr.fs bsd.rd

%RULES


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

machine		armv7 arm

makeoptions	KERNEL_BASE_VIRT="0xc0300000"

maxusers	4			# estimated number of users
option		CPU_ARMv7		# Support the ARMv7

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

option		MINIROOTSIZE=10240
option		RAMDISK_HOOKS

option		FFS
option		MSDOSFS
option		INET6
option		EXT2FS

option		USBVERBOSE

config		bsd root on rd0a swap on rd0b

# The main bus device
mainbus0	at root
cpu0		at mainbus?

# Cortex-A9
cortex0		at mainbus?
ampintc*	at cortex?
amptimer*	at cortex?
agtimer*	at cortex?
armliicc*	at cortex?

# iMX
imx0		at mainbus?		# iMX SoC
imxccm*		at imx?			# clock control module
imxiomuxc*	at imx?			# iomux controller
imxdog*		at imx?			# watchdog timer
imxocotp*	at imx?			# on-chip otp controller
imxgpio*	at imx?			# user-visible GPIO pins?
imxenet*	at imx?			# ethernet
imxuart*	at imx?			# onboard uarts
imxiic*		at imx?			# i2c
iic*		at imxiic?
imxesdhc*	at imx?			# SDHC controller
sdmmc*		at imxesdhc?		# SD/MMC bus
ahci*		at imx?			# AHCI/SATA
ehci*		at imx?			# EHCI (shim)
usb*		at ehci?

# OMAP3xxx/OMAP4xxx SoC
omap0		at mainbus?
omapid*		at omap?

# OMAP on-chip devices
intc*		at omap?		# OMAP3 interrupt controller
edma*		at omap?		# OMAP3 dma controller
prcm*		at omap?		# power/clock controller
sitaracm*	at omap?		# sitara control module
omdog*		at omap?		# watchdog timer
omgpio*		at omap?		# user-visible GPIO pins?
gpio*		at omgpio?
#tiiic*		at omap?
#iic*		at tiiic?
gptimer*	at omap?		# general purpose timers
dmtimer*	at omap?		# am335x dual mode timers
omusbtll*	at omap?
cpsw*		at omap?
com*		at omap?		# onboard uarts
ommmc*		at omap?		# SD/MMC card controller
sdmmc*		at ommmc?		# SD/MMC bus

ehci*		at omap?		# EHCI (shim)
usb*		at ehci?

# Sunxi A1x/A20 SoC
sunxi0		at mainbus?

# Sunxi on-chip devices
a1xintc*	at sunxi?		# A1x interrupt controller
sxipio*		at sunxi?		# GPIO pins for leds & PHYs
gpio*		at sxipio?
sxiccmu*	at sunxi?		# Clock Control Module/Unit
sxitimer*	at sunxi?
sxidog*		at sunxi?		# watchdog timer
sxirtc*		at sunxi?		# Real Time Clock
sxiuart*	at sunxi?		# onboard UARTs
sxie*		at sunxi?
ahci*		at sunxi?		# AHCI/SATA (shim)
ehci*		at sunxi?		# EHCI (shim)
usb*		at ehci?	#flags 0x1
#ohci*		at sunxi?
#usb*		at ohci?

# ARM Versatile Express
vexpress0	at mainbus?
sysreg*		at vexpress?
pluart*		at vexpress?
plrtc*		at vexpress?
virtio*		at vexpress?

# Exynos
exynos0		at mainbus?
exdisplay*	at exynos?
wsdisplay*	at exdisplay? console ?
exclock*	at exynos?
expower*	at exynos?
exsysreg*	at exynos?
exmct*		at exynos?
exdog*		at exynos?
exgpio*		at exynos?
exiic*		at exynos?
iic*		at exiic?
exehci*		at exynos?
ehci*		at exehci?
exesdhc*	at exynos?
sdmmc*		at exesdhc?
exuart*		at exynos?

crosec*		at iic?
wskbd*		at crosec? mux 1
tpspmic*	at iic?

# virtio devices
vioblk*		at virtio?
vio*		at virtio?
viomb*		at virtio?
viornd*		at virtio?
vioscsi*	at virtio?

# USB bus support
usb*		at ehci?	flags 0x1

uhub*		at usb?
uhub*		at uhub?
uhidev*		at uhub?
ukbd*		at uhidev?
wskbd*		at ukbd? mux 1
umass*		at uhub?
aue*		at uhub?		# ADMtek AN986 Pegasus Ethernet
atu*		at uhub?		# Atmel AT76c50x based 802.11b
axe*		at uhub?		# ASIX Electronics AX88172 USB Ethernet
axen*		at uhub?		# ASIX Electronics AX88179 USB Ethernet
cue*		at uhub?		# CATC USB-EL1201A based Ethernet
kue*		at uhub?		# Kawasaki KL5KUSB101B based Ethernet
smsc*		at uhub?		# SMSC LAN95xx Ethernet
cdce*		at uhub?		# CDC Ethernet
udav*		at uhub?		# Davicom DM9601 based Ethernet
mos*		at uhub?		# MOSCHIP MCS7730/7830 10/100 Ethernet
url*		at uhub?		# Realtek RTL8150L based adapters
wi*		at uhub?		# WaveLAN IEEE 802.11DS
upl*		at uhub?		# Prolific PL2301/PL2302 host-to-host
ugl*		at uhub?		# Genesys Logic GL620USB-A host-to-host
ural*		at uhub?		# Ralink RT2500
rum*		at uhub?		# Ralink RT2501USB/RT2601USB
run*		at uhub?		# Ralink RT2700U/RT2800U/RT3000U
zyd*		at uhub?		# Zydas ZD1211/ZD1211B
upgt*		at uhub?		# Conexant/Intersil PrismGT SoftMAC USB
urtw*		at uhub?		# Realtek 8187
urtwn*		at uhub?		# Realtek RTL8188CU/RTL8192CU
rsu*		at uhub?		# Realtek RTL8188SU/RTL8191SU/RTL8192SU
uath*		at uhub?		# Atheros AR5005UG/AR5005UX
otus*		at uhub?		# Atheros AR9001U
athn*		at uhub?		# Atheros AR9002U

atphy*		at mii?			# Attansic F1 PHYs
rgephy*		at mii?			# Realtek 8169S/8110S PHY
rlphy*		at mii?			# Realtek 8139 internal PHYs
ukphy*		at mii?			# "unknown" PHYs

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

pseudo-device	loop 1
pseudo-device	bpfilter 1
pseudo-device	rd 1


code:
#	$OpenBSD: files.armv7,v 1.13 2015/06/08 06:33:16 jsg Exp $

maxpartitions	16
maxusers	2 8 64

major	{wd = 16}
major	{sd = 24}
major	{cd = 26}
major	{rd = 18}

define	fdt {}
file	arch/armv7/fdt/fdt_machdep.c	fdt	needs-flag

file	arch/arm/arm/conf.c

#interrupt API layer
file	arch/armv7/armv7/intr.c

# u-boot argument support
file	arch/armv7/armv7/uboot_tags.c

# CPU support and integrated peripherals
file	arch/arm/arm/irq_dispatch.S
file	arch/arm/arm/softintr.c

# Generic MD files
file	arch/armv7/armv7/armv7.c
file	arch/armv7/armv7/armv7_machdep.c
file	arch/armv7/armv7/autoconf.c
file	arch/armv7/armv7/platform.c
file	arch/arm/arm/disksubr.c			disk

include "dev/sdmmc/files.sdmmc"

# Media Independent Interface (mii)
include "dev/mii/files.mii"

# Machine-independent I2C drivers
include "dev/i2c/files.i2c"

# Machine-independent SCSI drivers
include "scsi/files.scsi"
include "dev/atapiscsi/files.atapiscsi"

# Machine-independent ATA drivers
include "dev/ata/files.ata"

# Include WSCONS stuff
include "dev/wscons/files.wscons"
include "dev/rasops/files.rasops"
include "dev/wsfont/files.wsfont"

# Include USB stuff
include "dev/usb/files.usb"

# PCI and virtio
include "dev/pci/files.pci"

# Machine-independent GPIO drivers
include "dev/gpio/files.gpio"

# Machine-independent 1-Wire drivers
include "dev/onewire/files.onewire"

# SoC includes
include "arch/armv7/imx/files.imx"
include "arch/armv7/omap/files.omap"
include "arch/armv7/sunxi/files.sunxi"
include "arch/armv7/exynos/files.exynos"
include "arch/armv7/vexpress/files.vexpress"


code:
/* $OpenBSD: crosec.c,v 1.1 2015/01/26 02:48:24 bmercer Exp $ */
/*
 * Copyright (c) 2013 Patrick Wildt <patrick@blueri.se>
 *
 * 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/device.h>
#include <sys/sensors.h>
#include <sys/malloc.h>

#include <armv7/exynos/crosecvar.h>

#ifdef DEBUG
#define DPRINTF(x) printf x
#else
#define DPRINTF(x)
#endif

int	cros_ec_match(struct device *, void *, void *);
void	cros_ec_attach(struct device *, struct device *, void *);

int	cros_ec_send_command(struct cros_ec_softc *, uint8_t,
		int, const void *, int, uint8_t **, int);
int	cros_ec_command(struct cros_ec_softc *, uint8_t,
		int, const void *, int, void *, int);
int	cros_ec_command_inptr(struct cros_ec_softc *, uint8_t,
		int, const void *, int, uint8_t **, int);
int	cros_ec_i2c_command(struct cros_ec_softc *, uint8_t,
		int, const uint8_t *, int, uint8_t **, int);
int	cros_ec_calc_checksum(const uint8_t *, int);

struct cfattach crosec_ca = {
	sizeof(struct cros_ec_softc), cros_ec_match, cros_ec_attach
};

struct cfdriver crosec_cd = {
	NULL, "crosec", DV_DULL
};

int
cros_ec_match(struct device *parent, void *match, void *aux)
{
	struct i2c_attach_args *ia = aux;

	if (strcmp(ia->ia_name, "crosec") == 0)
		return 1;
	return 0;
}

void
cros_ec_attach(struct device *parent, struct device *self, void *aux)
{
	struct cros_ec_softc *sc = (struct cros_ec_softc *)self;
	struct i2c_attach_args *ia = aux;

	sc->sc_tag = ia->ia_tag;
	sc->sc_addr = ia->ia_addr;

	printf("\n");

	if (cros_ec_check_version(sc)) {
		printf("%s: could not initialize ChromeOS EC\n", __func__);
		return;
	}

	if (cros_ec_init_keyboard(sc)) {
		printf("%s: could not initialize keyboard\n", __func__);
		return;
	}
}

int
cros_ec_check_version(struct cros_ec_softc *sc)
{
	struct ec_params_hello req;
	struct ec_response_hello *resp;

	sc->cmd_version_is_supported = 1;
	if (cros_ec_command_inptr(sc, EC_CMD_HELLO, 0, &req, sizeof(req),
				(uint8_t **)&resp, sizeof(*resp)) > 0) {
		/* new version supported */
		sc->cmd_version_is_supported = 1;
	} else {
		printf("%s: old EC interface not supported\n", __func__);
		return -1;
	}

	return 0;
}

int
cros_ec_i2c_command(struct cros_ec_softc *sc, uint8_t cmd, int cmd_version,
		const uint8_t *out, int out_len, uint8_t **in, int in_len)
{
	int out_bytes, in_bytes, ret;
	uint8_t *ptr = sc->out;
	uint8_t *inptr = sc->in;

	inptr += sizeof(uint64_t); /* returned data should be 64-bit aligned */
	if (!sc->cmd_version_is_supported) {
		/* old-style */
		*ptr++ = cmd;
		out_bytes = out_len + 1;
		in_bytes = in_len + 2;
		inptr--; /* status byte */
	} else {
		/* new-style */
		*ptr++ = EC_CMD_VERSION0 + cmd_version;
		*ptr++ = cmd;
		*ptr++ = out_len;
		out_bytes = out_len + 4;
		in_bytes = in_len + 3;
		inptr -= 2; /* status byte, length */
	}
	memcpy(ptr, out, out_len);
	ptr += out_len;

	if (sc->cmd_version_is_supported)
		*ptr++ = (uint8_t)
			 cros_ec_calc_checksum(sc->out, out_len + 3);

	iic_acquire_bus(sc->sc_tag, 0);
	ret = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
	    sc->sc_addr, NULL, 0, &sc->out, out_bytes, 0);
	if (ret) {
		DPRINTF(("%s: I2C write failed\n", __func__));
		iic_release_bus(sc->sc_tag, 0);
		return -1;
	}

	ret = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
	    sc->sc_addr, NULL, 0, inptr, in_bytes, 0);
	if (ret) {
		DPRINTF(("%s: I2C read failed\n", __func__));
		iic_release_bus(sc->sc_tag, 0);
		return -1;
	}

	iic_release_bus(sc->sc_tag, 0);

	if (*inptr != EC_RES_SUCCESS) {
		DPRINTF(("%s: bad result\n", __func__));
		return -(int)*inptr;
	}

	if (sc->cmd_version_is_supported) {
		int len, csum;

		len = inptr[1];
		if (len > sizeof(sc->in)) {
			DPRINTF(("%s: Received length too large\n", __func__));
			return -1;
		}
		csum = cros_ec_calc_checksum(inptr, 2 + len);
		if (csum != inptr[2 + len]) {
			DPRINTF(("%s: Invalid checksum\n", __func__));
			return -1;
		}
		in_len = min(in_len, len);
	}

	*in = sc->in + sizeof(uint64_t);

	return in_len;
}

int
cros_ec_send_command(struct cros_ec_softc *sc, uint8_t cmd, int cmd_version,
		const void *out, int out_len, uint8_t **in, int in_len)
{
	return cros_ec_i2c_command(sc, cmd, cmd_version,
				(const uint8_t *)out, out_len, in, in_len);
}

int
cros_ec_command(struct cros_ec_softc *sc, uint8_t cmd,
		int cmd_version, const void *out, int out_len,
		void *in, int in_len) {
	uint8_t *in_buffer;
	int len;

	len = cros_ec_command_inptr(sc, cmd, cmd_version, out, out_len,
			&in_buffer, in_len);

	if (len > 0) {
		if (in && in_buffer) {
			len = min(in_len, len);
			memmove(in, in_buffer, len);
		}
	}
	return len;
}

int
cros_ec_command_inptr(struct cros_ec_softc *sc, uint8_t cmd,
		int cmd_version, const void *out, int out_len,
		uint8_t **inp, int in_len) {
	uint8_t *in;
	int len;

	len = cros_ec_send_command(sc, cmd, cmd_version,
			(const uint8_t *)out, out_len, &in, in_len);

	/* Wait for the command to complete. */
	if (len == -EC_RES_IN_PROGRESS) {
		struct ec_response_get_comms_status *resp;

		do {
			int ret;

			delay(50000);
			cros_ec_send_command(sc, EC_CMD_GET_COMMS_STATUS, 0,
					NULL, 0,
					(uint8_t **)&resp, sizeof(*resp));
			if (ret < 0)
				return ret;

			//timeout CROS_EC_CMD_TIMEOUT_MS
			//return -EC_RES_TIMEOUT
		} while (resp->flags & EC_COMMS_STATUS_PROCESSING);

		/* Let's get the response. */
		len = cros_ec_send_command(sc, EC_CMD_RESEND_RESPONSE, 0,
				out, out_len, &in, in_len);
	}

	if (inp != NULL)
		*inp = in;

	return len;
}

int
cros_ec_calc_checksum(const uint8_t *data, int size)
{
	int csum, i;

	for (i = csum = 0; i < size; i++)
		csum += data[i];
	return csum & 0xff;
}

int
cros_ec_scan_keyboard(struct cros_ec_softc *sc, uint8_t *scan, int len)
{
	if (cros_ec_command(sc, EC_CMD_CROS_EC_STATE, 0, NULL, 0, scan,
			len) < len)
		return -1;

	return 0;
}

int
cros_ec_info(struct cros_ec_softc *sc, struct ec_response_cros_ec_info *info)
{
	if (cros_ec_command(sc, EC_CMD_CROS_EC_INFO, 0, NULL, 0, info,
				sizeof(*info)) < sizeof(*info))
		return -1;

	return 0;
}


code:
/* $OpenBSD: crosec_kbd.c,v 1.3 2015/07/19 01:13:27 bmercer Exp $ */
/*
 * Copyright (c) 2013 Patrick Wildt <patrick@blueri.se>
 *
 * 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/device.h>
#include <sys/sensors.h>
#include <sys/malloc.h>

#include <armv7/exynos/crosecvar.h>

#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wskbdvar.h>
#include <dev/wscons/wsksymdef.h>
#include <dev/wscons/wsksymvar.h>

void cros_ec_add_task(void *);
void cros_ec_poll_keystate(void *);
int cros_ec_get_keystate(struct cros_ec_softc *);

int cros_ec_keyboard_enable(void *, int);
void cros_ec_keyboard_set_leds(void *, int);
int cros_ec_keyboard_ioctl(void *, u_long, caddr_t, int, struct proc *);

struct wskbd_accessops cros_ec_keyboard_accessops = {
	cros_ec_keyboard_enable,
	cros_ec_keyboard_set_leds,
	cros_ec_keyboard_ioctl,
};

void cros_ec_keyboard_cngetc(void *, u_int *, int *);
void cros_ec_keyboard_cnpollc(void *, int);

struct wskbd_consops cros_ec_keyboard_consops = {
	cros_ec_keyboard_cngetc,
	cros_ec_keyboard_cnpollc,
};

/* XXX: assumes 8 rows, 13 cols, FDT */
#define KC(n) KS_KEYCODE(n)
static const keysym_t cros_ec_keyboard_keydesc_us[] = {
	KC(1),	KS_Caps_Lock,
	KC(3),	KS_b,
	KC(6),	KS_n,
	KC(10),	KS_Alt_R,
	KC(14),	KS_Escape,
	KC(16),	KS_g,
	KC(19),	KS_h,
	KC(24),	KS_BackSpace,
	KC(26),	KS_Control_L,
	KC(27),	KS_Tab,
	KC(29),	KS_t,
	KC(32),	KS_y,
	KC(42),	KS_5,
	KC(45),	KS_6,
	KC(52),	KS_Control_R,
	KC(53),	KS_a,
	KC(54),	KS_d,
	KC(55),	KS_f,
	KC(56),	KS_s,
	KC(57),	KS_k,
	KC(58),	KS_j,
	KC(61),	KS_l,
	KC(63),	KS_Return,
	KC(66),	KS_z,
	KC(67),	KS_c,
	KC(68),	KS_v,
	KC(69),	KS_x,
	KC(70),	KS_comma,
	KC(71),	KS_m,
	KC(72),	KS_Shift_L,
	KC(74),	KS_period,
	KC(76),	KS_space,
	KC(79),	KS_1,
	KC(80),	KS_3,
	KC(81),	KS_4,
	KC(82),	KS_2,
	KC(83),	KS_8,
	KC(84),	KS_7,
	KC(86),	KS_0,
	KC(87),	KS_9,
	KC(88),	KS_Alt_L,
	KC(92),	KS_q,
	KC(93),	KS_e,
	KC(94),	KS_r,
	KC(95),	KS_w,
	KC(96),	KS_i,
	KC(97),	KS_u,
	KC(98),	KS_Shift_R,
	KC(99),	KS_p,
	KC(100),	KS_o,
};

#define KBD_MAP(name, base, map) \
	{ name, base, sizeof(map)/sizeof(keysym_t), map }
static const struct wscons_keydesc cros_ec_keyboard_keydesctab[] = {
	KBD_MAP(KB_US,			0,	cros_ec_keyboard_keydesc_us),
	{0, 0, 0, 0}
};
struct wskbd_mapdata cros_ec_keyboard_keymapdata = {
	cros_ec_keyboard_keydesctab,
	KB_US,
};

int
cros_ec_init_keyboard(struct cros_ec_softc *sc)
{
	struct ec_response_cros_ec_info info;
	struct wskbddev_attach_args a;

	if (cros_ec_info(sc, &info)) {
		printf("%s: could not read KBC info\n", __func__);
		return (-1);
	}

	sc->keyboard.rows = info.rows;
	sc->keyboard.cols = info.cols;
	sc->keyboard.switches = info.switches;
	sc->keyboard.state = (uint8_t *)malloc(info.rows*info.cols,
			M_DEVBUF, M_WAITOK|M_ZERO);
	if (sc->keyboard.state == NULL)
		panic("%s: no memory available for keyboard states", __func__);

	/* FIXME: interrupt driven, please. */
	sc->keyboard.taskq = taskq_create("crosec-keyb", 1, IPL_TTY, 0);
	task_set(&sc->keyboard.task, cros_ec_poll_keystate, sc);
	timeout_set(&sc->keyboard.timeout, cros_ec_add_task, sc);

	/* XXX: ghosting */

	wskbd_cnattach(&cros_ec_keyboard_consops, sc, &cros_ec_keyboard_keymapdata);
	a.console = 1;

	a.keymap = &cros_ec_keyboard_keymapdata;
	a.accessops = &cros_ec_keyboard_accessops;
	a.accesscookie = sc;

	sc->keyboard.wskbddev = config_found((void *)sc, &a, wskbddevprint);

	timeout_add_sec(&sc->keyboard.timeout, 10);

	return 0;
}

void
cros_ec_add_task(void *arg)
{
	struct cros_ec_softc *sc = (struct cros_ec_softc *)arg;
	task_add(sc->keyboard.taskq, &sc->keyboard.task);
	timeout_add_msec(&sc->keyboard.timeout, 100);
}

void
cros_ec_poll_keystate(void *arg)
{
	struct cros_ec_softc *sc = (struct cros_ec_softc *)arg;
	cros_ec_get_keystate(sc);
}

int
cros_ec_get_keystate(struct cros_ec_softc *sc)
{
	int col, row, s;
	uint8_t state[sc->keyboard.cols];
	cros_ec_scan_keyboard(sc, state, sc->keyboard.cols);
	for (col = 0; col < sc->keyboard.cols; col++) {
		for (row = 0; row < sc->keyboard.rows; row++) {
			int off = row*sc->keyboard.cols;
			int pressed = !!(state[col] & (1 << row));
			if (pressed && !sc->keyboard.state[off+col]) {
				//printf("row %d col %d id %d pressed\n", row, col, off+col);
				sc->keyboard.state[off+col] = 1;
				if (sc->keyboard.polling)
					return off+col;
				s = spltty();
				wskbd_input(sc->keyboard.wskbddev, WSCONS_EVENT_KEY_DOWN, off+col);
				splx(s);
			} else if (!pressed && sc->keyboard.state[off+col]) {
				//printf("row %d col %d id %d released\n", row, col, off+col);
				sc->keyboard.state[off+col] = 0;
				if (sc->keyboard.polling)
					return off+col;
				s = spltty();
				wskbd_input(sc->keyboard.wskbddev, WSCONS_EVENT_KEY_UP, off+col);
				splx(s);
			} else if (sc->keyboard.state[off+col]) {
				//printf("row %d col %d id %d repeated\n", row, col, off+col);
			}
		}
	}
	return (-1);
}

void
cros_ec_keyboard_cngetc(void *v, u_int *type, int *data)
{
	struct cros_ec_softc *sc = v;
	int key;

	sc->keyboard.polling = 1;
	while ((key = cros_ec_get_keystate(sc)) == -1) {
		delay(10000);
	}
	sc->keyboard.polling = 0;

	*data = key;
	*type = sc->keyboard.state[key] ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN;
}

void
cros_ec_keyboard_cnpollc(void *v, int on)
{
}

int
cros_ec_keyboard_enable(void *v, int on)
{
	return 0;
}

void
cros_ec_keyboard_set_leds(void *v, int on)
{
}

int
cros_ec_keyboard_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
{
#ifdef WSDISPLAY_COMPAT_RAWKBD
	struct cros_ec_softc *sc = v;
#endif

	switch (cmd) {

	case WSKBDIO_GTYPE:
		*(int *)data = WSKBD_TYPE_ZAURUS;
		return 0;
	case WSKBDIO_SETLEDS:
		return 0;
	case WSKBDIO_GETLEDS:
		*(int *)data = 0;
		return 0;
#ifdef WSDISPLAY_COMPAT_RAWKBD
	case WSKBDIO_SETMODE:
		sc->keyboard.rawkbd = *(int *)data == WSKBD_RAW;
		return (0);
#endif

	}
	/* kbdioctl(...); */

	return -1;
}


code:
/* $OpenBSD: crosecvar.h,v 1.2 2015/07/19 01:13:27 bmercer Exp $ */
/*
 * Copyright (c) 2013 Patrick Wildt <patrick@blueri.se>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef CROSECVAR_H
#define CROSECVAR_H

#include <sys/timeout.h>
#include <sys/task.h>
#include <dev/i2c/i2cvar.h>
#include <armv7/exynos/ec_commands.h>

/* message sizes */
#define MSG_HEADER		0xec
#define MSG_HEADER_BYTES	3
#define MSG_TRAILER_BYTES	2
#define MSG_PROTO_BYTES		(MSG_HEADER_BYTES + MSG_TRAILER_BYTES)
#define MSG_BYTES		(EC_HOST_PARAM_SIZE + MSG_PROTO_BYTES)
#define MSG_BYTES_ALIGNED	((MSG_BYTES+8) & ~8)

#define min(a,b)	(((a)<(b))?(a):(b))

struct cros_ec_softc {
	struct device sc_dev;
	i2c_tag_t sc_tag;
	i2c_addr_t sc_addr;

	int cmd_version_is_supported;
	struct {
		int rows;
		int cols;
		int switches;
		uint8_t *state;

		/* wskbd bits */
		struct device *wskbddev;
		int rawkbd;
		int polling;

		/* polling */
		struct timeout timeout;
		struct taskq *taskq;
		struct task task;
	} keyboard;
	uint8_t in[MSG_BYTES_ALIGNED];
	uint8_t out[MSG_BYTES_ALIGNED];
};

int	cros_ec_check_version(struct cros_ec_softc *);
int	cros_ec_scan_keyboard(struct cros_ec_softc *, uint8_t *, int);
int	cros_ec_info(struct cros_ec_softc *, struct ec_response_cros_ec_info *);

int	cros_ec_init_keyboard(struct cros_ec_softc *);

#endif /* !CROSECVAR_H */