diff mbox

[v3,09/14] hw/exynos4210.c: Boot secondary CPU.

Message ID 1323672206-11891-10-git-send-email-e.voevodin@samsung.com
State New
Headers show

Commit Message

Evgeny Voevodin Dec. 12, 2011, 6:43 a.m. UTC
Signed-off-by: Evgeny Voevodin <e.voevodin@samsung.com>
---
 hw/exynos4210.c |   26 ++++++++++++++++++++++++++
 1 files changed, 26 insertions(+), 0 deletions(-)
diff mbox

Patch

diff --git a/hw/exynos4210.c b/hw/exynos4210.c
index e2c4bf5..055205d 100644
--- a/hw/exynos4210.c
+++ b/hw/exynos4210.c
@@ -93,8 +93,15 @@ 
 #define EXYNOS4210_EXT_COMBINER_BASE_ADDR   0x10440000
 #define EXYNOS4210_INT_COMBINER_BASE_ADDR   0x10448000
 
+/* Secondary CPU polling address to get loader start from */
+#define EXYNOS4210_SECOND_CPU_BOOTREG       0x10020814
+
+/* Secondary CPU startup code is in IROM memory */
+#define EXYNOS4210_SMP_BOOT_ADDR            EXYNOS4210_IROM_BASE_ADDR
+
 static struct arm_boot_info exynos4210_binfo = {
         .loader_start     = EXYNOS4210_BASE_BOOT_ADDR,
+        .smp_loader_start = EXYNOS4210_SMP_BOOT_ADDR,
 };
 
 static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
@@ -208,6 +215,8 @@  static void exynos4210_init(ram_addr_t ram_size,
     MemoryRegion *irom_alias_mem = g_new(MemoryRegion, 1);
     MemoryRegion *dram0_mem = g_new(MemoryRegion, 1);
     MemoryRegion *dram1_mem = NULL;
+    MemoryRegion *hack_mem = g_new(MemoryRegion, 1);
+    MemoryRegion *bootreg_mem = g_new(MemoryRegion, 1);
     Exynos4210Irq *irqs;
     qemu_irq *irq_table;
     qemu_irq *irqp;
@@ -221,9 +230,11 @@  static void exynos4210_init(ram_addr_t ram_size,
     switch (board_type) {
     case BOARD_EXYNOS4210_NURI:
         exynos4210_binfo.board_id      = MACH_NURI_ID;
+        exynos4210_binfo.smp_bootreg_addr = EXYNOS4210_SECOND_CPU_BOOTREG;
     break;
     case BOARD_EXYNOS4210_SMDKC210:
         exynos4210_binfo.board_id = MACH_SMDKC210_ID;
+        exynos4210_binfo.smp_bootreg_addr = EXYNOS4210_SECOND_CPU_BOOTREG;
     break;
     default:
     break;
@@ -367,6 +378,20 @@  static void exynos4210_init(ram_addr_t ram_size,
     memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR,
             dram0_mem);
 
+    /*
+     * Secondary CPU startup code will be placed here.
+     */
+    memory_region_init_ram(hack_mem, NULL, "exynos4210.hack", 0x1000);
+    memory_region_add_subregion(system_mem, EXYNOS4210_SMP_BOOT_ADDR,
+            hack_mem);
+
+    /*
+     * Hack: Map SECOND_CPU_BOOTREG, because it is in PMU USER5 register.
+     */
+    memory_region_init_ram(bootreg_mem, NULL, "exynos4210.bootreg", 0x4);
+    memory_region_add_subregion(system_mem, EXYNOS4210_SECOND_CPU_BOOTREG,
+            bootreg_mem);
+
     /* CMU */
     sysbus_create_simple("exynos4210.cmu", EXYNOS4210_CMU_BASE_ADDR, NULL);
 
@@ -441,6 +466,7 @@  static void exynos4210_init(ram_addr_t ram_size,
     exynos4210_binfo.kernel_filename = kernel_filename;
     exynos4210_binfo.initrd_filename = initrd_filename;
     exynos4210_binfo.kernel_cmdline = kernel_cmdline;
+    exynos4210_binfo.smp_priv_base = EXYNOS4210_SMP_PRIVATE_BASE_ADDR;
 
     arm_load_kernel(first_cpu, &exynos4210_binfo);
 }