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 func plat_get_my_entrypoint
ldr x0, msm8916_entry_point ldr x0, msm8916_entry_point
cbz x0, 1f
ret ret
endfunc plat_get_my_entrypoint 1:
/*
/* ------------------------------------------------- * Cold boot: Disable TCM redirect to L2 cache as early as
* void plat_reset_handler(void) * possible to avoid crashes when making use of the cache.
* Perform additional initialization after reset.
* Clobber list : x0 - x18, x30
* -------------------------------------------------
*/ */
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. * After reset the CPU always starts executing at the fixed reset
* During cold boot the CPU enters here at the wrong address * address (0x0), which does not match the link address of BL31.
* using the "boot remapper". (It remaps the BL31_BASE to * The "boot remapper" redirects all memory accesses to the real
* the CPU reset address 0x0). * 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 adr x1, bl31_entrypoint
cmp x0, x1 cbnz x1, 2f
b.ne _remapped_cold_boot
/* Already running at correct address, just return directly */
ret
_remapped_cold_boot:
/* /*
* The previous boot stage seems to use the L2 cache as TCM. * Add the real BL31_BASE offset to the return address in the link
* Disable the TCM redirect before enabling caches to avoid * register so the CPU will continue at the real address after return.
* strange crashes.
*/ */
mov x2, #APCS_CFG mov_imm x1, BL31_BASE
ldr w3, [x2, #APCS_TCM_START_ADDR] add lr, lr, x1
and w3, w3, #~APCS_TCM_REDIRECT_EN_0 2:
str w3, [x2, #APCS_TCM_START_ADDR] ret
endfunc plat_get_my_entrypoint
/* Enter BL31 again at the real address */
br x0
endfunc plat_reset_handler
/* ------------------------------------------------- /* -------------------------------------------------
* void platform_mem_init(void) * void platform_mem_init(void)

Loading…
Cancel
Save