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