From 23d39dbc7e3a74dad630e2dea977f89242e0bdae Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Wed, 18 Nov 2015 11:10:30 +0000 Subject: [PATCH 1/2] Juno: Rework platform reset handler This patch splits the Juno reset handler in 4 distinct pieces: - Detection of the board revision; - Juno R0 specific handler; - Juno R1 specific handler; - Juno R2 specific handler. Depending on the board revision, the appropriate handler is called. This makes the code easier to understand and maintain. This patch is mainly cosmetic. The only functional change introduced is that the Juno platform reset handler will now spin infinitely if the board revision is not recognised. Previously, it would have assumed that it was running on Juno R1 in this case. Change-Id: I54ed77c4665085ead9d1573316c9c884d7d3ffa0 --- plat/arm/board/juno/aarch64/juno_helpers.S | 168 ++++++++++++++------- plat/arm/board/juno/juno_def.h | 1 + 2 files changed, 118 insertions(+), 51 deletions(-) diff --git a/plat/arm/board/juno/aarch64/juno_helpers.S b/plat/arm/board/juno/aarch64/juno_helpers.S index 263a98056..ab06da204 100644 --- a/plat/arm/board/juno/aarch64/juno_helpers.S +++ b/plat/arm/board/juno/aarch64/juno_helpers.S @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include "../juno_def.h" @@ -39,52 +40,99 @@ .globl plat_reset_handler .globl plat_arm_calc_core_pos +#define JUNO_REVISION(rev) REV_JUNO_R##rev +#define JUNO_HANDLER(rev) plat_reset_handler_juno_r##rev +#define JUMP_TO_HANDLER_IF_JUNO_R(revision) \ + jump_to_handler JUNO_REVISION(revision), JUNO_HANDLER(revision) + /* -------------------------------------------------------------------- - * void plat_reset_handler(void); + * Helper macro to jump to the given handler if the board revision + * matches. + * Expects the Juno board revision in x0. + * -------------------------------------------------------------------- + */ + .macro jump_to_handler _revision, _handler + cmp x0, #\_revision + b.eq \_handler + .endm + + /* -------------------------------------------------------------------- + * Helper macro that reads the part number of the current CPU and jumps + * to the given label if it matches the CPU MIDR provided. * - * For Juno r0: + * Clobbers x0. + * -------------------------------------------------------------------- + */ + .macro jump_if_cpu_midr _cpu_midr, _label + mrs x0, midr_el1 + ubfx x0, x0, MIDR_PN_SHIFT, #12 + cmp w0, #((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK) + b.eq \_label + .endm + + /* -------------------------------------------------------------------- + * Platform reset handler for Juno R0. + * + * Juno R0 has the following topology: + * - Quad core Cortex-A53 processor cluster; + * - Dual core Cortex-A57 processor cluster. + * + * This handler does the following: * - Implement workaround for defect id 831273 by enabling an event * stream every 65536 cycles. * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A57 * - Set the L2 Tag RAM latency to 2 (i.e. 3 cycles) for Cortex-A57 + * -------------------------------------------------------------------- + */ +func JUNO_HANDLER(0) + /* -------------------------------------------------------------------- + * Enable the event stream every 65536 cycles + * -------------------------------------------------------------------- + */ + mov x0, #(0xf << EVNTI_SHIFT) + orr x0, x0, #EVNTEN_BIT + msr CNTKCTL_EL1, x0 + + /* -------------------------------------------------------------------- + * Nothing else to do on Cortex-A53. + * -------------------------------------------------------------------- + */ + jump_if_cpu_midr CORTEX_A53_MIDR, 1f + + /* -------------------------------------------------------------------- + * Cortex-A57 specific settings + * -------------------------------------------------------------------- + */ + mov x0, #((L2_DATA_RAM_LATENCY_3_CYCLES << L2CTLR_DATA_RAM_LATENCY_SHIFT) | \ + (L2_TAG_RAM_LATENCY_3_CYCLES << L2CTLR_TAG_RAM_LATENCY_SHIFT)) + msr L2CTLR_EL1, x0 +1: + isb + ret +endfunc JUNO_HANDLER(0) + + /* -------------------------------------------------------------------- + * Platform reset handler for Juno R1. * - * For Juno r1: + * Juno R1 has the following topology: + * - Quad core Cortex-A53 processor cluster; + * - Dual core Cortex-A57 processor cluster. + * + * This handler does the following: * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A57 + * * Note that: * - The default value for the L2 Tag RAM latency for Cortex-A57 is * suitable. - * - Defect #831273 doesn't affect Juno r1. + * - Defect #831273 doesn't affect Juno R1. * -------------------------------------------------------------------- */ -func plat_reset_handler +func JUNO_HANDLER(1) /* -------------------------------------------------------------------- - * Determine whether this code is running on Juno r0 or Juno r1. - * Keep this information in x2. + * Nothing to do on Cortex-A53. * -------------------------------------------------------------------- */ - /* Read the V2M SYS_ID register */ - mov_imm x0, (V2M_SYSREGS_BASE + V2M_SYS_ID) - ldr w1, [x0] - /* Extract board revision from the SYS_ID */ - ubfx x1, x1, #V2M_SYS_ID_REV_SHIFT, #4 - /* - * On Juno R0: x2 := REV_JUNO_R0 - 1 = 0 - * On Juno R1: x2 := REV_JUNO_R1 - 1 = 1 - */ - sub x2, x1, #1 - - /* -------------------------------------------------------------------- - * Determine whether this code is executed on a Cortex-A53 or on a - * Cortex-A57 core. - * -------------------------------------------------------------------- - */ - mrs x0, midr_el1 - ubfx x1, x0, MIDR_PN_SHIFT, #12 - cmp w1, #((CORTEX_A57_MIDR >> MIDR_PN_SHIFT) & MIDR_PN_MASK) - b.eq A57 - - /* Nothing needs to be done for the Cortex-A53 on Juno r1 */ - cbz x2, apply_831273 + jump_if_cpu_midr CORTEX_A57_MIDR, A57 ret A57: @@ -92,30 +140,48 @@ A57: * Cortex-A57 specific settings * -------------------------------------------------------------------- */ - - /* Change the L2 Data RAM latency to 3 cycles */ - mov x0, #L2_DATA_RAM_LATENCY_3_CYCLES - cbnz x2, apply_l2_ram_latencies - /* On Juno r0, also change the L2 Tag RAM latency to 3 cycles */ - orr x0, x0, #(L2_TAG_RAM_LATENCY_3_CYCLES << \ - L2CTLR_TAG_RAM_LATENCY_SHIFT) -apply_l2_ram_latencies: + mov x0, #(L2_DATA_RAM_LATENCY_3_CYCLES << L2CTLR_DATA_RAM_LATENCY_SHIFT) msr L2CTLR_EL1, x0 - - /* Juno r1 doesn't suffer from defect #831273 */ - cbnz x2, ret - -apply_831273: - /* -------------------------------------------------------------------- - * On Juno r0, enable the event stream every 65536 cycles - * -------------------------------------------------------------------- - */ - mov x0, #(0xf << EVNTI_SHIFT) - orr x0, x0, #EVNTEN_BIT - msr CNTKCTL_EL1, x0 -ret: isb ret +endfunc JUNO_HANDLER(1) + + /* -------------------------------------------------------------------- + * Platform reset handler for Juno R2. + * + * Juno R2 has the following topology: + * - Quad core Cortex-A53 processor cluster; + * - Dual core Cortex-A72 processor cluster. + * + * This handler does nothing. + * -------------------------------------------------------------------- + */ +func JUNO_HANDLER(2) + ret +endfunc JUNO_HANDLER(2) + + /* -------------------------------------------------------------------- + * void plat_reset_handler(void); + * + * Determine the Juno board revision and call the appropriate reset + * handler. + * -------------------------------------------------------------------- + */ +func plat_reset_handler + /* Read the V2M SYS_ID register */ + mov_imm x0, (V2M_SYSREGS_BASE + V2M_SYS_ID) + ldr w1, [x0] + /* Extract board revision from the SYS_ID */ + ubfx x0, x1, #V2M_SYS_ID_REV_SHIFT, #4 + + JUMP_TO_HANDLER_IF_JUNO_R(0) + JUMP_TO_HANDLER_IF_JUNO_R(1) + JUMP_TO_HANDLER_IF_JUNO_R(2) + + /* Board revision is not supported */ +not_supported: + b not_supported + endfunc plat_reset_handler /* ----------------------------------------------------- diff --git a/plat/arm/board/juno/juno_def.h b/plat/arm/board/juno/juno_def.h index 143cf00a0..1f367f274 100644 --- a/plat/arm/board/juno/juno_def.h +++ b/plat/arm/board/juno/juno_def.h @@ -39,6 +39,7 @@ /* Board revisions */ #define REV_JUNO_R0 0x1 /* Rev B */ #define REV_JUNO_R1 0x2 /* Rev C */ +#define REV_JUNO_R2 0x3 /* Rev D */ /* Bypass offset from start of NOR flash */ #define BL1_ROM_BYPASS_OFFSET 0x03EC0000 From 1dbe31591a24177d1dee3562dffe0f0aabe473f9 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Wed, 18 Nov 2015 11:59:35 +0000 Subject: [PATCH 2/2] Juno R2: Configure the correct L2 RAM latency values The default reset values for the L2 Data & Tag RAM latencies on the Cortex-A72 on Juno R2 are not suitable. This patch modifies the Juno platform reset handler to configure the right settings on Juno R2. Change-Id: I20953de7ba0619324a389e0b7bbf951b64057db8 --- include/lib/cpus/aarch64/cortex_a72.h | 1 + plat/arm/board/juno/aarch64/juno_helpers.S | 24 +++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/include/lib/cpus/aarch64/cortex_a72.h b/include/lib/cpus/aarch64/cortex_a72.h index bb32f9b97..fa10ca902 100644 --- a/include/lib/cpus/aarch64/cortex_a72.h +++ b/include/lib/cpus/aarch64/cortex_a72.h @@ -62,6 +62,7 @@ #define L2CTLR_TAG_RAM_LATENCY_SHIFT 6 #define L2_DATA_RAM_LATENCY_3_CYCLES 0x2 +#define L2_TAG_RAM_LATENCY_2_CYCLES 0x1 #define L2_TAG_RAM_LATENCY_3_CYCLES 0x2 #endif /* __CORTEX_A72_H__ */ diff --git a/plat/arm/board/juno/aarch64/juno_helpers.S b/plat/arm/board/juno/aarch64/juno_helpers.S index ab06da204..1931535e7 100644 --- a/plat/arm/board/juno/aarch64/juno_helpers.S +++ b/plat/arm/board/juno/aarch64/juno_helpers.S @@ -33,6 +33,7 @@ #include #include #include +#include #include #include "../juno_def.h" @@ -153,10 +154,31 @@ endfunc JUNO_HANDLER(1) * - Quad core Cortex-A53 processor cluster; * - Dual core Cortex-A72 processor cluster. * - * This handler does nothing. + * This handler does the following: + * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A72 + * - Set the L2 Tag RAM latency to 1 (i.e. 2 cycles) for Cortex-A72 + * + * Note that: + * - Defect #831273 doesn't affect Juno R2. * -------------------------------------------------------------------- */ func JUNO_HANDLER(2) + /* -------------------------------------------------------------------- + * Nothing to do on Cortex-A53. + * -------------------------------------------------------------------- + */ + jump_if_cpu_midr CORTEX_A72_MIDR, A72 + ret + +A72: + /* -------------------------------------------------------------------- + * Cortex-A72 specific settings + * -------------------------------------------------------------------- + */ + mov x0, #((L2_DATA_RAM_LATENCY_3_CYCLES << L2CTLR_DATA_RAM_LATENCY_SHIFT) | \ + (L2_TAG_RAM_LATENCY_2_CYCLES << L2CTLR_TAG_RAM_LATENCY_SHIFT)) + msr L2CTLR_EL1, x0 + isb ret endfunc JUNO_HANDLER(2)