diff --git a/Makefile b/Makefile index 80e05fa63..0c3303f86 100644 --- a/Makefile +++ b/Makefile @@ -89,6 +89,9 @@ TRUSTED_BOARD_BOOT := 0 PROGRAMMABLE_RESET_ADDRESS := 0 # Build flag to treat usage of deprecated platform and framework APIs as error. ERROR_DEPRECATED := 0 +# By default, consider that the platform may release several CPUs out of reset. +# The platform Makefile is free to override this value. +COLD_BOOT_SINGLE_CPU := 0 # Flag to introduce an infinite loop in BL1 just before it exits into the next # image. This is meant to help debugging the post-BL2 phase. SPIN_ON_BL1_EXIT := 0 @@ -357,6 +360,7 @@ $(eval $(call assert_boolean,CREATE_KEYS)) $(eval $(call assert_boolean,SAVE_KEYS)) $(eval $(call assert_boolean,TRUSTED_BOARD_BOOT)) $(eval $(call assert_boolean,PROGRAMMABLE_RESET_ADDRESS)) +$(eval $(call assert_boolean,COLD_BOOT_SINGLE_CPU)) $(eval $(call assert_boolean,PSCI_EXTENDED_STATE_ID)) $(eval $(call assert_boolean,ERROR_DEPRECATED)) $(eval $(call assert_boolean,ENABLE_PLAT_COMPAT)) @@ -380,6 +384,7 @@ $(eval $(call add_define,LOG_LEVEL)) $(eval $(call add_define,USE_COHERENT_MEM)) $(eval $(call add_define,TRUSTED_BOARD_BOOT)) $(eval $(call add_define,PROGRAMMABLE_RESET_ADDRESS)) +$(eval $(call add_define,COLD_BOOT_SINGLE_CPU)) $(eval $(call add_define,PSCI_EXTENDED_STATE_ID)) $(eval $(call add_define,ERROR_DEPRECATED)) $(eval $(call add_define,ENABLE_PLAT_COMPAT)) diff --git a/bl1/aarch64/bl1_entrypoint.S b/bl1/aarch64/bl1_entrypoint.S index 4fc52918a..83594f218 100644 --- a/bl1/aarch64/bl1_entrypoint.S +++ b/bl1/aarch64/bl1_entrypoint.S @@ -51,7 +51,7 @@ func bl1_entrypoint el3_entrypoint_common \ _set_endian=1 \ _warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS \ - _secondary_cold_boot=1 \ + _secondary_cold_boot=!COLD_BOOT_SINGLE_CPU \ _init_memory=1 \ _init_c_runtime=1 \ _exception_vectors=bl1_exceptions diff --git a/bl31/aarch64/bl31_entrypoint.S b/bl31/aarch64/bl31_entrypoint.S index 636b1d287..45aa85dc4 100644 --- a/bl31/aarch64/bl31_entrypoint.S +++ b/bl31/aarch64/bl31_entrypoint.S @@ -85,7 +85,7 @@ func bl31_entrypoint el3_entrypoint_common \ _set_endian=1 \ _warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS \ - _secondary_cold_boot=1 \ + _secondary_cold_boot=!COLD_BOOT_SINGLE_CPU \ _init_memory=1 \ _init_c_runtime=1 \ _exception_vectors=runtime_exceptions diff --git a/docs/porting-guide.md b/docs/porting-guide.md index 82bed6b04..6c6122adf 100644 --- a/docs/porting-guide.md +++ b/docs/porting-guide.md @@ -459,7 +459,7 @@ type of reset nor to query the warm reset entrypoint. Therefore, implementing this function is not required on such platforms. -### Function : plat_secondary_cold_boot_setup() [mandatory] +### Function : plat_secondary_cold_boot_setup() [mandatory when COLD_BOOT_SINGLE_CPU == 0] Argument : void @@ -476,8 +476,12 @@ populated. This function fulfills requirement 2 above. +Note that for platforms that can't release secondary CPUs out of reset, only the +primary CPU will execute the cold boot code. Therefore, implementing this +function is not required on such platforms. -### Function : plat_is_my_cpu_primary() [mandatory] + +### Function : plat_is_my_cpu_primary() [mandatory when COLD_BOOT_SINGLE_CPU == 0] Argument : void Return : unsigned int @@ -487,6 +491,11 @@ secondary CPU. A return value of zero indicates that the CPU is not the primary CPU, while a non-zero return value indicates that the CPU is the primary CPU. +Note that for platforms that can't release secondary CPUs out of reset, only the +primary CPU will execute the cold boot code. Therefore, there is no need to +distinguish between primary and secondary CPUs and implementing this function is +not required. + ### Function : platform_mem_init() [mandatory] diff --git a/docs/user-guide.md b/docs/user-guide.md index 53745f0eb..f7e4f4c79 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -359,6 +359,15 @@ performed. implication for `plat_get_my_entrypoint()` platform porting interface. (see the [Porting Guide] for details) +* `COLD_BOOT_SINGLE_CPU`: This option indicates whether the platform may + release several CPUs out of reset. It can take either 0 (several CPUs may be + brought up) or 1 (only one CPU will ever be brought up during cold reset). + Default is 0. If the platform always brings up a single CPU, there is no + need to distinguish between primary and secondary CPUs and the boot path can + be optimised. The `plat_is_my_cpu_primary()` and + `plat_secondary_cold_boot_setup()` platform porting interfaces do not need + to be implemented in this case. + * `PSCI_EXTENDED_STATE_ID`: As per PSCI1.0 Specification, there are 2 formats possible for the PSCI power-state parameter viz original and extended State-ID formats. This flag if set to 1, configures the generic PSCI layer