If LOWVECTORS is selected, then we need to clear the VBAR register. A bootloader may have left the VBAR in an bad state

This commit is contained in:
Gregory Nutt 2014-04-03 13:09:30 -06:00
parent e3d2117b29
commit 362d539914
3 changed files with 41 additions and 8 deletions

View File

@ -192,10 +192,10 @@ __start:
/* The MMU and caches should be disabled */
mrc p15, 0, r0, c1, c0, 0
mrc CP15_SCTLR(r0)
bic r0, r0, #(SCTLR_M | SCTLR_C)
bic r0, r0, #(SCTLR_I)
mcr p15, 0, r0, c1, c0, 0
mcr CP15_SCTLR(r0)
/* Clear the 16K level 1 page table */

View File

@ -204,7 +204,8 @@
*/
/* Vector Base Address Register (VBAR) */
/* TODO: To be provided */
#define VBAR_MASK (0xffffffe0)
/* Monitor Vector Base Address Register (MVBAR) */
/* TODO: To be provided */
@ -313,6 +314,33 @@ static inline void cp15_wrsctlr(unsigned int sctlr)
);
}
/* Read/write the vector base address register (VBAR) */
static inline unsigned int cp15_rdvbar(void)
{
unsigned int sctlr;
__asm__ __volatile__
(
"\tmrc p15, 0, %0, c12, c0, 0\n"
: "=r" (sctlr)
:
: "memory"
);
return sctlr;
}
static inline void cp15_wrvbar(unsigned int sctlr)
{
__asm__ __volatile__
(
"\tmcr p15, 0, %0, c12, c0, 0\n"
:
: "r" (sctlr)
: "memory"
);
}
#endif /* __ASSEMBLY__ */
/****************************************************************************

View File

@ -56,6 +56,7 @@
#include "mmu.h"
#include "cache.h"
#include "sctlr.h"
#include "chip/sam_aic.h"
#include "chip/sam_matrix.h"
#include "chip/sam_aximx.h"
@ -121,7 +122,7 @@ static void sam_dumpaic(const char *msg, int irq)
lldbg(" SSR: %08x SMR: %08x SVR: %08x IVR: %08x\n",
getreg32(SAM_AIC_SSR), getreg32(SAM_AIC_SMR),
getreg32(SAM_AIC_SVR), getreg32(SAM_AIC_IVR));
lldbg(" FVR: %08x ISR: %08x\n",
lldbg(" FVR: %08x ISR: %08x\n",
getreg32(SAM_AIC_FVR), getreg32(SAM_AIC_ISR));
lldbg(" IPR: %08x %08x %08x %08x\n",
getreg32(SAM_AIC_IPR0), getreg32(SAM_AIC_IPR1),
@ -129,9 +130,9 @@ static void sam_dumpaic(const char *msg, int irq)
lldbg(" IMR: %08x CISR: %08x SPU: %08x FFSR: %08x\n",
getreg32(SAM_AIC_IMR), getreg32(SAM_AIC_CISR),
getreg32(SAM_AIC_SPU), getreg32(SAM_AIC_FFSR));
lldbg(" DCR: %08x WPMR: %08x WPMR: %08x\n",
lldbg(" DCR: %08x WPMR: %08x WPSR: %08x\n",
getreg32(SAM_AIC_DCR), getreg32(SAM_AIC_WPMR),
getreg32(SAM_AIC_WPMR));
getreg32(SAM_AIC_WPSR));
irqrestore(flags);
}
#else
@ -308,9 +309,13 @@ void up_irqinitialize(void)
putreg32(AIC_WPMR_WPKEY | AIC_WPMR_WPEN, SAM_AIC_WPMR);
#if defined(CONFIG_ARCH_LOWVECTORS)
/* Disable MATRIX write protection */
/* Set the vector base address register to zero */
cp15_wrvbar(0);
#if 0 /* Disabled on reset */
/* Disable MATRIX write protection */
putreg32(MATRIX_WPMR_WPKEY, SAM_MATRIX_WPMR);
#endif
@ -348,9 +353,9 @@ void up_irqinitialize(void)
cp15_invalidate_dcache(0, vectorsize);
mmu_invalidate_region(0, vectorsize);
#if 0 /* Disabled on reset */
/* Restore MATRIX write protection */
#if 0 /* Disabled on reset */
putreg32(MATRIX_WPMR_WPKEY | MATRIX_WPMR_WPEN, SAM_MATRIX_WPMR);
#endif