mirror of
https://github.com/apache/nuttx.git
synced 2026-06-07 09:18:00 +08:00
Merged nuttx/nuttx into master
This commit is contained in:
@@ -4920,34 +4920,6 @@ Mem: 29232 5920 23312 23312
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><br></td>
|
||||
<td><hr></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><br></td>
|
||||
<td>
|
||||
<p>
|
||||
<b>RGMP</b>.
|
||||
RGMP stands for RTOS and GPOS on Multi-Processor.
|
||||
RGMP is a project for running GPOS and RTOS simultaneously on multi-processor platforms
|
||||
You can port your favorite RTOS to RGMP together with an unmodified Linux to form a hybrid operating system.
|
||||
This makes your application able to use both RTOS and GPOS features.
|
||||
</p>
|
||||
<p>
|
||||
See the <a href="http://rgmp.sourceforge.net/wiki/index.php/Main_Page">RGMP Wiki</a> for further information about RGMP.
|
||||
</p>
|
||||
<ul>
|
||||
<p>
|
||||
<b>STATUS:</b>
|
||||
This initial port of NuttX to RGMP was provided in NuttX-6.3.
|
||||
This initial RGP port provides only minimal driver support and does not use the native NuttX interrupt system.
|
||||
This is a great, stable starting point for anyone interest in working with NuttX under RGMP!
|
||||
Refer to the NuttX <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/rgmp/README.txt" target="_blank">README</a> file for further information.
|
||||
</p>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top"><img height="20" width="20" src="favicon.ico"></td>
|
||||
<td bgcolor="#5eaee1">
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<tr align="center" bgcolor="#e4e4e4">
|
||||
<td>
|
||||
<h1><big><font color="#3c34ec"><i>NuttX README Files</i></font></big></h1>
|
||||
<p>Last Updated: November 14, 2016</p>
|
||||
<p>Last Updated: December 4, 2016</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -203,8 +203,6 @@ nuttx/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/pirelli_dpl10/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
| |- qemu-i486/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/qemu-i486/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
| |- rgmp/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/rgmp/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
| |- sabre-6quad/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/sabre-6quad/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
| |- sama5d2-xult/
|
||||
@@ -223,6 +221,8 @@ nuttx/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/saml21-xplained/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
| |- sam3u-ek/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/sam3u-ek/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
| |- sam4cmp-db
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/sam4cmp-d/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
| |- sam4e-ek/
|
||||
| | `- <a href="https://bitbucket.org/nuttx/nuttx/src/master/configs/sam4e-ek/README.txt" target="_blank"><b><i>README.txt</i></b></a>
|
||||
| |- sam4l-xplained/
|
||||
|
||||
+2
-2
@@ -1419,8 +1419,6 @@ nuttx/
|
||||
| | `- README.txt
|
||||
| |- qemu-i486/
|
||||
| | `- README.txt
|
||||
| |- rgmp/
|
||||
| | `- README.txt
|
||||
| |- sabre-6quad/
|
||||
| | `- README.txt
|
||||
| |- sama5d2-xult/
|
||||
@@ -1439,6 +1437,8 @@ nuttx/
|
||||
| | `- README.txt
|
||||
| |- sam3u-ek/
|
||||
| | `- README.txt
|
||||
| |- sam4cmp-db
|
||||
| | `- README.txt
|
||||
| |- sam4e-ek/
|
||||
| | `- README.txt
|
||||
| |- sam4l-xplained/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
NuttX TODO List (Last updated November 22, 2016)
|
||||
NuttX TODO List (Last updated December 3, 2016)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This file summarizes known NuttX bugs, limitations, inconsistencies with
|
||||
@@ -308,33 +308,33 @@ o Task/Scheduler (sched/)
|
||||
o SMP
|
||||
^^^
|
||||
|
||||
Title: SPINLOCKS AND DATA CACHES
|
||||
Description: If spinlocks are used in a system with a data cache, then there
|
||||
may be a problem with cache coherency in some CPU architectures:
|
||||
When one CPU modifies the spinlock, the changes may not be
|
||||
visible to another CPU if it does not share the data cache.
|
||||
That would cause failure in the spinlock logic.
|
||||
Title: SMP AND DATA CACHES
|
||||
Description: When spinlocks, semaphores, etc. are used in an SMP system with
|
||||
a data cache, then there may be problems with cache coherency
|
||||
in some CPU architectures: When one CPU modifies the shared
|
||||
object, the changes may not be visible to another CPU if it
|
||||
does not share the data cache. That would cause failure in
|
||||
the IPC logic.
|
||||
|
||||
Flushing the D-cache on writes and invalidating before a read is
|
||||
not really an option. spinlocks are normally 8-bits in size and
|
||||
cache lines are typically 32-bytes so that would have side effects
|
||||
unless the spinlocks were made to be the same size as one cache
|
||||
line.
|
||||
not really an option. That would essentially effect every memory
|
||||
access and there may be side-effects due to cache line sizes
|
||||
and alignment.
|
||||
|
||||
This might be doable if a write-through cache is used. Then you
|
||||
could always safely invalidate the cache line before reading the
|
||||
spinlock because there should never be any dirty cache lines in
|
||||
this case.
|
||||
For the same reason a separate, non-cacheable memory region is
|
||||
not an option. Essentially all data would have to go in the
|
||||
non-cached region and you would have no benefit from the data
|
||||
cache.
|
||||
|
||||
The better option is to add compiler independent "ornamentation"
|
||||
to the spinlock so that the spinlocks are all linked together
|
||||
into a separate, non-cacheable memory regions. Because of
|
||||
region alignment and minimum region mapping sizes this could
|
||||
still be wasteful of memory. This would work in systems that
|
||||
have both data cache and either an MPU or an MMU.
|
||||
Status: Open
|
||||
Priority: High. spinlocks, and hence SMP, will not work on such systems
|
||||
without this change.
|
||||
On ARM Cortex-A, each CPU has a separate data cache. However,
|
||||
the MPCore's Snoop Controller Unit supports coherency among
|
||||
the different caches. The SCU is enabled by the SCU control
|
||||
register and each CPU participates in the SMP coherency by
|
||||
setting the ACTLR_SMP bit in the auxiliary control register
|
||||
(ACTLR).
|
||||
|
||||
Status: Closed
|
||||
Priority: High on platforms that may have the issue.
|
||||
|
||||
o Memory Management (mm/)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -1043,41 +1043,18 @@ o Network (net/, drivers/net)
|
||||
Priority: Medium. Important on slow applications that will not accept
|
||||
connections promptly.
|
||||
|
||||
Title: INTERRUPT LEVEL PROCESSING IN ETHERNET DRIVERS
|
||||
Description: Too many Ethernet drivers do interrupt-level processing with
|
||||
the network stack. The network stack supports either interrupt
|
||||
level processing or normal task level processing (depending on
|
||||
CONFIG_NET_NOINTS). This is really a very bad use of CPU
|
||||
resources; All of the network stack processing should be
|
||||
modified to use a work queue (and, all use of CONFIG_NET_NOINTS=n
|
||||
should be eliminated). This applies to many Ethernet drivers:
|
||||
Title: IPv6 REQUIRES ADDRESS FILTER SUPPORT
|
||||
Description: IPv6 requires that the Ethernet driver support NuttX address
|
||||
filter interfaces. Several Ethernet drivers do support there,
|
||||
however. Others support the address filtering interfaces but
|
||||
have never been verifed:
|
||||
|
||||
ARCHITECTURE CONFIG_NET_NOINTS? ADDRESS FILTER SUPPORT?
|
||||
C5471 NO NO
|
||||
STM32 YES YES
|
||||
STM32F7 YES YES
|
||||
TIVA ----------------------- ------
|
||||
LM3S NO NO
|
||||
TM4C YES YES
|
||||
eZ80 NO NO
|
||||
Kinetis YES YES (not tested)
|
||||
LPC17xx YES YES (not tested)
|
||||
LPC43xx YES YES (not tested)
|
||||
DMxxx NIC NO NO
|
||||
PIC32 NO NO
|
||||
RGMP ??? ???
|
||||
SAM3/4 YES YES
|
||||
SAMA5D ----------------------- ------
|
||||
EMACA NO YES (not tested)
|
||||
EMACB YES YES
|
||||
GMAC NO YES (not tested)
|
||||
SAMV7 YES YES
|
||||
SIM N/A (No interrupts) NO
|
||||
C5471, LM3X, ez80, DM0x90 NIC, PIC: Do not support address
|
||||
filteringing.
|
||||
Kinetis, LPC17xx, LPC43xx: Untested address filter support
|
||||
|
||||
The general outline of how this might be done is included in
|
||||
drivers/net/skeleton.c
|
||||
Status: Open
|
||||
Priority: Pretty high if you want a well behaved system.
|
||||
Priority: Pretty high if you want a to use IPv6 on these platforms.
|
||||
|
||||
Title: UDP MULTICAST RECEPTION
|
||||
Description: The logic in udp_input() expects either a single receive socket or
|
||||
|
||||
@@ -46,12 +46,6 @@ config ARCH_MISOC
|
||||
---help---
|
||||
MISOC
|
||||
|
||||
config ARCH_RGMP
|
||||
bool "RGMP"
|
||||
---help---
|
||||
RTOS and GPOS on Multi-Processor (RGMP) architecture. See
|
||||
http://rgmp.sourceforge.net/wiki/index.php/Main_Page.
|
||||
|
||||
config ARCH_RENESAS
|
||||
bool "Renesas"
|
||||
select ARCH_NOINTC
|
||||
@@ -107,7 +101,6 @@ config ARCH
|
||||
default "hc" if ARCH_HC
|
||||
default "mips" if ARCH_MIPS
|
||||
default "misoc" if ARCH_MISOC
|
||||
default "rgmp" if ARCH_RGMP
|
||||
default "renesas" if ARCH_RENESAS
|
||||
default "risc-v" if ARCH_RISCV
|
||||
default "sim" if ARCH_SIM
|
||||
@@ -121,7 +114,6 @@ source arch/avr/Kconfig
|
||||
source arch/hc/Kconfig
|
||||
source arch/mips/Kconfig
|
||||
source arch/misoc/Kconfig
|
||||
source arch/rgmp/Kconfig
|
||||
source arch/renesas/Kconfig
|
||||
source arch/risc-v/Kconfig
|
||||
source arch/sim/Kconfig
|
||||
|
||||
@@ -222,17 +222,6 @@ arch/renesas - Support for Renesas and legacy Hitachi microcontrollers.
|
||||
arch/renesas/include/m16c and arch/renesas/src/m16c
|
||||
arch/renesas/include/sh1 and arch/renesas/src/sh1
|
||||
|
||||
arch/rgmp
|
||||
|
||||
RGMP stands for RTOS and GPOS on Multi-Processor. RGMP is a project
|
||||
for running GPOS and RTOS simultaneously on multi-processor platforms.
|
||||
You can port your favorite RTOS to RGMP together with an unmodified
|
||||
Linux to form a hybrid operating system. This makes your application
|
||||
able to use both RTOS and GPOS features.
|
||||
|
||||
See http://rgmp.sourceforge.net/wiki/index.php/Main_Page for further
|
||||
information about RGMP.
|
||||
|
||||
arch/risc-v
|
||||
This directory is dedicated to ports to the RISC-V family.
|
||||
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
/****************************************************************************
|
||||
* arch/rgmp/src/arm/sigentry.S
|
||||
* arch/arm/include/armv7-a/spinlock.h
|
||||
*
|
||||
* Copyright (C) 2011 Yu Qiang. All rights reserved.
|
||||
* Author: Yu Qiang <yuq825@gmail.com>
|
||||
*
|
||||
* This file is a part of NuttX:
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -37,13 +33,7 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.globl up_sigentry
|
||||
up_sigentry:
|
||||
sub sp, sp, #68 @ 68 is the size of Trapframe
|
||||
mov r0, sp
|
||||
bl up_sigdeliver
|
||||
add sp, sp, #4 @ skip current_task
|
||||
pop {r0-r12, lr}
|
||||
rfefd sp!
|
||||
#ifndef __ARCH_ARM_INCLUDE_ARM_SPINLOCK_H
|
||||
#define __ARCH_ARM_INCLUDE_ARM_SPINLOCK_H
|
||||
|
||||
|
||||
#endif /* __ARCH_ARM_INCLUDE_ARM_SPINLOCK_H */
|
||||
@@ -1,12 +1,8 @@
|
||||
/****************************************************************************
|
||||
* arch/rgmp/include/arm/arch/subarch/arch.h
|
||||
* arch/arm/include/armv7-a/spinlock.h
|
||||
*
|
||||
* Copyright (C) 2011 Yu Qiang. All rights reserved.
|
||||
* Author: Yu Qiang <yuq825@gmail.com>
|
||||
*
|
||||
* This file is a part of NuttX:
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -37,22 +33,7 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __RGMP_ARCH_SUBARCH_ARCH_H
|
||||
#define __RGMP_ARCH_SUBARCH_ARCH_H
|
||||
#ifndef __ARCH_ARM_INCLUDE_ARMV6_M_SPINLOCK_H
|
||||
#define __ARCH_ARM_INCLUDE_ARMV6_M_SPINLOCK_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
|
||||
static inline void up_mdelay(uint32_t msec)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static inline void up_udelay(uint32_t usec)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif
|
||||
#endif /* __ARCH_ARM_INCLUDE_ARMV6_M_SPINLOCK_H */
|
||||
@@ -1,12 +1,8 @@
|
||||
/****************************************************************************
|
||||
* arch/rgmp/include/x86/arch/subarch/arch.h
|
||||
* arch/arm/include/armv7-a/spinlock.h
|
||||
*
|
||||
* Copyright (C) 2011 Yu Qiang. All rights reserved.
|
||||
* Author: Yu Qiang <yuq825@gmail.com>
|
||||
*
|
||||
* This file is a part of NuttX:
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -37,32 +33,28 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __RGMP_ARCH_SUBARCH_ARCH_H
|
||||
#define __RGMP_ARCH_SUBARCH_ARCH_H
|
||||
#ifndef __ARCH_ARM_INCLUDE_ARMV7_A_SPINLOCK_H
|
||||
#define __ARCH_ARM_INCLUDE_ARMV7_A_SPINLOCK_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#include <nuttx/config.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
/* Not a useful feature */
|
||||
|
||||
#undef SMP_INTERCPU_NONCACHED
|
||||
|
||||
#if defined(CONFIG_SMP) && defined(SMP_INTERCPU_NONCACHED)
|
||||
/* In SMP configurations, save spinlocks and other inter-CPU communications
|
||||
* data in a non-cached memory region.
|
||||
*/
|
||||
|
||||
# define SP_SECTION __attribute__((section(".nocache")))
|
||||
#endif
|
||||
|
||||
#include <rgmp/arch/hpet.h>
|
||||
|
||||
static inline void up_mdelay(uint32_t msec)
|
||||
{
|
||||
hpet_ndelay(msec*1000000);
|
||||
}
|
||||
|
||||
static inline void up_udelay(uint32_t usec)
|
||||
{
|
||||
hpet_ndelay(usec*1000);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif
|
||||
#endif /* __ARCH_ARM_INCLUDE_ARMV7_A_SPINLOCK_H */
|
||||
@@ -1,8 +1,8 @@
|
||||
/****************************************************************************
|
||||
* configs/misoc/include/generated/common.h
|
||||
* arch/arm/include/armv7-a/spinlock.h
|
||||
*
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Ramtin Amin <keytwo@gmail.com>
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -33,17 +33,7 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __CONFIGS_MISOC_INCLUDE_GENERATED_COMMON_H
|
||||
#define __CONFIGS_MISOC_INCLUDE_GENERATED_COMMON_H
|
||||
#ifndef __ARCH_ARM_INCLUDE_ARMV7_M_SPINLOCK_H
|
||||
#define __ARCH_ARM_INCLUDE_ARMV7_M_SPINLOCK_H
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __ASSEMBLER__
|
||||
# define MMPTR(x) x
|
||||
#else
|
||||
# define MMPTR(x) (*((volatile unsigned int *)(x)))
|
||||
#endif
|
||||
|
||||
#endif /* __CONFIGS_MISOC_INCLUDE_GENERATED_COMMON_H */
|
||||
#endif /* __ARCH_ARM_INCLUDE_ARMV7_M_SPINLOCK_H */
|
||||
@@ -1,12 +1,8 @@
|
||||
/****************************************************************************
|
||||
* arch/rgmp/src/x86/sigentry.S
|
||||
* arch/arm/include/armv7-r/spinlock.h
|
||||
*
|
||||
* Copyright (C) 2011 Yu Qiang. All rights reserved.
|
||||
* Author: Yu Qiang <yuq825@gmail.com>
|
||||
*
|
||||
* This file is a part of NuttX:
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -37,19 +33,7 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.globl up_sigentry
|
||||
up_sigentry:
|
||||
subl $172, %esp # 172 is the size of Trapframe without cross ring part
|
||||
pushl %esp
|
||||
movl %esp, %eax
|
||||
call up_sigdeliver
|
||||
addl $8, %esp # skip parameter and tf_curregs
|
||||
frstor 0(%esp)
|
||||
addl $108, %esp
|
||||
popal
|
||||
popl %es
|
||||
popl %ds
|
||||
addl $0x8, %esp # trapno and errcode
|
||||
iret
|
||||
#ifndef __ARCH_ARM_INCLUDE_ARMV7_R_SPINLOCK_H
|
||||
#define __ARCH_ARM_INCLUDE_ARMV7_R_SPINLOCK_H
|
||||
|
||||
|
||||
#endif /* __ARCH_ARM_INCLUDE_ARMV7_R_SPINLOCK_H */
|
||||
@@ -44,6 +44,26 @@
|
||||
# include <stdint.h>
|
||||
#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 <arch/armv7-a/spinlock.h>
|
||||
#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 <arch/armv7-r/spinlock.h>
|
||||
#elif defined(CONFIG_ARCH_CORTEXM3) || defined(CONFIG_ARCH_CORTEXM4) || \
|
||||
defined(CONFIG_ARCH_CORTEXM7)
|
||||
# include <arch/armv7-m/spinlock.h>
|
||||
#elif defined(CONFIG_ARCH_CORTEXM0)
|
||||
# include <arch/armv6-m/spinlock.h>
|
||||
#else
|
||||
# include <arch/arm/spinlock.h>
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
# define STM32L4_NBTIM 2 /* Two basic timers, TIM6-7 */
|
||||
# define STM32L4_NLPTIM 2 /* Two low-power timers, LPTIM1-2 */
|
||||
# define STM32L4_NRNG 1 /* Random number generator (RNG) */
|
||||
# define STM32L4_NUART 4 /* UART 4-5 */
|
||||
# define STM32L4_NUART 2 /* UART 4-5 */
|
||||
# define STM32L4_NUSART 3 /* USART 1-3 */
|
||||
# define STM32L4_NLPUART 1 /* LPUART 1 */
|
||||
# define STM32L4_NSPI 3 /* SPI1-3 */
|
||||
|
||||
@@ -308,7 +308,11 @@ __cpu3_start:
|
||||
orr r0, r0, #(SCTLR_RR)
|
||||
#endif
|
||||
|
||||
#ifndef CPU_DCACHE_DISABLE
|
||||
/* In SMP configurations, the data cache will not be enabled until later
|
||||
* after SMP cache coherency has been setup.
|
||||
*/
|
||||
|
||||
#if 0 /* !defined(CPU_DCACHE_DISABLE) && !defined(CONFIG_SMP) */
|
||||
/* Dcache enable
|
||||
*
|
||||
* SCTLR_C Bit 2: DCache enable
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/sched.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
#include <nuttx/sched_note.h>
|
||||
|
||||
#include "up_internal.h"
|
||||
#include "gic.h"
|
||||
@@ -69,8 +70,8 @@
|
||||
* so that it will be ready for the next pause operation.
|
||||
*/
|
||||
|
||||
static volatile spinlock_t g_cpu_wait[CONFIG_SMP_NCPUS];
|
||||
static volatile spinlock_t g_cpu_paused[CONFIG_SMP_NCPUS];
|
||||
static volatile spinlock_t g_cpu_wait[CONFIG_SMP_NCPUS] SP_SECTION;
|
||||
static volatile spinlock_t g_cpu_paused[CONFIG_SMP_NCPUS] SP_SECTION;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
@@ -131,23 +132,42 @@ int up_cpu_paused(int cpu)
|
||||
|
||||
sched_suspend_scheduler(tcb);
|
||||
|
||||
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
||||
/* Notify that we are paused */
|
||||
|
||||
sched_note_cpu_paused(tcb);
|
||||
#endif
|
||||
|
||||
/* Save the current context at CURRENT_REGS into the TCB at the head
|
||||
* of the assigned task list for this CPU.
|
||||
*/
|
||||
|
||||
up_savestate(tcb->xcp.regs);
|
||||
|
||||
/* Wait for the spinlock to be released */
|
||||
/* Release the g_cpu_puased spinlock to synchronize with the
|
||||
* requesting CPU.
|
||||
*/
|
||||
|
||||
spin_unlock(&g_cpu_paused[cpu]);
|
||||
|
||||
/* Wait for the spinlock to be released. The requesting CPU will release
|
||||
* the spinlcok when the CPU is resumed.
|
||||
*/
|
||||
|
||||
spin_lock(&g_cpu_wait[cpu]);
|
||||
|
||||
/* Restore the exception context of the tcb at the (new) head of the
|
||||
* assigned task list.
|
||||
/* This CPU has been resumed. Restore the exception context of the TCB at
|
||||
* the (new) head of the assigned task list.
|
||||
*/
|
||||
|
||||
tcb = this_task();
|
||||
|
||||
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
||||
/* Notify that we have resumed */
|
||||
|
||||
sched_note_cpu_resumed(tcb);
|
||||
#endif
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
sched_resume_scheduler(tcb);
|
||||
@@ -224,6 +244,12 @@ int up_cpu_pause(int cpu)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
||||
/* Notify of the pause event */
|
||||
|
||||
sched_note_cpu_pause(this_task(), cpu);
|
||||
#endif
|
||||
|
||||
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu());
|
||||
|
||||
/* Take the both spinlocks. The g_cpu_wait spinlock will prevent the SGI2
|
||||
@@ -287,6 +313,12 @@ int up_cpu_pause(int cpu)
|
||||
|
||||
int up_cpu_resume(int cpu)
|
||||
{
|
||||
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
||||
/* Notify of the resume event */
|
||||
|
||||
sched_note_cpu_resume(this_task(), cpu);
|
||||
#endif
|
||||
|
||||
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu());
|
||||
|
||||
/* Release the spinlock. Releasing the spinlock will cause the SGI2
|
||||
|
||||
@@ -43,10 +43,11 @@
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/sched.h>
|
||||
#include <nuttx/sched_note.h>
|
||||
|
||||
#include "up_internal.h"
|
||||
#include "gic.h"
|
||||
#include "cp15_cacheops.h"
|
||||
#include "gic.h"
|
||||
#include "sched/sched.h"
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
@@ -104,13 +105,18 @@ static inline void arm_registerdump(FAR struct tcb_s *tcb)
|
||||
|
||||
int arm_start_handler(int irq, FAR void *context)
|
||||
{
|
||||
FAR struct tcb_s *tcb;
|
||||
FAR struct tcb_s *tcb = this_task();
|
||||
|
||||
sinfo("CPU%d Started\n", up_cpu_index());
|
||||
sinfo("CPU%d Started\n", this_cpu());
|
||||
|
||||
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
||||
/* Notify that this CPU has started */
|
||||
|
||||
sched_note_cpu_started(tcb);
|
||||
#endif
|
||||
|
||||
/* Reset scheduler parameters */
|
||||
|
||||
tcb = this_task();
|
||||
sched_resume_scheduler(tcb);
|
||||
|
||||
/* Dump registers so that we can see what is going to happen on return */
|
||||
@@ -159,6 +165,12 @@ int up_cpu_start(int cpu)
|
||||
|
||||
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu());
|
||||
|
||||
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
||||
/* Notify of the start event */
|
||||
|
||||
sched_note_cpu_start(this_task(), cpu);
|
||||
#endif
|
||||
|
||||
/* Make the content of CPU0 L1 cache has been written to coherent L2 */
|
||||
|
||||
cp15_clean_dcache(CONFIG_RAM_START, CONFIG_RAM_END - 1);
|
||||
|
||||
@@ -40,10 +40,10 @@
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
|
||||
@@ -51,21 +51,40 @@
|
||||
#include "up_internal.h"
|
||||
|
||||
#include "group/group.h"
|
||||
#include "gic.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* A bit set of pending, non-maskable SGI interrupts, on bit set for each
|
||||
* supported CPU.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARMV7A_HAVE_GICv2
|
||||
#ifdef CONFIG_SMP
|
||||
static uint16_t g_sgi_pending[CONFIG_SMP_NCPUS];
|
||||
#else
|
||||
static uint16_t g_sgi_pending[1];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t *arm_doirq(int irq, uint32_t *regs)
|
||||
/****************************************************************************
|
||||
* Name: _arm_doirq
|
||||
*
|
||||
* Description:
|
||||
* Receives the one decoded interrupt and dispatches control to the
|
||||
* attached interrupt handler.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||
static inline uint32_t *_arm_doirq(int irq, uint32_t *regs)
|
||||
{
|
||||
board_autoled_on(LED_INIRQ);
|
||||
#ifdef CONFIG_SUPPRESS_INTERRUPTS
|
||||
PANIC();
|
||||
#else
|
||||
/* Nested interrupts are not supported */
|
||||
|
||||
DEBUGASSERT(CURRENT_REGS == NULL);
|
||||
|
||||
/* Current regs non-zero indicates that we are processing an interrupt;
|
||||
* CURRENT_REGS is also used to manage interrupt level context switches.
|
||||
*/
|
||||
@@ -110,8 +129,131 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
|
||||
|
||||
regs = (uint32_t *)CURRENT_REGS;
|
||||
CURRENT_REGS = NULL;
|
||||
|
||||
return regs;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm_doirq
|
||||
*
|
||||
* Description:
|
||||
* Receives the decoded GIC interrupt information and dispatches control
|
||||
* to the attached interrupt handler. There are two versions:
|
||||
*
|
||||
* 1) For the simple case where all interrupts are maskable. In that
|
||||
* simple case, arm_doirq() is simply a wrapper for the inlined
|
||||
* _arm_do_irq() that does the real work.
|
||||
*
|
||||
* 2) With the GICv2, there are 16 non-maskable software generated
|
||||
* interrupts (SGIs) that also come through arm_doirq(). In that case,
|
||||
* we must avoid nesting interrupt handling and serial the processing.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_ARMV7A_HAVE_GICv2
|
||||
uint32_t *arm_doirq(int irq, uint32_t *regs)
|
||||
{
|
||||
board_autoled_on(LED_INIRQ);
|
||||
#ifdef CONFIG_SUPPRESS_INTERRUPTS
|
||||
PANIC();
|
||||
#else
|
||||
/* Nested interrupts are not supported */
|
||||
|
||||
DEBUGASSERT(CURRENT_REGS == NULL);
|
||||
|
||||
/* Dispatch the interrupt to its attached handler */
|
||||
|
||||
regs = _arm_doirq(irq, regs);
|
||||
#endif
|
||||
|
||||
board_autoled_off(LED_INIRQ);
|
||||
return regs;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARMV7A_HAVE_GICv2
|
||||
uint32_t *arm_doirq(int irq, uint32_t *regs)
|
||||
{
|
||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||
uint32_t bit;
|
||||
int cpu;
|
||||
int i;
|
||||
#endif
|
||||
|
||||
board_autoled_on(LED_INIRQ);
|
||||
#ifdef CONFIG_SUPPRESS_INTERRUPTS
|
||||
PANIC();
|
||||
|
||||
#else
|
||||
/* Get the CPU processing the interrupt */
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
cpu = up_cpu_index();
|
||||
#else
|
||||
cpu = 0;
|
||||
#endif
|
||||
|
||||
/* Non-zero CURRENT_REGS indicates that we are already processing an
|
||||
* interrupt. This could be a normal event for the case of the GICv2;
|
||||
* Software generated interrupts are non-maskable.
|
||||
*
|
||||
* REVISIT: There is no support for nested SGIs! That will cause an
|
||||
* assertion below. There is also no protection for concurrent access
|
||||
* to g_sgi_pending for that case.
|
||||
*/
|
||||
|
||||
if (CURRENT_REGS != NULL)
|
||||
{
|
||||
int ndx = irq - GIC_IRQ_SGI0;
|
||||
bit = (1 << (ndx));
|
||||
|
||||
/* Only an SGI should cause this event. We also cannot support
|
||||
* multiple pending SGI interrupts.
|
||||
*/
|
||||
|
||||
ASSERT((unsigned int)irq <= GIC_IRQ_SGI15 &&
|
||||
(g_sgi_pending[cpu] & bit) == 0);
|
||||
|
||||
/* Mare the SGI as pending and return immediately */
|
||||
|
||||
sinfo("SGI%d pending\n", ndx);
|
||||
g_sgi_pending[cpu] |= bit;
|
||||
return regs;
|
||||
}
|
||||
|
||||
/* Dispatch the interrupt to its attached handler */
|
||||
|
||||
regs = _arm_doirq(irq, regs);
|
||||
|
||||
/* Then loop dispatching any pending SGI interrupts that occcurred during
|
||||
* processing of the interrupts.
|
||||
*/
|
||||
|
||||
for (i = 0; i < 16 && g_sgi_pending[cpu] != 0; i++)
|
||||
{
|
||||
/* Check if this SGI is pending */
|
||||
|
||||
bit = (1 << i);
|
||||
if ((g_sgi_pending[cpu] & bit) != 0)
|
||||
{
|
||||
/* Clear the pending bit */
|
||||
|
||||
g_sgi_pending[cpu] &= ~bit;
|
||||
|
||||
/* And dispatch the SGI */
|
||||
|
||||
sinfo("Dispatching pending SGI%d\n", i + GIC_IRQ_SGI0);
|
||||
regs = _arm_doirq(i + GIC_IRQ_SGI0, regs);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
board_autoled_off(LED_INIRQ);
|
||||
return regs;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -122,7 +122,7 @@ void arm_gic0_initialize(void)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* Attach SGI interrupt handlers */
|
||||
/* Attach SGI interrupt handlers. This attaches the handler for all CPUs. */
|
||||
|
||||
DEBUGVERIFY(irq_attach(GIC_IRQ_SGI1, arm_start_handler));
|
||||
DEBUGVERIFY(irq_attach(GIC_IRQ_SGI2, arm_pause_handler));
|
||||
@@ -574,5 +574,4 @@ int arm_gic_irq_trigger(int irq, bool edge)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
#endif /* CONFIG_ARMV7A_HAVE_GICv2 */
|
||||
|
||||
@@ -450,7 +450,11 @@ __start:
|
||||
orr r0, r0, #(SCTLR_RR)
|
||||
#endif
|
||||
|
||||
#ifndef CPU_DCACHE_DISABLE
|
||||
/* In SMP configurations, the data cache will not be enabled until later
|
||||
* after SMP cache coherency has been setup.
|
||||
*/
|
||||
|
||||
#if !defined(CPU_DCACHE_DISABLE) && !defined(CONFIG_SMP)
|
||||
/* Dcache enable
|
||||
*
|
||||
* SCTLR_C Bit 2: DCache enable
|
||||
@@ -638,7 +642,7 @@ __start:
|
||||
#endif
|
||||
|
||||
/* Perform early C-level, platform-specific initialization. Logic
|
||||
* within arm_boot() must configure SDRAM and call arm_ram_initailize.
|
||||
* within arm_boot() must configure SDRAM and call arm_data_initialize().
|
||||
*/
|
||||
|
||||
bl arm_boot
|
||||
|
||||
@@ -434,7 +434,11 @@ __start:
|
||||
orr r0, r0, #(SCTLR_RR)
|
||||
#endif
|
||||
|
||||
#ifndef CPU_DCACHE_DISABLE
|
||||
/* In SMP configurations, the data cache will not be enabled until later
|
||||
* after SMP cache coherency has been setup.
|
||||
*/
|
||||
|
||||
#if !defined(CPU_DCACHE_DISABLE) && !defined(CONFIG_SMP)
|
||||
/* Dcache enable
|
||||
*
|
||||
* SCTLR_C Bit 2: DCache enable
|
||||
@@ -670,7 +674,7 @@ __start:
|
||||
#endif
|
||||
|
||||
/* Perform early C-level, platform-specific initialization. Logic
|
||||
* within arm_boot() must configure SDRAM and call arm_ram_initailize.
|
||||
* within arm_boot() must configure SDRAM and call arm_data_initialize().
|
||||
*/
|
||||
|
||||
bl arm_boot
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/arm_scu.c
|
||||
*
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "up_arch.h"
|
||||
#include "cp15_cacheops.h"
|
||||
#include "sctlr.h"
|
||||
#include "cache.h"
|
||||
#include "scu.h"
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm_get_sctlr
|
||||
*
|
||||
* Description:
|
||||
* Get the contents of the SCTLR register
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint32_t arm_get_sctlr(void)
|
||||
{
|
||||
uint32_t sctlr;
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\tmrc p15, 0, %0, c1, c0, 0\n" /* Read SCTLR */
|
||||
: "=r"(sctlr)
|
||||
:
|
||||
:
|
||||
);
|
||||
|
||||
return sctlr;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm_set_sctlr
|
||||
*
|
||||
* Description:
|
||||
* Set the contents of the SCTLR register
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void arm_set_sctlr(uint32_t sctlr)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\tmcr p15, 0, %0, c1, c0, 0\n" /* Write SCTLR */
|
||||
:
|
||||
: "r"(sctlr)
|
||||
:
|
||||
);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm_get_actlr
|
||||
*
|
||||
* Description:
|
||||
* Get the contents of the ACTLR register
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint32_t arm_get_actlr(void)
|
||||
{
|
||||
uint32_t actlr;
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\tmrc p15, 0, %0, c1, c0, 1\n" /* Read ACTLR */
|
||||
: "=r"(actlr)
|
||||
:
|
||||
:
|
||||
);
|
||||
|
||||
return actlr;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm_set_actlr
|
||||
*
|
||||
* Description:
|
||||
* Set the contents of the ACTLR register
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void arm_set_actlr(uint32_t actlr)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\tmcr p15, 0, %0, c1, c0, 1\n" /* Write ACTLR */
|
||||
:
|
||||
: "r"(actlr)
|
||||
:
|
||||
);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm_enable_smp
|
||||
*
|
||||
* Description:
|
||||
* Enable the SCU and make certain that current CPU is participating in
|
||||
* the SMP cache coherency.
|
||||
*
|
||||
* Assumption:
|
||||
* Called early in the CPU start-up. No special critical sections are
|
||||
* needed if only CPU-private registers are modified.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void arm_enable_smp(int cpu)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
/* Handle actions unique to CPU0 which comes up first */
|
||||
|
||||
if (cpu == 0)
|
||||
{
|
||||
/* Invalidate the SCU duplicate tags for all processors */
|
||||
|
||||
putreg32((SCU_INVALIDATE_ALL_WAYS << SCU_INVALIDATE_CPU0_SHIFT) |
|
||||
(SCU_INVALIDATE_ALL_WAYS << SCU_INVALIDATE_CPU1_SHIFT) |
|
||||
(SCU_INVALIDATE_ALL_WAYS << SCU_INVALIDATE_CPU2_SHIFT) |
|
||||
(SCU_INVALIDATE_ALL_WAYS << SCU_INVALIDATE_CPU3_SHIFT),
|
||||
SCU_INVALIDATE);
|
||||
|
||||
/* Invalidate CPUn L1 data cache so that is will we be reloaded from
|
||||
* coherent L2.
|
||||
*/
|
||||
|
||||
cp15_invalidate_dcache_all();
|
||||
ARM_DSB();
|
||||
|
||||
/* Invalidate the L2C-310 -- Missing logic. */
|
||||
|
||||
/* Enable the SCU */
|
||||
|
||||
regval = getreg32(SCU_CTRL);
|
||||
regval |= SCU_CTRL_ENABLE;
|
||||
putreg32(regval, SCU_CTRL);
|
||||
}
|
||||
|
||||
/* Actions for other CPUs */
|
||||
|
||||
else
|
||||
{
|
||||
/* Invalidate CPUn L1 data cache so that is will we be reloaded from
|
||||
* coherent L2.
|
||||
*/
|
||||
|
||||
cp15_invalidate_dcache_all();
|
||||
ARM_DSB();
|
||||
|
||||
/* Wait for the SCU to be enabled by the primary processor -- should
|
||||
* not be necessary.
|
||||
*/
|
||||
}
|
||||
|
||||
/* Enable the data cache, set the SMP mode with ACTLR.SMP=1.
|
||||
*
|
||||
* SMP - Sgnals if the Cortex-A9 processor is taking part in coherency
|
||||
* or not.
|
||||
*
|
||||
* Cortex-A9 also needs ACTLR.FW=1
|
||||
*
|
||||
* FW - Cache and TLB maintenance broadcast.
|
||||
*/
|
||||
|
||||
regval = arm_get_actlr();
|
||||
regval |= ACTLR_SMP;
|
||||
#ifdef CONFIG_ARCH_CORTEXA9
|
||||
regval |= ACTLR_FW;
|
||||
#endif
|
||||
arm_set_actlr(regval);
|
||||
|
||||
regval = arm_get_sctlr();
|
||||
regval |= SCTLR_C;
|
||||
arm_set_sctlr(regval);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -50,6 +50,16 @@
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
|
||||
/* Intrinsics are used in these inline functions */
|
||||
|
||||
#define arm_isb(n) __asm__ __volatile__ ("isb " #n : : : "memory")
|
||||
#define arm_dsb(n) __asm__ __volatile__ ("dsb " #n : : : "memory")
|
||||
#define arm_dmb(n) __asm__ __volatile__ ("dmb " #n : : : "memory")
|
||||
|
||||
#define ARM_DSB() arm_dsb(15)
|
||||
#define ARM_ISB() arm_isb(15)
|
||||
#define ARM_DMB() arm_dmb(15)
|
||||
|
||||
/************************************************************************************
|
||||
* Inline Functions
|
||||
************************************************************************************/
|
||||
|
||||
@@ -601,11 +601,13 @@
|
||||
#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_PTE_DOM(0))
|
||||
#define MMU_L2_INTERCPUFLAGS (PTE_TYPE_SMALL | PTE_DEVICE | PTE_AP_RW1)
|
||||
|
||||
/* Mapped section size */
|
||||
|
||||
#define SECTION_SHIFT (20)
|
||||
@@ -1423,6 +1425,28 @@ void mmu_l1_restore(uintptr_t vaddr, uint32_t l1entry);
|
||||
# define mmu_l1_clrentry(v) mmu_l1_restore(v,0)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mmu_l2_setentry
|
||||
*
|
||||
* Description:
|
||||
* Set one small (4096B) entry in a level2 translation table.
|
||||
*
|
||||
* Input Parameters:
|
||||
* l2vaddr - the virtual address of the beginning of the L2 translation
|
||||
* table.
|
||||
* paddr - The physical address to be mapped. Must be aligned to a 4KB
|
||||
* address boundary
|
||||
* vaddr - The virtual address to be mapped. Must be aligned to a 4KB
|
||||
* address boundary
|
||||
* mmuflags - The MMU flags to use in the mapping.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_ARCH_ROMPGTABLE
|
||||
void mmu_l2_setentry(uint32_t l2vaddr, uint32_t paddr, uint32_t vaddr,
|
||||
uint32_t mmuflags);
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: mmu_l1_map_region
|
||||
*
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/scu.h
|
||||
* Generic Interrupt Controller Definitions
|
||||
*
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Reference:
|
||||
* Cortex™-A9 MPCore, Revision: r4p1, Technical Reference Manual, ARM DDI
|
||||
* 0407I (ID091612).
|
||||
*
|
||||
* 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_SCU_H
|
||||
#define __ARCH_ARM_SRC_ARMV7_A_SCU_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "mpcore.h" /* For MPCORE_SCU_VBASE */
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Register offsets *********************************************************/
|
||||
|
||||
#define SCU_CTRL_OFFSET 0x0000 /* SCU Control Register (Implementation defined) */
|
||||
#define SCU_CONFIG_OFFSET 0x0004 /* SCU Configuration Register (Implementation defined) */
|
||||
#define SCU_PWRSTATUS_OFFSET 0x0008 /* SCU CPU Power Status Register */
|
||||
#define SCU_INVALIDATE_OFFSET 0x000c /* SCU Invalidate All Registers in Secure State */
|
||||
#define SCU_FILTERSTART_OFFSET 0x0040 /* Filtering Start Address Register Defined by FILTERSTART input */
|
||||
#define SCU_FILTEREND_OFFSET 0x0044 /* Filtering End Address Register Defined by FILTEREND input */
|
||||
#define SCU_SAC_OFFSET 0x0050 /* SCU Access Control (SAC) Register */
|
||||
#define SCU_SNSAC_OFFSET 0x0054 /* SCU Non-secure Access Control (SNSAC) Register */
|
||||
|
||||
/* Register addresses *******************************************************/
|
||||
|
||||
#define SCU_CTRL (MPCORE_SCU_VBASE+SCU_CTRL_OFFSET)
|
||||
#define SCU_CONFIG (MPCORE_SCU_VBASE+SCU_CONFIG_OFFSET)
|
||||
#define SCU_PWRSTATUS (MPCORE_SCU_VBASE+SCU_PWRSTATUS_OFFSET)
|
||||
#define SCU_INVALIDATE (MPCORE_SCU_VBASE+SCU_INVALIDATE_OFFSET)
|
||||
#define SCU_FILTERSTART (MPCORE_SCU_VBASE+SCU_FILTERSTART_OFFSET)
|
||||
#define SCU_FILTEREND (MPCORE_SCU_VBASE+SCU_FILTEREND_OFFSET)
|
||||
#define SCU_SAC (MPCORE_SCU_VBASE+SCU_SAC_OFFSET)
|
||||
#define SCU_SNSAC (MPCORE_SCU_VBASE+SCU_SNSAC_OFFSET)
|
||||
|
||||
/* Register bit-field definitions *******************************************/
|
||||
|
||||
/* SCU Control Register (Implementation defined) */
|
||||
|
||||
#define SCU_CTRL_ENABLE (1 << 0) /* SCU enable */
|
||||
#define SCU_CTRL_ADDRFILTER (1 << 1) /* Address filtering enable */
|
||||
#define SCU_CTRL_RAMPARITY (1 << 2) /* SCU RAMs parity enable */
|
||||
#define SCU_CTRL_LINFILL (1 << 3) /* SCU speculative linefill enable */
|
||||
#define SCU_CTRL_PORT0 (1 << 4) /* Force all device to port0 enable */
|
||||
#define SCU_CTRL_STANDBY (1 << 5) /* SCU standby enable */
|
||||
#define SCU_CTRL_ICSTANDBY (1 << 6) /* IC standby enable */
|
||||
|
||||
/* SCU Configuration Register (Implementation defined) */
|
||||
|
||||
#define SCU_CONFIG_NCPUS_SHIFT 0 /* CPU number Number of CPUs present */
|
||||
#define SCU_CONFIG_NCPUS_MASK (3 << SCU_CONFIG_NCPUS_SHIFT)
|
||||
# define SCU_CONFIG_NCPUS(r) ((((uint32_t)(r) & SCU_CONFIG_NCPUS_MASK) >> SCU_CONFIG_NCPUS_SHIFT) + 1)
|
||||
#define SCU_CONFIG_SMPCPUS_SHIFT 4 /* Processors that are in SMP or AMP mode */
|
||||
#define SCU_CONFIG_SMPCPUS_MASK (15 << SCU_CONFIG_SMPCPUS_SHIFT)
|
||||
# define SCU_CONFIG_CPU_SMP(n) (1 << ((n)+4))
|
||||
# define SCU_CONFIG_CPU0_SMP (1 << 4)
|
||||
# define SCU_CONFIG_CPU1_SMP (1 << 5)
|
||||
# define SCU_CONFIG_CPU2_SMP (1 << 6)
|
||||
# define SCU_CONFIG_CPU3_SMP (1 << 7)
|
||||
|
||||
#define SCU_CONFIG_TAGRAM_16KB 0
|
||||
#define SCU_CONFIG_TAGRAM_32KB 1
|
||||
#define SCU_CONFIG_TAGRAM_64KB 2
|
||||
|
||||
#define SCU_CONFIG_CPU0_TAGRAM_SHIFT 8 /* CPU 0 tag RAM size */
|
||||
#define SCU_CONFIG_CPU0_TAGRAM_MASK (3 << SCU_CONFIG_CPU0_TAGRAM_SHIFT)
|
||||
#define SCU_CONFIG_CPU1_TAGRAM_SHIFT 10 /* CPU 1 tag RAM size */
|
||||
#define SCU_CONFIG_CPU1_TAGRAM_MASK (3 << SCU_CONFIG_CPU0_TAGRAM_SHIFT)
|
||||
#define SCU_CONFIG_CPU2_TAGRAM_SHIFT 12 /* CPU 1 tag RAM size */
|
||||
#define SCU_CONFIG_CPU2_TAGRAM_MASK (3 << SCU_CONFIG_CPU0_TAGRAM_SHIFT)
|
||||
#define SCU_CONFIG_CPU3_TAGRAM_SHIFT 14 /* CPU 1 tag RAM size */
|
||||
#define SCU_CONFIG_CPU3_TAGRAM_MASK (3 << SCU_CONFIG_CPU0_TAGRAM_SHIFT)
|
||||
|
||||
/* SCU CPU Power Status Register */
|
||||
|
||||
#define SCU_PWRSTATUS_NORMAL 0
|
||||
#define SCU_PWRSTATUS_DORMANT 2
|
||||
#define SCU_PWRSTATUS_PWROFF 3
|
||||
|
||||
#define SCU_PWRSTATUS_CPU0_SHIFT 0 /* CPU0 status Power status */
|
||||
#define SCU_PWRSTATUS_CPU0_MASK (3 << SCU_PWRSTATUS_CPU0_SHIFT)
|
||||
#define SCU_PWRSTATUS_CPU1_SHIFT 8 /* CPU1 status Power status */
|
||||
#define SCU_PWRSTATUS_CPU1_MASK (3 << SCU_PWRSTATUS_CPU1_SHIFT)
|
||||
#define SCU_PWRSTATUS_CPU2_SHIFT 16 /* CPU2 status Power status */
|
||||
#define SCU_PWRSTATUS_CPU2_MASK (3 << SCU_PWRSTATUS_CPU2_SHIFT)
|
||||
#define SCU_PWRSTATUS_CPU3_SHIFT 24 /* CPU3 status Power status */
|
||||
#define SCU_PWRSTATUS_CPU3_MASK (3 << SCU_PWRSTATUS_CPU3_SHIFT)
|
||||
|
||||
/* SCU Invalidate All Registers in Secure State */
|
||||
|
||||
#define SCU_INVALIDATE_ALL_WAYS 15
|
||||
#define SCU_INVALIDATE_CPU0_SHIFT 0 /* Ways that must be invalidated for CPU0 */
|
||||
#define SCU_INVALIDATE_CPU0_MASK (15 << SCU_INVALIDATE_CPU0_SHIFT)
|
||||
#define SCU_INVALIDATE_CPU1_SHIFT 4 /* Ways that must be invalidated for CPU1 */
|
||||
#define SCU_INVALIDATE_CPU1_MASK (15 << SCU_INVALIDATE_CPU1_SHIFT)
|
||||
#define SCU_INVALIDATE_CPU2_SHIFT 8 /* Ways that must be invalidated for CPU2 */
|
||||
#define SCU_INVALIDATE_CPU2_MASK (15 << SCU_INVALIDATE_CPU2_SHIFT)
|
||||
#define SCU_INVALIDATE_CPU3_SHIFT 12 /* Ways that must be invalidated for CPU3 */
|
||||
#define SCU_INVALIDATE_CPU3_MASK (15 << SCU_INVALIDATE_CPU3_SHIFT)
|
||||
|
||||
/* Filtering Start Address Register Defined by FILTERSTART input */
|
||||
|
||||
#define SCU_FILTERSTART_SHIFT 10 /* Filtering start address */
|
||||
#define SCU_FILTERSTART_MASK (0xfff << SCU_FILTERSTART_SHIFT)
|
||||
|
||||
/* Filtering End Address Register Defined by FILTEREND input */
|
||||
|
||||
#define SCU_FILTEREND_SHIFT 10 /* Filtering start address */
|
||||
#define SCU_FILTEREND_MASK (0xfff << SCU_FILTEREND_SHIFT)
|
||||
|
||||
/* SCU Access Control (SAC) Register */
|
||||
|
||||
#define SCU_SAC_CPU(n) (1 << (n)) /* CPUn may access components */
|
||||
|
||||
/* SCU Non-secure Access Control (SNSAC) Register */
|
||||
|
||||
#define SCU_SNSAC_COMP_CPU(n) (1 << (n)) /* CPUn has non-secure access to components */
|
||||
#define SCU_SNSAC_PTIM_CPU(n) (1 << ((n)+4)) /* CPUn has non-secure access to private timers */
|
||||
#define SCU_SNSAC_GTIM_CPU(n) (1 << ((n)+8)) /* CPUn has non-secure access to global timer */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm_enable_smp
|
||||
*
|
||||
* Description:
|
||||
* Enable the SCU and make certain that current CPU is participating in
|
||||
* the SMP cache coherency.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void arm_enable_smp(int cpu);
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_ARMV7_A_SCU_H */
|
||||
@@ -53,6 +53,7 @@
|
||||
|
||||
#include "up_arch.h"
|
||||
#include "sched/sched.h"
|
||||
#include "irq/irq.h"
|
||||
#include "up_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
@@ -319,6 +320,12 @@ static void up_dumpstate(void)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* Show the CPU number */
|
||||
|
||||
_alert("CPU%d:\n", up_cpu_index());
|
||||
#endif
|
||||
|
||||
/* Then dump the registers (if available) */
|
||||
|
||||
up_registerdump();
|
||||
@@ -351,6 +358,12 @@ static void _up_assert(int errorcode)
|
||||
(void)up_irq_save();
|
||||
for (; ; )
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
/* Try (again) to stop activity on other CPUs */
|
||||
|
||||
(void)spin_trylock(&g_cpu_irqlock);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_LEDS
|
||||
board_autoled_on(LED_PANIC);
|
||||
up_mdelay(250);
|
||||
|
||||
@@ -165,6 +165,19 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
CURRENT_REGS[REG_LR] = EXC_RETURN_PRIVTHR;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* In an SMP configuration, the interrupt disable logic also
|
||||
* involves spinlocks that are configured per the TCB irqcount
|
||||
* field. This is logically equivalent to enter_critical_section().
|
||||
* The matching call to leave_critical_section() will be
|
||||
* performed in up_sigdeliver().
|
||||
*/
|
||||
|
||||
DEBUGASSERT(tcb->irqcount < INT16_MAX);
|
||||
tcb->irqcount++;
|
||||
#endif
|
||||
|
||||
/* And make sure that the saved context in the TCB is the same
|
||||
* as the interrupt return context.
|
||||
*/
|
||||
@@ -211,6 +224,19 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
tcb->xcp.regs[REG_LR] = EXC_RETURN_PRIVTHR;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* In an SMP configuration, the interrupt disable logic also
|
||||
* involves spinlocks that are configured per the TCB irqcount
|
||||
* field. This is logically equivalent to enter_critical_section();
|
||||
* The matching leave_critical_section will be performed in
|
||||
* The matching call to leave_critical_section() will be performed
|
||||
* in up_sigdeliver().
|
||||
*/
|
||||
|
||||
DEBUGASSERT(tcb->irqcount < INT16_MAX);
|
||||
tcb->irqcount++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -124,9 +124,9 @@ void up_sigdeliver(void)
|
||||
/* Then restore the task interrupt state */
|
||||
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
up_irq_restore((uint8_t)regs[REG_BASEPRI]);
|
||||
leave_critical_section((uint8_t)regs[REG_BASEPRI]);
|
||||
#else
|
||||
up_irq_restore((uint16_t)regs[REG_PRIMASK]);
|
||||
leave_critical_section((uint16_t)regs[REG_PRIMASK]);
|
||||
#endif
|
||||
|
||||
/* Deliver the signal */
|
||||
@@ -136,9 +136,18 @@ void up_sigdeliver(void)
|
||||
/* Output any debug messages BEFORE restoring errno (because they may
|
||||
* alter errno), then disable interrupts again and restore the original
|
||||
* errno that is needed by the user logic (it is probably EINTR).
|
||||
*
|
||||
* REVISIT: In SMP mode up_irq_save() probably only disables interrupts
|
||||
* on the local CPU. We do not want to call enter_critical_section()
|
||||
* here, however, because we don't want this state to stick after the
|
||||
* call to up_fullcontextrestore().
|
||||
*
|
||||
* I would prefer that all interrupts are disabled when
|
||||
* up_fullcontextrestore() is called, but that may not be necessary.
|
||||
*/
|
||||
|
||||
sinfo("Resuming\n");
|
||||
|
||||
(void)up_irq_save();
|
||||
rtcb->pterrno = saved_errno;
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
|
||||
/* intrinsics are used in these inline functions */
|
||||
/* Intrinsics are used in these inline functions */
|
||||
|
||||
#define arm_isb(n) __asm__ __volatile__ ("isb " #n : : : "memory")
|
||||
#define arm_dsb(n) __asm__ __volatile__ ("dsb " #n : : : "memory")
|
||||
@@ -61,7 +61,7 @@
|
||||
#define ARM_ISB() arm_isb(15)
|
||||
#define ARM_DMB() arm_dmb(15)
|
||||
|
||||
/************************************************************************************
|
||||
/************************************************************************************
|
||||
* Inline Functions
|
||||
************************************************************************************/
|
||||
|
||||
|
||||
@@ -110,3 +110,23 @@ config C5471_BASET10
|
||||
bool "10BaseT FullDuplex"
|
||||
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "Ethernet work queue"
|
||||
default C5471_LPWORK if SCHED_LPWORK
|
||||
default C5471_HPWORK if !SCHED_LPWORK && SCHED_HPWORK
|
||||
depends on SCHED_WORKQUEUE
|
||||
---help---
|
||||
Work queue support is required to use the Ethernet driver. If the
|
||||
low priority work queue is available, then it should be used by the
|
||||
driver.
|
||||
|
||||
config C5471_HPWORK
|
||||
bool "High priority"
|
||||
depends on SCHED_HPWORK
|
||||
|
||||
config C5471_LPWORK
|
||||
bool "Low priority"
|
||||
depends on SCHED_LPWORK
|
||||
|
||||
endchoice # Work queue
|
||||
|
||||
+444
-231
File diff suppressed because it is too large
Load Diff
@@ -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,
|
||||
|
||||
@@ -81,6 +81,7 @@ CMN_CSRCS += arm_unblocktask.c arm_undefinedinsn.c
|
||||
|
||||
ifeq ($(CONFIG_SMP),y)
|
||||
CMN_CSRCS += arm_cpuindex.c arm_cpustart.c arm_cpupause.c arm_cpuidlestack.c
|
||||
CMN_CSRCS += arm_scu.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_DEBUG_IRQ_INFO),y)
|
||||
|
||||
@@ -122,6 +122,18 @@
|
||||
#define IMX_MMDCDDR_PSECTION 0x10000000 /* 10000000-ffffffff 3840 MB MMDC-DDR Controller */
|
||||
/* 10000000-7fffffff 1792 MB */
|
||||
|
||||
/* By default, NuttX uses a 1-1 memory mapping. So the unused, reserved
|
||||
* address in the top-level memory map are candidates for other mapping uses:
|
||||
*
|
||||
* 00018000-000fffff Reserved -- Not used
|
||||
* 00400000-007fffff Reserved -- Used as the virtual address an inter-CPU,
|
||||
* un-cached memory region in SMP
|
||||
* configurations
|
||||
* 00d00000-00ffffff Reserved -- Not used
|
||||
* 0220c000-023fffff Reserved -- Not used
|
||||
* 80000000-efffffff Reserved -- Level 2 page table (See below)
|
||||
*/
|
||||
|
||||
/* i.MX6 DMA PSECTION Offsets */
|
||||
|
||||
#define IMX_CAAMRAM_OFFSET 0x00000000 /* 00000000-00003fff 16 KB CAAM (16K secure RAM) */
|
||||
@@ -897,7 +909,7 @@
|
||||
* 0x80000000-0xefffffff: Undefined (1.75 GB)
|
||||
*
|
||||
* That is the offset where the main L2 page tables will be positioned. This
|
||||
* corresponds to page table offsets 0x000002000 up to 0x000003c00. That
|
||||
* corresponds to page table offsets 0x00002000 up to 0x00003c00. That
|
||||
* is 1792 entries, each mapping 4KB of address for a total of 7MB of virtual
|
||||
* address space)
|
||||
*
|
||||
@@ -917,7 +929,21 @@
|
||||
* the address space.
|
||||
*/
|
||||
|
||||
#define INTERCPU_L2_PAGES 1 /* Pages allowed for inter-processor communications */
|
||||
|
||||
#ifndef CONFIG_ARCH_LOWVECTORS
|
||||
/* Memory map
|
||||
* VIRTUAL ADDRESS RANGE L1 PG TABLE L2 PG TABLE DESCRIPTION
|
||||
* START END OFFSET SIZE
|
||||
* ---------- ---------- ------------ ----------------------------
|
||||
* 0x80000000 0x803fffff 0x000002000 0x000000400 Vectors (1MiB)
|
||||
* 0x80100000 0x806fffff 0x000002400 0x000001800 Paging (6MiB)
|
||||
*
|
||||
* 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 */
|
||||
|
||||
# define VECTOR_L2_OFFSET 0x000002000
|
||||
@@ -933,16 +959,44 @@
|
||||
# define VECTOR_L2_END_PADDR (VECTOR_L2_PBASE + VECTOR_L2_SIZE)
|
||||
# define VECTOR_L2_END_VADDR (VECTOR_L2_VBASE + VECTOR_L2_SIZE)
|
||||
|
||||
/* Paging L2 page table offset/size */
|
||||
# if defined(CONFIG_SMP) && defined(SMP_INTERCPU_NONCACHED)
|
||||
/* Paging L2 page table offset/size */
|
||||
|
||||
# define PGTABLE_L2_OFFSET 0x000002400
|
||||
# define PGTABLE_L2_SIZE 0x000001800
|
||||
# define PGTABLE_L2_OFFSET 0x000002400
|
||||
# define PGTABLE_L2_SIZE 0x000001400
|
||||
|
||||
# else
|
||||
/* Paging L2 page table offset/size */
|
||||
|
||||
# define PGTABLE_L2_OFFSET 0x000002400
|
||||
# define PGTABLE_L2_SIZE 0x000001800
|
||||
# endif
|
||||
|
||||
#else
|
||||
/* Memory map
|
||||
* VIRTUAL ADDRESS RANGE L1 PG TABLE L2 PG TABLE DESCRIPTION
|
||||
* START END OFFSET SIZE
|
||||
* ---------- ---------- ------------ ----------------------------
|
||||
* 0x80000000 0x806fffff 0x000002000 0x000001c00 Paging (7MiB)
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
# if defined(CONFIG_SMP) && defined(SMP_INTERCPU_NONCACHED)
|
||||
/* Paging L2 page table offset/size */
|
||||
|
||||
# define PGTABLE_L2_OFFSET 0x000002000
|
||||
# define PGTABLE_L2_SIZE 0x000001c00
|
||||
# define PGTABLE_L2_OFFSET 0x000002000
|
||||
# define PGTABLE_L2_SIZE 0x000001800
|
||||
|
||||
# else
|
||||
/* Paging L2 page table offset/size */
|
||||
|
||||
# define PGTABLE_L2_OFFSET 0x000002000
|
||||
# define PGTABLE_L2_SIZE 0x000001c00
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Paging L2 page table base addresses
|
||||
@@ -959,6 +1013,23 @@
|
||||
#define PGTABLE_L2_END_PADDR (PGTABLE_L2_PBASE + PGTABLE_L2_SIZE)
|
||||
#define PGTABLE_L2_END_VADDR (PGTABLE_L2_VBASE + PGTABLE_L2_SIZE)
|
||||
|
||||
#if defined(CONFIG_SMP) && defined(SMP_INTERCPU_NONCACHED)
|
||||
/* Non-cached inter-processor communication data */
|
||||
|
||||
# define INTERCPU_L2_OFFSET (PGTABLE_L2_OFFSET + PGTABLE_L2_SIZE)
|
||||
# define INTERCPU_L2_SIZE (0x00000400)
|
||||
|
||||
/* Non-cached inter-processor communication page table base addresses */
|
||||
|
||||
# define INTERCPU_L2_PBASE (PGTABLE_BASE_PADDR + INTERCPU_L2_OFFSET)
|
||||
# define INTERCPU_L2_VBASE (PGTABLE_BASE_VADDR + INTERCPU_L2_OFFSET)
|
||||
|
||||
/* Non-cached inter-processor communication end addresses */
|
||||
|
||||
# define INTERCPU_L2_END_PADDR (INTERCPU_L2_PBASE + INTERCPU_L2_SIZE)
|
||||
# define INTERCPU_L2_END_VADDR (INTERCPU_L2_VBASE + INTERCPU_L2_SIZE)
|
||||
#endif
|
||||
|
||||
/* Base address of the interrupt vector table.
|
||||
*
|
||||
* IMX_VECTOR_PADDR - Unmapped, physical address of vector table in SRAM
|
||||
@@ -974,19 +1045,62 @@
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARCH_LOWVECTORS /* Vectors located at 0x0000:0000 */
|
||||
|
||||
/* Vectors will always lie at the beginnin of OCRAM */
|
||||
/* Vectors will always lie at the beginning of OCRAM
|
||||
*
|
||||
* OCRAM Memory Map:
|
||||
* ---------- ---------- ---------------------------
|
||||
* START END CONTENT
|
||||
* ---------- ---------- ---------------------------
|
||||
* 0x00000000 0x00010000 Vectors (VECTOR_TABLE_SIZE)
|
||||
* 0x00010000 0x00011000 Inter-CPU communications
|
||||
* 0x00011000 0x0003c000 Unused
|
||||
* 0x0003c000 0x00004000 Page table (PGTABLE_SIZE)
|
||||
*/
|
||||
|
||||
# define IMX_VECTOR_PADDR IMX_OCRAM_PBASE
|
||||
# define IMX_VECTOR_VSRAM IMX_OCRAM_VBASE
|
||||
# define IMX_VECTOR_VADDR 0x00000000
|
||||
|
||||
#if defined(CONFIG_SMP) && defined(SMP_INTERCPU_NONCACHED)
|
||||
/* Inter-processor communications.
|
||||
*
|
||||
* NOTICE that we use the unused virtual address space at 0x00400000 for
|
||||
* the inter-CPU virtual communication area.
|
||||
*/
|
||||
|
||||
# define INTERCPU_PADDR (IMX_VECTOR_PADDR + VECTOR_TABLE_SIZE)
|
||||
# define INTERCPU_VADDR (0x00400000)
|
||||
# define INTERCPU_SIZE (INTERCPU_L2_PAGES << 12)
|
||||
# define INTERCPU_VSRAM (IMX_VECTOR_VSRAM + VECTOR_TABLE_SIZE)
|
||||
#endif
|
||||
|
||||
#else /* Vectors located at 0xffff:0000 -- this probably does not work */
|
||||
/* OCRAM Memory Map:
|
||||
* ---------- ---------- ---------------------------
|
||||
* START END CONTENT
|
||||
* ---------- ---------- ---------------------------
|
||||
* 0x00000000 0x00004000 Page table (PGTABLE_SIZE)
|
||||
* 0x00004000 0x0002f000 Unused
|
||||
* 0x0002f000 0x00030000 Inter-CPU communications
|
||||
* 0x00030000 0x00010000 Vectors (VECTOR_TABLE_SIZE)
|
||||
*/
|
||||
|
||||
# define IMX_VECTOR_PADDR (IMX_OCRAM_PBASE + IMX_OCRAM_SIZE - VECTOR_TABLE_SIZE)
|
||||
# define IMX_VECTOR_VSRAM (IMX_OCRAM_VBASE + IMX_OCRAM_SIZE - VECTOR_TABLE_SIZE)
|
||||
# define IMX_VECTOR_VADDR 0xffff0000
|
||||
|
||||
#if defined(CONFIG_SMP) && defined(SMP_INTERCPU_NONCACHED)
|
||||
/* Inter-processor communications
|
||||
*
|
||||
* NOTICE that we use the unused virtual address space at 0x00400000 for
|
||||
* the inter-CPU virtual communication area.
|
||||
*/
|
||||
|
||||
# define INTERCPU_PADDR (IMX_VECTOR_PADDR - INTERCPU_L2_SIZE)
|
||||
# define INTERCPU_VADDR (0x00400000)
|
||||
# define INTERCPU_SIZE (INTERCPU_L2_PAGES << 12)
|
||||
# define INTERCPU_VSRAM (IMX_VECTOR_VSRAM - INTERCPU_L2_SIZE)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
|
||||
+109
-21
@@ -52,6 +52,7 @@
|
||||
#include "chip.h"
|
||||
#include "arm.h"
|
||||
#include "mmu.h"
|
||||
#include "scu.h"
|
||||
#include "cache.h"
|
||||
#include "fpu.h"
|
||||
#include "up_internal.h"
|
||||
@@ -64,6 +65,16 @@
|
||||
#include "imx_serial.h"
|
||||
#include "imx_boot.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_FEATURES
|
||||
# define PROGRESS(c) imx_lowputc(c)
|
||||
#else
|
||||
# define PROGRESS(c)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
@@ -224,6 +235,48 @@ static void imx_vectormapping(void)
|
||||
# define imx_vectormapping()
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imx_intercpu_mapping
|
||||
*
|
||||
* Description:
|
||||
* Setup a special mapping for the non-cached, inter-cpu communications
|
||||
* area.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_SMP) && defined(SMP_INTERCPU_NONCACHED)
|
||||
static void imx_intercpu_mapping(void)
|
||||
{
|
||||
uint32_t intercpu_paddr = INTERCPU_PADDR & PTE_SMALL_PADDR_MASK;
|
||||
uint32_t intercpu_vaddr = INTERCPU_VADDR & PTE_SMALL_PADDR_MASK;
|
||||
uint32_t end_paddr = INTERCPU_PADDR + INTERCPU_SIZE;
|
||||
|
||||
DEBUGASSERT(intercpu_vaddr == (uint32_t)&_snocache);
|
||||
|
||||
/* We want to keep the inter-cpu region in on-chip RAM (OCRAM). The
|
||||
* i.MX6 has 256Kb of OCRAM positioned at physical address 0x0090:0000.
|
||||
*/
|
||||
|
||||
while (intercpu_paddr < end_paddr)
|
||||
{
|
||||
mmu_l2_setentry(INTERCPU_L2_VBASE, intercpu_paddr, intercpu_vaddr,
|
||||
MMU_L2_INTERCPUFLAGS);
|
||||
intercpu_paddr += 4096;
|
||||
intercpu_vaddr += 4096;
|
||||
}
|
||||
|
||||
/* Now set the level 1 descriptor to refer to the level 2 page table. */
|
||||
|
||||
mmu_l1_setentry(INTERCPU_L2_PBASE & PMD_PTE_PADDR_MASK,
|
||||
INTERCPU_VADDR & PMD_PTE_PADDR_MASK,
|
||||
MMU_L1_INTERCPUFLAGS);
|
||||
}
|
||||
#else
|
||||
/* No inter-cpu communications area */
|
||||
|
||||
# define imx_intercpu_mapping()
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imx_copyvectorblock
|
||||
*
|
||||
@@ -388,8 +441,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) && defined(SMP_INTERCPU_NONCACHED)
|
||||
uint32_t *dest;
|
||||
#endif
|
||||
|
||||
@@ -398,7 +453,7 @@ void arm_boot(void)
|
||||
*/
|
||||
|
||||
imx_setupmappings();
|
||||
imx_lowputc('A');
|
||||
PROGRESS('A');
|
||||
|
||||
/* Make sure that all other CPUs are in the disabled state. This is a
|
||||
* formality because the other CPUs are actually running then we have
|
||||
@@ -406,13 +461,30 @@ void arm_boot(void)
|
||||
*/
|
||||
|
||||
imx_cpu_disable();
|
||||
PROGRESS('B');
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* Enable SMP cache coherency for CPU0 */
|
||||
|
||||
arm_enable_smp(0);
|
||||
PROGRESS('C');
|
||||
#endif
|
||||
|
||||
/* Provide a special mapping for the OCRAM interrupt vector positioned in
|
||||
* high memory.
|
||||
*/
|
||||
|
||||
imx_vectormapping();
|
||||
imx_lowputc('B');
|
||||
PROGRESS('D');
|
||||
|
||||
#if defined(CONFIG_SMP) && defined(SMP_INTERCPU_NONCACHED)
|
||||
/* Provide a special mapping for the OCRAM interrupt vector positioned in
|
||||
* high memory.
|
||||
*/
|
||||
|
||||
imx_intercpu_mapping();
|
||||
PROGRESS('E');
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_RAMFUNCS
|
||||
/* Copy any necessary code sections from FLASH to RAM. The correct
|
||||
@@ -426,14 +498,14 @@ void arm_boot(void)
|
||||
*dest++ = *src++;
|
||||
}
|
||||
|
||||
imx_lowputc('C');
|
||||
PROGRESS('F');
|
||||
|
||||
/* Flush the copied RAM functions into physical RAM so that will
|
||||
* be available when fetched into the I-Cache.
|
||||
*/
|
||||
|
||||
arch_clean_dcache((uintptr_t)&_sramfuncs, (uintptr_t)&_eramfuncs)
|
||||
imx_lowputc('D');
|
||||
PROGRESS('G');
|
||||
#endif
|
||||
|
||||
/* Setup up vector block. _vector_start and _vector_end are exported from
|
||||
@@ -441,37 +513,35 @@ void arm_boot(void)
|
||||
*/
|
||||
|
||||
imx_copyvectorblock();
|
||||
imx_lowputc('E');
|
||||
PROGRESS('H');
|
||||
|
||||
/* Disable the watchdog timer */
|
||||
|
||||
imx_wdtdisable();
|
||||
imx_lowputc('F');
|
||||
PROGRESS('I');
|
||||
|
||||
/* Initialize clocking to settings provided by board-specific logic */
|
||||
|
||||
imx_clockconfig();
|
||||
imx_lowputc('G');
|
||||
PROGRESS('J');
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Initialize the FPU */
|
||||
|
||||
arm_fpuconfig();
|
||||
imx_lowputc('H');
|
||||
PROGRESS('K');
|
||||
#endif
|
||||
|
||||
/* Perform board-specific initialization, This must include:
|
||||
*
|
||||
* - Initialization of board-specific memory resources (e.g., SDRAM)
|
||||
* - Configuration of board specific resources (PIOs, LEDs, etc).
|
||||
/* Perform board-specific memroy initialization, This must include
|
||||
* initialization of board-specific memory resources (e.g., SDRAM)
|
||||
*
|
||||
* NOTE: We must use caution prior to this point to make sure that
|
||||
* the logic does not access any global variables that might lie
|
||||
* in SDRAM.
|
||||
*/
|
||||
|
||||
imx_board_initialize();
|
||||
imx_lowputc('I');
|
||||
imx_memory_initialize();
|
||||
PROGRESS('L');
|
||||
|
||||
#ifdef NEED_SDRAM_REMAPPING
|
||||
/* SDRAM was configured in a temporary state to support low-level
|
||||
@@ -480,7 +550,7 @@ void arm_boot(void)
|
||||
*/
|
||||
|
||||
imx_remap();
|
||||
imx_lowputc('J');
|
||||
PROGRESS('M');
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BOOT_SDRAM_DATA
|
||||
@@ -489,13 +559,31 @@ void arm_boot(void)
|
||||
*/
|
||||
|
||||
arm_data_initialize();
|
||||
imx_lowputc('K');
|
||||
PROGRESS('N');
|
||||
#endif
|
||||
|
||||
/* Perform board-specific device initialization. This would include
|
||||
* configuration of board specific resources such as GPIOs, LEDs, etc.
|
||||
*/
|
||||
|
||||
imx_board_initialize();
|
||||
PROGRESS('O');
|
||||
|
||||
#if defined(CONFIG_SMP) && defined(SMP_INTERCPU_NONCACHED)
|
||||
/* Initialize the uncached, inter-CPU communications area */
|
||||
|
||||
for (dest = &_snocache; dest < &_enocache; )
|
||||
{
|
||||
*dest++ = 0;
|
||||
}
|
||||
|
||||
PROGRESS('P');
|
||||
#endif
|
||||
|
||||
/* Perform common, low-level chip initialization (might do nothing) */
|
||||
|
||||
imx_lowsetup();
|
||||
imx_lowputc('L');
|
||||
PROGRESS('Q');
|
||||
|
||||
#ifdef USE_EARLYSERIALINIT
|
||||
/* Perform early serial initialization if we are going to use the serial
|
||||
@@ -503,7 +591,7 @@ void arm_boot(void)
|
||||
*/
|
||||
|
||||
imx_earlyserialinit();
|
||||
imx_lowputc('M');
|
||||
PROGRESS('R');
|
||||
#endif
|
||||
|
||||
/* Now we can enable all other CPUs. The enabled CPUs will start execution
|
||||
@@ -512,6 +600,6 @@ void arm_boot(void)
|
||||
*/
|
||||
|
||||
imx_cpu_enable();
|
||||
imx_lowputc('N');
|
||||
imx_lowputc('\n');
|
||||
PROGRESS('S');
|
||||
PROGRESS('\n');
|
||||
}
|
||||
|
||||
@@ -110,14 +110,37 @@ void imx_cpu_enable(void);
|
||||
# define imx_cpu_enable()
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imx_memory_initialize
|
||||
*
|
||||
* Description:
|
||||
* All i.MX6 architectures must provide the following entry point. This
|
||||
* entry point is called early in the initialization before memory has
|
||||
* been configured. This board-specific function is responsible for
|
||||
* configuring any on-board memories.
|
||||
*
|
||||
* Logic in imx_memory_initialize must be careful to avoid using any
|
||||
* global variables because those will be uninitialized at the time this
|
||||
* function is called.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void imx_memory_initialize(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imx_board_initialize
|
||||
*
|
||||
* Description:
|
||||
* All i.MX6 architectures must provide the following entry point. This
|
||||
* entry point is called early in the initialization -- after all memory
|
||||
* has been configured and mapped but before any devices have been
|
||||
* initialized.
|
||||
* entry point is called in the initialization phase -- after
|
||||
* imx_memory_initialize and after all memory has been configured and
|
||||
* mapped but before any devices have been initialized.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
|
||||
@@ -51,9 +51,9 @@
|
||||
#include "chip/imx_src.h"
|
||||
#include "sctlr.h"
|
||||
#include "smp.h"
|
||||
#include "scu.h"
|
||||
#include "fpu.h"
|
||||
#include "gic.h"
|
||||
#include "cp15_cacheops.h"
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
@@ -260,6 +260,10 @@ void imx_cpu_enable(void)
|
||||
|
||||
void arm_cpu_boot(int cpu)
|
||||
{
|
||||
/* Enable SMP cache coherency for the CPU */
|
||||
|
||||
arm_enable_smp(cpu);
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Initialize the FPU */
|
||||
|
||||
@@ -297,10 +301,6 @@ void arm_cpu_boot(int cpu)
|
||||
(void)up_irq_enable();
|
||||
#endif
|
||||
|
||||
/* Invalidate CPUn L1 so that is will be reloaded from coherent L2. */
|
||||
|
||||
cp15_invalidate_dcache_all();
|
||||
|
||||
/* The next thing that we expect to happen is for logic running on CPU0
|
||||
* to call up_cpu_start() which generate an SGI and a context switch to
|
||||
* the configured NuttX IDLE task.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -134,11 +134,11 @@ void up_irqinitialize(void)
|
||||
CURRENT_REGS = NULL;
|
||||
|
||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||
#ifdef CONFIG_IMX6_PIO_IRQ
|
||||
/* Initialize logic to support a second level of interrupt decoding for
|
||||
* PIO pins.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_IMX6_PIO_IRQ
|
||||
imx_gpioirq_initialize();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -254,7 +254,6 @@ config KINETIS_ENET
|
||||
select ARCH_HAVE_NETDEV_STATISTICS
|
||||
select NET
|
||||
select NETDEVICES
|
||||
select NET_MULTIBUFFER
|
||||
---help---
|
||||
Support Ethernet (K6x only)
|
||||
|
||||
|
||||
@@ -53,14 +53,11 @@
|
||||
#include <nuttx/wdog.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/net/mii.h>
|
||||
#include <nuttx/net/arp.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
# include <nuttx/wqueue.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_PKT
|
||||
# include <nuttx/net/pkt.h>
|
||||
#endif
|
||||
@@ -84,13 +81,12 @@
|
||||
* is required.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
#if !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# error Work queue support is required
|
||||
#endif
|
||||
#else
|
||||
|
||||
/* Select work queue */
|
||||
/* Select work queue */
|
||||
|
||||
#if defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# if defined(CONFIG_KINETIS_EMAC_HPWORK)
|
||||
# define ETHWORK HPWORK
|
||||
# elif defined(CONFIG_KINETIS_EMAC_LPWORK)
|
||||
@@ -119,10 +115,6 @@
|
||||
#define NENET_NBUFFERS \
|
||||
(CONFIG_KINETIS_ENETNTXBUFFERS+CONFIG_KINETIS_ENETNRXBUFFERS)
|
||||
|
||||
#ifndef CONFIG_NET_MULTIBUFFER
|
||||
# error "CONFIG_NET_MULTIBUFFER is required in the configuration"
|
||||
#endif
|
||||
|
||||
/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per
|
||||
* second.
|
||||
*/
|
||||
@@ -223,9 +215,7 @@ struct kinetis_driver_s
|
||||
uint8_t phyaddr; /* Selected PHY address */
|
||||
WDOG_ID txpoll; /* TX poll timer */
|
||||
WDOG_ID txtimeout; /* TX timeout timer */
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
struct work_s work; /* For deferring work to the work queue */
|
||||
#endif
|
||||
struct enet_desc_s *txdesc; /* A pointer to the list of TX descriptor */
|
||||
struct enet_desc_s *rxdesc; /* A pointer to the list of RX descriptors */
|
||||
|
||||
@@ -283,24 +273,15 @@ static int kinetis_txpoll(struct net_driver_s *dev);
|
||||
static void kinetis_receive(FAR struct kinetis_driver_s *priv);
|
||||
static void kinetis_txdone(FAR struct kinetis_driver_s *priv);
|
||||
|
||||
static inline void kinetis_interrupt_process(FAR struct kinetis_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void kinetis_interrupt_work(FAR void *arg);
|
||||
#endif
|
||||
static int kinetis_interrupt(int irq, FAR void *context);
|
||||
|
||||
/* Watchdog timer expirations */
|
||||
|
||||
static inline void kinetis_txtimeout_process(FAR struct kinetis_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void kinetis_txtimeout_work(FAR void *arg);
|
||||
#endif
|
||||
static void kinetis_txtimeout_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
static inline void kinetis_poll_process(FAR struct kinetis_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void kinetis_poll_work(FAR void *arg);
|
||||
#endif
|
||||
static void kinetis_polltimer_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
/* NuttX callback functions */
|
||||
@@ -308,10 +289,7 @@ static void kinetis_polltimer_expiry(int argc, uint32_t arg, ...);
|
||||
static int kinetis_ifup(struct net_driver_s *dev);
|
||||
static int kinetis_ifdown(struct net_driver_s *dev);
|
||||
|
||||
static inline void kinetis_txavail_process(FAR struct kinetis_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void kinetis_txavail_work(FAR void *arg);
|
||||
#endif
|
||||
static int kinetis_txavail(struct net_driver_s *dev);
|
||||
|
||||
#ifdef CONFIG_NET_IGMP
|
||||
@@ -828,27 +806,31 @@ static void kinetis_txdone(FAR struct kinetis_driver_s *priv)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: kinetis_interrupt_process
|
||||
* Function: kinetis_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Interrupt processing. This may be performed either within the interrupt
|
||||
* handler or on the worker thread, depending upon the configuration
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* The network is locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void kinetis_interrupt_process(FAR struct kinetis_driver_s *priv)
|
||||
static void kinetis_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
|
||||
uint32_t pending;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
net_lock();
|
||||
|
||||
/* Get the set of unmasked, pending interrupt. */
|
||||
|
||||
pending = getreg32(KINETIS_ENET_EIR) & getreg32(KINETIS_ENET_EIMR);
|
||||
@@ -896,36 +878,8 @@ static inline void kinetis_interrupt_process(FAR struct kinetis_driver_s *priv)
|
||||
|
||||
putreg32(ENET_RDAR, KINETIS_ENET_RDAR);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: kinetis_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* The network is locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void kinetis_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
state = net_lock();
|
||||
kinetis_interrupt_process(priv);
|
||||
net_unlock(state);
|
||||
net_unlock();
|
||||
|
||||
/* Re-enable Ethernet interrupts */
|
||||
|
||||
@@ -936,7 +890,6 @@ static void kinetis_interrupt_work(FAR void *arg)
|
||||
up_enable_irq(KINETIS_IRQ_EMACRX);
|
||||
up_enable_irq(KINETIS_IRQ_EMACMISC);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: kinetis_interrupt
|
||||
@@ -962,7 +915,6 @@ static int kinetis_interrupt(int irq, FAR void *context)
|
||||
{
|
||||
register FAR struct kinetis_driver_s *priv = &g_enet[0];
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. Because Ethernet interrupts are
|
||||
* also disabled if the TX timeout event occurs, there can be no race
|
||||
* condition here.
|
||||
@@ -991,51 +943,9 @@ static int kinetis_interrupt(int irq, FAR void *context)
|
||||
/* Schedule to perform the interrupt processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->work, kinetis_interrupt_work, priv, 0);
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
kinetis_interrupt_process(priv);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: kinetis_txtimeout_process
|
||||
*
|
||||
* Description:
|
||||
* Process a TX timeout. Called from the either the watchdog timer
|
||||
* expiration logic or from the worker thread, depending upon the
|
||||
* configuration. The timeout means that the last TX never completed.
|
||||
* Reset the hardware and start again.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void kinetis_txtimeout_process(FAR struct kinetis_driver_s *priv)
|
||||
{
|
||||
/* Increment statistics and dump debug info */
|
||||
|
||||
NETDEV_TXTIMEOUTS(&priv->dev);
|
||||
|
||||
/* Take the interface down and bring it back up. The is the most agressive
|
||||
* hardware reset.
|
||||
*/
|
||||
|
||||
(void)kinetis_ifdown(&priv->dev);
|
||||
(void)kinetis_ifup(&priv->dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
(void)devif_poll(&priv->dev, kinetis_txpoll);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: kinetis_txtimeout_work
|
||||
*
|
||||
@@ -1053,19 +963,27 @@ static inline void kinetis_txtimeout_process(FAR struct kinetis_driver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void kinetis_txtimeout_work(FAR void *arg)
|
||||
{
|
||||
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
/* Increment statistics and dump debug info */
|
||||
|
||||
state = net_lock();
|
||||
kinetis_txtimeout_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
NETDEV_TXTIMEOUTS(&priv->dev);
|
||||
|
||||
/* Take the interface down and bring it back up. The is the most agressive
|
||||
* hardware reset.
|
||||
*/
|
||||
|
||||
(void)kinetis_ifdown(&priv->dev);
|
||||
(void)kinetis_ifup(&priv->dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
(void)devif_poll(&priv->dev, kinetis_txpoll);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: kinetis_txtimeout_expiry
|
||||
@@ -1090,7 +1008,6 @@ static void kinetis_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
{
|
||||
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. This will prevent some race
|
||||
* conditions with interrupt work. There is still a potential race
|
||||
* condition with interrupt work that is already queued and in progress.
|
||||
@@ -1110,50 +1027,6 @@ static void kinetis_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
/* Schedule to perform the TX timeout processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->work, kinetis_txtimeout_work, priv, 0);
|
||||
#else
|
||||
/* Process the timeout now */
|
||||
|
||||
kinetis_txtimeout_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: kinetis_poll_process
|
||||
*
|
||||
* Description:
|
||||
* Perform the periodic poll. This may be called either from watchdog
|
||||
* timer logic or from the worker thread, depending upon the configuration.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void kinetis_poll_process(FAR struct kinetis_driver_s *priv)
|
||||
{
|
||||
/* Check if there is there is a transmission in progress. We cannot perform
|
||||
* the TX poll if he are unable to accept another packet for transmission.
|
||||
*/
|
||||
|
||||
if (!kinetics_txringfull(priv))
|
||||
{
|
||||
/* If so, update TCP timing states and poll the network for new XMIT data. Hmmm..
|
||||
* might be bug here. Does this mean if there is a transmit in progress,
|
||||
* we will missing TCP time state updates?
|
||||
*/
|
||||
|
||||
(void)devif_timer(&priv->dev, kinetis_txpoll);
|
||||
}
|
||||
|
||||
/* Setup the watchdog poll timer again in any case */
|
||||
|
||||
(void)wd_start(priv->txpoll, KINETIS_WDDELAY, kinetis_polltimer_expiry,
|
||||
1, (wdparm_t)priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -1173,19 +1046,31 @@ static inline void kinetis_poll_process(FAR struct kinetis_driver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void kinetis_poll_work(FAR void *arg)
|
||||
{
|
||||
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
/* Check if there is there is a transmission in progress. We cannot perform
|
||||
* the TX poll if he are unable to accept another packet for transmission.
|
||||
*/
|
||||
|
||||
state = net_lock();
|
||||
kinetis_poll_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
if (!kinetics_txringfull(priv))
|
||||
{
|
||||
/* If so, update TCP timing states and poll the network for new XMIT data. Hmmm..
|
||||
* might be bug here. Does this mean if there is a transmit in progress,
|
||||
* we will missing TCP time state updates?
|
||||
*/
|
||||
|
||||
(void)devif_timer(&priv->dev, kinetis_txpoll);
|
||||
}
|
||||
|
||||
/* Setup the watchdog poll timer again in any case */
|
||||
|
||||
(void)wd_start(priv->txpoll, KINETIS_WDDELAY, kinetis_polltimer_expiry,
|
||||
1, (wdparm_t)priv);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: kinetis_polltimer_expiry
|
||||
@@ -1209,7 +1094,6 @@ static void kinetis_polltimer_expiry(int argc, uint32_t arg, ...)
|
||||
{
|
||||
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions.
|
||||
*/
|
||||
@@ -1229,12 +1113,6 @@ static void kinetis_polltimer_expiry(int argc, uint32_t arg, ...)
|
||||
(void)wd_start(priv->txpoll, KINETIS_WDDELAY, kinetis_polltimer_expiry,
|
||||
1, (wdparm_t)arg);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
kinetis_poll_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -1420,49 +1298,6 @@ static int kinetis_ifdown(struct net_driver_s *dev)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: kinetis_txavail_process
|
||||
*
|
||||
* Description:
|
||||
* Perform an out-of-cycle poll.
|
||||
*
|
||||
* Parameters:
|
||||
* dev - Reference to the NuttX driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called in normal user mode
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void kinetis_txavail_process(FAR struct kinetis_driver_s *priv)
|
||||
{
|
||||
net_lock_t state;
|
||||
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
state = net_lock();
|
||||
if (priv->bifup)
|
||||
{
|
||||
/* Check if there is room in the hardware to hold another outgoing
|
||||
* packet.
|
||||
*/
|
||||
|
||||
if (!kinetics_txringfull(priv))
|
||||
{
|
||||
/* No, there is space for another transfer. Poll the network for new
|
||||
* XMIT data.
|
||||
*/
|
||||
|
||||
(void)devif_poll(&priv->dev, kinetis_txpoll);
|
||||
}
|
||||
}
|
||||
|
||||
net_unlock(state);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: kinetis_txavail_work
|
||||
*
|
||||
@@ -1480,16 +1315,31 @@ static inline void kinetis_txavail_process(FAR struct kinetis_driver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void kinetis_txavail_work(FAR void *arg)
|
||||
{
|
||||
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
|
||||
|
||||
/* Perform the poll */
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
kinetis_txavail_process(priv);
|
||||
net_lock();
|
||||
if (priv->bifup)
|
||||
{
|
||||
/* Check if there is room in the hardware to hold another outgoing
|
||||
* packet.
|
||||
*/
|
||||
|
||||
if (!kinetics_txringfull(priv))
|
||||
{
|
||||
/* No, there is space for another transfer. Poll the network for new
|
||||
* XMIT data.
|
||||
*/
|
||||
|
||||
(void)devif_poll(&priv->dev, kinetis_txpoll);
|
||||
}
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: kinetis_txavail
|
||||
@@ -1515,7 +1365,6 @@ static int kinetis_txavail(struct net_driver_s *dev)
|
||||
FAR struct kinetis_driver_s *priv =
|
||||
(FAR struct kinetis_driver_s *)dev->d_private;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions and we will have to ignore the Tx
|
||||
* availability action.
|
||||
@@ -1528,12 +1377,6 @@ static int kinetis_txavail(struct net_driver_s *dev)
|
||||
work_queue(ETHWORK, &priv->work, kinetis_txavail_work, priv, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Perform the out-of-cycle poll now */
|
||||
|
||||
kinetis_txavail_process(priv);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
# endif /* LPC17_HAVE_BANK1 && LPC17_BANK1_HEAPSIZE */
|
||||
# else /* !LPC17_BANK0_HEAPSIZE */
|
||||
|
||||
/* We have Bnak 0, but no memory is available for the heap there.
|
||||
/* We have Bank 0, but no memory is available for the heap there.
|
||||
* Do we have Bank 1? Is any heap memory available in Bank 1?
|
||||
*/
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -70,12 +70,12 @@
|
||||
#define LPC43_GPDMA_CONTROL_CHOFFSET 0x000c /* DMA Channel Control Register */
|
||||
#define LPC43_GPDMA_CONFIG_CHOFFSET 0x0010 /* DMA Channel Configuration Register */
|
||||
|
||||
#define LPC43_GPDMA_CHOFFSET(n) (0x0100 ((n) << 5))
|
||||
#define LPC43_GPDMA_CHOFFSET(n) (0x0100 + ((n) << 5))
|
||||
#define LPC43_GPDMA_SRCADDR_OFFSET(n) (LPC43_GPDMA_CHOFFSET(n)+LPC43_GPDMA_SRCADDR_CHOFFSET)
|
||||
#define LPC43_GPDMA_DESTADDR_OFFSET(n) (LPC43_GPDMA_CHOFFSET(n)+LPC43_GPDMA_DESTADDR_CHOFFSET)
|
||||
#define LPC43_GPDMA_LLI_OFFSET(n) (LPC43_GPDMA_CHOFFSET(n)+LPC43_GPDMA_LLI_CHOFFSET)
|
||||
#define LPC43_GPDMA_CONTROL_OFFSET(n) (LPC43_GPDMA_CHOFFSET(n)+LPC43_GPDMA_CONTROL_CHOFFSET)
|
||||
#define LPC43_GPDMA_CONFIG_OFFSET(n) (LPC43_GPDMA_CHOFFSET(n)+LPC43_GPDMA_CONFIG_CHOFFSET)
|
||||
#define LPC43_GPDMA_CONFIG_OFFSET_(n) (LPC43_GPDMA_CHOFFSET(n)+LPC43_GPDMA_CONFIG_CHOFFSET)
|
||||
|
||||
#define LPC43_GPDMA_SRCADDR0_OFFSET 0x0100 /* DMA Channel 0 Source Address Register */
|
||||
#define LPC43_GPDMA_DESTADDR0_OFFSET 0x0104 /* DMA Channel 0 Destination Address Register */
|
||||
@@ -149,7 +149,7 @@
|
||||
#define LPC43_GPDMA_DESTADDR(n) (LPC43_DMA_BASE+LPC43_GPDMA_DESTADDR_OFFSET(n))
|
||||
#define LPC43_GPDMA_LLI(n) (LPC43_DMA_BASE+LPC43_GPDMA_LLI_OFFSET(n))
|
||||
#define LPC43_GPDMA_CONTROL(n) (LPC43_DMA_BASE+LPC43_GPDMA_CONTROL_OFFSET(n))
|
||||
#define LPC43_GPDMA_CONFIG(n) (LPC43_DMA_BASE+LPC43_GPDMA_CONFIG_OFFSET(n))
|
||||
#define LPC43_GPDMA_CONFIG_(n) (LPC43_DMA_BASE+LPC43_GPDMA_CONFIG_OFFSET_(n))
|
||||
|
||||
#define LPC43_GPDMA_SRCADDR0 (LPC43_DMA_BASE+LPC43_GPDMA_SRCADDR0_OFFSET)
|
||||
#define LPC43_GPDMA_DESTADDR0 (LPC43_DMA_BASE+LPC43_GPDMA_DESTADDR0_OFFSET)
|
||||
@@ -203,6 +203,9 @@
|
||||
|
||||
/* Common macros for DMA channel and source bit settings */
|
||||
|
||||
#define DMACH_ALL (0xff)
|
||||
#define LPC43_NDMACH 8 /* Eight DMA channels */
|
||||
#define LPC43_NDMAREQ (16) /* The number of DMA requests */
|
||||
#define GPDMA_CHANNEL(n) (1 << (n)) /* Bits 0-7 correspond to DMA channel 0-7 */
|
||||
#define GPDMA_SOURCE(n) (1 << (n)) /* Bits 0-15 correspond to DMA source 0-15 */
|
||||
#define GPDMA_REQUEST(n) (1 << (n)) /* Bits 0-15 correspond to DMA request 0-15 */
|
||||
|
||||
@@ -143,10 +143,11 @@
|
||||
#define SDMMC_CTRL_CEATAINT (1 << 11) /* Bit 11: CE-ATA device interrupts enabled */
|
||||
/* Bits 12-15: Reserved */
|
||||
#define SDMMC_CTRL_CDVA0 (1 << 16) /* Bit 16: Controls SD_VOLT0 pin */
|
||||
#define SDMMC_CTRL_CDVA0 (1 << 17) /* Bit 17: Controls SD_VOLT1 pin */
|
||||
#define SDMMC_CTRL_CDVA0 (1 << 18) /* Bit 18: Controls SD_VOLT2 pin */
|
||||
#define SDMMC_CTRL_CDVA1 (1 << 17) /* Bit 17: Controls SD_VOLT1 pin */
|
||||
#define SDMMC_CTRL_CDVA2 (1 << 18) /* Bit 18: Controls SD_VOLT2 pin */
|
||||
/* Bits 19-23: Reserved */
|
||||
#define SDMMC_CTRL_INTDMA (1 << 25) /* Bit 24: SD/MMC DMA use */
|
||||
/* Bit 24: Reserved - always write it as 0 */
|
||||
#define SDMMC_CTRL_INTDMA (1 << 25) /* Bit 25: SD/MMC DMA use */
|
||||
/* Bits 26-31: Reserved */
|
||||
/* Power Enable Register (PWREN) */
|
||||
|
||||
|
||||
@@ -53,11 +53,7 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/wdog.h>
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
# include <nuttx/wqueue.h>
|
||||
#endif
|
||||
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/net/mii.h>
|
||||
#include <nuttx/net/arp.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
@@ -87,13 +83,12 @@
|
||||
* is required.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
#if !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# error Work queue support is required
|
||||
#endif
|
||||
#else
|
||||
|
||||
/* Select work queue */
|
||||
/* Select work queue */
|
||||
|
||||
#if defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# if defined(CONFIG_LPC43_ETHERNET_HPWORK)
|
||||
# define ETHWORK HPWORK
|
||||
# elif defined(CONFIG_LPC43_ETHERNET_LPWORK)
|
||||
@@ -164,12 +159,6 @@
|
||||
#undef CONFIG_LPC43_ETH_ENHANCEDDESC
|
||||
#undef CONFIG_LPC43_ETH_HWCHECKSUM
|
||||
|
||||
/* Ethernet buffer sizes, number of buffers, and number of descriptors */
|
||||
|
||||
#ifndef CONFIG_NET_MULTIBUFFER
|
||||
# error "CONFIG_NET_MULTIBUFFER is required"
|
||||
#endif
|
||||
|
||||
/* Add 4 to the configured buffer size to account for the 2 byte checksum
|
||||
* memory needed at the end of the maximum size packet. Buffer sizes must
|
||||
* be an even multiple of 4, 8, or 16 bytes (depending on buswidth). We
|
||||
@@ -530,9 +519,7 @@ struct lpc43_ethmac_s
|
||||
uint8_t fduplex : 1; /* Full (vs. half) duplex */
|
||||
WDOG_ID txpoll; /* TX poll timer */
|
||||
WDOG_ID txtimeout; /* TX timeout timer */
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
struct work_s work; /* For deferring work to the work queue */
|
||||
#endif
|
||||
|
||||
/* This holds the information visible to the NuttX network */
|
||||
|
||||
@@ -605,34 +592,26 @@ static int lpc43_recvframe(FAR struct lpc43_ethmac_s *priv);
|
||||
static void lpc43_receive(FAR struct lpc43_ethmac_s *priv);
|
||||
static void lpc43_freeframe(FAR struct lpc43_ethmac_s *priv);
|
||||
static void lpc43_txdone(FAR struct lpc43_ethmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
|
||||
static void lpc43_interrupt_work(FAR void *arg);
|
||||
#endif
|
||||
static int lpc43_interrupt(int irq, FAR void *context);
|
||||
|
||||
/* Watchdog timer expirations */
|
||||
|
||||
static inline void lpc43_txtimeout_process(FAR struct lpc43_ethmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void lpc43_txtimeout_work(FAR void *arg);
|
||||
#endif
|
||||
static void lpc43_txtimeout_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
static inline void lpc43_poll_process(FAR struct lpc43_ethmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void lpc43_poll_work(FAR void *arg);
|
||||
#endif
|
||||
static void lpc43_poll_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
/* NuttX callback functions */
|
||||
|
||||
static int lpc43_ifup(struct net_driver_s *dev);
|
||||
static int lpc43_ifdown(struct net_driver_s *dev);
|
||||
static inline void lpc43_txavail_process(FAR struct lpc43_ethmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
|
||||
static void lpc43_txavail_work(FAR void *arg);
|
||||
#endif
|
||||
static int lpc43_txavail(struct net_driver_s *dev);
|
||||
|
||||
#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
|
||||
static int lpc43_addmac(struct net_driver_s *dev, FAR const uint8_t *mac);
|
||||
#endif
|
||||
@@ -1906,29 +1885,32 @@ static void lpc43_txdone(FAR struct lpc43_ethmac_s *priv)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_interrupt_process
|
||||
* Function: lpc43_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Interrupt processing. This may be performed either within the interrupt
|
||||
* handler or on the worker thread, depending upon the configuration
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void lpc43_interrupt_process(FAR struct lpc43_ethmac_s *priv)
|
||||
static void lpc43_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)arg;
|
||||
uint32_t dmasr;
|
||||
|
||||
DEBUGASSERT(priv);
|
||||
|
||||
/* Get the DMA interrupt status bits (no MAC interrupts are expected) */
|
||||
|
||||
net_lock();
|
||||
dmasr = lpc43_getreg(LPC43_ETH_DMASTAT);
|
||||
|
||||
/* Mask only enabled interrupts. This depends on the fact that the interrupt
|
||||
@@ -1980,7 +1962,6 @@ static inline void lpc43_interrupt_process(FAR struct lpc43_ethmac_s *priv)
|
||||
/* Handle error interrupt only if CONFIG_DEBUG_NET is eanbled */
|
||||
|
||||
#ifdef CONFIG_DEBUG_NET
|
||||
|
||||
/* Check if there are pending "abnormal" interrupts */
|
||||
|
||||
if ((dmasr & ETH_DMAINT_AIS) != 0)
|
||||
@@ -1997,45 +1978,13 @@ static inline void lpc43_interrupt_process(FAR struct lpc43_ethmac_s *priv)
|
||||
|
||||
lpc43_putreg(ETH_DMAINT_AIS, LPC43_ETH_DMASTAT);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void lpc43_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
DEBUGASSERT(priv);
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
state = net_lock();
|
||||
lpc43_interrupt_process(priv);
|
||||
net_unlock(state);
|
||||
net_unlock();
|
||||
|
||||
/* Re-enable Ethernet interrupts at the NVIC */
|
||||
|
||||
up_enable_irq(LPC43M4_IRQ_ETHERNET);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_interrupt
|
||||
@@ -2057,8 +2006,6 @@ static void lpc43_interrupt_work(FAR void *arg)
|
||||
static int lpc43_interrupt(int irq, FAR void *context)
|
||||
{
|
||||
FAR struct lpc43_ethmac_s *priv = &g_lpc43ethmac;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
uint32_t dmasr;
|
||||
|
||||
/* Get the DMA interrupt status bits (no MAC interrupts are expected) */
|
||||
@@ -2094,49 +2041,9 @@ static int lpc43_interrupt(int irq, FAR void *context)
|
||||
work_queue(ETHWORK, &priv->work, lpc43_interrupt_work, priv, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
lpc43_interrupt_process(priv);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_txtimeout_process
|
||||
*
|
||||
* Description:
|
||||
* Process a TX timeout. Called from the either the watchdog timer
|
||||
* expiration logic or from the worker thread, depending upon the
|
||||
* configuration. The timeout means that the last TX never completed.
|
||||
* Reset the hardware and start again.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Global interrupts are disabled by the watchdog logic.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void lpc43_txtimeout_process(FAR struct lpc43_ethmac_s *priv)
|
||||
{
|
||||
/* Then reset the hardware. Just take the interface down, then back
|
||||
* up again.
|
||||
*/
|
||||
|
||||
lpc43_ifdown(&priv->dev);
|
||||
lpc43_ifup(&priv->dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
lpc43_dopoll(priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_txtimeout_work
|
||||
*
|
||||
@@ -2154,19 +2061,23 @@ static inline void lpc43_txtimeout_process(FAR struct lpc43_ethmac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void lpc43_txtimeout_work(FAR void *arg)
|
||||
{
|
||||
FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
/* Then reset the hardware. Just take the interface down, then back
|
||||
* up again.
|
||||
*/
|
||||
|
||||
state = net_lock();
|
||||
lpc43_txtimeout_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
lpc43_ifdown(&priv->dev);
|
||||
lpc43_ifup(&priv->dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
lpc43_dopoll(priv);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_txtimeout_expiry
|
||||
@@ -2193,7 +2104,6 @@ static void lpc43_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
|
||||
ninfo("Timeout!\n");
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. This will prevent some race
|
||||
* conditions with interrupt work. There is still a potential race
|
||||
* condition with interrupt work that is already queued and in progress.
|
||||
@@ -2212,33 +2122,28 @@ static void lpc43_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
/* Schedule to perform the TX timeout processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->work, lpc43_txtimeout_work, priv, 0);
|
||||
|
||||
#else
|
||||
/* Process the timeout now */
|
||||
|
||||
lpc43_txtimeout_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_poll_process
|
||||
* Function: lpc43_poll_work
|
||||
*
|
||||
* Description:
|
||||
* Perform the periodic poll. This may be called either from watchdog
|
||||
* timer logic or from the worker thread, depending upon the configuration.
|
||||
* Perform periodic polling from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* arg - The argument passed when work_queue() as called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void lpc43_poll_process(FAR struct lpc43_ethmac_s *priv)
|
||||
static void lpc43_poll_work(FAR void *arg)
|
||||
{
|
||||
FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)arg;
|
||||
FAR struct net_driver_s *dev = &priv->dev;
|
||||
|
||||
/* Check if the next TX descriptor is owned by the Ethernet DMA or CPU. We
|
||||
@@ -2252,6 +2157,7 @@ static inline void lpc43_poll_process(FAR struct lpc43_ethmac_s *priv)
|
||||
* CONFIG_LPC43_ETH_NTXDESC).
|
||||
*/
|
||||
|
||||
net_lock();
|
||||
if ((priv->txhead->tdes0 & ETH_TDES0_OWN) == 0 &&
|
||||
priv->txhead->tdes2 == 0)
|
||||
{
|
||||
@@ -2287,39 +2193,9 @@ static inline void lpc43_poll_process(FAR struct lpc43_ethmac_s *priv)
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->txpoll, LPC43_WDDELAY, lpc43_poll_expiry, 1, priv);
|
||||
net_unlock();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_poll_work
|
||||
*
|
||||
* Description:
|
||||
* Perform periodic polling from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* arg - The argument passed when work_queue() as called.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void lpc43_poll_work(FAR void *arg)
|
||||
{
|
||||
FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
|
||||
state = net_lock();
|
||||
lpc43_poll_process(priv);
|
||||
net_unlock(state);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_poll_expiry
|
||||
*
|
||||
@@ -2342,7 +2218,6 @@ static void lpc43_poll_expiry(int argc, uint32_t arg, ...)
|
||||
{
|
||||
FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions.
|
||||
*/
|
||||
@@ -2362,12 +2237,6 @@ static void lpc43_poll_expiry(int argc, uint32_t arg, ...)
|
||||
(void)wd_start(priv->txpoll, LPC43_WDDELAY, lpc43_poll_expiry, 1,
|
||||
(uint32_t)priv);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
lpc43_poll_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -2473,37 +2342,6 @@ static int lpc43_ifdown(struct net_driver_s *dev)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_txavail_process
|
||||
*
|
||||
* Description:
|
||||
* Perform an out-of-cycle poll.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the NuttX driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called in normal user mode
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void lpc43_txavail_process(FAR struct lpc43_ethmac_s *priv)
|
||||
{
|
||||
ninfo("ifup: %d\n", priv->ifup);
|
||||
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
if (priv->ifup)
|
||||
{
|
||||
/* Poll for new XMIT data */
|
||||
|
||||
lpc43_dopoll(priv);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_txavail_work
|
||||
*
|
||||
@@ -2521,19 +2359,23 @@ static inline void lpc43_txavail_process(FAR struct lpc43_ethmac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void lpc43_txavail_work(FAR void *arg)
|
||||
{
|
||||
FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
state = net_lock();
|
||||
lpc43_txavail_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
ninfo("ifup: %d\n", priv->ifup);
|
||||
if (priv->ifup)
|
||||
{
|
||||
/* Poll for new XMIT data */
|
||||
|
||||
lpc43_dopoll(priv);
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_txavail
|
||||
@@ -2558,7 +2400,6 @@ static int lpc43_txavail(struct net_driver_s *dev)
|
||||
{
|
||||
FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)dev->d_private;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions and we will have to ignore the Tx
|
||||
* availability action.
|
||||
@@ -2571,21 +2412,6 @@ static int lpc43_txavail(struct net_driver_s *dev)
|
||||
work_queue(ETHWORK, &priv->work, lpc43_txavail_work, priv, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
irqstate_t flags;
|
||||
|
||||
/* Disable interrupts because this function may be called from interrupt
|
||||
* level processing.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Perform the out-of-cycle poll now */
|
||||
|
||||
lpc43_txavail_process(priv);
|
||||
leave_critical_section(flags);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -240,6 +240,7 @@ config ARCH_CHIP_SAM3A
|
||||
config ARCH_CHIP_SAM4CM
|
||||
bool
|
||||
default n
|
||||
select ARCH_HAVE_MULTICPU
|
||||
select ARCH_HAVE_TICKLESS
|
||||
|
||||
config ARCH_CHIP_SAM4L
|
||||
|
||||
@@ -50,13 +50,17 @@ CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S
|
||||
CMN_ASRCS += up_testset.S vfork.S
|
||||
|
||||
CMN_CSRCS = up_assert.c up_blocktask.c up_copyfullstate.c up_createstack.c
|
||||
CMN_CSRCS += up_mdelay.c up_udelay.c up_exit.c up_idle.c up_initialize.c
|
||||
CMN_CSRCS += up_mdelay.c up_udelay.c up_exit.c up_initialize.c
|
||||
CMN_CSRCS += up_initialstate.c up_interruptcontext.c up_memfault.c up_modifyreg8.c
|
||||
CMN_CSRCS += up_modifyreg16.c up_modifyreg32.c up_releasepending.c
|
||||
CMN_CSRCS += up_releasestack.c up_reprioritizertr.c up_schedulesigaction.c
|
||||
CMN_CSRCS += up_sigdeliver.c up_stackframe.c up_unblocktask.c up_usestack.c
|
||||
CMN_CSRCS += up_doirq.c up_hardfault.c up_svcall.c up_vfork.c
|
||||
|
||||
ifneq ($(CONFIG_SMP),y)
|
||||
CMN_CSRCS += up_idle.c
|
||||
endif
|
||||
|
||||
# Configuration-dependent common files
|
||||
|
||||
ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y)
|
||||
@@ -198,14 +202,22 @@ endif
|
||||
ifeq ($(CONFIG_ARCH_CHIP_SAM4CM),y)
|
||||
ifeq ($(CONFIG_SAM34_TC),y)
|
||||
CHIP_CSRCS += sam4cm_tc.c
|
||||
|
||||
ifeq ($(CONFIG_SAM34_ONESHOT),y)
|
||||
CHIP_CSRCS += sam4cm_oneshot.c sam4cm_oneshot_lowerhalf.c
|
||||
endif
|
||||
endif # CONFIG_SAM34_ONESHOT
|
||||
|
||||
ifeq ($(CONFIG_SAM34_FREERUN),y)
|
||||
CHIP_CSRCS += sam4cm_freerun.c
|
||||
endif
|
||||
endif # CONFIG_SAM34_FREERUN
|
||||
|
||||
ifeq ($(CONFIG_SCHED_TICKLESS),y)
|
||||
CHIP_CSRCS += sam4cm_tickless.c
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif # CONFIG_SCHED_TICKLESS
|
||||
endif # CONFIG_SAM34_TC
|
||||
|
||||
ifeq ($(CONFIG_SMP),y)
|
||||
CHIP_CSRCS += sam4cm_cpuindex.c sam4cm_cpuidlestack.c
|
||||
CHIP_CSRCS += sam4cm_cpupause.c sam4cm_cpustart.c sam4cm_idle.c
|
||||
endif # CONFIG_SMP
|
||||
endif # CONFIG_ARCH_CHIP_SAM4CM
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
/* Internal SRAM memory region */
|
||||
|
||||
#define SAM_INTSRAM0_BASE 0x20000000 /* For SAM3U compatibility */
|
||||
#define SAM_INTSRAM1_BASE 0x20080000 /* 0x20080000-0x200fffff: Internal SRAM 1 */
|
||||
#define SAM_BBSRAM_BASE 0x22000000 /* 0x22000000-0x23ffffff: 32MB bit-band region */
|
||||
/* 0x24000000-0x3fffffff: Undefined */
|
||||
/* Peripherals address region */
|
||||
|
||||
@@ -402,10 +402,10 @@
|
||||
# define PMC_MCKR_CPCSS_SHIFT (16)
|
||||
# define PMC_MCKR_CPCSS_MASK (0x7 << PMC_MCKR_CPCSS_SHIFT)
|
||||
# define PMC_MCKR_CPCSS_SLOW (0 << PMC_MCKR_CPCSS_SHIFT) /* Slow Clock */
|
||||
# define PMC_MCKR_CCPSS_MAIN (1 << PMC_MCKR_CPCSS_SHIFT) /* Main Clock */
|
||||
# define PMC_MCKR_CCPSS_PLLA (2 << PMC_MCKR_CPCSS_SHIFT) /* PLLA Clock */
|
||||
# define PMC_MCKR_CCPSS_PLLB (3 << PMC_MCKR_CPCSS_SHIFT) /* PLLB Clock */
|
||||
# define PMC_MCKR_CCPSS_MCK (4 << PMC_MCKR_CPCSS_SHIFT) /* Master Clock */
|
||||
# define PMC_MCKR_CPCSS_MAIN (1 << PMC_MCKR_CPCSS_SHIFT) /* Main Clock */
|
||||
# define PMC_MCKR_CPCSS_PLLA (2 << PMC_MCKR_CPCSS_SHIFT) /* PLLA Clock */
|
||||
# define PMC_MCKR_CPCSS_PLLB (3 << PMC_MCKR_CPCSS_SHIFT) /* PLLB Clock */
|
||||
# define PMC_MCKR_CPCSS_MCK (4 << PMC_MCKR_CPCSS_SHIFT) /* Master Clock */
|
||||
# define PMC_MCKR_CPPRES_SHIFT (20)
|
||||
# define PMC_MCKR_CPPRES_MASK (0xF << PMC_MCKR_CPPRES_SHIFT)
|
||||
# define PMC_MCKR_CPPRES(D) (((D) - 1) << PMC_MCKR_CPPRES_SHIFT)
|
||||
@@ -547,13 +547,14 @@
|
||||
/* Peripheral Clock Status Register 1 */
|
||||
|
||||
#if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3X) || \
|
||||
defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E)
|
||||
defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E) || \
|
||||
defined(CONFIG_ARCH_CHIP_SAM4CM)
|
||||
# define PMC_PIDH(n) (1 << ((n) - 32))
|
||||
# define PMC_PID32 (1 << 0) /* Bit 0: PID32 */
|
||||
# define PMC_PID33 (1 << 1) /* Bit 1: PID33 */
|
||||
# define PMC_PID34 (1 << 2) /* Bit 2: PID34 */
|
||||
# if defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3X) || \
|
||||
defined(CONFIG_ARCH_CHIP_SAM4E)
|
||||
defined(CONFIG_ARCH_CHIP_SAM4E) || defined(CONFIG_ARCH_CHIP_SAM4CM)
|
||||
# define PMC_PID35 (1 << 3) /* Bit 3: PID35 */
|
||||
# define PMC_PID36 (1 << 4) /* Bit 4: PID36 */
|
||||
# define PMC_PID37 (1 << 5) /* Bit 5: PID37 */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user