From aae306e9425b7ceb01e0328b8c2e6deb25e6d2a8 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 26 Nov 2016 12:04:02 -0600 Subject: [PATCH] i.MX6 SMP: Inter-CPU data no saved in a non-cacheable region. --- arch/arm/include/arm/spinlock.h | 57 +++++++++++++++++++++++++ arch/arm/include/armv6-m/spinlock.h | 39 +++++++++++++++++ arch/arm/include/armv7-a/spinlock.h | 39 +++++++++++++++++ arch/arm/include/armv7-m/spinlock.h | 39 +++++++++++++++++ arch/arm/include/armv7-r/spinlock.h | 39 +++++++++++++++++ arch/arm/include/spinlock.h | 20 +++++++++ arch/arm/src/armv7-a/mmu.h | 5 ++- arch/arm/src/common/up_internal.h | 10 +++++ arch/arm/src/imx6/chip/imx_memorymap.h | 18 ++++---- arch/arm/src/imx6/imx_boot.c | 25 ++++++++--- configs/sabre-6quad/scripts/dramboot.ld | 8 ++++ 11 files changed, 283 insertions(+), 16 deletions(-) create mode 100644 arch/arm/include/arm/spinlock.h create mode 100644 arch/arm/include/armv6-m/spinlock.h create mode 100644 arch/arm/include/armv7-a/spinlock.h create mode 100644 arch/arm/include/armv7-m/spinlock.h create mode 100644 arch/arm/include/armv7-r/spinlock.h diff --git a/arch/arm/include/arm/spinlock.h b/arch/arm/include/arm/spinlock.h new file mode 100644 index 0000000000..efe292acb7 --- /dev/null +++ b/arch/arm/include/arm/spinlock.h @@ -0,0 +1,57 @@ +/**************************************************************************** + * arch/arm/include/armv7-a/spinlock.h + * + * Copyright (C) 2016 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_INCLUDE_ARM_SPINLOCK_H +#define __ARCH_ARM_INCLUDE_ARM_SPINLOCK_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_SMP + /* In SMP configurations, save spinlocks and other inter-CPU communications + * data in a non-cached memory region. + */ + +# define SP_SECTION __attribute__((section(.nocache))) +#endif + +#endif /* __ARCH_ARM_INCLUDE_ARM_SPINLOCK_H */ diff --git a/arch/arm/include/armv6-m/spinlock.h b/arch/arm/include/armv6-m/spinlock.h new file mode 100644 index 0000000000..c1d154b370 --- /dev/null +++ b/arch/arm/include/armv6-m/spinlock.h @@ -0,0 +1,39 @@ +/**************************************************************************** + * arch/arm/include/armv7-a/spinlock.h + * + * Copyright (C) 2016 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_INCLUDE_ARMV6_M_SPINLOCK_H +#define __ARCH_ARM_INCLUDE_ARMV6_M_SPINLOCK_H + +#endif /* __ARCH_ARM_INCLUDE_ARMV6_M_SPINLOCK_H */ diff --git a/arch/arm/include/armv7-a/spinlock.h b/arch/arm/include/armv7-a/spinlock.h new file mode 100644 index 0000000000..764a96ecef --- /dev/null +++ b/arch/arm/include/armv7-a/spinlock.h @@ -0,0 +1,39 @@ +/**************************************************************************** + * arch/arm/include/armv7-a/spinlock.h + * + * Copyright (C) 2016 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_INCLUDE_ARMV7_A_SPINLOCK_H +#define __ARCH_ARM_INCLUDE_ARMV7_A_SPINLOCK_H + +#endif /* __ARCH_ARM_INCLUDE_ARMV7_A_SPINLOCK_H */ diff --git a/arch/arm/include/armv7-m/spinlock.h b/arch/arm/include/armv7-m/spinlock.h new file mode 100644 index 0000000000..79a06b4173 --- /dev/null +++ b/arch/arm/include/armv7-m/spinlock.h @@ -0,0 +1,39 @@ +/**************************************************************************** + * arch/arm/include/armv7-a/spinlock.h + * + * Copyright (C) 2016 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_INCLUDE_ARMV7_M_SPINLOCK_H +#define __ARCH_ARM_INCLUDE_ARMV7_M_SPINLOCK_H + +#endif /* __ARCH_ARM_INCLUDE_ARMV7_M_SPINLOCK_H */ diff --git a/arch/arm/include/armv7-r/spinlock.h b/arch/arm/include/armv7-r/spinlock.h new file mode 100644 index 0000000000..ab7900fa73 --- /dev/null +++ b/arch/arm/include/armv7-r/spinlock.h @@ -0,0 +1,39 @@ +/**************************************************************************** + * arch/arm/include/armv7-r/spinlock.h + * + * Copyright (C) 2016 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_INCLUDE_ARMV7_R_SPINLOCK_H +#define __ARCH_ARM_INCLUDE_ARMV7_R_SPINLOCK_H + +#endif /* __ARCH_ARM_INCLUDE_ARMV7_R_SPINLOCK_H */ diff --git a/arch/arm/include/spinlock.h b/arch/arm/include/spinlock.h index 45f26e0006..16079cc81a 100644 --- a/arch/arm/include/spinlock.h +++ b/arch/arm/include/spinlock.h @@ -44,6 +44,26 @@ # include #endif /* __ASSEMBLY__ */ +/* Include ARM architecture-specific IRQ definitions (including register + * save structure and up_irq_save()/up_irq_restore() functions) + */ + +#if defined(CONFIG_ARCH_CORTEXA5) || defined(CONFIG_ARCH_CORTEXA8) || \ + defined(CONFIG_ARCH_CORTEXA9) +# include +#elif defined(CONFIG_ARCH_CORTEXR4) || defined(CONFIG_ARCH_CORTEXR4F) || \ + defined(CONFIG_ARCH_CORTEXR5) || defined(CONFIG_ARCH_CORTEXR5F) || \ + defined(CONFIG_ARCH_CORTEXR7) || defined(CONFIG_ARCH_CORTEXR7F) +# include +#elif defined(CONFIG_ARCH_CORTEXM3) || defined(CONFIG_ARCH_CORTEXM4) || \ + defined(CONFIG_ARCH_CORTEXM7) +# include +#elif defined(CONFIG_ARCH_CORTEXM0) +# include +#else +# include +#endif + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ diff --git a/arch/arm/src/armv7-a/mmu.h b/arch/arm/src/armv7-a/mmu.h index c84deda619..a10b357397 100644 --- a/arch/arm/src/armv7-a/mmu.h +++ b/arch/arm/src/armv7-a/mmu.h @@ -601,11 +601,14 @@ #define MMU_L2_PGTABFLAGS (PTE_TYPE_SMALL | PTE_WRITE_THROUGH | PTE_AP_RW1) #define MMU_L1_VECTORFLAGS (PMD_TYPE_PTE | PMD_PTE_PXN | PMD_PTE_DOM(0)) - #define MMU_L2_VECTRWFLAGS (PTE_TYPE_SMALL | PTE_WRITE_THROUGH | PTE_AP_RW1) #define MMU_L2_VECTROFLAGS (PTE_TYPE_SMALL | PTE_WRITE_THROUGH | PTE_AP_R1) #define MMU_L2_VECTORFLAGS MMU_L2_VECTRWFLAGS +#define MMU_L1_INTERCPUFLAGS (PMD_TYPE_PTE | PMD_PTE_PXN | PMD_DEVICE | \ + PMD_PTE_DOM(0)) +#define MMU_L2_INTERCPUFLAGS (PTE_TYPE_SMALL | PTE_DEVICE | PTE_AP_R1) + /* Mapped section size */ #define SECTION_SHIFT (20) diff --git a/arch/arm/src/common/up_internal.h b/arch/arm/src/common/up_internal.h index 36095a87a4..7318a70caa 100644 --- a/arch/arm/src/common/up_internal.h +++ b/arch/arm/src/common/up_internal.h @@ -191,6 +191,11 @@ # define _DATA_INIT &_eronly # define _START_DATA &_sdata # define _END_DATA &_edata + +#ifdef CONFIG_SMP +# define _START_NOCACHE &_snocache +# define _END_NOCACHE &_enocache +#endif #endif /* This is the value used to mark the stack for subsequent stack monitoring @@ -279,6 +284,11 @@ EXTERN uint32_t _edata; /* End+1 of .data */ EXTERN uint32_t _sbss; /* Start of .bss */ EXTERN uint32_t _ebss; /* End+1 of .bss */ +#ifdef CONFIG_SMP +EXTERN uint32_t _snocache; /* Start of .nocache */ +EXTERN uint32_t _enocache; /* End+1 of .nocache */ +#endif + /* Sometimes, functions must be executed from RAM. In this case, the following * macro may be used (with GCC!) to specify a function that will execute from * RAM. For example, diff --git a/arch/arm/src/imx6/chip/imx_memorymap.h b/arch/arm/src/imx6/chip/imx_memorymap.h index 6f185a0964..7b675e117b 100644 --- a/arch/arm/src/imx6/chip/imx_memorymap.h +++ b/arch/arm/src/imx6/chip/imx_memorymap.h @@ -927,9 +927,9 @@ * 0x80000000 0x803fffff 0x000002000 0x000000400 Vectors (1MiB) * 0x80100000 0x806fffff 0x000002400 0x000001800 Paging (6MiB) * - * If SMP is enabled, then INTERCPU_L2_PAGES pages are taken from the end - * of the Paging L2 page table to hold non-cacheable, inter-processor - * communication data. + * If SMP is enabled, then 1MiB of address spaces for the INTERCPU_L2_PAGES + * pages are taken from the end of the Paging L2 page table to hold non- + * cacheable, inter-processor communication data. */ /* Vector L2 page table offset/size */ @@ -951,7 +951,7 @@ /* Paging L2 page table offset/size */ # define PGTABLE_L2_OFFSET 0x000002400 -# define PGTABLE_L2_SIZE (0x000001800 - 4*INTERCPU_L2_PAGES) +# define PGTABLE_L2_SIZE 0x000001400 # else /* Paging L2 page table offset/size */ @@ -967,16 +967,16 @@ * ---------- ---------- ------------ ---------------------------- * 0x80000000 0x806fffff 0x000002000 0x000001c00 Paging (7MiB) * - * If SMP is enabled, then INTERCPU_L2_PAGES pages are taken from the end - * of the Paging L2 page table to hold non-cacheable, inter-processor - * communication data. + * If SMP is enabled, then 1MiB of address spaces for the INTERCPU_L2_PAGES + * pages are taken from the end of the Paging L2 page table to hold non- + * cacheable, inter-processor communication data. */ # ifdef CONFIG_SMP /* Paging L2 page table offset/size */ # define PGTABLE_L2_OFFSET 0x000002000 -# define PGTABLE_L2_SIZE (0x000001c00 - 4*INTERCPU_L2_PAGES) +# define PGTABLE_L2_SIZE 0x000001800 # else /* Paging L2 page table offset/size */ @@ -1005,7 +1005,7 @@ /* Non-cached inter-processor communication data */ # define INTERCPU_L2_OFFSET (PGTABLE_L2_OFFSET + PGTABLE_L2_SIZE) -# define INTERCPU_L2_SIZE (4*INTERCPU_L2_PAGES) +# define INTERCPU_L2_SIZE (0x00000400) /* Inter-processor communications L2 page table virtual base addresse */ diff --git a/arch/arm/src/imx6/imx_boot.c b/arch/arm/src/imx6/imx_boot.c index b4c36b9540..7e11fba87b 100644 --- a/arch/arm/src/imx6/imx_boot.c +++ b/arch/arm/src/imx6/imx_boot.c @@ -254,9 +254,9 @@ static void imx_intercpu_mapping(void) /* Now set the level 1 descriptor to refer to the level 2 page table. */ - mmu_l1_setentry(VECTOR_L2_PBASE & PMD_PTE_PADDR_MASK, + mmu_l1_setentry(INTERCPU_PBASE & PMD_PTE_PADDR_MASK, INTERCPU_VADDR & PMD_PTE_PADDR_MASK, - MMU_L1_PGTABFLAGS); + MMU_L1_INTERCPUFLAGS); } #else /* No inter-cpu communications area */ @@ -428,8 +428,10 @@ static inline void imx_wdtdisable(void) void arm_boot(void) { -#ifdef CONFIG_ARCH_RAMFUNCS +#if defined(CONFIG_ARCH_RAMFUNCS) const uint32_t *src; +#endif +#if defined(CONFIG_ARCH_RAMFUNCS) || defined(CONFIG_SMP) uint32_t *dest; #endif @@ -541,10 +543,21 @@ void arm_boot(void) imx_lowputc('L'); #endif +#ifdef CONFIG_SMP + /* Initialize the uncached, inter-CPU communications area */ + + for (dest = &_snocache; dest < &_enocache; ) + { + *dest++ = 0; + } + + imx_lowputc('M'); +#endif + /* Perform common, low-level chip initialization (might do nothing) */ imx_lowsetup(); - imx_lowputc('M'); + imx_lowputc('N'); #ifdef USE_EARLYSERIALINIT /* Perform early serial initialization if we are going to use the serial @@ -552,7 +565,7 @@ void arm_boot(void) */ imx_earlyserialinit(); - imx_lowputc('N'); + imx_lowputc('O'); #endif /* Now we can enable all other CPUs. The enabled CPUs will start execution @@ -561,6 +574,6 @@ void arm_boot(void) */ imx_cpu_enable(); - imx_lowputc('O'); + imx_lowputc('P'); imx_lowputc('\n'); } diff --git a/configs/sabre-6quad/scripts/dramboot.ld b/configs/sabre-6quad/scripts/dramboot.ld index f1134bcc92..de4b7a33dd 100644 --- a/configs/sabre-6quad/scripts/dramboot.ld +++ b/configs/sabre-6quad/scripts/dramboot.ld @@ -46,6 +46,7 @@ MEMORY { oscram (W!RX) : ORIGIN = 0x00900000, LENGTH = 256K - 16K ddr3 (W!RX) : ORIGIN = 0x10800000, LENGTH = 1024M - 8M + nocache (WR) : ORIGIN = 0x80600000, LENGTH = 4K } OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") @@ -122,6 +123,13 @@ SECTIONS _enoinit = ABSOLUTE(.); } > ddr3 + .nocache : + { + _snocache = ABSOLUTE(.); + *(.nocache) + _enocache = ABSOLUTE(.); + } > nocahce + /* Stabs debugging sections. */ .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) }