summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-08-02 11:11:57 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-08-02 11:11:57 -0600
commitec1d1b72fc58f664506ed4a8071cf8d48c7d9e64 (patch)
tree214105f4509e1d047775e3a38e5c4ad129e9f2e6
parent5b9a446aec5dfd38e1f4db42851137cf684d0d00 (diff)
downloadnuttx-ec1d1b72fc58f664506ed4a8071cf8d48c7d9e64.tar.gz
nuttx-ec1d1b72fc58f664506ed4a8071cf8d48c7d9e64.tar.bz2
nuttx-ec1d1b72fc58f664506ed4a8071cf8d48c7d9e64.zip
SAMA5: More MMU-related changes to properly initialize SDRAM
-rw-r--r--nuttx/ChangeLog11
-rw-r--r--nuttx/arch/arm/src/armv7-a/arm_mmu.c205
-rw-r--r--nuttx/arch/arm/src/armv7-a/cp15.h16
-rw-r--r--nuttx/arch/arm/src/armv7-a/mmu.h197
-rw-r--r--nuttx/arch/arm/src/sama5/Kconfig7
-rw-r--r--nuttx/arch/arm/src/sama5/Make.defs2
-rw-r--r--nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h25
-rw-r--r--nuttx/arch/arm/src/sama5/sam_allocateheap.c20
-rw-r--r--nuttx/arch/arm/src/sama5/sam_boot.c226
-rw-r--r--nuttx/configs/sama5d3x-ek/Kconfig17
-rw-r--r--nuttx/configs/sama5d3x-ek/hello/defconfig16
-rw-r--r--nuttx/configs/sama5d3x-ek/norboot/defconfig2
-rw-r--r--nuttx/configs/sama5d3x-ek/nsh/defconfig2
-rw-r--r--nuttx/configs/sama5d3x-ek/ostest/defconfig2
-rw-r--r--nuttx/configs/sama5d3x-ek/src/sam_boot.c12
-rw-r--r--nuttx/configs/sama5d3x-ek/src/sam_sdram.c139
-rw-r--r--nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h7
17 files changed, 682 insertions, 224 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 9d40b4253..4a72b867a 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -5257,4 +5257,15 @@
* nuttx/configs/sama5d3x-ek/src/sam_sdram.c: Add logic which
will (eventually) support the SDRAM on the SAMA5D3x-EK
board. Initial commit is untested and incomplete (2013-8-1).
+ * arch/arm/src/armv7-a/arm_mmu.c: Move some generic MMU logic
+ out of SAMA5-specific code into this share-able file (2013-8-2)
+ * arch/arm/src/armv7-a/mmu.h: Add inline functions to invalidate
+ a single TLB.
+ * arch/arm/src/sama5/sam_allocateheap.c and chip/sama5d3x_memorymap.h:
+ Add logic to handle signed overflow when a memory region is
+ greater than or equal to 2GB (2013-8-2).
+ * arch/arm/src/sama5/sam_boot.c: Boot logic now initially
+ configures DRAM as strongly ordered so that it can be initialized.
+ After initialization, the page table entries are modified so
+ that DRAM is fully cache-able (2018-8-2).
diff --git a/nuttx/arch/arm/src/armv7-a/arm_mmu.c b/nuttx/arch/arm/src/armv7-a/arm_mmu.c
new file mode 100644
index 000000000..b88ada551
--- /dev/null
+++ b/nuttx/arch/arm/src/armv7-a/arm_mmu.c
@@ -0,0 +1,205 @@
+/****************************************************************************
+ * arch/arm/src/armv7-a/arm_mmu.c
+ *
+ * Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+
+#include "cache.h"
+#include "mmu.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mmu_l1_setentry
+ *
+ * Description:
+ * Set a one level 1 translation table entry. Only a single L1 page table
+ * is supported.
+ *
+ * Input Paramters:
+ * paddr - The physical address to be mapped. Must be aligned to a 1MB
+ * address boundary
+ * vaddr - The virtual address to be mapped. Must be aligned to a 1MB
+ * address boundary
+ * mmuflags - The MMU flags to use in the mapping.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_ARCH_ROMPGTABLE
+void mmu_l1_setentry(uint32_t paddr, uint32_t vaddr, uint32_t mmuflags)
+{
+ uint32_t *l1table = (uint32_t*)PGTABLE_BASE_VADDR;
+ uint32_t index = vaddr >> 20;
+
+ /* Save the page table entry */
+
+ l1table[index] = (paddr | mmuflags);
+
+ /* Flush the data cache entry. Make sure that the modified contents
+ * of the page table are flushed into physical memory.
+ */
+
+ cp15_clean_dcache_bymva((uint32_t)&l1table[index]);
+
+ /* Invalidate the TLB cache associated with virtual address range */
+
+ mmu_invalidate_region(vaddr, 1024*1024);
+}
+#endif
+
+/****************************************************************************
+ * Name: mmu_l2_setentry
+ *
+ * Description:
+ * Set one small (4096B) entry in a level2 translation table.
+ *
+ * Input Parameters:
+ * l2vaddr - the virtual address of the beginning of the L2 translation
+ * table.
+ * paddr - The physical address to be mapped. Must be aligned to a 4KB
+ * address boundary
+ * vaddr - The virtual address to be mapped. Must be aligned to a 4KB
+ * address boundary
+ * mmuflags - The MMU flags to use in the mapping.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_ARCH_ROMPGTABLE
+void mmu_l2_setentry(uint32_t l2vaddr, uint32_t paddr, uint32_t vaddr,
+ uint32_t mmuflags)
+{
+ uint32_t *l2table = (uint32_t*)l2vaddr;
+ uint32_t index;
+
+ /* The table divides a 1Mb address space up into 256 entries, each
+ * corresponding to 4Kb of address space. The page table index is
+ * related to the offset from the beginning of 1Mb region.
+ */
+
+ index = (vaddr & 0x000ff000) >> 12;
+
+ /* Save the table entry */
+
+ l2table[index] = (paddr | mmuflags);
+
+ /* Flush the data cache entry. Make sure that the modified contents
+ * of the page table are flushed into physical memory.
+ */
+
+ cp15_clean_dcache_bymva((uint32_t)&l2table[index]);
+
+ /* Invalidate the TLB cache associated with virtual address range */
+
+ cp15_invalidate_tlb_bymva(vaddr);
+}
+#endif
+
+/****************************************************************************
+ * Name: mmu_l2_map_region
+ *
+ * Description:
+ * Set multiple level 1 translation table entries in order to map a
+ * region of memory.
+ *
+ * Input Parameters:
+ * mapping - Describes the mapping to be performed.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_ARCH_ROMPGTABLE
+void mmu_l2_map_region(const struct section_mapping_s *mapping)
+{
+ uint32_t paddr = mapping->physbase;
+ uint32_t vaddr = mapping->virtbase;
+ uint32_t mmuflags = mapping->mmuflags;
+ int i;
+
+ /* Loop, writting each mapping into the L1 page table */
+
+ for (i = 0; i < mapping->nsections; i++)
+ {
+ mmu_l1_setentry(paddr, vaddr, mmuflags);
+ paddr += SECTION_SIZE;
+ vaddr += SECTION_SIZE;
+ }
+}
+#endif
+
+/****************************************************************************
+ * Name: mmu_invalidate_region
+ *
+ * Description:
+ * Invalidate TLBs for a range of addresses (all 4KB aligned).
+ *
+ * Input Parameters:
+ * vaddr - The beginning of the region to invalidate.
+ * size - The size of the region in bytes to be invalidated.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_ARCH_ROMPGTABLE
+void mmu_invalidate_region(uint32_t vstart, size_t size)
+{
+ uint32_t vaddr = vstart & 0xfffff000;
+ uint32_t vend = vaddr + size;
+
+ /* Loop, writting each mapping into the L1 page table */
+
+ while (vaddr < vend)
+ {
+ cp15_invalidate_tlb_bymva(vaddr);
+ vaddr += 4096;
+ }
+}
+#endif
diff --git a/nuttx/arch/arm/src/armv7-a/cp15.h b/nuttx/arch/arm/src/armv7-a/cp15.h
index 49face4cd..193437419 100644
--- a/nuttx/arch/arm/src/armv7-a/cp15.h
+++ b/nuttx/arch/arm/src/armv7-a/cp15.h
@@ -147,14 +147,14 @@
#define CP15_DCCIMVAC(r) _CP15(0, r, c7, c14, 1)
#define CP15_DCCISW(r) _CP15(0, r, c7, c14, 2)
-#define CP15_TLBIALLIS(r) _CP15(0, r, c8, c3, 0) /* TLB maintenance operations */
-#define CP15_TLBIMVAIS(r) _CP15(0, r, c8, c3, 1)
-#define CP15_TLBIASIDIS(r) _CP15(0, r, c8, c3, 2)
-#define CP15_TLBIMVAAIS(r) _CP15(0, r, c8, c3, 3)
-#define CP15_TLBIALL(r,c) _CP15(0, r, c8, c, 0) /* CRm = c5, c6, or c7 */
-#define CP15_TLBIMVA(r,c) _CP15(0, r, c8, c, 1) /* CRm = c5, c6, or c7 */
-#define CP15_TLBIASID(r,c) _CP15(0, r, c8, c, 2) /* CRm = c5, c6, or c7 */
-#define CP15_TLBIMVAA(r,c) _CP15(0, r, c8, c, 3) /* CRm = c5, c6, or c7 */
+#define CP15_TLBIALLIS(r) _CP15(0, r, c8, c3, 0) /* Invalidate entire unified TLB Inner Shareable */
+#define CP15_TLBIMVAIS(r) _CP15(0, r, c8, c3, 1) /* Invalidate unified TLB entry by MVA and ASID, Inner Shareable */
+#define CP15_TLBIASIDIS(r) _CP15(0, r, c8, c3, 2) /* Invalidate unified TLB by ASID match Inner Shareable */
+#define CP15_TLBIMVAAIS(r) _CP15(0, r, c8, c3, 3) /* Invalidate unified TLB entry by MVA all ASID Inner Shareable */
+#define CP15_TLBIALL(r,c) _CP15(0, r, c8, c, 0) /* Invalidate entire instruction TLB. CRm = c5, c6, or c7 */
+#define CP15_TLBIMVA(r,c) _CP15(0, r, c8, c, 1) /* Invalidate instruction TLB entry by MVA and ASID. CRm = c5, c6, or c7 */
+#define CP15_TLBIASID(r,c) _CP15(0, r, c8, c, 2) /* Invalidate data TLB by ASID match. CRm = c5, c6, or c7 */
+#define CP15_TLBIMVAA(r,c) _CP15(0, r, c8, c, 3) /* Invalidate unified TLB entry by MVA and ASID. CRm = c5, c6, or c7 */
#define CP15_MCR(r) _CP15(0, r, c9, c12, 0) /* Performance Monitor Control Register */
#define CP15_PMCNTENSET(r) _CP15(0, r, c9, c12, 1) /* Count Enable Set Register */
diff --git a/nuttx/arch/arm/src/armv7-a/mmu.h b/nuttx/arch/arm/src/armv7-a/mmu.h
index 4cd7fad10..3067add52 100644
--- a/nuttx/arch/arm/src/armv7-a/mmu.h
+++ b/nuttx/arch/arm/src/armv7-a/mmu.h
@@ -49,6 +49,14 @@
* Included Files
************************************************************************************/
+#include <nuttx/config.h>
+
+#ifndef __ASSEMBLY__
+# include <sys/types.h>
+# include <stdint.h>
+# include "chip.h"
+#endif /* __ASSEMBLY__ */
+
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
@@ -490,7 +498,7 @@
* NMRR[23:22] = 0b11, Region is Write-Back, no Write-Allocate
*/
-#define PMD_STRONGLY_ORDER (0)
+#define PMD_STRONGLY_ORDERED (0)
#define PMD_DEVICE (PMD_SECT_B)
#define PMD_WRITE_THROUGH (PMD_SECT_C)
#define PMD_WRITE_BACK (PMD_SECT_B | PMD_SECT_C)
@@ -511,6 +519,9 @@
PMD_SECT_DOM(0))
#define MMU_IOFLAGS (PMD_TYPE_SECT | PMD_SECT_AP_RW1 | PMD_DEVICE | \
PMD_SECT_DOM(0) | PMD_SECT_XN)
+#define MMU_STRONGLY_ORDERED (PMD_TYPE_SECT | PMD_SECT_AP_RW1 | \
+ PMD_STRONGLY_ORDERED | PMD_SECT_DOM(0) | \
+ PMD_SECT_XN)
#define MMU_L1_VECTORFLAGS (PMD_TYPE_PTE | PMD_PTE_PXN | PMD_PTE_DOM(0))
#define MMU_L2_VECTORFLAGS (PTE_TYPE_SMALL | PTE_WRITE_THROUGH | PTE_AP_RW1)
@@ -788,6 +799,26 @@
#endif /* CONFIG_PAGING */
/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+#ifndef __ASSEMBLY__
+/* struct section_mapping_s describes the L1 mapping of a large region of memory
+ * consisting of one or more 1MB sections (nsections).
+ *
+ * All addresses must be aligned to 1MB address boundaries.
+ */
+
+struct section_mapping_s
+{
+ uint32_t physbase; /* Physical address of the region to be mapped */
+ uint32_t virtbase; /* Virtual address of the region to be mapped */
+ uint32_t mmuflags; /* MMU settings for the region (e.g., cache-able) */
+ uint32_t nsections; /* Number of mappings in the region */
+};
+#endif
+
+/************************************************************************************
* Assemby Macros
************************************************************************************/
@@ -814,7 +845,12 @@
* Name: cp15_invalidate_tlbs
*
* Description:
- * Invalidate TLBs
+ * Invalidate entire unified TLB
+ *
+ * The Invalidate entire TLB operations invalidate all unlocked entries in the
+ * TLB. The operation ignores the value in the register Rt specified by the MCR
+ * instruction that performs the operation. Software does not have to write a
+ * value to the register before issuing the MCR instruction.
*
* Inputs:
* None
@@ -826,6 +862,24 @@
.endm
/************************************************************************************
+ * Name: cp15_invalidate_tlb_bymva
+ *
+ * Description:
+ * Invalidate unified TLB entry by MVA all ASID Inner Shareable
+ *
+ * Inputs:
+ * vaddr - The virtual address to be invalidated
+ *
+ ************************************************************************************/
+
+ .macro cp15_invalidate_tlb_bymva, vaddr
+ dsb
+ mcr p15, 0, \vaddr, c8, c3, 3 /* TLBIMVAAIS */
+ dsb
+ isb
+ .endm
+
+/************************************************************************************
* Name: cp15_wrdacr
*
* Description:
@@ -1060,7 +1114,12 @@ static inline void cp15_disable_mmu(void)
* Name: cp15_invalidate_tlbs
*
* Description:
- * Invalidate TLBs
+ * Invalidate entire unified TLB
+ *
+ * The Invalidate entire TLB operations invalidate all unlocked entries in the
+ * TLB. The operation ignores the value in the register Rt specified by the MCR
+ * instruction that performs the operation. Software does not have to write a
+ * value to the register before issuing the MCR instruction.
*
* Inputs:
* None
@@ -1079,6 +1138,31 @@ static inline void cp15_invalidate_tlbs(void)
}
/************************************************************************************
+ * Name: cp15_invalidate_tlb_bymva
+ *
+ * Description:
+ * Invalidate unified TLB entry by MVA all ASID Inner Shareable
+ *
+ * Inputs:
+ * vaddr - The virtual address to be invalidated
+ *
+ ************************************************************************************/
+
+static inline void cp15_invalidate_tlb_bymva(uint32_t vaddr)
+{
+ __asm__ __volatile__
+ (
+ "\tdsb\n"
+ "\tmcr p15, 0, %0, c8, c3, 3\n" /* TLBIMVAAIS */
+ "\tdsb\n"
+ "\tisb\n"
+ :
+ : "r" (vaddr)
+ : "r1", "memory"
+ );
+}
+
+/************************************************************************************
* Name: cp15_wrdacr
*
* Description:
@@ -1144,6 +1228,61 @@ static inline void cp14_wrttb(unsigned int ttb)
);
}
+/*************************************************************************************
+ * Name: mmu_l1_getentry
+ *
+ * Description:
+ * Given a virtual address, return the valule of the corresponding L1 table entry.
+ *
+ * Input Paramters:
+ * vaddr - The virtual address to be mapped.
+ *
+ ************************************************************************************/
+
+#ifndef CONFIG_ARCH_ROMPGTABLE
+static inline uint32_t mmu_l1_getentry(uint32_t vaddr)
+{
+ uint32_t *l1table = (uint32_t*)PGTABLE_BASE_VADDR;
+ uint32_t index = vaddr >> 20;
+
+ /* Return the address of the page table entry */
+
+ return l1table[index];
+}
+#endif
+
+/*************************************************************************************
+ * Name: mmu_l2_getentry
+ *
+ * Description:
+ * Given a address of the beginning of an L2 page table and a virtual address,
+ * return the varlue of the corresponding L2 page table entry.
+ *
+ * Input Paramters:
+ * l2vaddr - The virtual address of the beginning of the L2 page table
+ * vaddr - The virtual address to be mapped.
+ *
+ ************************************************************************************/
+
+#ifndef CONFIG_ARCH_ROMPGTABLE
+static inline uint32_t mmu_l2_getentry(uint32_t l2vaddr, uint32_t vaddr)
+{
+ uint32_t *l2table = (uint32_t*)l2vaddr;
+ uint32_t index;
+
+ /* The table divides a 1Mb address space up into 256 entries, each
+ * corresponding to 4Kb of address space. The page table index is
+ * related to the offset from the beginning of 1Mb region.
+ */
+
+ index = (vaddr & 0x000ff000) >> 12;
+
+ /* Return the address of the page table entry */
+
+ return l2table[index];
+}
+#endif
+
#endif /* __ASSEMBLY__ */
/************************************************************************************
@@ -1162,6 +1301,58 @@ extern "C" {
#define EXTERN extern
#endif
+/************************************************************************************
+ * Name: mmu_l1_setentry
+ *
+ * Description:
+ * Set a one level 1 translation table entry. Only a single L1 page table is
+ * supported.
+ *
+ * Input Paramters:
+ * paddr - The physical address to be mapped. Must be aligned to a 1MB address
+ * boundary
+ * vaddr - The virtual address to be mapped. Must be aligned to a 1MB address
+ * boundary
+ * mmuflags - The MMU flags to use in the mapping.
+ *
+ ************************************************************************************/
+
+#ifndef CONFIG_ARCH_ROMPGTABLE
+void mmu_l1_setentry(uint32_t paddr, uint32_t vaddr, uint32_t mmuflags);
+#endif
+
+/************************************************************************************
+ * Name: mmu_l2_map_region
+ *
+ * Description:
+ * Set multiple level 1 translation table entries in order to map a region of
+ * memory.
+ *
+ * Input Parameters:
+ * mapping - Describes the mapping to be performed.
+ *
+ ************************************************************************************/
+
+#ifndef CONFIG_ARCH_ROMPGTABLE
+void mmu_l2_map_region(const struct section_mapping_s *mapping);
+#endif
+
+/****************************************************************************
+ * Name: mmu_invalidate_region
+ *
+ * Description:
+ * Invalidate TLBs for a range of addresses (all 4KB aligned).
+ *
+ * Input Parameters:
+ * vaddr - The beginning of the region to invalidate.
+ * size - The size of the region in bytes to be invalidated.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_ARCH_ROMPGTABLE
+void mmu_invalidate_region(uint32_t vstart, size_t size);
+#endif
+
#undef EXTERN
#ifdef __cplusplus
}
diff --git a/nuttx/arch/arm/src/sama5/Kconfig b/nuttx/arch/arm/src/sama5/Kconfig
index 407d68772..68fcb3b08 100644
--- a/nuttx/arch/arm/src/sama5/Kconfig
+++ b/nuttx/arch/arm/src/sama5/Kconfig
@@ -44,7 +44,7 @@ config SAMA5_WDT
default n
config SAMA5_HSMC
- bool "Multi-bit ECC Interrupt (HSMC)"
+ bool "Static Memory Controller (HSMC)"
default n
config SAMA5_SMD
@@ -241,6 +241,7 @@ menu "External Memory Configuration"
config SAMA5_DDRCS
bool "External DDR-SDRAM Memory"
default n
+ depends on SAMA5_MPDDRC
---help---
Build in support for DDR-SDRAM memory resources.
@@ -270,6 +271,7 @@ endif # SAMA5_DDRCS
config SAMA5_EBICS0
bool "External CS0 Memory"
default n
+ depends on SAMA5_HSMC
---help---
Build in support for memory resources in the chip select 0 (CS0)
memory region.
@@ -318,6 +320,7 @@ endif # SAMA5_EBICS0
config SAMA5_EBICS1
bool "External CS1 Memory"
default n
+ depends on SAMA5_HSMC
---help---
Build in support for memory resources in the chip select 1 (CS1)
memory region.
@@ -365,6 +368,7 @@ endif # SAMA5_EBICS1
config SAMA5_EBICS2
bool "External CS2 Memory"
+ depends on SAMA5_HSMC
default n
---help---
Build in support for memory resources in the chip select 2 (CS2)
@@ -414,6 +418,7 @@ endif # SAMA5_EBICS2
config SAMA5_EBICS3
bool "External CS3 Memory"
default n
+ depends on SAMA5_HSMC
---help---
Build in support for memory resources in the chip select 3 (CS3)
memory region.
diff --git a/nuttx/arch/arm/src/sama5/Make.defs b/nuttx/arch/arm/src/sama5/Make.defs
index c3a65ef47..176230cf6 100644
--- a/nuttx/arch/arm/src/sama5/Make.defs
+++ b/nuttx/arch/arm/src/sama5/Make.defs
@@ -62,7 +62,7 @@ CMN_CSRCS += up_mdelay.c up_udelay.c
CMN_CSRCS += up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c
CMN_CSRCS += arm_assert.c arm_blocktask.c arm_copyfullstate.c arm_dataabort.c
-CMN_CSRCS += arm_doirq.c arm_initialstate.c arm_prefetchabort.c
+CMN_CSRCS += arm_doirq.c arm_initialstate.c arm_mmu.c arm_prefetchabort.c
CMN_CSRCS += arm_releasepending.c arm_reprioritizertr.c
CMN_CSRCS += arm_schedulesigaction.c arm_sigdeliver.c arm_syscall.c
CMN_CSRCS += arm_unblocktask.c arm_undefinedinsn.c
diff --git a/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h b/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h
index abb40b63a..b3ba2deff 100644
--- a/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h
+++ b/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h
@@ -46,6 +46,13 @@
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
+/* Decimal configuration values may exceed 2Gb and, hence, overflow to negative
+ * values unless we force them to unsigned long:
+ */
+
+#define __CONCAT(a,b) a ## b
+#define MKULONG(a) __CONCAT(a,ul)
+
/* Overview:
*
* SAMA5 Physical (unmapped) Memory Map
@@ -189,6 +196,14 @@
#define SAM_PERIPHB_SIZE (272*1024) /* 0xf8000000-0xf8043fff: Internal Peripherals */
#define SAM_SYSC_SIZE (1*1024*1024) /* 0xfff00000-0x0ffffedf: Internal Peripherals */
+/* Force configured sizes that might exceed 2GB to be unsigned long */
+
+#define SAMA5_EBICS0_SIZE MKULONG(CONFIG_SAMA5_EBICS0_SIZE)
+#define SAMA5_DDRCS_SIZE MKULONG(CONFIG_SAMA5_DDRCS_SIZE)
+#define SAMA5_EBICS1_SIZE MKULONG(CONFIG_SAMA5_EBICS1_SIZE)
+#define SAMA5_EBICS2_SIZE MKULONG(CONFIG_SAMA5_EBICS2_SIZE)
+#define SAMA5_EBICS3_SIZE MKULONG(CONFIG_SAMA5_EBICS3_SIZE)
+
/* Convert size in bytes to number of sections (in Mb). */
#define _NSECTIONS(b) (((b)+0x000fffff) >> 20)
@@ -212,11 +227,11 @@
#define SAM_AXIMX_NSECTIONS _NSECTIONS(SAM_AXIMX_SIZE)
#define SAM_DAP_NSECTIONS _NSECTIONS(SAM_DAP_SIZE)
-#define SAM_EBICS0_NSECTIONS _NSECTIONS(CONFIG_SAMA5_EBICS0_SIZE)
-#define SAM_DDRCS_NSECTIONS _NSECTIONS(CONFIG_SAMA5_DDRCS_SIZE)
-#define SAM_EBICS1_NSECTIONS _NSECTIONS(CONFIG_SAMA5_EBICS1_SIZE)
-#define SAM_EBICS2_NSECTIONS _NSECTIONS(CONFIG_SAMA5_EBICS2_SIZE)
-#define SAM_EBICS3_NSECTIONS _NSECTIONS(CONFIG_SAMA5_EBICS3_SIZE)
+#define SAM_EBICS0_NSECTIONS _NSECTIONS(SAMA5_EBICS0_SIZE)
+#define SAM_DDRCS_NSECTIONS _NSECTIONS(SAMA5_DDRCS_SIZE)
+#define SAM_EBICS1_NSECTIONS _NSECTIONS(SAMA5_EBICS1_SIZE)
+#define SAM_EBICS2_NSECTIONS _NSECTIONS(SAMA5_EBICS2_SIZE)
+#define SAM_EBICS3_NSECTIONS _NSECTIONS(SAMA5_EBICS3_SIZE)
#define SAM_NFCCR_NSECTIONS _NSECTIONS(SAM_NFCCR_SIZE)
#define SAM_PERIPHA_NSECTIONS _NSECTIONS(SAM_PERIPHA_SIZE)
diff --git a/nuttx/arch/arm/src/sama5/sam_allocateheap.c b/nuttx/arch/arm/src/sama5/sam_allocateheap.c
index 7d68f15fb..a87aa50ab 100644
--- a/nuttx/arch/arm/src/sama5/sam_allocateheap.c
+++ b/nuttx/arch/arm/src/sama5/sam_allocateheap.c
@@ -45,6 +45,7 @@
#include <debug.h>
#include <nuttx/arch.h>
+#include <nuttx/kmalloc.h>
#include <nuttx/userspace.h>
#include <arch/board/board.h>
@@ -242,11 +243,11 @@ void up_addregion(void)
size_t size;
#ifdef CONFIG_SAMA5_ISRAM_HEAP
-#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+ size = SAM_ISRAM0_SIZE + SAM_ISRAM1_SIZE;
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
/* Allow user-mode access to the ISRAM heap */
- size = SAM_ISRAM0_SIZE + SAM_ISRAM1_SIZE;
sam_uheap((uintptr_t)SAM_ISRAM0_VADDR, size);
#endif
@@ -261,10 +262,11 @@ void up_addregion(void)
#ifdef CONFIG_SAMA5_DDRCS_HEAP
if (nregions > 0)
{
+ size = SAMA5_DDRCS_SIZE;
+
#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
/* Allow user-mode access to the ISRAM heap */
- size = CONFIG_SAMA5_DDRCS_SIZE;
sam_uheap((uintptr_t)SAM_DDRCS_VSECTION, size);
#endif
@@ -285,10 +287,11 @@ void up_addregion(void)
#ifdef SAMA5_EBICS0_HEAP
if (nregions > 0)
{
+ size = SAMA5_EBICS0_SIZE;
+
#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
/* Allow user-mode access to the ISRAM heap */
- size = CONFIG_SAMA5_EBICS0_SIZE;
sam_uheap((uintptr_t)SAM_EBICS0_VSECTION, size);
#endif
@@ -309,10 +312,11 @@ void up_addregion(void)
#ifdef SAMA5_EBICS1_HEAP
if (nregions > 0)
{
+ size = SAMA5_EBICS1_SIZE;
+
#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
/* Allow user-mode access to the ISRAM heap */
- size = CONFIG_SAMA5_EBICS1_SIZE;
sam_uheap((uintptr_t)SAM_EBICS1_VSECTION, size);
#endif
@@ -333,10 +337,11 @@ void up_addregion(void)
#ifdef SAMA5_EBICS2_HEAP
if (nregions > 0)
{
+ size = SAMA5_EBICS2_SIZE;
+
#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
/* Allow user-mode access to the ISRAM heap */
- size = CONFIG_SAMA5_EBICS2_SIZE;
sam_uheap((uintptr_t)SAM_EBICS2_VSECTION, size);
#endif
@@ -357,10 +362,11 @@ void up_addregion(void)
#ifdef SAMA5_EBICS3_HEAP
if (nregions > 0)
{
+ size = SAMA5_EBICS3_SIZE;
+
#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
/* Allow user-mode access to the ISRAM heap */
- size = CONFIG_SAMA5_EBICS3_SIZE;
sam_uheap((uintptr_t)SAM_EBICS3_VSECTION, size);
#endif
diff --git a/nuttx/arch/arm/src/sama5/sam_boot.c b/nuttx/arch/arm/src/sama5/sam_boot.c
index 995ee376b..075e79593 100644
--- a/nuttx/arch/arm/src/sama5/sam_boot.c
+++ b/nuttx/arch/arm/src/sama5/sam_boot.c
@@ -51,7 +51,6 @@
#include "chip.h"
#include "arm.h"
#include "mmu.h"
-#include "cache.h"
#include "fpu.h"
#include "up_internal.h"
#include "up_arch.h"
@@ -89,14 +88,6 @@
* Private Types
****************************************************************************/
-struct section_mapping_s
-{
- uint32_t physbase; /* Physical address of the region to be mapped */
- uint32_t virtbase; /* Virtual address of the region to be mapped */
- uint32_t mmuflags; /* MMU settings for the region (e.g., cache-able) */
- uint32_t nsections; /* Number of mappings in the region */
-};
-
/****************************************************************************
* Public Variables
****************************************************************************/
@@ -142,140 +133,128 @@ static const struct section_mapping_s section_mapping[] =
*/
#if defined(CONFIG_ARCH_LOWVECTORS) && !defined(CONFIG_SAMA5_BOOT_ISRAM)
- { CONFIG_FLASH_VSTART, 0x00000000, MMU_ROMFLAGS, 1},
+ { CONFIG_FLASH_VSTART, 0x00000000,
+ MMU_ROMFLAGS, 1 },
#else
- { SAM_BOOTMEM_PSECTION, SAM_BOOTMEM_VSECTION,
- SAM_BOOTMEM_MMUFLAGS, SAM_BOOTMEM_NSECTIONS},
+ { 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,
- SAM_NFCSRAM_MMUFLAGS, SAM_NFCSRAM_NSECTIONS},
+ { SAM_ROM_PSECTION, SAM_ROM_VSECTION,
+ SAM_ROM_MMUFLAGS, SAM_ROM_NSECTIONS },
+ { SAM_NFCSRAM_PSECTION, SAM_NFCSRAM_VSECTION,
+ SAM_NFCSRAM_MMUFLAGS, SAM_NFCSRAM_NSECTIONS },
#ifndef CONFIG_PAGING /* Internal SRAM is already fully mapped */
- { SAM_ISRAM_PSECTION, SAM_ISRAM_VSECTION,
- SAM_ISRAM_MMUFLAGS, SAM_ISRAM_NSECTIONS},
+ { SAM_ISRAM_PSECTION, SAM_ISRAM_VSECTION,
+ SAM_ISRAM_MMUFLAGS, SAM_ISRAM_NSECTIONS },
#endif
- { SAM_SMD_PSECTION, SAM_SMD_VSECTION,
- SAM_SMD_MMUFLAGS, SAM_SMD_NSECTIONS},
+ { SAM_SMD_PSECTION, SAM_SMD_VSECTION,
+ SAM_SMD_MMUFLAGS, SAM_SMD_NSECTIONS },
{ SAM_UDPHSRAM_PSECTION, SAM_UDPHSRAM_VSECTION,
- SAM_UDPHSRAM_MMUFLAGS, SAM_UDPHSRAM_NSECTIONS},
- { SAM_UHPOHCI_PSECTION, SAM_UHPOHCI_VSECTION,
- SAM_UHPOHCI_MMUFLAGS, SAM_UHPOHCI_NSECTIONS},
- { SAM_UHPEHCI_PSECTION, SAM_UHPEHCI_VSECTION,
- SAM_UHPEHCI_MMUFLAGS, SAM_UHPEHCI_NSECTIONS},
- { SAM_AXIMX_PSECTION, SAM_AXIMX_VSECTION,
- SAM_AXIMX_MMUFLAGS, SAM_AXIMX_NSECTIONS},
- { SAM_DAP_PSECTION, SAM_DAP_VSECTION,
- SAM_DAP_MMUFLAGS, SAM_DAP_NSECTIONS},
-
-/* SAMA5 External Memories */
+ SAM_UDPHSRAM_MMUFLAGS, SAM_UDPHSRAM_NSECTIONS },
+ { SAM_UHPOHCI_PSECTION, SAM_UHPOHCI_VSECTION,
+ SAM_UHPOHCI_MMUFLAGS, SAM_UHPOHCI_NSECTIONS },
+ { SAM_UHPEHCI_PSECTION, SAM_UHPEHCI_VSECTION,
+ SAM_UHPEHCI_MMUFLAGS, SAM_UHPEHCI_NSECTIONS },
+ { SAM_AXIMX_PSECTION, SAM_AXIMX_VSECTION,
+ SAM_AXIMX_MMUFLAGS, SAM_AXIMX_NSECTIONS },
+ { SAM_DAP_PSECTION, SAM_DAP_VSECTION,
+ SAM_DAP_MMUFLAGS, SAM_DAP_NSECTIONS },
+
+/* SAMA5 CS0 External Memories */
#ifdef CONFIG_SAMA5_EBICS0
{ SAM_EBICS0_PSECTION, SAM_EBICS0_VSECTION,
- SAM_EBICS0_MMUFLAGS, SAM_EBICS0_NSECTIONS},
+ SAM_EBICS0_MMUFLAGS, SAM_EBICS0_NSECTIONS },
#endif
+
+/* SAMA5 External SDRAM Memory. The SDRAM is not usable until it has been
+ * initialized. If we are running out of SDRAM now, we can assume that some
+ * second level boot loader has properly configured SRAM for us. In that
+ * case, we set the the MMU flags for the final, fully cache-able state.
+ *
+ * If we are running from ISRAM or NOR flash, then we will need to configure
+ * the SDRAM ourselves. In this case, we set the MMU flags to the strongly
+ * ordered, non-cacheable state. We need this direct access to SDRAM in
+ * order to configure it. Once SDRAM has been initialized, it will be re-
+ * configured in its final state.
+ */
+
#ifdef CONFIG_SAMA5_DDRCS
- { SAM_DDRCS_PSECTION, SAM_DDRCS_VSECTION,
- SAM_DDRCS_MMUFLAGS, SAM_DDRCS_NSECTIONS},
+#ifdef CONFIG_SAMA5_BOOT_SDRAM
+ { SAM_DDRCS_PSECTION, SAM_DDRCS_VSECTION,
+ MMU_STRONGLY_ORDERED, SAM_DDRCS_NSECTIONS },
+#else
+ { SAM_DDRCS_PSECTION, SAM_DDRCS_VSECTION,
+ SAM_DDRCS_MMUFLAGS, SAM_DDRCS_NSECTIONS },
+#endif
#endif
+
+/* SAMA5 CS1-3 External Memories */
+
#ifdef CONFIG_SAMA5_EBICS1
- { SAM_EBICS1_PSECTION, SAM_EBICS1_VSECTION,
- SAM_EBICS1_MMUFLAGS, SAM_EBICS1_NSECTIONS},
+ { SAM_EBICS1_PSECTION, SAM_EBICS1_VSECTION,
+ SAM_EBICS1_MMUFLAGS, SAM_EBICS1_NSECTIONS },
#endif
#ifdef CONFIG_SAMA5_EBICS2
- { SAM_EBICS2_PSECTION, SAM_EBICS2_VSECTION,
- SAM_EBICS2_MMUFLAGS, SAM_EBICS2_NSECTIONS},
+ { SAM_EBICS2_PSECTION, SAM_EBICS2_VSECTION,
+ SAM_EBICS2_MMUFLAGS, SAM_EBICS2_NSECTIONS },
#endif
#ifdef CONFIG_SAMA5_EBICS3
- { SAM_EBICS3_PSECTION, SAM_EBICS3_VSECTION,
- SAM_EBICS3_MMUFLAGS, SAM_EBICS3_NSECTIONS},
+ { SAM_EBICS3_PSECTION, SAM_EBICS3_VSECTION,
+ SAM_EBICS3_MMUFLAGS, SAM_EBICS3_NSECTIONS },
#endif
#ifdef CONFIG_SAMA5_NFCCR
- { SAM_NFCCR_PSECTION, SAM_NFCCR_VSECTION,
- SAM_NFCCR_MMUFLAGS, SAM_NFCCR_NSECTIONS},
+ { SAM_NFCCR_PSECTION, SAM_NFCCR_VSECTION,
+ SAM_NFCCR_MMUFLAGS, SAM_NFCCR_NSECTIONS },
#endif
/* SAMA5 Internal Peripherals */
{ SAM_PERIPHA_PSECTION, SAM_PERIPHA_VSECTION,
- SAM_PERIPHA_MMUFLAGS, SAM_PERIPHA_NSECTIONS},
+ SAM_PERIPHA_MMUFLAGS, SAM_PERIPHA_NSECTIONS },
{ SAM_PERIPHB_PSECTION, SAM_PERIPHB_VSECTION,
- SAM_PERIPHB_MMUFLAGS, SAM_PERIPHB_NSECTIONS},
- { SAM_SYSC_PSECTION, SAM_SYSC_VSECTION,
- SAM_SYSC_MMUFLAGS, SAM_SYSC_NSECTIONS},
+ SAM_PERIPHB_MMUFLAGS, SAM_PERIPHB_NSECTIONS },
+ { SAM_SYSC_PSECTION, SAM_SYSC_VSECTION,
+ SAM_SYSC_MMUFLAGS, SAM_SYSC_NSECTIONS },
};
#define NMAPPINGS (sizeof(section_mapping) / sizeof(struct section_mapping_s))
#endif
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: sam_setl1entry
- *
- * Description:
- * Set a level 1 translation table entry.
- *
- ****************************************************************************/
+/* SAMA5 External SDRAM Memory. Final configuration. The SDRAM was
+ * configured in a temporary state to support low-level ininitialization.
+ * After the SDRAM has been fully initialized, this structure is used to
+ * set the SDRM in its final, fully cache-able state.
+ */
-#ifndef CONFIG_ARCH_ROMPGTABLE
-static inline void sam_setl1entry(uint32_t paddr, uint32_t vaddr,
- uint32_t mmuflags)
+#if defined(CONFIG_SAMA5_DDRCS) && !defined(CONFIG_SAMA5_BOOT_SDRAM)
+static const struct section_mapping_s operational_mapping =
{
- uint32_t *pgtable = (uint32_t*)PGTABLE_BASE_VADDR;
- uint32_t index = vaddr >> 20;
-
- /* Save the page table entry */
-
- pgtable[index] = (paddr | mmuflags);
-}
+ SAM_DDRCS_PSECTION, SAM_DDRCS_VSECTION,
+ SAM_DDRCS_MMUFLAGS, SAM_DDRCS_NSECTIONS
+};
#endif
/****************************************************************************
- * Name: sam_setl2smallentry
+ * Private Functions
****************************************************************************/
-static inline void sam_setl2smallentry(uint32_t ctabvaddr, uint32_t paddr,
- uint32_t vaddr, uint32_t mmuflags)
-{
- uint32_t *ctable = (uint32_t*)ctabvaddr;
- uint32_t index;
-
- /* The table divides a 1Mb address space up into 256 entries, each
- * corresponding to 4Kb of address space. The page table index is
- * related to the offset from the beginning of 1Mb region.
- */
-
- index = (vaddr & 0x000ff000) >> 12;
-
- /* Save the table entry */
-
- ctable[index] = (paddr | mmuflags);
-}
-
/****************************************************************************
* Name: sam_setupmappings
+ *
+ * Description
+ * Map all of the memory regions defined in section_mapping[]
+ *
****************************************************************************/
#ifndef CONFIG_ARCH_ROMPGTABLE
-static void sam_setupmappings(void)
+static inline void sam_setupmappings(void)
{
- int i, j;
+ int i;
for (i = 0; i < NMAPPINGS; i++)
{
- uint32_t sect_paddr = section_mapping[i].physbase;
- uint32_t sect_vaddr = section_mapping[i].virtbase;
- uint32_t mmuflags = section_mapping[i].mmuflags;
-
- for (j = 0; j < section_mapping[i].nsections; j++)
- {
- sam_setl1entry(sect_paddr, sect_vaddr, mmuflags);
- sect_paddr += SECTION_SIZE;
- sect_vaddr += SECTION_SIZE;
- }
+ mmu_l2_map_region(&section_mapping[i]);
}
}
#endif
@@ -290,16 +269,17 @@ static void sam_setupmappings(void)
#if !defined(CONFIG_ARCH_ROMPGTABLE) && defined(CONFIG_ARCH_LOWVECTORS) && \
defined(CONFIG_PAGING)
-static void sam_vectorpermissions(uint32_t mmuflags)
+static void sam_vectorpermissions(uint32_t mmuflags)
{
/* The PTE for the beginning of ISRAM is at the base of the L2 page table */
- uint32_t *ptr = (uint32_t*)PG_L2_VECT_VADDR;
- uint32_t pte;
+ uint32_t pte = mmu_l2_getentry(PG_L2_VECT_VADDR, 0);
- /* The pte might be zero the first time this function is called. */
+ /* String the MMU flags from the page table entry.
+ *
+ * The pte might be zero the first time this function is called.
+ */
- pte = *ptr;
if (pte == 0)
{
pte = PG_VECT_PBASE;
@@ -309,13 +289,9 @@ static void sam_vectorpermissions(uint32_t mmuflags)
pte &= PG_L1_PADDRMASK;
}
- /* Update the MMU flags and save */
-
- *ptr = pte | mmuflags;
-
- /* Invalid the TLB for this address */
+ /* Update the page table entry with the MMU flags and save */
- tlb_invalidate_single(PG_L2_VECT_VADDR);
+ mmu_l2_setentry(PG_L2_VECT_VADDR, pte, 0, mmuflags);
}
#endif
@@ -352,17 +328,17 @@ static void sam_vectormapping(void)
while (vector_paddr < end_paddr)
{
- sam_setl2smallentry(VECTOR_L2_VBASE, vector_paddr, vector_vaddr,
- MMU_L2_VECTORFLAGS);
+ mmu_l2_setentry(VECTOR_L2_VBASE, vector_paddr, vector_vaddr,
+ MMU_L2_VECTORFLAGS);
vector_paddr += 4096;
vector_vaddr += 4096;
}
/* Now set the level 1 descriptor to refer to the level 2 page table. */
- sam_setl1entry(VECTOR_L2_PBASE & PMD_PTE_PADDR_MASK,
- SAM_VECTOR_VADDR & PMD_PTE_PADDR_MASK,
- MMU_L1_VECTORFLAGS);
+ mmu_l1_setentry(VECTOR_L2_PBASE & PMD_PTE_PADDR_MASK,
+ SAM_VECTOR_VADDR & PMD_PTE_PADDR_MASK,
+ MMU_L1_VECTORFLAGS);
}
#else
/* No vector remap */
@@ -527,13 +503,6 @@ 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(PGTABLE_BASE_VADDR, PGTABLE_BASE_VADDR + PGTABLE_SIZE);
-
#endif /* CONFIG_ARCH_ROMPGTABLE */
/* Setup up vector block. _vector_start and _vector_end are exported from
@@ -578,7 +547,20 @@ void up_boot(void)
sam_userspace();
#endif
- /* Perform board-specific initialization */
+ /* Perform board-specific initialization, This must include:
+ *
+ * - Initialization of board-specific memory resources (e.g., SDRAM)
+ * - Configuration of board specific resources (GPIOs, LEDs, etc).
+ */
sam_boardinitialize();
+
+ /* SDRAM was configured in a temporary state to support low-level
+ * ininitialization. Now that the SDRAM has been fully initialized,
+ * we can reconfigure the SDRAM in its final, fully cache-able state.
+ */
+
+#if defined(CONFIG_SAMA5_DDRCS) && !defined(CONFIG_SAMA5_BOOT_SDRAM)
+ mmu_l2_map_region(&operational_mapping);
+#endif
}
diff --git a/nuttx/configs/sama5d3x-ek/Kconfig b/nuttx/configs/sama5d3x-ek/Kconfig
index 5f977fe16..301b272e1 100644
--- a/nuttx/configs/sama5d3x-ek/Kconfig
+++ b/nuttx/configs/sama5d3x-ek/Kconfig
@@ -5,6 +5,23 @@
if ARCH_BOARD_SAMA5D3X_EK
+choice
+ prompt "SAMA5D3x-EK DRAM Type"
+ default SAMA5_MT47H128M16RT
+ depends on SAMA5_DDRCS
+
+config SAMA5_MT47H128M16RT
+ bool "MT47H128M16RT"
+ ---help---
+ Micron 2Gbit x16 DDR2-1066 128Mb
+
+config SAMA5_MT47H64M16HR
+ bool "MT47H64M16HR"
+ ---help---
+ Micron 1Gbit x16 DDR2-800 64Mb
+
+endchoice
+
config SAMA5_NOR_MAIN
bool "Build nor_main"
default n
diff --git a/nuttx/configs/sama5d3x-ek/hello/defconfig b/nuttx/configs/sama5d3x-ek/hello/defconfig
index b047352fa..2166fc65f 100644
--- a/nuttx/configs/sama5d3x-ek/hello/defconfig
+++ b/nuttx/configs/sama5d3x-ek/hello/defconfig
@@ -167,11 +167,6 @@ CONFIG_SAMA5_USART1=y
#
# External Memory Configuration
#
-# CONFIG_SAMA5_DDRCS is not set
-# CONFIG_SAMA5_EBICS0 is not set
-# CONFIG_SAMA5_EBICS1 is not set
-# CONFIG_SAMA5_EBICS2 is not set
-# CONFIG_SAMA5_EBICS3 is not set
CONFIG_SAMA5_BOOT_ISRAM=y
#
@@ -199,9 +194,6 @@ CONFIG_ARCH_STACKDUMP=y
#
CONFIG_BOARD_LOOPSPERMSEC=49341
# CONFIG_ARCH_CALIBRATION is not set
-CONFIG_RAM_START=0x00300000
-CONFIG_RAM_VSTART=0x00300000
-CONFIG_RAM_SIZE=114688
CONFIG_ARCH_HAVE_INTERRUPTSTACK=y
CONFIG_ARCH_INTERRUPTSTACK=0
@@ -215,6 +207,13 @@ CONFIG_BOOT_RUNFROMISRAM=y
# CONFIG_BOOT_COPYTORAM is not set
#
+# Boot Memory Configuration
+#
+CONFIG_RAM_START=0x00300000
+CONFIG_RAM_VSTART=0x00300000
+CONFIG_RAM_SIZE=114688
+
+#
# Board Selection
#
CONFIG_ARCH_BOARD_SAMA5D3X_EK=y
@@ -233,6 +232,7 @@ CONFIG_ARCH_HAVE_IRQBUTTONS=y
#
# Board-Specific Options
#
+# CONFIG_SAMA5_NOR_MAIN is not set
#
# RTOS Features
diff --git a/nuttx/configs/sama5d3x-ek/norboot/defconfig b/nuttx/configs/sama5d3x-ek/norboot/defconfig
index 92cb7bbc0..1537ef783 100644
--- a/nuttx/configs/sama5d3x-ek/norboot/defconfig
+++ b/nuttx/configs/sama5d3x-ek/norboot/defconfig
@@ -123,7 +123,7 @@ CONFIG_ARCH_CHIP_ATSAMA5D33=y
# CONFIG_SAMA5_DBGU is not set
# CONFIG_SAMA5_PIT is not set
# CONFIG_SAMA5_WDT is not set
-# CONFIG_SAMA5_HSMC is not set
+CONFIG_SAMA5_HSMC=y
# CONFIG_SAMA5_SMD is not set
# CONFIG_SAMA5_UART0 is not set
# CONFIG_SAMA5_UART1 is not set
diff --git a/nuttx/configs/sama5d3x-ek/nsh/defconfig b/nuttx/configs/sama5d3x-ek/nsh/defconfig
index adeca9925..0d76d8d4a 100644
--- a/nuttx/configs/sama5d3x-ek/nsh/defconfig
+++ b/nuttx/configs/sama5d3x-ek/nsh/defconfig
@@ -123,7 +123,7 @@ CONFIG_ARCH_CHIP_ATSAMA5D33=y
# CONFIG_SAMA5_DBGU is not set
# CONFIG_SAMA5_PIT is not set
# CONFIG_SAMA5_WDT is not set
-# CONFIG_SAMA5_HSMC is not set
+CONFIG_SAMA5_HSMC=y
# CONFIG_SAMA5_SMD is not set
# CONFIG_SAMA5_UART0 is not set
# CONFIG_SAMA5_UART1 is not set
diff --git a/nuttx/configs/sama5d3x-ek/ostest/defconfig b/nuttx/configs/sama5d3x-ek/ostest/defconfig
index 8262ee7dd..30a80cb09 100644
--- a/nuttx/configs/sama5d3x-ek/ostest/defconfig
+++ b/nuttx/configs/sama5d3x-ek/ostest/defconfig
@@ -123,7 +123,7 @@ CONFIG_ARCH_CHIP_ATSAMA5D33=y
# CONFIG_SAMA5_DBGU is not set
# CONFIG_SAMA5_PIT is not set
# CONFIG_SAMA5_WDT is not set
-# CONFIG_SAMA5_HSMC is not set
+CONFIG_SAMA5_HSMC=y
# CONFIG_SAMA5_SMD is not set
# CONFIG_SAMA5_UART0 is not set
# CONFIG_SAMA5_UART1 is not set
diff --git a/nuttx/configs/sama5d3x-ek/src/sam_boot.c b/nuttx/configs/sama5d3x-ek/src/sam_boot.c
index fd21a6564..f68cae4b4 100644
--- a/nuttx/configs/sama5d3x-ek/src/sam_boot.c
+++ b/nuttx/configs/sama5d3x-ek/src/sam_boot.c
@@ -67,6 +67,18 @@
void sam_boardinitialize(void)
{
+#if defined(CONFIG_SAMA5_DDRCS) && !defined(CONFIG_SAMA5_BOOT_SDRAM)
+
+ /* Configure SDRAM if (1) SDRAM has been enalbled in the NuttX configuration and
+ * (2) if we are not currently running out of SDRAM. If we are now running out
+ * of SDRAM then we have to assume that some second level bootloader has properly
+ * configured SDRAM for our use.
+ */
+
+ sam_sdram_config();
+
+#endif
+
#ifdef CONFIG_ARCH_LEDS
/* Configure on-board LEDs if LED support has been selected. */
diff --git a/nuttx/configs/sama5d3x-ek/src/sam_sdram.c b/nuttx/configs/sama5d3x-ek/src/sam_sdram.c
index 71b9748dd..ce1fa1e04 100644
--- a/nuttx/configs/sama5d3x-ek/src/sam_sdram.c
+++ b/nuttx/configs/sama5d3x-ek/src/sam_sdram.c
@@ -51,36 +51,50 @@
#include "up_arch.h"
#include "sam_periphclks.h"
-#incldue "chip/sam_memorymap.h"
+#include "chip/sam_memorymap.h"
#include "chip/sam_pmc.h"
#include "chip/sam_sfr.h"
+#include "chip/sam_mpddrc.h"
#include "sama5d3x-ek.h"
/* This file requires:
*
* CONFIG_SAMA5_DDRCS -- DRAM support is enabled, and
- * !CONFIG_SAMA5_BOOT_SDRAM - We did not boot into SRAM, and
- * !CONFIG_BOOT_RUNFROMSDRAM - We are not running from SDRAM.
+ * !CONFIG_SAMA5_BOOT_SDRAM - We did not boot into SRAM.
*/
-#if defined(CONFIG_SAMA5_DDRCS) && !defined(CONFIG_SAMA5_BOOT_SDRAM) && \
- !defined(CONFIG_BOOT_RUNFROMSDRAM)
+#if defined(CONFIG_SAMA5_DDRCS) && !defined(CONFIG_SAMA5_BOOT_SDRAM)
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
-/* Used for SDRAM command handshaking */
+/* SDRAM differences */
-#define DDR2_BA0(r) (1 << (25 + r))
-#define DDR2_BA1(r) (1 << (26 + r))
+#if defined(CONFIG_SAMA5_MT47H128M16RT)
+
+ /* Used for SDRAM command handshaking */
+
+# define DDR2_BA0 (1 << 26)
+# define DDR2_BA1 (1 << 27)
+
+#elif defined(CONFIG_SAMA5_MT47H64M16HR)
+
+ /* Used for SDRAM command handshaking */
+
+# define DDR2_BA0 (1 << 25)
+# define DDR2_BA1 (1 << 26)
+
+#else
+# error Unknwon SDRAM type
+#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
- * Name: board_sdram_delay
+ * Name: sam_sdram_delay
*
* Description:
* Precision delay function for SDRAM configuration.
@@ -90,7 +104,7 @@
*
****************************************************************************/
-static inline board_sdram_delay(unsigned int loops)
+static inline void sam_sdram_delay(unsigned int loops)
{
volatile unsigned int i;
@@ -105,7 +119,7 @@ static inline board_sdram_delay(unsigned int loops)
************************************************************************************/
/************************************************************************************
- * Name: board_sdram_config
+ * Name: sam_sdram_config
*
* Description:
* Configures DDR2 (MT47H128M16RT 128MB/ MT47H64M16HR)
@@ -128,7 +142,7 @@ static inline board_sdram_delay(unsigned int loops)
*
************************************************************************************/
-void board_sdram_config(uint8_t sdramtype)
+void sam_sdram_config(void)
{
volatile uint8_t *ddr = (uint8_t *)SAM_DDRCS_VSECTION;
uint32_t regval;
@@ -180,7 +194,7 @@ void board_sdram_config(uint8_t sdramtype)
regval = getreg32(SAM_MPDDRC_IO_CALIBR);
regval &= ~(MPDDRC_IO_CALIBR_RDIV_MASK | MPDDRC_IO_CALIBR_TZQIO_MASK);
regval |= (MPDDRC_IO_CALIBR_RZQ48_40 | MPDDRC_IO_CALIBR_TZQIO(3));
- putreg(regval, SAM_MPDDRC_IO_CALIBR);
+ putreg32(regval, SAM_MPDDRC_IO_CALIBR);
/* Force DDR_DQ and DDR_DQS input buffer always on, clearing other bits
* (undocumented)
@@ -198,8 +212,11 @@ void board_sdram_config(uint8_t sdramtype)
/* Step 2: Program the features of DDR2-SDRAM device into the Timing
* Register
- *
- * For DDRAM_MT47H128M16RT
+ */
+
+#if defined(CONFIG_SAMA5_MT47H128M16RT)
+
+ /* For MT47H128M16RT
*
* NC = 10 DDR column bits
* NR = 14 DDR row bits
@@ -217,19 +234,16 @@ void board_sdram_config(uint8_t sdramtype)
* UNAL = Unaliged access supported
*/
- if (sdramtype == DDRAM_MT47H128M16RT)
- {
- regval = MPDDRC_CR_NC_10 | /* Number of Column Bits */
- MPDDRC_CR_NR_14 | /* Number of Row Bits */
- MPDDRC_CR_CAS_4 | /* CAS Latency */
- MPDDRC_CR_OCD_EXIT | /* Off-chip Driver */
- MPDDRC_CR_8BANKS | /* Number of Banks */
- MPDDRC_CR_NDQS | /* Not DQS */
- MPDDRC_CR_UNAL; /* upport Unaligned Access */
- putreg32(regval, SAM_MPDDRC_CR);
- }
+ regval = MPDDRC_CR_NC_10 | /* Number of Column Bits */
+ MPDDRC_CR_NR_14 | /* Number of Row Bits */
+ MPDDRC_CR_CAS_4 | /* CAS Latency */
+ MPDDRC_CR_OCD_EXIT | /* Off-chip Driver */
+ MPDDRC_CR_8BANKS | /* Number of Banks */
+ MPDDRC_CR_NDQS | /* Not DQS */
+ MPDDRC_CR_UNAL; /* upport Unaligned Access */
- /* For DDRAM_MT47H128M16RT
+#elif defined(CONFIG_SAMA5_MT47H64M16HR)
+ /* For MT47H64M16HR
*
* NC = 10 DDR column bits
* NR = 13 DDR row bits
@@ -247,17 +261,19 @@ void board_sdram_config(uint8_t sdramtype)
* UNAL = Unaliged access supported
*/
- else if (sdramtype == DDRAM_MT47H64M16HR)
- {
- regval = MPDDRC_CR_NC_10 | /* Number of Column Bits */
- MPDDRC_CR_NR_13 | /* Number of Row Bits */
- MPDDRC_CR_CAS_3 | /* CAS Latency */
- MPDDRC_CR_OCD_EXIT | /* Off-chip Driver */
- MPDDRC_CR_8BANKS | /* Number of Banks */
- MPDDRC_CR_NDQS | /* Not DQS */
- MPDDRC_CR_UNAL; /* upport Unaligned Access */
- putreg32(regval, SAM_MPDDRC_CR);
- }
+ regval = MPDDRC_CR_NC_10 | /* Number of Column Bits */
+ MPDDRC_CR_NR_13 | /* Number of Row Bits */
+ MPDDRC_CR_CAS_3 | /* CAS Latency */
+ MPDDRC_CR_OCD_EXIT | /* Off-chip Driver */
+ MPDDRC_CR_8BANKS | /* Number of Banks */
+ MPDDRC_CR_NDQS | /* Not DQS */
+ MPDDRC_CR_UNAL; /* upport Unaligned Access */
+
+#else
+# error Unknwon SDRAM type
+#endif
+
+ putreg32(regval, SAM_MPDDRC_CR);
/* Configure the Timing Parameter 0 Register */
@@ -301,7 +317,7 @@ void board_sdram_config(uint8_t sdramtype)
/* DDRSDRC Low-power Register */
- board_sdram_delay(13200);
+ sam_sdram_delay(13200);
regval = MPDDRC_LPR_LPCB_DISABLED | /* Low-power Feature is inhibited */
MPDDRC_LPR_TIMEOUT_0CLKS | /* Activates low-power mode after the end of transfer */
@@ -333,7 +349,7 @@ void board_sdram_config(uint8_t sdramtype)
/* Now CKE is driven high.*/
/* Wait 400 ns min */
- board_sdram_delay(100);
+ sam_sdram_delay(100);
/* Step 5: An all banks precharge command is issued to the DDR2-SDRAM. */
@@ -345,7 +361,7 @@ void board_sdram_config(uint8_t sdramtype)
/* Wait 400 ns min */
- board_sdram_delay(100);
+ sam_sdram_delay(100);
/* Step 6: An Extended Mode Register set (EMRS2) cycle is issued to chose
* between commercialor high temperature operations.
@@ -355,11 +371,11 @@ void board_sdram_config(uint8_t sdramtype)
*/
putreg32(MPDDRC_MR_MODE_EXTLMR, SAM_MPDDRC_MR);
- *((uint8_t *)(ddr + DDR2_BA1(sdramtype))) = 0;
+ *((uint8_t *)(ddr + DDR2_BA1)) = 0;
/* Wait 2 cycles min */
- board_sdram_delay(100);
+ sam_sdram_delay(100);
/* Step 7: An Extended Mode Register set (EMRS3) cycle is issued to set
* all registers to 0.
@@ -369,11 +385,11 @@ void board_sdram_config(uint8_t sdramtype)
*/
putreg32(MPDDRC_MR_MODE_EXTLMR, SAM_MPDDRC_MR);
- *((uint8_t *)(ddr + DDR2_BA1(sdramtype) + DDR2_BA0(sdramtype))) = 0;
+ *((uint8_t *)(ddr + DDR2_BA1 + DDR2_BA0)) = 0;
/* Wait 2 cycles min */
- board_sdram_delay(100);
+ sam_sdram_delay(100);
/* Step 8: An Extended Mode Register set (EMRS1) cycle is issued to enable DLL.
*
@@ -381,11 +397,11 @@ void board_sdram_config(uint8_t sdramtype)
*/
putreg32(MPDDRC_MR_MODE_EXTLMR, SAM_MPDDRC_MR);
- *((uint8_t *)(ddr + DDR2_BA0(sdramtype))) = 0;
+ *((uint8_t *)(ddr + DDR2_BA0)) = 0;
/* An additional 200 cycles of clock are required for locking DLL */
- board_sdram_delay(10000);
+ sam_sdram_delay(10000);
/* Step 9: Program DLL field into the Configuration Register.*/
@@ -403,11 +419,12 @@ void board_sdram_config(uint8_t sdramtype)
/* Wait 2 cycles min */
- board_sdram_delay(100);
+ sam_sdram_delay(100);
/* Step 11: An all banks precharge command is issued to the DDR2-SDRAM.
*
- * Perform a write access to any DDR2-SDRAM address to acknowledge this command */
+ * Perform a write access to any DDR2-SDRAM address to acknowledge this
+ * command
*/
putreg32(MPDDRC_MR_MODE_PRCGALL, SAM_MPDDRC_MR);
@@ -415,7 +432,7 @@ void board_sdram_config(uint8_t sdramtype)
/* Wait 2 cycles min */
- board_sdram_delay(100);
+ sam_sdram_delay(100);
/* Step 12: Two auto-refresh (CBR) cycles are provided. Program the auto
* refresh command (CBR) into the Mode Register.
@@ -429,7 +446,7 @@ void board_sdram_config(uint8_t sdramtype)
/* Wait 2 cycles min */
- board_sdram_delay(100);
+ sam_sdram_delay(100);
/* Configure 2nd CBR.
*
@@ -441,7 +458,7 @@ void board_sdram_config(uint8_t sdramtype)
/* Wait 2 cycles min */
- board_sdram_delay(100);
+ sam_sdram_delay(100);
/* Step 13: Program DLL field into the Configuration Register to low
* (Disable DLL reset).
@@ -462,14 +479,14 @@ void board_sdram_config(uint8_t sdramtype)
/* Wait 2 cycles min */
- board_sdram_delay(100);
+ sam_sdram_delay(100);
/* Step 15: Program OCD field into the Configuration Register to high (OCD
* calibration default).
*/
regval = getreg32(SAM_MPDDRC_CR);
- retval |= MPDDRC_CR_OCD_DEFAULT;
+ regval |= MPDDRC_CR_OCD_DEFAULT;
putreg32(regval, SAM_MPDDRC_CR);
/* Step 16: An Extended Mode Register set (EMRS1) cycle is issued to OCD
@@ -480,11 +497,11 @@ void board_sdram_config(uint8_t sdramtype)
*/
putreg32(MPDDRC_MR_MODE_EXTLMR, SAM_MPDDRC_MR);
- *((uint8_t *)(ddr + DDR2_BA0(sdramtype))) = 0;
+ *((uint8_t *)(ddr + DDR2_BA0)) = 0;
/* Wait 2 cycles min */
- board_sdram_delay(100);
+ sam_sdram_delay(100);
/* Step 17: Program OCD field into the Configuration Register to low (OCD
* calibration mode exit).
@@ -504,11 +521,11 @@ void board_sdram_config(uint8_t sdramtype)
*/
putreg32(MPDDRC_MR_MODE_EXTLMR, SAM_MPDDRC_MR);
- *((uint8_t *)(ddr + DDR2_BA0(sdramtype))) = 0;
+ *((uint8_t *)(ddr + DDR2_BA0)) = 0;
/* Wait 2 cycles min */
- board_sdram_delay(100);
+ sam_sdram_delay(100);
/* Step 19,20: A mode Normal command is provided. Program the Normal mode
* into Mode Register.
@@ -540,9 +557,7 @@ void board_sdram_config(uint8_t sdramtype)
/* OK now we are ready to work on the DDRSDR */
/* Wait for end of calibration */
- board_sdram_delay(500);
-#warning Make SDRAM cacheable
+ sam_sdram_delay(500);
}
-#endif /* CONFIG_SAMA5_DDRCS && !CONFIG_SAMA5_BOOT_SDRAM && !CONFIG_BOOT_RUNFROMSDRAM */
-#endif /* CONFIG_SAMA5_BOOT_CS0FLASH */
+#endif /* CONFIG_SAMA5_DDRCS && !CONFIG_SAMA5_BOOT_SDRAM */
diff --git a/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h b/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h
index 2b2a0d7fb..757863c18 100644
--- a/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h
+++ b/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h
@@ -112,7 +112,7 @@
* Name: board_sdram_config
*
* Description:
- * Configures DDR2 (MT47H128M16RT 128MB/ MT47H64M16HR)
+ * Configures DDR2 (MT47H128M16RT 128MB / MT47H64M16HR)
*
* MT47H64M16HR : 8 Meg x 16 x 8 banks
* Refresh count: 8K
@@ -132,9 +132,8 @@
*
************************************************************************************/
-#if defined(CONFIG_SAMA5_DDRCS) && !defined(CONFIG_SAMA5_BOOT_SDRAM) && \
- !defined(CONFIG_BOOT_RUNFROMSDRAM)
-void board_sdram_config(uint8_t sdramtype);
+#if defined(CONFIG_SAMA5_DDRCS) && !defined(CONFIG_SAMA5_BOOT_SDRAM)
+void sam_sdram_config(void);
#else
# define board_sdram_config(t)
#endif