Signed-off-by: Paul Butler <paul.but...@windriver.com>
---
 arch/arm/Makefile                              |  4 ++
 arch/arm/kernel/head.S                         |  8 +++
 arch/arm/mach-axxia/Kconfig                    |  3 +
 arch/arm/mach-axxia/include/mach/debug-macro.S | 34 ++++-----
 arch/arm/mach-axxia/platsmp.c                  | 96 +++++++++++++++++++++++++-
 init/main.c                                    | 11 +++
 6 files changed, 139 insertions(+), 17 deletions(-)

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index db992cd..16a0b42 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -133,6 +133,10 @@ textofs-$(CONFIG_ARCH_MSM7X30) := 0x00208000
 textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000
 textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
 
+ifneq ($(CONFIG_ARCH_AXXIA_SIM),y)
+textofs-$(CONFIG_ARCH_AXXIA)   := 0x00408000
+endif
+
 # Machine directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
 machine-$(CONFIG_ARCH_AT91)            := at91
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 3bf0c7f..bd39808 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -52,7 +52,12 @@
        .equ    swapper_pg_dir, KERNEL_RAM_VADDR - PG_DIR_SIZE
 
        .macro  pgtbl, rd, phys
+#ifdef CONFIG_ARCH_AXXIA
+       ldr     \rd, =(TEXT_OFFSET - PG_DIR_SIZE)
+       add     \rd, \rd, \phys
+#else
        add     \rd, \phys, #TEXT_OFFSET - PG_DIR_SIZE
+#endif
        .endm
 
 #ifdef CONFIG_XIP_KERNEL
@@ -289,6 +294,9 @@ __create_page_tables:
 #else
        orr     r3, r3, #PMD_SECT_XN
 #endif
+#ifdef CONFIG_ARCH_AXXIA
+       orr     r7, r7, #0x20
+#endif
 1:     str     r3, [r0], #4
 #ifdef CONFIG_ARM_LPAE
        str     r7, [r0], #4
diff --git a/arch/arm/mach-axxia/Kconfig b/arch/arm/mach-axxia/Kconfig
index 4a4922f..206c344 100644
--- a/arch/arm/mach-axxia/Kconfig
+++ b/arch/arm/mach-axxia/Kconfig
@@ -28,4 +28,7 @@ config ARCH_AXXIA_DT
          If your bootloader supports Flattened Device Tree based booting,
          say Y here.
 
+config ARCH_AXXIA_SIM
+       bool "Build for Simulation instead of Emulation or ASIC"
+
 endmenu
diff --git a/arch/arm/mach-axxia/include/mach/debug-macro.S 
b/arch/arm/mach-axxia/include/mach/debug-macro.S
index f25a024..83d6670 100644
--- a/arch/arm/mach-axxia/include/mach/debug-macro.S
+++ b/arch/arm/mach-axxia/include/mach/debug-macro.S
@@ -10,26 +10,28 @@
  * published by the Free Software Foundation.
  */
 
-#ifdef CONFIG_DEBUG_VEXPRESS_CA9X4_UART
-#define DEBUG_LL_PHYS_BASE             0x10000000
-#define DEBUG_LL_UART_OFFSET           0x00009000
-#endif
+/*
+ * -- NOTE --
+ *
+*/
 
-#ifdef CONFIG_DEBUG_VEXPRESS_RS1_UART
-#define DEBUG_LL_PHYS_BASE             0x1c000000
-#define DEBUG_LL_UART_OFFSET           0x00090000
+#if !defined(CONFIG_ARM_LPAE)
+#error "Axxia Peripherals Are Only Accessible Using the LPAE!"
 #endif
 
-#define DEBUG_LL_VIRT_BASE             0xf8000000
+#define UART0_PHYSICAL_ADDRESS 0x0000002010080000ULL
+#define UART1_PHYSICAL_ADDRESS 0x0000002010081000ULL
+#define UART2_PHYSICAL_ADDRESS 0x0000002010082000ULL
+#define UART3_PHYSICAL_ADDRESS 0x0000002010083000ULL
 
-#ifndef DEBUG_LL_UART_OFFSET
-#error "Unknown vexpress UART offset"
-#endif
+#define UART0_VIRTUAL_ADDRESS 0xf0080000
+#define UART1_VIRTUAL_ADDRESS 0xf0081000
+#define UART2_VIRTUAL_ADDRESS 0xf0082000
+#define UART3_VIRTUAL_ADDRESS 0xf0083000
 
-               .macro  addruart,rp,rv,tmp
-               mov     \rp, #DEBUG_LL_UART_OFFSET
-               orr     \rv, \rp, #DEBUG_LL_VIRT_BASE
-               orr     \rp, \rp, #DEBUG_LL_PHYS_BASE
-               .endm
+       .macro  addruart, rp, rv, tmp
+       ldr     \rp, =0x10080000
+       ldr     \rv, =0xf0080000
+       .endm
 
 #include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-axxia/platsmp.c b/arch/arm/mach-axxia/platsmp.c
index 4ba2e7a..95859ec 100644
--- a/arch/arm/mach-axxia/platsmp.c
+++ b/arch/arm/mach-axxia/platsmp.c
@@ -31,6 +31,9 @@ volatile int __cpuinitdata pen_release = -1;
 
 extern void axxia_secondary_startup(void);
 
