blob: 8efc2386cfd943bc19add56b90d2fd5972e04256 [file] [log] [blame]
Achin Gupta4f6ad662013-10-25 09:08:21 +01001/*
John Tsichritzis19b384b2019-06-03 16:20:46 +01002 * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
Achin Gupta4f6ad662013-10-25 09:08:21 +01003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Achin Gupta4f6ad662013-10-25 09:08:21 +01005 */
6
7#include <arch.h>
Andrew Thoelke38bde412014-03-18 13:46:55 +00008#include <asm_macros.S>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00009#include <drivers/arm/gicv2.h>
10#include <drivers/arm/gicv3.h>
Antonio Nino Diazf13d09a2019-01-23 21:50:09 +000011#include <drivers/arm/fvp/fvp_pwrc.h>
Dan Handley4fd2f5c2014-08-04 11:41:20 +010012#include <platform_def.h>
Antonio Nino Diaza320ecd2019-01-15 14:19:50 +000013
Vikram Kanigiri96377452014-04-24 11:02:16 +010014 .globl plat_secondary_cold_boot_setup
Soby Mathewfec4eb72015-07-01 16:16:20 +010015 .globl plat_get_my_entrypoint
Soby Mathewfec4eb72015-07-01 16:16:20 +010016 .globl plat_is_my_cpu_primary
Jeenu Viswambharan528d21b2016-11-15 13:53:57 +000017 .globl plat_arm_calc_core_pos
Achin Gupta4f6ad662013-10-25 09:08:21 +010018
Vikram Kanigiri96377452014-04-24 11:02:16 +010019 /* -----------------------------------------------------
20 * void plat_secondary_cold_boot_setup (void);
21 *
22 * This function performs any platform specific actions
23 * needed for a secondary cpu after a cold reset e.g
24 * mark the cpu's presence, mechanism to place it in a
25 * holding pen etc.
26 * TODO: Should we read the PSYS register to make sure
27 * that the request has gone through.
28 * -----------------------------------------------------
29 */
30func plat_secondary_cold_boot_setup
Sandrine Bailleuxd47c9a52015-10-02 14:35:25 +010031#ifndef EL3_PAYLOAD_BASE
Vikram Kanigiri96377452014-04-24 11:02:16 +010032 /* ---------------------------------------------
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
Soby Mathewef81bc52018-10-12 17:08:28 +010041 mov_imm x1, PWRC_BASE
Vikram Kanigiri96377452014-04-24 11:02:16 +010042 str w0, [x1, #PPOFFR_OFF]
43
Vikram Kanigiri96377452014-04-24 11:02:16 +010044 /* ---------------------------------------------
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
Jeenu Viswambharan68aef102016-11-30 15:21:11 +000052 no_ret plat_panic_handler
Sandrine Bailleuxd47c9a52015-10-02 14:35:25 +010053#else
54 mov_imm x0, PLAT_ARM_TRUSTED_MAILBOX_BASE
55
56 /* Wait until the entrypoint gets populated */
57poll_mailbox:
58 ldr x1, [x0]
59 cbz x1, 1f
60 br x1
611:
62 wfe
63 b poll_mailbox
64#endif /* EL3_PAYLOAD_BASE */
Kévin Petita877c252015-03-24 14:03:57 +000065endfunc plat_secondary_cold_boot_setup
Vikram Kanigiri96377452014-04-24 11:02:16 +010066
Sandrine Bailleuxdaf9a9d2015-07-10 16:49:31 +010067 /* ---------------------------------------------------------------------
Soby Mathewa0fedc42016-06-16 14:52:04 +010068 * uintptr_t plat_get_my_entrypoint (void);
Vikram Kanigiri96377452014-04-24 11:02:16 +010069 *
Sandrine Bailleuxdaf9a9d2015-07-10 16:49:31 +010070 * Main job of this routine is to distinguish between a cold and warm
71 * boot. On FVP, this information can be queried from the power
72 * controller. The Power Control SYS Status Register (PSYSR) indicates
73 * the wake-up reason for the CPU.
74 *
75 * For a cold boot, return 0.
76 * For a warm boot, read the mailbox and return the address it contains.
Vikram Kanigiri96377452014-04-24 11:02:16 +010077 *
Vikram Kanigiri96377452014-04-24 11:02:16 +010078 * TODO: PSYSR is a common register and should be
Sandrine Bailleuxf4119ec2015-12-17 13:58:58 +000079 * accessed using locks. Since it is not possible
Vikram Kanigiri96377452014-04-24 11:02:16 +010080 * to use locks immediately after a cold reset
81 * we are relying on the fact that after a cold
82 * reset all cpus will read the same WK field
Sandrine Bailleuxdaf9a9d2015-07-10 16:49:31 +010083 * ---------------------------------------------------------------------
Vikram Kanigiri96377452014-04-24 11:02:16 +010084 */
Soby Mathewfec4eb72015-07-01 16:16:20 +010085func plat_get_my_entrypoint
Sandrine Bailleuxdaf9a9d2015-07-10 16:49:31 +010086 /* ---------------------------------------------------------------------
87 * When bit PSYSR.WK indicates either "Wake by PPONR" or "Wake by GIC
88 * WakeRequest signal" then it is a warm boot.
89 * ---------------------------------------------------------------------
90 */
Soby Mathewfec4eb72015-07-01 16:16:20 +010091 mrs x2, mpidr_el1
Soby Mathewef81bc52018-10-12 17:08:28 +010092 mov_imm x1, PWRC_BASE
Vikram Kanigiri96377452014-04-24 11:02:16 +010093 str w2, [x1, #PSYSR_OFF]
94 ldr w2, [x1, #PSYSR_OFF]
Soby Mathew2ae23192015-04-30 12:27:41 +010095 ubfx w2, w2, #PSYSR_WK_SHIFT, #PSYSR_WK_WIDTH
Juan Castillo9a5b56e2014-07-11 10:23:18 +010096 cmp w2, #WKUP_PPONR
97 beq warm_reset
98 cmp w2, #WKUP_GICREQ
99 beq warm_reset
Sandrine Bailleuxdaf9a9d2015-07-10 16:49:31 +0100100
101 /* Cold reset */
Juan Castillo9a5b56e2014-07-11 10:23:18 +0100102 mov x0, #0
Sandrine Bailleuxdaf9a9d2015-07-10 16:49:31 +0100103 ret
104
Vikram Kanigiri96377452014-04-24 11:02:16 +0100105warm_reset:
Sandrine Bailleuxdaf9a9d2015-07-10 16:49:31 +0100106 /* ---------------------------------------------------------------------
107 * A mailbox is maintained in the trusted SRAM. It is flushed out of the
108 * caches after every update using normal memory so it is safe to read
109 * it here with SO attributes.
110 * ---------------------------------------------------------------------
Vikram Kanigiri96377452014-04-24 11:02:16 +0100111 */
Soby Mathewfeac8fc2015-09-29 15:47:16 +0100112 mov_imm x0, PLAT_ARM_TRUSTED_MAILBOX_BASE
Sandrine Bailleuxdaf9a9d2015-07-10 16:49:31 +0100113 ldr x0, [x0]
Antonio Nino Diaz1f21bcf2016-02-01 13:57:25 +0000114 cbz x0, _panic_handler
Sandrine Bailleuxdaf9a9d2015-07-10 16:49:31 +0100115 ret
116
117 /* ---------------------------------------------------------------------
118 * The power controller indicates this is a warm reset but the mailbox
119 * is empty. This should never happen!
120 * ---------------------------------------------------------------------
121 */
Antonio Nino Diaz1f21bcf2016-02-01 13:57:25 +0000122_panic_handler:
Jeenu Viswambharan68aef102016-11-30 15:21:11 +0000123 no_ret plat_panic_handler
Soby Mathewfec4eb72015-07-01 16:16:20 +0100124endfunc plat_get_my_entrypoint
Vikram Kanigiri96377452014-04-24 11:02:16 +0100125
Soby Matheweb3bbf12015-06-08 12:32:50 +0100126 /* -----------------------------------------------------
127 * unsigned int plat_is_my_cpu_primary (void);
128 *
129 * Find out whether the current cpu is the primary
130 * cpu.
131 * -----------------------------------------------------
132 */
Soby Mathewfec4eb72015-07-01 16:16:20 +0100133func plat_is_my_cpu_primary
134 mrs x0, mpidr_el1
Soby Mathewef81bc52018-10-12 17:08:28 +0100135 mov_imm x1, MPIDR_AFFINITY_MASK
Jeenu Viswambharan528d21b2016-11-15 13:53:57 +0000136 and x0, x0, x1
Juan Castillob3dbeb02014-07-16 15:53:43 +0100137 cmp x0, #FVP_PRIMARY_CPU
Soby Matheweb3bbf12015-06-08 12:32:50 +0100138 cset w0, eq
Juan Castillob3dbeb02014-07-16 15:53:43 +0100139 ret
Soby Mathewfec4eb72015-07-01 16:16:20 +0100140endfunc plat_is_my_cpu_primary
Jeenu Viswambharan528d21b2016-11-15 13:53:57 +0000141
Wang Feng8d22ec32018-03-15 15:32:41 +0800142 /* ---------------------------------------------------------------------
Jeenu Viswambharan528d21b2016-11-15 13:53:57 +0000143 * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
144 *
145 * Function to calculate the core position on FVP.
146 *
Wang Feng8d22ec32018-03-15 15:32:41 +0800147 * (ClusterId * FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU) +
Jeenu Viswambharan528d21b2016-11-15 13:53:57 +0000148 * (CPUId * FVP_MAX_PE_PER_CPU) +
149 * ThreadId
Wang Feng8d22ec32018-03-15 15:32:41 +0800150 *
151 * which can be simplified as:
152 *
153 * ((ClusterId * FVP_MAX_CPUS_PER_CLUSTER + CPUId) * FVP_MAX_PE_PER_CPU)
154 * + ThreadId
155 * ---------------------------------------------------------------------
Jeenu Viswambharan528d21b2016-11-15 13:53:57 +0000156 */
157func plat_arm_calc_core_pos
Jeenu Viswambharan528d21b2016-11-15 13:53:57 +0000158 /*
159 * Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it
160 * look as if in a multi-threaded implementation.
161 */
162 tst x0, #MPIDR_MT_MASK
163 lsl x3, x0, #MPIDR_AFFINITY_BITS
164 csel x3, x3, x0, eq
165
166 /* Extract individual affinity fields from MPIDR */
167 ubfx x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
168 ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
169 ubfx x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
170
171 /* Compute linear position */
Wang Feng8d22ec32018-03-15 15:32:41 +0800172 mov x4, #FVP_MAX_CPUS_PER_CLUSTER
173 madd x1, x2, x4, x1
174 mov x5, #FVP_MAX_PE_PER_CPU
175 madd x0, x1, x5, x0
Jeenu Viswambharan528d21b2016-11-15 13:53:57 +0000176 ret
177endfunc plat_arm_calc_core_pos