1/* 2 * Copyright 2014, General Dynamics C4 Systems 3 * 4 * SPDX-License-Identifier: GPL-2.0-only 5 */ 6 7#include <config.h> 8#include <api/types.h> 9#include <arch/machine.h> 10#include <arch/machine/hardware.h> 11#include <util.h> 12 13/* Prototyped here as this is referenced from assembly */ 14void arm_errata(void); 15 16#ifdef ARM1136_WORKAROUND 17/* 18 * Potentially work around ARM1136 errata #364296, which can cause data 19 * cache corruption. 20 * 21 * The fix involves disabling hit-under-miss via an undocumented bit in 22 * the aux control register, as well as the FI bit in the control 23 * register. The result of enabling these two bits is for fast 24 * interrupts to *not* be enabled, but hit-under-miss to be disabled. We 25 * only need to do this for a particular revision of the ARM1136. 26 */ 27BOOT_CODE static void errata_arm1136(void) 28{ 29 /* See if we are affected by the errata. */ 30 if ((getProcessorID() & ~0xf) == ARM1136_R0PX) { 31 32 /* Enable the Fast Interrupts bit in the control register. */ 33 writeSystemControlRegister( 34 readSystemControlRegister() | BIT(CONTROL_FI)); 35 36 /* Set undocumented bit 31 in the auxiliary control register */ 37 writeAuxiliaryControlRegister( 38 readAuxiliaryControlRegister() | BIT(31)); 39 } 40} 41#endif 42 43#ifdef CONFIG_ARM_ERRATA_773022 44/* 45 * There is an errata for Cortex-A15 up to r0p4 where the loop buffer 46 * may deliver incorrect instructions. The work around is to disable 47 * the loop buffer. Errata is number 773022. 48 */ 49BOOT_CODE static void errata_armA15_773022(void) 50{ 51 /* Fetch the processor primary part number. */ 52 uint32_t proc_id = getProcessorID(); 53 uint32_t variant = (proc_id >> 20) & MASK(4); 54 uint32_t revision = proc_id & MASK(4); 55 uint32_t part = (proc_id >> 4) & MASK(12); 56 57 /* Check that we are running A15 and a revision upto r0p4. */ 58 if (part == 0xc0f && variant == 0 && revision <= 4) { 59 /* Disable loop buffer in the auxiliary control register */ 60 writeAuxiliaryControlRegister( 61 readAuxiliaryControlRegister() | BIT(1)); 62 } 63} 64#endif 65 66BOOT_CODE void VISIBLE arm_errata(void) 67{ 68#ifdef ARM1136_WORKAROUND 69 errata_arm1136(); 70#endif 71#ifdef CONFIG_ARM_ERRATA_773022 72 errata_armA15_773022(); 73#endif 74} 75 76