acx-mac80211: v3.14 related compile fixes
[openwrt.git] / package / boot / uboot-sunxi / patches / 002-uboot-jwrdegoede-psci-support.patch
1 From 86f31982ac62e80fe586cad2e0a49a7b22e3d4ee Mon Sep 17 00:00:00 2001
2 From: Marc Zyngier <marc.zyngier@arm.com>
3 Date: Sat, 7 Dec 2013 11:19:07 +0000
4 Subject: [PATCH] ARM: HYP/non-sec: move switch to non-sec to the last boot
5  phase
6
7 Having the switch to non-secure in the "prep" phase is causing
8 all kind of troubles, as that stage can be called multiple times.
9
10 Instead, move the switch to non-secure to the last possible phase,
11 when there is no turning back anymore.
12
13 Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
14 ---
15  arch/arm/lib/bootm.c | 5 +++--
16  1 file changed, 3 insertions(+), 2 deletions(-)
17
18 diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
19 index 47ee070..10634a4 100644
20 --- a/arch/arm/lib/bootm.c
21 +++ b/arch/arm/lib/bootm.c
22 @@ -242,7 +242,6 @@ static void boot_prep_linux(bootm_headers_t *images)
23                 printf("FDT and ATAGS support not compiled in - hanging\n");
24                 hang();
25         }
26 -       do_nonsec_virt_switch();
27  }
28  
29  /* Subcommand: GO */
30 @@ -287,8 +286,10 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
31         else
32                 r2 = gd->bd->bi_boot_params;
33  
34 -       if (!fake)
35 +       if (!fake) {
36 +               do_nonsec_virt_switch();
37                 kernel_entry(0, machid, r2);
38 +       }
39  #endif
40  }
41  
42 From c26d288f6cbc6d53219001d42476f314c403257b Mon Sep 17 00:00:00 2001
43 From: Marc Zyngier <marc.zyngier@arm.com>
44 Date: Sat, 7 Dec 2013 11:19:08 +0000
45 Subject: [PATCH] ARM: HYP/non-sec: add a barrier after setting SCR.NS==1
46
47 A CP15 instruction execution can be reordered, requiring an
48 isb to be sure it is executed in program order.
49
50 Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
51 ---
52  arch/arm/cpu/armv7/nonsec_virt.S | 1 +
53  1 file changed, 1 insertion(+)
54
55 diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S
56 index 6367e09..12de5c2 100644
57 --- a/arch/arm/cpu/armv7/nonsec_virt.S
58 +++ b/arch/arm/cpu/armv7/nonsec_virt.S
59 @@ -46,6 +46,7 @@ _secure_monitor:
60  #endif
61  
62         mcr     p15, 0, r1, c1, c1, 0           @ write SCR (with NS bit set)
63 +       isb
64  
65  #ifdef CONFIG_ARMV7_VIRT
66         mrceq   p15, 0, r0, c12, c0, 1          @ get MVBAR value
67 From 06feeea3c84cc58ff3d5c19f6a430886495f86ce Mon Sep 17 00:00:00 2001
68 From: Marc Zyngier <marc.zyngier@arm.com>
69 Date: Sat, 7 Dec 2013 11:19:09 +0000
70 Subject: [PATCH] ARM: non-sec: reset CNTVOFF to zero
71
72 Before switching to non-secure, make sure that CNTVOFF is set
73 to zero on all CPUs. Otherwise, kernel running in non-secure
74 without HYP enabled (hence using virtual timers) may observe
75 timers that are not synchronized, effectively seeing time
76 going backward...
77
78 Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
79 ---
80  arch/arm/cpu/armv7/nonsec_virt.S | 9 ++++++++-
81  1 file changed, 8 insertions(+), 1 deletion(-)
82
83 diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S
84 index 12de5c2..b5c946f 100644
85 --- a/arch/arm/cpu/armv7/nonsec_virt.S
86 +++ b/arch/arm/cpu/armv7/nonsec_virt.S
87 @@ -38,10 +38,10 @@ _secure_monitor:
88         bic     r1, r1, #0x4e                   @ clear IRQ, FIQ, EA, nET bits
89         orr     r1, r1, #0x31                   @ enable NS, AW, FW bits
90  
91 -#ifdef CONFIG_ARMV7_VIRT
92         mrc     p15, 0, r0, c0, c1, 1           @ read ID_PFR1
93         and     r0, r0, #CPUID_ARM_VIRT_MASK    @ mask virtualization bits
94         cmp     r0, #(1 << CPUID_ARM_VIRT_SHIFT)
95 +#ifdef CONFIG_ARMV7_VIRT
96         orreq   r1, r1, #0x100                  @ allow HVC instruction
97  #endif
98  
99 @@ -52,7 +52,14 @@ _secure_monitor:
100         mrceq   p15, 0, r0, c12, c0, 1          @ get MVBAR value
101         mcreq   p15, 4, r0, c12, c0, 0          @ write HVBAR
102  #endif
103 +       bne     1f
104  
105 +       @ Reset CNTVOFF to 0 before leaving monitor mode
106 +       mrc     p15, 0, r0, c0, c1, 1           @ read ID_PFR1
107 +       ands    r0, r0, #CPUID_ARM_GENTIMER_MASK        @ test arch timer bits
108 +       movne   r0, #0
109 +       mcrrne  p15, 4, r0, r0, c14             @ Reset CNTVOFF to zero
110 +1:
111         movs    pc, lr                          @ return to non-secure SVC
112  
113  _hyp_trap:
114 From 054bcf5147ff5a20298bce5b3bdfbf3e1c797594 Mon Sep 17 00:00:00 2001
115 From: Marc Zyngier <marc.zyngier@arm.com>
116 Date: Sat, 7 Dec 2013 11:19:10 +0000
117 Subject: [PATCH] ARM: add missing HYP mode constant
118
119 In order to be able to use the various mode constants (far more
120 readable than random hex values), add the missing HYP and A
121 values.
122
123 Also update arm/lib/interrupts.c to display HYP instead of an
124 unknown value.
125
126 Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
127 ---
128  arch/arm/include/asm/proc-armv/ptrace.h | 2 ++
129  arch/arm/lib/interrupts.c               | 2 +-
130  2 files changed, 3 insertions(+), 1 deletion(-)
131
132 diff --git a/arch/arm/include/asm/proc-armv/ptrace.h b/arch/arm/include/asm/proc-armv/ptrace.h
133 index 21aef58..71df5a9 100644
134 --- a/arch/arm/include/asm/proc-armv/ptrace.h
135 +++ b/arch/arm/include/asm/proc-armv/ptrace.h
136 @@ -38,12 +38,14 @@ struct pt_regs {
137  #define IRQ_MODE       0x12
138  #define SVC_MODE       0x13
139  #define ABT_MODE       0x17
140 +#define HYP_MODE       0x1a
141  #define UND_MODE       0x1b
142  #define SYSTEM_MODE    0x1f
143  #define MODE_MASK      0x1f
144  #define T_BIT          0x20
145  #define F_BIT          0x40
146  #define I_BIT          0x80
147 +#define A_BIT          0x100
148  #define CC_V_BIT       (1 << 28)
149  #define CC_C_BIT       (1 << 29)
150  #define CC_Z_BIT       (1 << 30)
151 diff --git a/arch/arm/lib/interrupts.c b/arch/arm/lib/interrupts.c
152 index 758b013..f6b7c03 100644
153 --- a/arch/arm/lib/interrupts.c
154 +++ b/arch/arm/lib/interrupts.c
155 @@ -103,7 +103,7 @@ void show_regs (struct pt_regs *regs)
156         "UK12_26",      "UK13_26",      "UK14_26",      "UK15_26",
157         "USER_32",      "FIQ_32",       "IRQ_32",       "SVC_32",
158         "UK4_32",       "UK5_32",       "UK6_32",       "ABT_32",
159 -       "UK8_32",       "UK9_32",       "UK10_32",      "UND_32",
160 +       "UK8_32",       "UK9_32",       "HYP_32",       "UND_32",
161         "UK12_32",      "UK13_32",      "UK14_32",      "SYS_32",
162         };
163  
164 From 213a8d9b7e613210d3c7d8b99c95b454ad0527d8 Mon Sep 17 00:00:00 2001
165 From: Marc Zyngier <marc.zyngier@arm.com>
166 Date: Sat, 7 Dec 2013 11:19:11 +0000
167 Subject: [PATCH] ARM: HYP/non-sec: add separate section for secure code
168
169 In anticipation of refactoring the HYP/non-secure code to run
170 from secure RAM, add a new linker section that will contain that
171 code.
172
173 Nothing is using it just yet.
174
175 Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
176 ---
177  arch/arm/config.mk      |  2 +-
178  arch/arm/cpu/u-boot.lds | 30 ++++++++++++++++++++++++++++++
179  arch/arm/lib/sections.c |  2 ++
180  3 files changed, 33 insertions(+), 1 deletion(-)
181
182 diff --git a/arch/arm/config.mk b/arch/arm/config.mk
183 index 66ecc2e..2bdfca5 100644
184 --- a/arch/arm/config.mk
185 +++ b/arch/arm/config.mk
186 @@ -113,7 +113,7 @@ endif
187  ifdef CONFIG_ARM64
188  OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
189  else
190 -OBJCOPYFLAGS += -j .text -j .rodata -j .hash -j .data -j .got.plt -j .u_boot_list -j .rel.dyn
191 +OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash -j .data -j .got.plt -j .u_boot_list -j .rel.dyn
192  endif
193  
194  ifneq ($(CONFIG_IMX_CONFIG),)
195 diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds
196 index 33c1f99..f45885d 100644
197 --- a/arch/arm/cpu/u-boot.lds
198 +++ b/arch/arm/cpu/u-boot.lds
199 @@ -7,6 +7,8 @@
200   * SPDX-License-Identifier:    GPL-2.0+
201   */
202  
203 +#include <config.h>
204 +
205  OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
206  OUTPUT_ARCH(arm)
207  ENTRY(_start)
208 @@ -22,6 +24,34 @@ SECTIONS
209                 *(.text*)
210         }
211  
212 +#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) || defined(CONFIG_ARMV7_PSCI)
213 +
214 +#ifndef CONFIG_ARMV7_SECURE_BASE
215 +#define CONFIG_ARMV7_SECURE_BASE
216 +#endif
217 +
218 +       .__secure_start : {
219 +               . = ALIGN(0x1000);
220 +               *(.__secure_start)
221 +       }
222 +
223 +       .secure_text CONFIG_ARMV7_SECURE_BASE :
224 +               AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
225 +       {
226 +               *(._secure.text)
227 +       }
228 +
229 +       . = LOADADDR(.__secure_start) +
230 +               SIZEOF(.__secure_start) +
231 +               SIZEOF(.secure_text);
232 +
233 +       __secure_end_lma = .;
234 +       .__secure_end : AT(__secure_end_lma) {
235 +               *(.__secure_end)
236 +               LONG(0x1d1071c);        /* Must output something to reset LMA */
237 +       }
238 +#endif
239 +
240         . = ALIGN(4);
241         .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
242  
243 diff --git a/arch/arm/lib/sections.c b/arch/arm/lib/sections.c
244 index 5b30bcb..a1205c3 100644
245 --- a/arch/arm/lib/sections.c
246 +++ b/arch/arm/lib/sections.c
247 @@ -25,4 +25,6 @@ char __image_copy_start[0] __attribute__((section(".__image_copy_start")));
248  char __image_copy_end[0] __attribute__((section(".__image_copy_end")));
249  char __rel_dyn_start[0] __attribute__((section(".__rel_dyn_start")));
250  char __rel_dyn_end[0] __attribute__((section(".__rel_dyn_end")));
251 +char __secure_start[0] __attribute__((section(".__secure_start")));
252 +char __secure_end[0] __attribute__((section(".__secure_end")));
253  char _end[0] __attribute__((section(".__end")));
254 From d7ebd8f57e84ea92ef0cf55080f0acec9c6d1ace Mon Sep 17 00:00:00 2001
255 From: Marc Zyngier <marc.zyngier@arm.com>
256 Date: Sat, 7 Dec 2013 11:19:12 +0000
257 Subject: [PATCH] ARM: HYP/non-sec: allow relocation to secure RAM
258
259 The current non-sec switching code suffers from one major issue:
260 it cannot run in secure RAM, as a large part of u-boot still needs
261 to be run while we're switched to non-secure.
262
263 This patch reworks the whole HYP/non-secure strategy by:
264 - making sure the secure code is the *last* thing u-boot executes
265   before entering the payload
266 - performing an exception return from secure mode directly into
267   the payload
268 - allowing the code to be dynamically relocated to secure RAM
269   before switching to non-secure.
270
271 This involves quite a bit of horrible code, specially as u-boot
272 relocation is quite primitive.
273
274 Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
275 ---
276  arch/arm/cpu/armv7/nonsec_virt.S | 161 +++++++++++++++++++--------------------
277  arch/arm/cpu/armv7/virt-v7.c     |  59 +++++---------
278  arch/arm/include/asm/armv7.h     |  10 ++-
279  arch/arm/include/asm/secure.h    |  26 +++++++
280  arch/arm/lib/bootm.c             |  22 +++---
281  5 files changed, 138 insertions(+), 140 deletions(-)
282  create mode 100644 arch/arm/include/asm/secure.h
283
284 diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S
285 index b5c946f..2a43e3c 100644
286 --- a/arch/arm/cpu/armv7/nonsec_virt.S
287 +++ b/arch/arm/cpu/armv7/nonsec_virt.S
288 @@ -10,10 +10,13 @@
289  #include <linux/linkage.h>
290  #include <asm/gic.h>
291  #include <asm/armv7.h>
292 +#include <asm/proc-armv/ptrace.h>
293  
294  .arch_extension sec
295  .arch_extension virt
296  
297 +       .pushsection ._secure.text, "ax"
298 +
299         .align  5
300  /* the vector table for secure state and HYP mode */
301  _monitor_vectors:
302 @@ -22,51 +25,86 @@ _monitor_vectors:
303         adr pc, _secure_monitor
304         .word 0
305         .word 0
306 -       adr pc, _hyp_trap
307 +       .word 0
308         .word 0
309         .word 0
310  
311 +.macro is_cpu_virt_capable     tmp
312 +       mrc     p15, 0, \tmp, c0, c1, 1         @ read ID_PFR1
313 +       and     \tmp, \tmp, #CPUID_ARM_VIRT_MASK        @ mask virtualization bits
314 +       cmp     \tmp, #(1 << CPUID_ARM_VIRT_SHIFT)
315 +.endm
316 +
317  /*
318   * secure monitor handler
319   * U-boot calls this "software interrupt" in start.S
320   * This is executed on a "smc" instruction, we use a "smc #0" to switch
321   * to non-secure state.
322 - * We use only r0 and r1 here, due to constraints in the caller.
323 + * r0, r1, r2: passed to the callee
324 + * ip: target PC
325   */
326  _secure_monitor:
327 -       mrc     p15, 0, r1, c1, c1, 0           @ read SCR
328 -       bic     r1, r1, #0x4e                   @ clear IRQ, FIQ, EA, nET bits
329 -       orr     r1, r1, #0x31                   @ enable NS, AW, FW bits
330 +       mrc     p15, 0, r5, c1, c1, 0           @ read SCR
331 +       bic     r5, r5, #0x4e                   @ clear IRQ, FIQ, EA, nET bits
332 +       orr     r5, r5, #0x31                   @ enable NS, AW, FW bits
333  
334 -       mrc     p15, 0, r0, c0, c1, 1           @ read ID_PFR1
335 -       and     r0, r0, #CPUID_ARM_VIRT_MASK    @ mask virtualization bits
336 -       cmp     r0, #(1 << CPUID_ARM_VIRT_SHIFT)
337 +       mov     r6, #SVC_MODE                   @ default mode is SVC
338 +       is_cpu_virt_capable r4
339  #ifdef CONFIG_ARMV7_VIRT
340 -       orreq   r1, r1, #0x100                  @ allow HVC instruction
341 +       orreq   r5, r5, #0x100                  @ allow HVC instruction
342 +       moveq   r6, #HYP_MODE                   @ Enter the kernel as HYP
343  #endif
344  
345 -       mcr     p15, 0, r1, c1, c1, 0           @ write SCR (with NS bit set)
346 +       mcr     p15, 0, r5, c1, c1, 0           @ write SCR (with NS bit set)
347         isb
348  
349 -#ifdef CONFIG_ARMV7_VIRT
350 -       mrceq   p15, 0, r0, c12, c0, 1          @ get MVBAR value
351 -       mcreq   p15, 4, r0, c12, c0, 0          @ write HVBAR
352 -#endif
353         bne     1f
354  
355         @ Reset CNTVOFF to 0 before leaving monitor mode
356 -       mrc     p15, 0, r0, c0, c1, 1           @ read ID_PFR1
357 -       ands    r0, r0, #CPUID_ARM_GENTIMER_MASK        @ test arch timer bits
358 -       movne   r0, #0
359 -       mcrrne  p15, 4, r0, r0, c14             @ Reset CNTVOFF to zero
360 +       mrc     p15, 0, r4, c0, c1, 1           @ read ID_PFR1
361 +       ands    r4, r4, #CPUID_ARM_GENTIMER_MASK        @ test arch timer bits
362 +       movne   r4, #0
363 +       mcrrne  p15, 4, r4, r4, c14             @ Reset CNTVOFF to zero
364  1:
365 -       movs    pc, lr                          @ return to non-secure SVC
366 -
367 -_hyp_trap:
368 -       mrs     lr, elr_hyp     @ for older asm: .byte 0x00, 0xe3, 0x0e, 0xe1
369 -       mov pc, lr                              @ do no switch modes, but
370 -                                               @ return to caller
371 -
372 +       mov     lr, ip
373 +       mov     ip, #(F_BIT | I_BIT | A_BIT)    @ Set A, I and F
374 +       tst     lr, #1                          @ Check for Thumb PC
375 +       orrne   ip, ip, #T_BIT                  @ Set T if Thumb
376 +       orr     ip, ip, r6                      @ Slot target mode in
377 +       msr     spsr_cxfs, ip                   @ Set full SPSR
378 +       movs    pc, lr                          @ ERET to non-secure
379 +
380 +ENTRY(_do_nonsec_entry)
381 +       mov     ip, r0
382 +       mov     r0, r1
383 +       mov     r1, r2
384 +       mov     r2, r3
385 +       smc     #0
386 +ENDPROC(_do_nonsec_entry)
387 +
388 +.macro get_cbar_addr   addr
389 +#ifdef CONFIG_ARM_GIC_BASE_ADDRESS
390 +       ldr     \addr, =CONFIG_ARM_GIC_BASE_ADDRESS
391 +#else
392 +       mrc     p15, 4, \addr, c15, c0, 0       @ read CBAR
393 +       bfc     \addr, #0, #15                  @ clear reserved bits
394 +#endif
395 +.endm
396 +
397 +.macro get_gicd_addr   addr
398 +       get_cbar_addr   \addr
399 +       add     \addr, \addr, #GIC_DIST_OFFSET  @ GIC dist i/f offset
400 +.endm
401 +
402 +.macro get_gicc_addr   addr, tmp
403 +       get_cbar_addr   \addr
404 +       is_cpu_virt_capable \tmp
405 +       movne   \tmp, #GIC_CPU_OFFSET_A9        @ GIC CPU offset for A9
406 +       moveq   \tmp, #GIC_CPU_OFFSET_A15       @ GIC CPU offset for A15/A7
407 +       add     \addr, \addr, \tmp
408 +.endm
409 +
410 +#ifndef CONFIG_ARMV7_PSCI
411  /*
412   * Secondary CPUs start here and call the code for the core specific parts
413   * of the non-secure and HYP mode transition. The GIC distributor specific
414 @@ -74,31 +112,21 @@ _hyp_trap:
415   * Then they go back to wfi and wait to be woken up by the kernel again.
416   */
417  ENTRY(_smp_pen)
418 -       mrs     r0, cpsr
419 -       orr     r0, r0, #0xc0
420 -       msr     cpsr, r0                        @ disable interrupts
421 -       ldr     r1, =_start
422 -       mcr     p15, 0, r1, c12, c0, 0          @ set VBAR
423 +       cpsid   i
424 +       cpsid   f
425  
426         bl      _nonsec_init
427 -       mov     r12, r0                         @ save GICC address
428 -#ifdef CONFIG_ARMV7_VIRT
429 -       bl      _switch_to_hyp
430 -#endif
431 -
432 -       ldr     r1, [r12, #GICC_IAR]            @ acknowledge IPI
433 -       str     r1, [r12, #GICC_EOIR]           @ signal end of interrupt
434  
435         adr     r0, _smp_pen                    @ do not use this address again
436         b       smp_waitloop                    @ wait for IPIs, board specific
437  ENDPROC(_smp_pen)
438 +#endif
439  
440  /*
441   * Switch a core to non-secure state.
442   *
443   *  1. initialize the GIC per-core interface
444   *  2. allow coprocessor access in non-secure modes
445 - *  3. switch the cpu mode (by calling "smc #0")
446   *
447   * Called from smp_pen by secondary cores and directly by the BSP.
448   * Do not assume that the stack is available and only use registers
449 @@ -108,38 +136,23 @@ ENDPROC(_smp_pen)
450   * though, but we check this in C before calling this function.
451   */
452  ENTRY(_nonsec_init)
453 -#ifdef CONFIG_ARM_GIC_BASE_ADDRESS
454 -       ldr     r2, =CONFIG_ARM_GIC_BASE_ADDRESS
455 -#else
456 -       mrc     p15, 4, r2, c15, c0, 0          @ read CBAR
457 -       bfc     r2, #0, #15                     @ clear reserved bits
458 -#endif
459 -       add     r3, r2, #GIC_DIST_OFFSET        @ GIC dist i/f offset
460 +       get_gicd_addr   r3
461 +
462         mvn     r1, #0                          @ all bits to 1
463         str     r1, [r3, #GICD_IGROUPRn]        @ allow private interrupts
464  
465 -       mrc     p15, 0, r0, c0, c0, 0           @ read MIDR
466 -       ldr     r1, =MIDR_PRIMARY_PART_MASK
467 -       and     r0, r0, r1                      @ mask out variant and revision
468 +       get_gicc_addr   r3, r1
469  
470 -       ldr     r1, =MIDR_CORTEX_A7_R0P0 & MIDR_PRIMARY_PART_MASK
471 -       cmp     r0, r1                          @ check for Cortex-A7
472 -
473 -       ldr     r1, =MIDR_CORTEX_A15_R0P0 & MIDR_PRIMARY_PART_MASK
474 -       cmpne   r0, r1                          @ check for Cortex-A15
475 -
476 -       movne   r1, #GIC_CPU_OFFSET_A9          @ GIC CPU offset for A9
477 -       moveq   r1, #GIC_CPU_OFFSET_A15         @ GIC CPU offset for A15/A7
478 -       add     r3, r2, r1                      @ r3 = GIC CPU i/f addr
479 -
480 -       mov     r1, #1                          @ set GICC_CTLR[enable]
481 +       mov     r1, #3                          @ Enable both groups
482         str     r1, [r3, #GICC_CTLR]            @ and clear all other bits
483         mov     r1, #0xff
484         str     r1, [r3, #GICC_PMR]             @ set priority mask register
485  
486 +       mrc     p15, 0, r0, c1, c1, 2
487         movw    r1, #0x3fff
488 -       movt    r1, #0x0006
489 -       mcr     p15, 0, r1, c1, c1, 2           @ NSACR = all copros to non-sec
490 +       movt    r1, #0x0004
491 +       orr     r0, r0, r1
492 +       mcr     p15, 0, r0, c1, c1, 2           @ NSACR = all copros to non-sec
493  
494  /* The CNTFRQ register of the generic timer needs to be
495   * programmed in secure state. Some primary bootloaders / firmware
496 @@ -157,21 +170,9 @@ ENTRY(_nonsec_init)
497  
498         adr     r1, _monitor_vectors
499         mcr     p15, 0, r1, c12, c0, 1          @ set MVBAR to secure vectors
500 -
501 -       mrc     p15, 0, ip, c12, c0, 0          @ save secure copy of VBAR
502 -
503         isb
504 -       smc     #0                              @ call into MONITOR mode
505 -
506 -       mcr     p15, 0, ip, c12, c0, 0          @ write non-secure copy of VBAR
507 -
508 -       mov     r1, #1
509 -       str     r1, [r3, #GICC_CTLR]            @ enable non-secure CPU i/f
510 -       add     r2, r2, #GIC_DIST_OFFSET
511 -       str     r1, [r2, #GICD_CTLR]            @ allow private interrupts
512  
513         mov     r0, r3                          @ return GICC address
514 -
515         bx      lr
516  ENDPROC(_nonsec_init)
517  
518 @@ -183,18 +184,10 @@ ENTRY(smp_waitloop)
519         ldr     r1, [r1]
520         cmp     r0, r1                  @ make sure we dont execute this code
521         beq     smp_waitloop            @ again (due to a spurious wakeup)
522 -       mov     pc, r1
523 +       mov     r0, r1
524 +       b       _do_nonsec_entry
525  ENDPROC(smp_waitloop)
526  .weak smp_waitloop
527  #endif
528  
529 -ENTRY(_switch_to_hyp)
530 -       mov     r0, lr
531 -       mov     r1, sp                          @ save SVC copy of LR and SP
532 -       isb
533 -       hvc #0                   @ for older asm: .byte 0x70, 0x00, 0x40, 0xe1
534 -       mov     sp, r1
535 -       mov     lr, r0                          @ restore SVC copy of LR and SP
536 -
537 -       bx      lr
538 -ENDPROC(_switch_to_hyp)
539 +       .popsection
540 diff --git a/arch/arm/cpu/armv7/virt-v7.c b/arch/arm/cpu/armv7/virt-v7.c
541 index 2cd604f..6500030 100644
542 --- a/arch/arm/cpu/armv7/virt-v7.c
543 +++ b/arch/arm/cpu/armv7/virt-v7.c
544 @@ -13,17 +13,10 @@
545  #include <asm/armv7.h>
546  #include <asm/gic.h>
547  #include <asm/io.h>
548 +#include <asm/secure.h>
549  
550  unsigned long gic_dist_addr;
551  
552 -static unsigned int read_cpsr(void)
553 -{
554 -       unsigned int reg;
555 -
556 -       asm volatile ("mrs %0, cpsr\n" : "=r" (reg));
557 -       return reg;
558 -}
559 -
560  static unsigned int read_id_pfr1(void)
561  {
562         unsigned int reg;
563 @@ -72,6 +65,18 @@ static unsigned long get_gicd_base_address(void)
564  #endif
565  }
566  
567 +static void relocate_secure_section(void)
568 +{
569 +#ifdef CONFIG_ARMV7_SECURE_BASE
570 +       size_t sz = __secure_end - __secure_start;
571 +
572 +       memcpy((void *)CONFIG_ARMV7_SECURE_BASE, __secure_start, sz);
573 +       flush_dcache_range(CONFIG_ARMV7_SECURE_BASE,
574 +                          CONFIG_ARMV7_SECURE_BASE + sz + 1);
575 +       invalidate_icache_all();
576 +#endif
577 +}
578 +
579  static void kick_secondary_cpus_gic(unsigned long gicdaddr)
580  {
581         /* kick all CPUs (except this one) by writing to GICD_SGIR */
582 @@ -83,35 +88,7 @@ void __weak smp_kick_all_cpus(void)
583         kick_secondary_cpus_gic(gic_dist_addr);
584  }
585  
586 -int armv7_switch_hyp(void)
587 -{
588 -       unsigned int reg;
589 -
590 -       /* check whether we are in HYP mode already */
591 -       if ((read_cpsr() & 0x1f) == 0x1a) {
592 -               debug("CPU already in HYP mode\n");
593 -               return 0;
594 -       }
595 -
596 -       /* check whether the CPU supports the virtualization extensions */
597 -       reg = read_id_pfr1();
598 -       if ((reg & CPUID_ARM_VIRT_MASK) != 1 << CPUID_ARM_VIRT_SHIFT) {
599 -               printf("HYP mode: Virtualization extensions not implemented.\n");
600 -               return -1;
601 -       }
602 -
603 -       /* call the HYP switching code on this CPU also */
604 -       _switch_to_hyp();
605 -
606 -       if ((read_cpsr() & 0x1F) != 0x1a) {
607 -               printf("HYP mode: switch not successful.\n");
608 -               return -1;
609 -       }
610 -
611 -       return 0;
612 -}
613 -
614 -int armv7_switch_nonsec(void)
615 +int armv7_init_nonsec(void)
616  {
617         unsigned int reg;
618         unsigned itlinesnr, i;
619 @@ -147,11 +124,13 @@ int armv7_switch_nonsec(void)
620         for (i = 1; i <= itlinesnr; i++)
621                 writel((unsigned)-1, gic_dist_addr + GICD_IGROUPRn + 4 * i);
622  
623 -       smp_set_core_boot_addr((unsigned long)_smp_pen, -1);
624 +#ifndef CONFIG_ARMV7_PSCI
625 +       smp_set_core_boot_addr((unsigned long)secure_ram_addr(_smp_pen), -1);
626         smp_kick_all_cpus();
627 +#endif
628  
629         /* call the non-sec switching code on this CPU also */
630 -       _nonsec_init();
631 -
632 +       relocate_secure_section();
633 +       secure_ram_addr(_nonsec_init)();
634         return 0;
635  }
636 diff --git a/arch/arm/include/asm/armv7.h b/arch/arm/include/asm/armv7.h
637 index 395444e..11476dd 100644
638 --- a/arch/arm/include/asm/armv7.h
639 +++ b/arch/arm/include/asm/armv7.h
640 @@ -78,13 +78,17 @@ void v7_outer_cache_inval_range(u32 start, u32 end);
641  
642  #if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT)
643  
644 -int armv7_switch_nonsec(void);
645 -int armv7_switch_hyp(void);
646 +int armv7_init_nonsec(void);
647  
648  /* defined in assembly file */
649  unsigned int _nonsec_init(void);
650 +void _do_nonsec_entry(void *target_pc, unsigned long r0,
651 +                     unsigned long r1, unsigned long r2);
652  void _smp_pen(void);
653 -void _switch_to_hyp(void);
654 +
655 +extern char __secure_start[];
656 +extern char __secure_end[];
657 +
658  #endif /* CONFIG_ARMV7_NONSEC || CONFIG_ARMV7_VIRT */
659  
660  #endif /* ! __ASSEMBLY__ */
661 diff --git a/arch/arm/include/asm/secure.h b/arch/arm/include/asm/secure.h
662 new file mode 100644
663 index 0000000..effdb18
664 --- /dev/null
665 +++ b/arch/arm/include/asm/secure.h
666 @@ -0,0 +1,26 @@
667 +#ifndef __ASM_SECURE_H
668 +#define __ASM_SECURE_H
669 +
670 +#include <config.h>
671 +
672 +#ifdef CONFIG_ARMV7_SECURE_BASE
673 +/*
674 + * Warning, horror ahead.
675 + *
676 + * The target code lives in our "secure ram", but u-boot doesn't know
677 + * that, and has blindly added reloc_off to every relocation
678 + * entry. Gahh. Do the opposite conversion. This hack also prevents
679 + * GCC from generating code veeners, which u-boot doesn't relocate at
680 + * all...
681 + */
682 +#define secure_ram_addr(_fn) ({                                                \
683 +                       DECLARE_GLOBAL_DATA_PTR;                        \
684 +                       void *__fn = _fn;                               \
685 +                       typeof(_fn) *__tmp = (__fn - gd->reloc_off);    \
686 +                       __tmp;                                          \
687 +               })
688 +#else
689 +#define secure_ram_addr(_fn)   (_fn)
690 +#endif
691 +
692 +#endif
693 diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
694 index 10634a4..61aa14e 100644
695 --- a/arch/arm/lib/bootm.c
696 +++ b/arch/arm/lib/bootm.c
697 @@ -20,6 +20,7 @@
698  #include <libfdt.h>
699  #include <fdt_support.h>
700  #include <asm/bootm.h>
701 +#include <asm/secure.h>
702  #include <linux/compiler.h>
703  
704  #if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT)
705 @@ -184,27 +185,17 @@ static void setup_end_tag(bd_t *bd)
706  
707  __weak void setup_board_tags(struct tag **in_params) {}
708  
709 +#ifdef CONFIG_ARM64
710  static void do_nonsec_virt_switch(void)
711  {
712 -#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT)
713 -       if (armv7_switch_nonsec() == 0)
714 -#ifdef CONFIG_ARMV7_VIRT
715 -               if (armv7_switch_hyp() == 0)
716 -                       debug("entered HYP mode\n");
717 -#else
718 -               debug("entered non-secure state\n");
719 -#endif
720 -#endif
721 -
722 -#ifdef CONFIG_ARM64
723         smp_kick_all_cpus();
724         flush_dcache_all();     /* flush cache before swtiching to EL2 */
725         armv8_switch_to_el2();
726  #ifdef CONFIG_ARMV8_SWITCH_TO_EL1
727         armv8_switch_to_el1();
728  #endif
729 -#endif
730  }
731 +#endif
732  
733  /* Subcommand: PREP */
734  static void boot_prep_linux(bootm_headers_t *images)
735 @@ -287,8 +278,13 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
736                 r2 = gd->bd->bi_boot_params;
737  
738         if (!fake) {
739 -               do_nonsec_virt_switch();
740 +#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT)
741 +               armv7_init_nonsec();
742 +               secure_ram_addr(_do_nonsec_entry)(kernel_entry,
743 +                                                 0, machid, r2);
744 +#else
745                 kernel_entry(0, machid, r2);
746 +#endif
747         }
748  #endif
749  }
750 From 8ea1554da4a6e556d3213a77cf59daa1c154bdb5 Mon Sep 17 00:00:00 2001
751 From: Marc Zyngier <marc.zyngier@arm.com>
752 Date: Sat, 7 Dec 2013 11:19:13 +0000
753 Subject: [PATCH] ARM: HYP/non-sec: add generic ARMv7 PSCI code
754
755 Implement core support for PSCI. As this is generic code, it doesn't
756 implement anything really useful (all the functions are returning
757 Not Implemented).
758
759 Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
760 ---
761  arch/arm/cpu/armv7/Makefile |   4 ++
762  arch/arm/cpu/armv7/psci.S   | 105 ++++++++++++++++++++++++++++++++++++++++++++
763  arch/arm/include/asm/psci.h |  35 +++++++++++++++
764  3 files changed, 144 insertions(+)
765  create mode 100644 arch/arm/cpu/armv7/psci.S
766  create mode 100644 arch/arm/include/asm/psci.h
767
768 diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile
769 index 6f17771..0cf5c45 100644
770 --- a/arch/arm/cpu/armv7/Makefile
771 +++ b/arch/arm/cpu/armv7/Makefile
772 @@ -24,6 +24,10 @@ obj-y        += nonsec_virt.o
773  obj-y  += virt-v7.o
774  endif
775  
776 +ifneq ($(CONFIG_ARMV7_PSCI),)
777 +obj-y  += psci.o
778 +endif
779 +
780  obj-$(CONFIG_KONA) += kona-common/
781  obj-$(CONFIG_OMAP_COMMON) += omap-common/
782  obj-$(CONFIG_TEGRA) += tegra-common/
783 diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S
784 new file mode 100644
785 index 0000000..a9341e0
786 --- /dev/null
787 +++ b/arch/arm/cpu/armv7/psci.S
788 @@ -0,0 +1,105 @@
789 +/*
790 + * Copyright (C) 2013 - ARM Ltd
791 + * Author: Marc Zyngier <marc.zyngier@arm.com>
792 + *
793 + * This program is free software; you can redistribute it and/or modify
794 + * it under the terms of the GNU General Public License version 2 as
795 + * published by the Free Software Foundation.
796 + *
797 + * This program is distributed in the hope that it will be useful,
798 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
799 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
800 + * GNU General Public License for more details.
801 + *
802 + * You should have received a copy of the GNU General Public License
803 + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
804 + */
805 +
806 +#include <config.h>
807 +#include <linux/linkage.h>
808 +#include <asm/psci.h>
809 +
810 +       .pushsection ._secure.text, "ax"
811 +
812 +       .arch_extension sec
813 +
814 +       .align  5
815 +       .globl _psci_vectors
816 +_psci_vectors:
817 +       b       default_psci_vector     @ reset
818 +       b       default_psci_vector     @ undef
819 +       b       _smc_psci               @ smc
820 +       b       default_psci_vector     @ pabort
821 +       b       default_psci_vector     @ dabort
822 +       b       default_psci_vector     @ hyp
823 +       b       default_psci_vector     @ irq
824 +       b       psci_fiq_enter          @ fiq
825 +
826 +ENTRY(psci_fiq_enter)
827 +       movs    pc, lr
828 +ENDPROC(psci_fiq_enter)
829 +.weak psci_fiq_enter
830 +
831 +ENTRY(default_psci_vector)
832 +       movs    pc, lr
833 +ENDPROC(default_psci_vector)
834 +.weak default_psci_vector
835 +
836 +ENTRY(psci_cpu_suspend)
837 +ENTRY(psci_cpu_off)
838 +ENTRY(psci_cpu_on)
839 +ENTRY(psci_migrate)
840 +       mov     r0, #ARM_PSCI_RET_NI    @ Return -1 (Not Implemented)
841 +       mov     pc, lr
842 +ENDPROC(psci_migrate)
843 +ENDPROC(psci_cpu_on)
844 +ENDPROC(psci_cpu_off)
845 +ENDPROC(psci_cpu_suspend)
846 +.weak psci_cpu_suspend
847 +.weak psci_cpu_off
848 +.weak psci_cpu_on
849 +.weak psci_migrate
850 +
851 +_psci_table:
852 +       .word   ARM_PSCI_FN_CPU_SUSPEND
853 +       .word   psci_cpu_suspend
854 +       .word   ARM_PSCI_FN_CPU_OFF
855 +       .word   psci_cpu_off
856 +       .word   ARM_PSCI_FN_CPU_ON
857 +       .word   psci_cpu_on
858 +       .word   ARM_PSCI_FN_MIGRATE
859 +       .word   psci_migrate
860 +       .word   0
861 +       .word   0
862 +
863 +_smc_psci:
864 +       push    {r3-r7,lr}
865 +
866 +       @ Switch to secure
867 +       mrc     p15, 0, r7, c1, c1, 0
868 +       bic     r4, r7, #1
869 +       mcr     p15, 0, r4, c1, c1, 0
870 +       isb
871 +
872 +       adr     r4, _psci_table
873 +1:     ldr     r5, [r4]        @ Load PSCI function ID
874 +       ldr     r6, [r4, #4]    @ Load target PC
875 +       cmp     r5, #0          @ If reach the end, bail out
876 +       mvneq   r0, #0          @ Return -1 (Not Implemented)
877 +       beq     2f
878 +       cmp     r0, r5          @ If not matching, try next entry
879 +       addne   r4, r4, #8
880 +       bne     1b
881 +       cmp     r6, #0          @ Not implemented
882 +       moveq   r0, #ARM_PSCI_RET_NI
883 +       beq     2f
884 +
885 +       blx     r6              @ Execute PSCI function
886 +
887 +       @ Switch back to non-secure
888 +       mcr     p15, 0, r7, c1, c1, 0
889 +
890 +2:     pop     {r3-r7, lr}
891 +       movs    pc, lr          @ Return to the kernel
892 +
893 +       .popsection
894 diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h
895 new file mode 100644
896 index 0000000..704b4b0
897 --- /dev/null
898 +++ b/arch/arm/include/asm/psci.h
899 @@ -0,0 +1,35 @@
900 +/*
901 + * Copyright (C) 2013 - ARM Ltd
902 + * Author: Marc Zyngier <marc.zyngier@arm.com>
903 + *
904 + * This program is free software; you can redistribute it and/or modify
905 + * it under the terms of the GNU General Public License version 2 as
906 + * published by the Free Software Foundation.
907 + *
908 + * This program is distributed in the hope that it will be useful,
909 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
910 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
911 + * GNU General Public License for more details.
912 + *
913 + * You should have received a copy of the GNU General Public License
914 + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
915 + */
916 +
917 +#ifndef __ARM_PSCI_H__
918 +#define __ARM_PSCI_H__
919 +
920 +/* PSCI interface */
921 +#define ARM_PSCI_FN_BASE               0x95c1ba5e
922 +#define ARM_PSCI_FN(n)                 (ARM_PSCI_FN_BASE + (n))
923 +
924 +#define ARM_PSCI_FN_CPU_SUSPEND                ARM_PSCI_FN(0)
925 +#define ARM_PSCI_FN_CPU_OFF            ARM_PSCI_FN(1)
926 +#define ARM_PSCI_FN_CPU_ON             ARM_PSCI_FN(2)
927 +#define ARM_PSCI_FN_MIGRATE            ARM_PSCI_FN(3)
928 +
929 +#define ARM_PSCI_RET_SUCCESS           0
930 +#define ARM_PSCI_RET_NI                        (-1)
931 +#define ARM_PSCI_RET_INVAL             (-2)
932 +#define ARM_PSCI_RET_DENIED            (-3)
933 +
934 +#endif /* __ARM_PSCI_H__ */
935 From 0ca6171c385fed00125b320592ee94922f44f13a Mon Sep 17 00:00:00 2001
936 From: Marc Zyngier <marc.zyngier@arm.com>
937 Date: Sat, 7 Dec 2013 11:19:14 +0000
938 Subject: [PATCH] ARM: HYP/non-sec: add the option for a second-stage monitor
939
940 Allow the switch to a second stage secure monitor just before
941 switching to non-secure.
942
943 This allows a resident piece of firmware to be active once the
944 kernel has been entered (the u-boot monitor is dead anyway,
945 its pages being reused).
946
947 Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
948 ---
949  arch/arm/cpu/armv7/nonsec_virt.S | 13 +++++++++++--
950  1 file changed, 11 insertions(+), 2 deletions(-)
951
952 diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S
953 index 2a43e3c..745670e 100644
954 --- a/arch/arm/cpu/armv7/nonsec_virt.S
955 +++ b/arch/arm/cpu/armv7/nonsec_virt.S
956 @@ -44,10 +44,19 @@ _monitor_vectors:
957   * ip: target PC
958   */
959  _secure_monitor:
960 +#ifdef CONFIG_ARMV7_PSCI
961 +       ldr     r5, =_psci_vectors              @ Switch to the next monitor
962 +       mcr     p15, 0, r5, c12, c0, 1
963 +       isb
964 +
965 +       @ Obtain a secure stack, and configure the PSCI backend
966 +       bl      psci_arch_init
967 +#endif
968 +
969         mrc     p15, 0, r5, c1, c1, 0           @ read SCR
970 -       bic     r5, r5, #0x4e                   @ clear IRQ, FIQ, EA, nET bits
971 +       bic     r5, r5, #0x4a                   @ clear IRQ, EA, nET bits
972         orr     r5, r5, #0x31                   @ enable NS, AW, FW bits
973 -
974 +                                               @ FIQ preserved for secure mode
975         mov     r6, #SVC_MODE                   @ default mode is SVC
976         is_cpu_virt_capable r4
977  #ifdef CONFIG_ARMV7_VIRT
978 From 9aa373162eb2cc0055a6e4ecd46977c911de1124 Mon Sep 17 00:00:00 2001
979 From: Ma Haijun <mahaijuns@gmail.com>
980 Date: Sat, 15 Feb 2014 12:51:10 +0000
981 Subject: [PATCH] ARM: convert arch_fixup_memory_node to a generic FDT fixup
982  function
983
984 Some architecture needs extra device tree setup. Instead of adding
985 yet another hook, convert arch_fixup_memory_node to be a generic
986 FDT fixup function.
987
988 [maz: collapsed 3 patches into one, rewrote commit message]
989
990 Signed-off-by: Ma Haijun <mahaijuns@gmail.com>
991 Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
992 ---
993  arch/arm/lib/bootm-fdt.c | 2 +-
994  arch/arm/lib/bootm.c     | 2 +-
995  common/image-fdt.c       | 7 +++++--
996  include/common.h         | 6 +++---
997  4 files changed, 10 insertions(+), 7 deletions(-)
998
999 diff --git a/arch/arm/lib/bootm-fdt.c b/arch/arm/lib/bootm-fdt.c
1000 index e40691d..8394e15 100644
1001 --- a/arch/arm/lib/bootm-fdt.c
1002 +++ b/arch/arm/lib/bootm-fdt.c
1003 @@ -20,7 +20,7 @@
1004  
1005  DECLARE_GLOBAL_DATA_PTR;
1006  
1007 -int arch_fixup_memory_node(void *blob)
1008 +int arch_fixup_fdt(void *blob)
1009  {
1010         bd_t *bd = gd->bd;
1011         int bank;
1012 diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
1013 index 61aa14e..4cff6b0 100644
1014 --- a/arch/arm/lib/bootm.c
1015 +++ b/arch/arm/lib/bootm.c
1016 @@ -357,7 +357,7 @@ void boot_prep_vxworks(bootm_headers_t *images)
1017         if (images->ft_addr) {
1018                 off = fdt_path_offset(images->ft_addr, "/memory");
1019                 if (off < 0) {
1020 -                       if (arch_fixup_memory_node(images->ft_addr))
1021 +                       if (arch_fixup_fdt(images->ft_addr))
1022                                 puts("## WARNING: fixup memory failed!\n");
1023                 }
1024         }
1025 diff --git a/common/image-fdt.c b/common/image-fdt.c
1026 index a54a919..6f074de 100644
1027 --- a/common/image-fdt.c
1028 +++ b/common/image-fdt.c
1029 @@ -445,7 +445,7 @@ __weak int ft_verify_fdt(void *fdt)
1030         return 1;
1031  }
1032  
1033 -__weak int arch_fixup_memory_node(void *blob)
1034 +__weak int arch_fixup_fdt(void *blob)
1035  {
1036         return 0;
1037  }
1038 @@ -462,7 +462,10 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob,
1039                 puts(" - must RESET the board to recover.\n");
1040                 return -1;
1041         }
1042 -       arch_fixup_memory_node(blob);
1043 +       if (arch_fixup_fdt(blob) < 0) {
1044 +               puts("ERROR: arch specific fdt fixup failed");
1045 +               return -1;
1046 +       }
1047         if (IMAGE_OF_BOARD_SETUP)
1048                 ft_board_setup(blob, gd->bd);
1049         fdt_fixup_ethernet(blob);
1050 diff --git a/include/common.h b/include/common.h
1051 index cbd3c9e..700b015 100644
1052 --- a/include/common.h
1053 +++ b/include/common.h
1054 @@ -326,14 +326,14 @@ int arch_early_init_r(void);
1055  void board_show_dram(ulong size);
1056  
1057  /**
1058 - * arch_fixup_memory_node() - Write arch-specific memory information to fdt
1059 + * arch_fixup_fdt() - Write arch-specific information to fdt
1060   *
1061 - * Defined in arch/$(ARCH)/lib/bootm.c
1062 + * Defined in arch/$(ARCH)/lib/bootm-fdt.c
1063   *
1064   * @blob:      FDT blob to write to
1065   * @return 0 if ok, or -ve FDT_ERR_... on failure
1066   */
1067 -int arch_fixup_memory_node(void *blob);
1068 +int arch_fixup_fdt(void *blob);
1069  
1070  /* common/flash.c */
1071  void flash_perror (int);
1072 From ccdf689da800c9f1c5226146e936b071c7ec8800 Mon Sep 17 00:00:00 2001
1073 From: Marc Zyngier <marc.zyngier@arm.com>
1074 Date: Sat, 7 Dec 2013 11:19:15 +0000
1075 Subject: [PATCH] ARM: HYP/non-sec/PSCI: emit DT nodes
1076
1077 Generate the PSCI node in the device tree.
1078
1079 Also add a reserve section for the "secure" code that lives in
1080 in normal RAM, so that the kernel knows it'd better not trip on
1081 it.
1082
1083 Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
1084 ---
1085  arch/arm/cpu/armv7/Makefile  |   1 +
1086  arch/arm/cpu/armv7/virt-dt.c | 100 +++++++++++++++++++++++++++++++++++++++++++
1087  arch/arm/include/asm/armv7.h |   1 +
1088  arch/arm/lib/bootm-fdt.c     |  11 ++++-
1089  4 files changed, 111 insertions(+), 2 deletions(-)
1090  create mode 100644 arch/arm/cpu/armv7/virt-dt.c
1091
1092 diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile
1093 index 0cf5c45..93a5a69 100644
1094 --- a/arch/arm/cpu/armv7/Makefile
1095 +++ b/arch/arm/cpu/armv7/Makefile
1096 @@ -22,6 +22,7 @@ endif
1097  ifneq ($(CONFIG_ARMV7_NONSEC)$(CONFIG_ARMV7_VIRT),)
1098  obj-y  += nonsec_virt.o
1099  obj-y  += virt-v7.o
1100 +obj-y  += virt-dt.o
1101  endif
1102  
1103  ifneq ($(CONFIG_ARMV7_PSCI),)
1104 diff --git a/arch/arm/cpu/armv7/virt-dt.c b/arch/arm/cpu/armv7/virt-dt.c
1105 new file mode 100644
1106 index 0000000..0b0d6a7
1107 --- /dev/null
1108 +++ b/arch/arm/cpu/armv7/virt-dt.c
1109 @@ -0,0 +1,100 @@
1110 +/*
1111 + * Copyright (C) 2013 - ARM Ltd
1112 + * Author: Marc Zyngier <marc.zyngier@arm.com>
1113 + *
1114 + * This program is free software; you can redistribute it and/or modify
1115 + * it under the terms of the GNU General Public License version 2 as
1116 + * published by the Free Software Foundation.
1117 + *
1118 + * This program is distributed in the hope that it will be useful,
1119 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1120 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1121 + * GNU General Public License for more details.
1122 + *
1123 + * You should have received a copy of the GNU General Public License
1124 + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
1125 + */
1126 +
1127 +#include <common.h>
1128 +#include <stdio_dev.h>
1129 +#include <linux/ctype.h>
1130 +#include <linux/types.h>
1131 +#include <asm/global_data.h>
1132 +#include <libfdt.h>
1133 +#include <fdt_support.h>
1134 +#include <asm/armv7.h>
1135 +#include <asm/psci.h>
1136 +
1137 +static int fdt_psci(void *fdt)
1138 +{
1139 +#ifdef CONFIG_ARMV7_PSCI
1140 +       int nodeoff;
1141 +       int tmp;
1142 +
1143 +       nodeoff = fdt_path_offset(fdt, "/cpus");
1144 +       if (nodeoff < 0) {
1145 +               printf("couldn't find /cpus\n");
1146 +               return nodeoff;
1147 +       }
1148 +
1149 +       /* add 'enable-method = "psci"' to each cpu node */
1150 +       for (tmp = fdt_first_subnode(fdt, nodeoff);
1151 +            tmp >= 0;
1152 +            tmp = fdt_next_subnode(fdt, tmp)) {
1153 +               const struct fdt_property *prop;
1154 +               int len;
1155 +
1156 +               prop = fdt_get_property(fdt, tmp, "device_type", &len);
1157 +               if (!prop)
1158 +                       continue;
1159 +               if (len < 4)
1160 +                       continue;
1161 +               if (strcmp(prop->data, "cpu"))
1162 +                       continue;
1163 +
1164 +               fdt_setprop_string(fdt, tmp, "enable-method", "psci");
1165 +       }
1166 +
1167 +       nodeoff = fdt_path_offset(fdt, "/psci");
1168 +       if (nodeoff < 0) {
1169 +               nodeoff = fdt_path_offset(fdt, "/");
1170 +               if (nodeoff < 0)
1171 +                       return nodeoff;
1172 +
1173 +               nodeoff = fdt_add_subnode(fdt, nodeoff, "psci");
1174 +               if (nodeoff < 0)
1175 +                       return nodeoff;
1176 +       }
1177 +
1178 +       tmp = fdt_setprop_string(fdt, nodeoff, "compatible", "arm,psci");
1179 +       if (tmp)
1180 +               return tmp;
1181 +       tmp = fdt_setprop_string(fdt, nodeoff, "method", "smc");
1182 +       if (tmp)
1183 +               return tmp;
1184 +       tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_suspend", ARM_PSCI_FN_CPU_SUSPEND);
1185 +       if (tmp)
1186 +               return tmp;
1187 +       tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_off", ARM_PSCI_FN_CPU_OFF);
1188 +       if (tmp)
1189 +               return tmp;
1190 +       tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_on", ARM_PSCI_FN_CPU_ON);
1191 +       if (tmp)
1192 +               return tmp;
1193 +       tmp = fdt_setprop_u32(fdt, nodeoff, "migrate", ARM_PSCI_FN_MIGRATE);
1194 +       if (tmp)
1195 +               return tmp;
1196 +#endif
1197 +       return 0;
1198 +}
1199 +
1200 +int armv7_update_dt(void *fdt)
1201 +{
1202 +#ifndef CONFIG_ARMV7_SECURE_BASE
1203 +       /* secure code lives in RAM, keep it alive */
1204 +       fdt_add_mem_rsv(fdt, (unsigned long)__secure_start,
1205 +                       __secure_end - __secure_start);
1206 +#endif
1207 +
1208 +       return fdt_psci(fdt);
1209 +}
1210 diff --git a/arch/arm/include/asm/armv7.h b/arch/arm/include/asm/armv7.h
1211 index 11476dd..323f282 100644
1212 --- a/arch/arm/include/asm/armv7.h
1213 +++ b/arch/arm/include/asm/armv7.h
1214 @@ -79,6 +79,7 @@ void v7_outer_cache_inval_range(u32 start, u32 end);
1215  #if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT)
1216  
1217  int armv7_init_nonsec(void);
1218 +int armv7_update_dt(void *fdt);
1219  
1220  /* defined in assembly file */
1221  unsigned int _nonsec_init(void);
1222 diff --git a/arch/arm/lib/bootm-fdt.c b/arch/arm/lib/bootm-fdt.c
1223 index 8394e15..ccb76c7 100644
1224 --- a/arch/arm/lib/bootm-fdt.c
1225 +++ b/arch/arm/lib/bootm-fdt.c
1226 @@ -17,13 +17,14 @@
1227  
1228  #include <common.h>
1229  #include <fdt_support.h>
1230 +#include <asm/armv7.h>
1231  
1232  DECLARE_GLOBAL_DATA_PTR;
1233  
1234  int arch_fixup_fdt(void *blob)
1235  {
1236         bd_t *bd = gd->bd;
1237 -       int bank;
1238 +       int bank, ret;
1239         u64 start[CONFIG_NR_DRAM_BANKS];
1240         u64 size[CONFIG_NR_DRAM_BANKS];
1241  
1242 @@ -32,5 +33,11 @@ int arch_fixup_fdt(void *blob)
1243                 size[bank] = bd->bi_dram[bank].size;
1244         }
1245  
1246 -       return fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS);
1247 +       ret = fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS);
1248 +       if (ret)
1249 +               return ret;
1250 +
1251 +#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT)
1252 +       return armv7_update_dt(blob);
1253 +#endif
1254  }
1255 From d5ee64675e6481e4f29e48e494ea132cd74786c8 Mon Sep 17 00:00:00 2001
1256 From: Marc Zyngier <marc.zyngier@arm.com>
1257 Date: Sat, 7 Dec 2013 11:19:17 +0000
1258 Subject: [PATCH] sunxi: HYP/non-sec: add sun7i PSCI backend
1259
1260 So far, only supporting the CPU_ON method.
1261 Other functions can be added later.
1262
1263 Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
1264 ---
1265  arch/arm/cpu/armv7/sunxi/Makefile |   3 +
1266  arch/arm/cpu/armv7/sunxi/psci.S   | 162 ++++++++++++++++++++++++++++++++++++++
1267  include/configs/sun7i.h           |   6 ++
1268  3 files changed, 171 insertions(+)
1269  create mode 100644 arch/arm/cpu/armv7/sunxi/psci.S
1270
1271 diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile
1272 index 19e4b17..0df6772 100644
1273 --- a/arch/arm/cpu/armv7/sunxi/Makefile
1274 +++ b/arch/arm/cpu/armv7/sunxi/Makefile
1275 @@ -32,6 +32,9 @@ obj-y += cpu_info.o
1276  ifdef CONFIG_CMD_WATCHDOG
1277  obj-$(CONFIG_CMD_WATCHDOG)     += cmd_watchdog.o
1278  endif
1279 +ifdef CONFIG_ARMV7_PSCI
1280 +obj-y  += psci.o
1281 +endif
1282  endif
1283  
1284  ifdef CONFIG_SPL_BUILD
1285 diff --git a/arch/arm/cpu/armv7/sunxi/psci.S b/arch/arm/cpu/armv7/sunxi/psci.S
1286 new file mode 100644
1287 index 0000000..0084c81
1288 --- /dev/null
1289 +++ b/arch/arm/cpu/armv7/sunxi/psci.S
1290 @@ -0,0 +1,162 @@
1291 +/*
1292 + * Copyright (C) 2013 - ARM Ltd
1293 + * Author: Marc Zyngier <marc.zyngier@arm.com>
1294 + *
1295 + * Based on code by Carl van Schaik <carl@ok-labs.com>.
1296 + *
1297 + * This program is free software; you can redistribute it and/or modify
1298 + * it under the terms of the GNU General Public License version 2 as
1299 + * published by the Free Software Foundation.
1300 + *
1301 + * This program is distributed in the hope that it will be useful,
1302 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1303 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1304 + * GNU General Public License for more details.
1305 + *
1306 + * You should have received a copy of the GNU General Public License
1307 + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
1308 + */
1309 +
1310 +#include <config.h>
1311 +#include <asm/psci.h>
1312 +#include <asm/arch/cpu.h>
1313 +
1314 +/*
1315 + * Memory layout:
1316 + *
1317 + * SECURE_RAM to text_end :
1318 + *     ._secure_text section
1319 + * text_end to ALIGN_PAGE(text_end):
1320 + *     nothing
1321 + * ALIGN_PAGE(text_end) to ALIGN_PAGE(text_end) + 0x1000)
1322 + *     1kB of stack per CPU (4 CPUs max).
1323 + */
1324 +
1325 +       .pushsection ._secure.text, "ax"
1326 +
1327 +       .arch_extension sec
1328 +
1329 +#define        ONE_MS                  (CONFIG_SYS_CLK_FREQ / 1000)
1330 +#define        TEN_MS                  (10 * ONE_MS)
1331 +
1332 +.macro timer_wait      reg, ticks
1333 +       @ Program CNTP_TVAL
1334 +       movw    \reg, #(\ticks & 0xffff)
1335 +       movt    \reg, #(\ticks >> 16)
1336 +       mcr     p15, 0, \reg, c14, c2, 0
1337 +       isb
1338 +       @ Enable physical timer, mask interrupt
1339 +       mov     \reg, #3
1340 +       mcr     p15, 0, \reg, c14, c2, 1
1341 +       @ Poll physical timer until ISTATUS is on
1342 +1:     isb
1343 +       mrc     p15, 0, \reg, c14, c2, 1
1344 +       ands    \reg, \reg, #4
1345 +       bne     1b
1346 +       @ Disable timer
1347 +       mov     \reg, #0
1348 +       mcr     p15, 0, \reg, c14, c2, 1
1349 +       isb
1350 +.endm
1351 +
1352 +.globl psci_arch_init
1353 +psci_arch_init:
1354 +       mrc     p15, 0, r5, c1, c1, 0   @ Read SCR
1355 +       bic     r5, r5, #1              @ Secure mode
1356 +       mcr     p15, 0, r5, c1, c1, 0   @ Write SCR
1357 +       isb
1358 +
1359 +       mrc     p15, 0, r4, c0, c0, 5   @ MPIDR
1360 +       and     r4, r4, #3              @ cpu number in cluster
1361 +       mov     r5, #400                @ 1kB of stack per CPU
1362 +       mul     r4, r4, r5
1363 +
1364 +       adr     r5, text_end            @ end of text
1365 +       add     r5, r5, #0x2000         @ Skip two pages
1366 +       lsr     r5, r5, #12             @ Align to start of page
1367 +       lsl     r5, r5, #12
1368 +       sub     sp, r5, r4              @ here's our stack!
1369 +
1370 +       bx      lr
1371 +
1372 +       @ r1 = target CPU
1373 +       @ r2 = target PC
1374 +.globl psci_cpu_on
1375 +psci_cpu_on:
1376 +       adr     r0, _target_pc
1377 +       str     r2, [r0]
1378 +       dsb
1379 +
1380 +       movw    r0, #(SUNXI_CPUCFG_BASE & 0xffff)
1381 +       movt    r0, #(SUNXI_CPUCFG_BASE >> 16)
1382 +
1383 +       @ CPU mask
1384 +       and     r1, r1, #3      @ only care about first cluster
1385 +       mov     r4, #1
1386 +       lsl     r4, r4, r1
1387 +
1388 +       adr     r6, _sunxi_cpu_entry
1389 +       str     r6, [r0, #0x1a4] @ PRIVATE_REG (boot vector)
1390 +
1391 +       @ Assert reset on target CPU
1392 +       mov     r6, #0
1393 +       lsl     r5, r1, #6      @ 64 bytes per CPU
1394 +       add     r5, r5, #0x40   @ Offset from base
1395 +       add     r5, r5, r0      @ CPU control block
1396 +       str     r6, [r5]        @ Reset CPU
1397 +
1398 +       @ l1 invalidate
1399 +       ldr     r6, [r0, #0x184]
1400 +       bic     r6, r6, r4
1401 +       str     r6, [r0, #0x184]
1402 +
1403 +       @ Lock CPU
1404 +       ldr     r6, [r0, #0x1e4]
1405 +       bic     r6, r6, r4
1406 +       str     r6, [r0, #0x1e4]
1407 +
1408 +       @ Release power clamp
1409 +       movw    r6, #0x1ff
1410 +       movt    r6, #0
1411 +1:     lsrs    r6, r6, #1
1412 +       str     r6, [r0, #0x1b0]
1413 +       bne     1b
1414 +
1415 +       timer_wait r1, TEN_MS
1416 +
1417 +       @ Clear power gating
1418 +       ldr     r6, [r0, #0x1b4]
1419 +       bic     r6, r6, #1
1420 +       str     r6, [r0, #0x1b4]
1421 +
1422 +       @ Deassert reset on target CPU
1423 +       mov     r6, #3
1424 +       str     r6, [r5]
1425 +
1426 +       @ Unlock CPU
1427 +       ldr     r6, [r0, #0x1e4]
1428 +       orr     r6, r6, r4
1429 +       str     r6, [r0, #0x1e4]
1430 +
1431 +       mov     r0, #ARM_PSCI_RET_SUCCESS       @ Return PSCI_RET_SUCCESS
1432 +       mov     pc, lr
1433 +
1434 +_target_pc:
1435 +       .word   0
1436 +
1437 +_sunxi_cpu_entry:
1438 +       @ Set SMP bit
1439 +       mrc     p15, 0, r0, c1, c0, 1
1440 +       orr     r0, r0, #0x40
1441 +       mcr     p15, 0, r0, c1, c0, 1
1442 +       isb
1443 +
1444 +       bl      _nonsec_init
1445 +       bl      psci_arch_init
1446 +
1447 +       adr     r0, _target_pc
1448 +       ldr     r0, [r0]
1449 +       b       _do_nonsec_entry
1450 +
1451 +text_end:
1452 +       .popsection
1453 diff --git a/include/configs/sun7i.h b/include/configs/sun7i.h
1454 index 11cc9ea..bae7b37 100644
1455 --- a/include/configs/sun7i.h
1456 +++ b/include/configs/sun7i.h
1457 @@ -22,6 +22,12 @@
1458  #define CONFIG_BOARD_POSTCLK_INIT 1
1459  #endif
1460  
1461 +#define CONFIG_ARMV7_VIRT              1
1462 +#define CONFIG_ARMV7_NONSEC            1
1463 +#define CONFIG_ARMV7_PSCI              1
1464 +#define CONFIG_ARMV7_PSCI_NR_CPUS      2
1465 +#define CONFIG_ARMV7_SECURE_BASE       SUNXI_SRAM_B_BASE
1466 +
1467  /*
1468   * Include common sunxi configuration where most the settings are
1469   */
1470 From a74a847c3727209a45c30a80c01b930938941dd4 Mon Sep 17 00:00:00 2001
1471 From: Marc Zyngier <marc.zyngier@arm.com>
1472 Date: Sat, 7 Dec 2013 11:19:18 +0000
1473 Subject: [PATCH] sunxi: HYP/non-sec: configure CNTFRQ on all CPUs
1474
1475 CNTFRQ needs to be properly configured on all CPUs. Otherwise,
1476 virtual machines hoping to find valuable information on secondary
1477 CPUs will be disapointed...
1478
1479 Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
1480 ---
1481  include/configs/sun7i.h | 1 +
1482  1 file changed, 1 insertion(+)
1483
1484 diff --git a/include/configs/sun7i.h b/include/configs/sun7i.h
1485 index bae7b37..58a254b 100644
1486 --- a/include/configs/sun7i.h
1487 +++ b/include/configs/sun7i.h
1488 @@ -27,6 +27,7 @@
1489  #define CONFIG_ARMV7_PSCI              1
1490  #define CONFIG_ARMV7_PSCI_NR_CPUS      2
1491  #define CONFIG_ARMV7_SECURE_BASE       SUNXI_SRAM_B_BASE
1492 +#define CONFIG_SYS_CLK_FREQ            24000000
1493  
1494  /*
1495   * Include common sunxi configuration where most the settings are