Commit 3fb340a2 authored by davidcunado-arm's avatar davidcunado-arm Committed by GitHub
Browse files

Merge pull request #912 from vwadekar/tegra-smmu-ctx-save-robust

Tegra: smmu: make the context save sequence robust
parents 484acce3 63ac1a2a
...@@ -87,7 +87,7 @@ static void tegra_smmu_write_32(uint32_t smmu_id, ...@@ -87,7 +87,7 @@ static void tegra_smmu_write_32(uint32_t smmu_id,
*/ */
void tegra_smmu_save_context(uint64_t smmu_ctx_addr) void tegra_smmu_save_context(uint64_t smmu_ctx_addr)
{ {
uint32_t i; uint32_t i, num_entries = 0;
smmu_regs_t *smmu_ctx_regs; smmu_regs_t *smmu_ctx_regs;
#if DEBUG #if DEBUG
plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
...@@ -110,13 +110,29 @@ void tegra_smmu_save_context(uint64_t smmu_ctx_addr) ...@@ -110,13 +110,29 @@ void tegra_smmu_save_context(uint64_t smmu_ctx_addr)
smmu_ctx_regs = plat_get_smmu_ctx(); smmu_ctx_regs = plat_get_smmu_ctx();
assert(smmu_ctx_regs); assert(smmu_ctx_regs);
/*
* smmu_ctx_regs[0].val contains the size of the context table minus
* the last entry. Sanity check the table size before we start with
* the context save operation.
*/
while (smmu_ctx_regs[num_entries].val != 0xFFFFFFFFU) {
num_entries++;
}
/* panic if the sizes do not match */
if (num_entries != smmu_ctx_regs[0].val)
panic();
/* save SMMU register values */ /* save SMMU register values */
for (i = 1; i < smmu_ctx_regs[0].val; i++) for (i = 1; i < num_entries; i++)
smmu_ctx_regs[i].val = mmio_read_32(smmu_ctx_regs[i].reg); smmu_ctx_regs[i].val = mmio_read_32(smmu_ctx_regs[i].reg);
/* increment by 1 to take care of the last entry */
num_entries++;
/* Save SMMU config settings */ /* Save SMMU config settings */
memcpy16((void *)(uintptr_t)smmu_ctx_addr, (void *)smmu_ctx_regs, memcpy16((void *)(uintptr_t)smmu_ctx_addr, (void *)smmu_ctx_regs,
sizeof(smmu_regs_t)); (sizeof(smmu_regs_t) * num_entries));
/* save the SMMU table address */ /* save the SMMU table address */
mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV11_LO, mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV11_LO,
......
...@@ -46,11 +46,8 @@ ...@@ -46,11 +46,8 @@
extern void prepare_cpu_pwr_dwn(void); extern void prepare_cpu_pwr_dwn(void);
extern void tegra186_cpu_reset_handler(void); extern void tegra186_cpu_reset_handler(void);
extern uint32_t __tegra186_cpu_reset_handler_data, extern uint32_t __tegra186_cpu_reset_handler_end,
__tegra186_cpu_reset_handler_end; __tegra186_smmu_context;
/* TZDRAM offset for saving SMMU context */
#define TEGRA186_SMMU_CTX_OFFSET 16
/* state id mask */ /* state id mask */
#define TEGRA186_STATE_ID_MASK 0xF #define TEGRA186_STATE_ID_MASK 0xF
...@@ -151,9 +148,8 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) ...@@ -151,9 +148,8 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
/* save SMMU context to TZDRAM */ /* save SMMU context to TZDRAM */
smmu_ctx_base = params_from_bl2->tzdram_base + smmu_ctx_base = params_from_bl2->tzdram_base +
((uintptr_t)&__tegra186_cpu_reset_handler_data - ((uintptr_t)&__tegra186_smmu_context -
(uintptr_t)tegra186_cpu_reset_handler) + (uintptr_t)tegra186_cpu_reset_handler);
TEGRA186_SMMU_CTX_OFFSET;
tegra_smmu_save_context((uintptr_t)smmu_ctx_base); tegra_smmu_save_context((uintptr_t)smmu_ctx_base);
/* Prepare for system suspend */ /* Prepare for system suspend */
......
...@@ -94,6 +94,8 @@ endfunc tegra186_cpu_reset_handler ...@@ -94,6 +94,8 @@ endfunc tegra186_cpu_reset_handler
__tegra186_cpu_reset_handler_data: __tegra186_cpu_reset_handler_data:
.quad tegra_secure_entrypoint .quad tegra_secure_entrypoint
.quad __BL31_END__ - BL31_BASE .quad __BL31_END__ - BL31_BASE
.globl __tegra186_smmu_context
__tegra186_smmu_context:
.rept TEGRA186_SMMU_CTX_SIZE .rept TEGRA186_SMMU_CTX_SIZE
.quad 0 .quad 0
.endr .endr
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment