blob: 373036c906a81cf82efdfe571b3a4172edbc5f22 [file] [log] [blame]
Soby Mathew0d268dc2016-07-11 14:13:56 +01001/*
2 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <arch.h>
32#include <asm_macros.S>
33#include <platform_def.h>
34#include "../drivers/pwrc/fvp_pwrc.h"
35#include "../fvp_def.h"
36
37 .globl plat_get_my_entrypoint
38 .globl plat_is_my_cpu_primary
39
40 /* ---------------------------------------------------------------------
41 * unsigned long plat_get_my_entrypoint (void);
42 *
43 * Main job of this routine is to distinguish between a cold and warm
44 * boot. On FVP, this information can be queried from the power
45 * controller. The Power Control SYS Status Register (PSYSR) indicates
46 * the wake-up reason for the CPU.
47 *
48 * For a cold boot, return 0.
49 * For a warm boot, read the mailbox and return the address it contains.
50 *
51 * TODO: PSYSR is a common register and should be
52 * accessed using locks. Since it is not possible
53 * to use locks immediately after a cold reset
54 * we are relying on the fact that after a cold
55 * reset all cpus will read the same WK field
56 * ---------------------------------------------------------------------
57 */
58func plat_get_my_entrypoint
59 /* ---------------------------------------------------------------------
60 * When bit PSYSR.WK indicates either "Wake by PPONR" or "Wake by GIC
61 * WakeRequest signal" then it is a warm boot.
62 * ---------------------------------------------------------------------
63 */
64 ldcopr r2, MPIDR
65 ldr r1, =PWRC_BASE
66 str r2, [r1, #PSYSR_OFF]
67 ldr r2, [r1, #PSYSR_OFF]
68 ubfx r2, r2, #PSYSR_WK_SHIFT, #PSYSR_WK_WIDTH
69 cmp r2, #WKUP_PPONR
70 beq warm_reset
71 cmp r2, #WKUP_GICREQ
72 beq warm_reset
73
74 /* Cold reset */
75 mov r0, #0
76 bx lr
77
78warm_reset:
79 /* ---------------------------------------------------------------------
80 * A mailbox is maintained in the trusted SRAM. It is flushed out of the
81 * caches after every update using normal memory so it is safe to read
82 * it here with SO attributes.
83 * ---------------------------------------------------------------------
84 */
85 ldr r0, =PLAT_ARM_TRUSTED_MAILBOX_BASE
86 ldr r0, [r0]
87 cmp r0, #0
88 beq _panic
89 bx lr
90
91 /* ---------------------------------------------------------------------
92 * The power controller indicates this is a warm reset but the mailbox
93 * is empty. This should never happen!
94 * ---------------------------------------------------------------------
95 */
96_panic:
97 b _panic
98endfunc plat_get_my_entrypoint
99
100 /* -----------------------------------------------------
101 * unsigned int plat_is_my_cpu_primary (void);
102 *
103 * Find out whether the current cpu is the primary
104 * cpu.
105 * -----------------------------------------------------
106 */
107func plat_is_my_cpu_primary
108 ldcopr r0, MPIDR
109 ldr r1, =(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
110 and r0, r1
111 cmp r0, #FVP_PRIMARY_CPU
112 moveq r0, #1
113 movne r0, #0
114 bx lr
115endfunc plat_is_my_cpu_primary