+#define APB2_SER3_PHY_ADDR      0x002010030000ULL
+#define APB2_SER3_ADDR_SIZE   0x10000
+
 /*
  * Write pen_release in a way that is guaranteed to be visible to all
  * observers, irrespective of whether they're taking part in coherency
@@ -113,7 +116,12 @@ int __cpuinit boot_secondary(unsigned int cpu, struct 
task_struct *idle)
 #endif
 
        /* Wait for so long, then give up if nothing happens ... */
+#ifdef CONFIG_ARCH_AXXIA_SIM
        timeout = jiffies + (1 * HZ);
+#else
+       timeout = jiffies + (10 * HZ);
+#endif
+
        while (time_before(jiffies, timeout)) {
                smp_rmb();
                if (pen_release == -1)
@@ -159,8 +167,10 @@ void __init smp_init_cpus(void)
        set_smp_cross_call(axxia_gic_raise_softirq);
 }
 
-void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+void __init
+platform_smp_prepare_cpus(unsigned int max_cpus)
 {
+#ifdef CONFIG_ARCH_AXXIA_SIM
        int i;
 
        /*
@@ -177,4 +187,88 @@ void __init platform_smp_prepare_cpus(unsigned int 
max_cpus)
         */
        *(u32 *)phys_to_virt(0x10000020) =
                virt_to_phys(axxia_secondary_startup);
+#else
+       int i;
+       void __iomem *apb2_ser3_base;
+       unsigned long resetVal;
+       int phys_cpu, cpu_count=0;
+       struct device_node *np;
+       unsigned long release_addr[NR_CPUS] = {0};
+       unsigned long release;
+
+       if (of_find_compatible_node(NULL, NULL, "lsi,axm5516")) {
+               for_each_node_by_name(np, "cpu") {
+                       if (of_property_read_u32(np, "reg", &phys_cpu))
+                               continue;
+
+                       if (0 == phys_cpu)
+                               continue;
+
+                       if (of_property_read_u32(np, "cpu-release-addr",
+                                                &release))
+                               continue;
+
+                       release_addr[phys_cpu] = release;
+                       printk(KERN_ERR
+                              "%s:%d - set address for %d to 0x%08x\n",
+                              __FILE__, __LINE__,
+                              phys_cpu, release_addr[phys_cpu]);
+               }
+
+               /*
+                * Initialise the present map, which describes the set of CPUs
+                * actually populated at the present time.
+                */
+
+               apb2_ser3_base = ioremap(APB2_SER3_PHY_ADDR, 
APB2_SER3_ADDR_SIZE);
+
+               for (i = 0; i < NR_CPUS; i++) { 
+                       /* check if this is a possible CPU and
+                          it is within max_cpus range */
+                       if ((cpu_possible(i)) &&
+                           (cpu_count < max_cpus) &&
+                           (0 != release_addr[i])) {
+                               resetVal = readl(apb2_ser3_base + 0x1010);
+                               phys_cpu = cpu_logical_map(i);
+                               set_cpu_present(cpu_count, true);
+                               if (phys_cpu != 0) {
+                                       writel(0xab, apb2_ser3_base+0x1000);
+                                       resetVal &= ~(1 << phys_cpu);
+                                       writel(resetVal, apb2_ser3_base+0x1010);
+                                       udelay(1000);
+                               }
+                               cpu_count++;
+                       }
+               }
+
+               iounmap(apb2_ser3_base);
+
+               /*
+                * This is the entry point of the routine that the secondary
+                * cores will execute once they are released from their
+                * "holding pen".
+                */
+               *(u32 *)phys_to_virt(release) =
+                       virt_to_phys(axxia_secondary_startup);
+               smp_wmb();
+               __cpuc_flush_dcache_area((void *)phys_to_virt(release),
+                                        sizeof(u32));
+       } else if (of_find_compatible_node(NULL, NULL, "lsi,axm5516-sim")) {
+               for (i = 0; i < max_cpus; i++)
+                       set_cpu_present(i, true);
+
+               /*
+                * This is the entry point of the routine that the secondary
+                * cores will execute once they are released from their
+                * "holding pen".
+                */
+               *(u32 *)phys_to_virt(0x10000020) =
+                       virt_to_phys(axxia_secondary_startup);
+               smp_wmb();
+               __cpuc_flush_dcache_area((void *)phys_to_virt(0x10000020),
+                                        sizeof(u32));
+       }
+
+       return;
+#endif
 }
diff --git a/init/main.c b/init/main.c
index 6484e4e..82b4513 100644
--- a/init/main.c
+++ b/init/main.c
@@ -467,6 +467,17 @@ asmlinkage void __init start_kernel(void)
        char * command_line;
        extern const struct kernel_param __start___param[], __stop___param[];
 
+#if defined(CONFIG_ARCH_AXXIA) && defined(DEBUG_LL)
+       {
+               *(unsigned long *)(0xf0080000 + 0x24) = 13;
+               *(unsigned long *)(0xf0080000 + 0x28) = 1;
+               *(unsigned long *)(0xf0080000 + 0x2c) = 0x70;
+               *(unsigned long *)(0xf0080000 + 0x30) = 0x301;
+               *(unsigned long *)(0xf0080000 + 0x34) = 0;
+               *(unsigned long *)(0xf0080000 + 0x38) = 0x700;
+       }
+#endif /* CONFIG_ARCH_AXXIA && DEBUG_LL */
+
        /*
         * Need to run as early as possible, to initialize the
         * lockdep hash:
-- 
1.8.3.4

_______________________________________________
linux-yocto mailing list
linux-yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to