Hi Sumit,
On 08/05/2026 09:28, Sumit Garg wrote:
> From: Sumit Garg <[email protected]>
>
> On Qcom platforms, cmd-db region is required to be mapped as uncached
> region especially when executing at EL2. Otherwise an xPU violation
> can be triggered due to cache operations as descibed by a similar fix
> for the kernel here:
Nice, I've run into this one before and it was pretty annoying.
It feels less than ideal to have more bool properties here, maybe we
could get something like pgprot_set_attrs()? actually is there a reason
that function wouldn't work in this case?
Kind regards,
>
> Commit f9bb896eab22 ("soc: qcom: cmd-db: Map shared memory as WC, not WB")
>
> So, let's map CMD-DB region as uncached to avoid any issues while
> booting U-Boot in EL2 mode.
>
> Fixes: a9cbf76e4dd3 ("soc: qcom: cmd-db: map cmd-db region")
> Signed-off-by: Sumit Garg <[email protected]>
> ---
> arch/arm/cpu/armv8/cache_v8.c | 11 ++++++++---
> arch/arm/include/asm/system.h | 3 ++-
> drivers/soc/qcom/cmd-db.c | 2 +-
> 3 files changed, 11 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
> index 39479df7b21..05e90e1eb32 100644
> --- a/arch/arm/cpu/armv8/cache_v8.c
> +++ b/arch/arm/cpu/armv8/cache_v8.c
> @@ -388,13 +388,18 @@ static void map_range(u64 virt, u64 phys, u64 size, int
> level,
> }
> }
>
> -void mmu_map_region(phys_addr_t addr, u64 size, bool emergency)
> +void mmu_map_region(phys_addr_t addr, u64 size, bool cached, bool emergency)
> {
> u64 va_bits;
> int level = 0;
> - u64 attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE;
> + u64 attrs;
>
> - attrs |= PTE_TYPE_BLOCK | PTE_BLOCK_AF;
> + if (cached)
> + attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL);
> + else
> + attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC);
> +
> + attrs |= PTE_BLOCK_INNER_SHARE | PTE_TYPE_BLOCK | PTE_BLOCK_AF;
>
> get_tcr(NULL, &va_bits);
> if (va_bits < 39)
> diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
> index 5ed6833c155..52ab86112fb 100644
> --- a/arch/arm/include/asm/system.h
> +++ b/arch/arm/include/asm/system.h
> @@ -306,9 +306,10 @@ void flush_l3_cache(void);
> *
> * @start: Start address of the region
> * @size: Size of the region
> + * @cached: Map memory as cacheable or not
> * @emerg: Also map the region in the emergency table
> */
> -void mmu_map_region(phys_addr_t start, u64 size, bool emerg);
> +void mmu_map_region(phys_addr_t start, u64 size, bool cached, bool emerg);
>
> /**
> * mmu_change_region_attr() - change a mapped region attributes
> diff --git a/drivers/soc/qcom/cmd-db.c b/drivers/soc/qcom/cmd-db.c
> index d0a6047b8a6..61e15783123 100644
> --- a/drivers/soc/qcom/cmd-db.c
> +++ b/drivers/soc/qcom/cmd-db.c
> @@ -248,7 +248,7 @@ static int cmd_db_bind(struct udevice *dev)
> }
>
> /* On SM8550/SM8650 and newer SoCs cmd-db might not be mapped */
> - mmu_map_region((phys_addr_t)base, (phys_size_t)size, false);
> + mmu_map_region((phys_addr_t)base, (phys_size_t)size, false, false);
>
> cmd_db_header = base;
> if (!cmd_db_magic_matches(cmd_db_header)) {
--
// Casey (she/her)