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