Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/evbarm/armadaxp Import cleaned up MD parts of Armad...



details:   https://anonhg.NetBSD.org/src/rev/afb59e48d3a4
branches:  trunk
changeset: 787019:afb59e48d3a4
user:      rkujawa <rkujawa%NetBSD.org@localhost>
date:      Wed May 29 19:55:56 2013 +0000

description:
Import cleaned up MD parts of Armada XP port.

Compared to what was posted to port-arm, the main difference is that now it uses
arm32_kvminit, arm32_boot, arm32_reboot as advised by nick@.

Obtained from Marvell, Semihalf.

diffstat:

 sys/arch/evbarm/armadaxp/armadaxp_machdep.c |  588 ++++++++++++++++++++++++++++
 sys/arch/evbarm/armadaxp/armadaxp_start.S   |  158 +++++++
 2 files changed, 746 insertions(+), 0 deletions(-)

diffs (truncated from 754 to 300 lines):

diff -r 6a3ff6179a58 -r afb59e48d3a4 sys/arch/evbarm/armadaxp/armadaxp_machdep.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/evbarm/armadaxp/armadaxp_machdep.c       Wed May 29 19:55:56 2013 +0000
@@ -0,0 +1,588 @@
+/*******************************************************************************
+Copyright (C) Marvell International Ltd. and its affiliates
+
+Developed by Semihalf
+
+********************************************************************************
+Marvell BSD License
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File under the following licensing terms.
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    *   Redistributions of source code must retain the above copyright notice,
+            this list of conditions and the following disclaimer.
+
+    *   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.
+
+    *   Neither the name of Marvell nor the names of its contributors may be
+        used to endorse or promote products derived from this software without
+        specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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: armadaxp_machdep.c,v 1.1 2013/05/29 19:55:56 rkujawa Exp $");
+
+#include "opt_machdep.h"
+#include "opt_mvsoc.h"
+#include "opt_evbarm_boardtype.h"
+#include "opt_com.h"
+#include "opt_ddb.h"
+#include "opt_kgdb.h"
+#include "opt_pci.h"
+#include "opt_ipkdb.h"
+
+#include <sys/bus.h>
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/exec.h>
+#include <sys/proc.h>
+#include <sys/msgbuf.h>
+#include <sys/reboot.h>
+#include <sys/termios.h>
+#include <sys/ksyms.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <sys/conf.h>
+#include <dev/cons.h>
+#include <dev/md.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <machine/pci_machdep.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 <machine/autoconf.h>
+#include <machine/cpu.h>
+#include <machine/frame.h>
+#include <arm/armreg.h>
+#include <arm/undefined.h>
+
+#include <arm/arm32/machdep.h>
+
+#include <arm/marvell/mvsocreg.h>
+#include <arm/marvell/mvsocvar.h>
+#include <evbarm/armadaxp/armadaxpreg.h>
+
+#include <evbarm/marvell/marvellreg.h>
+#include <evbarm/marvell/marvellvar.h>
+
+#include "mvpex.h"
+#include "com.h"
+#if NCOM > 0
+#include <dev/ic/comreg.h>
+#include <dev/ic/comvar.h>
+#endif
+
+/*
+ * Address to call from cpu_reset() to reset the machine.
+ * This is machine architecture dependent 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
+#ifdef IPKDB
+#define UND_STACK_SIZE 2
+#else
+#define UND_STACK_SIZE 1
+#endif
+
+BootConfig bootconfig;         /* Boot config storage */
+char *boot_args = NULL;
+char *boot_file = NULL;
+
+extern int KERNEL_BASE_phys[];
+
+/*extern char KERNEL_BASE_phys[];*/
+extern char etext[], __data_start[], _edata[], __bss_start[], __bss_end__[];
+extern char _end[];
+
+/*
+ * Put some bogus settings of the MEMSTART and MEMSIZE
+ * if they are not defined in kernel configuration file.
+ */
+#ifndef MEMSTART
+#define MEMSTART 0x00000000UL
+#endif
+#ifndef MEMSIZE
+#define MEMSIZE 0x40000000UL
+#endif
+
+#ifndef STARTUP_PAGETABLE_ADDR
+#define        STARTUP_PAGETABLE_ADDR 0x00000000UL
+#endif
+
+/* Physical offset of the kernel from MEMSTART */
+#define KERNEL_OFFSET          (paddr_t)&KERNEL_BASE_phys
+/* Kernel base virtual address */
+#define        KERNEL_TEXT_BASE        (KERNEL_BASE + KERNEL_OFFSET)
+
+#define        KERNEL_VM_BASE          (KERNEL_BASE + 0x01000000)
+#define KERNEL_VM_SIZE         0x10000000
+
+/* Prototypes */
+extern int armadaxp_l2_init(void);
+extern void armadaxp_io_coherency_init(void);
+
+void consinit(void);
+#ifdef KGDB
+static void kgdb_port_init(void);
+#endif
+
+static void axp_device_register(device_t dev, void *aux);
+
+static void
+axp_system_reset(void)
+{
+       cpu_reset_address = 0;
+
+       /* Unmask soft reset */
+       write_miscreg(MVSOC_MLMB_RSTOUTNMASKR,
+           MVSOC_MLMB_RSTOUTNMASKR_SOFTRSTOUTEN);
+       /* Assert soft reset */
+       write_miscreg(MVSOC_MLMB_SSRR, MVSOC_MLMB_SSRR_SYSTEMSOFTRST);
+
+       while (1);
+}
+
+/*
+ * Static device mappings. These peripheral registers are mapped at
+ * fixed virtual addresses very early in initarm() so that we can use
+ * them while booting the kernel, and stay at the same address
+ * throughout whole kernel's life time.
+ *
+ * We use this table twice; once with bootstrap page table, and once
+ * with kernel's page table which we build up in initarm().
+ *
+ * Since we map these registers into the bootstrap page table using
+ * pmap_devmap_bootstrap() which calls pmap_map_chunk(), we map
+ * registers segment-aligned and segment-rounded in order to avoid
+ * using the 2nd 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 devmap[] = {
+       {
+               /* Internal registers */
+               .pd_va = _A(MARVELL_INTERREGS_VBASE),
+               .pd_pa = _A(MARVELL_INTERREGS_PBASE),
+               .pd_size = _S(MARVELL_INTERREGS_SIZE),
+               .pd_prot = VM_PROT_READ|VM_PROT_WRITE,
+               .pd_cache = PTE_NOCACHE
+       },
+       {0, 0, 0, 0, 0}
+};
+
+#undef _A
+#undef _S
+
+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));
+}
+
+static int
+axp_pcie_free_win(void)
+{
+       int i;
+       /* Find first disabled window */
+       for (i = 0; i < ARMADAXP_MLMB_NWINDOW; i++) {
+               if ((read_mlmbreg(MVSOC_MLMB_WCR(i)) &
+                   MVSOC_MLMB_WCR_WINEN) == 0) {
+                       return i;
+               }
+       }
+       /* If there is no free window, return erroneous value */
+       return (-1);
+}
+
+static void
+reset_axp_pcie_win(void)
+{
+       uint32_t target, attr;
+       int memtag = 0, iotag = 0, window, i;
+       uint32_t membase;
+       uint32_t iobase;
+       uint32_t tags[] = { ARMADAXP_TAG_PEX00_MEM, ARMADAXP_TAG_PEX00_IO,
+                           ARMADAXP_TAG_PEX01_MEM, ARMADAXP_TAG_PEX01_IO,
+                           ARMADAXP_TAG_PEX02_MEM, ARMADAXP_TAG_PEX02_IO,
+                           ARMADAXP_TAG_PEX03_MEM, ARMADAXP_TAG_PEX03_IO,
+                           ARMADAXP_TAG_PEX2_MEM, ARMADAXP_TAG_PEX2_IO,
+                           ARMADAXP_TAG_PEX3_MEM, ARMADAXP_TAG_PEX3_IO};
+
+       nwindow = ARMADAXP_MLMB_NWINDOW;
+       nremap = ARMADAXP_MLMB_NREMAP;
+       membase = MARVELL_PEXMEM_PBASE;
+       iobase = MARVELL_PEXIO_PBASE;
+       for (i = 0; i < __arraycount(tags) / 2; i++) {
+               memtag = tags[2 * i];
+               iotag = tags[(2 * i) + 1];
+
+               /* Reset PCI-Express space to window register. */
+               window = mvsoc_target(memtag, &target, &attr, NULL, NULL);
+
+               /* Find free window if we've got spurious one */
+               if (window >= nwindow) {
+                       window = axp_pcie_free_win();
+                       /* Just break if there is no free windows left */
+                       if (window < 0) {
+                               aprint_error(": no free windows for PEX MEM\n");
+                               break;
+                       }
+               }
+               write_mlmbreg(MVSOC_MLMB_WCR(window),
+                   MVSOC_MLMB_WCR_WINEN |
+                   MVSOC_MLMB_WCR_TARGET(target) |
+                   MVSOC_MLMB_WCR_ATTR(attr) |
+                   MVSOC_MLMB_WCR_SIZE(MARVELL_PEXMEM_SIZE));
+               write_mlmbreg(MVSOC_MLMB_WBR(window),
+                   membase & MVSOC_MLMB_WBR_BASE_MASK);
+#ifdef PCI_NETBSD_CONFIGURE
+               if (window < nremap) {
+                       write_mlmbreg(MVSOC_MLMB_WRLR(window),
+                           membase & MVSOC_MLMB_WRLR_REMAP_MASK);
+                       write_mlmbreg(MVSOC_MLMB_WRHR(window), 0);
+               }
+#endif
+               window = mvsoc_target(iotag, &target, &attr, NULL, NULL);
+
+               /* Find free window if we've got spurious one */
+               if (window >= nwindow) {
+                       window = axp_pcie_free_win();
+                       /* Just break if there is no free windows left */
+                       if (window < 0) {
+                               aprint_error(": no free windows for PEX I/O\n");
+                               break;
+                       }
+               }
+               write_mlmbreg(MVSOC_MLMB_WCR(window),
+                   MVSOC_MLMB_WCR_WINEN |
+                   MVSOC_MLMB_WCR_TARGET(target) |



Home | Main Index | Thread Index | Old Index