This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 081b04f05e iMXRT MCUboot support
081b04f05e is described below
commit 081b04f05ee3fa2a9f2476fe77bd268621908d24
Author: jturnsek <[email protected]>
AuthorDate: Fri Feb 24 07:12:28 2023 +0100
iMXRT MCUboot support
---
arch/arm/src/imxrt/Kconfig | 116 +++
arch/arm/src/imxrt/Make.defs | 3 +
arch/arm/src/imxrt/imxrt106x_flash.c | 789 +++++++++++++++++++++
arch/arm/src/imxrt/imxrt_flash.c | 35 +
.../imxrt1064-evk/configs/mcuboot-app/defconfig | 85 +++
.../imxrt1064-evk/configs/mcuboot-loader/defconfig | 59 ++
boards/arm/imxrt/imxrt1064-evk/scripts/Make.defs | 16 +-
.../imxrt1064-evk/scripts/flash-mcuboot-app.ld | 119 ++++
.../imxrt1064-evk/scripts/flash-mcuboot-loader.ld | 139 ++++
boards/arm/imxrt/imxrt1064-evk/src/Makefile | 12 +
boards/arm/imxrt/imxrt1064-evk/src/imxrt1064-evk.h | 15 +
.../arm/imxrt/imxrt1064-evk/src/imxrt_boot_image.c | 180 +++++
boards/arm/imxrt/imxrt1064-evk/src/imxrt_bringup.c | 10 +
boards/arm/imxrt/imxrt1064-evk/src/imxrt_progmem.c | 255 +++++++
boards/arm/imxrt/imxrt1064-evk/src/imxrt_reset.c | 62 ++
15 files changed, 1891 insertions(+), 4 deletions(-)
diff --git a/arch/arm/src/imxrt/Kconfig b/arch/arm/src/imxrt/Kconfig
index 5dc6c436cb..296732fff5 100644
--- a/arch/arm/src/imxrt/Kconfig
+++ b/arch/arm/src/imxrt/Kconfig
@@ -151,6 +151,47 @@ config ARCH_FAMILY_IMXRT106x
select ARMV7M_HAVE_DTCM
select IMXRT_HIGHSPEED_GPIO
+config IMXRT_HAVE_OTA_PARTITION
+ bool
+ default n
+
+config IMXRT_PROGMEM
+ bool "Flash progmem support"
+ default n
+ select ARCH_HAVE_PROGMEM
+ ---help---
+ Add progmem support, start block and end block options are
provided to
+ obtain an uniform flash memory mapping.
+
+menu "Application Image Configuration"
+choice
+ prompt "Application Image Format"
+ default IMXRT_APP_FORMAT_LEGACY
+ ---help---
+ Depending on the chosen 2nd stage bootloader, the application
may
+ be required to be perform a specific startup routine.
Furthermore,
+ the image binary must be formatted according to the definition
from
+ the 2nd stage bootloader.
+
+config IMXRT_APP_FORMAT_LEGACY
+ bool "Legacy format"
+ ---help---
+ This is the legacy application image format.
+
+config IMXRT_APP_FORMAT_MCUBOOT
+ bool "MCUboot-bootable format"
+ select IMXRT_HAVE_OTA_PARTITION
+ depends on EXPERIMENTAL
+ ---help---
+ The MCUboot support of loading the firmware images.
+
+comment "MCUboot support depends on CONFIG_EXPERIMENTAL"
+ depends on !EXPERIMENTAL
+
+endchoice # Application Image Format
+
+endmenu # Application Image Configuration
+
# Peripheral support
config IMXRT_USDHC
@@ -2781,4 +2822,79 @@ config IMXRT_USBDEV_REGDEBUG
endmenu # USB device controller driver (DCD) options
endif # IMXRT_USBDEV
+menu "Progmem MTD configuration"
+
+if IMXRT_PROGMEM
+
+comment "Progmem instance support"
+
+config IMXRT_PROGMEM_FLEXSPI_INSTANCE
+ int "FlexSPI instance number (0 or 1)"
+ default 1
+ ---help---
+ FlexSPI instance number. Base address 0x60000000 is used for
instance 0
+ and 0x70000000 for instance 1. Other values are not supported.
+
+endif #IMXRT_PROGMEM
+
+if IMXRT_HAVE_OTA_PARTITION
+
+comment "Application Image OTA Update support"
+
+config IMXRT_PROGMEM_OTA_PARTITION
+ bool "MTD driver"
+ default n
+ select BCH
+ select MTD
+ select MTD_BYTE_WRITE
+ select MTD_PARTITION
+ select MTD_PROGMEM
+ select IMXRT_PROGMEM
+ ---help---
+ Initialize an MTD driver for the Flash, which will
+ add an entry at /dev for application access from userspace.
+
+if IMXRT_PROGMEM_OTA_PARTITION
+config IMXRT_MCUBOOT_HEADER_SIZE
+ hex
+ default 0x200
+ depends on IMXRT_APP_FORMAT_MCUBOOT
+
+config IMXRT_OTA_PRIMARY_SLOT_DEVPATH
+ string "Application image primary slot device path"
+ default "/dev/ota0"
+
+config IMXRT_OTA_SECONDARY_SLOT_DEVPATH
+ string "Application image secondary slot device path"
+ default "/dev/ota1"
+
+config IMXRT_OTA_SCRATCH_DEVPATH
+ string "Scratch partition device path"
+ default "/dev/otascratch"
+
+config IMXRT_OTA_PRIMARY_SLOT_OFFSET
+ hex "MCUboot application image primary slot offset"
+ default "0x40000"
+
+config IMXRT_OTA_SECONDARY_SLOT_OFFSET
+ hex "MCUboot application image secondary slot offset"
+ default "0x200000"
+
+config IMXRT_OTA_SCRATCH_OFFSET
+ hex "MCUboot scratch partition offset"
+ default "0x3c0000"
+
+config IMXRT_OTA_SLOT_SIZE
+ hex "MCUboot application image slot size (in bytes)"
+ default "0x1c0000"
+
+config IMXRT_OTA_SCRATCH_SIZE
+ hex "MCUboot scratch partition size (in bytes)"
+ default "0x40000"
+
+endif #IMXRT_PROGMEM_OTA_PARTITION
+endif #IMXRT_HAVE_OTA_PARTITION
+
+endmenu # Progmem configuration
+
endif # ARCH_CHIP_IMXRT
diff --git a/arch/arm/src/imxrt/Make.defs b/arch/arm/src/imxrt/Make.defs
index f67aa27b9c..bfbd4776ac 100644
--- a/arch/arm/src/imxrt/Make.defs
+++ b/arch/arm/src/imxrt/Make.defs
@@ -25,6 +25,9 @@ include armv7-m/Make.defs
# Required i.MX RT files
CHIP_CSRCS = imxrt_allocateheap.c imxrt_start.c imxrt_clockconfig.c
+ifeq ($(CONFIG_IMXRT_PROGMEM),y)
+CHIP_CSRCS += imxrt_flash.c
+endif
CHIP_CSRCS += imxrt_periphclks.c imxrt_irq.c imxrt_clrpend.c imxrt_gpio.c
CHIP_CSRCS += imxrt_daisy.c imxrt_wdog.c imxrt_iomuxc.c imxrt_serial.c
CHIP_CSRCS += imxrt_xbar.c imxrt_ocotp.c imxrt_lowputc.c
diff --git a/arch/arm/src/imxrt/imxrt106x_flash.c
b/arch/arm/src/imxrt/imxrt106x_flash.c
new file mode 100644
index 0000000000..ef9b5ed615
--- /dev/null
+++ b/arch/arm/src/imxrt/imxrt106x_flash.c
@@ -0,0 +1,789 @@
+/****************************************************************************
+ * arch/arm/src/imxrt/imxrt106x_flash.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/* Provides standard flash access functions, to be used by the flash mtd
+ * driver. The interface is defined in the include/nuttx/progmem.h
+ */
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+#include <nuttx/mutex.h>
+#include <debug.h>
+
+#include <stdbool.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "barriers.h"
+
+#include "hardware/rt106x/imxrt106x_memorymap.h"
+#include "arm_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if CONFIG_IMXRT_PROGMEM_FLEXSPI_INSTANCE == 0
+#define FLEXSPI_INSTANCE (0)
+#else
+#define FLEXSPI_INSTANCE (1)
+#endif
+
+#define FLASH_PAGE_SIZE (256UL)
+#define FLASH_SECTOR_SIZE (4096UL)
+#define FLASH_ERASEDVALUE (0xffu)
+#define FLASH_ERASEDVALUE_DW (0xffffffffu)
+#define PROGMEM_NBLOCKS (1024UL)
+#define FLASH_NPAGES ((4UL * 1024UL * 1024UL) / FLASH_PAGE_SIZE)
+
+#define FLEXSPI_CFG_BLK_TAG (0x42464346UL)
+#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL)
+#define FLEXSPI_CFG_BLK_SIZE (512)
+
+#define CMD_SDR 0x01
+#define CMD_DDR 0x21
+#define RADDR_SDR 0x02
+#define RADDR_DDR 0x22
+#define CADDR_SDR 0x03
+#define CADDR_DDR 0x23
+#define MODE1_SDR 0x04
+#define MODE1_DDR 0x24
+#define MODE2_SDR 0x05
+#define MODE2_DDR 0x25
+#define MODE4_SDR 0x06
+#define MODE4_DDR 0x26
+#define MODE8_SDR 0x07
+#define MODE8_DDR 0x27
+#define WRITE_SDR 0x08
+#define WRITE_DDR 0x28
+#define READ_SDR 0x09
+#define READ_DDR 0x29
+#define LEARN_SDR 0x0a
+#define LEARN_DDR 0x2a
+#define DATSZ_SDR 0x0b
+#define DATSZ_DDR 0x2b
+#define DUMMY_SDR 0x0c
+#define DUMMY_DDR 0x2c
+#define DUMMY_RWDS_SDR 0x0d
+#define DUMMY_RWDS_DDR 0x2d
+#define JMP_ON_CS 0x1f
+#define STOP 0
+
+#define FLEXSPI_1PAD 0
+#define FLEXSPI_2PAD 1
+#define FLEXSPI_4PAD 2
+#define FLEXSPI_8PAD 3
+
+#define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \
+ (FLEXSPI_LUT_OPERAND0(op0) | \
+ FLEXSPI_LUT_NUM_PADS0(pad0) | \
+ FLEXSPI_LUT_OPCODE0(cmd0) | \
+ FLEXSPI_LUT_OPERAND1(op1) | \
+ FLEXSPI_LUT_NUM_PADS1(pad1) | \
+ FLEXSPI_LUT_OPCODE1(cmd1))
+
+typedef enum
+{
+ FLEXSPI_SERIAL_CLK_NO_CHANGE = 0,
+ FLEXSPI_SERIAL_CLK_30MHz = 1,
+ FLEXSPI_SERIAL_CLK_50MHz = 2,
+ FLEXSPI_SERIAL_CLK_60MHz = 3,
+ FLEXSPI_SERIAL_CLK_75MHz = 4,
+ FLEXSPI_SERIAL_CLK_80MHz = 5,
+ FLEXSPI_SERIAL_CLK_100MHz = 6,
+ FLEXSPI_SERIAL_CLK_120MHz = 7,
+ FLEXSPI_SERIAL_CLK_133MHz = 8,
+ FLEXSPI_SERIAL_CLK_166MHz = 9,
+} flexspi_serial_clk_freq_t;
+
+enum
+{
+ FLEXSPI_CLK_SDR,
+ FLEXSPI_CLK_DDR,
+};
+
+typedef enum
+{
+ FLEXSPI_READ_SAMPLE_CLK_LOOPBACK_INTERNALLY = 0,
+ FLEXSPI_READ_SAMPLE_CLK_LOOPBACK_FROM_DQS_PAD = 1,
+ FLEXSPI_READ_SAMPLE_CLK_LOOPBACK_FROM_SCK_PAD = 2,
+ FLEXSPI_READ_SAMPLE_CLK_EXTERNAL_INPUT_FROM_DQS_PAD = 3,
+} flexspi_read_sample_clk_t;
+
+enum
+{
+ FLEXSPI_MISC_OFFSET_DIFF_CLK_ENABLE = 0,
+ FLEXSPI_MISC_OFFSET_CK2_ENABLE = 1,
+ FLEXSPI_MISC_OFFSET_PARALLEL_ENABLE = 2,
+ FLEXSPI_MISC_OFFSET_WORD_ADDRESSABLE_ENABLE = 3,
+ FLEXSPI_MISC_OFFSET_SAFE_CONFIG_FREQ_ENABLE = 4,
+ FLEXSPI_MISC_OFFSET_PAD_SETTING_OVERRIDE_ENABLE = 5,
+ FLEXSPI_MISC_OFFSET_DDR_MODE_ENABLE = 6,
+ FLEXSPI_MISC_OFFSET_USE_VALID_TIME_FOR_ALL_FREQ = 7,
+ FLEXSPI_MISC_OFFSET_SECOND_PINMUX = 8,
+};
+
+enum
+{
+ FLEXSPI_DEVICE_TYPE_SERIAL_NOR = 1,
+ FLEXSPI_DEVICE_TYPE_SERIAL_NAND = 2,
+};
+
+enum
+{
+ SERIAL_FLASH_1PAD = 1,
+ SERIAL_FLASH_2PADS = 2,
+ SERIAL_FLASH_4PADS = 4,
+ SERIAL_FLASH_8PADS = 8,
+};
+
+typedef struct _lut_sequence
+{
+ uint8_t seq_num;
+ uint8_t seq_id;
+ uint16_t reserved;
+} flexspi_lut_seq_t;
+
+enum
+{
+ DEVICE_CONFIG_CMD_TYPE_GENERIC,
+ DEVICE_CONFIG_CMD_TYPE_QUADENABLE,
+ DEVICE_CONFIG_CMD_TYPE_SPI2XPI,
+ DEVICE_CONFIG_CMD_TYPE_XPI2SPI,
+ DEVICE_CONFIG_CMD_TYPE_SPI2NOCMD,
+ DEVICE_CONFIG_CMD_TYPE_RESET,
+};
+
+typedef struct
+{
+ uint8_t time_100ps;
+ uint8_t delay_cells;
+} flexspi_dll_time_t;
+
+typedef struct
+{
+ uint32_t tag;
+ uint32_t version;
+ uint32_t reserved0;
+ uint8_t read_sample_clk_src;
+ uint8_t data_hold_time;
+ uint8_t data_setup_time;
+ uint8_t column_address_width;
+ uint8_t device_mode_cfg_enable;
+ uint8_t device_mode_type;
+ uint16_t wait_time_cfg_commands;
+ flexspi_lut_seq_t device_mode_seq;
+ uint32_t device_mode_arg;
+ uint8_t config_cmd_enable;
+ uint8_t config_mode_type[3];
+ flexspi_lut_seq_t config_cmd_seqs[3];
+ uint32_t reserved1;
+ uint32_t config_cmd_args[3];
+ uint32_t reserved2;
+ uint32_t controller_misc_option;
+ uint8_t device_type;
+ uint8_t sflash_pad_type;
+ uint8_t serial_clk_freq;
+ uint8_t lut_custom_seq_enable;
+ uint32_t reserved3[2];
+ uint32_t sflash_a1_size;
+ uint32_t sflash_a2_size;
+ uint32_t sflash_b1_size;
+ uint32_t sflash_b2_size;
+ uint32_t cs_pad_setting_override;
+ uint32_t sclk_pad_setting_override;
+ uint32_t data_pad_setting_override;
+ uint32_t dqs_pad_setting_override;
+ uint32_t timeout_in_ms;
+ uint32_t command_interval;
+ flexspi_dll_time_t data_valid_time[2];
+ uint16_t busy_offset;
+ uint16_t busy_bit_polarity;
+ uint32_t lookup_table[64];
+ flexspi_lut_seq_t lut_custom_seq[12];
+ uint32_t reserved4[4];
+} flexspi_mem_config_t;
+
+typedef enum
+{
+ FLEXSPI_OPERATION_COMMAND,
+ FLEXSPI_OPERATION_CONFIG,
+ FLEXSPI_OPERATION_WRITE,
+ FLEXSPI_OPERATION_READ,
+ FLEXSPI_OPERATION_END = FLEXSPI_OPERATION_READ,
+} flexspi_operation_t;
+
+typedef struct
+{
+ flexspi_operation_t operation;
+ uint32_t base_address;
+ uint32_t seq_id;
+ uint32_t seq_num;
+ bool is_parallel_mode_enable;
+ uint32_t *tx_buffer;
+ uint32_t tx_size;
+ uint32_t *rx_buffer;
+ uint32_t rx_size;
+} flexspi_xfer_t;
+
+typedef enum
+{
+ FLEXSPI_CLOCK_CORE_CLOCK,
+ FLEXSPI_CLOCK_AHB_CLOCK,
+ FLEXSPI_CLOCK_SERIAL_ROOT_CLOCK,
+ FLEXSPI_CLOCK_IPG_CLOCK,
+} flexspi_clock_type_t;
+
+#define FLEXSPI_BITMASK(bit_offset) (1u << (bit_offset))
+
+enum
+{
+ STATUS_GROUP_GENERIC = 0,
+ STATUS_GROUP_FLEXSPINOR = 201,
+};
+
+typedef int32_t status_t;
+
+#define MAKE_STATUS(group, code) ((((group)*100) + (code)))
+
+enum
+{
+ STATUS_SUCCESS = MAKE_STATUS(STATUS_GROUP_GENERIC, 0),
+ STATUS_FAIL = MAKE_STATUS(STATUS_GROUP_GENERIC, 1),
+ STATUS_READONLY = MAKE_STATUS(STATUS_GROUP_GENERIC, 2),
+ STATUS_OUTOFRANGE = MAKE_STATUS(STATUS_GROUP_GENERIC, 3),
+ STATUS_INVALIDARGUMENT = MAKE_STATUS(STATUS_GROUP_GENERIC, 4),
+ STATUS_TIMEOUT = MAKE_STATUS(STATUS_GROUP_GENERIC, 5),
+ STATUS_NOTRANSFERINPROGRESS =
+ MAKE_STATUS(STATUS_GROUP_GENERIC, 6),
+ STATUS_BUSY = MAKE_STATUS(STATUS_GROUP_GENERIC, 7),
+ STATUS_NODATA =
+ MAKE_STATUS(STATUS_GROUP_GENERIC, 8),
+};
+
+enum _flexspi_nor_status
+{
+ STATUS_FLEXSPINOR_PROGRAMFAIL = MAKE_STATUS(STATUS_GROUP_FLEXSPINOR, 0),
+ STATUS_FLEXSPINOR_ERASESECTORFAIL =
+ MAKE_STATUS(STATUS_GROUP_FLEXSPINOR, 1),
+ STATUS_FLEXSPINOR_ERASEALLFAIL = MAKE_STATUS(STATUS_GROUP_FLEXSPINOR, 2),
+ STATUS_FLEXSPINOR_WAITTIMEOUT = MAKE_STATUS(STATUS_GROUP_FLEXSPINOR, 3),
+ STATUS_FLEXSPINOR_NOTSUPPORTED = MAKE_STATUS(STATUS_GROUP_FLEXSPINOR, 4),
+ STATUS_FLEXSPINOR_WRITEALIGNMENTERROR =
+ MAKE_STATUS(STATUS_GROUP_FLEXSPINOR, 5),
+ STATUS_FLEXSPINOR_COMMANDFAILURE =
+ MAKE_STATUS(STATUS_GROUP_FLEXSPINOR, 6),
+ STATUS_FLEXSPINOR_SFDP_NOTFOUND = MAKE_STATUS(STATUS_GROUP_FLEXSPINOR, 7),
+ STATUS_FLEXSPINOR_UNSUPPORTED_SFDP_VERSION =
+ MAKE_STATUS(STATUS_GROUP_FLEXSPINOR, 8),
+ STATUS_FLEXSPINOR_FLASH_NOTFOUND = MAKE_STATUS(STATUS_GROUP_FLEXSPINOR, 9),
+ STATUS_FLEXSPINOR_DTRREAD_DUMMYPROBEFAILED =
+ MAKE_STATUS(STATUS_GROUP_FLEXSPINOR, 10),
+};
+
+enum
+{
+ SERIAL_NOR_CFG_OPTION_TAG = 0x0c,
+ SERIAL_NOR_CFG_OPTION_DEVICETYPE_READSFDP_SDR = 0,
+ SERIAL_NOR_CFG_OPTION_DEVICETYPE_READSFDP_DDR = 1,
+ SERIAL_NOR_CFG_OPTION_DEVICETYPE_HYPERFLASH1V8 = 2,
+ SERIAL_NOR_CFG_OPTION_DEVICETYPE_HYPERFLASH3V0 = 3,
+ SERIAL_NOR_CFG_OPTION_DEVICETYPE_MACRONIXOCTALDDR = 4,
+ SERIAL_NOR_CFG_OPTION_DEVICETYPE_MACRONIXOCTALSDR = 5,
+ SERIAL_NOR_CFG_OPTION_DEVICETYPE_MICRONOCTALDDR = 6,
+ SERIAL_NOR_CFG_OPTION_DEVICETYPE_MICRONOCTALSDR = 7,
+ SERIAL_NOR_CFG_OPTION_DEVICETYPE_ADESTOOCTALDDR = 8,
+ SERIAL_NOR_CFG_OPTION_DEVICETYPE_ADESTOOCTALSDR = 9,
+};
+
+enum
+{
+ SERIAL_NOR_QUAD_MODE_NOTCONFIG = 0,
+ SERIAL_NOR_QUAD_MODE_STATUSREG1_BIT6 = 1,
+ SERIAL_NOR_QUAD_MODE_STATUSREG2_BIT1 = 2,
+ SERIAL_NOR_QUAD_MODE_STATUSREG2_BIT7 = 3,
+ SERIAL_NOR_QUAD_MODE_STATUSREG2_BIT1_0X31 = 4,
+};
+
+enum
+{
+ SERIAL_NOR_ENHANCE_MODE_DISABLED = 0,
+ SERIAL_NOR_ENHANCE_MODE_0_4_4_MODE = 1,
+ SERIAL_NOR_ENHANCE_MODE_0_8_8_MODE = 2,
+ SERIAL_NOR_ENHANCE_MODE_DATAORDERSWAPPED = 3,
+ SERIAL_NOR_ENHANCE_MODE_2NDPINMUX = 4,
+};
+
+typedef struct _serial_nor_config_option
+{
+ union
+ {
+ struct
+ {
+ uint32_t max_freq : 4;
+ uint32_t misc_mode : 4;
+ uint32_t quad_mode_setting : 4;
+ uint32_t cmd_pads : 4;
+ uint32_t query_pads : 4;
+ uint32_t device_type : 4;
+ uint32_t option_size : 4;
+ uint32_t tag : 4;
+ } B;
+ uint32_t U;
+ } option0;
+
+ union
+ {
+ struct
+ {
+ uint32_t dummy_cycles : 8;
+ uint32_t status_override : 8;
+ uint32_t is_pinmux_group2 : 4;
+ uint32_t reserved : 12;
+ } B;
+ uint32_t U;
+ } option1;
+} serial_nor_config_option_t;
+
+typedef struct _flexspi_nor_config
+{
+ flexspi_mem_config_t mem_config;
+ uint32_t page_size;
+ uint32_t sector_size;
+ uint8_t ipcmd_serial_clk_freq;
+ uint8_t is_uniform_block_size;
+ uint8_t is_data_order_swapped;
+ uint8_t reserved0[1];
+ uint8_t serial_nor_type;
+ uint8_t need_exit_no_cmd_mode;
+ uint8_t half_clk_for_non_read_cmd;
+ uint8_t need_restore_no_cmd_mode;
+ uint32_t block_size;
+ uint32_t reserve2[11];
+} flexspi_nor_config_t;
+
+typedef struct
+{
+ uint32_t version;
+ status_t (*init)(uint32_t instance, flexspi_nor_config_t *config);
+ status_t (*program)(uint32_t instance, flexspi_nor_config_t *config,
+ uint32_t dst_addr, const uint32_t *src);
+ status_t (*erase_all)(uint32_t instance, flexspi_nor_config_t *config);
+ status_t (*erase)(uint32_t instance, flexspi_nor_config_t *config,
+ uint32_t start, uint32_t length_in_bytes);
+ status_t (*read)(uint32_t instance, flexspi_nor_config_t *config,
+ uint32_t *dst, uint32_t addr, uint32_t length_in_bytes);
+ void (*clear_cache)(uint32_t instance);
+ status_t (*xfer)(uint32_t instance, flexspi_xfer_t *xfer);
+ status_t (*update_lut)(uint32_t instance, uint32_t seq_index,
+ const uint32_t *lut_base, uint32_t seq_number);
+ status_t (*get_config)(uint32_t instance, flexspi_nor_config_t *config,
+ serial_nor_config_option_t *option);
+} flexspi_nor_driver_interface_t;
+
+typedef struct
+{
+ const uint32_t version;
+ const char *copyright;
+ void (*run_bootloader)(void *arg);
+ const uint32_t *reserved0;
+ const flexspi_nor_driver_interface_t *flexspi_nor_driver;
+ const uint32_t *reserved1[2];
+ const void *rtwdog_driver;
+ const void *wdog_driver;
+ const uint32_t *reserved2;
+} bootloader_api_entry_t;
+
+enum
+{
+ ENTER_BOOTLOADER_TAG = 0xeb,
+ ENTER_BOOTLOADER_MODE_DEFAULT = 0,
+ ENTER_BOOTLOADER_MODE_SERIALDOWNLOADER = 1,
+
+ ENTER_BOOTLOADER_SERIALINTERFACE_AUTO = 0,
+ ENTER_BOOTLOADER_SERIALINTERFACE_USB = 1,
+ ENTER_BOOTLOADER_SERIALINTERFACE_UART = 2,
+
+ ENTER_BOOTLOADER_IMAGEINDEX_MAX = 3,
+};
+
+typedef union
+{
+ struct
+ {
+ uint32_t image_index : 4;
+ uint32_t reserved : 12;
+ uint32_t serial_boot_interface : 4;
+ uint32_t boot_mode : 4;
+ uint32_t tag : 8;
+ } B;
+ uint32_t U;
+} run_bootloader_ctx_t;
+
+#define g_bootloader_tree (*(bootloader_api_entry_t**)0x0020001c)
+
+static inline void run_bootloader(run_bootloader_ctx_t *ctx)
+{
+ g_bootloader_tree->run_bootloader(ctx);
+}
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+status_t flexspi_nor_flash_init(uint32_t instance,
+ flexspi_nor_config_t *config)
+{
+ return g_bootloader_tree->flexspi_nor_driver->init(instance, config);
+}
+
+status_t flexspi_nor_flash_page_program(uint32_t instance,
+ flexspi_nor_config_t *config,
+ uint32_t dst_addr,
+ const uint32_t *src)
+{
+ return g_bootloader_tree->flexspi_nor_driver->program(instance, config,
+ dst_addr, src);
+}
+
+status_t flexspi_nor_flash_erase_all(uint32_t instance,
+ flexspi_nor_config_t *config)
+{
+ return g_bootloader_tree->flexspi_nor_driver->erase_all(instance, config);
+}
+
+status_t flexspi_nor_get_config(uint32_t instance,
+ flexspi_nor_config_t *config,
+ serial_nor_config_option_t *option)
+{
+ return g_bootloader_tree->flexspi_nor_driver->get_config(instance, config,
+ option);
+}
+
+status_t flexspi_nor_flash_erase(uint32_t instance,
+ flexspi_nor_config_t *config,
+ uint32_t start,
+ uint32_t length)
+{
+ return g_bootloader_tree->flexspi_nor_driver->erase(instance, config,
+ start, length);
+}
+
+status_t flexspi_nor_flash_read(uint32_t instance,
+ flexspi_nor_config_t *config,
+ uint32_t *dst,
+ uint32_t start,
+ uint32_t bytes)
+{
+ return g_bootloader_tree->flexspi_nor_driver->read(instance, config,
+ dst, start, bytes);
+}
+
+status_t flexspi_update_lut(uint32_t instance,
+ uint32_t seq_index,
+ const uint32_t *lut_base,
+ uint32_t number_of_seq)
+{
+ return g_bootloader_tree->flexspi_nor_driver->update_lut(instance,
+ seq_index,
+ lut_base,
+ number_of_seq);
+}
+
+status_t flexspi_command_xfer(uint32_t instance, flexspi_xfer_t *xfer)
+{
+ return g_bootloader_tree->flexspi_nor_driver->xfer(instance, xfer);
+}
+
+void flexspi_clear_cache(uint32_t instance)
+{
+ g_bootloader_tree->flexspi_nor_driver->clear_cache(instance);
+}
+
+struct imxrt106x_flash_priv_s
+{
+ mutex_t lock;
+ uint32_t ifbase;
+ uint32_t base;
+ uint32_t stblock;
+ uint32_t stpage;
+};
+
+#if CONFIG_IMXRT_PROGMEM_FLEXSPI_INSTANCE == 0
+static struct imxrt106x_flash_priv_s imxrt106x_flash_priv =
+{
+ .lock = NXMUTEX_INITIALIZER,
+ .ifbase = IMXRT_FLEXSPIC_BASE,
+ .base = IMXRT_FLEXCIPHER_BASE,
+ .stblock = 0,
+ .stpage = 0,
+};
+#else
+static struct imxrt106x_flash_priv_s imxrt106x_flash_priv =
+{
+ .lock = NXMUTEX_INITIALIZER,
+ .ifbase = IMXRT_FLEXSPI2C_BASE,
+ .base = IMXRT_FLEX2CIPHER_BASE,
+ .stblock = 0,
+ .stpage = 0,
+};
+#endif
+
+static flexspi_nor_config_t flash_config;
+static serial_nor_config_option_t config_option;
+
+static int imxrt106x_israngeerased(size_t startaddress, size_t size)
+{
+ uint32_t *addr;
+ uint8_t *baddr;
+ size_t count = 0;
+ size_t bwritten = 0;
+
+ addr = (uint32_t *)startaddress;
+ while (count + 4 <= size)
+ {
+ if (getreg32(addr) != FLASH_ERASEDVALUE_DW)
+ {
+ bwritten++;
+ }
+
+ addr++;
+ count += 4;
+ }
+
+ baddr = (uint8_t *)addr;
+ while (count < size)
+ {
+ if (getreg8(baddr) != FLASH_ERASEDVALUE)
+ {
+ bwritten++;
+ }
+
+ baddr++;
+ count++;
+ }
+
+ return bwritten;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+size_t up_progmem_erasesize(size_t block)
+{
+ return FLASH_SECTOR_SIZE;
+}
+
+size_t up_progmem_pagesize(size_t page)
+{
+ return up_progmem_erasesize(page);
+}
+
+ssize_t up_progmem_getpage(size_t addr)
+{
+ struct imxrt106x_flash_priv_s *priv = &imxrt106x_flash_priv;
+
+ return priv->stpage + ((addr - priv->base) / FLASH_SECTOR_SIZE);
+}
+
+size_t up_progmem_getaddress(size_t page)
+{
+ struct imxrt106x_flash_priv_s *priv = &imxrt106x_flash_priv;
+
+ if (page >= PROGMEM_NBLOCKS)
+ {
+ return SIZE_MAX;
+ }
+
+ return priv->base + (page - priv->stpage) * FLASH_SECTOR_SIZE;
+}
+
+size_t up_progmem_neraseblocks(void)
+{
+ return PROGMEM_NBLOCKS;
+}
+
+bool up_progmem_isuniform(void)
+{
+ return true;
+}
+
+ssize_t up_progmem_ispageerased(size_t page)
+{
+ size_t addr;
+ size_t count;
+ size_t bwritten = 0;
+
+ if (page >= PROGMEM_NBLOCKS)
+ {
+ return -EFAULT;
+ }
+
+ for (addr = up_progmem_getaddress(page), count = up_progmem_pagesize(page);
+ count; count--, addr++)
+ {
+ if (getreg8(addr) != FLASH_ERASEDVALUE)
+ {
+ bwritten++;
+ }
+ }
+
+ return bwritten;
+}
+
+ssize_t up_progmem_eraseblock(size_t block)
+{
+ struct imxrt106x_flash_priv_s *priv = &imxrt106x_flash_priv;
+ int ret;
+ status_t status;
+ size_t block_address = (block * FLASH_SECTOR_SIZE);
+
+ ret = nxmutex_lock(&priv->lock);
+ if (ret < 0)
+ {
+ return (ssize_t)ret;
+ }
+
+ config_option.option0.U = 0xc0000008;
+
+ up_irq_disable();
+ up_disable_icache();
+ up_disable_dcache();
+
+ status = flexspi_nor_get_config(FLEXSPI_INSTANCE, &flash_config,
+ &config_option);
+ if (status != STATUS_SUCCESS)
+ {
+ ret = -EIO;
+ goto exit_with_lock;
+ }
+
+ status = flexspi_nor_flash_init(FLEXSPI_INSTANCE, &flash_config);
+ if (status != STATUS_SUCCESS)
+ {
+ ret = -EIO;
+ goto exit_with_lock;
+ }
+
+ status = flexspi_nor_flash_erase(FLEXSPI_INSTANCE, &flash_config,
+ block_address, FLASH_SECTOR_SIZE);
+ if (status != STATUS_SUCCESS)
+ {
+ ret = -EIO;
+ goto exit_with_lock;
+ }
+
+ ret = 0;
+
+exit_with_lock:
+ nxmutex_unlock(&priv->lock);
+
+ /* Verify */
+
+ if (ret == 0 &&
+ imxrt106x_israngeerased(priv->base + block_address,
+ up_progmem_erasesize(block)) == 0)
+ {
+ ret = up_progmem_erasesize(block); /* success */
+ }
+ else
+ {
+ ret = -EIO; /* failure */
+ }
+
+ up_enable_dcache();
+ up_enable_icache();
+ up_irq_enable();
+
+ return ret;
+}
+
+ssize_t up_progmem_write(size_t addr, const void *buf, size_t count)
+{
+ struct imxrt106x_flash_priv_s *priv = &imxrt106x_flash_priv;
+ size_t written = count;
+ uint32_t *ll = (uint32_t *)buf;
+ size_t faddr;
+ status_t status;
+ int ret;
+ const size_t pagesize = FLASH_PAGE_SIZE;
+ const size_t llperpage = pagesize / sizeof(uint32_t);
+ size_t pcount = count / pagesize;
+
+ ret = nxmutex_lock(&priv->lock);
+ if (ret < 0)
+ {
+ return (ssize_t)ret;
+ }
+
+ /* Check address and count alignment */
+
+ DEBUGASSERT(!(addr % pagesize));
+ DEBUGASSERT(!(count % pagesize));
+
+ config_option.option0.U = 0xc0000008;
+
+ up_irq_disable();
+ up_disable_icache();
+
+ status = flexspi_nor_get_config(FLEXSPI_INSTANCE, &flash_config,
+ &config_option);
+ if (status != STATUS_SUCCESS)
+ {
+ written = -EIO;
+ goto exit_with_lock;
+ }
+
+ status = flexspi_nor_flash_init(FLEXSPI_INSTANCE, &flash_config);
+ if (status != STATUS_SUCCESS)
+ {
+ written = -EIO;
+ goto exit_with_lock;
+ }
+
+ for (ll = (uint32_t *)buf, faddr = addr - priv->base; pcount;
+ pcount -= 1, ll += llperpage, faddr += pagesize)
+ {
+ status = flexspi_nor_flash_page_program(FLEXSPI_INSTANCE,
+ &flash_config, faddr, ll);
+ if (status != STATUS_SUCCESS)
+ {
+ written = -EIO;
+ break;
+ }
+ }
+
+exit_with_lock:
+ nxmutex_unlock(&priv->lock);
+ up_enable_icache();
+ up_irq_enable();
+
+ return written;
+}
+
+uint8_t up_progmem_erasestate(void)
+{
+ return FLASH_ERASEDVALUE;
+}
diff --git a/arch/arm/src/imxrt/imxrt_flash.c b/arch/arm/src/imxrt/imxrt_flash.c
new file mode 100644
index 0000000000..62f769735b
--- /dev/null
+++ b/arch/arm/src/imxrt/imxrt_flash.c
@@ -0,0 +1,35 @@
+/****************************************************************************
+ * arch/arm/src/imxrt/imxrt_flash.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#if defined(CONFIG_ARCH_FAMILY_IMXRT106x)
+# include "imxrt106x_flash.c"
+#else
+# error "Unsupported IMXRT chip"
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
diff --git a/boards/arm/imxrt/imxrt1064-evk/configs/mcuboot-app/defconfig
b/boards/arm/imxrt/imxrt1064-evk/configs/mcuboot-app/defconfig
new file mode 100644
index 0000000000..16078de3cd
--- /dev/null
+++ b/boards/arm/imxrt/imxrt1064-evk/configs/mcuboot-app/defconfig
@@ -0,0 +1,85 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed
.config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that
includes your
+# modifications.
+#
+# CONFIG_ARCH_LEDS is not set
+CONFIG_ARCH="arm"
+CONFIG_ARCH_BOARD="imxrt1064-evk"
+CONFIG_ARCH_BOARD_IMXRT1064_EVK=y
+CONFIG_ARCH_CHIP="imxrt"
+CONFIG_ARCH_CHIP_IMXRT=y
+CONFIG_ARCH_CHIP_MIMXRT1064DVL6A=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARMV7M_DCACHE=y
+CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y
+CONFIG_ARMV7M_ICACHE=y
+CONFIG_ARMV7M_USEBASEPRI=y
+CONFIG_BOARDCTL_RESET=y
+CONFIG_BOARD_LOOPSPERMSEC=104926
+CONFIG_BUILTIN=y
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_ETH0_PHY_KSZ8081=y
+CONFIG_EXAMPLES_MCUBOOT_SLOT_CONFIRM=y
+CONFIG_EXAMPLES_MCUBOOT_SWAP_TEST=y
+CONFIG_EXAMPLES_MCUBOOT_UPDATE_AGENT=y
+CONFIG_EXAMPLES_MCUBOOT_UPDATE_AGENT_DL_BUFFER_SIZE=4096
+CONFIG_EXPERIMENTAL=y
+CONFIG_FAT_LCNAMES=y
+CONFIG_FS_FAT=y
+CONFIG_FS_PROCFS=y
+CONFIG_FS_PROCFS_REGISTER=y
+CONFIG_IDLETHREAD_STACKSIZE=2048
+CONFIG_IMXRT_APP_FORMAT_MCUBOOT=y
+CONFIG_IMXRT_ENET=y
+CONFIG_IMXRT_LPUART1=y
+CONFIG_IMXRT_PROGMEM_OTA_PARTITION=y
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INIT_STACKSIZE=4096
+CONFIG_IOB_NBUFFERS=128
+CONFIG_LIBC_HOSTNAME="i.MXRT1064 EVK"
+CONFIG_LPUART1_BAUD=9600
+CONFIG_LPUART1_SERIAL_CONSOLE=y
+CONFIG_NET=y
+CONFIG_NETDB_DNSCLIENT=y
+CONFIG_NETDEV_STATISTICS=y
+CONFIG_NETINIT_NOMAC=y
+CONFIG_NETUTILS_DISCOVER=y
+CONFIG_NETUTILS_WEBCLIENT=y
+CONFIG_NET_ARP_SEND=y
+CONFIG_NET_BROADCAST=y
+CONFIG_NET_ETH_PKTSIZE=1514
+CONFIG_NET_GUARDSIZE=4
+CONFIG_NET_ICMP=y
+CONFIG_NET_ICMP_SOCKET=y
+CONFIG_NET_ICMPv6=y
+CONFIG_NET_ICMPv6_NEIGHBOR=y
+CONFIG_NET_ICMPv6_SOCKET=y
+CONFIG_NET_IPv6=y
+CONFIG_NET_STATISTICS=y
+CONFIG_NET_TCP=y
+CONFIG_NET_TCPBACKLOG=y
+CONFIG_NET_TCP_WRITE_BUFFERS=y
+CONFIG_NET_UDP=y
+CONFIG_NET_UDP_WRITE_BUFFERS=y
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_MOTD=y
+CONFIG_NSH_MOTD_STRING="Welcome to Nuttx from MCUboot, this is the FIRST
firmware."
+CONFIG_NSH_READLINE=y
+CONFIG_RAM_SIZE=1048576
+CONFIG_RAM_START=0x20200000
+CONFIG_RAW_BINARY=y
+CONFIG_READLINE_CMD_HISTORY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_LPWORK=y
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=14
+CONFIG_START_MONTH=3
+CONFIG_SYSTEM_DHCPC_RENEW=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_SYSTEM_PING=y
diff --git a/boards/arm/imxrt/imxrt1064-evk/configs/mcuboot-loader/defconfig
b/boards/arm/imxrt/imxrt1064-evk/configs/mcuboot-loader/defconfig
new file mode 100644
index 0000000000..ec8ca69331
--- /dev/null
+++ b/boards/arm/imxrt/imxrt1064-evk/configs/mcuboot-loader/defconfig
@@ -0,0 +1,59 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed
.config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that
includes your
+# modifications.
+#
+CONFIG_ARCH="arm"
+CONFIG_ARCH_BOARD="imxrt1064-evk"
+CONFIG_ARCH_BOARD_IMXRT1064_EVK=y
+CONFIG_ARCH_CHIP="imxrt"
+CONFIG_ARCH_CHIP_IMXRT=y
+CONFIG_ARCH_CHIP_MIMXRT1064DVL6A=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARMV7M_DCACHE=y
+CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y
+CONFIG_ARMV7M_ICACHE=y
+CONFIG_ARMV7M_USEBASEPRI=y
+CONFIG_BOARDCTL_RESET=y
+CONFIG_BOARD_LOOPSPERMSEC=104926
+CONFIG_BOOT_MCUBOOT=y
+CONFIG_BUILTIN=y
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_FAT_LCNAMES=y
+CONFIG_FS_FAT=y
+CONFIG_FS_PROCFS=y
+CONFIG_FS_PROCFS_REGISTER=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_IDLETHREAD_STACKSIZE=2048
+CONFIG_IMXRT_APP_FORMAT_MCUBOOT=y
+CONFIG_IMXRT_LPUART1=y
+CONFIG_IMXRT_PROGMEM_OTA_PARTITION=y
+CONFIG_INIT_ENTRYPOINT="mcuboot_loader_main"
+CONFIG_INIT_STACKSIZE=4096
+CONFIG_LIBM=y
+CONFIG_LPUART1_BAUD=9600
+CONFIG_LPUART1_SERIAL_CONSOLE=y
+CONFIG_MCUBOOT_BOOTLOADER=y
+CONFIG_MCUBOOT_VERSION="414ac87cfd8d9cedeb781f812ad6f5072e6d8a39"
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_DISABLE_IFUPDOWN=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LIBRARY=y
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_MOTD=y
+CONFIG_NSH_MOTD_STRING="Welcome to Nuttx MCUboot-Loader!"
+CONFIG_NSH_READLINE=y
+CONFIG_RAM_SIZE=1048576
+CONFIG_RAM_START=0x20200000
+CONFIG_RAW_BINARY=y
+CONFIG_SCHED_HPWORK=y
+CONFIG_SCHED_LPWORK=y
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=14
+CONFIG_START_MONTH=3
+CONFIG_TASK_NAME_SIZE=0
+CONFIG_WQUEUE_NOTIFIER=y
diff --git a/boards/arm/imxrt/imxrt1064-evk/scripts/Make.defs
b/boards/arm/imxrt/imxrt1064-evk/scripts/Make.defs
index 4a2f40105b..f6dbc5f7a0 100644
--- a/boards/arm/imxrt/imxrt1064-evk/scripts/Make.defs
+++ b/boards/arm/imxrt/imxrt1064-evk/scripts/Make.defs
@@ -22,10 +22,18 @@ include $(TOPDIR)/.config
include $(TOPDIR)/tools/Config.mk
include $(TOPDIR)/arch/arm/src/armv7-m/Toolchain.defs
-ifeq ($(CONFIG_BOOT_RUNFROMFLASH),y)
- LDSCRIPT = flash.ld
-else ifeq ($(CONFIG_BOOT_RUNFROMISRAM),y)
- LDSCRIPT = flash-ocram.ld
+ifeq ($(CONFIG_IMXRT_APP_FORMAT_MCUBOOT),y)
+ ifeq ($(CONFIG_MCUBOOT_BOOTLOADER),y)
+ LDSCRIPT = flash-mcuboot-loader.ld
+ else
+ LDSCRIPT = flash-mcuboot-app.ld
+ endif
+else
+ ifeq ($(CONFIG_BOOT_RUNFROMFLASH),y)
+ LDSCRIPT = flash.ld
+ else ifeq ($(CONFIG_BOOT_RUNFROMISRAM),y)
+ LDSCRIPT = flash-ocram.ld
+ endif
endif
ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT)
diff --git a/boards/arm/imxrt/imxrt1064-evk/scripts/flash-mcuboot-app.ld
b/boards/arm/imxrt/imxrt1064-evk/scripts/flash-mcuboot-app.ld
new file mode 100644
index 0000000000..7b70b44a59
--- /dev/null
+++ b/boards/arm/imxrt/imxrt1064-evk/scripts/flash-mcuboot-app.ld
@@ -0,0 +1,119 @@
+/****************************************************************************
+ * boards/arm/imxrt/imxrt1064-evk/scripts/flash.ld
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/* Specify the memory areas */
+
+MEMORY
+{
+ flash (rx) : ORIGIN = 0x70040200, LENGTH = 1792K - 512
+ sram (rwx) : ORIGIN = 0x20200000, LENGTH = 512M
+ itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 128K
+ dtcm (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
+}
+
+OUTPUT_ARCH(arm)
+EXTERN(_vectors)
+
+ENTRY(_stext)
+
+SECTIONS
+{
+ .text :
+ {
+ _stext = ABSOLUTE(.);
+ *(.vectors)
+ *(.text .text.*)
+ *(.fixup)
+ *(.gnu.warning)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.t.*)
+ *(.glue_7)
+ *(.glue_7t)
+ *(.got)
+ *(.gcc_except_table)
+ *(.gnu.linkonce.r.*)
+ _etext = ABSOLUTE(.);
+ } > flash
+
+ .init_section :
+ {
+ _sinit = ABSOLUTE(.);
+ *(.init_array .init_array.*)
+ _einit = ABSOLUTE(.);
+ } > flash
+
+ .ARM.extab :
+ {
+ *(.ARM.extab*)
+ } > flash
+
+ .ARM.exidx :
+ {
+ __exidx_start = ABSOLUTE(.);
+ *(.ARM.exidx*)
+ __exidx_end = ABSOLUTE(.);
+ } > flash
+
+ _eronly = ABSOLUTE(.);
+
+ .data :
+ {
+ _sdata = ABSOLUTE(.);
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ CONSTRUCTORS
+ . = ALIGN(4);
+ _edata = ABSOLUTE(.);
+ } > sram AT > flash
+
+ .ramfunc ALIGN(4):
+ {
+ _sramfuncs = ABSOLUTE(.);
+ *(.ramfunc .ramfunc.*)
+ _eramfuncs = ABSOLUTE(.);
+ } > sram AT > flash
+
+ _framfuncs = LOADADDR(.ramfunc);
+
+ .bss :
+ {
+ _sbss = ABSOLUTE(.);
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = ABSOLUTE(.);
+ } > sram
+
+ /* Stabs debugging sections. */
+
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_info 0 : { *(.debug_info) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+}
diff --git a/boards/arm/imxrt/imxrt1064-evk/scripts/flash-mcuboot-loader.ld
b/boards/arm/imxrt/imxrt1064-evk/scripts/flash-mcuboot-loader.ld
new file mode 100644
index 0000000000..7c80d9dee7
--- /dev/null
+++ b/boards/arm/imxrt/imxrt1064-evk/scripts/flash-mcuboot-loader.ld
@@ -0,0 +1,139 @@
+/****************************************************************************
+ * boards/arm/imxrt/imxrt1064-evk/scripts/flash.ld
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/* Specify the memory areas */
+
+MEMORY
+{
+ flash (rx) : ORIGIN = 0x70000000, LENGTH = 256K
+ sram (rwx) : ORIGIN = 0x20200000, LENGTH = 512M
+ itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 128K
+ dtcm (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
+}
+
+OUTPUT_ARCH(arm)
+EXTERN(_vectors)
+EXTERN(g_flash_config)
+EXTERN(g_image_vector_table)
+EXTERN(g_boot_data)
+
+ENTRY(_stext)
+
+SECTIONS
+{
+ /* Image Vector Table and Boot Data for booting from external flash */
+
+ .boot_hdr : ALIGN(4)
+ {
+ FILL(0xff)
+ __boot_hdr_start__ = ABSOLUTE(.) ;
+ KEEP(*(.boot_hdr.conf))
+ . = 0x1000 ;
+ KEEP(*(.boot_hdr.ivt))
+ . = 0x1020 ;
+ KEEP(*(.boot_hdr.boot_data))
+ . = 0x1030 ;
+ KEEP(*(.boot_hdr.dcd_data))
+ __boot_hdr_end__ = ABSOLUTE(.) ;
+ . = 0x2000 ;
+ } >flash
+
+ .text :
+ {
+ _stext = ABSOLUTE(.);
+ *(.vectors)
+ *(.text .text.*)
+ *(.fixup)
+ *(.gnu.warning)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.t.*)
+ *(.glue_7)
+ *(.glue_7t)
+ *(.got)
+ *(.gcc_except_table)
+ *(.gnu.linkonce.r.*)
+ _etext = ABSOLUTE(.);
+ } > flash
+
+ .init_section :
+ {
+ _sinit = ABSOLUTE(.);
+ *(.init_array .init_array.*)
+ _einit = ABSOLUTE(.);
+ } > flash
+
+ .ARM.extab :
+ {
+ *(.ARM.extab*)
+ } > flash
+
+ .ARM.exidx :
+ {
+ __exidx_start = ABSOLUTE(.);
+ *(.ARM.exidx*)
+ __exidx_end = ABSOLUTE(.);
+ } > flash
+
+ _eronly = ABSOLUTE(.);
+
+ .data :
+ {
+ _sdata = ABSOLUTE(.);
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ CONSTRUCTORS
+ . = ALIGN(4);
+ _edata = ABSOLUTE(.);
+ } > sram AT > flash
+
+ .ramfunc ALIGN(4):
+ {
+ _sramfuncs = ABSOLUTE(.);
+ *(.ramfunc .ramfunc.*)
+ _eramfuncs = ABSOLUTE(.);
+ } > sram AT > flash
+
+ _framfuncs = LOADADDR(.ramfunc);
+
+ .bss :
+ {
+ _sbss = ABSOLUTE(.);
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = ABSOLUTE(.);
+ } > sram
+
+ /* Stabs debugging sections. */
+
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_info 0 : { *(.debug_info) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+}
diff --git a/boards/arm/imxrt/imxrt1064-evk/src/Makefile
b/boards/arm/imxrt/imxrt1064-evk/src/Makefile
index bffdbca9ea..92dc98b1c1 100644
--- a/boards/arm/imxrt/imxrt1064-evk/src/Makefile
+++ b/boards/arm/imxrt/imxrt1064-evk/src/Makefile
@@ -86,4 +86,16 @@ ifeq ($(CONFIG_IMXRT_FLEXSPI),y)
CSRCS += imxrt_flexspi_nor.c
endif
+ifeq ($(CONFIG_IMXRT_PROGMEM),y)
+CSRCS += imxrt_progmem.c
+endif
+
+ifeq ($(CONFIG_BOARDCTL_RESET),y)
+CSRCS += imxrt_reset.c
+endif
+
+ifeq ($(CONFIG_BOARDCTL_BOOT_IMAGE),y)
+CSRCS += imxrt_boot_image.c
+endif
+
include $(TOPDIR)/boards/Board.mk
diff --git a/boards/arm/imxrt/imxrt1064-evk/src/imxrt1064-evk.h
b/boards/arm/imxrt/imxrt1064-evk/src/imxrt1064-evk.h
index 17894c2365..3a6111264c 100644
--- a/boards/arm/imxrt/imxrt1064-evk/src/imxrt1064-evk.h
+++ b/boards/arm/imxrt/imxrt1064-evk/src/imxrt1064-evk.h
@@ -40,6 +40,14 @@
* Pre-processor Definitions
****************************************************************************/
+/* Configuration ************************************************************/
+
+#define HAVE_PROGMEM_CHARDEV 1
+
+#if !defined(CONFIG_IMXRT_PROGMEM) || !defined(CONFIG_MTD_PROGMEM)
+# undef HAVE_PROGMEM_CHARDEV
+#endif
+
/* Touchscreen definitions **************************************************/
/* The IMXRT 1050/1060 have connectors for the LCD model RK043FN02H-CT.
@@ -317,5 +325,12 @@ int imxrt_usbhost_initialize(void);
int imxrt_flexspi_nor_initialize(void);
#endif
+#ifdef CONFIG_MTD
+
+#ifdef HAVE_PROGMEM_CHARDEV
+int imxrt_progmem_init(void);
+#endif /* HAVE_PROGMEM_CHARDEV */
+#endif
+
#endif /* __ASSEMBLY__ */
#endif /* __BOARDS_ARM_IMXRT_IMXRT1064_EVK_SRC_IMXRT1064_EVK_H */
diff --git a/boards/arm/imxrt/imxrt1064-evk/src/imxrt_boot_image.c
b/boards/arm/imxrt/imxrt1064-evk/src/imxrt_boot_image.c
new file mode 100644
index 0000000000..ccfa93ffff
--- /dev/null
+++ b/boards/arm/imxrt/imxrt1064-evk/src/imxrt_boot_image.c
@@ -0,0 +1,180 @@
+/****************************************************************************
+ * boards/arm/imxrt/imxrt1064-evk/src/imxrt_boot_image.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <debug.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+#include <sys/boardctl.h>
+#include <nuttx/irq.h>
+#include <nuttx/cache.h>
+
+#include "nvic.h"
+#include "arm_internal.h"
+#include "barriers.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* This structure represents the first two entries on NVIC vector table */
+
+struct arm_vector_table
+{
+ uint32_t spr; /* Stack pointer on reset */
+ uint32_t reset; /* Pointer to reset exception handler */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void cleanup_arm_nvic(void);
+static void systick_disable(void);
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: cleanup_arm_nvic
+ *
+ * Description:
+ * Acknowledge and disable all interrupts in NVIC
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void cleanup_arm_nvic(void)
+{
+ int i;
+
+ /* Allow any pending interrupts to be recognized */
+
+ ARM_ISB();
+ cpsid();
+
+ /* Disable all interrupts */
+
+ for (i = 0; i < NR_IRQS; i += 32)
+ {
+ putreg32(0xffffffff, NVIC_IRQ_CLEAR(i));
+ }
+
+ /* Clear all pending interrupts */
+
+ for (i = 0; i < NR_IRQS; i += 32)
+ {
+ putreg32(0xffffffff, NVIC_IRQ_CLRPEND(i));
+ }
+}
+
+/****************************************************************************
+ * Name: systick_disable
+ *
+ * Description:
+ * Disable the SysTick system timer
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void systick_disable(void)
+{
+ putreg32(0, NVIC_SYSTICK_CTRL);
+ putreg32(NVIC_SYSTICK_RELOAD_MASK, NVIC_SYSTICK_RELOAD);
+ putreg32(0, NVIC_SYSTICK_CURRENT);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_boot_image
+ *
+ * Description:
+ * This entry point is called by bootloader to jump to application image.
+ *
+ ****************************************************************************/
+
+int board_boot_image(const char *path, uint32_t hdr_size)
+{
+ static struct arm_vector_table vt;
+ int fd;
+ ssize_t bytes;
+
+ fd = open(path, O_RDONLY | O_CLOEXEC);
+ if (fd < 0)
+ {
+ syslog(LOG_ERR, "Failed to open %s with: %d", path, fd);
+ return fd;
+ }
+
+ bytes = pread(fd, &vt, sizeof(vt), hdr_size);
+ if (bytes != sizeof(vt))
+ {
+ syslog(LOG_ERR, "Failed to read ARM vector table: %d", bytes);
+ return bytes < 0 ? bytes : -1;
+ }
+
+ systick_disable();
+
+ cleanup_arm_nvic();
+
+#ifdef CONFIG_ARMV7M_DCACHE
+ up_disable_dcache();
+#endif
+#ifdef CONFIG_ARMV7M_ICACHE
+ up_disable_icache();
+#endif
+
+#ifdef CONFIG_ARM_MPU
+ mpu_control(false, false, false);
+#endif
+
+ /* Set main and process stack pointers */
+
+ __asm__ __volatile__("\tmsr msp, %0\n" : : "r" (vt.spr));
+ setcontrol(0x00);
+ ARM_ISB();
+ ((void (*)(void))vt.reset)();
+
+ return 0;
+}
diff --git a/boards/arm/imxrt/imxrt1064-evk/src/imxrt_bringup.c
b/boards/arm/imxrt/imxrt1064-evk/src/imxrt_bringup.c
index 58272f7da4..666f68fd9b 100644
--- a/boards/arm/imxrt/imxrt1064-evk/src/imxrt_bringup.c
+++ b/boards/arm/imxrt/imxrt1064-evk/src/imxrt_bringup.c
@@ -287,6 +287,16 @@ int imxrt_bringup(void)
}
#endif /* CONFIG_IMXRT_FLEXSPI */
+#ifdef CONFIG_MTD
+#ifdef HAVE_PROGMEM_CHARDEV
+ ret = imxrt_progmem_init();
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to initialize MTD progmem: %d\n", ret);
+ }
+#endif /* HAVE_PROGMEM_CHARDEV */
+#endif /* CONFIG_MTD */
+
UNUSED(ret);
return OK;
}
diff --git a/boards/arm/imxrt/imxrt1064-evk/src/imxrt_progmem.c
b/boards/arm/imxrt/imxrt1064-evk/src/imxrt_progmem.c
new file mode 100644
index 0000000000..bd031ee979
--- /dev/null
+++ b/boards/arm/imxrt/imxrt1064-evk/src/imxrt_progmem.c
@@ -0,0 +1,255 @@
+/****************************************************************************
+ * boards/arm/imxrt/imxrt1064-evk/src/imxrt_progmem.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/mount.h>
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/progmem.h>
+#include <nuttx/drivers/drivers.h>
+#include <nuttx/fs/ioctl.h>
+#include <nuttx/kmalloc.h>
+#include <nuttx/mtd/mtd.h>
+#ifdef CONFIG_BCH
+#include <nuttx/drivers/drivers.h>
+#endif
+
+#include "imxrt1064-evk.h"
+
+#ifdef HAVE_PROGMEM_CHARDEV
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define ARRAYSIZE(x) (sizeof((x)) / sizeof((x)[0]))
+
+#define PARTITION_LABEL_LEN 16
+
+/* Configuration ************************************************************/
+
+/* Make sure that support for MTD partitions is enabled */
+#ifdef CONFIG_MTD
+
+#ifndef CONFIG_MTD_PARTITION
+# error "CONFIG_MTD_PARTITION is required"
+#endif
+
+#endif
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+#if defined(CONFIG_IMXRT_PROGMEM_OTA_PARTITION)
+
+struct ota_partition_s
+{
+ uint32_t offset; /* Partition offset from the beginning of MTD */
+ uint32_t size; /* Partition size in bytes */
+ const char *devpath; /* Partition device path */
+};
+
+#endif
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+#if defined(CONFIG_IMXRT_PROGMEM_OTA_PARTITION)
+static struct mtd_dev_s *progmem_alloc_mtdpart(uint32_t mtd_offset,
+ uint32_t mtd_size);
+static int init_ota_partitions(void);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct mtd_dev_s *g_progmem_mtd;
+
+#if defined(CONFIG_IMXRT_PROGMEM_OTA_PARTITION)
+static const struct ota_partition_s g_ota_partition_table[] =
+{
+ {
+ .offset = CONFIG_IMXRT_OTA_PRIMARY_SLOT_OFFSET,
+ .size = CONFIG_IMXRT_OTA_SLOT_SIZE,
+ .devpath = CONFIG_IMXRT_OTA_PRIMARY_SLOT_DEVPATH
+ },
+ {
+ .offset = CONFIG_IMXRT_OTA_SECONDARY_SLOT_OFFSET,
+ .size = CONFIG_IMXRT_OTA_SLOT_SIZE,
+ .devpath = CONFIG_IMXRT_OTA_SECONDARY_SLOT_DEVPATH
+ },
+ {
+ .offset = CONFIG_IMXRT_OTA_SCRATCH_OFFSET,
+ .size = CONFIG_IMXRT_OTA_SCRATCH_SIZE,
+ .devpath = CONFIG_IMXRT_OTA_SCRATCH_DEVPATH
+ }
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+#if defined(CONFIG_IMXRT_PROGMEM_OTA_PARTITION)
+
+/****************************************************************************
+ * Name: progmem_alloc_mtdpart
+ *
+ * Description:
+ * Allocate an MTD partition from FLASH.
+ *
+ * Input Parameters:
+ * mtd_offset - MTD Partition offset from the base address in FLASH.
+ * mtd_size - Size for the MTD partition.
+ *
+ * Returned Value:
+ * MTD partition data pointer on success, NULL on failure.
+ *
+ ****************************************************************************/
+
+static struct mtd_dev_s *progmem_alloc_mtdpart(uint32_t mtd_offset,
+ uint32_t mtd_size)
+{
+ uint32_t blocks;
+ ssize_t startblock;
+
+ ASSERT((mtd_offset % up_progmem_pagesize(0)) == 0);
+ ASSERT((mtd_size % up_progmem_pagesize(0)) == 0);
+
+ finfo("\tMTD offset = 0x%"PRIx32"\n", mtd_offset);
+ finfo("\tMTD size = 0x%"PRIx32"\n", mtd_size);
+
+ startblock = up_progmem_getpage(mtd_offset + up_progmem_getaddress(0));
+ if (startblock < 0)
+ {
+ return NULL;
+ }
+
+ blocks = mtd_size / up_progmem_pagesize(0);
+
+ return mtd_partition(g_progmem_mtd, startblock, blocks);
+}
+
+/****************************************************************************
+ * Name: init_ota_partitions
+ *
+ * Description:
+ * Initialize partitions that are dedicated to firmware OTA update.
+ *
+ * Input Parameters:
+ * None.
+ *
+ * Returned Value:
+ * Zero on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+static int init_ota_partitions(void)
+{
+ int i;
+ struct mtd_dev_s *mtd;
+ int ret = 0;
+ char path[PARTITION_LABEL_LEN + 1];
+
+ for (i = 0; i < ARRAYSIZE(g_ota_partition_table); ++i)
+ {
+ const struct ota_partition_s *part = &g_ota_partition_table[i];
+ mtd = progmem_alloc_mtdpart(part->offset, part->size);
+
+ strncpy(path, (char *)part->devpath, PARTITION_LABEL_LEN);
+ path[PARTITION_LABEL_LEN] = '\0';
+
+ finfo("INFO: [label]: %s\n", path);
+ finfo("INFO: [offset]: 0x%08" PRIx32 "\n", part->offset);
+ finfo("INFO: [size]: 0x%08" PRIx32 "\n", part->size);
+
+ if (!mtd)
+ {
+ ferr("ERROR: Failed to create MTD partition\n");
+ ret = -1;
+ }
+
+ ret = register_mtddriver(path, mtd, 0777, NULL);
+ if (ret < 0)
+ {
+ ferr("ERROR: Failed to register MTD @ %s\n", path);
+ ret = -1;
+ }
+ }
+
+ return ret;
+}
+#endif /* CONFIG_IMXRT_PROGMEM_OTA_PARTITION */
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: imxrt_progmem_init
+ *
+ * Initialize Progmem partition. Read partition information, and use
+ * these data for creating MTD.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * 0 if success or a negative value if fail.
+ *
+ ****************************************************************************/
+
+int imxrt_progmem_init(void)
+{
+ int ret = 0;
+
+ g_progmem_mtd = progmem_initialize();
+ if (g_progmem_mtd == NULL)
+ {
+ ferr("ERROR: Failed to get progmem flash MTD\n");
+ ret = -EIO;
+ }
+
+#ifdef CONFIG_IMXRT_PROGMEM_OTA_PARTITION
+ ret = init_ota_partitions();
+ if (ret < 0)
+ {
+ ferr("ERROR: Failed to create OTA partition from MTD\n");
+ ret = -EIO;
+ }
+#endif
+
+ return ret;
+}
+
+#endif /* HAVE_PROGMEM_CHARDEV */
diff --git a/boards/arm/imxrt/imxrt1064-evk/src/imxrt_reset.c
b/boards/arm/imxrt/imxrt1064-evk/src/imxrt_reset.c
new file mode 100644
index 0000000000..f05c427060
--- /dev/null
+++ b/boards/arm/imxrt/imxrt1064-evk/src/imxrt_reset.c
@@ -0,0 +1,62 @@
+/****************************************************************************
+ * boards/arm/imxrt/imxrt1064-evk/src/imxrt_reset.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/board.h>
+
+#ifdef CONFIG_BOARDCTL_RESET
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_reset
+ *
+ * Description:
+ * Reset board. Support for this function is required by board-level
+ * logic if CONFIG_BOARDCTL_RESET is selected.
+ *
+ * Input Parameters:
+ * status - Status information provided with the reset event. This
+ * meaning of this status information is board-specific. If not
+ * used by a board, the value zero may be provided in calls to
+ * board_reset().
+ *
+ * Returned Value:
+ * If this function returns, then it was not possible to power-off the
+ * board due to some constraints. The return value int this case is a
+ * board-specific reason for the failure to shutdown.
+ *
+ ****************************************************************************/
+
+int board_reset(int status)
+{
+ up_systemreset();
+ return 0;
+}
+
+#endif /* CONFIG_BOARDCTL_RESET */