Subject: [PATCH] rpi3/4: Add support for offlining CPUs From: Jan Kiszka jan.kiszka@siemens.com
The hooks were populated but the power down left the CPU in limbo-land. What we need to do - until there is a way to actually power off - is to turn off the MMU and enter the spinning loop as if we were cold-booted. This allows the on-call to pick up the CPU again.
Signed-off-by: Jan Kiszka jan.kiszka@siemens.com
plat/rpi/common/rpi3_pm.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/plat/rpi/common/rpi3_pm.c b/plat/rpi/common/rpi3_pm.c index 8c2d070c4..2a6bf076b 100644 --- a/plat/rpi/common/rpi3_pm.c +++ b/plat/rpi/common/rpi3_pm.c @@ -123,6 +123,15 @@ static void rpi3_pwr_domain_off(const psci_power_state_t *target_state) #endif }
+void __dead2 plat_secondary_cold_boot_setup(void);
+static void __dead2 +rpi3_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state) +{
- disable_mmu_el3();
- plat_secondary_cold_boot_setup();
+}
- /*******************************************************************************
- Platform handler called when a power domain is about to be turned on. The
- mpidr determines the CPU to be turned on.
@@ -224,6 +233,7 @@ static void __dead2 rpi3_system_off(void) static const plat_psci_ops_t plat_rpi3_psci_pm_ops = { .cpu_standby = rpi3_cpu_standby, .pwr_domain_off = rpi3_pwr_domain_off,
- .pwr_domain_pwr_down_wfi = rpi3_pwr_domain_pwr_down_wfi, .pwr_domain_on = rpi3_pwr_domain_on, .pwr_domain_on_finish = rpi3_pwr_domain_on_finish, .system_off = rpi3_system_off,
-- 2.16.4
Hi Jan, I have put in a suggestion for the change. Basically, if you are able to do a `reset` before spinning in `plat_secondary_cold_boot_setup()`, that would be ideal. Also, if `plat_secondary_cold_boot_setup()` can trap the primary CPU as well if it were to be offlined, then I think your changes should be good.
Best Regards Soby Mathew
On 18.12.19 15:52, Soby Mathew wrote:
Subject: [PATCH] rpi3/4: Add support for offlining CPUs From: Jan Kiszka jan.kiszka@siemens.com
The hooks were populated but the power down left the CPU in limbo-land. What we need to do - until there is a way to actually power off - is to turn off the MMU and enter the spinning loop as if we were cold-booted. This allows the on-call to pick up the CPU again.
Signed-off-by: Jan Kiszka jan.kiszka@siemens.com
plat/rpi/common/rpi3_pm.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/plat/rpi/common/rpi3_pm.c b/plat/rpi/common/rpi3_pm.c index 8c2d070c4..2a6bf076b 100644 --- a/plat/rpi/common/rpi3_pm.c +++ b/plat/rpi/common/rpi3_pm.c @@ -123,6 +123,15 @@ static void rpi3_pwr_domain_off(const psci_power_state_t *target_state) #endif }
+void __dead2 plat_secondary_cold_boot_setup(void);
+static void __dead2 +rpi3_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state) +{
- disable_mmu_el3();
- plat_secondary_cold_boot_setup();
+}
- /*******************************************************************************
- Platform handler called when a power domain is about to be turned on. The
- mpidr determines the CPU to be turned on.
@@ -224,6 +233,7 @@ static void __dead2 rpi3_system_off(void) static const plat_psci_ops_t plat_rpi3_psci_pm_ops = { .cpu_standby = rpi3_cpu_standby, .pwr_domain_off = rpi3_pwr_domain_off,
- .pwr_domain_pwr_down_wfi = rpi3_pwr_domain_pwr_down_wfi, .pwr_domain_on = rpi3_pwr_domain_on, .pwr_domain_on_finish = rpi3_pwr_domain_on_finish, .system_off = rpi3_system_off,
-- 2.16.4
Hi Jan, I have put in a suggestion for the change. Basically, if you are able to do a `reset` before spinning in `plat_secondary_cold_boot_setup()`, that would be ideal. Also, if `plat_secondary_cold_boot_setup()` can trap the primary CPU as well if it were to be offlined, then I think your changes should be good.
I've seen the comment, but replying was a bit... unhandy.
I'm not yet getting your reset idea. If there was a physical reset, I would need to install a path how to get back into that cold_boot_setup - how?
Regarding primary CPU offlining: The current code supports that already. Granted, without any proper power-off. But that is what would not change with the reset as well, no?
Thanks, Jan
-----Original Message----- From: Jan Kiszka jan.kiszka@web.de Sent: 18 December 2019 16:28 To: Soby Mathew Soby.Mathew@arm.com; Andre Przywara Andre.Przywara@arm.com Cc: nd nd@arm.com; tf-a@lists.trustedfirmware.org Subject: Re: [TF-A] RPi4 and CPU hotplugging
On 18.12.19 15:52, Soby Mathew wrote:
Subject: [PATCH] rpi3/4: Add support for offlining CPUs From: Jan Kiszka jan.kiszka@siemens.com
The hooks were populated but the power down left the CPU in limbo-land. What we need to do - until there is a way to actually power off - is to turn off the MMU and enter the spinning loop as if we were cold-booted. This allows the on-call to pick up the CPU again.
Signed-off-by: Jan Kiszka jan.kiszka@siemens.com
plat/rpi/common/rpi3_pm.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/plat/rpi/common/rpi3_pm.c b/plat/rpi/common/rpi3_pm.c index 8c2d070c4..2a6bf076b 100644 --- a/plat/rpi/common/rpi3_pm.c +++ b/plat/rpi/common/rpi3_pm.c @@ -123,6 +123,15 @@ static void rpi3_pwr_domain_off(const
psci_power_state_t *target_state)
#endif }
+void __dead2 plat_secondary_cold_boot_setup(void);
+static void __dead2 +rpi3_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state) +{
- disable_mmu_el3();
- plat_secondary_cold_boot_setup();
+}
/****************************************************************
* Platform handler called when a power domain is about to be turned on.
The
* mpidr determines the CPU to be turned on.
@@ -224,6 +233,7 @@ static void __dead2 rpi3_system_off(void) static const plat_psci_ops_t plat_rpi3_psci_pm_ops = { .cpu_standby = rpi3_cpu_standby, .pwr_domain_off = rpi3_pwr_domain_off,
- .pwr_domain_pwr_down_wfi = rpi3_pwr_domain_pwr_down_wfi, .pwr_domain_on = rpi3_pwr_domain_on, .pwr_domain_on_finish = rpi3_pwr_domain_on_finish, .system_off = rpi3_system_off,
-- 2.16.4
Hi Jan, I have put in a suggestion for the change. Basically, if you are able to do a `reset` before spinning in `plat_secondary_cold_boot_setup()`, that would be ideal. Also, if `plat_secondary_cold_boot_setup()` can trap the primary CPU as well if it were to be offlined, then I think your changes should be good.
I've seen the comment, but replying was a bit... unhandy.
I'm not yet getting your reset idea. If there was a physical reset, I would need to install a path how to get back into that cold_boot_setup - how?
Hi Jan, Hmm, I see your point. I didn't fully think through my suggestion for RPi4. My thought was, when the CPU is reset, it hits the reset vector (address in RVBAR), which has some trampoline code to jump to bl31_entrypoint() [cold boot setup] and the CPU can be held in a pen there. This ensures that the architectural state of the CPU is reset properly and doesn't have left over state from the previous run. For RPi4, this might be difficult to pull off depending on the reset flow.
Regarding primary CPU offlining: The current code supports that already. Granted, without any proper power-off. But that is what would not change with the reset as well, no?
Okay, I wanted to confirm that primary CPU is also handled within the plat_secondary_cold_boot_setup(). So that should be fine.
BRs Soby Mathew
Thanks, Jan
tf-a@lists.trustedfirmware.org