SAMA5: Correct vector mapping
This commit is contained in:
parent
9a5311296f
commit
f191ac94c0
@ -94,10 +94,10 @@
|
||||
* Public Symbols
|
||||
****************************************************************************/
|
||||
|
||||
.globl cp15_coherent_dcache_for_dma
|
||||
.globl cp15_invalidate_dcache_for_dma
|
||||
.globl cp15_clean_dcache_for_dma
|
||||
.globl cp15_flush_dcache_for_dma
|
||||
.globl cp15_coherent_dcache
|
||||
.globl cp15_invalidate_dcache
|
||||
.globl cp15_clean_dcache
|
||||
.globl cp15_flush_dcache
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
@ -106,7 +106,7 @@
|
||||
.text
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cp15_coherent_dcache_for_dma
|
||||
* Name: cp15_coherent_dcache
|
||||
*
|
||||
* Description:
|
||||
* Ensure that the I and D caches are coherent within specified region
|
||||
@ -123,10 +123,10 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.globl cp15_coherent_dcache_for_dma
|
||||
.type cp15_coherent_dcache_for_dma, function
|
||||
.globl cp15_coherent_dcache
|
||||
.type cp15_coherent_dcache, function
|
||||
|
||||
cp15_coherent_dcache_for_dma:
|
||||
cp15_coherent_dcache:
|
||||
mrc CP15_TR(r3) /* Read the Cache Type Register */
|
||||
lsr r3, r3, #16 /* Isolate the DMinLine field */
|
||||
and r3, r3, #0xf
|
||||
@ -167,10 +167,10 @@ cp15_coherent_dcache_for_dma:
|
||||
dsb
|
||||
isb
|
||||
bx lr
|
||||
.size cp15_coherent_dcache_for_dma, . - cp15_coherent_dcache_for_dma
|
||||
.size cp15_coherent_dcache, . - cp15_coherent_dcache
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cp15_invalidate_dcache_for_dma
|
||||
* Name: cp15_invalidate_dcache
|
||||
*
|
||||
* Description:
|
||||
* Invalidate the data cache within the specified region; we will be
|
||||
@ -186,10 +186,10 @@ cp15_coherent_dcache_for_dma:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.globl cp15_invalidate_dcache_for_dma
|
||||
.type cp15_invalidate_dcache_for_dma, function
|
||||
.globl cp15_invalidate_dcache
|
||||
.type cp15_invalidate_dcache, function
|
||||
|
||||
cp15_invalidate_dcache_for_dma:
|
||||
cp15_invalidate_dcache:
|
||||
|
||||
mrc CP15_TR(r3) /* Read the Cache Type Register */
|
||||
lsr r3, r3, #16 /* Isolate the DMinLine field */
|
||||
@ -216,10 +216,10 @@ cp15_invalidate_dcache_for_dma:
|
||||
|
||||
dsb
|
||||
bx lr
|
||||
.size cp15_coherent_dcache_for_dma, . - cp15_coherent_dcache_for_dma
|
||||
.size cp15_coherent_dcache, . - cp15_coherent_dcache
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cp15_clean_dcache_for_dma
|
||||
* Name: cp15_clean_dcache
|
||||
*
|
||||
* Description:
|
||||
* Clean the data cache within the specified region by flushing the
|
||||
@ -234,10 +234,10 @@ cp15_invalidate_dcache_for_dma:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.globl cp15_clean_dcache_for_dma
|
||||
.type cp15_clean_dcache_for_dma, function
|
||||
.globl cp15_clean_dcache
|
||||
.type cp15_clean_dcache, function
|
||||
|
||||
cp15_clean_dcache_for_dma:
|
||||
cp15_clean_dcache:
|
||||
|
||||
mrc CP15_TR(r3) /* Read the Cache Type Register */
|
||||
lsr r3, r3, #16 /* Isolate the DMinLine field */
|
||||
@ -258,10 +258,10 @@ cp15_clean_dcache_for_dma:
|
||||
|
||||
dsb
|
||||
bx lr
|
||||
.size cp15_clean_dcache_for_dma, . - cp15_clean_dcache_for_dma
|
||||
.size cp15_clean_dcache, . - cp15_clean_dcache
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cp15_flush_dcache_for_dma
|
||||
* Name: cp15_flush_dcache
|
||||
*
|
||||
* Description:
|
||||
* Flush the data cache within the specified region by cleaning and
|
||||
@ -276,10 +276,10 @@ cp15_clean_dcache_for_dma:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.globl cp15_flush_dcache_for_dma
|
||||
.type cp15_flush_dcache_for_dma, function
|
||||
.globl cp15_flush_dcache
|
||||
.type cp15_flush_dcache, function
|
||||
|
||||
cp15_flush_dcache_for_dma:
|
||||
cp15_flush_dcache:
|
||||
|
||||
mrc CP15_TR(r3) /* Read the Cache Type Register */
|
||||
lsr r3, r3, #16 /* Isolate the DMinLine field */
|
||||
@ -300,5 +300,5 @@ cp15_flush_dcache_for_dma:
|
||||
|
||||
dsb
|
||||
bx lr
|
||||
.size cp15_flush_dcache_for_dma, . - cp15_flush_dcache_for_dma
|
||||
.size cp15_flush_dcache, . - cp15_flush_dcache
|
||||
.end
|
||||
|
@ -765,7 +765,7 @@ extern "C" {
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cp15_coherent_dcache_for_dma
|
||||
* Name: cp15_coherent_dcache
|
||||
*
|
||||
* Description:
|
||||
* Ensure that the I and D caches are coherent within specified region
|
||||
@ -782,10 +782,10 @@ extern "C" {
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void cp15_coherent_dcache_for_dma(uintptr_t start, uintptr_t end);
|
||||
void cp15_coherent_dcache(uintptr_t start, uintptr_t end);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cp15_invalidate_dcache_for_dma
|
||||
* Name: cp15_invalidate_dcache
|
||||
*
|
||||
* Description:
|
||||
* Invalidate the data cache within the specified region; we will be
|
||||
@ -801,10 +801,10 @@ void cp15_coherent_dcache_for_dma(uintptr_t start, uintptr_t end);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void cp15_invalidate_dcache_for_dma(uintptr_t start, uintptr_t end);
|
||||
void cp15_invalidate_dcache(uintptr_t start, uintptr_t end);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cp15_clean_dcache_for_dma
|
||||
* Name: cp15_clean_dcache
|
||||
*
|
||||
* Description:
|
||||
* Clean the data cache within the specified region by flushing the
|
||||
@ -819,10 +819,10 @@ void cp15_invalidate_dcache_for_dma(uintptr_t start, uintptr_t end);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void cp15_clean_dcache_for_dma(uintptr_t start, uintptr_t end);
|
||||
void cp15_clean_dcache(uintptr_t start, uintptr_t end);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cp15_flush_dcache_for_dma
|
||||
* Name: cp15_flush_dcache
|
||||
*
|
||||
* Description:
|
||||
* Flush the data cache within the specified region by cleaning and
|
||||
@ -837,7 +837,7 @@ void cp15_clean_dcache_for_dma(uintptr_t start, uintptr_t end);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void cp15_flush_dcache_for_dma(uintptr_t start, uintptr_t end);
|
||||
void cp15_flush_dcache(uintptr_t start, uintptr_t end);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
|
@ -486,55 +486,69 @@
|
||||
*
|
||||
* 0x80000000-0xefffffff: Undefined (1.75 GB)
|
||||
*
|
||||
* That is the offset where the main L2 page table will be positioned. This
|
||||
* corresponds to page table offsets 0x000002000 through 0x000003c00. That
|
||||
* That is the offset where the main L2 page tables will be positioned. This
|
||||
* corresponds to page table offsets 0x000002000 up to 0x000003c00. That
|
||||
* is 1792 entries, each mapping 4KB of address for a total of 7MB of virtual
|
||||
* address space)
|
||||
*
|
||||
* Up to two L2 page tables may be used:
|
||||
*
|
||||
* 1) One mapping the vector table. However, L2 page tables must be aligned
|
||||
* to 1KB address boundaries, so the minimum L2 page table size is then
|
||||
* 1KB, mapping up a full megabyte of virtual address space.
|
||||
*
|
||||
* This L2 page table is only allocated if CONFIG_ARCH_LOWVECTORS is *not*
|
||||
* defined. The SAMA5 boot-up logic will map the beginning of the boot
|
||||
* memory to address 0x0000:0000 using both the MMU and the AXI matrix
|
||||
* REMAP register. So no L2 page table is required.
|
||||
*
|
||||
* 2) If on-demand paging is supported (CONFIG_PAGING=y), than an additional
|
||||
* L2 page table is needed. This page table will use the remainder of
|
||||
* the address space.
|
||||
*/
|
||||
|
||||
#define PGTABLE_L2_OFFSET 0x000002000
|
||||
#define PGTABLE_L2_SIZE 0x000001c00
|
||||
#ifndef CONFIG_ARCH_LOWVECTORS
|
||||
/* Vector L2 page table offset/size */
|
||||
|
||||
/* This other small region is reserved for the vector table L2 page table
|
||||
*
|
||||
* 0x00a00000-0x0fffffff: Undefined (246 MB)
|
||||
*
|
||||
* This corresponds to page table offsets 0x000000028 through 0x00000400.
|
||||
* That is 246 entries each mapping 4KB of address each for a total of 984KB
|
||||
* of virtual address space). For low vectors, this L2 page table can can
|
||||
* span: 0x0000:0000 through 0x000f:6000 leaving up to the full 984KB for
|
||||
* vector logic. For high vectors located at 0xffff:0000, this L2 page
|
||||
* table can cover only 0xfff0:0000 through 0xffff:6000 which leaves 5KB for
|
||||
* vectors.
|
||||
*/
|
||||
# define VECTOR_L2_OFFSET 0x000002000
|
||||
# define VECTOR_L2_SIZE 0x000000400
|
||||
|
||||
#define VECTOR_L2_OFFSET 0x000000028
|
||||
#define VECTOR_L2_SIZE 0x000000400
|
||||
/* Vector L2 page table base addresses */
|
||||
|
||||
/* If we need more L2 page tables, there additional entries can be obtained
|
||||
* from other unused areas in the physical memory map:
|
||||
# define VECTOR_L2_PBASE (PGTABLE_BASE_PADDR+VECTOR_L2_OFFSET)
|
||||
# define VECTOR_L2_VBASE (PGTABLE_BASE_VADDR+VECTOR_L2_OFFSET)
|
||||
|
||||
/* Vector L2 page table end addresses */
|
||||
|
||||
# define VECTOR_L2_END_PADDR (VECTOR_L2_PBASE+VECTOR_L2_SIZE)
|
||||
# define VECTOR_L2_END_VADDR (VECTOR_L2_VBASE+VECTOR_L2_SIZE)
|
||||
|
||||
/* Paging L2 page table offset/size */
|
||||
|
||||
# define PGTABLE_L2_OFFSET 0x000002400
|
||||
# define PGTABLE_L2_SIZE 0x000001800
|
||||
|
||||
#else
|
||||
/* Paging L2 page table offset/size */
|
||||
|
||||
# define PGTABLE_L2_OFFSET 0x000002000
|
||||
# define PGTABLE_L2_SIZE 0x000001c00
|
||||
#endif
|
||||
|
||||
/* Paging L2 page table base addresses
|
||||
*
|
||||
* 0x0003c000-0x07ffffff: Reserved (127.8 MB)
|
||||
* 0x00044000-0x00ffbfff: Reserved ( 15.7 MB)
|
||||
*
|
||||
* NOTE: If CONFIG_PAGING is defined, mmu.h will re-assign the virtual address
|
||||
* of the page table.
|
||||
* NOTE: If CONFIG_PAGING is defined, mmu.h will re-assign the virtual
|
||||
* address of the page table.
|
||||
*/
|
||||
|
||||
#define PGTABLE_L2_PBASE (PGTABLE_BASE_PADDR+PGTABLE_L2_OFFSET)
|
||||
#define PGTABLE_L2_VBASE (PGTABLE_BASE_VADDR+PGTABLE_L2_OFFSET)
|
||||
|
||||
#define VECTOR_L2_PBASE (PGTABLE_BASE_PADDR+VECTOR_L2_OFFSET)
|
||||
#define VECTOR_L2_VBASE (PGTABLE_BASE_VADDR+VECTOR_L2_OFFSET)
|
||||
|
||||
/* Page table end addresses: */
|
||||
/* Paging L2 page table end addresses */
|
||||
|
||||
#define PGTABLE_L2_END_PADDR (PGTABLE_L2_PBASE+PGTABLE_L2_SIZE)
|
||||
#define PGTABLE_L2_END_VADDR (PGTABLE_L2_VBASE+PGTABLE_L2_SIZE)
|
||||
|
||||
#define VECTOR_L2_END_PADDR (VECTOR_L2_PBASE+VECTOR_L2_SIZE)
|
||||
#define VECTOR_L2_END_VADDR (VECTOR_L2_VBASE+VECTOR_L2_SIZE)
|
||||
|
||||
/* Base address of the interrupt vector table.
|
||||
*
|
||||
* SAM_VECTOR_PADDR - Unmapped, physical address of vector table in SRAM
|
||||
|
@ -66,23 +66,23 @@
|
||||
/* The vectors are, by default, positioned at the beginning of the text
|
||||
* section. Under what conditions do we have to remap the these vectors?
|
||||
*
|
||||
* 1) If we are using high vectors. In this case, the vectors will lie at
|
||||
* virtual address 0xfffc0000 and we will need to a) copy the vectors to
|
||||
* another location, and 2) map the vectors to that address.
|
||||
* 2) If we are using low vectors but the .text region is not already mapped
|
||||
* to address 0x0000:0000
|
||||
* 3) We are not using a ROM page table. We cannot set any custom mappings in
|
||||
* 1) If we are using high vectors (CONFIG_ARCH_LOWVECTORS=n). In this case,
|
||||
* the vectors will lie at virtual address 0xffff:000 and we will need
|
||||
* to a) copy the vectors to another location, and b) map the vectors
|
||||
* to that address, and
|
||||
*
|
||||
* For the case of CONFIG_ARCH_LOWVECTORS=y, defined. The SAMA5 boot-up
|
||||
* logic will map the beginning of the boot memory to address 0x0000:0000
|
||||
* using both the MMU and the AXI matrix REMAP register. No vector copy
|
||||
* is required because the vectors are position at the beginning of the
|
||||
* boot memory at link time and no additional MMU mapping required.
|
||||
*
|
||||
* 2) We are not using a ROM page table. We cannot set any custom mappings in
|
||||
* the case and the build must conform to the ROM page table properties
|
||||
*/
|
||||
|
||||
#undef NEED_VECTORMAP
|
||||
#if !defined(CONFIG_ARCH_LOWVECTORS) || (NUTTX_START_VADDR & 0xfff00000) != 0
|
||||
|
||||
# if defined(CONFIG_ARCH_ROMPGTABLE)
|
||||
# error Vector remap cannot be performed if we are using a ROM page table
|
||||
# endif
|
||||
|
||||
# define NEED_VECTORMAP
|
||||
#if !defined(CONFIG_ARCH_LOWVECTORS) && defined(CONFIG_ARCH_ROMPGTABLE)
|
||||
# error High vector remap cannot be performed if we are using a ROM page table
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
@ -117,10 +117,8 @@ static const struct section_mapping_s section_mapping[] =
|
||||
{
|
||||
/* SAMA5 Internal Memories */
|
||||
|
||||
#ifndef CONFIG_ARCH_LOWVECTORS
|
||||
{ SAM_BOOTMEM_PSECTION, SAM_BOOTMEM_VSECTION,
|
||||
SAM_BOOTMEM_MMUFLAGS, SAM_BOOTMEM_NSECTIONS},
|
||||
#endif
|
||||
{ SAM_ROM_PSECTION, SAM_ROM_VSECTION,
|
||||
SAM_ROM_MMUFLAGS, SAM_ROM_NSECTIONS},
|
||||
{ SAM_NFCSRAM_PSECTION, SAM_NFCSRAM_VSECTION,
|
||||
@ -261,7 +259,8 @@ static void sam_setupmappings(void)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(NEED_VECTORMAP) && defined(CONFIG_PAGING)
|
||||
#if !defined(CONFIG_ARCH_ROMPGTABLE) && defined(CONFIG_ARCH_LOWVECTORS) && \
|
||||
defined(CONFIG_PAGING)
|
||||
static void sam_vectorpermissions(uint32_t mmuflags)
|
||||
{
|
||||
/* The PTE for the beginning of ISRAM is at the base of the L2 page table */
|
||||
@ -304,7 +303,7 @@ static void sam_vectorpermissions(uint32_t mmuflags)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef NEED_VECTORMAP
|
||||
#if !defined(CONFIG_ARCH_ROMPGTABLE) && !defined(CONFIG_ARCH_LOWVECTORS)
|
||||
static void sam_vectormapping(void)
|
||||
{
|
||||
uint32_t vector_paddr = SAM_VECTOR_PADDR & PTE_SMALL_PADDR_MASK;
|
||||
@ -312,7 +311,7 @@ static void sam_vectormapping(void)
|
||||
uint32_t vector_size = (uint32_t)&_vector_end - (uint32_t)&_vector_start;
|
||||
uint32_t end_paddr = SAM_VECTOR_PADDR + vector_size;
|
||||
|
||||
/* REVISIT: Can really assert in this context */
|
||||
/* REVISIT: Cannot really assert in this context */
|
||||
|
||||
DEBUGASSERT (vector_size <= VECTOR_TABLE_SIZE);
|
||||
|
||||
@ -363,7 +362,7 @@ static void sam_copyvectorblock(void)
|
||||
* read only, then temparily mark the mapping write-able (non-buffered).
|
||||
*/
|
||||
|
||||
#if defined(NEED_VECTORMAP) && defined(CONFIG_PAGING)
|
||||
#ifdef CONFIG_PAGING
|
||||
sam_vectorpermissions(MMU_L2_VECTRWFLAGS);
|
||||
#endif
|
||||
|
||||
@ -387,7 +386,7 @@ static void sam_copyvectorblock(void)
|
||||
|
||||
/* Make the vectors read-only, cacheable again */
|
||||
|
||||
#if defined(NEED_VECTORMAP) && defined(CONFIG_PAGING)
|
||||
#if !defined(CONFIG_ARCH_LOWVECTORS) && defined(CONFIG_PAGING)
|
||||
sam_vectorpermissions(MMU_L2_VECTORFLAGS);
|
||||
#endif
|
||||
}
|
||||
@ -407,9 +406,7 @@ static void sam_copyvectorblock(void)
|
||||
|
||||
static inline void sam_wdtdisable(void)
|
||||
{
|
||||
#if 0 // REVISIT
|
||||
putreg32(WDT_MR_WDDIS, SAM_WDT_MR);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -501,13 +498,12 @@ void up_boot(void)
|
||||
|
||||
sam_vectormapping();
|
||||
|
||||
|
||||
/* The SRAM address hold the the page table is probably buffered. Make sure
|
||||
* that the modified contents of the page table are flushed into physical
|
||||
* memory.
|
||||
*/
|
||||
|
||||
cp15_clean_dcache_for_dma(VECTOR_L2_VBASE, VECTOR_L2_VBASE + PGTABLE_SIZE);
|
||||
cp15_clean_dcache(PGTABLE_BASE_VADDR, PGTABLE_BASE_VADDR + PGTABLE_SIZE);
|
||||
|
||||
#endif /* CONFIG_ARCH_ROMPGTABLE */
|
||||
|
||||
|
@ -283,14 +283,17 @@ void up_irqinitialize(void)
|
||||
|
||||
putreg32(AIC_WPMR_WPKEY | AIC_WPMR_WPEN, SAM_AIC_WPMR);
|
||||
|
||||
#ifndef CONFIG_ARCH_LOWVECTORS
|
||||
/* Set remap state 0:
|
||||
#ifdef CONFIG_ARCH_LOWVECTORS
|
||||
/* Set remap state 0. This is done late in the boot sequence. Any
|
||||
* exceptions taken before this point in time will be handled by the
|
||||
* ROM code, not by the NuttX interrupt since which was, up to this
|
||||
* point, uninitialized.
|
||||
*
|
||||
* Boot state: ROM is seen at address 0x00000000
|
||||
* Remap State 0: SRAM is seen at address 0x00000000 (through AHB slave
|
||||
* interface) instead of ROM.
|
||||
* Remap State 1: HEBI is seen at address 0x00000000 (through AHB slave
|
||||
* interface) instead of ROM for external boot.
|
||||
* Boot state: ROM is seen at address 0x00000000
|
||||
* Remap State 0: SRAM is seen at address 0x00000000 (through AHB slave
|
||||
* interface) instead of ROM.
|
||||
* Remap State 1: HEBI is seen at address 0x00000000 (through AHB slave
|
||||
* interface) instead of ROM for external boot.
|
||||
*
|
||||
* Here we are assuming that vectors reside in the lower end of ISRAM.
|
||||
* Hmmm... this probably does not matter since we will map a page to
|
||||
@ -299,6 +302,8 @@ void up_irqinitialize(void)
|
||||
|
||||
putreg32(MATRIX_MRCR_RCB0, SAM_MATRIX_MRCR); /* Enable remap */
|
||||
putreg32(AXIMX_REMAP_REMAP0, SAM_AXIMX_REMAP); /* Remap SRAM */
|
||||
|
||||
/* It might be wise to flush the instruction cache here */
|
||||
#endif
|
||||
|
||||
/* currents_regs is non-NULL only while processing an interrupt */
|
||||
|
Loading…
Reference in New Issue
Block a user