summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2018-08-28 16:00:05 +0530
committerArd Biesheuvel <ard.biesheuvel@linaro.org>2019-02-12 11:42:37 +0100
commitef8c83974378c2ba1c76de92a4b84641bf5103ce (patch)
tree9ff7e79c168c5c8f775698d149972e9d899b0959
parent434454a2710eea3f49ebfca951019d7b6c783fb5 (diff)
downloadarm-trusted-firmware-ef8c83974378c2ba1c76de92a4b84641bf5103ce.tar.gz
synquacer: add stage2 override for PCIe config and MMIO regions
If dip switch DSW3-2 is set, install the static stage2 translation tables that are located in the NOR flash and drop to EL1 when entering the non-secure world. This works around SynQuacer SoC errata related to PCIe. Change-Id: Id148e767a13348af489a9cc9a3f40a3f22d352e8 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
-rw-r--r--bl31/bl31_main.c5
-rw-r--r--lib/psci/psci_on.c5
-rw-r--r--plat/socionext/synquacer/sq_bl31_setup.c5
-rw-r--r--plat/socionext/synquacer/sq_helpers.S36
4 files changed, 51 insertions, 0 deletions
diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c
index 927cda2f..eeddc021 100644
--- a/bl31/bl31_main.c
+++ b/bl31/bl31_main.c
@@ -152,6 +152,8 @@ uint32_t bl31_get_next_image_type(void)
******************************************************************************/
void __init bl31_prepare_next_image_entry(void)
{
+ extern void bl31_setup_s2_translation(void);
+
entry_point_info_t *next_image_info;
uint32_t image_type;
@@ -180,6 +182,9 @@ void __init bl31_prepare_next_image_entry(void)
print_entry_point_info(next_image_info);
cm_init_my_context(next_image_info);
cm_prepare_el3_exit(image_type);
+
+ if (image_type != SECURE)
+ bl31_setup_s2_translation();
}
/*******************************************************************************
diff --git a/lib/psci/psci_on.c b/lib/psci/psci_on.c
index aa6b324e..5af14841 100644
--- a/lib/psci/psci_on.c
+++ b/lib/psci/psci_on.c
@@ -166,6 +166,8 @@ exit:
******************************************************************************/
void psci_cpu_on_finish(int cpu_idx, const psci_power_state_t *state_info)
{
+ extern void bl31_setup_s2_translation(void);
+
/*
* Plat. management: Perform the platform specific actions
* for this cpu e.g. enabling the gic or zeroing the mailbox
@@ -220,4 +222,7 @@ void psci_cpu_on_finish(int cpu_idx, const psci_power_state_t *state_info)
* call to set this cpu on its way.
*/
cm_prepare_el3_exit(NON_SECURE);
+
+ bl31_setup_s2_translation();
+
}
diff --git a/plat/socionext/synquacer/sq_bl31_setup.c b/plat/socionext/synquacer/sq_bl31_setup.c
index 2fac80ff..5134c15a 100644
--- a/plat/socionext/synquacer/sq_bl31_setup.c
+++ b/plat/socionext/synquacer/sq_bl31_setup.c
@@ -48,6 +48,7 @@ uint32_t sq_get_spsr_for_bl32_entry(void)
******************************************************************************/
uint32_t sq_get_spsr_for_bl33_entry(void)
{
+ uint32_t *gpio = (uint32_t *)PLAT_SQ_GPIO_BASE;
unsigned long el_status;
unsigned int mode;
uint32_t spsr;
@@ -58,6 +59,10 @@ uint32_t sq_get_spsr_for_bl33_entry(void)
mode = (el_status) ? MODE_EL2 : MODE_EL1;
+ /* enable the stage 2 override page tables if PD[1] is set */
+ if (gpio[0] & 0x2)
+ mode = MODE_EL1;
+
spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
return spsr;
}
diff --git a/plat/socionext/synquacer/sq_helpers.S b/plat/socionext/synquacer/sq_helpers.S
index 558aa15f..c2059241 100644
--- a/plat/socionext/synquacer/sq_helpers.S
+++ b/plat/socionext/synquacer/sq_helpers.S
@@ -108,3 +108,39 @@ func plat_crash_console_flush
mov_imm x0, PLAT_SQ_BOOT_UART_BASE
b console_pl011_core_flush
endfunc plat_crash_console_flush
+
+ /* -------------------------------------------------------------
+ * On the Socionext SynQuacer platform, we need to prevent the
+ * OS from using write combine mappings on PCIe MMIO regions.
+ * Let's do so by setting a stage 2 override for those regions,
+ * and run the OS in EL1 with stage 2 translations enabled.
+ * While we're at it, remap the config space of bus #0 on both
+ * RCs so we can use a generic ECAM driver.
+ * -------------------------------------------------------------
+ */
+
+#define VTCR_T0SZ (64 - 40)
+#define VTCR_SL0 (1 << 6) /* start at level 1 */
+#define VTCR_IRGN0 (3 << 8) /* inner wbwa */
+#define VTCR_ORGN0 (3 << 10) /* outer wbwa */
+#define VTCR_SH0 (0 << 12) /* non shareable */
+#define VTCR_TG0 (0 << 14) /* 4 KB granule */
+#define VTCR_PS (2 << 16) /* 40 bit PAs */
+#define VTCR_RES1 (1 << 31) /* RES1 */
+
+ .globl bl31_setup_s2_translation
+func bl31_setup_s2_translation
+ mov_imm x0, (PRELOADED_BL33_BASE - 0x8000)
+ msr vttbr_el2, x0
+ mov_imm x0, VTCR_T0SZ | VTCR_SL0 | VTCR_IRGN0 | \
+ VTCR_ORGN0 | VTCR_SH0 | VTCR_TG0 | \
+ VTCR_PS | VTCR_RES1
+ msr vtcr_el2, x0
+ isb
+
+ mrs x0, hcr_el2
+ orr x0, x0, #1
+ msr hcr_el2, x0
+ isb
+ ret
+endfunc bl31_setup_s2_translation