Module Name:    src
Committed By:   marty
Date:           Sun Dec  6 00:33:44 UTC 2015

Added Files:
        src/sys/arch/evbarm/exynos: exynos_machdep.c exynos_start.S platform.h

Log Message:
try 2


To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 src/sys/arch/evbarm/exynos/exynos_machdep.c \
    src/sys/arch/evbarm/exynos/exynos_start.S \
    src/sys/arch/evbarm/exynos/platform.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Added files:

Index: src/sys/arch/evbarm/exynos/exynos_machdep.c
diff -u /dev/null src/sys/arch/evbarm/exynos/exynos_machdep.c:1.1
--- /dev/null	Sun Dec  6 00:33:44 2015
+++ src/sys/arch/evbarm/exynos/exynos_machdep.c	Sun Dec  6 00:33:44 2015
@@ -0,0 +1,484 @@
+/*	$NetBSD: exynos_machdep.c,v 1.1 2015/12/06 00:33:44 marty Exp $ */
+
+/*
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Reinoud Zandijk.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: exynos_machdep.c,v 1.1 2015/12/06 00:33:44 marty Exp $");
+
+#include "opt_evbarm_boardtype.h"
+#include "opt_exynos.h"
+#include "opt_machdep.h"
+#include "opt_ddb.h"
+#include "opt_kgdb.h"
+#include "opt_ipkdb.h"
+#include "opt_md.h"
+#include "opt_sscom.h"
+#include "opt_arm_debug.h"
+
+#include "ukbd.h"
+#include "arml2cc.h"	// RPZ why is it not called opt_l2cc.h?
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/cpu.h>
+#include <sys/device.h>
+#include <sys/exec.h>
+#include <sys/kernel.h>
+#include <sys/ksyms.h>
+#include <sys/msgbuf.h>
+#include <sys/proc.h>
+#include <sys/reboot.h>
+#include <sys/termios.h>
+#include <sys/gpio.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <sys/conf.h>
+#include <dev/cons.h>
+#include <dev/md.h>
+
+#include <machine/db_machdep.h>
+#include <ddb/db_sym.h>
+#include <ddb/db_extern.h>
+#ifdef KGDB
+#include <sys/kgdb.h>
+#endif
+
+#include <machine/bootconfig.h>
+#include <arm/armreg.h>
+#include <arm/undefined.h>
+#include <arm/cortex/pl310_var.h>
+
+#include <arm/arm32/machdep.h>
+#include <arm/mainbus/mainbus.h>
+
+#include <arm/samsung/exynos4_reg.h>
+#include <arm/samsung/exynos5_reg.h>
+#include <arm/samsung/exynos_var.h>
+
+#include <evbarm/include/autoconf.h>
+#include <evbarm/exynos/platform.h>
+
+#include <dev/i2c/i2cvar.h>
+#include <dev/i2c/ddcreg.h>
+
+#include <dev/usb/ukbdvar.h>
+#include <net/if_ether.h>
+
+/* serial console stuff */
+#include "sscom.h"
+#include "opt_sscom.h"
+
+#include <arm/samsung/sscom_var.h>
+#include <arm/samsung/sscom_reg.h>
+
+extern const int num_exynos_uarts_entries;
+extern const struct sscom_uart_info exynos_uarts[];
+
+#ifndef CONSPEED
+#define CONSPEED 115200
+#endif	/* CONSPEED */
+#ifndef CONMODE
+#define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB | HUPCL)) | CS8) /* 8N1 */
+#endif	/* CONMODE */
+
+static const int conspeed = CONSPEED;
+static const int conmode = CONMODE;
+
+/*
+ * uboot passes 4 arguments to us.
+ *
+ * arg0 arg1 arg2 arg3 : the `bootargs' environment variable from the uboot
+ * context (in PA!)
+ *
+ * Note that the storage has to be in .data and not in .bss. On kernel start
+ * the .bss is cleared and this information would get lost.
+ */
+uintptr_t uboot_args[4] = { 0 };
+
+/*
+ * argument and boot configure storage
+ */
+BootConfig bootconfig;				/* for pmap's sake */
+char bootargs[MAX_BOOT_STRING] = "";		/* copied string from uboot */
+char *boot_args = NULL;				/* MI bootargs */
+char *boot_file = NULL;				/* MI bootfile */
+uint8_t uboot_enaddr[ETHER_ADDR_LEN] = {};
+
+
+/*
+ * kernel start and end from the linker
+ */
+extern char KERNEL_BASE_phys[];	/* physical start of kernel */
+extern char _end[];		/* physical end of kernel */
+#define KERNEL_BASE_PHYS	((paddr_t)KERNEL_BASE_phys)
+
+#define EXYNOS_IOPHYSTOVIRT(a) \
+    ((vaddr_t)(((a) - EXYNOS_CORE_PBASE) + EXYNOS_CORE_VBASE))
+
+static void exynos_reset(void);
+static void exynos_powerdown(void);
+/* XXX we have no framebuffer implementation yet so com is console XXX */
+int use_fb_console = false;
+
+
+/* prototypes */
+void consinit(void);
+#ifdef KGDB
+static void kgdb_port_init(void);
+#endif
+static void exynos_extract_mac_adress(void);
+void exynos_device_register(device_t self, void *aux);
+void exynos_device_register_post_config(device_t self, void *aux);
+
+/*
+ * Our static device mappings at fixed virtual addresses so we can use them
+ * while booting the kernel.
+ *
+ * Map the extents segment-aligned and segment-rounded in size to avoid L2
+ * page tables
+ */
+
+#define _A(a)	((a) & ~L1_S_OFFSET)
+#define _S(s)	(((s) + L1_S_SIZE - 1) & (~(L1_S_SIZE-1)))
+
+static const struct pmap_devmap e5_devmap[] = {
+	{
+		/* map in core IO space */
+		.pd_va    = _A(EXYNOS_CORE_VBASE),
+		.pd_pa    = _A(EXYNOS_CORE_PBASE),
+		.pd_size  = _S(EXYNOS5_CORE_SIZE),
+		.pd_prot  = VM_PROT_READ | VM_PROT_WRITE,
+		.pd_cache = PTE_NOCACHE
+	},
+	{
+		/* map in audiocore IO space */
+		.pd_va    = _A(EXYNOS5_AUDIOCORE_VBASE),
+		.pd_pa    = _A(EXYNOS5_AUDIOCORE_PBASE),
+		.pd_size  = _S(EXYNOS5_AUDIOCORE_SIZE),
+		.pd_prot  = VM_PROT_READ | VM_PROT_WRITE,
+		.pd_cache = PTE_NOCACHE
+	},
+	{0}
+};
+#undef _A
+#undef _S
+
+#ifdef PMAP_NEED_ALLOC_POOLPAGE
+static struct boot_physmem bp_highgig = {
+	.bp_pages = (KERNEL_VM_BASE - KERNEL_BASE) / NBPG,
+	.bp_freelist = VM_FREELIST_ISADMA,
+	.bp_flags = 0,
+};
+#endif
+
+#ifdef VERBOSE_INIT_ARM
+extern void exynos_putchar(int);
+
+static void
+exynos_putstr(const char *s)
+{
+	for (const char *p = s; *p; p++) {
+		exynos_putchar(*p);
+	}
+}
+
+static void
+exynos_printn(u_int n, int base)
+{
+	char *p, buf[(sizeof(u_int) * NBBY / 3) + 1 + 2 /* ALT + SIGN */];
+
+	p = buf;
+	do {
+		*p++ = hexdigits[n % base];
+	} while (n /= base);
+
+	do {
+		exynos_putchar(*--p);
+	} while (p > buf);
+}
+#define DPRINTF(...)		printf(__VA_ARGS__)
+#define DPRINT(x)		exynos_putstr(x)
+#define DPRINTN(x,b)		exynos_printn((x), (b))
+#else
+#define DPRINTF(...)
+#define DPRINT(x)
+#define DPRINTN(x,b)
+#endif
+
+extern void cortex_mpstart(void);
+
+/*
+ * u_int initarm(...)
+ *
+ * Our entry point from the assembly before main() is called.
+ * - take a copy of the config we got from uboot
+ * - init the physical console
+ * - setting up page tables for the kernel
+ */
+
+u_int
+initarm(void *arg)
+{
+	const struct pmap_devmap const *devmap;
+	bus_addr_t rambase;
+	psize_t ram_size;
+	DPRINT("initarm:");
+
+	DPRINT(" mpstart<0x");
+	DPRINTN((uint32_t)cortex_mpstart, 16);
+	DPRINT(">");
+
+	/* allocate/map our basic memory mapping */
+    	switch (EXYNOS_PRODUCT_FAMILY(exynos_soc_id)) {
+#if defined(EXYNOS5)
+	case EXYNOS5_PRODUCT_FAMILY:
+		devmap = e5_devmap;
+		rambase = EXYNOS5_SDRAM_PBASE;
+		break;
+#endif
+	default:
+		/* Won't work, but... */
+		panic("Unknown product family %llx",
+		   EXYNOS_PRODUCT_FAMILY(exynos_soc_id));
+	}
+	DPRINT(" devmap");
+	pmap_devmap_register(devmap);
+
+	/* bootstrap soc. uart_address is determined in exynos_start */
+	paddr_t uart_address = armreg_tpidruro_read();
+	DPRINT(" bootstrap");
+	exynos_bootstrap(EXYNOS_CORE_VBASE, EXYNOS_IOPHYSTOVIRT(uart_address));
+
+	/* set up CPU / MMU / TLB functions */
+	DPRINT(" cpufunc");
+	if (set_cpufuncs())
+		panic("cpu not recognized!");
+
+	/* get normal console working */
+	DPRINT(" consinit");
+ 	consinit();
+
+#ifdef KGDB
+	kgdb_port_init();
+#endif
+
+#ifdef VERBOSE_INIT_ARM
+	printf("\nuboot arg = %#"PRIxPTR", %#"PRIxPTR", %#"PRIxPTR", %#"PRIxPTR"\n",
+	    uboot_args[0], uboot_args[1], uboot_args[2], uboot_args[3]);
+	printf("Exynos SoC ID %08x\n", exynos_soc_id);
+
+	printf("initarm: cbar=%#x\n", armreg_cbar_read());
+#endif
+
+	/* determine cpu0 clock rate */
+	exynos_clocks_bootstrap();
+#ifdef VERBOSE_INIT_ARM
+	printf("CPU0 now running on %"PRIu64" Mhz\n", exynos_get_cpufreq()/(1000*1000));
+#endif
+
+	cpu_reset_address = exynos_reset;
+	cpu_powerdown_address = exynos_powerdown;
+
+#ifdef VERBOSE_INIT_ARM
+	printf("\nNetBSD/evbarm (Exynnos 5422) booting ...\n");
+#endif
+
+#ifdef BOOT_ARGS
+	char mi_bootargs[] = BOOT_ARGS;
+	parse_mi_bootargs(mi_bootargs);
+#endif
+	boot_args = bootargs;
+	parse_mi_bootargs(boot_args);
+	exynos_extract_mac_adress();
+
+	/* Don't map the DMA reserved region */
+//	ram_size = (psize_t) 0xC0000000 - 0x40000000;
+	ram_size = (psize_t) 0xb0000000 - 0x40000000;
+
+#ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS
+	const bool mapallmem_p = true;
+#ifndef PMAP_NEED_ALLOC_POOLPAGE
+	if (ram_size > KERNEL_VM_BASE - KERNEL_BASE) {
+		printf("%s: dropping RAM size from %luMB to %uMB\n",
+		   __func__, (unsigned long) (ram_size >> 20),
+		   (KERNEL_VM_BASE - KERNEL_BASE) >> 20);
+		ram_size = KERNEL_VM_BASE - KERNEL_BASE;
+	}
+#endif
+#else
+	const bool mapallmem_p = false;
+#endif
+
+	/* Fake bootconfig structure for the benefit of pmap.c. */
+	bootconfig.dramblocks = 1;
+	bootconfig.dram[0].address = rambase;
+	bootconfig.dram[0].pages = ram_size / PAGE_SIZE;
+	KASSERT((armreg_pfr1_read() & ARM_PFR1_SEC_MASK) != 0);
+
+	arm32_bootmem_init(bootconfig.dram[0].address, ram_size,
+	    KERNEL_BASE_PHYS);
+	arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_LOW, 0, devmap,
+	    mapallmem_p);
+
+	/* we've a specific device_register routine */
+	evbarm_device_register = exynos_device_register;
+	evbarm_device_register_post_config = exynos_device_register_post_config;
+
+	/*
+	 * If we couldn't map all of memory via TTBR1, limit the memory the
+	 * kernel can allocate from to be from the highest available 1GB.
+	 */
+#ifdef PMAP_NEED_ALLOC_POOLPAGE
+	if (atop(ram_size) > bp_highgig.bp_pages) {
+		arm_poolpage_vmfreelist = bp_highgig.bp_freelist;
+		return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE,
+		    &bp_highgig, 1);
+	}
+#endif
+
+	return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0);
+}
+
+void
+consinit(void)
+{
+	static bool consinit_called;
+
+	if (consinit_called)
+		return;
+	consinit_called = true;
+
+#if NSSCOM > 0
+	bus_space_tag_t bst = &exynos_bs_tag;
+	bus_addr_t iobase = armreg_tpidruro_read();
+	bus_space_handle_t bsh = EXYNOS_IOPHYSTOVIRT(iobase);
+	u_int i;
+	/*	
+	 * No need to guess at the UART frequency since we can calculate it.
+	 */
+	uint32_t freq = conspeed
+	   * (16 * (bus_space_read_4(bst, bsh, SSCOM_UBRDIV) + 1)
+		 + bus_space_read_4(bst, bsh, SSCOM_UFRACVAL));
+	freq = (freq + conspeed / 2) / 1000;
+	freq *= 1000;
+
+	/* go through all entries */
+	for (i = 0; i < num_exynos_uarts_entries; i++) {
+		/* attach console */
+		if (exynos_uarts[i].iobase + EXYNOS_CORE_PBASE == iobase)
+			break;
+	}
+	KASSERT(i < num_exynos_uarts_entries);
+	printf("%s: attaching console @ %#"PRIxPTR" (%u HZ, %u bps)\n",
+	    __func__, iobase, freq, conspeed);
+	if (sscom_cnattach(bst, exynos_core_bsh, &exynos_uarts[i],
+			   conspeed, freq, conmode))
+		panic("Serial console can not be initialized");
+#ifdef VERBOSE_INIT_ARM
+	printf("Console initialized\n");
+#endif
+#else
+#error only serial console is supported
+#if NUKBD > 0
+	/* allow USB keyboards to become console */
+	ukbd_cnattach();
+#endif /* NUKBD */
+#endif
+}
+
+
+/* extract ethernet mac address from bootargs */
+static void
+exynos_extract_mac_adress(void)
+{
+	char *str, *ptr;
+	int i, v1, v2, val;
+
+#define EXPECT_COLON() {\
+		v1 = *ptr++; \
+		if (v1 != ':') break; \
+	}
+#define EXPECT_HEX(v) {\
+		(v) = (v) >= '0' && (v) <= '9'? (v) - '0' : \
+		      (v) >= 'a' && (v) <= 'f'? (v) - 'a' + 10 : \
+		      (v) >= 'A' && (v) <= 'F'? (v) - 'A' + 10 : -1; \
+		if ((v) < 0) break; \
+	}
+#define EXPECT_2HEX(val) {\
+		v1 = *ptr++; EXPECT_HEX(v1); \
+		v2 = *ptr++; EXPECT_HEX(v2); \
+		val = (v1 << 4) | v2; \
+	}
+	if (get_bootconf_option(boot_args, "ethaddr",
+			BOOTOPT_TYPE_STRING, &str)) {
+		for (i = 0, ptr = str; i < sizeof(uboot_enaddr); i++) {
+			if (i)
+				EXPECT_COLON();
+			EXPECT_2HEX(val);
+			uboot_enaddr[i] = val;
+		}
+		if (i != sizeof(uboot_enaddr)) {
+			printf( "Ignoring invalid MAC address '%s' passed "
+				"as boot paramter `ethaddr'\n", str);
+			memset((char *) uboot_enaddr, 0, sizeof(uboot_enaddr));
+		}
+	}
+#undef EXPECT_2HEX
+#undef EXPECT_HEX
+#undef EXPECT_COLON
+}
+
+/*
+ * Exynos specific tweaks
+ */
+/*
+ * The external USB devices are clocked trough the DEBUG clkout
+ * XXX is this Odroid specific? XXX
+ */
+void
+exynos_init_clkout_for_usb(void)
+{
+	/* Select XUSBXTI as source for CLKOUT */
+	bus_space_write_4(&exynos_bs_tag, exynos_pmu_bsh,
+		EXYNOS_PMU_DEBUG_CLKOUT, 0x1000);
+}
+
+static void
+exynos_reset(void)
+{
+}
+
+static void
+exynos_powerdown(void)
+{
+}
Index: src/sys/arch/evbarm/exynos/exynos_start.S
diff -u /dev/null src/sys/arch/evbarm/exynos/exynos_start.S:1.1
--- /dev/null	Sun Dec  6 00:33:44 2015
+++ src/sys/arch/evbarm/exynos/exynos_start.S	Sun Dec  6 00:33:44 2015
@@ -0,0 +1,308 @@
+/*	$NetBSD: exynos_start.S,v 1.1 2015/12/06 00:33:44 marty Exp $	*/
+
+/*-
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas of 3am Software Foundry.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opt_exynos.h"
+#include "opt_sscom.h"
+#include "opt_cpuoptions.h"
+#include "opt_cputypes.h"
+#include "opt_multiprocessor.h"
+#include "opt_arm_debug.h"
+
+#include <arm/asm.h>
+#include <arm/armreg.h>
+#include "assym.h"
+
+#include <arch/arm/samsung/exynos_reg.h>
+#include <arch/arm/samsung/exynos5_reg.h>
+
+#include <evbarm/exynos/platform.h>
+
+RCSID("$NetBSD: exynos_start.S,v 1.1 2015/12/06 00:33:44 marty Exp $")
+
+
+#if defined(VERBOSE_INIT_ARM)
+
+#define	XPUTC(n)	mov r0, n; bl exynos_putc
+#if KERNEL_BASE_VOFFSET == 0
+#define	XPUTC2(n)	mov r0, n; bl exynos_putc
+#else
+#define	XPUTC2(n)	mov r0, n; blx r11
+#endif
+#ifdef __ARMEB__
+#define COM_BSWAP
+#endif
+#else
+#define	XPUTC(n)
+#define	XPUTC2(n)
+#endif
+
+#define INIT_MEMSIZE	128
+
+#define	TEMP_L1_TABLE	(KERNEL_BASE - KERNEL_BASE_VOFFSET + INIT_MEMSIZE * L1_S_SIZE - L1_TABLE_SIZE)
+
+#define	MD_CPU_HATCH	_C_LABEL(gtmr_init_cpu_clock)
+
+/*
+ * Kernel start routine for Exynos 5422 boards running on uboot firmware
+ * At this point, this code has been loaded into SDRAM
+ * and the MMU is off
+ */
+#ifdef KERNEL_BASES_EQUAL
+	.text
+#else
+	.section .start,"ax",%progbits
+#endif
+
+	.global	_C_LABEL(exynos_start)
+_C_LABEL(exynos_start):
+#ifdef __ARMEB__
+	setend	be			/* force big endian */
+#endif
+
+	/* Leave HYP (hypervisor or monitor) mode and move into supervisor mode
+	 * with IRQs/FIQs disabled. */
+	mrs	r0, cpsr
+	and	r0, r0, #(PSR_MODE)	/* Mode is in the low 5 bits of CPSR */
+	teq	r0, #(PSR_HYP32_MODE)	/* Hyp Mode? */
+	bne	1f
+	/* Ensure that IRQ, and FIQ will be disabled after eret */
+	mrs	r0, cpsr
+	bic	r0, r0, #(PSR_MODE)
+	orr	r0, r0, #(PSR_SVC32_MODE)
+	orr	r0, r0, #(I32_bit | F32_bit)
+	msr	spsr_cxsf, r0
+	/* Exit hypervisor mode */
+	adr	lr, 1f
+	msr	elr_hyp, lr
+	eret
+1:
+
+	/*
+	 * Save any arguments passed to us.  If .start is not at
+	 * 0x80000000 but .text is, we can't directly use the address that
+	 * the linker gave us.  In that case convert the virtual address to the
+	 * physical address by using KERNEL_BASE_VOFFSET.
+	 */
+	movw	r4, #:lower16:uboot_args
+	movt	r4, #:upper16:uboot_args
+#if KERNEL_BASE_VOFFSET != 0
+	sub	r4, r4, #KERNEL_BASE_VOFFSET
+#endif
+	stmia	r4, {r0-r3}			// Save the arguments
+
+	movw	r4, #:lower16:bootargs
+	movt	r4, #:upper16:bootargs
+#if KERNEL_BASE_VOFFSET != 0
+	sub	r4, r4, #KERNEL_BASE_VOFFSET
+#endif
+
+	cmp	r3, #0
+	beq	1f
+2:
+	ldrb	r0, [r3], #1
+	strb	r0, [r4], #1
+	teq	r0, #0
+	bne	2b
+
+1:
+
+	/*
+	 * For easy and early SoC / PoP dependency, retrieve the IDs
+	 */
+	movw	r6, #:lower16:EXYNOS_CORE_PBASE
+	movt	r6, #:upper16:EXYNOS_CORE_PBASE
+
+	ldr	r0, [r6, #EXYNOS_PROD_ID_OFFSET]	// load soc_id
+
+	movw	r4, #:lower16:exynos_soc_id
+	movt	r4, #:upper16:exynos_soc_id
+	sub	r4, r4, #KERNEL_BASE_VOFFSET
+	str	r0, [r4]				// save soc_id
+	mov	r5, r0					// save soc_id
+
+	/* Pick uart address for the SoC */
+	adr	r1, .Lsscom_exynos5_table
+#ifdef SSCOM0CONSOLE
+	ldr	r2, [r1, #0*8+4]
+#endif
+#ifdef SSCOM1CONSOLE
+	ldr	r2, [r1, #1*8+4]
+#endif
+#ifdef SSCOM2CONSOLE
+	ldr	r2, [r1, #2*8+4]
+#endif
+#ifdef SSCOM3CONSOLE
+	ldr	r2, [r1, #3*8+4]
+#endif
+	add	r2, r2, #EXYNOS_CORE_PBASE
+	mcr	p15, 0, r2, c13, c0, 3		// TPIDRURO set (uart address)
+
+	/*
+	 * Turn on the SMP bit
+	 */
+	bl	cortex_init
+
+	XPUTC(#'C')
+
+	/*
+	 * Set up a preliminary mapping in the MMU to allow us to run
+	 * at KERNEL_BASE with caches on.
+	 */
+	movw	r0, #:lower16:TEMP_L1_TABLE
+	movt	r0, #:upper16:TEMP_L1_TABLE
+	movw	r1, #:lower16:mmu_init_table
+	movt	r1, #:upper16:mmu_init_table
+	bl	arm_boot_l1pt_init
+	XPUTC(#'D')
+
+	/*
+	 * Turn on the MMU, Caches, etc.  Return to new enabled address space.
+	 */
+	movw	r0, #:lower16:TEMP_L1_TABLE
+	movt	r0, #:upper16:TEMP_L1_TABLE
+#if KERNEL_BASE_VOFFSET == 0
+	bl	arm_cpuinit
+#else
+	/*
+	 * After the MMU is on, we can execute in the normal .text segment
+	 * so setup the lr to be in .text.  Cache the address for exynos_putc
+	 * before we go.
+	 */
+#if defined(VERBOSE_INIT_ARM)
+	adr	r11, exynos_putc		@ for XPUTC2
+#endif
+	movw	lr, #:lower16:1f
+	movt	lr, #:upper16:1f
+	b	arm_cpuinit
+	.pushsection .text, "ax", %progbits
+1:
+#endif
+	XPUTC2(#'Z')
+
+	XPUTC2(#13)
+	XPUTC2(#10)
+
+	/*
+	 * Jump to start in locore.S, which in turn will call initarm and main.
+	 */
+	b	start
+
+	/* NOTREACHED */
+#ifndef KERNEL_BASES_EQUAL
+	.popsection
+#endif
+
+	.align 0
+	.global _C_LABEL(num_exynos_uarts_entries)
+_C_LABEL(num_exynos_uarts_entries):
+	.word	8				// update number of entries!!!
+	.global _C_LABEL(exynos_uarts)
+_C_LABEL(exynos_uarts):
+.Lsscom_exynos5_table:
+	.word	0
+	.word	EXYNOS5_UART0_OFFSET
+	.word	1
+	.word	EXYNOS5_UART1_OFFSET
+	.word	2
+	.word	EXYNOS5_UART2_OFFSET
+	.word	3
+	.word	EXYNOS5_UART3_OFFSET
+
+
+#if defined(VERBOSE_INIT_ARM)
+	.align 0
+	.global exynos_putc
+	.global _C_LABEL(exynos_putchar)
+	.type	exynos_putc,%function
+
+#define TIMO		0x25000
+_C_LABEL(exynos_putchar):
+exynos_putc:
+	mov	r2, #TIMO
+	mrc	p15, 0, r3, c13, c0, 3		// TPIDRURO get (uart address)
+1:
+	ldr	r1, [r3, #SSCOM_UTRSTAT]
+#ifdef __ARMEB__
+	rev	r1, r1
+#endif
+	tst	r1, #UTRSTAT_TXEMPTY
+	bne	2f
+	subs	r2, r2, #1
+	bne	1b
+2:
+#ifdef __ARMEB__
+	rev	r0, r0
+#endif
+	str	r0, [r3, #SSCOM_UTXH]
+
+	mov	r2, #TIMO
+3:
+	ldr	r1, [r3, #SSCOM_UTRSTAT]
+#ifdef __ARMEB__
+	rev	r1, r1
+#endif
+	tst	r1, #UTRSTAT_TXSHIFTER_EMPTY
+	bne	4f
+	subs	r2, r2, #1
+	bne	3b
+4:
+	bx	lr
+#endif
+
+#include <arm/cortex/a9_mpsubr.S>
+
+	.align	0
+mmu_init_table:
+	/* Map KERNEL_BASE VA to SDRAM PA, write-back cacheable, shareable */
+	MMU_INIT(KERNEL_BASE, KERNEL_BASE - KERNEL_BASE_VOFFSET, INIT_MEMSIZE,
+		L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_CACHEABLE)
+
+#if KERNEL_BASE_VOFFSET !=0
+	/* Map physical addresses of kernel 1:1 PA:VA write-back cacheable, shareable */
+	MMU_INIT(KERNEL_BASE - KERNEL_BASE_VOFFSET,
+		KERNEL_BASE - KERNEL_BASE_VOFFSET, INIT_MEMSIZE,
+		L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_CACHEABLE)
+#endif
+
+	/* Map EXYNOS CORE (so console will work) */
+	MMU_INIT(EXYNOS_CORE_VBASE, EXYNOS_CORE_PBASE,
+		EXYNOS_CORE_SIZE / L1_S_SIZE,
+		L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN)
+
+	/* Map EXYNOS CORE (so console will work) */
+	MMU_INIT(EXYNOS_CORE_PBASE, EXYNOS_CORE_PBASE,
+		EXYNOS_CORE_SIZE / L1_S_SIZE,
+		L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN)
+
+	/* end of table */
+	MMU_INIT(0, 0, 0, 0)
+
+END(exynos_start)
Index: src/sys/arch/evbarm/exynos/platform.h
diff -u /dev/null src/sys/arch/evbarm/exynos/platform.h:1.1
--- /dev/null	Sun Dec  6 00:33:44 2015
+++ src/sys/arch/evbarm/exynos/platform.h	Sun Dec  6 00:33:44 2015
@@ -0,0 +1,47 @@
+/*	$NetBSD: platform.h,v 1.1 2015/12/06 00:33:44 marty Exp $	*/
+
+/*-
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Nick Hudson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ARM_EXYNOS_PLATFORM_H
+#define _ARM_EXYNOS_PLATFORM_H
+
+/*
+ * Kernel VM space 16Mb behind KERNEL_BASE upto 0xeff00000
+ */
+#define KERNEL_VM_BASE		0xc0000000
+#define KERNEL_VM_SIZE		(EXYNOS_CORE_VBASE - KERNEL_VM_BASE)
+
+/*
+ * IO space
+ */
+
+#define EXYNOS_CORE_VBASE	0xf0000000
+
+#endif /* _ARM_EXYNOS_PLATFORM_H */

Reply via email to