blob: ba857779aab304f1b6fb5fcfb733ef6bd14f4c00 [file] [log] [blame]
laurenw-arm7c7b1982020-10-21 13:34:40 -05001/*
2 * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
8#include <asm_macros.S>
9#include <drivers/arm/fvp/fvp_pwrc.h>
10#include <drivers/arm/gicv2.h>
11#include <drivers/arm/gicv3.h>
12
13#include <platform_def.h>
14
15
16 .globl plat_secondary_cold_boot_setup
17 .globl plat_get_my_entrypoint
18 .globl plat_is_my_cpu_primary
laurenw-arm7c7b1982020-10-21 13:34:40 -050019
20 /* -----------------------------------------------------
21 * void plat_secondary_cold_boot_setup (void);
22 *
23 * This function performs any platform specific actions
24 * needed for a secondary cpu after a cold reset e.g
25 * mark the cpu's presence, mechanism to place it in a
26 * holding pen etc.
27 * TODO: Should we read the PSYS register to make sure
28 * that the request has gone through.
29 * -----------------------------------------------------
30 */
31func plat_secondary_cold_boot_setup
32 /* ---------------------------------------------
33 * Power down this cpu.
34 * TODO: Do we need to worry about powering the
35 * cluster down as well here? That will need
36 * locks which we won't have unless an elf-
37 * loader zeroes out the zi section.
38 * ---------------------------------------------
39 */
40 mrs x0, mpidr_el1
41 mov_imm x1, PWRC_BASE
42 str w0, [x1, #PPOFFR_OFF]
43
44 /* ---------------------------------------------
45 * There is no sane reason to come out of this
46 * wfi so panic if we do. This cpu will be pow-
47 * ered on and reset by the cpu_on pm api
48 * ---------------------------------------------
49 */
50 dsb sy
51 wfi
52 no_ret plat_panic_handler
53endfunc plat_secondary_cold_boot_setup
54
55 /* ---------------------------------------------------------------------
56 * uintptr_t plat_get_my_entrypoint (void);
57 *
58 * Main job of this routine is to distinguish between a cold and warm
59 * boot. On FVP_R, this information can be queried from the power
60 * controller. The Power Control SYS Status Register (PSYSR) indicates
61 * the wake-up reason for the CPU.
62 *
63 * For a cold boot, return 0.
64 * For a warm boot, read the mailbox and return the address it contains.
65 *
66 * TODO: PSYSR is a common register and should be
67 * accessed using locks. Since it is not possible
68 * to use locks immediately after a cold reset
69 * we are relying on the fact that after a cold
70 * reset all cpus will read the same WK field
71 * ---------------------------------------------------------------------
72 */
73func plat_get_my_entrypoint
74 /* ---------------------------------------------------------------------
75 * When bit PSYSR.WK indicates either "Wake by PPONR" or "Wake by GIC
76 * WakeRequest signal" then it is a warm boot.
77 * ---------------------------------------------------------------------
78 */
79 mrs x2, mpidr_el1
80 mov_imm x1, PWRC_BASE
81 str w2, [x1, #PSYSR_OFF]
82 ldr w2, [x1, #PSYSR_OFF]
83 ubfx w2, w2, #PSYSR_WK_SHIFT, #PSYSR_WK_WIDTH
84 cmp w2, #WKUP_PPONR
85 beq warm_reset
86 cmp w2, #WKUP_GICREQ
87 beq warm_reset
88
89 /* Cold reset */
90 mov x0, #0
91 ret
92
93warm_reset:
94 /* ---------------------------------------------------------------------
95 * A mailbox is maintained in the trusted SRAM. It is flushed out of the
96 * caches after every update using normal memory so it is safe to read
97 * it here with SO attributes.
98 * ---------------------------------------------------------------------
99 */
100 mov_imm x0, PLAT_ARM_TRUSTED_MAILBOX_BASE
101 ldr x0, [x0]
102 cbz x0, _panic_handler
103 ret
104
105 /* ---------------------------------------------------------------------
106 * The power controller indicates this is a warm reset but the mailbox
107 * is empty. This should never happen!
108 * ---------------------------------------------------------------------
109 */
110_panic_handler:
111 no_ret plat_panic_handler
112endfunc plat_get_my_entrypoint
113
114 /* -----------------------------------------------------
115 * unsigned int plat_is_my_cpu_primary (void);
116 *
117 * Find out whether the current cpu is the primary
118 * cpu.
119 * -----------------------------------------------------
120 */
121func plat_is_my_cpu_primary
122 mrs x0, mpidr_el1
123 mov_imm x1, MPIDR_AFFINITY_MASK
124 and x0, x0, x1
125 cmp x0, #FVP_R_PRIMARY_CPU
126 cset w0, eq
127 ret
128endfunc plat_is_my_cpu_primary