Patrick Georgi (pgeorgi@google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/10899
-gerrit
commit b845fe9ddcaa9e2557ddd2cfe1b831c878155b2a Author: Furquan Shaikh furquan@google.com Date: Fri Jul 10 15:29:13 2015 -0700
t210: Apply A57 hardware issue workaround during cpu startup
Define custom stage_entry to apply workaround for A57 hardware issue for power on reset. It is observed that BTB contains stale data after power on reset. This could lead to unexpected branching and crashes at random intervals during the boot flow. Thus, invalidate the BTB immediately after power on reset.
BUG=chrome-os-partner:41877 BRANCH=None TEST=Compiles successfully and reboot test does not crash in firmware for 10K iterations.
Change-Id: Ifbc9667bc5556112374f35733192b67b64a345d2 Signed-off-by: Patrick Georgi pgeorgi@chromium.org Original-Commit-Id: bc7c2fec3c6b29e291235669ba9f22ff611064a7 Original-Change-Id: I1f5714074afdfee64b88cea8a394936ca848634b Original-Signed-off-by: Furquan Shaikh furquan@google.com Original-Reviewed-on: https://chromium-review.googlesource.com/284869 Original-Reviewed-by: Aaron Durbin adurbin@chromium.org Original-Trybot-Ready: Furquan Shaikh furquan@chromium.org Original-Tested-by: Furquan Shaikh furquan@chromium.org Original-Commit-Queue: Furquan Shaikh furquan@chromium.org --- src/soc/nvidia/tegra210/Makefile.inc | 3 +- src/soc/nvidia/tegra210/reset_handler.S | 75 -------------------------- src/soc/nvidia/tegra210/stage_entry.S | 95 +++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 76 deletions(-)
diff --git a/src/soc/nvidia/tegra210/Makefile.inc b/src/soc/nvidia/tegra210/Makefile.inc index 3b2dc7c..8d7e1fc 100644 --- a/src/soc/nvidia/tegra210/Makefile.inc +++ b/src/soc/nvidia/tegra210/Makefile.inc @@ -101,13 +101,14 @@ ramstage-$(CONFIG_DRIVERS_UART) += uart.c ramstage-y += ../tegra/usb.c ramstage-$(CONFIG_ARM64_USE_SECURE_MONITOR) += secmon.c ramstage-$(CONFIG_HAVE_MTC) += mtc.c +ramstage-y += stage_entry.S
secmon-y += cpu.c secmon-y += cpu_lib.S secmon-y += flow_ctrl.c secmon-y += power.c secmon-y += psci.c -secmon-y += reset_handler.S +secmon-y += stage_entry.S secmon-y += uart.c secmon-y += gic.c
diff --git a/src/soc/nvidia/tegra210/reset_handler.S b/src/soc/nvidia/tegra210/reset_handler.S deleted file mode 100644 index 53622b1..0000000 --- a/src/soc/nvidia/tegra210/reset_handler.S +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include <arch/asm.h> - -#define CPUACTLR_EL1 s3_1_c15_c2_0 - -CPU_RESET_ENTRY(tegra210_reset_handler) - /* - * Invalidate BTB along with I$ to remove any stale entries - * from the branch predictor array. - */ - mrs x0, CPUACTLR_EL1 - orr x0, x0, #1 - msr CPUACTLR_EL1, x0 /* invalidate BTB and I$ together */ - dsb sy - isb - ic iallu /* invalidate */ - dsb sy - isb - - bic x0, x0, #1 - msr CPUACTLR_EL1, x0 /* restore original CPUACTLR_EL1 */ - dsb sy - isb - - .rept 7 - nop /* wait */ - .endr - - /* - * Extract OSLK bit and check if it is '1'. This bit remains '0' - * for A53. If '1', turn off regional clock gating and request - * warm reset. - */ - mrs x0, oslsr_el1 - and x0, x0, #2 /* extract oslk bit */ - mrs x1, mpidr_el1 - bics xzr, x0, x1, lsr #7 /* 0 if slow cluster */ - b.eq __restore_oslock - mov x0, xzr - msr oslar_el1, x0 /* os lock stays 0 across warm reset */ - mov x3, #3 - movz x4, #0x8000, lsl #48 - msr CPUACTLR_EL1, x4 /* turn off RCG */ - isb - msr rmr_el3, x3 /* request warm reset */ - isb - dsb sy - wfi - - /* - * These nops are here so that speculative execution won't harm us - * before we are done warm reset. - */ - .rept 65 - nop - .endr - -__restore_oslock: - mov x0, #1 - msr oslar_el1, x0 - - b arm64_cpu_startup_resume -ENDPROC(tegra210_reset_handler) diff --git a/src/soc/nvidia/tegra210/stage_entry.S b/src/soc/nvidia/tegra210/stage_entry.S new file mode 100644 index 0000000..ee0265f --- /dev/null +++ b/src/soc/nvidia/tegra210/stage_entry.S @@ -0,0 +1,95 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved. + * Copyright 2015 Google Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <arch/asm.h> +#include <cpu/cortex_a57.h> + +/* + * It is observed that BTB contains stale data after power on reset. This could + * lead to unexpected branching and crashes at random intervals during the boot + * flow. Thus, invalidate the BTB immediately after power on reset. + */ +.macro t210_a57_fixup + /* + * Invalidate BTB along with I$ to remove any stale entries + * from the branch predictor array. + */ + mrs x0, CPUACTLR_EL1 + orr x0, x0, #BTB_INVALIDATE + msr CPUACTLR_EL1, x0 /* invalidate BTB and I$ together */ + dsb sy + isb + ic iallu /* invalidate */ + dsb sy + isb + + bic x0, x0, #BTB_INVALIDATE + msr CPUACTLR_EL1, x0 /* restore original CPUACTLR_EL1 */ + dsb sy + isb + + .rept 7 + nop /* wait */ + .endr + + /* + * Extract OSLK bit and check if it is '1'. This bit remains '0' + * for A53. If '1', turn off regional clock gating and request + * warm reset. + */ + mrs x0, oslsr_el1 + and x0, x0, #2 /* extract oslk bit */ + mrs x1, mpidr_el1 + bics xzr, x0, x1, lsr #7 /* 0 if slow cluster */ + b.eq 1000f + mov x0, xzr + msr oslar_el1, x0 /* os lock stays 0 across warm reset */ + mov x3, #3 + movz x4, #0x8000, lsl #48 + msr CPUACTLR_EL1, x4 /* turn off RCG */ + isb + msr rmr_el3, x3 /* request warm reset */ + isb + dsb sy + wfi + + /* + * These nops are here so that speculative execution won't harm us + * before we are done warm reset. + */ + .rept 65 + nop + .endr + +1000: + /* Restore os lock */ + mov x0, #1 + msr oslar_el1, x0 +.endm + +ENTRY(stage_entry) + t210_a57_fixup + b arm64_cpu_startup +ENDPROC(stage_entry) + +ENTRY(tegra210_reset_handler) + t210_a57_fixup + b arm64_cpu_startup_resume +ENDPROC(tegra210_reset_handler)