From 543b5b7e035cd62e19a5d106291a47bcee4211c1 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 21 Jul 2013 12:52:38 -0600 Subject: [PATCH] A few more Cortex-A5 and SAMA5 files --- ChangeLog | 7 +- arch/arm/include/sama5/chip.h | 16 +- arch/arm/src/arm/pg_macros.h | 4 +- arch/arm/src/armv7-a/arm.h | 27 +- arch/arm/src/armv7-a/arm_fpuconfig.S | 98 ++ arch/arm/src/armv7-a/arm_head.S | 28 +- arch/arm/src/armv7-a/fpu.h | 90 ++ arch/arm/src/armv7-a/mmu.h | 911 ++++++++++++++++--- arch/arm/src/sama5/Make.defs | 4 +- arch/arm/src/sama5/chip/sama5d3x_memorymap.h | 155 ++-- arch/arm/src/sama5/sam_boot.c | 420 +++++++++ arch/arm/src/sama5/sam_clockconfig.h | 94 ++ arch/arm/src/sama5/sam_lowputc.h | 102 +++ configs/sama5d3x-ek/README.txt | 5 +- configs/sama5d3x-ek/ostest/setenv.sh | 4 +- configs/sama5d3x-ek/src/sam_autoleds.c | 107 +++ 16 files changed, 1837 insertions(+), 235 deletions(-) create mode 100644 arch/arm/src/armv7-a/arm_fpuconfig.S create mode 100644 arch/arm/src/armv7-a/fpu.h create mode 100644 arch/arm/src/sama5/sam_boot.c create mode 100644 arch/arm/src/sama5/sam_clockconfig.h create mode 100644 arch/arm/src/sama5/sam_lowputc.h create mode 100644 configs/sama5d3x-ek/src/sam_autoleds.c diff --git a/ChangeLog b/ChangeLog index 7e9dd7af71..5ea68d5004 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5143,4 +5143,9 @@ create the Cortex-A5 support (2013-7-19). * arch/arm/src/armv7-a/arm_cache.S: Cortex-A5 cache operations (2013-7-20). - + * /arch/arm/src/armv7-a/arm_fpuconfig.S and fpu.h: A few more files for + the ARMv7-A/Cortex-A5 port (2013-7-21). + * arm/src/sama5/sam_boot.c, sam_clockconfig.h, sam_lowputc.h: A few + more files for the SAMA5D3 port (2013-7-21). + * configs/sama5d3x-ek/src/sam_autoleds.c: A few more files for the port + to the SAMA5D3x-EK board (2013-7-21). diff --git a/arch/arm/include/sama5/chip.h b/arch/arm/include/sama5/chip.h index 8a727e0f4d..aea3dea852 100644 --- a/arch/arm/include/sama5/chip.h +++ b/arch/arm/include/sama5/chip.h @@ -92,13 +92,21 @@ */ #if defined(CONFIG_ARCH_CHIP_ATSAMA5D31) -# define ATSAMA5D3 1 /* SAMA5D3 family */ +# define ATSAMA5D3 1 /* SAMA5D3 family */ +# define SAM_ISRAM0_SIZE (64*1024) /* 128KB of SRAM in two banks */ +# define SAM_ISRAM1_SIZE (64*1024) #elif defined(CONFIG_ARCH_CHIP_ATSAMA5D33) -# define ATSAMA5D3 1 /* SAMA5D3 family */ +# define ATSAMA5D3 1 /* SAMA5D3 family */ +# define SAM_ISRAM0_SIZE (64*1024) /* 128KB of SRAM in two banks */ +# define SAM_ISRAM1_SIZE (64*1024) #elif defined(CONFIG_ARCH_CHIP_ATSAMA5D34) -# define ATSAMA5D3 1 /* SAMA5D3 family */ +# define ATSAMA5D3 1 /* SAMA5D3 family */ +# define SAM_ISRAM0_SIZE (64*1024) /* 128KB of SRAM in two banks */ +# define SAM_ISRAM1_SIZE (64*1024) #elif defined(CONFIG_ARCH_CHIP_ATSAMA5D35) -# define ATSAMA5D3 1 /* SAMA5D3 family */ +# define ATSAMA5D3 1 /* SAMA5D3 family */ +# define SAM_ISRAM0_SIZE (64*1024) /* 128KB of SRAM in two banks */ +# define SAM_ISRAM1_SIZE (64*1024) #else # error Unrecognized SAMAD5 chip #endif diff --git a/arch/arm/src/arm/pg_macros.h b/arch/arm/src/arm/pg_macros.h index dc65a5d06a..e461ced419 100644 --- a/arch/arm/src/arm/pg_macros.h +++ b/arch/arm/src/arm/pg_macros.h @@ -80,7 +80,7 @@ /* Virtual base of the address of the L2 page tables need to recalculates * using this new virtual base address of the L2 page table. - */ + */ # undef PGTABLE_L2_FINE_VBASE # define PGTABLE_L2_FINE_VBASE (PGTABLE_BASE_VADDR+PGTABLE_L2_FINE_OFFSET) @@ -369,7 +369,7 @@ * Description: * Write several, contiguous L2 page table entries. npages entries will be * written. This macro is used when CONFIG_PAGING is enable. This case, - * it is used asfollows: + * it is used as follows: * * ldr r0, =PGTABLE_L2_BASE_PADDR <-- Address in L2 table * ldr r1, =PG_LOCKED_PBASE <-- Physical page memory address diff --git a/arch/arm/src/armv7-a/arm.h b/arch/arm/src/armv7-a/arm.h index 79804909ac..8afe160614 100644 --- a/arch/arm/src/armv7-a/arm.h +++ b/arch/arm/src/armv7-a/arm.h @@ -1,4 +1,4 @@ -/************************************************************************************ +/**************************************************************************** * arch/arm/src/armv7-a/arm.h * Non-CP15 Registers * @@ -7,10 +7,11 @@ * * References: * - * "Cortex-A5™ MPCore, Technical Reference Manual", Revision: r0p1, Copyright © 2010 - * ARM. All rights reserved. ARM DDI 0434B (ID101810) - * "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition", Copyright © - * 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM DDI 0406C.b (ID072512) + * "Cortex-A5™ MPCore, Technical Reference Manual", Revision: r0p1, + * Copyright © 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810) + * "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition", + * Copyright © 1996-1998, 2000, 2004-2012 ARM. All rights reserved. + * ARM DDI 0406C.b (ID072512) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -39,20 +40,20 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************************/ + ****************************************************************************/ #ifndef __ARCH_ARM_SRC_ARMV7_A_CPSR_H #define __ARCH_ARM_SRC_ARMV7_A_CPSR_H -/************************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************************/ + ****************************************************************************/ -/************************************************************************************ +/**************************************************************************** * Pre-processor Definitions - ************************************************************************************/ + ****************************************************************************/ -/* ARMv7-A **************************************************************************/ +/* ARMv7-A ******************************************************************/ /* PSR bits */ @@ -86,9 +87,9 @@ #define PSR_Z_BIT (1 << 30) /* Bit 30: Zero condition flag */ #define PSR_N_BIT (1 << 31) /* Bit 31: Negative condition flag */ -/************************************************************************************ +/**************************************************************************** * Inline Functions - ************************************************************************************/ + ****************************************************************************/ #ifndef __ASSEMBLY__ diff --git a/arch/arm/src/armv7-a/arm_fpuconfig.S b/arch/arm/src/armv7-a/arm_fpuconfig.S new file mode 100644 index 0000000000..262fb70952 --- /dev/null +++ b/arch/arm/src/armv7-a/arm_fpuconfig.S @@ -0,0 +1,98 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_fpuconfig.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#include "cp15.h" + + .file "arm_fpuconfig.S" + +/**************************************************************************** + * Preprocessor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl arm_fpuconfig + +/**************************************************************************** + * Assembly Macros + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + + .text + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_fpuconfig + * + * Description: + * Configure the FPU. Enables access to CP10 and CP11 + * + ****************************************************************************/ + + .globl arm_fpuconfig + .type arm_fpuconfig, %function + +arm_fpuconfig: + + /* Enable access to CP10 and CP11 in CP15.CACR */ + + mrc CP15_CPACR(r0) + orr r0, r0, #0xf00000 + mcr CP15_CPACR(r0) + + /* Enable access to CP10 and CP11 in CP15.NSACR */ + /* REVISIT: Do we need to do this? */ + + /* Set FPEXC.EN (B30) */ + + fmrx r0, fpexc + orr r0, r0, #0x40000000 + fmxr fpexc, r0 + bx lr + .size arm_fpuconfig, . - arm_fpuconfig + .end diff --git a/arch/arm/src/armv7-a/arm_head.S b/arch/arm/src/armv7-a/arm_head.S index fdd139b360..acb87b248d 100644 --- a/arch/arm/src/armv7-a/arm_head.S +++ b/arch/arm/src/armv7-a/arm_head.S @@ -343,17 +343,20 @@ __start: /* Invalidate caches and TLBs. * - * NOTE: "The ARMv7 Virtual Memory System Architecture (VMSA) does not - * support a CP15 operation to invalidate the entire data cache. ... - * In normal usage the only time the entire data cache has to be - * invalidated is on reset." + * NOTE: "The ARMv7 Virtual Memory System Architecture (VMSA) does not + * support a CP15 operation to invalidate the entire data cache. ... + * In normal usage the only time the entire data cache has to be + * invalidated is on reset." * - * REVISIT: This could be an issue if NuttX is every started in a - * context where the DCache could be dirty. + * The instruction cache is virtually indexed and physically tagged but + * the data cache is physically indexed and physically tagged. So it + * should not be an issue if the system comes up with a dirty Dcache; + * the ICache, however, must be invalidated. */ mov r0, #0 mcr CP15_ICIALLUIS(r0) /* Invalidate entire instruction cache Inner Shareable */ + mcr CP15_TLBIALLIS(r0) /* Invalidate entire Unified TLB Inner Shareable */ /* Load the page table address. * @@ -392,10 +395,15 @@ __start: ldr lr, .LCvstart /* Abs. virtual address */ - /* Configure the domain access register (see mmu.h) */ + /* Configure the domain access register (see mmu.h). + * + * Domains 0: Accesses are not checked + * Domains 1: Accesses are not checked + * Domains 2: Accesses checked against permissions in the TLB + */ - mov r0, #0x1f /* Domains 0, 1 = client */ - mcr CP15_DACR(r0) /* Load domain access register */ + mov r0, #(DACR_MANAGER(0) | DACR_MANAGER(1) | DACR_CLIENT(2)) + mcr CP15_DACR(r0) /* Set domain access register */ /* Configure the system control register (see sctrl.h) */ @@ -668,7 +676,7 @@ __start: /* Finally branch to the OS entry point */ - mov lr, #0 + mov lr, #0 b os_start /* Text-section constants: diff --git a/arch/arm/src/armv7-a/fpu.h b/arch/arm/src/armv7-a/fpu.h new file mode 100644 index 0000000000..1a22371d12 --- /dev/null +++ b/arch/arm/src/armv7-a/fpu.h @@ -0,0 +1,90 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/fpu.h + * Non-CP15 Registers + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_A_CPSR_H +#define __ARCH_ARM_SRC_ARMV7_A_CPSR_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Variables + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" { +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_fpuconfig + * + * Description: + * Configure the FPU. Enables access to CP10 and CP11 + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_FPU +void arm_fpuconfig(void); +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_ARMV7_A_CPSR_H */ diff --git a/arch/arm/src/armv7-a/mmu.h b/arch/arm/src/armv7-a/mmu.h index 25d19016c3..b0135de7ae 100644 --- a/arch/arm/src/armv7-a/mmu.h +++ b/arch/arm/src/armv7-a/mmu.h @@ -7,10 +7,11 @@ * * References: * - * "Cortex-A5™ MPCore, Technical Reference Manual", Revision: r0p1, Copyright © 2010 - * ARM. All rights reserved. ARM DDI 0434B (ID101810) + * "Cortex-A5™ MPCore, Technical Reference Manual", Revision: r0p1, Copyright © + * 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810) * "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition", Copyright © - * 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM DDI 0406C.b (ID072512) + * 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM + * DDI 0406C.b (ID072512) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -51,24 +52,27 @@ /************************************************************************************ * Pre-processor Definitions ************************************************************************************/ -/* The Cortex-A5 supports two translation table base address registers. In this, - * implementation, only Translation Table Base Register 0 (TTBR0) is used. The - * TTBR0 contains the upper bits of the address a a page table in physical memory. - * If 4KB page sizes are used, then TTBR0 registers holds bits 14-31 of the page - * table address; A full 30-bit address is formed by ORing in bits 2-13 or the - * virtual address (MVA). As a consequence, the page table must be aligned to a - * 16Kb address in physical memory and could require up to 16Kb of memory. +/* Configuration ********************************************************************/ + +#ifdef CONFIG_PAGING + +/* Sanity check -- we cannot be using a ROM page table and supporting on- + * demand paging. */ -#define PGTABLE_SIZE 0x00004000 +#ifdef CONFIG_ARCH_ROMPGTABLE +# error "Cannot support both CONFIG_PAGING and CONFIG_ARCH_ROMPGTABLE" +#endif +#endif /* CONFIG_PAGING */ +/* MMU CP15 Register Bit Definitions ************************************************/ /* Reference: Cortex-A5™ MPCore Paragraph 6.7, "MMU software accessible registers." */ /* TLB Type Register TLB Type Register * - * The Translation Lookaside Buffer (TLB) Type Register, TLBTR, returns the number - * of lockable entries for the TLB. The Cortex-A5 MPCore processor does not - * implement this feature, so this register always RAZ. + * The Translation Lookaside Buffer (TLB) Type Register, TLBTR, returns the number of + * lockable entries for the TLB. The Cortex-A5 MPCore processor does not implement + * this feature, so this register always RAZ. */ /* System Control Register (SCTLR). see cstlr.h */ @@ -76,85 +80,85 @@ /* Translation Table Base Register 0 (TTBR0)*/ -#define TTBR0_IRGN1 (1 << 0) /* Bit 0: Inner cacheability for table walk */ -#define TTBR0_S (1 << 1) /* Bit 1: Translation table walk */ - /* Bit 2: Reserved */ -#define TTBR0_RGN_SHIFT (3) /* Bits 3-4: Outer cacheable attributes for table walk */ -#define TTBR0_RGN_MASK (3 << TTBR0_RGN_SHIFT) -# define TTBR0_RGN_NONE (0 << TTBR0_RGN_SHIFT) /* Non-cacheable */ -# define TTBR0_RGN_WBWA (1 << TTBR0_RGN_SHIFT) /* Write-Back cached + Write-Allocate */ -# define TTBR0_RGN_WT (2 << TTBR0_RGN_SHIFT) /* Write-Through */ -# define TTBR0_RGN_WB (3 << TTBR0_RGN_SHIFT) /* Write-Back */ - /* Bit 5: Reserved */ -#define TTBR0_IRGN0 (1 << 6) /* Bit 6: Inner cacheability (with IRGN0) */ - /* Bits 7-n: Reserved, n=7-13 */ -#define _TTBR0_LOWER(n) (0xffffffff << (n)) - /* Bits (n+1)-31: Translation table base 0 */ -#define TTBR0_BASE_MASK(n) (~_TTBR0_LOWER(n)) +#define TTBR0_IRGN1 (1 << 0) /* Bit 0: Inner cacheability for table walk */ +#define TTBR0_S (1 << 1) /* Bit 1: Translation table walk */ + /* Bit 2: Reserved */ +#define TTBR0_RGN_SHIFT (3) /* Bits 3-4: Outer cacheable attributes for table walk */ +#define TTBR0_RGN_MASK (3 << TTBR0_RGN_SHIFT) +# define TTBR0_RGN_NONE (0 << TTBR0_RGN_SHIFT) /* Non-cacheable */ +# define TTBR0_RGN_WBWA (1 << TTBR0_RGN_SHIFT) /* Write-Back cached + Write-Allocate */ +# define TTBR0_RGN_WT (2 << TTBR0_RGN_SHIFT) /* Write-Through */ +# define TTBR0_RGN_WB (3 << TTBR0_RGN_SHIFT) /* Write-Back */ + /* Bit 5: Reserved */ +#define TTBR0_IRGN0 (1 << 6) /* Bit 6: Inner cacheability (with IRGN0) */ + /* Bits 7-n: Reserved, n=7-13 */ +#define _TTBR0_LOWER(n) (0xffffffff << (n)) + /* Bits (n+1)-31: Translation table base 0 */ +#define TTBR0_BASE_MASK(n) (~_TTBR0_LOWER(n)) /* Translation Table Base Register 1 (TTBR1) */ -#define TTBR1_IRGN1 (1 << 0) /* Bit 0: Inner cacheability for table walk */ -#define TTBR1_S (1 << 1) /* Bit 1: Translation table walk */ - /* Bit 2: Reserved */ -#define TTBR1_RGN_SHIFT (3) /* Bits 3-4: Outer cacheable attributes for table walk */ -#define TTBR1_RGN_MASK (3 << TTBR1_RGN_SHIFT) -# define TTBR1_RGN_NONE (0 << TTBR1_RGN_SHIFT) /* Non-cacheable */ -# define TTBR1_RGN_WBWA (1 << TTBR1_RGN_SHIFT) /* Write-Back cached + Write-Allocate */ -# define TTBR1_RGN_WT (2 << TTBR1_RGN_SHIFT) /* Write-Through */ -# define TTBR1_RGN_WB (3 << TTBR1_RGN_SHIFT) /* Write-Back */ - /* Bit 5: Reserved */ -#define TTBR1_IRGN0 (1 << 6) /* Bit 6: Inner cacheability (with IRGN0) */ - /* Bits 7-13: Reserved */ -#define TTBR1_BASE_SHIFT (14) /* Bits 14-31: Translation table base 1 */ -#define TTBR1_BASE_MASK (0xffffc000) +#define TTBR1_IRGN1 (1 << 0) /* Bit 0: Inner cacheability for table walk */ +#define TTBR1_S (1 << 1) /* Bit 1: Translation table walk */ + /* Bit 2: Reserved */ +#define TTBR1_RGN_SHIFT (3) /* Bits 3-4: Outer cacheable attributes for table walk */ +#define TTBR1_RGN_MASK (3 << TTBR1_RGN_SHIFT) +# define TTBR1_RGN_NONE (0 << TTBR1_RGN_SHIFT) /* Non-cacheable */ +# define TTBR1_RGN_WBWA (1 << TTBR1_RGN_SHIFT) /* Write-Back cached + Write-Allocate */ +# define TTBR1_RGN_WT (2 << TTBR1_RGN_SHIFT) /* Write-Through */ +# define TTBR1_RGN_WB (3 << TTBR1_RGN_SHIFT) /* Write-Back */ + /* Bit 5: Reserved */ +#define TTBR1_IRGN0 (1 << 6) /* Bit 6: Inner cacheability (with IRGN0) */ + /* Bits 7-13: Reserved */ +#define TTBR1_BASE_SHIFT (14) /* Bits 14-31: Translation table base 1 */ +#define TTBR1_BASE_MASK (0xffffc000) /* Translation Table Base Control Register (TTBCR) */ -#define TTBCR_N_SHIFT (0) /* Bits 0-2: Boundary size of TTBR0 */ -#define TTBCR_N_MASK (7 << TTBCR_N_SHIFT) -# define TTBCR_N_16KB (0 << TTBCR_N_SHIFT) /* Reset value */ -# define TTBCR_N_8KB (1 << TTBCR_N_SHIFT) -# define TTBCR_N_4KB (2 << TTBCR_N_SHIFT) -# define TTBCR_N_2KB (3 << TTBCR_N_SHIFT) -# define TTBCR_N_1KB (4 << TTBCR_N_SHIFT) -# define TTBCR_N_512B (5 << TTBCR_N_SHIFT) -# define TTBCR_N_256B (6 << TTBCR_N_SHIFT) -# define TTBCR_N_128B (7 << TTBCR_N_SHIFT) - /* Bit 3: Reserved */ -#define TTBCR_PD0 (1 << 4) /* Bit 4: Translation table walk on a TLB miss w/TTBR0 */ -#define TTBCR_PD1 (1 << 5) /* Bit 5: Translation table walk on a TLB miss w/TTBR1 */ - /* Bits 6-31: Reserved */ +#define TTBCR_N_SHIFT (0) /* Bits 0-2: Boundary size of TTBR0 */ +#define TTBCR_N_MASK (7 << TTBCR_N_SHIFT) +# define TTBCR_N_16KB (0 << TTBCR_N_SHIFT) /* Reset value */ +# define TTBCR_N_8KB (1 << TTBCR_N_SHIFT) +# define TTBCR_N_4KB (2 << TTBCR_N_SHIFT) +# define TTBCR_N_2KB (3 << TTBCR_N_SHIFT) +# define TTBCR_N_1KB (4 << TTBCR_N_SHIFT) +# define TTBCR_N_512B (5 << TTBCR_N_SHIFT) +# define TTBCR_N_256B (6 << TTBCR_N_SHIFT) +# define TTBCR_N_128B (7 << TTBCR_N_SHIFT) + /* Bit 3: Reserved */ +#define TTBCR_PD0 (1 << 4) /* Bit 4: Translation table walk on a TLB miss w/TTBR0 */ +#define TTBCR_PD1 (1 << 5) /* Bit 5: Translation table walk on a TLB miss w/TTBR1 */ + /* Bits 6-31: Reserved */ /* Domain Access Control Register (DACR) */ -#define DACR_SHIFT(n) (1 << ((n) << 1)) /* Domain n, n=0-31 */ -#define DACR_MASK(n) (3 << DACR_SHIFT(n)) -# define DACR_NONE(n) (0 << DACR_SHIFT(n)) /* Any access generates a domain fault */ -# define DACR_CLIENT(n) (1 << DACR_SHIFT(n)) /* Accesses checked against permissions TLB */ -# define DACR_MANAGER(n) (3 << DACR_SHIFT(n)) /* Accesses are not checked */ +#define DACR_SHIFT(n) ((n) << 1) /* Domain n, n=0-15 */ +#define DACR_MASK(n) (3 << DACR_SHIFT(n)) +# define DACR_NONE(n) (0 << DACR_SHIFT(n)) /* Any access generates a domain fault */ +# define DACR_CLIENT(n) (1 << DACR_SHIFT(n)) /* Accesses checked against permissions TLB */ +# define DACR_MANAGER(n) (3 << DACR_SHIFT(n)) /* Accesses are not checked */ /* Data Fault Status Register (DFSR) */ -#define DFSR_STATUS_SHIFT (0) /* Bits 0-3: Type of exception generated (w/EXT and FS) */ -#define DFSR_STATUS_MASK (15 << DFSR_STATUS_SHIFT) -#define DFSR_DOMAIN_SHIFT (4) /* Bits 4-7: Domain accessed when a data fault occurred */ -#define DFSR_DOMAIN_MASK (15 << DFSR_STATUS_MASK) - /* Bits 8-9: Reserved */ -#define DFSR_FS (1 << 10) /* Bit 10: Part of the STATUS field */ -#define DFSR_WNR (1 << 11) /* Bit 11: Not read and write */ -#define DFSR_EXT (1 << 12) /* Bit 12: External Abort Qualifier */ - /* Bits 13-31: Reserved */ +#define DFSR_STATUS_SHIFT (0) /* Bits 0-3: Type of exception generated (w/EXT and FS) */ +#define DFSR_STATUS_MASK (15 << DFSR_STATUS_SHIFT) +#define DFSR_DOMAIN_SHIFT (4) /* Bits 4-7: Domain accessed when a data fault occurred */ +#define DFSR_DOMAIN_MASK (15 << DFSR_STATUS_MASK) + /* Bits 8-9: Reserved */ +#define DFSR_FS (1 << 10) /* Bit 10: Part of the STATUS field */ +#define DFSR_WNR (1 << 11) /* Bit 11: Not read and write */ +#define DFSR_EXT (1 << 12) /* Bit 12: External Abort Qualifier */ + /* Bits 13-31: Reserved */ /* Instruction Fault Status Register (IFSR) */ -#define IFSR_STATUS_SHIFT (0) /* Bits 0-3: Type of fault generated (w/EXT and FS) */ -#define IFSR_STATUS_MASK (15 << IFSR_STATUS_SHIFT) - /* Bits 4-9: Reserved */ -#define IFSR_S (1 << 10) /* Bit 10: Part of the STATUS field */ - /* Bits 11: Reserved */ -#define IFSR_EXT (1 << 12) /* Bit 12: External Abort Qualifier */ - /* Bits 13-31: Reserved */ +#define IFSR_STATUS_SHIFT (0) /* Bits 0-3: Type of fault generated (w/EXT and FS) */ +#define IFSR_STATUS_MASK (15 << IFSR_STATUS_SHIFT) + /* Bits 4-9: Reserved */ +#define IFSR_S (1 << 10) /* Bit 10: Part of the STATUS field */ + /* Bits 11: Reserved */ +#define IFSR_EXT (1 << 12) /* Bit 12: External Abort Qualifier */ + /* Bits 13-31: Reserved */ /* Data Fault Address Register(DFAR). Holds the MVA of the faulting address when a * synchronous fault occurs @@ -174,15 +178,17 @@ * Register Format: VA/ASID * Instruction: MCR p15, 0, , c8, c3, 1 * CP15 Register: TLBIASIDIS - * Description: Invalidate Unified TLB entry by ASID match Inner Shareable + * Description: Invalidate Unified TLB entry by ASID match Inner + * Shareable * Register Format: ASID * Instruction: MCR p15, 0, , c8, c3, 2 * CP15 Register: TLBIMVAAIS - * Description: Invalidate Unified TLB entry by VA all ASID Inner Shareable + * Description: Invalidate Unified TLB entry by VA all ASID Inner + * Shareable * Register Format: VA * Instruction: MCR p15, 0, , c8, c3, 3 * CP15 Register: TLBIALL - * Description: Invalidate entire Unified TLB + * Description: Invalidate entire Unified TLB * Register Format: Ignored * Instruction: MCR p15, 0, , c8, c7, 0 * CP15 Register: TLBIMVA @@ -190,7 +196,7 @@ * Register Format: VA/ASID * Instruction: MCR p15, 0, , c8, c7, 1 * CP15 Register: TLBIASID - * Description: Invalidate TLB entries by ASID Match + * Description: Invalidate TLB entries by ASID Match * Register Format: ASID * MCR p15, 0, , c8, c7, 2 * CP15 Register: TLBIMVAA @@ -199,32 +205,532 @@ * Instruction: MCR p15, 0, , c8, c7, 3 */ -#define TLB_ASID_SHIFT (0) /* Bits 0-7: Address Space Identifier */ -#define TLB_ASID_MASK (0xff << TLB_ASID_SHIFT) -#define TLB_SBZ_SHIFT (8) /* Bits 8-11: SBZ */ -#define TLB_SBZ_MASK (15 << TLB_SBZ_SHIFT) -#define TLB_VA_MASK (0xfffff000) /* Bits 12-31: Virtual address */ +#define TLB_ASID_SHIFT (0) /* Bits 0-7: Address Space Identifier */ +#define TLB_ASID_MASK (0xff << TLB_ASID_SHIFT) +#define TLB_SBZ_SHIFT (8) /* Bits 8-11: SBZ */ +#define TLB_SBZ_MASK (15 << TLB_SBZ_SHIFT) +#define TLB_VA_MASK (0xfffff000) /* Bits 12-31: Virtual address */ /* Primary Region Remap Register (PRRR) */ /* Normal Memory Remap Register (NMRR) */ /* TLB Hitmap Register (TLBHR) */ -#define TLBHR_4KB (1 << 0) /* Bit 0: 4KB pages are present in the TLB */ -#define TLBHR_16KB (1 << 1) /* Bit 1: 16KB pages are present in the TLB */ -#define TLBHR_1MB (1 << 2) /* Bit 2: 1MB sections are present in the TLB */ -#define TLBHR_16MB (1 << 3) /* Bit 3: 16MB supersections are present in the TLB */ - /* Bits 4-31: Reserved */ +#define TLBHR_4KB (1 << 0) /* Bit 0: 4KB pages are present in the TLB */ +#define TLBHR_16KB (1 << 1) /* Bit 1: 16KB pages are present in the TLB */ +#define TLBHR_1MB (1 << 2) /* Bit 2: 1MB sections are present in the TLB */ +#define TLBHR_16MB (1 << 3) /* Bit 3: 16MB supersections are present in the TLB */ + /* Bits 4-31: Reserved */ /* Context ID Register (CONTEXTIDR). See cstlr.h */ +/* Translation Table Definitions ****************************************************/ +/* Hardware translation table definitions. Only the "short descriptor format" is + * supported. + * + * Level 1 Descriptor (PMD) + * + * Common definitions that apply to all L1 table entry types + */ + +#define PMD_TYPE_SHIFT (0) /* Bits: 1:0: Type of mapping */ +#define PMD_TYPE_MASK (3 << PMD_TYPE_SHIFT) +# define PMD_TYPE_FAULT (0 << PMD_TYPE_SHIFT) /* None */ +# define PMD_TYPE_PTE (1 << PMD_TYPE_SHIFT) /* Page table */ +# define PMD_TYPE_SECT (2 << PMD_TYPE_SHIFT) /* Section or supersection */ +# define PMD_TYPE_PXN (3 << PMD_TYPE_SHIFT) /* PXN Section or supersection */ + /* Bits 2-31: Depend on the mapping type */ + +/* Level 1 Fault Translation Table Format. + * + * Invalid or fault entry. "The associated VA is unmapped, and any attempt to + * access it generates a Translation fault. Software can use bits[31:2] of the + * descriptor for its own purposes, because the hardware ignores + * these bits." + */ + +/* Level 1 Page Table Translation Table Format. + * + * Page table. "The descriptor gives the address of a second-level translation + * table, that specifies the mapping of the associated 1MByte VA range." + */ + + /* Bits 0-1: Type of mapping */ +#define PMD_PTE_PXN (1 << 2) /* Bit 2: Privileged execute-never bit */ +#define PMD_PTE_NS (1 << 3) /* Bit 3: Non-secure bit */ + /* Bit 4: Should be zero (SBZ) */ +#define PMD_PTE_DOM_SHIFT (5) /* Bits 5-8: Domain */ +#define PMD_PTE_DOM_MASK (15 << PMD_PTE_DOMAIN_SHIFT) + /* Bit 9: Not implemented */ +#define PMD_PTE_PADDR_MASK (0xfffffc00) /* Bits 10-31: Page table base address */ + +/* Level 1 Section/Supersection Descriptor. + * + * Section or Supersection. "The descriptor gives the base address of the + * Section or Supersection. Bit[18] determines whether the entry describes a + * Section or a Supersection. If the implementation supports the PXN + * attribute, this encoding also defines the PXN bit as 0. Section descriptors + * allow fast, single level mapping between 1Mb address regions." + + * PXN Section or Supersection. "If an implementation supports the PXN attribute, + * this encoding is identical..., except that it defines the PXN bit as 1. + * + * "If the implementation does not support the PXN attribute, an attempt to access + * the associated VA generates a Translation fault. On an implementation that + * does not support the PXN attribute, this encoding must not be used." + */ + +/* Section */ + +#define PMD_SECT_PXN (1 << 0) /* Bit 0: Privileged execute-never bit */ + /* Bits 0-1: Type of mapping */ +#define PMD_SECT_B (1 << 2) /* Bit 2: Bufferable bit */ +#define PMD_SECT_C (1 << 3) /* Bit 3: Cacheable bit*/ +#define PMD_SECT_XN (1 << 4) /* Bit 4: Execute-never bit */ +#define PMD_SECT_DOM_SHIFT (5) /* Bits 5-8: Domain */ +#define PMD_SECT_DOM_MASK (15 << PMD_SECT_DOMAIN_SHIFT) + /* Bit 9: Implementation defined */ +#define PMD_SECT_AP_SHIFT (10) /* Bits 10-11: Access Permissions bits AP[0:1] */ +#define PMD_SECT_AP_MASK (3 << PMD_SECT_AP_SHIFT) +# define PMD_SECT_AP0 (1 << PMD_SECT_AP_SHIFT) /* AP[0]: Access permission bit 0 */ +# define PMD_SECT_AP1 (2 << PMD_SECT_AP_SHIFT) /* AP[1]: Access permission bit 1 */ +#define PMD_SECT_TEX_SHIFT (12) /* Bits 12-14: Memory region attribute bits */ +#define PMD_SECT_TEX_MASK (7 << PMD_SECT_AP_SHIFT) +#define PMD_SECT_AP2 (1 << 15) /* Bit 15: AP[2]: Access permission bit 2 */ +#define PMD_SECT_S (1 << 16) /* Bit 16: Shareable bit */ +#define PMD_SECT_NG (1 << 17) /* Bit 17: Not global bit. */ +#define PMD_SECT_PADDR_MASK (0xfff00000) /* Bits 20-31: Section base address, PA[31:20] */ + +/* Super Section (differences only) */ + +#define PMD_SSECT_XBA3_SHIFT (5) /* Bits 24-31: Extended base address, PA[39:36] */ +#define PMD_SSECT_XBA3_MASK (15 << PMD_SSECT_XBA3_SHIFT) +#define PMD_SSECT_XBA2_SHIFT (5) /* Bits 20-23: Extended base address, PA[35:32] */ +#define PMD_SSECT_XBA2_MASK (15 << PMD_SSECT_XBA2_SHIFT) +#define PMD_SSECT_XBA1_SHIFT (5) /* Bits 24-31: Extended base address, PA[31:24] */ +#define PMD_SSECT_XBA1_MASK (15 << PMD_SSECT_XBA1_SHIFT) + +/* Level 1 Section/Supersection Access Permissions: + * + * WR - Read/write addess allowed + * R - Read-only access allowed + * 0,1,2 - At PL0, PL1, and/or PL2 + * + * PL0 - User privilege level + * PL1 - Privilieged mode + * PL2 - Software executing in Hyp mode + */ + +#define PMD_SECT_AP_NONE (0) +#define PMD_SECT_AP_RW12 (PMD_SECT_AP0) +#define PMD_SECT_AP_RW12_R0 (PMD_SECT_AP1) +#define PMD_SECT_AP_RW012 (PMD_SECT_AP0 | PMD_SECT_AP1) +#define PMD_SECT_AP_R12 (PMD_SECT_AP0 | PMD_SECT_AP2) +#define PMD_SECT_AP_R012 (PMD_SECT_AP0 | PMD_SECT_AP1 | PMD_SECT_AP2) + +/* Short-descriptor translation table second-level descriptor formats + * + * A PMD_TYPE_PTE level-one table entry provides the base address of the beginning of a second + * -level page table. There are two types of page table entries: + * + * - Large page table entries support mapping of 64KB memory regions. + * - Small page table entries support mapping of 4KB memory regions. + * + * The following definitions apply to all L2 tables: + */ + +#define PTE_TYPE_SHIFT (0) /* Bits: 1:0: Type of mapping */ +#define PTE_TYPE_MASK (3 << PTE_TYPE_SHIFT) +# define PTE_TYPE_FAULT (0 << PTE_TYPE_SHIFT) /* None */ +# define PTE_TYPE_LARGE (1 << PTE_TYPE_SHIFT) /* 64Kb of memory */ +# define PTE_TYPE_SMALL (2 << PTE_TYPE_SHIFT) /* 4Kb of memory */ +#define PTE_B (1 << 2) /* Bit 2: Bufferable bit */ +#define PTE_CACHEABLE (1 << 3) /* Bit 3: Cacheable bit */ +#define PTE_AP_SHIFT (4) /* Bits 4-5: Access Permissions bits AP[0:1] */ +#define PTE_AP_MASK (3 << PTE_AP_SHIFT) +# define PTE_AP0 (1 << PTE_AP_SHIFT) /* AP[0]: Access permission bit 0 */ +# define PTE_AP1 (2 << PTE_AP_SHIFT) /* AP[1]: Access permission bit 1 */ + /* Bits 6-8: Depend on entry type */ +#define PTE_AP2 (1 << 9) /* Bit 9: AP[2]: Access permission bit 2 */ +#define PTE_S (1 << 10) /* Bit 10: Shareable bit */ +#define PTE_NG (1 << 11) /* Bit 11: Not global bit. */ + /* Bits 12-31:Depend on entry type */ + +/* Large page -- 64Kb */ + /* Bits: 1:0: Type of mapping */ + /* Bit 2: Bufferable bit */ + /* Bit 3: Cacheable bit */ + /* Bits 4-5: Access Permissions bits AP[0:1] */ +#define PTE_LARGE_TEX_SHIFT (12) /* Bits 12-14: Memory region attribute bits */ +#define PTE_LARGE_TEX_MASK (7 << PTE_LARGE_TEX_SHIFT) +#define PTE_LARGE_XN (1 << 15) /* Bit 15: Execute-never bit */ +#define PTE_LARGE_PADDR_MASK (0xffff0000) /* Bits 16-31: Large page base address, PA[31:16] */ + +/* Small page -- 4Kb */ + + /* Bits: 1:0: Type of mapping */ + /* Bit 2: Bufferable bit */ + /* Bit 3: Cacheable bit */ + /* Bits 4-5: Access Permissions bits AP[0:1] */ +#define PTE_SMALL_AP_MASK (0xfffff000) /* Bits 12-31: Small page base address, PA[31:12] */ + +/* Level 2 Translation Table Access Permissions: + * + * WR - Read/write addess allowed + * R - Read-only access allowed + * 0,1,2 - At PL0, PL1, and/or PL2 + * + * PL0 - User privilege level + * PL1 - Privilieged mode + * PL2 - Software executing in Hyp mode + */ + +#define PTE_AP_NONE (0) +#define PTE_AP_RW12 (PTE_AP0) +#define PTE_AP_RW12_R0 (PTE_AP1) +#define PTE_AP_RW012 (PTE_AP0 | PTE_AP1) +#define PTE_AP_R12 (PTE_AP0 | PTE_AP2) +#define PTE_AP_R012 (PTE_AP0 | PTE_AP1 | PTE_AP2) + +/* Default MMU flags for RAM memory, IO, vector region + * + * REVISIT: Here we expect all threads to be running at PL1 + */ + +#define MMU_ROMFLAGS \ + (PMD_TYPE_SECT | PMD_SECT_AP_R12) + +#define MMU_MEMFLAGS \ + (PMD_TYPE_SECT | PMD_SECT_C | PMD_SECT_B | PMD_SECT_AP_RW12) + +#define MMU_IOFLAGS \ + (PMD_TYPE_SECT | PMD_SECT_AP_RW012) + +#define MMU_L1_VECTORFLAGS (PMD_TYPE_PTE) +#define MMU_L2_VECTORFLAGS (PTE_TYPE_SMALL | PTE_AP_RW12) + +/* Mapped section size */ + +#define SECTION_SIZE (1 << 20) /* 1Mb */ + +/* The Cortex-A5 supports two translation table base address registers. In + * this, implementation, only Translation Table Base Register 0 (TTBR0) is + * used. The TTBR0 contains the upper bits of the address a a page table in + * physical memory. If 4KB page sizes are used, then TTBR0 registers holds + * bits 14-31 of the page table address; A full 30-bit address is formed by + * ORing in bits 2-13 or the virtual address (MVA). As a consequence, the + * page table must be aligned to a 16Kb address in physical memory and could + * require up to 16Kb of memory. + */ + +#define PGTABLE_SIZE 0x00004000 + +/* Virtual Page Table Location ******************************************************/ + +#ifdef CONFIG_PAGING +/* Check if the virtual address of the page table has been defined. It + * should not be defined: architecture specific logic should suppress + * defining PGTABLE_BASE_VADDR unless: (1) it is defined in the NuttX + * configuration file, or (2) the page table is position in low memory + * (because the vectors are in high memory). + */ + +#ifndef PGTABLE_BASE_VADDR +# define PGTABLE_BASE_VADDR (PG_LOCKED_VBASE + PG_TEXT_VSIZE + PG_DATA_SIZE) + + /* Virtual base of the address of the L2 page tables need to recalculates + * using this new virtual base address of the L2 page table. + */ + +# undef PGTABLE_L2_VBASE +# define PGTABLE_L2_VBASE (PGTABLE_BASE_VADDR+PGTABLE_L2_OFFSET) + +#endif /* CONFIG_PAGING */ + +/* Page Size Selections *************************************************************/ + +/* Create some friendly definitions to handle some differences between + * small and tiny pages. + */ + +#if CONFIG_PAGING_PAGESIZE == 1024 + + /* Base of the L2 page table (aligned to 4Kb byte boundaries) */ + +# define PGTABLE_L2_BASE_PADDR PGTABLE_L2_FINE_PBASE +# define PGTABLE_L2_BASE_VADDR PGTABLE_L2_FINE_VBASE + + /* Number of pages in an L2 table per L1 entry */ + +# define PTE_NPAGES PTE_TINY_NPAGES + + /* Mask to get the page table physical address from an L1 entry */ + +# define PG_L1_PADDRMASK PMD_PTE_PADDR_MASK + + /* MMU Flags for each memory region */ + +# define MMU_L1_TEXTFLAGS (PMD_TYPE_PTE) +# define MMU_L2_TEXTFLAGS (PTE_TYPE_SMALL | PTE_AP_R12 | PTE_CACHEABLE) +# define MMU_L1_DATAFLAGS (PMD_TYPE_PTE) +# define MMU_L2_DATAFLAGS (PTE_TYPE_SMALL | PTE_AP_RW12 | PTE_CACHEABLE|PTE_B) +# define MMU_L2_ALLOCFLAGS (PTE_TYPE_SMALL | PTE_AP_RW12) +# define MMU_L1_PGTABFLAGS (PMD_TYPE_PTE) +# define MMU_L2_PGTABFLAGS (PTE_TYPE_SMALL | PTE_AP_RW12) + +# define MMU_L2_VECTRWFLAGS (PTE_TYPE_SMALL | PTE_AP_RW12) +# define MMU_L2_VECTROFLAGS (PTE_TYPE_SMALL | PTE_AP_R12 | PTE_CACHEABLE) + +#elif CONFIG_PAGING_PAGESIZE == 4096 + + /* Base of the L2 page table (aligned to 1Kb byte boundaries) */ + +# define PGTABLE_L2_BASE_PADDR PGTABLE_L2_PBASE +# define PGTABLE_L2_BASE_VADDR PGTABLE_L2_VBASE + + /* Number of pages in an L2 table per L1 entry */ + +# define PTE_NPAGES PTE_SMALL_NPAGES + + /* Mask to get the page table physical address from an L1 entry */ + +# define PG_L1_PADDRMASK PMD_SECT_PADDR_MASK + + /* MMU Flags for each memory region. */ + +# define MMU_L1_TEXTFLAGS (PMD_TYPE_PTE) +# define MMU_L2_TEXTFLAGS (PTE_TYPE_SMALL|PTE_SMALL_AP_UNO_SRO|PTE_CACHEABLE) +# define MMU_L1_DATAFLAGS (PMD_TYPE_PTE) +# define MMU_L2_DATAFLAGS (PTE_TYPE_SMALL|PTE_SMALL_AP_UNO_SRW|PTE_CACHEABLE|PTE_B) +# define MMU_L2_ALLOCFLAGS (PTE_TYPE_SMALL|PTE_SMALL_AP_UNO_SRW) +# define MMU_L1_PGTABFLAGS (PMD_TYPE_PTE) +# define MMU_L2_PGTABFLAGS (PTE_TYPE_SMALL|PTE_SMALL_AP_UNO_SRW) + +# define MMU_L2_VECTRWFLAGS (PTE_TYPE_SMALL|PTE_SMALL_AP_UNO_SRW) +# define MMU_L2_VECTROFLAGS (PTE_TYPE_SMALL|PTE_SMALL_AP_UNO_SRO|PTE_CACHEABLE) + +#else +# error "Need extended definitions for CONFIG_PAGING_PAGESIZE" +#endif + +#define PT_SIZE (4*PTE_NPAGES) + +/* Addresses of Memory Regions ******************************************************/ + +/* We position the locked region PTEs at an offset into the first + * L2 page table. The L1 entry points to an 1Mb aligned virtual + * address. The actual L2 entry will be offset into the aligned + * L2 table. + * + * Coarse: PG_L1_PADDRMASK=0xfffffc00 + * OFFSET=(((a) & 0x000fffff) >> 12) << 2) + * Fine: PG_L1_PADDRMASK=0xfffff000 + * OFFSET=(((a) & 0x000fffff) >> 10) << 2) + */ + +#define PG_L1_LOCKED_PADDR (PGTABLE_BASE_PADDR + ((PG_LOCKED_VBASE >> 20) << 2)) +#define PG_L1_LOCKED_VADDR (PGTABLE_BASE_VADDR + ((PG_LOCKED_VBASE >> 20) << 2)) + +#define PG_L2_LOCKED_OFFSET (((PG_LOCKED_VBASE & 0x000fffff) >> PAGESHIFT) << 2) +#define PG_L2_LOCKED_PADDR (PGTABLE_L2_BASE_PADDR + PG_L2_LOCKED_OFFSET) +#define PG_L2_LOCKED_VADDR (PGTABLE_L2_BASE_VADDR + PG_L2_LOCKED_OFFSET) +#define PG_L2_LOCKED_SIZE (4*CONFIG_PAGING_NLOCKED) + +/* We position the paged region PTEs immediately after the locked + * region PTEs. NOTE that the size of the paged regions is much + * larger than the size of the physical paged region. That is the + * core of what the On-Demanding Paging feature provides. + */ + +#define PG_L1_PAGED_PADDR (PGTABLE_BASE_PADDR + ((PG_PAGED_VBASE >> 20) << 2)) +#define PG_L1_PAGED_VADDR (PGTABLE_BASE_VADDR + ((PG_PAGED_VBASE >> 20) << 2)) + +#define PG_L2_PAGED_PADDR (PG_L2_LOCKED_PADDR + PG_L2_LOCKED_SIZE) +#define PG_L2_PAGED_VADDR (PG_L2_LOCKED_VADDR + PG_L2_LOCKED_SIZE) +#define PG_L2_PAGED_SIZE (4*CONFIG_PAGING_NVPAGED) + +/* This describes the overall text region */ + +#define PG_L1_TEXT_PADDR PG_L1_LOCKED_PADDR +#define PG_L1_TEXT_VADDR PG_L1_LOCKED_VADDR + +#define PG_L2_TEXT_PADDR PG_L2_LOCKED_PADDR +#define PG_L2_TEXT_VADDR PG_L2_LOCKED_VADDR +#define PG_L2_TEXT_SIZE (PG_L2_LOCKED_SIZE + PG_L2_PAGED_SIZE) + +/* We position the data section PTEs just after the text region PTE's */ + +#define PG_L1_DATA_PADDR (PGTABLE_BASE_PADDR + ((PG_DATA_VBASE >> 20) << 2)) +#define PG_L1_DATA_VADDR (PGTABLE_BASE_VADDR + ((PG_DATA_VBASE >> 20) << 2)) + +#define PG_L2_DATA_PADDR (PG_L2_LOCKED_PADDR + PG_L2_TEXT_SIZE) +#define PG_L2_DATA_VADDR (PG_L2_LOCKED_VADDR + PG_L2_TEXT_SIZE) +#define PG_L2_DATA_SIZE (4*PG_DATA_NPAGES) + +/* Page Table Info ******************************************************************/ + +/* The number of pages in the in the page table (PG_PGTABLE_NPAGES). We + * position the pagetable PTEs just after the data section PTEs. + */ + +#define PG_PGTABLE_NPAGES (PGTABLE_SIZE >> PAGESHIFT) +#define PG_L1_PGTABLE_PADDR (PGTABLE_BASE_PADDR + ((PGTABLE_BASE_VADDR >> 20) << 2)) +#define PG_L1_PGTABLE_VADDR (PGTABLE_BASE_VADDR + ((PGTABLE_BASE_VADDR >> 20) << 2)) + +#define PG_L2_PGTABLE_PADDR (PG_L2_DATA_PADDR + PG_L2_DATA_SIZE) +#define PG_L2_PGTABLE_VADDR (PG_L2_DATA_VADDR + PG_L2_DATA_SIZE) +#define PG_L2_PGTABLE_SIZE (4*PG_DATA_NPAGES) + +/* Vector Mapping *******************************************************************/ + +/* One page is required to map the vector table. The vector table could lie + * at virtual address zero (or at the start of RAM which is aliased to address + * zero on the ea3131) or at virtual address 0xfff00000. We only have logic + * here to support the former case. + * + * NOTE: If the vectors are at address zero, the page table will be + * forced to the highest RAM addresses. If the vectors are at 0xfff0000, + * then the page table is forced to the beginning of RAM. + * + * When the vectors are at the beginning of RAM, they will probably overlap + * the first page of the locked text region. In any other case, the + * configuration must set CONFIG_PAGING_VECPPAGE to provide the physical + * address of the page to use for the vectors. + * + * When the vectors overlap the first page of the locked text region (the + * only case in use so far), then the text page will be temporarily be made + * writable in order to copy the vectors. + * + * PG_VECT_PBASE - This the physical address of the page in memory to be + * mapped to the vector address. + * PG_L2_VECT_PADDR - This is the physical address of the L2 page table + * entry to use for the vector mapping. + * PG_L2_VECT_VADDR - This is the virtual address of the L2 page table + * entry to use for the vector mapping. + */ + +/* Case 1: The configuration tells us everything */ + +#if defined(CONFIG_PAGING_VECPPAGE) +# define PG_VECT_PBASE CONFIG_PAGING_VECPPAGE +# define PG_L2_VECT_PADDR CONFIG_PAGING_VECL2PADDR +# define PG_L2_VECT_VADDR CONFIG_PAGING_VECL2VADDR + +/* Case 2: Vectors are in low memory and the locked text region starts at + * the beginning of SRAM (which will be aliased to address 0x00000000). + * However, the beginning of SRAM may not be aligned to the beginning + * of the L2 page table (because the beginning of RAM is offset into + * the table. + */ + +#elif defined(CONFIG_ARCH_LOWVECTORS) && !defined(CONFIG_PAGING_LOCKED_PBASE) +# define PG_VECT_PBASE PG_LOCKED_PBASE +# define PG_L2_VECT_OFFSET (((PG_LOCKED_VBASE & 0x000fffff) >> PAGESHIFT) << 2) +# define PG_L2_VECT_PADDR (PGTABLE_L2_BASE_PADDR + PG_L2_VECT_OFFSET) +# define PG_L2_VECT_VADDR (PGTABLE_L2_BASE_VADDR + PG_L2_VECT_OFFSET) + +/* Case 3: High vectors or the locked region is not at the beginning or SRAM */ + +#else +# error "Logic missing for high vectors in this case" +#endif + +/* Page Usage ***********************************************************************/ + +/* This is the total number of pages used in the text/data mapping: */ + +#define PG_TOTAL_NPPAGES (PG_TEXT_NPPAGES + PG_DATA_NPAGES + PG_PGTABLE_NPAGES) +#define PG_TOTAL_NVPAGES (PG_TEXT_NVPAGES + PG_DATA_NPAGES + PG_PGTABLE_NPAGES) +#define PG_TOTAL_PSIZE (PG_TOTAL_NPPAGES << PAGESHIFT) +#define PG_TOTAL_VSIZE (PG_TOTAL_NVPAGES << PAGESHIFT) + +/* Sanity check: */ + +#if PG_TOTAL_NPPAGES > PG_RAM_PAGES +# error "Total pages required exceeds RAM size" +#endif + +/* Page Management ******************************************************************/ + +/* For page managment purposes, the following summarize the "heap" of + * free pages, operations on free pages and the L2 page table. + * + * PG_POOL_VA2L1OFFSET(va) - Given a virtual address, return the L1 table + * offset (in bytes). + * PG_POOL_VA2L1VADDR(va) - Given a virtual address, return the virtual + * address of the L1 table entry + * PG_POOL_L12PPTABLE(L1) - Given the value of an L1 table entry return + * the physical address of the start of the L2 + * page table + * PG_POOL_L12PPTABLE(L1) - Given the value of an L1 table entry return + * the virtual address of the start of the L2 + * page table. + * + * PG_POOL_L1VBASE - The virtual address of the start of the L1 + * page table range corresponding to the first + * virtual address of the paged text region. + * PG_POOL_L1VEND - The virtual address of the end+1 of the L1 + * page table range corresponding to the last + * virtual address+1 of the paged text region. + * + * PG_POOL_VA2L2NDX(va) - Converts a virtual address within the paged + * text region to the most compact possible + * representation. Each PAGESIZE of address + * corresponds to 1 index in the L2 page table; + * Index 0 corresponds to the first L2 page table + * entry for the first page in the virtual paged + * text address space. + * PG_POOL_NDX2VA(ndx) - Performs the opposite conversion.. convests + * an index into a virtual address in the paged + * text region (the address at the beginning of + * the page). + * PG_POOL_MAXL2NDX - This is the maximum value+1 of such an index. + * + * PG_POOL_PGPADDR(ndx) - Converts an page index into the corresponding + * (physical) address of the backing page memory. + * PG_POOL_PGVADDR(ndx) - Converts an page index into the corresponding + * (virtual)address of the backing page memory. + * + * These are used as follows: If a miss occurs at some virtual address, va, + * A new page index, ndx, is allocated. PG_POOL_PGPADDR(i) converts the index + * into the physical address of the page memory; PG_POOL_L2VADDR(va) converts + * the virtual address in the L2 page table there the new mapping will be + * written. + */ + +#define PG_POOL_VA2L1OFFSET(va) (((va) >> 20) << 2) +#define PG_POOL_VA2L1VADDR(va) (PGTABLE_BASE_VADDR + PG_POOL_VA2L1OFFSET(va)) +#define PG_POOL_L12PPTABLE(L1) ((L1) & PG_L1_PADDRMASK) +#define PG_POOL_L12VPTABLE(L1) (PG_POOL_L12PPTABLE(L1) - PGTABLE_BASE_PADDR + PGTABLE_BASE_VADDR) + +#define PG_POOL_L1VBASE (PGTABLE_BASE_VADDR + ((PG_PAGED_VBASE >> 20) << 2)) +#define PG_POOL_L1VEND (PG_POOL_L1VBASE + (CONFIG_PAGING_NVPAGED << 2)) + +#define PG_POOL_VA2L2NDX(va) (((va) - PG_PAGED_VBASE) >> PAGESHIFT) +#define PG_POOL_NDX2VA(ndx) (((ndx) << PAGESHIFT) + PG_PAGED_VBASE) +#define PG_POOL_MAXL2NDX PG_POOL_VA2L2NDX(PG_PAGED_VEND) + +#define PG_POOL_PGPADDR(ndx) (PG_PAGED_PBASE + ((ndx) << PAGESHIFT)) +#define PG_POOL_PGVADDR(ndx) (PG_PAGED_VBASE + ((ndx) << PAGESHIFT)) + +#endif /* CONFIG_PAGING */ + /************************************************************************************ * Assemby Macros ************************************************************************************/ #ifdef __ASSEMBLY__ -/* Write the Domain Access Control Register (DACR) */ +/************************************************************************************ + * Name: cp15_wrdacr + * + * Description: + * Write the Domain Access Control Register (DACR) + * + * Inputs: + * dacr - The new value of the DACR + * + ************************************************************************************/ .macro cp15_wrdacr, dacr mcr p15, 0, \dacr, c3, c0, 0 @@ -238,12 +744,20 @@ nop .endm -/* The ARMv7-aA architecture supports two translation tables. This - * implementation, however, uses only translation table 0. This - * macro writes the address of the page table to the Translation - * Table Base Register 0 (TTBR0) . Then it clears the TTB control - * register (TTBCR), indicating that we are using TTB 0it. - */ +/************************************************************************************ + * Name: cp14_wrttb + * + * Description: + * The ARMv7-aA architecture supports two translation tables. This + * implementation, however, uses only translation table 0. This + * function writes the address of the page table to the Translation + * Table Base Register 0 (TTBR0). Then it clears the TTB control + * register (TTBCR), indicating that we are using TTBR0. + * + * Inputs: + * ttb - The new value of the TTBR0 register + * + ************************************************************************************/ .macro cp14_wrttb, ttb, scratch mcr p15, 0, \ttb, c2, c0, 0 @@ -259,6 +773,154 @@ mcr p15, 0, \scratch, c2, c0, 2 .endm +/************************************************************************************ + * Name: pg_l2map + * + * Description: + * Write several, contiguous L2 page table entries. npages entries will be + * written. This macro is used when CONFIG_PAGING is enable. This case, + * it is used asfollows: + * + * ldr r0, =PGTABLE_L2_BASE_PADDR <-- Address in L2 table + * ldr r1, =PG_LOCKED_PBASE <-- Physical page memory address + * ldr r2, =CONFIG_PAGING_NLOCKED <-- number of pages + * ldr r3, =MMUFLAGS <-- L2 MMU flags + * pg_l2map r0, r1, r2, r3, r4 + * + * Inputs: + * l2 - Physical or virtual start address in the L2 page table, depending + * upon the context. (modified) + * ppage - The physical address of the start of the region to span. Must + * be aligned to 1Mb section boundaries (modified) + * npages - Number of pages to write in the section (modified) + * mmuflags - L2 MMU FLAGS + * + * Scratch registers (modified): tmp + * l2 - Next address in the L2 page table. + * ppage - Start of next physical page + * npages - Loop counter + * tmp - scratch + * + * Assumptions: + * - The MMU is not yet enabled + * - The L2 page tables have been zeroed prior to calling this function + * - pg_l1span has been called to initialize the L1 table. + * + ************************************************************************************/ + +#ifdef CONFIG_PAGING + .macro pg_l2map, l2, ppage, npages, mmuflags, tmp + b 2f +1: + /* Write the one L2 entries. First, get tmp = (ppage | mmuflags), + * the value to write into the L2 PTE + */ + + orr \tmp, \ppage, \mmuflags + + /* Write value into table at the current table address + * (and increment the L2 page table address by 4) + */ + + str \tmp, [\l2], #4 + + /* Update the physical address that will correspond to the next + * table entry. + */ + + add \ppage, \ppage, #CONFIG_PAGING_PAGESIZE + + /* Decrement the number of pages written */ + + sub \npages, \npages, #1 +2: + /* Check if all of the pages have been written. If not, then + * loop and write the next PTE. + */ + + cmp \npages, #0 + bgt 1b + .endm +#endif /* CONFIG_PAGING */ + +/************************************************************************************ + * Name: pg_l1span + * + * Description: + * Write several, contiguous unmapped coarse L1 page table entries. As + * many entries will be written as many as needed to span npages. This + * macro is used when CONFIG_PAGING is enable. This case, it is used as + * follows: + * + * ldr r0, =PG_L1_PGTABLE_PADDR <-- Address in the L1 table + * ldr r1, =PG_L2_PGTABLE_PADDR <-- Physical address of L2 page table + * ldr r2, =PG_PGTABLE_NPAGES <-- Total number of pages + * ldr r3, =PG_PGTABLE_NPAGE1 <-- Number of pages in the first PTE + * ldr r4, =MMU_L1_PGTABFLAGS <-- L1 MMU flags + * pg_l1span r0, r1, r2, r3, r4, r4 + * + * Inputs (unmodified unless noted): + * l1 - Physical or virtual address in the L1 table to begin writing (modified) + * l2 - Physical start address in the L2 page table (modified) + * npages - Number of pages to required to span that memory region (modified) + * ppage - The number of pages in page 1 (modified) + * mmuflags - L1 MMU flags to use + * + * Scratch registers (modified): l1, l2, npages, tmp + * l1 - Next L1 table address + * l2 - Physical start address of the next L2 page table + * npages - Loop counter + * ppage - After the first page, this will be the full number of pages. + * tmp - scratch + * + * Return: + * Nothing of interest. + * + * Assumptions: + * - The MMU is not yet enabled + * - The L2 page tables have been zeroed prior to calling this function + * + ************************************************************************************/ + +#ifdef CONFIG_PAGING + .macro pg_l1span, l1, l2, npages, ppage, mmuflags, tmp + b 2f +1: + /* Write the L1 table entry that refers to this (unmapped) coarse page + * table. + * + * tmp = (l2table | mmuflags), the value to write into the page table + */ + + orr \tmp, \l2, \mmuflags + + /* Write the value into the L1 table at the correct offset. + * (and increment the L1 table address by 4) + */ + + str \tmp, [\l1], #4 + + /* Update the L2 page table address for the next L1 table entry. */ + + add \l2, \l2, #PT_SIZE /* Next L2 page table start address */ + + /* Update the number of pages that we have account for (with + * non-mappings). NOTE that the first page may have fewer than + * the maximum entries per page table. + */ + + sub \npages, \npages, \ppage + mov \ppage, #PTE_NPAGES +2: + /* Check if all of the pages have been written. If not, then + * loop and write the next L1 entry. + */ + + cmp \npages, #0 + bgt 1b + .endm + +#endif /* CONFIG_PAGING */ #endif /* __ASSEMBLY__ */ /************************************************************************************ @@ -267,13 +929,30 @@ #ifndef __ASSEMBLY__ -/* Write the Domain Access Control Register (DACR) */ +#endif /* __ASSEMBLY__ */ + +/******************************************************************************************** + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Name: cp15_wrdacr + * + * Description: + * Write the Domain Access Control Register (DACR) + * + * Inputs: + * dacr - The new value of the DACR + * + ************************************************************************************/ static inline void cp15_wrdacr(unsigned int dacr) { __asm__ __volatile__ ( - "\tmcr p15, 0, $0, c3, c0, 0\n" + "\tmcr p15, 0,0, c3, c0, 0\n" "\tnop\n" "\tnop\n" "\tnop\n" @@ -288,18 +967,26 @@ static inline void cp15_wrdacr(unsigned int dacr) ); } -/* The ARMv7-aA architecture supports two translation tables. This - * implementation, however, uses only translation table 0. This - * function writes the address of the page table to the Translation - * Table Base Register 0 (TTBR0). Then it clears the TTB control - * register (TTBCR), indicating that we are using TTBR0. - */ +/************************************************************************************ + * Name: cp14_wrttb + * + * Description: + * The ARMv7-aA architecture supports two translation tables. This + * implementation, however, uses only translation table 0. This + * function writes the address of the page table to the Translation + * Table Base Register 0 (TTBR0). Then it clears the TTB control + * register (TTBCR), indicating that we are using TTBR0. + * + * Inputs: + * ttb - The new value of the TTBR0 register + * + ************************************************************************************/ static inline void cp14_wrttb(unsigned int ttb) { __asm__ __volatile__ ( - "\tmcr p15, 0, $0, c2, c0, 0\n" + "\tmcr p15, 0,0, c2, c0, 0\n" "\tnop\n" "\tnop\n" "\tnop\n" @@ -318,13 +1005,13 @@ static inline void cp14_wrttb(unsigned int ttb) #endif /* __ASSEMBLY__ */ -/**************************************************************************** +/************************************************************************************ * Public Variables - ****************************************************************************/ + ************************************************************************************/ -/**************************************************************************** +/************************************************************************************ * Public Function Prototypes - ****************************************************************************/ + ************************************************************************************/ #ifndef __ASSEMBLY__ #ifdef __cplusplus diff --git a/arch/arm/src/sama5/Make.defs b/arch/arm/src/sama5/Make.defs index a9657c3f55..74b8c4c685 100644 --- a/arch/arm/src/sama5/Make.defs +++ b/arch/arm/src/sama5/Make.defs @@ -35,7 +35,7 @@ HEAD_ASRC = arm_head.S -CMN_ASRCS = arm_vectors.S arm_vectortab.S arm_cache.S +CMN_ASRCS = arm_vectors.S arm_vectortab.S arm_cache.S arm_fpuconfig.S CMN_ASRCS += arm_fullcontextrestore.S arm_saveusercontext.S CMN_ASRCS += arm_vectoraddrexcptn.S arm_vfork.S @@ -61,4 +61,4 @@ endif CHIP_ASRCS = -CHIP_CSRCS = +CHIP_CSRCS = sam_boot.c diff --git a/arch/arm/src/sama5/chip/sama5d3x_memorymap.h b/arch/arm/src/sama5/chip/sama5d3x_memorymap.h index 70bc3c28f1..e878e9e10c 100644 --- a/arch/arm/src/sama5/chip/sama5d3x_memorymap.h +++ b/arch/arm/src/sama5/chip/sama5d3x_memorymap.h @@ -41,7 +41,7 @@ ************************************************************************************/ #include -#include "chip.h" +#include /************************************************************************************ * Pre-processor Definitions @@ -64,8 +64,9 @@ #define SAM_BOOTMEM_PSECTION 0x00000000 /* 0x00000000-0x000fffff: Boot memory */ #define SAM_ROM_PSECTION 0x00100000 /* 0x00100000-0x001fffff: ROM */ #define SAM_NFCSRAM_PSECTION 0x00200000 /* 0x00200000-0x002fffff: NFC SRAM */ -#define SAM_SRAM0_PSECTION 0x00300000 /* 0x00300000-0x0030ffff: SRAM0 */ -#define SAM_SRAM1_PSECTION 0x00310000 /* 0x00310000-0x003fffff: SRAM1 */ +#define SAM_ISRAM_PSECTION 0x00300000 /* 0x00300000-0x0030ffff: SRAM */ +# define SAM_ISRAM0_PADDR 0x00300000 /* 0x00300000-0x0030ffff: SRAM0 */ +# define SAM_ISRAM1_PADDR 0x00310000 /* 0x00310000-0x003fffff: SRAM1 */ #define SAM_SMD_PSECTION 0x00400000 /* 0x00400000-0x004fffff: SMD */ #define SAM_UDPHSRAM_PSECTION 0x00500000 /* 0x00500000-0x005fffff: UDPH SRAM */ #define SAM_UHPOHCI_PSECTION 0x00600000 /* 0x00600000-0x006fffff: UHP OHCI */ @@ -154,7 +155,8 @@ #define SAM_BOOTMEM_SIZE (1*1024*1024) /* 0x00000000-0x000fffff: Boot memory */ #define SAM_ROM_SIZE (1*1024*1024) /* 0x00100000-0x001fffff: ROM */ #define SAM_NFCSRAM_SIZE (1*1024*1024) /* 0x00200000-0x002fffff: NFC SRAM */ -#define SAM_SRAM_SIZE (1*1024*1024) /* 0x00300000-0x0030ffff: SRAM0 and SRAM1 */ + /* 0x00300000-0x003fffff: SRAM0 and SRAM1 */ +#define SAM_ISRAM_SIZE (64*1024 + SAM_ISRAM1_SIZE) #define SAM_SMD_SIZE (1*1024*1024) /* 0x00400000-0x004fffff: SMD */ #define SAM_UDPHSRAM_SIZE (1*1024*1024) /* 0x00500000-0x005fffff: UDPH SRAM */ #define SAM_UHPOHCI_SIZE (1*1024*1024) /* 0x00600000-0x006fffff: UHP OHCI */ @@ -180,7 +182,7 @@ #define SAM_BOOTMEM_NSECTIONS _NSECTIONS(SAM_BOOTMEM_SIZE) #define SAM_ROM_NSECTIONS _NSECTIONS(SAM_ROM_SIZE) #define SAM_NFCSRAM_NSECTIONS _NSECTIONS(SAM_NFCSRAM_SIZE) -#define SAM_SRAM_NSECTION S _NSECTIONS(SAM_SRAM_SIZE) +#define SAM_ISRAM_NSECTIONS _NSECTIONS(SAM_ISRAM_SIZE) #define SAM_SMD_NSECTIONS _NSECTIONS(SAM_SMD_SIZE) #define SAM_UDPHSRAM_NSECTIONS _NSECTIONS(SAM_UDPHSRAM_SIZE) #define SAM_UHPOHCI_NSECTIONS _NSECTIONS(SAM_UHPOHCI_SIZE) @@ -204,7 +206,7 @@ #define SAM_BOOTMEM_MMUFLAGS MMU_ROMFLAGS #define SAM_ROM_MMUFLAGS MMU_ROMFLAGS #define SAM_NFCSRAM_MMUFLAGS MMU_IOFLAGS -#define SAM_SRAM_MMUFLAGS MMU_MEMFLAGS +#define SAM_ISRAM_MMUFLAGS MMU_MEMFLAGS #define SAM_SMD_MMUFLAGS MMU_MEMFLAGS #define SAM_UDPHSRAM_MMUFLAGS MMU_IOFLAGS #define SAM_UHPOHCI_MMUFLAGS MMU_IOFLAGS @@ -242,9 +244,9 @@ # define SAM_BOOTMEM_VSECTION 0x00000000 /* 0x00000000-0x000fffff: Boot memory */ # define SAM_ROM_VSECTION 0x00100000 /* 0x00100000-0x001fffff: ROM */ # define SAM_NFCSRAM_VSECTION 0x00200000 /* 0x00200000-0x002fffff: NFC SRAM */ -# define SAM_SRAM_VSECTION 0x00300000 /* 0x00300000-0x0030ffff: SRAM0 */ -# define SAM_SRAM0_VADDR 0x00300000 /* 0x00300000-0x0030ffff: SRAM0 */ -# define SAM_SRAM1_VADDR 0x00310000 /* 0x00310000-0x003fffff: SRAM1 */ +# define SAM_ISRAM_VSECTION 0x00300000 /* 0x00300000-0x0030ffff: SRAM */ +# define SAM_ISRAM0_VADDR 0x00300000 /* 0x00300000-0x0030ffff: SRAM0 */ +# define SAM_ISRAM1_VADDR 0x00310000 /* 0x00310000-0x003fffff: SRAM1 */ # define SAM_SMD_VSECTION 0x00400000 /* 0x00400000-0x004fffff: SMD */ # define SAM_UDPHSRAM_VSECTION 0x00500000 /* 0x00500000-0x005fffff: UDPH SRAM */ # define SAM_UHPOHCI_VSECTION 0x00600000 /* 0x00600000-0x006fffff: UHP OHCI */ @@ -278,7 +280,7 @@ #elif defined(CONFIG_BOOT_RUNFROMEXTSRAM) # define NUTTX_START_VADDR CONFIG_SAMA5_SRAM_VBASE #else /* CONFIG_BOOT_RUNFROMISRAM, CONFIG_PAGING */ -# define NUTTX_START_VADDR SAM_SRAM_VSECTION +# define NUTTX_START_VADDR SAM_ISRAM_VSECTION #endif /* Determine the address of the MMU page table. We will try to place that page @@ -308,63 +310,53 @@ # ifdef CONFIG_ARCH_ROMPGTABLE # error "CONFIG_ARCH_ROMPGTABLE defined; PGTABLE_BASE_P/VADDR not defined" +# endif + + /* If CONFIG_PAGING is selected, then parts of the 1-to-1 virtual memory + * map probably do not apply because paging logic will probably partition + * the SRAM section differently. In particular, if the page table is located + * at the end of SRAM, then the virtual page table address defined below + * will probably be in error. In that case PGTABLE_BASE_VADDR is defined + * in the file mmu.h + * + * We must declare the page table in ISRAM0 or 1. We decide depending upon + * where the vector table was place. + */ + +# ifdef CONFIG_ARCH_LOWVECTORS /* Vectors located at 0x0000:0000 */ + + /* In this case, table must lie at the top 16Kb of ISRAM1 (or ISRAM0 if ISRAM1 + * is not available in this architecture) + * + * If CONFIG_PAGING is defined, then mmu.h assign the virtual address + * of the page table. + */ + +# if SAM_ISRAM1_SIZE > 0 +# define PGTABLE_BASE_PADDR (SAM_ISRAM1_PADDR+SAM_ISRAM1_SIZE-PGTABLE_SIZE) +# ifndef CONFIG_PAGING +# define PGTABLE_BASE_VADDR (SAM_ISRAM1_VADDR+SAM_ISRAM1_SIZE-PGTABLE_SIZE) +# endif +# else +# define PGTABLE_BASE_PADDR (SAM_ISRAM0_PADDR+SAM_ISRAM0_SIZE-PGTABLE_SIZE) +# ifndef CONFIG_PAGING +# define PGTABLE_BASE_VADDR (SAM_ISRAM0_VADDR+SAM_ISRAM0_SIZE-PGTABLE_SIZE) +# endif +# endif +# define PGTABLE_IN_HIGHSRAM 1 # else - /* If CONFIG_PAGING is selected, then parts of the 1-to-1 virtual memory - * map probably do not apply because paging logic will probably partition - * the SRAM section differently. In particular, if the page table is located - * at the end of SRAM, then the virtual page table address defined below - * will probably be in error. - * - * We work around this header file interdependency by (1) insisting that - * pg_macros.h be included AFTER this header file, then (2) allowing the - * pg_macros.h header file to redefine PGTABLE_BASE_VADDR. - */ + /* Otherwise, ISRAM1 (or ISRAM0 if ISRAM1 is not available in this + * architecture) will be mapped so that the end of the SRAM region will + * provide memory for the vectors. The page table will then be places at + * the first 16Kb of ISRAM0. + */ -# if defined(CONFIG_PAGING) && defined(__ARCH_ARM_SRC_ARM_PG_MACROS_H) -# error "pg_macros.h must be included AFTER this header file" -# endif - - - /* We must declare the page table in ISRAM0 or 1. We decide depending upon - * where the vector table was place. - */ - -# ifdef CONFIG_ARCH_LOWVECTORS /* Vectors located at 0x0000:0000 */ - - /* In this case, ISRAM0 will be shadowed at address 0x0000:0000. The page - * table must lie at the top 16Kb of ISRAM1 (or ISRAM0 if this is a ISRAM1 is - * not available in this architecture) - */ - -# ifdef HAVE_INTSRAM1 -# define PGTABLE_BASE_PADDR (SAM_INTSRAM1_PADDR+SAM_INTSRAM1_SIZE-PGTABLE_SIZE) -# define PGTABLE_BASE_VADDR (SAM_INTSRAM1_VADDR+SAM_INTSRAM1_SIZE-PGTABLE_SIZE) -# else -# define PGTABLE_BASE_PADDR (SAM_INTSRAM0_PADDR+SAM_INTSRAM0_SIZE-PGTABLE_SIZE) -# define PGTABLE_BASE_VADDR (SAM_INTSRAM0_VADDR+SAM_INTSRAM0_SIZE-PGTABLE_SIZE) -# endif -# define PGTABLE_IN_HIGHSRAM 1 - - /* If CONFIG_PAGING is defined, insist that pg_macros.h assign the virtual - * address of the page table. - */ - -# ifdef CONFIG_PAGING -# undef PGTABLE_BASE_VADDR -# endif -# else - - /* Otherwise, ISRAM1 (or ISRAM0 for the is ISRAM1 is not available in this - * architecture) will be mapped so that the end of the SRAM region will - * provide memory for the vectors. The page table will then be places at - * the first 16Kb of ISRAM0 (which will be in the shadow memory region). - */ - -# define PGTABLE_BASE_PADDR SAM_SHADOWSPACE_PSECTION -# define PGTABLE_BASE_VADDR SAM_SHADOWSPACE_VSECTION -# define PGTABLE_IN_LOWSRAM 1 +# define PGTABLE_BASE_PADDR SAM_ISRAM0_PADDR +# ifndef CONFIG_PAGING +# define PGTABLE_BASE_VADDR SAM_ISRAM0_VADDR # endif +# define PGTABLE_IN_LOWSRAM 1 # endif #endif @@ -374,17 +366,12 @@ * portion of this table is not accessible in the virtual address space (for * normal operation). We will reuse this memory for coarse page tables as follows: * - * NOTE: If CONFIG_PAGING is defined, pg_macros.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_COARSE_OFFSET ((((SAM_LAST_PSECTION >> 20) + 255) & ~255) << 2) -#define PGTABLE_L2_COARSE_PBASE (PGTABLE_BASE_PADDR+PGTABLE_L2_COARSE_OFFSET) -#define PGTABLE_L2_COARSE_VBASE (PGTABLE_BASE_VADDR+PGTABLE_L2_COARSE_OFFSET) - -#define PGTABLE_L2_FINE_OFFSET ((((SAM_LAST_PSECTION >> 20) + 1023) & ~1023) << 2) -#define PGTABLE_L2_FINE_PBASE (PGTABLE_BASE_PADDR+PGTABLE_L2_FINE_OFFSET) -#define PGTABLE_L2_FINE_VBASE (PGTABLE_BASE_VADDR+PGTABLE_L2_FINE_OFFSET) +#define PGTABLE_L2_PBASE (PGTABLE_BASE_PADDR+0x00000800) +#define PGTABLE_L2_VBASE (PGTABLE_BASE_VADDR+0x00000800) /* Page table end addresses: */ @@ -393,13 +380,9 @@ /* Page table sizes */ -#define PGTABLE_L2_COARSE_ALLOC (PGTABLE_L2_END_VADDR-PGTABLE_L2_COARSE_VBASE) -#define PGTABLE_COARSE_TABLE_SIZE (4*256) -#define PGTABLE_NCOARSE_TABLES (PGTABLE_L2_COARSE_ALLOC / PGTABLE_COARSE_TABLE_SIZE) - -#define PGTABLE_L2_FINE_ALLOC (PGTABLE_L2_END_VADDR-PGTABLE_L2_FINE_VBASE) -#define PGTABLE_FINE_TABLE_SIZE (4*1024) -#define PGTABLE_NFINE_TABLES (PGTABLE_L2_FINE_ALLOC / PGTABLE_FINE_TABLE_SIZE) +#define PGTABLE_L2_ALLOC (PGTABLE_L2_END_VADDR-PGTABLE_L2_VBASE) +#define PGTABLE_L2_SIZE (4*256) +#define PGTABLE_L2_NENTRIES (PGTABLE_L2_ALLOC / PGTABLE_L2_SIZE) /* Determine the base address of the vector table: * @@ -410,17 +393,17 @@ #define VECTOR_TABLE_SIZE 0x00010000 #ifdef CONFIG_ARCH_LOWVECTORS /* Vectors located at 0x0000:0000 */ -# define SAM_VECTOR_PADDR SAM_INTSRAM0_PADDR -# define SAM_VECTOR_VSRAM SAM_INTSRAM0_VADDR +# define SAM_VECTOR_PADDR SAM_ISRAM0_PADDR +# define SAM_VECTOR_VSRAM SAM_ISRAM0_VADDR # define SAM_VECTOR_VADDR 0x00000000 # define SAM_VECTOR_VCOARSE 0x00000000 #else /* Vectors located at 0xffff:0000 -- this probably does not work */ -# ifdef HAVE_INTSRAM1 -# define SAM_VECTOR_PADDR (SAM_INTSRAM1_PADDR+SAM_INTSRAM1_SIZE-VECTOR_TABLE_SIZE) -# define SAM_VECTOR_VSRAM (SAM_INTSRAM1_VADDR+SAM_INTSRAM1_SIZE-VECTOR_TABLE_SIZE) +# ifdef HAVE_ISRAM1 +# define SAM_VECTOR_PADDR (SAM_ISRAM1_PADDR+SAM_ISRAM1_SIZE-VECTOR_TABLE_SIZE) +# define SAM_VECTOR_VSRAM (SAM_ISRAM1_VADDR+SAM_ISRAM1_SIZE-VECTOR_TABLE_SIZE) # else -# define SAM_VECTOR_PADDR (SAM_INTSRAM0_PADDR+SAM_INTSRAM0_SIZE-VECTOR_TABLE_SIZE) -# define SAM_VECTOR_VSRAM (SAM_INTSRAM0_VADDR+SAM_INTSRAM0_SIZE-VECTOR_TABLE_SIZE) +# define SAM_VECTOR_PADDR (SAM_ISRAM0_PADDR+SAM_ISRAM0_SIZE-VECTOR_TABLE_SIZE) +# define SAM_VECTOR_VSRAM (SAM_ISRAM0_VADDR+SAM_ISRAM0_SIZE-VECTOR_TABLE_SIZE) # endif # define SAM_VECTOR_VADDR 0xffff0000 # define SAM_VECTOR_VCOARSE 0xfff00000 diff --git a/arch/arm/src/sama5/sam_boot.c b/arch/arm/src/sama5/sam_boot.c new file mode 100644 index 0000000000..d234190e3d --- /dev/null +++ b/arch/arm/src/sama5/sam_boot.c @@ -0,0 +1,420 @@ +/************************************************************************************ + * arch/arm/src/sama5/sam_boot.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#include + +#ifdef CONFIG_PAGING +# include +#endif + +#include + +#include "chip.h" +#include "arm.h" +#include "mmu.h" +#include "fpu.h" +#include "up_internal.h" +#include "up_arch.h" + +#include "sam_clockconfig.h" +#include "sam_lowputc.h" + +/************************************************************************************ + * Private Types + ************************************************************************************/ + +/************************************************************************************ + * 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 + ************************************************************************************/ + +extern uint32_t _vector_start; /* Beginning of vector block */ +extern uint32_t _vector_end; /* End+1 of vector block */ + +/************************************************************************************ + * Private Variables + ************************************************************************************/ + +/* This table describes how to map a set of 1Mb pages to space the physical address + * space of the SAMA5. + */ + +#ifndef CONFIG_ARCH_ROMPGTABLE +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, + 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}, +#endif + { 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_AXIMATRIX_PSECTION, SAM_AXIMATRIX_VSECTION, + SAM_AXIMATRIX_MMUFLAGS, SAM_AXIMATRIX_NSECTIONS}, + { SAM_DAP_PSECTION, SAM_DAP_VSECTION, + SAM_DAP_MMUFLAGS, SAM_DAP_NSECTIONS}, + +/* SAMA5 External Memories */ + +#ifdef CONFIG_SAMA5_EBISC0 + { SAM_EBICS0_PSECTION, SAM_EBICS0_VSECTION, + SAM_EBICS0_MMUFLAGS, SAM_EBICS0_NSECTIONS}, +#endif +#ifdef CONFIG_SAMA5_DDRCS + { SAM_DDRCS_PSECTION, SAM_DDRCS_VSECTION, + SAM_DDRCS_MMUFLAGS, SAM_DDRCS_NSECTIONS}, +#endif +#ifdef CONFIG_SAMA5_EBISC1 + { SAM_EBICS1_PSECTION, SAM_EBICS1_VSECTION, + SAM_EBICS1_MMUFLAGS, SAM_EBICS1_NSECTIONS}, +#endif +#ifdef CONFIG_SAMA5_EBISC2 + { SAM_EBICS2_PSECTION, SAM_EBICS2_VSECTION, + SAM_EBICS2_MMUFLAGS, SAM_EBICS2_NSECTIONS}, +#endif +#ifdef CONFIG_SAMA5_EBISC3 + { 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}, +#endif + +/* SAMA5 Internal Peripherals */ + + { SAM_PERIPHA_PSECTION, SAM_PERIPHA_VSECTION, + 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}, +}; +#define NMAPPINGS (sizeof(section_mapping) / sizeof(struct section_mapping_s)) +#endif + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: sam_setlevel1entry + ************************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +static inline void sam_setlevel1entry(uint32_t paddr, uint32_t vaddr, + uint32_t mmuflags) +{ + uint32_t *pgtable = (uint32_t*)PGTABLE_BASE_VADDR; + uint32_t index = vaddr >> 20; + + /* Save the page table entry */ + + pgtable[index] = (paddr | mmuflags); +} +#endif + +/************************************************************************************ + * Name: sam_setlevel2coarseentry + ************************************************************************************/ + +static inline void sam_setlevel2coarseentry(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 + ************************************************************************************/ + +#ifndef CONFIG_ARCH_ROMPGTABLE +static void sam_setupmappings(void) +{ + int i, j; + + 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_setlevel1entry(sect_paddr, sect_vaddr, mmuflags); + sect_paddr += SECTION_SIZE; + sect_vaddr += SECTION_SIZE; + } + } +} +#endif + +/************************************************************************************ + * Name: sam_vectorpermissions + * + * Description: + * Set permissions on the vector mapping. + * + ************************************************************************************/ + +#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 */ + + uint32_t *ptr = (uint32_t*)PG_L2_VECT_VADDR; + uint32_t pte; + + /* The pte might be zero the first time this function is called. */ + + pte = *ptr; + if (pte == 0) + { + pte = PG_VECT_PBASE; + } + else + { + pte &= PG_L1_PADDRMASK; + } + + /* Update the MMU flags and save */ + + *ptr = pte | mmuflags; + + /* Invalid the TLB for this address */ + + tlb_invalidate_single(PG_L2_VECT_VADDR); +} +#endif + +/************************************************************************************ + * Name: sam_vectormapping + * + * Description: + * Setup a special mapping for the interrupt vectors when (1) the interrupt + * vectors are not positioned in ROM, and when (2) the interrupt vectors are + * located at the high address, 0xffff0000. When the interrupt vectors are located + * in ROM, we just have to assume that they were set up correctly; When vectors + * are located in low memory, 0x00000000, the shadow memory region will be mapped + * to support them. + * + ************************************************************************************/ + +#if !defined(CONFIG_ARCH_ROMPGTABLE) && !defined(CONFIG_ARCH_LOWVECTORS) +static void sam_vectormapping(void) +{ + uint32_t vector_paddr = SAM_VECTOR_PADDR; + uint32_t vector_vaddr = SAM_VECTOR_VADDR; + uint32_t end_paddr = vector_paddr + VECTOR_TABLE_SIZE; + + /* We want to keep our interrupt vectors and interrupt-related logic in zero-wait + * state internal RAM (IRAM). The DM320 has 16Kb of IRAM positioned at physical + * address 0x0000:0000; we need to map this to 0xffff:0000. + */ + + while (vector_paddr < end_paddr) + { + sam_setlevel2coarseentry(PGTABLE_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_setlevel1entry(PGTABLE_L2_PBASE, SAM_VECTOR_VCOARSE, + MMU_L1_VECTORFLAGS); +} +#endif + +/************************************************************************************ + * Name: sam_copyvectorblock + * + * Description: + * Copy the interrupt block to its final destination. + * + ************************************************************************************/ + +static void sam_copyvectorblock(void) +{ + uint32_t *src; + uint32_t *end; + uint32_t *dest; + + /* If we are using vectors in low memory but RAM in that area has been marked + * read only, then temparily mark the mapping write-able (non-buffered). + */ + +#if !defined(CONFIG_ARCH_ROMPGTABLE) && defined(CONFIG_ARCH_LOWVECTORS) && defined(CONFIG_PAGING) + sam_vectorpermissions(MMU_L2_VECTRWFLAGS); +#endif + + /* Copy the vectors into ISRAM at the address that will be mapped to the vector + * address: + * + * SAM_VECTOR_PADDR - Unmapped, physical address of vector table in SRAM + * SAM_VECTOR_VSRAM - Virtual address of vector table in SRAM + * SAM_VECTOR_VADDR - Virtual address of vector table (0x00000000 or 0xffff0000) + */ + + src = (uint32_t*)&_vector_start; + end = (uint32_t*)&_vector_end; + dest = (uint32_t*)SAM_VECTOR_VSRAM; + + while (src < end) + { + *dest++ = *src++; + } + + /* Make the vectors read-only, cacheable again */ + +#if !defined(CONFIG_ARCH_ROMPGTABLE) && defined(CONFIG_ARCH_LOWVECTORS) && defined(CONFIG_PAGING) + sam_vectorpermissions(MMU_L2_VECTROFLAGS); +#endif +} + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: up_boot + * + * Description: + * Complete boot operations started in arm_head.S + * + ************************************************************************************/ + +void up_boot(void) +{ + /* __start provided the basic MMU mappings for SRAM. Now provide mappings for all + * IO regions (Including the vector region). + */ + +#ifndef CONFIG_ARCH_ROMPGTABLE + sam_setupmappings(); + + /* Provide a special mapping for the IRAM interrupt vector positioned in high + * memory. + */ + +#ifndef CONFIG_ARCH_LOWVECTORS + sam_vectormapping(); +#endif +#endif /* CONFIG_ARCH_ROMPGTABLE */ + + /* Setup up vector block. _vector_start and _vector_end are exported from + * arm_vector.S + */ + + sam_copyvectorblock(); + + /* Initialize clocking to settings provided by board-specific logic */ + + sam_clockconfig(); + + /* Initialize the FPU */ + +#ifdef CONFIG_ARCH_FPU + arm_fpuconfig(); +#endif + + /* Perform common, low-level chip initialization (might do nothing) */ + + sam_lowsetup(); + + /* Perform early serial initialization if we are going to use the serial driver */ + +#ifdef USE_EARLYSERIALINIT + sam_earlyserialinit(); +#endif + + /* For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + */ + +#ifdef CONFIG_NUTTX_KERNEL + sam_userspace(); +#endif + + /* Perform board-specific initialization */ + + sam_boardinitialize(); +} diff --git a/arch/arm/src/sama5/sam_clockconfig.h b/arch/arm/src/sama5/sam_clockconfig.h new file mode 100644 index 0000000000..044890ba64 --- /dev/null +++ b/arch/arm/src/sama5/sam_clockconfig.h @@ -0,0 +1,94 @@ +/************************************************************************************ + * arch/arm/src/sama5/sam_clockconfig.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_CLOCKCONFIG_H +#define __ARCH_ARM_SRC_SAMA5_SAM_CLOCKCONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: sam_clockconfig + * + * Description: + * Called to initialize the SAM3/4. This does whatever setup is needed to put the + * SoC in a usable state. This includes the initialization of clocking using the + * settings in board.h. + * + ************************************************************************************/ + +void sam_clockconfig(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_CLOCKCONFIG_H */ diff --git a/arch/arm/src/sama5/sam_lowputc.h b/arch/arm/src/sama5/sam_lowputc.h new file mode 100644 index 0000000000..5a1c15875c --- /dev/null +++ b/arch/arm/src/sama5/sam_lowputc.h @@ -0,0 +1,102 @@ +/************************************************************************************ + * arch/arm/src/sama5/sam_lowputc.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_SAMA5_SAM_LOWPUTC_H +#define __ARCH_ARM_SRC_SAMA5_SAM_LOWPUTC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "up_internal.h" +#include "chip.h" + +/************************************************************************************ + * Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: sam_lowsetup + * + * Description: + * Called at the very beginning of _start. Performs low level initialization + * including setup of the console UART. This UART done early so that the serial + * console is available for debugging very early in the boot sequence. + * + ************************************************************************************/ + +void sam_lowsetup(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_SAMA5_SAM_LOWPUTC_H */ diff --git a/configs/sama5d3x-ek/README.txt b/configs/sama5d3x-ek/README.txt index 8da6d528b0..25049c4688 100644 --- a/configs/sama5d3x-ek/README.txt +++ b/configs/sama5d3x-ek/README.txt @@ -48,11 +48,10 @@ Development Environment GNU Toolchain Options ^^^^^^^^^^^^^^^^^^^^^ - The NuttX make system has been modified to support the several different - toolchain options. + The NuttX make system will support the several different toolchain options. All testing has been conducted using the AtmelStudio GCC toolchain. To use - the CodeSourcery, devkitARM or Raisonance GNU toolchain, you simply need to + the CodeSourcery, devkitARM or other GNU toolchain, you simply need to add add one of the following configuration options to your .config (or defconfig) file: diff --git a/configs/sama5d3x-ek/ostest/setenv.sh b/configs/sama5d3x-ek/ostest/setenv.sh index f079990eba..1378d42985 100755 --- a/configs/sama5d3x-ek/ostest/setenv.sh +++ b/configs/sama5d3x-ek/ostest/setenv.sh @@ -50,12 +50,12 @@ fi # This is the Cygwin path to the location where I installed the Atmel GCC # toolchain under Windows. You will also have to edit this if you install # this toolchain in any other location -#export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/Atmel/Atmel Toolchain/ARM GCC/Native/4.7.3.99/arm-gnu-toolchain/bin" +export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/Atmel/Atmel Toolchain/ARM GCC/Native/4.7.3.99/arm-gnu-toolchain/bin" # This is the Cygwin path to the location where I installed the CodeSourcery # toolchain under windows. You will also have to edit this if you install # the CodeSourcery toolchain in any other location -export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/CodeSourcery/Sourcery G++ Lite/bin" +#export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/CodeSourcery/Sourcery G++ Lite/bin" # These are the Cygwin paths to the locations where I installed the Atollic # toolchain under windows. You will also have to edit this if you install diff --git a/configs/sama5d3x-ek/src/sam_autoleds.c b/configs/sama5d3x-ek/src/sam_autoleds.c new file mode 100644 index 0000000000..29048a3bb0 --- /dev/null +++ b/configs/sama5d3x-ek/src/sam_autoleds.c @@ -0,0 +1,107 @@ +/**************************************************************************** + * configs/sama5d3x-ek/src/sam_autoleds.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include + +#include + +#include "sama5d3x-ek.h" + +#ifdef CONFIG_ARCH_LEDS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* CONFIG_DEBUG_LEDS enables debug output from this file (needs CONFIG_DEBUG + * with CONFIG_DEBUG_VERBOSE too) + */ + +#ifdef CONFIG_DEBUG_LEDS +# define leddbg lldbg +# define ledvdbg llvdbg +#else +# define leddbg(x...) +# define ledvdbg(x...) +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_ledinit + ****************************************************************************/ + +void up_ledinit(void) +{ +# warning Missing logic +} + +/**************************************************************************** + * Name: up_ledon + ****************************************************************************/ + +void up_ledon(int led) +{ +# warning Missing logic +} + +/**************************************************************************** + * Name: up_ledoff + ****************************************************************************/ + +void up_ledoff(int led) +{ +# warning Missing logic +} + +#endif /* CONFIG_ARCH_LEDS */