Browse Source

refactor(msm8916): detect cold boot in plat_get_my_entrypoint

The msm8916 platform port needs to disable the TCM redirect to the L2
cache as early as possible during cold boot to avoid crashes. Right now
this is done in plat_reset_handler by checking if BL31 was started
through the "boot remapper", which redirects memory accesses around the
fixed CPU reset address (0x0) to the actual link address of BL31. On
AArch64 this is always the case during cold boot, since a CPU reset was
necessary to switch from AArch32 in the initial bootloader to AArch64.

On AArch32, SP_MIN starts running at the real link address immediately,
so the initial cold boot must be detected with a different approach.

To keep the AArch32 and AArch64 implementation of this functionality
consistent, move this functionality to plat_get_my_entrypoint, by
checking if the msm8916_entry_point is still zero or was already
updated for later warm boots by the PSCI code.

Also, avoid entering BL31 twice and instead add the BL31_BASE offset
to the return address in the link register. This allows preserving the
bootloader arguments in x0-x3 because they otherwise get lost.

Change-Id: I90286c6cacf23f44ed7930a3e7e33804ca63c391
Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
pull/1999/head
Stephan Gerhold 2 years ago
committed by Manish Pandey
parent
commit
25132f7820
  1. 57
      plat/qti/msm8916/aarch64/msm8916_helpers.S

57
plat/qti/msm8916/aarch64/msm8916_helpers.S

@ -93,43 +93,42 @@ endfunc plat_my_core_pos
*/
func plat_get_my_entrypoint
ldr x0, msm8916_entry_point
cbz x0, 1f
ret
endfunc plat_get_my_entrypoint
/* -------------------------------------------------
* void plat_reset_handler(void)
* Perform additional initialization after reset.
* Clobber list : x0 - x18, x30
* -------------------------------------------------
1:
/*
* Cold boot: Disable TCM redirect to L2 cache as early as
* possible to avoid crashes when making use of the cache.
*/
func plat_reset_handler
mov_imm x1, APCS_CFG
ldr w2, [x1, #APCS_TCM_START_ADDR]
and w2, w2, #~APCS_TCM_REDIRECT_EN_0
str w2, [x1, #APCS_TCM_START_ADDR]
/*
* Check if the CPU is running at the correct address.
* During cold boot the CPU enters here at the wrong address
* using the "boot remapper". (It remaps the BL31_BASE to
* the CPU reset address 0x0).
* After reset the CPU always starts executing at the fixed reset
* address (0x0), which does not match the link address of BL31.
* The "boot remapper" redirects all memory accesses to the real
* physical address in DRAM.
*
* For warm boots, this is already handled by loading the real
* entry point address above.
*
* For cold boots, check if the CPU is using the boot remapper,
* i.e. if bl31_entrypoint appears to be at the reset address (0x0).
*/
mov x0, #BL31_BASE
adr x1, bl31_entrypoint
cmp x0, x1
b.ne _remapped_cold_boot
/* Already running at correct address, just return directly */
ret
cbnz x1, 2f
_remapped_cold_boot:
/*
* The previous boot stage seems to use the L2 cache as TCM.
* Disable the TCM redirect before enabling caches to avoid
* strange crashes.
* Add the real BL31_BASE offset to the return address in the link
* register so the CPU will continue at the real address after return.
*/
mov x2, #APCS_CFG
ldr w3, [x2, #APCS_TCM_START_ADDR]
and w3, w3, #~APCS_TCM_REDIRECT_EN_0
str w3, [x2, #APCS_TCM_START_ADDR]
/* Enter BL31 again at the real address */
br x0
endfunc plat_reset_handler
mov_imm x1, BL31_BASE
add lr, lr, x1
2:
ret
endfunc plat_get_my_entrypoint
/* -------------------------------------------------
* void platform_mem_init(void)

Loading…
Cancel
Save