summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-01-23 07:56:10 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-01-23 07:56:10 -0600
commitfa2903e34a1d4f32b1fed316c843134245d47ac2 (patch)
treea7e0b603d228ca335e4547be539547134be86e7e
parentd61269128b30220efab74363c76b5985804009e3 (diff)
downloadnuttx-fa2903e34a1d4f32b1fed316c843134245d47ac2.tar.gz
nuttx-fa2903e34a1d4f32b1fed316c843134245d47ac2.tar.bz2
nuttx-fa2903e34a1d4f32b1fed316c843134245d47ac2.zip
Basic support for the EFM32 processor family from Richar Cochran
-rw-r--r--nuttx/arch/arm/Kconfig11
-rw-r--r--nuttx/arch/arm/include/efm32/chip.h54
-rw-r--r--nuttx/arch/arm/include/efm32/irq.h65
-rw-r--r--nuttx/arch/arm/src/efm32/Kconfig52
-rw-r--r--nuttx/arch/arm/src/efm32/Make.defs136
-rw-r--r--nuttx/arch/arm/src/efm32/chip.h54
-rw-r--r--nuttx/arch/arm/src/efm32/efm32_idle.c96
-rw-r--r--nuttx/arch/arm/src/efm32/efm32_irq.c539
-rw-r--r--nuttx/arch/arm/src/efm32/efm32_lowputc.c111
-rw-r--r--nuttx/arch/arm/src/efm32/efm32_lowputc.h55
-rw-r--r--nuttx/arch/arm/src/efm32/efm32_start.c223
-rw-r--r--nuttx/arch/arm/src/efm32/efm32_timerisr.c143
-rw-r--r--nuttx/arch/arm/src/efm32/efm32_vectors.S121
13 files changed, 1660 insertions, 0 deletions
diff --git a/nuttx/arch/arm/Kconfig b/nuttx/arch/arm/Kconfig
index 0e721697f..9c3954528 100644
--- a/nuttx/arch/arm/Kconfig
+++ b/nuttx/arch/arm/Kconfig
@@ -42,6 +42,13 @@ config ARCH_CHIP_DM320
---help---
TI DMS320 DM320 (ARM926EJS)
+config ARCH_CHIP_EFM32
+ bool "Energy Micro"
+ select ARCH_HAVE_CMNVECTOR
+ select ARMV7M_CMNVECTOR
+ ---help---
+ Energy Micro EFM32 microcontrollers (ARM Cortex-M).
+
config ARCH_CHIP_IMX
bool "Freescale iMX"
select ARCH_ARM920T
@@ -210,6 +217,7 @@ config ARCH_CHIP
default "c5471" if ARCH_CHIP_C5471
default "calypso" if ARCH_CHIP_CALYPSO
default "dm320" if ARCH_CHIP_DM320
+ default "efm32" if ARCH_CHIP_EFM32
default "imx" if ARCH_CHIP_IMX
default "kinetis" if ARCH_CHIP_KINETIS
default "kl" if ARCH_CHIP_KL
@@ -346,6 +354,9 @@ endif
if ARCH_CHIP_DM320
source arch/arm/src/dm320/Kconfig
endif
+if ARCH_CHIP_EFM32
+source arch/arm/src/efm32/Kconfig
+endif
if ARCH_CHIP_IMX
source arch/arm/src/imx/Kconfig
endif
diff --git a/nuttx/arch/arm/include/efm32/chip.h b/nuttx/arch/arm/include/efm32/chip.h
new file mode 100644
index 000000000..b0d2a2ac5
--- /dev/null
+++ b/nuttx/arch/arm/include/efm32/chip.h
@@ -0,0 +1,54 @@
+/************************************************************************************
+ * arch/arm/include/efm32/chip.h
+ *
+ * Copyright (C) 2014 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.
+ *
+ ************************************************************************************/
+
+#ifndef __ARCH_ARM_INCLUDE_EFM32_CHIP_H
+#define __ARCH_ARM_INCLUDE_EFM32_CHIP_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <arch/efm32/irq.h>
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+#define NVIC_SYSH_PRIORITY_MIN 0xe0 /* Bits [7:5] set in minimum priority */
+#define NVIC_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */
+#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */
+#define NVIC_SYSH_PRIORITY_STEP 0x20 /* Three bits of interrupt priority used */
+
+#endif /* __ARCH_ARM_INCLUDE_EFM32_CHIP_H */
diff --git a/nuttx/arch/arm/include/efm32/irq.h b/nuttx/arch/arm/include/efm32/irq.h
new file mode 100644
index 000000000..c891e3c0f
--- /dev/null
+++ b/nuttx/arch/arm/include/efm32/irq.h
@@ -0,0 +1,65 @@
+/************************************************************************************
+ * arch/arm/include/efm32s/irq.h
+ *
+ * Copyright (C) 2014 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.
+ *
+ ************************************************************************************/
+
+#ifndef __ARCH_ARM_INCLUDE_EFM32_IRQ_H
+#define __ARCH_ARM_INCLUDE_EFM32_IRQ_H
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+#define EFM32_IRQ_RESERVED (0) /* Reserved vector (only used with CONFIG_DEBUG) */
+ /* Vector 0: Reset stack pointer value */
+ /* Vector 1: Reset (not handler as an IRQ) */
+#define EFM32_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */
+#define EFM32_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */
+#define EFM32_IRQ_MEMFAULT (4) /* Vector 4: Memory management (MPU) */
+#define EFM32_IRQ_BUSFAULT (5) /* Vector 5: Bus fault */
+#define EFM32_IRQ_USAGEFAULT (6) /* Vector 6: Usage fault */
+#define EFM32_IRQ_SVCALL (11) /* Vector 11: SVC call */
+#define EFM32_IRQ_DBGMONITOR (12) /* Vector 12: Debug Monitor */
+ /* Vector 13: Reserved */
+#define EFM32_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */
+#define EFM32_IRQ_SYSTICK (15) /* Vector 15: System tick */
+
+/* External interrupts (vectors >= 16). These definitions are chip-specific */
+
+#define EFM32_IRQ_INTERRUPTS (16) /* Vector number of the first external interrupt */
+
+#define ARMV7M_PERIPHERAL_INTERRUPTS 38
+
+#define NR_IRQS (16 + ARMV7M_PERIPHERAL_INTERRUPTS)
+
+#endif /* __ARCH_ARM_INCLUDE_EFM32_IRQ_H */
diff --git a/nuttx/arch/arm/src/efm32/Kconfig b/nuttx/arch/arm/src/efm32/Kconfig
new file mode 100644
index 000000000..280decd87
--- /dev/null
+++ b/nuttx/arch/arm/src/efm32/Kconfig
@@ -0,0 +1,52 @@
+#
+# arch/arm/src/efm32/Kconfig
+#
+
+if ARCH_CHIP_EFM32
+
+comment "EFM32 Configuration Options"
+
+config ARCH_CHIP_EFM32_EMLIB_PATH
+ string "External Energy Micro Sources"
+ default "/cygdrive/c/energymicro"
+ ---help---
+ The EFM32 port uses the Energy Micro headers and their
+ emlib sources. This string defines the include path to
+ the root directory of the Energy Micro source. That
+ directory will contain the following sub-directories.
+
+ - CMSIS/Include
+ - Device/EnergyMicro/EFM32LG/Include
+ - emlib/inc
+
+ This string may be either an absolute path, or a path
+ relative to arch/arm/src.
+
+choice
+ prompt "EFM32 Chip Selection"
+ default ARCH_CHIP_EFM32LG990F256
+
+config ARCH_CHIP_EFM32LG232F128
+ bool "EFM32LG232F128"
+ select ARCH_CORTEXM3
+ ---help---
+ This chip is a Leopard Gecko with 128 KB flash
+ and 32 KB RAM in a QFP64 package
+
+config ARCH_CHIP_EFM32LG990F256
+ bool "EFM32LG990F256"
+ select ARCH_CORTEXM3
+ ---help---
+ This chip is a Leopard Gecko with 256 KB flash
+ and 32 KB RAM in a BGA112 package.
+
+config ARCH_CHIP_EFM32GG990F1024
+ bool "EFM32GG990F1024"
+ select ARCH_CORTEXM3
+ ---help---
+ This chip is a Giant Gecko with 1024 KB flash
+ and 128 KB RAM in a BGA112 package.
+
+endchoice
+
+endif
diff --git a/nuttx/arch/arm/src/efm32/Make.defs b/nuttx/arch/arm/src/efm32/Make.defs
new file mode 100644
index 000000000..db7924e5e
--- /dev/null
+++ b/nuttx/arch/arm/src/efm32/Make.defs
@@ -0,0 +1,136 @@
+############################################################################
+# arch/arm/src/efm32/Make.defs
+#
+# Copyright (C) 2009, 2011-2014 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.
+#
+############################################################################
+
+ifeq ($(CONFIG_ARCH_CHIP_EFM32LG232F128),y)
+CFLAGS += -DEFM32LG232F128
+else ifeq ($(CONFIG_ARCH_CHIP_EFM32LG990F256),y)
+CFLAGS += -DEFM32LG990F256
+else ifeq ($(CONFIG_ARCH_CHIP_EFM32GG990F1024),y)
+CFLAGS += -DEFM32GG990F1024
+endif
+
+ifeq (-DEFM32LG, $(findstring -DEFM32LG,$(CFLAGS)))
+EM_INCDIR := EFM32LG
+SYSTEM_EFM32_C := system_efm32lg.c
+else ifeq (-DEFM32GG, $(findstring -DEFM32GG,$(CFLAGS)))
+EM_INCDIR := EFM32GG
+SYSTEM_EFM32_C := system_efm32gg.c
+else
+$(error unknown efm32 part)
+endif
+
+ext := $(patsubst "%",%,$(strip $(CONFIG_ARCH_CHIP_EFM32_EMLIB_PATH)))
+
+ifeq ($(WINTOOL),y)
+CFLAGS += -I"${shell cygpath -w $(ext)/CMSIS/Include}"
+CFLAGS += -I"${shell cygpath -w $(ext)/Device/EnergyMicro/$(EM_INCDIR)/Include}"
+CFLAGS += -I"${shell cygpath -w $(ext)/emlib/inc}"
+else
+CFLAGS += -I$(ext)/CMSIS/Include
+CFLAGS += -I$(ext)/Device/EnergyMicro/$(EM_INCDIR)/Include
+CFLAGS += -I$(ext)/emlib/inc
+endif
+
+VPATH += $(ext)/emlib/src
+VPATH += $(ext)/Device/EnergyMicro/$(EM_INCDIR)/Source
+
+HEAD_ASRC =
+CMN_UASRCS =
+CMN_UCSRCS =
+
+CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S
+CMN_ASRCS += up_exception.S
+CMN_ASRCS += vfork.S
+
+ifeq ($(CONFIG_ARCH_MEMCPY),y)
+CMN_ASRCS += up_memcpy.S
+endif
+
+CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copyfullstate.c
+CMN_CSRCS += up_createstack.c up_mdelay.c up_udelay.c up_exit.c
+CMN_CSRCS += up_initialize.c up_initialstate.c up_interruptcontext.c
+CMN_CSRCS += up_memfault.c up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c
+CMN_CSRCS += up_releasepending.c up_releasestack.c up_reprioritizertr.c
+CMN_CSRCS += up_schedulesigaction.c up_sigdeliver.c up_systemreset.c
+CMN_CSRCS += up_unblocktask.c up_usestack.c up_doirq.c up_hardfault.c
+CMN_CSRCS += up_svcall.c up_vfork.c
+CMN_CSRCS += up_vectors.c
+
+ifeq ($(CONFIG_ARCH_RAMVECTORS),y)
+CMN_CSRCS += up_ramvec_initialize.c up_ramvec_attach.c
+endif
+
+ifeq ($(CONFIG_NUTTX_KERNEL),y)
+CMN_CSRCS += up_mpu.c up_task_start.c up_pthread_start.c up_stackframe.c
+ifneq ($(CONFIG_DISABLE_SIGNALS),y)
+CMN_CSRCS += up_signal_dispatch.c
+CMN_UASRCS += up_signal_handler.S
+endif
+endif
+
+ifeq ($(CONFIG_DEBUG_STACK),y)
+CMN_CSRCS += up_checkstack.c
+endif
+
+ifeq ($(CONFIG_ELF),y)
+CMN_CSRCS += up_elf.c
+endif
+
+ifeq ($(CONFIG_ARCH_FPU),y)
+CMN_ASRCS += up_fpu.S
+ifneq ($(CONFIG_ARMV7M_CMNVECTOR),y)
+CMN_CSRCS += up_copyarmstate.c
+endif
+endif
+
+CHIP_ASRCS = efm32_vectors.S
+
+CHIP_CSRCS = \
+efm32_irq.c \
+efm32_start.c \
+efm32_timerisr.c \
+em_cmu.c \
+em_emu.c \
+em_gpio.c \
+em_usart.c \
+$(SYSTEM_EFM32_C)
+
+ifeq ($(CONFIG_DEV_LOWCONSOLE),y)
+CHIP_CSRCS += efm32_lowputc.c
+endif
+
+ifneq ($(CONFIG_IDLE_CUSTOM),y)
+CHIP_CSRCS += efm32_idle.c
+endif
diff --git a/nuttx/arch/arm/src/efm32/chip.h b/nuttx/arch/arm/src/efm32/chip.h
new file mode 100644
index 000000000..f564cf35c
--- /dev/null
+++ b/nuttx/arch/arm/src/efm32/chip.h
@@ -0,0 +1,54 @@
+/************************************************************************************
+ * arch/arm/src/efm32/chip.h
+ *
+ * Copyright (C) 2014 Richard Cochran. All rights reserved.
+ * Author: Richard Cochran <richardcochran@gmail.com>
+ *
+ * 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_EFM32_CHIP_H
+#define __ARCH_ARM_SRC_EFM32_CHIP_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+/*
+ * Greg says:
+ *
+ * This arch/arm/src/stm32/chip.h file was a bad idea that happened a
+ * long time ago. Right now, I believe that its only required to be
+ * there to provide the number of interrupt vectors. It is included
+ * by armv7-m/up_vectors.c where that value is used.
+ */
+
+#include <arch/efm32/chip.h>
+
+#endif /* __ARCH_ARM_SRC_EFM32_CHIP_H */
diff --git a/nuttx/arch/arm/src/efm32/efm32_idle.c b/nuttx/arch/arm/src/efm32/efm32_idle.c
new file mode 100644
index 000000000..0673fd099
--- /dev/null
+++ b/nuttx/arch/arm/src/efm32/efm32_idle.c
@@ -0,0 +1,96 @@
+/****************************************************************************
+ * arch/arm/src/efm32/efm32_idle.c
+ *
+ * Copyright (C) 2011-2012, 2014 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 <arch/board/board.h>
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/power/pm.h>
+
+#include <arch/irq.h>
+
+#include "chip.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Does the board support an IDLE LED to indicate that the board is in the
+ * IDLE state?
+ */
+
+#if defined(CONFIG_ARCH_LEDS) && defined(LED_IDLE)
+# define BEGIN_IDLE() up_ledon(LED_IDLE)
+# define END_IDLE() up_ledoff(LED_IDLE)
+#else
+# define BEGIN_IDLE()
+# define END_IDLE()
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_idle
+ *
+ * Description:
+ * up_idle() is the logic that will be executed when their is no other
+ * ready-to-run task. This is processor idle time and will continue until
+ * some interrupt occurs to cause a context switch from the idle task.
+ *
+ * Processing in this state may be processor-specific. e.g., this is where
+ * power management operations might be performed.
+ *
+ ****************************************************************************/
+
+void up_idle(void)
+{
+ /* Perform IDLE mode power management */
+ /* Sleep until an interrupt occurs to save power. */
+}
diff --git a/nuttx/arch/arm/src/efm32/efm32_irq.c b/nuttx/arch/arm/src/efm32/efm32_irq.c
new file mode 100644
index 000000000..3bca26365
--- /dev/null
+++ b/nuttx/arch/arm/src/efm32/efm32_irq.c
@@ -0,0 +1,539 @@
+/****************************************************************************
+ * arch/arm/src/efm32/efm32_irq.c
+ *
+ * Copyright (C) 2009-2014 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 <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <arch/irq.h>
+
+#include "nvic.h"
+#include "ram_vectors.h"
+#include "up_arch.h"
+#include "os_internal.h"
+#include "up_internal.h"
+
+#include "chip.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Get a 32-bit version of the default priority */
+
+#define DEFPRIORITY32 \
+ (NVIC_SYSH_PRIORITY_DEFAULT << 24 |\
+ NVIC_SYSH_PRIORITY_DEFAULT << 16 |\
+ NVIC_SYSH_PRIORITY_DEFAULT << 8 |\
+ NVIC_SYSH_PRIORITY_DEFAULT)
+
+/* Given the address of a NVIC ENABLE register, this is the offset to
+ * the corresponding CLEAR ENABLE register.
+ */
+
+#define NVIC_ENA_OFFSET (0)
+#define NVIC_CLRENA_OFFSET (NVIC_IRQ0_31_CLEAR - NVIC_IRQ0_31_ENABLE)
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+volatile uint32_t *current_regs;
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: efm32_dumpnvic
+ *
+ * Description:
+ * Dump some interesting NVIC registers
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_IRQ)
+static void efm32_dumpnvic(const char *msg, int irq)
+{
+ irqstate_t flags;
+
+ flags = irqsave();
+ lldbg("NVIC (%s, irq=%d):\n", msg, irq);
+ lldbg(" INTCTRL: %08x VECTAB: %08x\n",
+ getreg32(NVIC_INTCTRL), getreg32(NVIC_VECTAB));
+#if 0
+ lldbg(" SYSH ENABLE MEMFAULT: %08x BUSFAULT: %08x USGFAULT: %08x SYSTICK: %08x\n",
+ getreg32(NVIC_SYSHCON_MEMFAULTENA), getreg32(NVIC_SYSHCON_BUSFAULTENA),
+ getreg32(NVIC_SYSHCON_USGFAULTENA), getreg32(NVIC_SYSTICK_CTRL_ENABLE));
+#endif
+ lldbg(" IRQ ENABLE: %08x %08x %08x\n",
+ getreg32(NVIC_IRQ0_31_ENABLE), getreg32(NVIC_IRQ32_63_ENABLE),
+ getreg32(NVIC_IRQ64_95_ENABLE));
+ lldbg(" SYSH_PRIO: %08x %08x %08x\n",
+ getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY),
+ getreg32(NVIC_SYSH12_15_PRIORITY));
+ lldbg(" IRQ PRIO: %08x %08x %08x %08x\n",
+ getreg32(NVIC_IRQ0_3_PRIORITY), getreg32(NVIC_IRQ4_7_PRIORITY),
+ getreg32(NVIC_IRQ8_11_PRIORITY), getreg32(NVIC_IRQ12_15_PRIORITY));
+ lldbg(" %08x %08x %08x %08x\n",
+ getreg32(NVIC_IRQ16_19_PRIORITY), getreg32(NVIC_IRQ20_23_PRIORITY),
+ getreg32(NVIC_IRQ24_27_PRIORITY), getreg32(NVIC_IRQ28_31_PRIORITY));
+ lldbg(" %08x %08x %08x %08x\n",
+ getreg32(NVIC_IRQ32_35_PRIORITY), getreg32(NVIC_IRQ36_39_PRIORITY),
+ getreg32(NVIC_IRQ40_43_PRIORITY), getreg32(NVIC_IRQ44_47_PRIORITY));
+ lldbg(" %08x %08x %08x %08x\n",
+ getreg32(NVIC_IRQ48_51_PRIORITY), getreg32(NVIC_IRQ52_55_PRIORITY),
+ getreg32(NVIC_IRQ56_59_PRIORITY), getreg32(NVIC_IRQ60_63_PRIORITY));
+ lldbg(" %08x\n",
+ getreg32(NVIC_IRQ64_67_PRIORITY));
+ irqrestore(flags);
+}
+#else
+# define efm32_dumpnvic(msg, irq)
+#endif
+
+/****************************************************************************
+ * Name: efm32_nmi, efm32_busfault, efm32_usagefault, efm32_pendsv,
+ * efm32_dbgmonitor, efm32_pendsv, efm32_reserved
+ *
+ * Description:
+ * Handlers for various execptions. None are handled and all are fatal
+ * error conditions. The only advantage these provided over the default
+ * unexpected interrupt handler is that they provide a diagnostic output.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG
+static int efm32_nmi(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! NMI received\n");
+ PANIC();
+ return 0;
+}
+
+static int efm32_busfault(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Bus fault received: %08x\n", getreg32(NVIC_CFAULTS));
+ PANIC();
+ return 0;
+}
+
+static int efm32_usagefault(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Usage fault received: %08x\n", getreg32(NVIC_CFAULTS));
+ PANIC();
+ return 0;
+}
+
+static int efm32_pendsv(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! PendSV received\n");
+ PANIC();
+ return 0;
+}
+
+static int efm32_dbgmonitor(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Debug Monitor receieved\n");
+ PANIC();
+ return 0;
+}
+
+static int efm32_reserved(int irq, FAR void *context)
+{
+ (void)irqsave();
+ dbg("PANIC!!! Reserved interrupt\n");
+ PANIC();
+ return 0;
+}
+#endif
+
+/****************************************************************************
+ * Name: efm32_prioritize_syscall
+ *
+ * Description:
+ * Set the priority of an exception. This function may be needed
+ * internally even if support for prioritized interrupts is not enabled.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ARMV7M_USEBASEPRI
+static inline void efm32_prioritize_syscall(int priority)
+{
+ uint32_t regval;
+
+ /* SVCALL is system handler 11 */
+
+ regval = getreg32(NVIC_SYSH8_11_PRIORITY);
+ regval &= ~NVIC_SYSH_PRIORITY_PR11_MASK;
+ regval |= (priority << NVIC_SYSH_PRIORITY_PR11_SHIFT);
+ putreg32(regval, NVIC_SYSH8_11_PRIORITY);
+}
+#endif
+
+/****************************************************************************
+ * Name: efm32_irqinfo
+ *
+ * Description:
+ * Given an IRQ number, provide the register and bit setting to enable or
+ * disable the irq.
+ *
+ ****************************************************************************/
+
+static int efm32_irqinfo(int irq, uintptr_t *regaddr, uint32_t *bit,
+ uintptr_t offset)
+{
+ DEBUGASSERT(irq >= EFM32_IRQ_NMI && irq < NR_IRQS);
+
+ /* Check for external interrupt */
+
+ if (irq >= EFM32_IRQ_INTERRUPTS)
+ {
+ if (irq < EFM32_IRQ_INTERRUPTS + 32)
+ {
+ *regaddr = (NVIC_IRQ0_31_ENABLE + offset);
+ *bit = 1 << (irq - EFM32_IRQ_INTERRUPTS);
+ }
+ else if (irq < EFM32_IRQ_INTERRUPTS + 64)
+ {
+ *regaddr = (NVIC_IRQ32_63_ENABLE + offset);
+ *bit = 1 << (irq - EFM32_IRQ_INTERRUPTS - 32);
+ }
+ else if (irq < NR_IRQS)
+ {
+ *regaddr = (NVIC_IRQ64_95_ENABLE + offset);
+ *bit = 1 << (irq - EFM32_IRQ_INTERRUPTS - 64);
+ }
+ else
+ {
+ return ERROR; /* Invalid interrupt */
+ }
+ }
+
+ /* Handle processor exceptions. Only a few can be disabled */
+
+ else
+ {
+ *regaddr = NVIC_SYSHCON;
+ if (irq == EFM32_IRQ_MEMFAULT)
+ {
+ *bit = NVIC_SYSHCON_MEMFAULTENA;
+ }
+ else if (irq == EFM32_IRQ_BUSFAULT)
+ {
+ *bit = NVIC_SYSHCON_BUSFAULTENA;
+ }
+ else if (irq == EFM32_IRQ_USAGEFAULT)
+ {
+ *bit = NVIC_SYSHCON_USGFAULTENA;
+ }
+ else if (irq == EFM32_IRQ_SYSTICK)
+ {
+ *regaddr = NVIC_SYSTICK_CTRL;
+ *bit = NVIC_SYSTICK_CTRL_ENABLE;
+ }
+ else
+ {
+ return ERROR; /* Invalid or unsupported exception */
+ }
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_irqinitialize
+ ****************************************************************************/
+
+void up_irqinitialize(void)
+{
+ uint32_t regaddr;
+ int num_priority_registers;
+
+ /* Disable all interrupts */
+
+ putreg32(0, NVIC_IRQ0_31_ENABLE);
+ putreg32(0, NVIC_IRQ32_63_ENABLE);
+
+ /* Colorize the interrupt stack for debug purposes */
+
+#if defined(CONFIG_DEBUG_STACK) && CONFIG_ARCH_INTERRUPTSTACK > 3
+ {
+ size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3);
+ up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size),
+ intstack_size);
+ }
+#endif
+
+ /*
+ * If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based
+ * vector table that requires special initialization.
+ */
+#if defined(CONFIG_ARCH_RAMVECTORS)
+ up_ramvec_initialize();
+#endif
+
+ /* Set all interrupts (and exceptions) to the default priority */
+
+ putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY);
+
+ /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt
+ * lines that the NVIC supports:
+ *
+ * 0 -> 32 interrupt lines, 8 priority registers
+ * 1 -> 64 " " " ", 16 priority registers
+ * 2 -> 96 " " " ", 32 priority registers
+ * ...
+ */
+
+ num_priority_registers = (getreg32(NVIC_ICTR) + 1) * 8;
+
+ /* Now set all of the interrupt lines to the default priority */
+
+ regaddr = NVIC_IRQ0_3_PRIORITY;
+ while (num_priority_registers--)
+ {
+ putreg32(DEFPRIORITY32, regaddr);
+ regaddr += 4;
+ }
+
+ /* currents_regs is non-NULL only while processing an interrupt */
+
+ current_regs = NULL;
+
+ /* Attach the SVCall and Hard Fault exception handlers. The SVCall
+ * exception is used for performing context switches; The Hard Fault
+ * must also be caught because a SVCall may show up as a Hard Fault
+ * under certain conditions.
+ */
+
+ irq_attach(EFM32_IRQ_SVCALL, up_svcall);
+ irq_attach(EFM32_IRQ_HARDFAULT, up_hardfault);
+
+ /* Set the priority of the SVCall interrupt */
+
+#ifdef CONFIG_ARMV7M_USEBASEPRI
+ efm32_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY);
+#endif
+
+ /* If the MPU is enabled, then attach and enable the Memory Management
+ * Fault handler.
+ */
+
+#ifdef CONFIG_ARMV7M_MPU
+ irq_attach(EFM32_IRQ_MEMFAULT, up_memfault);
+ up_enable_irq(EFM32_IRQ_MEMFAULT);
+#endif
+
+ /* Attach all other processor exceptions (except reset and sys tick) */
+
+#ifdef CONFIG_DEBUG
+ irq_attach(EFM32_IRQ_NMI, efm32_nmi);
+#ifndef CONFIG_ARMV7M_MPU
+ irq_attach(EFM32_IRQ_MEMFAULT, up_memfault);
+#endif
+ irq_attach(EFM32_IRQ_BUSFAULT, efm32_busfault);
+ irq_attach(EFM32_IRQ_USAGEFAULT, efm32_usagefault);
+ irq_attach(EFM32_IRQ_PENDSV, efm32_pendsv);
+ irq_attach(EFM32_IRQ_DBGMONITOR, efm32_dbgmonitor);
+ irq_attach(EFM32_IRQ_RESERVED, efm32_reserved);
+#endif
+
+ efm32_dumpnvic("initial", NR_IRQS);
+
+#ifndef CONFIG_SUPPRESS_INTERRUPTS
+
+ /* And finally, enable interrupts */
+
+ irqenable();
+#endif
+}
+
+/****************************************************************************
+ * Name: up_disable_irq
+ *
+ * Description:
+ * Disable the IRQ specified by 'irq'
+ *
+ ****************************************************************************/
+
+void up_disable_irq(int irq)
+{
+ uintptr_t regaddr;
+ uint32_t regval;
+ uint32_t bit;
+
+ if (efm32_irqinfo(irq, &regaddr, &bit, NVIC_CLRENA_OFFSET) == 0)
+ {
+ /* Modify the appropriate bit in the register to disable the interrupt.
+ * For normal interrupts, we need to set the bit in the associated
+ * Interrupt Clear Enable register. For other exceptions, we need to
+ * clear the bit in the System Handler Control and State Register.
+ */
+
+ if (irq >= EFM32_IRQ_INTERRUPTS)
+ {
+ putreg32(bit, regaddr);
+ }
+ else
+ {
+ regval = getreg32(regaddr);
+ regval &= ~bit;
+ putreg32(regval, regaddr);
+ }
+ }
+
+ efm32_dumpnvic("disable", irq);
+}
+
+/****************************************************************************
+ * Name: up_enable_irq
+ *
+ * Description:
+ * Enable the IRQ specified by 'irq'
+ *
+ ****************************************************************************/
+
+void up_enable_irq(int irq)
+{
+ uintptr_t regaddr;
+ uint32_t regval;
+ uint32_t bit;
+
+ if (efm32_irqinfo(irq, &regaddr, &bit, NVIC_ENA_OFFSET) == 0)
+ {
+ /* Modify the appropriate bit in the register to enable the interrupt.
+ * For normal interrupts, we need to set the bit in the associated
+ * Interrupt Set Enable register. For other exceptions, we need to
+ * set the bit in the System Handler Control and State Register.
+ */
+
+ if (irq >= EFM32_IRQ_INTERRUPTS)
+ {
+ putreg32(bit, regaddr);
+ }
+ else
+ {
+ regval = getreg32(regaddr);
+ regval |= bit;
+ putreg32(regval, regaddr);
+ }
+ }
+
+ efm32_dumpnvic("enable", irq);
+}
+
+/****************************************************************************
+ * Name: up_ack_irq
+ *
+ * Description:
+ * Acknowledge the IRQ
+ *
+ ****************************************************************************/
+
+void up_ack_irq(int irq)
+{
+}
+
+/****************************************************************************
+ * Name: up_prioritize_irq
+ *
+ * Description:
+ * Set the priority of an IRQ.
+ *
+ * Since this API is not supported on all architectures, it should be
+ * avoided in common implementations where possible.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ARCH_IRQPRIO
+int up_prioritize_irq(int irq, int priority)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+ int shift;
+
+ DEBUGASSERT(irq >= EFM32_IRQ_MEMFAULT && irq < NR_IRQS &&
+ (unsigned)priority <= NVIC_SYSH_PRIORITY_MIN);
+
+ if (irq < EFM32_IRQ_INTERRUPTS)
+ {
+ /* NVIC_SYSH_PRIORITY() maps {0..15} to one of three priority
+ * registers (0-3 are invalid)
+ */
+
+ regaddr = NVIC_SYSH_PRIORITY(irq);
+ irq -= 4;
+ }
+ else
+ {
+ /* NVIC_IRQ_PRIORITY() maps {0..} to one of many priority registers */
+
+ irq -= EFM32_IRQ_INTERRUPTS;
+ regaddr = NVIC_IRQ_PRIORITY(irq);
+ }
+
+ regval = getreg32(regaddr);
+ shift = ((irq & 3) << 3);
+ regval &= ~(0xff << shift);
+ regval |= (priority << shift);
+ putreg32(regval, regaddr);
+
+ efm32_dumpnvic("prioritize", irq);
+ return OK;
+}
+#endif
diff --git a/nuttx/arch/arm/src/efm32/efm32_lowputc.c b/nuttx/arch/arm/src/efm32/efm32_lowputc.c
new file mode 100644
index 000000000..73801ad46
--- /dev/null
+++ b/nuttx/arch/arm/src/efm32/efm32_lowputc.c
@@ -0,0 +1,111 @@
+/****************************************************************************
+ * arch/arm/src/efm32/efm32_lowputc.c
+ *
+ * Copyright (C) 2014 Richard Cochran. All rights reserved.
+ * Author: Richard Cochran <richardcochran@gmail.com>
+ *
+ * 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 "up_internal.h"
+#include "efm32_lowputc.h"
+
+#include "em_device.h"
+#include "em_cmu.h"
+#include "em_gpio.h"
+#include "em_usart.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define BAUDRATE 115200
+
+#if defined UART_PRESENT
+
+#if UART_COUNT > 1
+#define RXPIN 10
+#define RXPORT gpioPortB
+#define TXPIN 9
+#define TXPORT gpioPortB
+#define UART UART1
+#define UART_CLOCK cmuClock_UART1
+#define UART_LOC USART_ROUTE_LOCATION_LOC2
+#else
+#error unknown efm32 part
+#endif
+
+#elif defined USART_PRESENT
+
+#define RXPIN 11
+#define RXPORT gpioPortE
+#define TXPIN 10
+#define TXPORT gpioPortE
+#define UART USART0
+#define UART_CLOCK cmuClock_USART0
+#define UART_LOC USART_ROUTE_LOCATION_LOC0
+
+#endif /* USART_PRESENT */
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+void efm32_lowsetup(void)
+{
+ USART_InitAsync_TypeDef settings = USART_INITASYNC_DEFAULT;
+
+ CMU_ClockEnable(UART_CLOCK, true);
+ GPIO_PinModeSet(TXPORT, TXPIN, gpioModePushPull, 1);
+ GPIO_PinModeSet(RXPORT, RXPIN, gpioModeInput, 0);
+ settings.baudrate = BAUDRATE;
+ USART_InitAsync(UART, &settings);
+ UART->ROUTE = USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | UART_LOC;
+}
+
+void up_lowputc(char c)
+{
+ while (!(UART->STATUS & USART_STATUS_TXBL));
+ UART->TXDATA = c;
+}
+
+void up_putc(char c)
+{
+ /* Convert LF into CRLF. */
+ if (c == '\n')
+ up_lowputc('\r');
+
+ up_lowputc(c);
+}
diff --git a/nuttx/arch/arm/src/efm32/efm32_lowputc.h b/nuttx/arch/arm/src/efm32/efm32_lowputc.h
new file mode 100644
index 000000000..d6488a42f
--- /dev/null
+++ b/nuttx/arch/arm/src/efm32/efm32_lowputc.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+ * arch/arm/src/efm32/efm32_lowputc.h
+ *
+ * Copyright (C) 2014 Richard Cochran. All rights reserved.
+ * Author: Richard Cochran <richardcochran@gmail.com>
+ *
+ * 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_EFM32_STM32_LOWPUTC_H
+#define __ARCH_ARM_SRC_EFM32_STM32_LOWPUTC_H
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+#ifdef CONFIG_DEV_LOWCONSOLE
+
+void efm32_lowsetup(void);
+
+#else
+
+static inline void efm32_lowsetup(void)
+{
+}
+
+#endif
+
+#endif
diff --git a/nuttx/arch/arm/src/efm32/efm32_start.c b/nuttx/arch/arm/src/efm32/efm32_start.c
new file mode 100644
index 000000000..2b75930fb
--- /dev/null
+++ b/nuttx/arch/arm/src/efm32/efm32_start.c
@@ -0,0 +1,223 @@
+/****************************************************************************
+ * arch/arm/src/efm32/efm32_start.c
+ *
+ * Copyright (C) 2009, 2011-2014 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 <assert.h>
+#include <debug.h>
+#include <nuttx/init.h>
+#include <arch/board/board.h>
+#include <arch/efm32/chip.h>
+
+#include "up_arch.h"
+#include "up_internal.h"
+#include "efm32_lowputc.h"
+
+#include "em_device.h"
+#include "em_cmu.h"
+
+/****************************************************************************
+ * Private Function prototypes
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_STACK
+static void go_os_start(void *pv, unsigned int nbytes)
+ __attribute__ ((naked,no_instrument_function,noreturn));
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: showprogress
+ *
+ * Description:
+ * Print a character on the UART to show boot status.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG
+# define showprogress(c) up_lowputc(c)
+#else
+# define showprogress(c)
+#endif
+
+/****************************************************************************
+ * Name: go_os_start
+ *
+ * Description:
+ * Set the IDLE stack to the
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_STACK
+static void go_os_start(void *pv, unsigned int nbytes)
+{
+ /* Set the IDLE stack to the stack coloration value then jump to
+ * os_start(). We take extreme care here because were currently
+ * executing on this stack.
+ *
+ * We want to avoid sneak stack access generated by the compiler.
+ */
+
+ __asm__ __volatile__
+ (
+ "\tmov r1, r1, lsr #2\n" /* R1 = nwords = nbytes >> 2 */
+ "\tbeq 2f\n" /* (should not happen) */
+
+ "\tbic r0, r0, #3\n" /* R0 = Aligned stackptr */
+ "\tmovw r2, #0xbeef\n" /* R2 = STACK_COLOR = 0xdeadbeef */
+ "\tmovt r2, #0xdead\n"
+
+ "1:\n" /* Top of the loop */
+ "\tsub r1, r1, #1\n" /* R1 nwords-- */
+ "\tcmp r1, #0\n" /* Check (nwords == 0) */
+ "\tstr r2, [r0], #4\n" /* Save stack color word, increment stackptr */
+ "\tbne 1b\n" /* Bottom of the loop */
+
+ "2:\n"
+ "\tmov r14, #0\n" /* LR = return address (none) */
+ "\tb os_start\n" /* Branch to os_start */
+ );
+}
+#endif
+
+static void efm32_clockconfig(void)
+{
+ /* Devices boots with 14 MHz HFRCO as the HFCLK source. */
+ /* Enable the GPIO clock. */
+ CMU_ClockEnable(cmuClock_GPIO, true);
+}
+
+static void efm32_gpioinit(void)
+{
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: _start
+ *
+ * Description:
+ * This is the reset entry point.
+ *
+ ****************************************************************************/
+
+void __start(void)
+{
+ const uint32_t *src;
+ uint32_t *dest;
+
+ /* Configure the uart so that we can get debug output as soon as possible */
+
+ efm32_clockconfig();
+ efm32_lowsetup();
+ efm32_gpioinit();
+
+ showprogress('A');
+
+ /* Clear .bss. We'll do this inline (vs. calling memset) just to be
+ * certain that there are no issues with the state of global variables.
+ */
+
+ for (dest = &_sbss; dest < &_ebss; )
+ {
+ *dest++ = 0;
+ }
+
+ showprogress('B');
+
+ /* Move the initialized data section from his temporary holding spot in
+ * FLASH into the correct place in SRAM. The correct place in SRAM is
+ * give by _sdata and _edata. The temporary location is in FLASH at the
+ * end of all of the other read-only data (.text, .rodata) at _eronly.
+ */
+
+ for (src = &_eronly, dest = &_sdata; dest < &_edata; )
+ {
+ *dest++ = *src++;
+ }
+
+ showprogress('C');
+
+ /* Perform early serial initialization */
+
+#ifdef USE_EARLYSERIALINIT
+ up_earlyserialinit();
+#endif
+ showprogress('D');
+
+ /* For the case of the separate user-/kernel-space build, perform whatever
+ * platform specific initialization of the user memory is required.
+ * Normally this just means initializing the user space .data and .bss
+ * segments.
+ */
+
+#ifdef CONFIG_NUTTX_KERNEL
+ efm32_userspace();
+ showprogress('E');
+#endif
+
+ /* Initialize onboard resources */
+
+ efm32_boardinitialize();
+ showprogress('F');
+
+ /* Then start NuttX */
+
+ showprogress('\r');
+ showprogress('\n');
+
+#ifdef CONFIG_DEBUG_STACK
+ /* Set the IDLE stack to the coloration value and jump into os_start() */
+
+ go_os_start((FAR void *)&_ebss, CONFIG_IDLETHREAD_STACKSIZE);
+#else
+ /* Call os_start() */
+
+ os_start();
+
+ /* Shoulnd't get here */
+
+ for(;;);
+#endif
+}
diff --git a/nuttx/arch/arm/src/efm32/efm32_timerisr.c b/nuttx/arch/arm/src/efm32/efm32_timerisr.c
new file mode 100644
index 000000000..3461a375b
--- /dev/null
+++ b/nuttx/arch/arm/src/efm32/efm32_timerisr.c
@@ -0,0 +1,143 @@
+/****************************************************************************
+ * arch/arm/src/efm32/efm32_timerisr.c
+ *
+ * Copyright (C) 2009, 2014 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 <time.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#include "nvic.h"
+#include "clock_internal.h"
+#include "up_internal.h"
+#include "up_arch.h"
+
+#include "chip.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/* The desired timer interrupt frequency is provided by the definition
+ * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of
+ * system clock ticks per second. That value is a user configurable setting
+ * that defaults to 100 (100 ticks per second = 10 MS interval).
+ */
+
+#define EFM32_HCLK_FREQUENCY 14000000
+
+#define SYSTICK_RELOAD ((EFM32_HCLK_FREQUENCY / CLK_TCK) - 1)
+
+/* The size of the reload field is 24 bits. Verify that the reload value
+ * will fit in the reload register.
+ */
+
+#if SYSTICK_RELOAD > 0x00ffffff
+# error SYSTICK_RELOAD exceeds the range of the RELOAD register
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: up_timerisr
+ *
+ * Description:
+ * The timer ISR will perform a variety of services for various portions
+ * of the systems.
+ *
+ ****************************************************************************/
+
+int up_timerisr(int irq, uint32_t *regs)
+{
+ /* Process timer interrupt */
+
+ sched_process_timer();
+ return 0;
+}
+
+/****************************************************************************
+ * Function: up_timerinit
+ *
+ * Description:
+ * This function is called during start-up to initialize
+ * the timer interrupt.
+ *
+ ****************************************************************************/
+
+void up_timerinit(void)
+{
+ uint32_t regval;
+
+ /* Set the SysTick interrupt to the default priority */
+
+ regval = getreg32(NVIC_SYSH12_15_PRIORITY);
+ regval &= ~NVIC_SYSH_PRIORITY_PR15_MASK;
+ regval |= (NVIC_SYSH_PRIORITY_DEFAULT << NVIC_SYSH_PRIORITY_PR15_SHIFT);
+ putreg32(regval, NVIC_SYSH12_15_PRIORITY);
+
+ /* Make sure that the SYSTICK clock source is set correctly */
+
+ /* Configure SysTick to interrupt at the requested rate */
+
+ putreg32(SYSTICK_RELOAD, NVIC_SYSTICK_RELOAD);
+
+ /* Attach the timer interrupt vector */
+
+ (void)irq_attach(EFM32_IRQ_SYSTICK, (xcpt_t)up_timerisr);
+
+ /* Enable SysTick interrupts */
+
+ putreg32((NVIC_SYSTICK_CTRL_CLKSOURCE|NVIC_SYSTICK_CTRL_TICKINT|NVIC_SYSTICK_CTRL_ENABLE), NVIC_SYSTICK_CTRL);
+
+ /* And enable the timer interrupt */
+
+ up_enable_irq(EFM32_IRQ_SYSTICK);
+}
diff --git a/nuttx/arch/arm/src/efm32/efm32_vectors.S b/nuttx/arch/arm/src/efm32/efm32_vectors.S
new file mode 100644
index 000000000..0e1503a60
--- /dev/null
+++ b/nuttx/arch/arm/src/efm32/efm32_vectors.S
@@ -0,0 +1,121 @@
+/************************************************************************************
+ * arch/arm/src/efm32/efm32_vectors.S
+ *
+ * Copyright (C) 2009-2014 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 <arch/irq.h>
+
+#include "chip.h"
+#include "exc_return.h"
+
+/************************************************************************************
+ * Configuration
+ ************************************************************************************/
+
+/************************************************************************************
+ * Preprocessor Definitions
+ ************************************************************************************/
+/* Configuration ********************************************************************/
+
+#ifdef CONFIG_ARCH_HIPRI_INTERRUPT
+ /* In kernel mode without an interrupt stack, this interrupt handler will set the
+ * MSP to the stack pointer of the interrupted thread. If the interrupted thread
+ * was a privileged thread, that will be the MSP otherwise it will be the PSP. If
+ * the PSP is used, then the value of the MSP will be invalid when the interrupt
+ * handler returns because it will be a pointer to an old position in the
+ * unprivileged stack. Then when the high priority interrupt occurs and uses this
+ * stale MSP, there will most likely be a system failure.
+ *
+ * If the interrupt stack is selected, on the other hand, then the interrupt
+ * handler will always set the the MSP to the interrupt stack. So when the high
+ * priority interrupt occurs, it will either use the MSP of the last privileged
+ * thread to run or, in the case of the nested interrupt, the interrupt stack if
+ * no privileged task has run.
+ */
+
+# if defined(CONFIG_NUTTX_KERNEL) && CONFIG_ARCH_INTERRUPTSTACK < 4
+# error Interrupt stack must be used with high priority interrupts in kernel mode
+# endif
+
+ /* Use the the BASEPRI to control interrupts is required if nested, high
+ * priority interrupts are supported.
+ */
+
+# ifndef CONFIG_ARMV7M_USEBASEPRI
+# error CONFIG_ARMV7M_USEBASEPRI must be used with CONFIG_ARCH_HIPRI_INTERRUPT
+# endif
+#endif
+
+#define IDLE_STACK (_ebss+CONFIG_IDLETHREAD_STACKSIZE-4)
+#define HEAP_BASE (_ebss+CONFIG_IDLETHREAD_STACKSIZE)
+
+/************************************************************************************
+ * Global Symbols
+ ************************************************************************************/
+
+ .syntax unified
+ .thumb
+ .file "efm32_vectors.S"
+
+/*
+ * The efm32 chips all use the common ARMv7 interrupt vectoring.
+ * (see arch/arm/src/armv7-m/up_vectors.S)
+ */
+
+/************************************************************************************
+ * .rodata
+ ************************************************************************************/
+
+ .section .rodata, "a"
+
+/* Variables: _sbss is the start of the BSS region (see ld.script) _ebss is the end
+ * of the BSS regsion (see ld.script). The idle task stack starts at the end of BSS
+ * and is of size CONFIG_IDLETHREAD_STACKSIZE. The IDLE thread is the thread that
+ * the system boots on and, eventually, becomes the idle, do nothing task that runs
+ * only when there is nothing else to run. The heap continues from there until the
+ * end of memory. See g_idle_topstack below.
+ */
+
+ .globl g_idle_topstack
+ .type g_idle_topstack, object
+g_idle_topstack:
+ .word HEAP_BASE
+ .size g_idle_topstack, .-g_idle_topstack
+
+ .end