imxrt - interrupt serial storm, add DTCM and set up I and D cache (#175)

* Serial Fixed interrupt storm

  The target would randomly hang in the serial isr.
  The priv->ie and the hardware were inconsistent.
  The isr used the priv->ie to gate offloading
  the RX data. Bang! Hung.

                  imxrt_disableuartint(priv, &ie);
                  ret = imxrt_setup(dev);

                  /* Restore the interrupt state */

                  imxrt_restoreuartint(priv, ie);
       interrupt->  Of no return
                  priv->ie = ie;

   On a fast cpu with FIFO, this will not work
   with out proper protections.

* Serial: Conditionally enable 9 bit mode

* armv7-mi/mpu.hi: Restructure API

   Preserve the existing API and enabled better granualriy on
   setting.

* Enable MPU for non protected builds to set cache

* mpuinit use symbolic values for addresses

* Allow DTCM on HEAP

* allocateheap Fix Coding style
This commit is contained in:
David Sidrane
2020-01-29 07:33:19 -06:00
committed by Gregory Nutt
parent ca5799e70d
commit 04a7ccdc68
7 changed files with 296 additions and 294 deletions
+129 -250
View File
File diff suppressed because it is too large Load Diff
+12 -6
View File
@@ -848,14 +848,14 @@ endmenu # IMXRT_ENET
menu "Memory Configuration"
config IMXRT_DTCM
bool "Enable DTCM"
default n
depends on !IMXRT_OCRAM_PRIMARY && EXPERIMENTAL
int "FLEXRAM DTCM Size in K"
default 128
depends on ARMV7M_HAVE_DTCM
config IMXRT_ITCM
bool "Enable ITCM"
default n
depends on !IMXRT_OCRAM_PRIMARY && EXPERIMENTAL
int "FLEXRAM ITCM Size in K"
default 128
depends on ARMV7M_HAVE_ITCM
config IMXRT_SEMC_SDRAM
bool "External SDRAM installed"
@@ -958,6 +958,12 @@ config IMXRT_OCRAM_HEAP
---help---
Select to add the entire OCRAM to the heap
config IMXRT_DTCM_HEAP
bool "Add DTCM to heap"
depends on IMXRT_DTCM > 0
---help---
Select to add the entire DTCM to the heap
config IMXRT_SDRAM_HEAP
bool "Add SDRAM to heap"
depends on IMXRT_SEMC_SDRAM && !IMXRT_SDRAM_PRIMARY
+3
View File
@@ -113,6 +113,9 @@ CHIP_CSRCS += imxrt_gpioirq.c
endif
ifeq ($(CONFIG_ARM_MPU),y)
ifneq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += up_mpu.c
endif
CHIP_CSRCS += imxrt_mpuinit.c
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CHIP_CSRCS += imxrt_userspace.c
+49 -22
View File
@@ -62,7 +62,9 @@
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
/* Terminology. In the flat build (CONFIG_BUILD_FLAT=y), there is only a
* single heap access with the standard allocations (malloc/free). This
* heap is referred to as the user heap. In the protected build
@@ -81,10 +83,9 @@
* Primary RAM: The Linker script positions the system BLOB's .data and
* .bss in some RAM. We refer to that RAM as the primary RAM. It also
* holds the IDLE threads stack and any remaining portion of the primary
* RAM is automatically added to the heap. The start and size of the
* primary RAM are provided by CONFIG_RAM_START and CONFIG_RAM_SIZE. The
* linker provided address, ... .sbss, .ebss, .sdat, etc. ... are expected
* to lie in the the region defined by those configuration settings.
* OCRAM is automatically added to the heap. The linker provided address,
* ... .sbss, .ebss, .sdat, etc. ... are expected to lie in the the region
* defined by the OCRAM configuration settings.
*
* Other RAM regions must be selected use configuration options and the
* start and end of those RAM regions must also be provided in the
@@ -110,22 +111,29 @@
*/
/* There there then several memory configurations with a one primary memory
* region and up to two additional memory regions which may be OCRAM,
* region and up to two additional memory regions which may be OCRAM, DTCM
* external SDRAM, or external SRAM.
*/
#undef IMXRT_OCRAM_ASSIGNED
#undef IMXRT_DCTM_ASSIGNED
#undef IMXRT_SDRAM_ASSIGNED
#undef IMXRT_SRAM_ASSIGNED
/* REVISIT: Assume that if OCRAM is the primary RAM, then DTCM and ITCM are
* not being used.
* When configured DTCM and ITCM consume OCRAM from the address space
/* When configured DTCM and ITCM consume OCRAM from the address space
* labeled IMXRT_OCRAM_BASE that uses the FlexRAM controller to allocate
* the function of OCRAM.
*
* The 1 MB version of the SOC have a second 512Kib of OCRAM that can not
* be consumed by the DTCM or ITCM.
*
* If we order the memory with the FlexRAM controller from high to low banks
* as ITCM DTCM OCRAM we can achieve an continuous RAM layout of
*
* High OCRAM-(DTCM Size, ITCM Size)
* Low OCRAM2
*
* The pieces of the OCRAM used for DTCM and ITCM DTCM and ITCM memory spaces
*/
#if defined(IMXRT_OCRAM2_BASE)
@@ -133,9 +141,34 @@
#else
# define _IMXRT_OCRAM_BASE IMXRT_OCRAM_BASE
#endif
#define CONFIG_ITCM_USED 0
#if defined(CONFIG_IMXRT_ITCM)
# if (CONFIG_IMXRT_ITCM % 32) != 0
# error IMXRT_ITCM must be divisible by 32
# endif
# undef CONFIG_ITCM_USED
# define CONFIG_ITCM_USED (CONFIG_IMXRT_ITCM * 1024)
#else
# define CONFIG_IMXRT_ITCM 0
#endif
#define CONFIG_DTCM_USED 0
#if defined(CONFIG_IMXRT_DTCM)
# if (CONFIG_IMXRT_DTCM % 32) != 0
# error CONFIG_IMXRT_DTCM must be divisible by 32
# endif
# undef CONFIG_DTCM_USED
# define CONFIG_DTCM_USED (CONFIG_IMXRT_DTCM * 1024)
#else
# define IMXRT_DTCM 0
#endif
#define FLEXRAM_REMAINING_K ((IMXRT_OCRAM_SIZE / 1024) - (CONFIG_IMXRT_DTCM + CONFIG_IMXRT_DTCM))
#if defined(CONFIG_IMXRT_OCRAM_PRIMARY)
# define PRIMARY_RAM_START _IMXRT_OCRAM_BASE /* CONFIG_RAM_START */
# define PRIMARY_RAM_SIZE IMXRT_OCRAM_SIZE /* CONFIG_RAM_SIZE */
# define PRIMARY_RAM_START _IMXRT_OCRAM_BASE
# define PRIMARY_RAM_SIZE IMXRT_OCRAM_SIZE - (CONFIG_ITCM_USED + CONFIG_DTCM_USED)
# define IMXRT_OCRAM_ASSIGNED 1
#elif defined(CONFIG_IMXRT_SDRAM_PRIMARY)
# define PRIMARY_RAM_START CONFIG_IMXRT_SDRAM_START /* CONFIG_RAM_START */
@@ -151,23 +184,13 @@
#define PRIMARY_RAM_END (PRIMARY_RAM_START + PRIMARY_RAM_SIZE)
/* REVISIT: I am not sure how this works. But I am assuming that if DTCM
* is enabled, then ITCM is not and we can just use the DTCM base address to
* access OCRAM.
*
* The FlexRAM controller manages the allocation of DTCM and ITCM from the
/* The FlexRAM controller manages the allocation of DTCM and ITCM from the
* OCRAM. The amount allocated it 2^n KiB where n is 2-9 and is configured in
* the GPR register space.
*/
#ifdef CONFIG_IMXRT_DTCM
# define IMXRT_OCRAM_START IMXRT_DTCM_BASE
#else
# define IMXRT_OCRAM_START _IMXRT_OCRAM_BASE
#endif
#if CONFIG_MM_REGIONS > 1
/* Pick the first region to add to the heap could be any one of OCRAM,
/* Pick the first region to add to the heap could be any one of OCRAM, DTCM,
* SDRAM, or SRAM depending upon which are enabled and which has not
* already been assigned as the primary RAM.
*/
@@ -176,6 +199,10 @@
# define REGION1_RAM_START IMXRT_OCRAM_START
# define REGION1_RAM_SIZE IMXRT_OCRAM_SIZE
# define IMXRT_OCRAM_ASSIGNED 1
#elif defined(CONFIG_IMXRT_DTCM_HEAP) && !defined(IMXRT_DCTM_ASSIGNED)
# define REGION1_RAM_START IMXRT_DTCM_BASE
# define REGION1_RAM_SIZE CONFIG_DTCM_USED
# define IMXRT_DCTM_ASSIGNED 1
#elif defined(CONFIG_IMXRT_SDRAM_HEAP) && !defined(IMXRT_SDRAM_ASSIGNED)
# define REGION1_RAM_START (CONFIG_IMXRT_SDRAM_START + CONFIG_IMXRT_SDRAM_HEAPOFFSET)
# define REGION1_RAM_SIZE (CONFIG_IMXRT_SDRAM_SIZE - CONFIG_IMXRT_SDRAM_HEAPOFFSET)
+7 -7
View File
@@ -97,9 +97,9 @@
/*****************************************************************************
* Pre-processor Definitions
****************************************************************************/
*****************************************************************************/
/* Configuration ************************************************************/
/* Configuration *************************************************************/
/* SPI interrupts */
@@ -119,7 +119,7 @@
/*****************************************************************************
* Private Types
****************************************************************************/
*****************************************************************************/
struct imxrt_lpspidev_s
{
@@ -144,7 +144,7 @@ enum imxrt_delay_e
/*****************************************************************************
* Private Function Prototypes
****************************************************************************/
*****************************************************************************/
/* Helpers */
@@ -1180,7 +1180,7 @@ static void imxrt_lpspi_setbits(FAR struct spi_dev_s *dev, int nbits)
* Zero (OK) if the selected H/W features are enabled; A negated errno
* value if any H/W feature is not supportable.
*
****************************************************************************/
*****************************************************************************/
#ifdef CONFIG_SPI_HWFEATURES
static int imxrt_lpspi_hwfeatures(FAR struct spi_dev_s *dev,
@@ -1369,7 +1369,7 @@ static void imxrt_lpspi_exchange_nodma(FAR struct spi_dev_s *dev,
}
#endif /* !CONFIG_IMXRT_LPSPI_DMA || CONFIG_IMXRT_DMACAPABLE */
/****************************************************************************
/*****************************************************************************
* Name: imxrt_lpspi_sndblock
*
* Description:
@@ -1570,7 +1570,7 @@ static void imxrt_lpspi_bus_initialize(struct imxrt_lpspidev_s *priv)
* Returned Value:
* Valid SPI device structure reference on success; a NULL on failure
*
****************************************************************************/
*****************************************************************************/
FAR struct spi_dev_s *imxrt_lpspibus_initialize(int bus)
{
+84 -1
View File
@@ -1,7 +1,7 @@
/****************************************************************************
* arch/arm/src/imxrt/imxrt_mpuinit.c
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Copyright (C) 2018, 2020 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -115,6 +115,89 @@ void imxrt_mpu_initialize(void)
DEBUGASSERT(dataend >= datastart);
mpu_user_intsram(datastart, dataend - datastart);
#else
mpu_configure_region(0xc0000000, 512 * 1024 * 1024,
MPU_RASR_TEX_DEV | /* Device */
/* Not Cacheable */
/* Not Bufferable */
/* Not Shareable */
MPU_RASR_AP_RWRW /* P:RW U:RW */
/* Instruction access */);
mpu_configure_region(IMXRT_EXTMEM_BASE, 1024 * 1024 * 1024,
MPU_RASR_TEX_DEV | /* Device */
/* Not Cacheable */
/* Not Bufferable */
/* Not Shareable */
MPU_RASR_AP_RWRW /* P:RW U:RW */
/* Instruction access */);
mpu_configure_region(IMXRT_FLEXCIPHER_BASE, 8 * 1024 * 1024,
MPU_RASR_TEX_SO | /* Ordered */
MPU_RASR_C | /* Cacheable */
MPU_RASR_B | /* Bufferable */
/* Not Shareable */
MPU_RASR_AP_RORO /* P:RO U:RO */
/* Instruction access */);
mpu_configure_region(0x00000000, 1024 * 1024 * 1024,
MPU_RASR_TEX_DEV | /* Device */
/* Not Cacheable */
/* Not Bufferable */
/* Not Shareable */
MPU_RASR_AP_RWRW /* P:RW U:RW */
/* Instruction access */);
mpu_configure_region(IMXRT_ITCM_BASE, 128 * 1024,
MPU_RASR_TEX_SO | /* Ordered */
MPU_RASR_C | /* Cacheable */
MPU_RASR_B | /* Bufferable */
/* Not Shareable */
MPU_RASR_AP_RWRW /* P:RW U:RW */
/* Instruction access */);
mpu_configure_region(IMXRT_DTCM_BASE, 128 * 1024,
MPU_RASR_TEX_SO | /* Ordered */
MPU_RASR_C | /* Cacheable */
MPU_RASR_B | /* Bufferable */
/* Not Shareable */
MPU_RASR_AP_RWRW /* P:RW U:RW */
/* Instruction access */);
mpu_configure_region(IMXRT_OCRAM2_BASE, 512 * 1024,
MPU_RASR_TEX_SO | /* Ordered */
MPU_RASR_C | /* Cacheable */
MPU_RASR_B | /* Bufferable */
/* Not Shareable */
MPU_RASR_AP_RWRW /* P:RW U:RW */
/* Instruction access */);
mpu_configure_region(IMXRT_OCRAM_BASE, 512 * 1024,
MPU_RASR_TEX_SO | /* Ordered */
MPU_RASR_C | /* Cacheable */
MPU_RASR_B | /* Bufferable */
/* Not Shareable */
MPU_RASR_AP_RWRW /* P:RW U:RW */
/* Instruction access */);
mpu_configure_region(IMXRT_EXTMEM_BASE, 32 * 1024 * 1024,
MPU_RASR_TEX_SO | /* Ordered */
MPU_RASR_C | /* Cacheable */
MPU_RASR_B | /* Bufferable */
/* Not Shareable */
MPU_RASR_AP_RWRW /* P:RW U:RW */
/* Instruction access */);
mpu_configure_region(0x81e00000, 2 * 1024 * 1024,
MPU_RASR_TEX_NOR | /* Normal */
/* Not Cacheable */
/* Not Bufferable */
/* Not Shareable */
MPU_RASR_AP_RWRW /* P:RW U:RW */
/* Instruction access */);
mpu_control(true, true, true);
return;
#endif
/* Then enable the MPU */
+12 -8
View File
@@ -258,6 +258,7 @@
* UART 5-8 could be the console. One of UART5-8 has already been
* assigned to ttys0, 1, 2, 3, or 4.
*/
#if defined(CONFIG_IMXRT_LPUART5) && !defined(UART5_ASSIGNED)
# define TTYS5_DEV g_uart5port /* LPUART5 is ttyS5 */
# define UART5_ASSIGNED 1
@@ -541,7 +542,7 @@ static struct uart_dev_s g_uart2port =
{
.size = CONFIG_LPUART2_TXBUFSIZE,
.buffer = g_uart2txbuffer,
},
},
.ops = &g_uart_ops,
.priv = &g_uart2priv,
};
@@ -922,11 +923,11 @@ static int imxrt_setup(struct uart_dev_s *dev)
{
struct imxrt_uart_s *priv = (struct imxrt_uart_s *)dev->priv;
#ifndef CONFIG_SUPPRESS_LPUART_CONFIG
int ret;
struct uart_config_s config =
{
0
};
int ret;
/* Configure the UART */
@@ -1121,6 +1122,7 @@ static int imxrt_ioctl(struct file *filep, int cmd, unsigned long arg)
#if defined(CONFIG_SERIAL_TIOCSERGSTRUCT) || defined(CONFIG_SERIAL_TERMIOS)
struct inode *inode = filep->f_inode;
struct uart_dev_s *dev = inode->i_private;
irqstate_t flags;
#endif
int ret = OK;
@@ -1196,9 +1198,11 @@ static int imxrt_ioctl(struct file *filep, int cmd, unsigned long arg)
termiosp->c_cflag |= CS8;
break;
#if defined(CS9)
case 9:
termiosp->c_cflag |= CS8 /* CS9 */;
termiosp->c_cflag |= CS9;
break;
#endif
}
}
break;
@@ -1250,7 +1254,8 @@ static int imxrt_ioctl(struct file *filep, int cmd, unsigned long arg)
case CS8:
nbits = 8;
break;
#if 0
#if defined(CS9)
case CS9:
nbits = 9;
break;
@@ -1295,6 +1300,7 @@ static int imxrt_ioctl(struct file *filep, int cmd, unsigned long arg)
* implement TCSADRAIN / TCSAFLUSH
*/
flags = spin_lock_irqsave();
imxrt_disableuartint(priv, &ie);
ret = imxrt_setup(dev);
@@ -1302,6 +1308,7 @@ static int imxrt_ioctl(struct file *filep, int cmd, unsigned long arg)
imxrt_restoreuartint(priv, ie);
priv->ie = ie;
spin_unlock_irqrestore(flags);
}
}
break;
@@ -1552,32 +1559,29 @@ static void up_pm_notify(struct pm_callback_s *cb, int domain,
case(PM_NORMAL):
{
/* Logic for PM_NORMAL goes here */
}
break;
case(PM_IDLE):
{
/* Logic for PM_IDLE goes here */
}
break;
case(PM_STANDBY):
{
/* Logic for PM_STANDBY goes here */
}
break;
case(PM_SLEEP):
{
/* Logic for PM_SLEEP goes here */
}
break;
default:
/* Should not get here */
break;