mirror of
https://github.com/seL4/seL4.git
synced 2026-04-05 06:49:54 +00:00
Merge branch 'master' into arm_hyp
Conflicts: src/arch/arm/head.S src/arch/arm/kernel/vspace.c
This commit is contained in:
10
Kconfig
10
Kconfig
@@ -384,4 +384,14 @@ menu "Errata"
|
||||
if code containing ARM/Thumb interworking branch is replaced by different code
|
||||
at the same virtual address.
|
||||
|
||||
config ARM_ERRATA_773022
|
||||
bool "Enable workaround for 773022 Cortex-A15 (r0p0..r0p4) erratum"
|
||||
depends on ARCH_ARM
|
||||
depends on ARM_CORTEX_A15
|
||||
default y
|
||||
help
|
||||
Enables a workaround for the 773022 Cortex-A15 (r0p0..r0p4) erratum. Error occurs
|
||||
on rare sequences of instructions and results in the loop buffer delivering
|
||||
incorrect instructions. The work around is to disable the loop buffer
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -64,6 +64,38 @@ void setNextPC(tcb_t *thread, word_t v);
|
||||
|
||||
/* Architecture specific machine operations */
|
||||
|
||||
/** MODIFIES: [*] */
|
||||
static inline uint32_t getProcessorID(void)
|
||||
{
|
||||
uint32_t processor_id;
|
||||
MRC("p15, 0, %0, c0, c0, 0", processor_id);
|
||||
return processor_id;
|
||||
}
|
||||
|
||||
static inline uint32_t readSystemControlRegister(void)
|
||||
{
|
||||
uint32_t scr;
|
||||
MRC("p15, 0, %0, c1, c0, 0", scr);
|
||||
return scr;
|
||||
}
|
||||
|
||||
static inline void writeSystemControlRegister(uint32_t scr)
|
||||
{
|
||||
MCR("p15, 0, %0, c1, c0, 0", scr);
|
||||
}
|
||||
|
||||
static inline uint32_t readAuxiliaryControlRegister(void)
|
||||
{
|
||||
uint32_t acr;
|
||||
MRC("p15, 0, %0, c1, c0, 1", acr);
|
||||
return acr;
|
||||
}
|
||||
|
||||
static inline void writeAuxiliaryControlRegister(uint32_t acr)
|
||||
{
|
||||
MCR("p15, 0, %0, c1, c0, 1", acr);
|
||||
}
|
||||
|
||||
/** MODIFIES: [*] */
|
||||
static inline void clearExMonitor(void)
|
||||
{
|
||||
|
||||
@@ -89,36 +89,6 @@ BEGIN_FUNC(_start)
|
||||
mrc p15, 0, r4, c1, c0, 0
|
||||
#endif
|
||||
ldr r5, =CR_BITS_SET
|
||||
|
||||
#ifdef ARM1136_WORKAROUND
|
||||
/*
|
||||
* We need to potentially work around arm1136 errata #364296 which
|
||||
* can cause data cache corruption. The fix involves disabling hit-under-miss
|
||||
* via an undocumented bit in the aux control register, as well as the
|
||||
* FI bit in the control register. The result of enabling these two bits
|
||||
* is for fast interrupts to *not* be enabled, but hit-under-miss to be
|
||||
* disabled. We only need to do this for a particular revision of the
|
||||
* arm1136
|
||||
*/
|
||||
ldr r6, =ARM1136_R0PX
|
||||
/* Load processor id */
|
||||
mrc p15, 0, r7, c0, c0, 0
|
||||
/* Mask out bottom four part bits */
|
||||
bic r7, r7, #0xf
|
||||
teq r7, r6
|
||||
bne 1f
|
||||
|
||||
/* Additionally enable the Fast Interrupts bit in the control register */
|
||||
ldr r6, =BIT(CONTROL_FI)
|
||||
orr r5, r5, r6
|
||||
|
||||
/* Set undocumented bit 31 in the auxiliary control register */
|
||||
mrc p15, 0, r6, c1, c0, 1
|
||||
orr r6, r6, #(1<<31)
|
||||
mcr p15, 0, r6, c1, c0, 1
|
||||
1:
|
||||
#endif /* ARM1136_WORKAROUND */
|
||||
|
||||
ldr r6, =CR_BITS_CLEAR
|
||||
orr r4, r4, r5
|
||||
bic r4, r4, r6
|
||||
@@ -142,6 +112,11 @@ BEGIN_FUNC(_start)
|
||||
ldr sp, =arm_kernel_stack
|
||||
add sp, sp, #(PPTR_KERNEL_STACK_TOP - PPTR_KERNEL_STACK)
|
||||
|
||||
/* Attempt to workaround any known ARM errata. */
|
||||
push {r0-r3}
|
||||
blx arm_errata
|
||||
pop {r0-r3}
|
||||
|
||||
/* Hyp kernel always run in Hyp mode. */
|
||||
#ifndef ARM_HYP
|
||||
/* Initialise ABORT stack pointer */
|
||||
|
||||
@@ -12,7 +12,8 @@ DIRECTORIES += src/arch/arm/machine
|
||||
|
||||
ARCH_C_SOURCES += machine/hardware.c \
|
||||
machine/registerset.c \
|
||||
machine/cache.c
|
||||
machine/cache.c \
|
||||
machine/errata.c
|
||||
|
||||
ifeq ($(CPU), cortex-a9)
|
||||
ARCH_C_SOURCES += machine/gic_pl390.c
|
||||
|
||||
71
src/arch/arm/machine/errata.c
Normal file
71
src/arch/arm/machine/errata.c
Normal file
@@ -0,0 +1,71 @@
|
||||
|
||||
#include <config.h>
|
||||
#include <api/types.h>
|
||||
#include <arch/machine.h>
|
||||
#include <arch/machine/hardware.h>
|
||||
|
||||
/* Prototyped here as this is referenced from assembly */
|
||||
void arm_errata(void);
|
||||
|
||||
#ifdef ARM1136_WORKAROUND
|
||||
/*
|
||||
* Potentially work around ARM1136 errata #364296, which can cause data
|
||||
* cache corruption.
|
||||
*
|
||||
* The fix involves disabling hit-under-miss via an undocumented bit in
|
||||
* the aux control register, as well as the FI bit in the control
|
||||
* register. The result of enabling these two bits is for fast
|
||||
* interrupts to *not* be enabled, but hit-under-miss to be disabled. We
|
||||
* only need to do this for a particular revision of the ARM1136.
|
||||
*/
|
||||
BOOT_CODE static void
|
||||
errata_arm1136(void)
|
||||
{
|
||||
/* See if we are affected by the errata. */
|
||||
if ((getProcessorID() & ~0xf) == ARM1136_R0PX) {
|
||||
|
||||
/* Enable the Fast Interrupts bit in the control register. */
|
||||
writeSystemControlRegister(
|
||||
readSystemControlRegister() | BIT(CONTROL_FI));
|
||||
|
||||
/* Set undocumented bit 31 in the auxiliary control register */
|
||||
writeAuxiliaryControlRegister(
|
||||
readAuxiliaryControlRegister() | BIT(31));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARM_ERRATA_773022
|
||||
/*
|
||||
* There is an errata for Cortex-A15 up to r0p4 where the loop buffer
|
||||
* may deliver incorrect instructions. The work around is to disable
|
||||
* the loop buffer. Errata is number 773022.
|
||||
*/
|
||||
BOOT_CODE static void errata_armA15_773022(void)
|
||||
{
|
||||
/* Fetch the processor primary part number. */
|
||||
uint32_t proc_id = getProcessorID();
|
||||
uint32_t variant = (proc_id >> 20) & MASK(4);
|
||||
uint32_t revision = proc_id & MASK(4);
|
||||
uint32_t part = (proc_id >> 4) & MASK(12);
|
||||
|
||||
/* Check that we are running A15 and a revision upto r0p4. */
|
||||
if (part == 0xc0f && variant == 0 && revision <= 4) {
|
||||
/* Disable loop buffer in the auxiliary control register */
|
||||
writeAuxiliaryControlRegister(
|
||||
readAuxiliaryControlRegister() | BIT(1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOT_CODE void __attribute__((externally_visible)) arm_errata(void)
|
||||
{
|
||||
#ifdef ARM1136_WORKAROUND
|
||||
errata_arm1136();
|
||||
#endif
|
||||
#ifdef CONFIG_ARM_ERRATA_773022
|
||||
(void)errata_armA15_773022;
|
||||
errata_armA15_773022();
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user