uboot/arch/arm/mach-exynos/sec_boot.S
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0+ */
   2/*
   3 * Copyright (C) 2013 Samsung Electronics
   4 * Akshay Saraswat <akshay.s@samsung.com>
   5 */
   6
   7#include <config.h>
   8#include <asm/arch/cpu.h>
   9
  10        .globl relocate_wait_code
  11relocate_wait_code:
  12        adr     r0, code_base           @ r0: source address (start)
  13        adr     r1, code_end            @ r1: source address (end)
  14        ldr     r2, =0x02073000         @ r2: target address
  151:
  16        ldmia   r0!, {r3-r6}
  17        stmia   r2!, {r3-r6}
  18        cmp     r0, r1
  19        blt     1b
  20        b       code_end
  21        .ltorg
  22/*
  23 * Secondary core waits here until Primary wake it up.
  24 * Below code is copied to CONFIG_EXYNOS_RELOCATE_CODE_BASE.
  25 * This is a workaround code which is supposed to act as a
  26 * substitute/supplement to the iROM code.
  27 *
  28 * This workaround code is relocated to the address 0x02073000
  29 * because that comes out to be the last 4KB of the iRAM
  30 * (Base Address - 0x02020000, Limit Address - 0x020740000).
  31 *
  32 * U-Boot and kernel are aware of this code and flags by the simple
  33 * fact that we are implementing a workaround in the last 4KB
  34 * of the iRAM and we have already defined these flag and address
  35 * values in both kernel and U-Boot for our use.
  36 */
  37code_base:
  38        b        1f
  39/*
  40 * These addresses are being used as flags in u-boot and kernel.
  41 *
  42 * Jump address for resume and flag to check for resume/reset:
  43 * Resume address - 0x2073008
  44 * Resume flag - 0x207300C
  45 *
  46 * Jump address for cluster switching:
  47 * Switch address - 0x2073018
  48 *
  49 * Jump address for core hotplug:
  50 * Hotplug address - 0x207301C
  51 *
  52 * Jump address for C2 state (Reserved for future not being used right now):
  53 * C2 address - 0x2073024
  54 *
  55 * Managed per core status for the active cluster:
  56 * CPU0 state - 0x2073028
  57 * CPU1 state - 0x207302C
  58 * CPU2 state - 0x2073030
  59 * CPU3 state - 0x2073034
  60 *
  61 * Managed per core GIC status for the active cluster:
  62 * CPU0 gic state - 0x2073038
  63 * CPU1 gic state - 0x207303C
  64 * CPU2 gic state - 0x2073040
  65 * CPU3 gic state - 0x2073044
  66 *
  67 * Logic of the code:
  68 * Step-1: Read current CPU status.
  69 * Step-2: If it's a resume then continue, else jump to step 4.
  70 * Step-3: Clear inform1 PMU register and jump to inform0 value.
  71 * Step-4: If it's a switch, C2 or reset, get the hotplug address.
  72 * Step-5: If address is not available, enter WFE.
  73 * Step-6: If address is available, jump to that address.
  74 */
  75        nop                          @ for backward compatibility
  76        .word   0x0                  @ REG0: RESUME_ADDR
  77        .word   0x0                  @ REG1: RESUME_FLAG
  78        .word   0x0                  @ REG2
  79        .word   0x0                  @ REG3
  80_switch_addr:
  81        .word   0x0                  @ REG4: SWITCH_ADDR
  82_hotplug_addr:
  83        .word   0x0                  @ REG5: CPU1_BOOT_REG
  84        .word   0x0                  @ REG6
  85_c2_addr:
  86        .word   0x0                  @ REG7: REG_C2_ADDR
  87_cpu_state:
  88        .word   0x1                  @ CPU0_STATE : RESET
  89        .word   0x2                  @ CPU1_STATE : SECONDARY RESET
  90        .word   0x2                  @ CPU2_STATE : SECONDARY RESET
  91        .word   0x2                  @ CPU3_STATE : SECONDARY RESET
  92_gic_state:
  93        .word   0x0                  @ CPU0 - GICD_IGROUPR0
  94        .word   0x0                  @ CPU1 - GICD_IGROUPR0
  95        .word   0x0                  @ CPU2 - GICD_IGROUPR0
  96        .word   0x0                  @ CPU3 - GICD_IGROUPR0
  971:
  98        adr     r0, _cpu_state
  99        mrc     p15, 0, r7, c0, c0, 5   @ read MPIDR
 100        and     r7, r7, #0xf        @ r7 = cpu id
 101/* Read the current cpu state */
 102        ldr     r10, [r0, r7, lsl #2]
 103svc_entry:
 104        tst     r10, #(1 << 4)
 105        adrne   r0, _switch_addr
 106        bne     wait_for_addr
 107/* Clear INFORM1 */
 108        ldr     r0, =(0x10040000 + 0x804)
 109        ldr     r1, [r0]
 110        cmp     r1, #0x0
 111        movne   r1, #0x0
 112        strne   r1, [r0]
 113/* Get INFORM0 */
 114        ldrne   r1, =(0x10040000 + 0x800)
 115        ldrne   pc, [r1]
 116        tst     r10, #(1 << 0)
 117        ldrne   pc, =0x23e00000
 118        adr     r0, _hotplug_addr
 119wait_for_addr:
 120        ldr     r1, [r0]
 121        cmp     r1, #0x0
 122        bxne    r1
 123        wfe
 124        b        wait_for_addr
 125        .ltorg
 126code_end:
 127        mov     pc, lr
 128