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 */