This is an automated email from Gerrit.

"Ryan QIAN <jianghao.q...@outlook.com>" just uploaded a new patch set to 
Gerrit, which you can find at https://review.openocd.org/c/openocd/+/7928

-- gerrit

commit 542f78c8fc941cdf0170a664b33e40ee9a034869
Author: Ryan QIAN <jianghao.q...@hpmicro.com>
Date:   Sat Oct 7 18:25:12 2023 +0800

    contrib/loaders/flash/hpmicro: add hpmicro device xpi support
    
    - add xpi flash support for hpmicro devices
    
    Change-Id: Iefad8696282a12ced12b7c98c6fd67cf46bb1b8d
    Signed-off-by: Ryan QIAN <jianghao.q...@hpmicro.com>

diff --git a/contrib/loaders/flash/hpmicro/Makefile 
b/contrib/loaders/flash/hpmicro/Makefile
new file mode 100644
index 0000000000..1b3ea9865d
--- /dev/null
+++ b/contrib/loaders/flash/hpmicro/Makefile
@@ -0,0 +1,51 @@
+# Copyright (c) 2023 HPMicro
+# SPDX-License-Identifier: BSD-3-Clause
+#
+BIN2C = ../../../../src/helper/bin2char.sh
+
+
+PROJECT=hpm_xpi_flash
+CROSS_COMPILE ?= riscv32-unknown-elf-
+CC=$(CROSS_COMPILE)gcc
+AS=$(CROSS_COMPILE)gcc
+OBJCOPY=$(CROSS_COMPILE)objcopy
+OBJDUMP=$(CROSS_COMPILE)objdump
+LD=$(CROSS_COMPILE)ld
+LDSCRIPT=linker.ld
+
+OPT=-O3
+
+ASFLAGS=
+CFLAGS=$(OPT) -fomit-frame-pointer -Wall
+LDFLAGS=-nostartfiles -T$(LDSCRIPT) -Wl,-Map=$(PROJECT).map -static 
-Wl,--gc-sections
+OBJS=$(ASRC:.S=.o) $(SRC:.c=.o)
+
+SRC=openocd_flash_algo.c
+ASRC=func_table.S
+
+all: $(OBJS) $(PROJECT).elf $(PROJECT).bin $(PROJECT).lst $(PROJECT).inc
+
+%o: %c
+       @$(CC) -c $(CFLAGS) -I . $< -o $@
+
+%o: %S
+       @$(AS) -c $(ASFLAGS) -I . $< -o $@
+
+%elf: $(OBJS)
+       @$(CC) $(OBJS) $(LDFLAGS) -o $@
+
+%lst: %elf
+       @$(OBJDUMP) -h -S $< > $@
+
+%bin: %elf
+       @$(OBJCOPY) -Obinary $< $@
+
+%inc: %bin
+       $(BIN2C) < $< > $@
+
+clean:
+       @-rm -f *.o *.elf *.lst *.bin *.inc
+
+.PHONY:        all clean
+
+.INTERMEDIATE: $(patsubst %.S,%.o,$(SRCS)) $(patsubst %.S,%.elf,$(SRCS)) 
$(patsubst %.S,%.bin,$(SRCS))
diff --git a/contrib/loaders/flash/hpmicro/func_table.S 
b/contrib/loaders/flash/hpmicro/func_table.S
new file mode 100644
index 0000000000..66394317b5
--- /dev/null
+++ b/contrib/loaders/flash/hpmicro/func_table.S
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+  .section .func_table, "ax"
+  .global _init
+_init:
+  jal flash_init
+  ebreak
+  jal flash_erase
+  ebreak
+  jal flash_program
+  ebreak
+  jal flash_read
+  ebreak
+  jal flash_get_info
+  ebreak
+  jal flash_erase_chip
+  ebreak
+  jal flash_deinit
+  ebreak
diff --git a/contrib/loaders/flash/hpmicro/hpm_common.h 
b/contrib/loaders/flash/hpmicro/hpm_common.h
new file mode 100644
index 0000000000..805e85499e
--- /dev/null
+++ b/contrib/loaders/flash/hpmicro/hpm_common.h
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2021-2023 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef _HPM_COMMON_H
+#define _HPM_COMMON_H
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+
+/**
+ *
+ * @brief COMMON driver APIs
+ * @defgroup common_interface COMMON driver APIs
+ * @{
+ *
+ */
+
+#define __R volatile const /* Define "read-only" permission */
+#define __RW volatile      /* Define "read-write" permission */
+#define __W volatile       /* Define "write-only" permission */
+
+#ifndef __I
+#define __I __R
+#endif
+
+#ifndef __IO
+#define __IO __RW
+#endif
+
+#ifndef __O
+#define __O __W
+#endif
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(a)   (sizeof(a) / sizeof((a)[0]))
+#endif
+
+#ifndef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+#ifndef MIN
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+#define HPM_BITSMASK(val, offset) ((uint32_t)(val) << (offset))
+#define IS_HPM_BITMASK_SET(val, mask) (((uint32_t)(val) & (uint32_t)(mask)) != 
0U)
+#define IS_HPM_BIT_SET(val, offset) (((uint32_t)(val) & (1UL << (offset))) != 
0U)
+#define IS_HPM_BITMASK_CLR(val, mask) (((uint32_t)(val) & (uint32_t)(mask)) == 
0U)
+#define IS_HPM_BIT_CLR(val, offset) (((uint32_t)(val) & (1UL << (offset))) == 
0U)
+
+#define HPM_BREAK_IF(cond)   if (cond) { break; }
+#define HPM_CONTINUE_IF(cond) if (cond) { continue; }
+
+#define HPM_CHECK_RET(x)               \
+    do {                               \
+        stat = (x);                    \
+        if (status_success != stat) { \
+            return stat;               \
+        }                              \
+    } while (false)
+
+#define SIZE_1KB (1024UL)
+#define SIZE_1MB (1048576UL)
+
+typedef uint32_t hpm_stat_t;
+
+/* @brief Enum definition for the Status group
+ * Rule:
+ *  [Group] 0-999 for the SoC driver and the corresponding components
+ *       1000 or above for the application status group
+ *  [Code]  Valid value: 0-999
+ *
+ */
+#define MAKE_STATUS(group, code) ((uint32_t)(group)*1000U + (uint32_t)(code))
+/* @brief System status group definitions */
+enum {
+    status_group_common = 0,
+    status_group_uart = 1,
+    status_group_i2c = 2,
+    status_group_spi = 3,
+    status_group_usb = 4,
+    status_group_i2s = 5,
+    status_group_xpi = 6,
+    status_group_l1c,
+    status_group_dma,
+    status_group_femc,
+    status_group_sdp,
+    status_group_xpi_nor,
+    status_group_otp,
+    status_group_lcdc,
+    status_group_mbx,
+    status_group_rng,
+    status_group_pdma,
+    status_group_wdg,
+    status_group_pmic_sec,
+    status_group_can,
+    status_group_sdxc,
+    status_group_pcfg,
+    status_group_clk,
+    status_group_pllctl,
+    status_group_pllctlv2,
+    status_group_ffa,
+    status_group_mcan,
+
+    status_group_middleware_start = 500,
+    status_group_sdmmc = status_group_middleware_start,
+    status_group_audio_codec,
+    status_group_dma_manager,
+};
+
+/* @brief Common status code definitions */
+enum {
+    status_success = MAKE_STATUS(status_group_common, 0),
+    status_fail = MAKE_STATUS(status_group_common, 1),
+    status_invalid_argument = MAKE_STATUS(status_group_common, 2),
+    status_timeout = MAKE_STATUS(status_group_common, 3),
+};
+
+#if defined(__GNUC__)
+
+/* alway_inline */
+#define ATTR_ALWAYS_INLINE __attribute__((always_inline))
+
+/* weak */
+#define ATTR_WEAK __attribute__((weak))
+
+/* alignment */
+#define ATTR_ALIGN(alignment) __attribute__((aligned(alignment)))
+
+/* place var_declare at section_name, e.x. PLACE_AT(".target_section", var); */
+#define ATTR_PLACE_AT(section_name) __attribute__((section(section_name)))
+
+#define ATTR_PLACE_AT_WITH_ALIGNMENT(section_name, alignment) \
+ATTR_PLACE_AT(section_name) ATTR_ALIGN(alignment)
+
+#define ATTR_PLACE_AT_NONCACHEABLE ATTR_PLACE_AT(".noncacheable.bss")
+#define ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(alignment) \
+    ATTR_PLACE_AT_NONCACHEABLE ATTR_ALIGN(alignment)
+
+#define ATTR_PLACE_AT_NONCACHEABLE_BSS ATTR_PLACE_AT(".noncacheable.bss")
+#define ATTR_PLACE_AT_NONCACHEABLE_BSS_WITH_ALIGNMENT(alignment) \
+    ATTR_PLACE_AT_NONCACHEABLE_BSS ATTR_ALIGN(alignment)
+
+/* initialize variable x with y using PLACE_AT_NONCACHEABLE_INIT(x) = {y}; */
+#define ATTR_PLACE_AT_NONCACHEABLE_INIT ATTR_PLACE_AT(".noncacheable.init")
+#define ATTR_PLACE_AT_NONCACHEABLE_INIT_WITH_ALIGNMENT(alignment) \
+    ATTR_PLACE_AT_NONCACHEABLE_INIT ATTR_ALIGN(alignment)
+
+#define ATTR_RAMFUNC ATTR_PLACE_AT(".fast")
+#define ATTR_RAMFUNC_WITH_ALIGNMENT(alignment) \
+    ATTR_RAMFUNC ATTR_ALIGN(alignment)
+
+#define ATTR_SHARE_MEM ATTR_PLACE_AT(".sh_mem")
+
+#define NOP() __asm volatile("nop")
+#define WFI() __asm volatile("wfi")
+
+#define HPM_ATTR_MACHINE_INTERRUPT __attribute__ ((section(".isr_vector"), 
interrupt("machine"), aligned(4)))
+
+#elif defined(__ICCRISCV__)
+
+
+      /* alway_inline */
+#define ATTR_ALWAYS_INLINE __attribute__((always_inline))
+
+/* weak */
+#define ATTR_WEAK __weak
+
+/* alignment */
+#define ATTR_ALIGN(alignment) __attribute__((aligned(alignment)))
+
+/* place var_declare at section_name, e.x. PLACE_AT(".target_section", var); */
+#define ATTR_PLACE_AT(section_name) __attribute__((section(section_name)))
+
+#define ATTR_PLACE_AT_WITH_ALIGNMENT(section_name, alignment) \
+ATTR_PLACE_AT(section_name) ATTR_ALIGN(alignment)
+
+#define ATTR_PLACE_AT_NONCACHEABLE ATTR_PLACE_AT(".noncacheable.bss")
+#define ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(alignment) \
+    ATTR_PLACE_AT_NONCACHEABLE ATTR_ALIGN(alignment)
+
+#define ATTR_PLACE_AT_NONCACHEABLE_BSS ATTR_PLACE_AT(".noncacheable.bss")
+#define ATTR_PLACE_AT_NONCACHEABLE_BSS_WITH_ALIGNMENT(alignment) \
+    ATTR_PLACE_AT_NONCACHEABLE_BSS ATTR_ALIGN(alignment)
+
+/* initialize variable x with y using PLACE_AT_NONCACHEABLE_INIT(x) = {y}; */
+#define ATTR_PLACE_AT_NONCACHEABLE_INIT ATTR_PLACE_AT(".noncacheable.init")
+#define ATTR_PLACE_AT_NONCACHEABLE_INIT_WITH_ALIGNMENT(alignment) \
+    ATTR_PLACE_AT_NONCACHEABLE_INIT ATTR_ALIGN(alignment)
+
+#define ATTR_RAMFUNC ATTR_PLACE_AT(".fast")
+#define ATTR_RAMFUNC_WITH_ALIGNMENT(alignment) \
+    ATTR_RAMFUNC ATTR_ALIGN(alignment)
+
+#define ATTR_SHARE_MEM ATTR_PLACE_AT(".sh_mem")
+
+#define NOP() __asm volatile("nop")
+#define WFI() __asm volatile("wfi")
+
+#define HPM_ATTR_MACHINE_INTERRUPT __machine __interrupt
+
+#else
+#error Unknown toolchain
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief   Count bits set to 1
+ *
+ * @param value Data to be counted
+ *
+ * @return number of bits set to 1
+ */
+static inline uint32_t count_set_bits(uint32_t value)
+{
+    if (value == 0) {
+        return 0;
+    }
+    return 1 + count_set_bits(value & (value - 1));
+}
+
+/**
+ * @brief   Count bits set to 1 from least significant bit
+ *
+ * @param value Data to be counted
+ *
+ * @return number of bits set to 1
+ * @return 0xFFFFFFFF if no bit was set to 1
+ */
+static inline uint32_t get_first_set_bit_from_lsb(uint32_t value)
+{
+    uint32_t i = 0;
+    if (!value) {
+        return 0xFFFFFFFFUL;
+    }
+    while (value && !(value & 0x1)) {
+        value >>= 1;
+        i++;
+    }
+    return i;
+}
+
+/**
+ * @brief   Count bits set to 1 from most significant bit
+ *
+ * @param value Data to be counted
+ *
+ * @return number of bits set to 1
+ * @return 0xFFFFFFFF if no bit was set to 1
+ */
+static inline uint32_t get_first_set_bit_from_msb(uint32_t value)
+{
+    uint32_t i = 31;
+    if (!value) {
+        return 0xFFFFFFFFUL;
+    }
+    while (value && !(value & 0x80000000)) {
+        value <<= 1;
+        value &= ~1;
+        i--;
+    }
+    return i;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}
+ */
+#endif /* _HPM_COMMON_H */
diff --git a/contrib/loaders/flash/hpmicro/hpm_romapi.h 
b/contrib/loaders/flash/hpmicro/hpm_romapi.h
new file mode 100644
index 0000000000..b8f12eec7a
--- /dev/null
+++ b/contrib/loaders/flash/hpmicro/hpm_romapi.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2021-2023 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef HPM_ROMAPI_H
+#define HPM_ROMAPI_H
+
+/**
+ * @brief ROM APIs
+ * @defgroup romapi_interface ROM APIs
+ * @{
+ */
+
+#include "hpm_common.h"
+#include "hpm_romapi_xpi_def.h"
+#include "hpm_romapi_xpi_soc_def.h"
+#include "hpm_romapi_xpi_nor_def.h"
+
+/* XPI0 base address */
+#define HPM_XPI0_BASE (0xF3040000UL)                /**< XPI0 Base address */
+/* XPI0 base pointer */
+#define HPM_XPI0 ((XPI_Type *) HPM_XPI0_BASE)       /**< XPI0 Base pointer */
+/* XPI1 base address */
+#define HPM_XPI1_BASE (0xF3044000UL)                /**< XPI1 Base address */
+/* XPI1 base pointer */
+#define HPM_XPI1 ((XPI_Type *) HPM_XPI1_BASE)       /**< XPI1 Base pointer */
+
+
+/***********************************************************************************************************************
+ *
+ *
+ *      Definitions
+ *
+ *
+ 
**********************************************************************************************************************/
+
+
+/**
+ * @brief XPI driver interface
+ */
+typedef struct {
+    /**< XPI driver interface: version */
+    uint32_t version;
+    /**< XPI driver interface: get default configuration */
+    hpm_stat_t (*get_default_config)(xpi_config_t *xpi_config);
+    /**< XPI driver interface: get default device configuration */
+    hpm_stat_t (*get_default_device_config)(xpi_device_config_t *dev_config);
+    /**< XPI driver interface: initialize the XPI using xpi_config */
+    hpm_stat_t (*init)(XPI_Type *base, xpi_config_t *xpi_config);
+    /**< XPI driver interface: configure the AHB buffer */
+    hpm_stat_t (*config_ahb_buffer)(XPI_Type *base, xpi_ahb_buffer_cfg_t 
*ahb_buf_cfg);
+    /**< XPI driver interface: configure the device */
+    hpm_stat_t (*config_device)(XPI_Type *base, xpi_device_config_t *dev_cfg, 
xpi_channel_t channel);
+    /**< XPI driver interface: update instruction talbe */
+    hpm_stat_t (*update_instr_table)(XPI_Type *base, const uint32_t 
*inst_base, uint32_t seq_idx, uint32_t num);
+    /**< XPI driver interface: transfer command/data using block interface */
+    hpm_stat_t (*transfer_blocking)(XPI_Type *base, xpi_xfer_ctx_t *xfer);
+    /**< Software reset the XPI controller */
+    void (*software_reset)(XPI_Type *base);
+    /**< XPI driver interface: Check whether IP is idle */
+    bool (*is_idle)(XPI_Type *base);
+    /**< XPI driver interface: update delay line setting */
+    void (*update_dllcr)(XPI_Type *base, uint32_t serial_root_clk_freq, 
uint32_t data_valid_time, xpi_channel_t channel,
+                         uint32_t dly_target);
+    /**< XPI driver interface: Get absolute address for APB transfer */
+    hpm_stat_t (*get_abs_apb_xfer_addr)(XPI_Type *base, xpi_xfer_channel_t 
channel, uint32_t in_addr,
+                                        uint32_t *out_addr);
+} xpi_driver_interface_t;
+
+/**
+ * @brief XPI NOR driver interface
+ */
+typedef struct {
+    /**< XPI NOR driver interface: API version */
+    uint32_t version;
+    /**< XPI NOR driver interface: Get FLASH configuration */
+    hpm_stat_t (*get_config)(XPI_Type *base, xpi_nor_config_t *nor_cfg, 
xpi_nor_config_option_t *cfg_option);
+    /**< XPI NOR driver interface: initialize FLASH */
+    hpm_stat_t (*init)(XPI_Type *base, xpi_nor_config_t *nor_config);
+    /**< XPI NOR driver interface: Enable write access to FLASH */
+    hpm_stat_t (*enable_write)(XPI_Type *base, xpi_xfer_channel_t channel, 
const xpi_nor_config_t *nor_config,
+                               uint32_t addr);
+    /**< XPI NOR driver interface: Get FLASH status register */
+    hpm_stat_t (*get_status)(XPI_Type *base, xpi_xfer_channel_t channel, const 
xpi_nor_config_t *nor_config,
+                             uint32_t addr,
+                             uint16_t *out_status);
+    /**< XPI NOR driver interface: Wait when FLASH is still busy */
+    hpm_stat_t (*wait_busy)(XPI_Type *base, xpi_xfer_channel_t channel, const 
xpi_nor_config_t *nor_config,
+                            uint32_t addr);
+    /**< XPI NOR driver interface: erase a specified FLASH region */
+    hpm_stat_t (*erase)(XPI_Type *base, xpi_xfer_channel_t channel, const 
xpi_nor_config_t *nor_config, uint32_t start,
+                        uint32_t length);
+    /**< XPI NOR driver interface: Erase the whole FLASH */
+    hpm_stat_t (*erase_chip)(XPI_Type *base, xpi_xfer_channel_t channel, const 
xpi_nor_config_t *nor_config);
+    /**< XPI NOR driver interface: Erase specified FLASH sector */
+    hpm_stat_t (*erase_sector)(XPI_Type *base, xpi_xfer_channel_t channel, 
const xpi_nor_config_t *nor_config,
+                               uint32_t addr);
+    /**< XPI NOR driver interface: Erase specified FLASH block */
+    hpm_stat_t (*erase_block)(XPI_Type *base, xpi_xfer_channel_t channel, 
const xpi_nor_config_t *nor_config,
+                              uint32_t addr);
+    /**< XPI NOR driver interface: Program data to specified FLASH address */
+    hpm_stat_t (*program)(XPI_Type *base, xpi_xfer_channel_t channel, const 
xpi_nor_config_t *nor_config,
+                          const uint32_t *src,
+                          uint32_t dst_addr, uint32_t length);
+    /**< XPI NOR driver interface: read data from specified FLASH address */
+    hpm_stat_t (*read)(XPI_Type *base, xpi_xfer_channel_t channel, const 
xpi_nor_config_t *nor_config, uint32_t *dst,
+                       uint32_t start, uint32_t length);
+    /**< XPI NOR driver interface: program FLASH page using nonblocking 
interface */
+    hpm_stat_t (*page_program_nonblocking)(XPI_Type *base, xpi_xfer_channel_t 
channel,
+                                           const xpi_nor_config_t *nor_config,
+                                           const uint32_t *src, uint32_t 
dst_addr, uint32_t length);
+    /**< XPI NOR driver interface: erase FLASH sector using nonblocking 
interface */
+    hpm_stat_t (*erase_sector_nonblocking)(XPI_Type *base, xpi_xfer_channel_t 
channel,
+                                           const xpi_nor_config_t *nor_config,
+                                           uint32_t addr);
+    /**< XPI NOR driver interface: erase FLASH block using nonblocking 
interface */
+    hpm_stat_t (*erase_block_nonblocking)(XPI_Type *base, xpi_xfer_channel_t 
channel,
+                                          const xpi_nor_config_t *nor_config,
+                                          uint32_t addr);
+    /**< XPI NOR driver interface: erase the whole FLASh using nonblocking 
interface */
+    hpm_stat_t (*erase_chip_nonblocking)(XPI_Type *base, xpi_xfer_channel_t 
channel,
+                                         const xpi_nor_config_t *nor_config);
+
+    uint32_t reserved0[3];
+
+    /**< XPI NOR driver interface: automatically configuration flash based on 
the cfg_option setting */
+    hpm_stat_t (*auto_config)(XPI_Type *base, xpi_nor_config_t *nor_cfg, 
xpi_nor_config_option_t *cfg_option);
+
+    /**< XPI NOR driver interface: Get FLASH properties */
+    hpm_stat_t (*get_property)(XPI_Type *base, xpi_nor_config_t *nor_cfg, 
uint32_t property_id, uint32_t *value);
+
+} xpi_nor_driver_interface_t;
+
+
+
+/**
+ * @brief Bootloader API table
+ */
+typedef struct {
+    /**< Bootloader API table: version */
+    const uint32_t version;
+    /**< Bootloader API table: copyright string address */
+    const char *copyright;
+    /**< Bootloader API table: run_bootloader API */
+    const uint32_t reserved0;
+    /**< Bootloader API table: otp driver interface address */
+    const uint32_t reserved1;
+    /**< Bootloader API table: xpi driver interface address */
+    const xpi_driver_interface_t *xpi_driver_if;
+    /**< Bootloader API table: xpi nor driver interface address */
+    const xpi_nor_driver_interface_t *xpi_nor_driver_if;
+    /**< Bootloader API table: xpi ram driver interface address */
+    const uint32_t reserved2;
+} bootloader_api_table_t;
+
+/**< Bootloader API table Root */
+#define ROM_API_TABLE_ROOT ((const bootloader_api_table_t *)0x2001FF00U)
+
+
+
+#endif /* HPM_ROMAPI_H */
diff --git a/contrib/loaders/flash/hpmicro/hpm_romapi_xpi_def.h 
b/contrib/loaders/flash/hpmicro/hpm_romapi_xpi_def.h
new file mode 100644
index 0000000000..6b9cbeb554
--- /dev/null
+++ b/contrib/loaders/flash/hpmicro/hpm_romapi_xpi_def.h
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2021 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#ifndef HPM_ROMAPI_XPI_DEF_H
+#define HPM_ROMAPI_XPI_DEF_H
+
+/**
+ * @brief XPI ROM APIs
+ * @defgroup xpi_interface XPI driver APIs
+ * @{
+ */
+
+#include "hpm_common.h"
+
+/**
+ *  @brief XPI_Type definitions for
+ *  @note For compatibility
+ */
+typedef uint32_t XPI_Type;
+
+/**
+ * @brief XPI Read Sample Clock source options
+ */
+typedef enum {
+    xpi_rxclksrc_internal_loopback = 0, /**< Internal loopback */
+    xpi_rxclksrc_dqs_loopback = 1,      /**< Loopback from DQS pad */
+    xpi_rxclksrc_external_dqs = 3,      /**< Read is driven by External DQS 
pad */
+} xpi_rxclksrc_type_t;
+
+
+/**
+ * @brief XPI pad definitions
+ */
+#define XPI_1PAD    (0U)    /**< Single pad */
+#define XPI_2PADS   (1U)    /**< Dual pads */
+#define XPI_4PADS   (2U)    /**< Quad pads */
+#define XPI_8PADS   (3U)    /**< Octal pads */
+
+/**
+ * @brief XPI IO pin group options
+ */
+typedef enum {
+    xpi_io_1st_group,       /**< First/Primary group */
+    xpi_io_2nd_group,       /**< Second/Secondary group */
+} xpi_io_group_t;
+
+/**
+ * @brief XPI Transfer Channel type definitions
+ */
+typedef enum {
+    xpi_xfer_channel_a1,                    /**< The address is based on the 
device connected to Channel A1 */
+    xpi_xfer_channel_a2,                    /**< The address is based on the 
device connected to Channel A2 */
+    xpi_xfer_channel_b1,                    /**< The address is based on the 
device connected to Channel B1 */
+    xpi_xfer_channel_b2,                    /**< The address is based on the 
device connected to Channel B2 */
+    xpi_xfer_channel_auto,                  /**< The channel is auto 
determined */
+} xpi_xfer_channel_t;
+
+/**
+ * @brief XPI Channel defitions
+ */
+typedef enum {
+    xpi_channel_a1,        /**< Port:  Channel A1 */
+    xpi_channel_a2,        /**< Port:  Channel A2 */
+    xpi_channel_b1,        /**< Port:  Channel B1 */
+    xpi_channel_b2,        /**< Port:  Channel B2 */
+} xpi_channel_t;
+
+/**
+ * @brief XPI APB Transfer type
+ */
+typedef enum {
+    xpi_apb_xfer_type_cmd,          /**< APB Command Type: Command only */
+    xpi_apb_xfer_type_config,       /**< APB Command Type: Configuration */
+    xpi_apb_xfer_type_read,         /**< APB Command Type: Read */
+    xpi_apb_xfer_type_write,        /**< APB Command Type: Write */
+} xpi_apb_xfer_type_t;
+
+/**
+ * @brief XPI Xfer Mode
+ */
+typedef enum {
+    xpi_xfer_mode_polling,      /**< Transfer mode: Polling */
+    xpi_xfer_mode_dma,          /**< Transfer mode: DMA */
+    xpi_xfer_mode_interrupt,    /**< Transfer mode: Interrupt */
+} xpi_xfer_mode_t;
+
+/**
+ * @brief XPI Xfer context
+ */
+typedef struct {
+    uint32_t addr;          /**< device address for XPI transfer */
+    uint8_t channel;           /**< channel for XPI transfer */
+    uint8_t cmd_type;       /**< command type for XPI transfer */
+    uint8_t seq_idx;        /**< Sequence index for XPI transfer */
+    uint8_t seq_num;        /**< Sequence number for XPI transfer */
+    uint32_t *buf;          /**< Buffer for XPI transfer */
+    uint32_t xfer_size;     /**< Transfer size in bytes */
+} xpi_xfer_ctx_t;
+
+/**
+ * @brief XPI instruction sequence
+ */
+typedef struct {
+    uint32_t entry[4];
+} xpi_instr_seq_t;
+
+/**
+ * @brief XPI Phase definitions
+ */
+#define XPI_PHASE_STOP            (0x00U)   /**< Phase: Stop */
+#define XPI_PHASE_CMD_SDR         (0x01U)   /**< Phase: Send CMD in SDR mode */
+#define XPI_PHASE_RADDR_SDR       (0x02U)   /**< Phase: Send Row Address in 
SDR Mode */
+#define XPI_PHASE_CADDR_SDR       (0x03U)   /**< Phase: Send Column Address in 
SDR Mode */
+#define XPI_PHASE_MODE4_SDR       (0x06U)   /**< Phase: Send Mode 4 in SDR 
Mode */
+#define XPI_PHASE_MODE8_SDR       (0x07U)   /**< Phase: Send Mode 8 in SDR 
Mode */
+#define XPI_PHASE_WRITE_SDR       (0x08U)   /**< Phase: Write data in SDR Mode 
*/
+#define XPI_PHASE_READ_SDR        (0x09U)   /**< Phase: Read data in SDR Mode 
*/
+#define XPI_PHASE_DUMMY_SDR       (0X0CU)   /**< Phase: Send Dummy in SDR Mode 
*/
+#define XPI_PHASE_DUMMY_RWDS_SDR  (0x0DU)   /**< Phase: Send Dummy RWDS  in 
SDR Mode */
+
+#define XPI_PHASE_CMD_DDR         (0x21U)   /**< Phase: Send CMD in DDR Mode */
+#define XPI_PHASE_RADDR_DDR       (0x22U)   /**< Phase: Send Raw Address in 
DDR Mode */
+#define XPI_PHASE_CADDR_DDR       (0x23U)   /**< Phase: Send Column address in 
DDR Mode */
+#define XPI_PHASE_MODE4_DDR       (0x26U)   /**< Phase: Send Mode 4 in DDR 
Mode */
+#define XPI_PHASE_MODE8_DDR       (0x27U)   /**< Phase: Send Mode 8 in DDR 
Mode */
+#define XPI_PHASE_WRITE_DDR       (0x28U)   /**< Phase: Write data in DDR Mode 
*/
+#define XPI_PHASE_READ_DDR        (0x29U)   /**< Phase: Read data in SDR Mode 
*/
+#define XPI_PHASE_DUMMY_DDR       (0x2CU)   /**< Phase: Send DUMMY in DDR Mode 
*/
+#define XPI_PHASE_DUMMY_RWDS_DDR  (0x2DU)   /**< Phase: Send DUMMY RWDS in DDR 
Mode */
+
+/**
+ * @brief XPI API command error codes
+ */
+enum {
+    status_xpi_apb_jump_on_cs = MAKE_STATUS(status_group_xpi, 1),
+    status_xpi_apb_unknown_inst = MAKE_STATUS(status_group_xpi, 2),
+    status_xpi_apb_dummy_sdr_in_ddr_seq = MAKE_STATUS(status_group_xpi, 3),
+    status_xpi_apb_dummy_ddr_in_sdr_seq = MAKE_STATUS(status_group_xpi, 4),
+    status_xpi_apb_exceed_addr_range = MAKE_STATUS(status_group_xpi, 5),
+    status_xpi_apb_seq_timeout = MAKE_STATUS(status_group_xpi, 6),
+    status_xpi_apb_cross_boundary = MAKE_STATUS(status_group_xpi, 7),
+};
+
+/**
+ * @brief Delay line definitions
+ */
+enum {
+    xpi_dll_half_cycle = 0xFU,
+    xpi_dll_quarter_cycle = 0x7U,
+    xpi_dll_sdr_default_cycle = xpi_dll_half_cycle,
+    xpi_dll_ddr_default_cycle = xpi_dll_quarter_cycle,
+};
+
+/**
+ * @brief XPI configuration structure
+ */
+typedef struct {
+    uint8_t rxclk_src;                      /**< Read sample clock source */
+    uint8_t reserved0[7];                   /**< Reserved */
+    uint8_t tx_watermark_in_dwords;         /**< Tx watermark in double words 
*/
+    uint8_t rx_watermark_in_dwords;         /**< Rx watermark in double words 
*/
+    uint8_t enable_differential_clk;        /**< Enable differential clock */
+    uint8_t reserved1[5];                   /**< Reserved */
+    uint32_t access_flags;                  /**< Access flags */
+} xpi_config_t;
+
+/**
+ * @brief XPI Device Configuration structure
+ */
+typedef struct {
+    uint32_t size_in_kbytes;                /**< Device size in kbytes */
+    uint32_t serial_root_clk_freq;          /**< XPI serial root clock 
frequency */
+
+    uint8_t enable_write_mask;              /**< Enable write mask, typically 
for PSRAM/HyperRAM */
+    uint8_t data_valid_time;                /**< Data valid time, Unit 0.1ns */
+    uint8_t reserved0[2];
+
+    uint8_t cs_hold_time;                   /**< CS hold time, cycles in terms 
of FLASH clock */
+    uint8_t cs_setup_time;                  /**< CS setup time, cycles in 
terms of FLASH clock */
+    uint16_t cs_interval;                   /**< CS interval, cycles in terms 
of FLASH clock */
+
+    uint8_t reserved1;
+    uint8_t column_addr_size;               /**< Column address bits */
+    uint8_t enable_word_address;            /**< Enable word address, for 
HyperFLASH/HyperRAM */
+    uint8_t dly_target;                     /**< Delay target */
+
+    uint8_t ahb_write_seq_idx;              /**< AHB write sequence index */
+    uint8_t ahb_write_seq_num;              /**< AHB write sequence number */
+    uint8_t ahb_read_seq_idx;               /**< AHB read sequence index */
+    uint8_t ahb_read_seq_num;               /**< AHB read sequence number */
+
+    uint8_t ahb_write_wait_interval;        /**< AHB write wait interval, in 
terms of FLASH clock */
+    uint8_t reserved2[3];
+} xpi_device_config_t;
+
+/**
+ * @brief SUB Instruction
+ * @param [in] phase Phase
+ * @param [in] pad  Pad for Phase
+ * @param [in] op   Operand for Phase
+ */
+#define SUB_INSTR(phase, pad, op) ((uint32_t)(((uint16_t)(phase) << 10) | 
((uint16_t)(pad) << 8) | ((uint16_t)(op))))
+/**
+ * @brief Generate a single word INSTRUCTION sequence word
+ * @note  Here intentionally use the MACRO because when the arguments are 
constant value, the compiler
+ *        can generate the const entry word during pre-processing
+ */
+#define XPI_INSTR_SEQ(phase0, pad0, op0, phase1, pad1, op1) (SUB_INSTR(phase0, 
pad0, op0) | (SUB_INSTR(phase1, pad1, op1)<<16))
+
+
+/**
+ * @}
+ */
+
+#endif /* HPM_ROMAPI_XPI_DEF_H */
diff --git a/contrib/loaders/flash/hpmicro/hpm_romapi_xpi_nor_def.h 
b/contrib/loaders/flash/hpmicro/hpm_romapi_xpi_nor_def.h
new file mode 100644
index 0000000000..dd5e63319f
--- /dev/null
+++ b/contrib/loaders/flash/hpmicro/hpm_romapi_xpi_nor_def.h
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 2021 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#ifndef HPM_ROMAPI_XPI_NOR_DEF_H
+#define HPM_ROMAPI_XPI_NOR_DEF_H
+
+/**
+ * @brief XPI NOR ROM APIs
+ * @defgroup xpi_nor_interface XPI NOR driver APIs
+ * @ingroup romapi_interfaces
+ * @{
+ */
+
+
+#include "hpm_common.h"
+#include "hpm_romapi_xpi_def.h"
+
+#define XPI_NOR_CFG_TAG 0x524f4E58U /**< ASCII: "XNOR" */
+
+/**
+ * @brief XPI NOR properties
+ */
+enum {
+    xpi_nor_property_total_size,                            /**< Total size in 
bytes */
+    xpi_nor_property_page_size,                             /**< Page size in 
bytes */
+    xpi_nor_property_sector_size,                           /**<sector size in 
bytes */
+    xpi_nor_property_block_size,                            /**< block size in 
bytes */
+    xpi_nor_property_max = xpi_nor_property_block_size,
+};
+
+
+/**
+ * @brief XPI NOR safe frequency option
+ */
+enum {
+    xpi_nor_clk_safe_clk_freq = 1,
+};
+
+/**
+ * @brief XPI NOR miscellaneous options
+ */
+enum {
+    xpi_nor_option_misc_spi_only = 1,           /**< SPI only */
+    xpi_nor_option_misc_internal_loopback = 2,  /**< Internal loopback mode */
+    xpi_nor_option_misc_ext_dqs = 3,            /**< External DQS pin */
+};
+
+/**
+ * @brief XPI NOR connection option
+ */
+enum {
+    xpi_nor_connection_sel_chna_cs0,               /**< Channel A, CS0 */
+    xpi_nor_connection_sel_chnb_cs0,               /**< Channel B, CS0 */
+    xpi_nor_connection_sel_chna_cs0_chnb_cs0,     /**< Channel A + Channel B, 
CS0 */
+    xpi_nor_connection_sel_chna_cs0_cs1,           /**< Channel A, CS0 + CS1 */
+    xpi_nor_connection_sel_chnb_cs0_cs1            /**< Channel B, CS0 + CS1 */
+};
+
+/**
+ * @brief QE bit enable sequence option
+ */
+typedef enum {
+    xpi_nor_quad_en_auto_or_ignore = 0U,                        /**< Auto 
enable or ignore */
+    xpi_nor_quad_en_set_bit6_in_status_reg1 = 1U,               /**< QE bit is 
at bit6 in Status register 1 */
+    xpi_nor_quad_en_set_bit1_in_status_reg2 = 2U,               /**< QE bit is 
at bit1 in Status register 2 register 2 */
+    xpi_nor_quad_en_set_bit7_in_status_reg2 = 3U,               /**< QE bit is 
at bit7 in Status register 2 */
+    xpi_nor_quad_en_set_bi1_in_status_reg2_via_0x31_cmd = 4U,   /**< QE bit is 
in status register 2 and configured by CMD 0x31 */
+} xpi_nor_quad_enable_seq_t;
+
+/**
+ * @brief XPI working mode
+ */
+typedef enum {
+    xpi_working_mode_extend_spi,    /**< XPI works in extended SPI mode, 
including 1-1-1, 1-2-2, 1-4-4, 1-8-8 */
+    xpi_working_mode_xpi,           /**< XPI works in XPI mode, including, 
1-1-1, 2-2-2, 4-4-4, 8-8-8 */
+    xpi_working_mode_hyperbus,      /**< XPI works in HyperBus mode */
+} xpi_working_mode_t;
+
+
+/**
+ * @brief XPI NOR configuration command type
+ */
+typedef enum {
+    xpi_nor_cfg_cmd_type_no_cfg = 0U,   /**< No configuration */
+    xpi_nor_cfg_cmd_type_generic = 1U,  /**< Generic configuration */
+    xpi_nor_cfg_cmd_type_spi2xpi = 2U,  /**< SPI to XPI mode */
+    xpi_nor_cfg_cmd_type_xpi2spi = 3U,  /**< XPI to SPI mode */
+} xpi_nor_cfg_cmd_type_t;
+
+/**
+ * @brief XPI NOR probe options
+ */
+typedef enum {
+    xpi_nor_probe_sfdp_sdr = 0U,    /**< Probe FLASH using SFDP and set FLASH 
to SDR mode */
+    xpi_nor_probe_sfdp_ddr = 1U,    /**< Probe FLASH using SDP and set FLASH 
to DDR mode */
+    xpi_nor_quad_read_0xeb = 2U,    /**< Set FLASH to default Quad I/O read in 
SDR mode */
+    xpi_nor_dual_read_0xbb = 3U,    /**< Set FLASH to default Dual I/O read in 
SDR mode */
+    xpi_nor_hyperbus_1v8 = 4U,      /**< Probe FLASH using HyperBus in 1.8V 
voltage */
+    xpi_nor_hyperbus_3v0 = 5U,      /**< Probe FLASH using HyperBus in 3.0V 
voltage */
+    xpi_nor_octabus_ddr = 6U,       /**< Probe FLASH using Macronix OctaBus 
and configure FLASH to OPI DDR mode */
+    xpi_nor_octabus_sdr = 7U,       /**< Probe FLASH using Macronix OctaBus 
and configure FLASH to OPI SDR mode */
+    xpi_nor_xccela_ddr = 8U,        /**< Probe FLASH using Xccela Protocol and 
configure FLASH to OPI DDR mode */
+    xpi_nor_xccela_sdr = 9U,        /**< Probe FLASH using Xccela Protocol and 
configure FLASH to SDR mode */
+    xpi_nor_ecoxip_ddr = 10U,       /**< Probe FLASH using EcoXiP Protocol and 
configure FLASH to OPI DDR mode */
+    xpi_nor_ecoxip_sdr = 11U,       /**< Probe FLASH using EcoXiP Protocol and 
configure FLASH to SDR mode */
+} xpi_nor_probe_t;
+
+/**
+ * @brief Standard XPI NOR seuqnce index definitions
+ */
+typedef enum {
+    xpi_std_nor_seq_idx_read = 0U,                     /**< 0 - Read */
+    xpi_std_nor_seq_idx_page_program = 1U,             /**< 1 - Page Program */
+    xpi_std_nor_seq_idx_read_status = 2U,              /**< 2 - Read Status */
+    xpi_std_nor_seq_idx_read_status_xpi = 3U,          /**< 3 - Read Status in 
xSPI mode */
+    xpi_std_nor_seq_idx_write_enable = 4U,             /**< 4 - Write Enable */
+    xpi_std_nor_seq_idx_write_enable_xpi = 5U,         /**< 5 - Write Enable 
in xSPI mode */
+    xpi_std_nor_seq_idx_erase_sector = 6U,             /**< 6 - Erase sector */
+    xpi_std_nor_seq_idx_erase_block = 7U,              /**< 7 - Erase block */
+    xpi_std_nor_seq_idx_erase_chip = 8U,               /**< 8 - Erase full 
chip */
+    xpi_std_nor_seq_idx_max = 9,                       /**< 9 */
+} xpi_std_nor_instr_idx_t;
+
+/**
+ * @brief XPI NOR option tag
+ */
+#define XPI_NOR_CFG_OPTION_TAG (0xfcf90U)
+
+/**
+ * @brief XPI NOR configuration option
+ *        The ROM SW can detect the FLASH configuration based on the following 
structure specified by the end-user
+ */
+typedef struct {
+    union {
+        struct {
+            uint32_t words: 4;       /**< Option words, exclude the header 
itself */
+            uint32_t reserved: 8;    /**< Reserved for future use */
+            uint32_t tag: 20;        /**< Must be 0xfcf90 */
+        };
+        uint32_t U;
+    } header;
+    union {
+        struct {
+            uint32_t freq_opt: 4;                /**< 1 - 30MHz, others, SoC 
specific setting */
+            uint32_t misc: 4;                    /**< Not used for now */
+            uint32_t dummy_cycles: 8;            /**< 0 - Auto detected/ use 
predefined value, others - specified by end-user */
+            uint32_t quad_enable_seq: 4;         /**< See the 
xpi_nor_quad_enable_seq_t definitions for more details */
+            uint32_t cmd_pads_after_init: 4;     /**< See the xpi_data_pad_t 
definitions for more details */
+            uint32_t cmd_pads_after_por: 4;      /**< See the xpi_data_pad_t 
definitions for more details */
+            uint32_t probe_type: 4;              /**< See the xpi_nor_probe_t 
definitions for more details */
+        };
+        uint32_t U;
+    } option0;
+    union {
+        struct {
+            uint32_t drive_strength: 8;      /**< IO drive strength, 0 - 
pre-defined, Others - specified by end-user */
+            uint32_t connection_sel: 4;      /**< Device connection selection: 
0 - PORTA, 1 - PORTB, 2 - Parallel mode */
+            uint32_t pin_group_sel: 4;       /**< Pin group selection, 0 - 1st 
group, 1 - 2nd group, by default, the pin group is 1st group */
+            uint32_t io_voltage: 4;          /**< SoC pad voltage, 0 - 3.0V, 
1-1.8V */
+            uint32_t reserved: 12;           /**< Reserved for future use */
+        };
+        uint32_t U;
+    } option1;
+    union {
+        struct {
+            uint32_t flash_size_option:8;               /**< FLASH size option 
*/
+            uint32_t flash_sector_size_option:4;        /**< FLASH sector size 
option */
+            uint32_t flash_sector_erase_cmd_option:4;   /**< Sector Erase 
command option */
+            uint32_t reserved:20;
+        };
+        uint32_t U;
+    } option2;
+} xpi_nor_config_option_t;
+
+/**
+ * @brief Sector size options
+ */
+enum {
+    serial_nor_sector_size_4kb,     /**< Sector size: 4KB */
+    serial_nor_sector_size_32kb,    /**< Sector size: 32KB */
+    serial_nor_sector_size_64kb,    /**< Sector size: 64KB */
+    serial_nor_sector_size_256kb,   /**< Sector size: 256KB */
+};
+
+/**
+ * @brief Sector erase command options
+ */
+enum  {
+    serial_nor_erase_type_4kb,      /**< Sector erase command: 4KB Erase */
+    serial_nor_erase_type_32kb,     /**< Sector erase command: 32KB Erase */
+    serial_nor_erase_type_64kb,     /**< Sector erase command: 64KB Erase */
+    serial_nor_erase_type_256kb,    /**< Sector erase command: 256KB Erase */
+};
+
+/**
+ * @brief FLASH size options
+ */
+enum {
+    flash_size_4mb,     /**< FLASH size: 4MB */
+    flash_size_8mb,     /**< FLASH size: 8MB */
+    flash_size_16mb,    /**< FLASH size: 16MB */
+};
+
+/**
+ * @brief Device Mode confiuration structure
+ */
+typedef struct {
+    uint8_t cfg_cmd_type;       /**< Configuration command type */
+    uint8_t param_size;         /**< Size for parameter */
+} device_mode_cfg_t;
+
+/**
+ * @brief Device mode parameter structure
+ */
+typedef struct {
+    uint32_t instr_seq[4];  /**< Command Instruction sequence*/
+    uint32_t param;         /**< Parameter */
+} device_mode_param_t;
+
+/**
+ * @brief XPI NOR device information structure
+ */
+typedef struct {
+    uint32_t size_in_kbytes;                /**< Device Size in Kilobytes, 
offset 0x00 */
+    uint16_t page_size;                     /**< Page size, offset 0x04 */
+    uint16_t sector_size_kbytes;            /**< Sector size in kilobytes, 
offset 0x06 */
+    uint16_t block_size_kbytes;             /**< Block size in kilobytes, 
offset 0x08 */
+    uint8_t busy_offset;                    /**< Busy offset, offset 0x0a */
+    uint8_t busy_polarity;                  /**< Busy polarity, offset 0x0b */
+    uint8_t data_pads;                      /**< Device Size in Kilobytes, 
offset 0x0c */
+    uint8_t en_ddr_mode;                    /**< Enable DDR mode, offset 0x0d 
*/
+    uint8_t clk_freq_for_device_cfg;        /**< Clk frequency for device 
configuration offset 0x0e */
+    uint8_t working_mode_por;               /**< Working mode after POR reset 
offset 0x0f */
+    uint8_t working_mode;                   /**< The device working mode, 
offset 0x10 */
+    uint8_t en_diff_clk;                    /**< Enable Differential clock, 
offset 0x11 */
+    uint8_t data_valid_time;                /**< Data valid time, in 0.1ns, 
offset 0x12 */
+    uint8_t en_half_clk_for_non_read_cmd;   /**< Enable half clock for 
non-read command, offset 0x13 */
+    uint8_t clk_freq_for_non_read_cmd;      /**< Enable safe clock for 
non-read command, offset 0x14 */
+    uint8_t dll_dly_target;                 /**< XPI DLL Delay Target, offset 
0x15 */
+    uint8_t io_voltage;                     /**< IO voltage, offset 0x16 */
+    uint8_t reserved0;                      /**< Reserved for future use, 
offset 0x17 */
+    uint8_t cs_hold_time;                   /**< CS hold time, 0 - default 
value, others - user specified value, offset 0x18 */
+    uint8_t cs_setup_time;                  /**< CS setup time, 0 - default 
value, others - user specified value, offset 0x19 */
+    uint8_t cs_interval;                    /**< CS interval, intervals 
between to CS active, offset 0x1a */
+    uint8_t en_dev_mode_cfg;                /**< Enable device mode 
configuration, offset 0x1b */
+    uint32_t flash_state_ctx;               /**< Flash state context, offset 
0x1c  */
+    device_mode_cfg_t mode_cfg_list[2];     /**< Mode configuration sequences, 
offset 0x20 */
+    uint32_t mode_cfg_param[2];             /**< Mode configuration 
parameters, offset 0x24 */
+    uint32_t reserved1;                     /**< Reserved for future use, 
offset 0x2C */
+    struct {
+        uint32_t entry[4];
+    } cfg_instr_seq[2];                      /**< Mode Configuration 
Instruction sequence, offset 0x30 */
+} xpi_device_info_t;
+
+/**
+ * @brief XPI NOR configuration structure
+ */
+typedef struct {
+    uint32_t tag;                         /**< Must be "XNOR", offset 0x000 */
+    uint32_t reserved0;                   /**< Reserved for future use, offset 
0x004 */
+    uint8_t rxclk_src;                    /**< RXCLKSRC value, offset 0x008 */
+    uint8_t clk_freq;                     /**< Clock frequency, offset 0x009 */
+    uint8_t drive_strength;               /**< Drive strength, offset 0x0a */
+    uint8_t column_addr_size;             /**< Column address size, offset 
0x0b */
+    uint8_t rxclk_src_for_init;           /**< RXCLKSRC during FLASH 
initialization, offset 0x0c */
+    uint8_t config_in_progress;           /**< Indicate whether device 
configuration is in progress, offset: 0x0d */
+    uint8_t reserved[2];                  /**< Reserved for future use, offset 
0x00f */
+    struct {
+        uint8_t enable;                   /**<  Port enable flag, 0 - not 
enabled, 1 - enabled */
+        uint8_t group;                    /**< 0 - 1st IO group, 1 - 2nd IO 
group */
+        uint8_t reserved[2];
+    } chn_info[4];                        /**< Device connection information */
+    xpi_device_info_t device_info;       /**< Device info, offset 0x20 */
+    xpi_instr_seq_t instr_set[xpi_std_nor_seq_idx_max];/**< Standard 
instruction sequence table, offset 0x70 */
+} xpi_nor_config_t;
+
+/**
+ * @brief FLASH runtime context structure
+ */
+typedef union {
+    struct {
+        uint32_t wait_time: 7;              /**< Wait time */
+        uint32_t wait_time_unit: 1;         /**< 0 - 10us, 1 - 1ms */
+        uint32_t reset_gpio: 8;             /**<Reset GPIO */
+        uint32_t restore_sequence: 4;       /**<Restore sequence */
+        uint32_t exit_no_cmd_sequence: 4;   /**< Exit no-cmd sequence */
+        uint32_t current_mode: 4;           /**< Current FLASH mode */
+        uint32_t por_mode: 4;               /**< FLASH mode upon Power-on 
Reset */
+    };
+    uint32_t U;
+} flash_run_context_t;
+
+/**
+ * @brief XPI NOR API error codes
+ */
+enum {
+    status_xpi_nor_sfdp_not_found = MAKE_STATUS(status_group_xpi_nor, 0),      
                 /**<  SFDP table was not found */
+    status_xpi_nor_ddr_read_dummy_cycle_probe_failed = 
MAKE_STATUS(status_group_xpi_nor, 1),    /**<  Probing Dummy cyles for DDR read 
failed */
+    status_xpi_nor_flash_not_found = MAKE_STATUS(status_group_xpi_nor, 2),     
                 /**< FLASH was not detected */
+};
+
+/**
+ * @}
+ */
+
+#endif /* HPM_ROMAPI_XPI_NOR_DEF_H */
diff --git a/contrib/loaders/flash/hpmicro/hpm_romapi_xpi_soc_def.h 
b/contrib/loaders/flash/hpmicro/hpm_romapi_xpi_soc_def.h
new file mode 100644
index 0000000000..ea3ba9e8f9
--- /dev/null
+++ b/contrib/loaders/flash/hpmicro/hpm_romapi_xpi_soc_def.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2021 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef HPM_ROMAPI_XPI_SOC_DEF_H
+#define HPM_ROMAPI_XPI_SOC_DEF_H
+
+#include "hpm_common.h"
+#include "hpm_romapi_xpi_def.h"
+
+/***********************************************************************************************************************
+ * Definitions
+ 
**********************************************************************************************************************/
+
+#define XPI_CLK_OUT_FREQ_OPTION_30MHz (1U)
+#define XPI_CLK_OUT_FREQ_OPTION_50MHz (2U)
+#define XPI_CLK_OUT_FREQ_OPTION_66MHz (3U)
+#define XPI_CLK_OUT_FREQ_OPTION_80MHz (4U)
+#define XPI_CLK_OUT_FREQ_OPTION_104MHz (5U)
+#define XPI_CLK_OUT_FREQ_OPTION_120MHz (6U)
+#define XPI_CLK_OUT_FREQ_OPTION_133MHz (7U)
+#define XPI_CLK_OUT_FREQ_OPTION_166MHz (8U)
+#define XPI_CLK_OUT_FREQ_OPTION_200MHz (9U)
+
+typedef struct {
+    struct {
+        uint8_t priority;                   /* Offset: 0x00 */
+        uint8_t master_idx;                 /* Offset: 0x01 */
+        uint8_t buf_size_in_dword;          /* Offset: 0x02 */
+        bool enable_prefetch;               /* Offset: 0x03 */
+    } entry[8];
+} xpi_ahb_buffer_cfg_t;
+
+typedef struct {
+    uint8_t data_pads;
+    xpi_channel_t channel;
+    xpi_io_group_t io_group;
+    uint8_t drive_strength;
+    bool enable_dqs;
+    bool enable_diff_clk;
+} xpi_io_config_t;
+
+typedef enum {
+    xpi_freq_type_typical,
+    xpi_freq_type_mhz,
+} clk_freq_type_t;
+
+typedef enum {
+    xpi_clk_src_auto,
+    xpi_clk_src_osc,
+    xpi_clk_src_pll0clk0,
+    xpi_clk_src_pll1clk0,
+    xpi_clk_src_pll1clk1,
+    xpi_clk_src_pll2clk0,
+    xpi_clk_src_pll2clk1,
+    xpi_clk_src_pll3clk0,
+    xpi_clk_src_pll4clk0,
+} xpi_clk_src_t;
+
+
+typedef union {
+    struct {
+        uint8_t freq;
+        bool enable_ddr;
+        xpi_clk_src_t clk_src;
+        clk_freq_type_t freq_type;
+    };
+    uint32_t freq_opt;
+} xpi_clk_config_t;
+
+typedef enum {
+    xpi_clock_bus,
+    xpi_clock_serial_root,
+    xpi_clock_serial,
+} xpi_clock_t;
+
+#endif /* HPM_ROMAPI_XPI_SOC_DEF_H */
diff --git a/contrib/loaders/flash/hpmicro/hpm_xpi_flash.h 
b/contrib/loaders/flash/hpmicro/hpm_xpi_flash.h
new file mode 100644
index 0000000000..855807500b
--- /dev/null
+++ b/contrib/loaders/flash/hpmicro/hpm_xpi_flash.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2021 hpmicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef HPM_XPI_FLASH_H
+#define HPM_XPI_FLASH_H
+
+#define FLASH_INIT    (0)
+#define FLASH_ERASE   (0x6)
+#define FLASH_PROGRAM (0xc)
+#define FLASH_READ (0x12)
+#define FLASH_GET_INFO (0x18)
+#define FLASH_ERASE_CHIP (0x1e)
+
+uint8_t flash_algo[] = {
+#include "hpm_xpi_flash.inc"
+};
+
+#endif
diff --git a/contrib/loaders/flash/hpmicro/hpm_xpi_flash.inc 
b/contrib/loaders/flash/hpmicro/hpm_xpi_flash.inc
new file mode 100644
index 0000000000..27e6e4a24d
--- /dev/null
+++ b/contrib/loaders/flash/hpmicro/hpm_xpi_flash.inc
@@ -0,0 +1,65 @@
+/* Autogenerated with ../../../../src/helper/bin2char.sh */
+0xef,0x00,0x00,0x05,0x02,0x90,0xef,0x00,0xc0,0x0e,0x02,0x90,0xef,0x00,0xc0,0x1a,
+0x02,0x90,0xef,0x00,0xa0,0x1c,0x02,0x90,0xef,0x00,0xa0,0x1e,0x02,0x90,0xef,0x00,
+0x00,0x20,0x02,0x90,0xef,0x00,0x20,0x21,0x02,0x90,0x9c,0x41,0x05,0x47,0xbd,0x8b,
+0x63,0x7f,0xf7,0x00,0x9c,0x45,0x05,0x67,0x13,0x07,0x07,0xf0,0xf9,0x8f,0x13,0x07,
+0x00,0x10,0x63,0x96,0xe7,0x00,0x23,0x20,0x05,0x06,0x23,0x22,0x05,0x06,0x82,0x80,
+0x39,0x71,0x22,0xdc,0x13,0x04,0x80,0x23,0x83,0x47,0x44,0x00,0x06,0xde,0x26,0xda,
+0x4a,0xd8,0x4e,0xd6,0x52,0xd4,0x18,0xc0,0xb5,0xe7,0xba,0x84,0x13,0x07,0x84,0x00,
+0x3a,0x85,0x2e,0x8a,0xb2,0x89,0x81,0x45,0x13,0x06,0x00,0x10,0x36,0x89,0x02,0xcc,
+0x02,0xce,0xc9,0x24,0xb7,0x07,0x02,0x20,0x83,0xa6,0x47,0xf1,0x93,0x57,0x79,0x00,
+0x89,0x8b,0xf4,0x46,0xaa,0x85,0x52,0xc6,0x4e,0xc8,0x4a,0xca,0x23,0x24,0xf4,0x10,
+0x70,0x00,0x26,0x85,0x82,0x96,0x13,0x07,0x00,0x10,0x15,0xe5,0xb2,0x47,0x85,0x46,
+0xbd,0x8b,0x63,0xf9,0xf6,0x00,0xd2,0x47,0x85,0x66,0x93,0x86,0x06,0xf0,0xf5,0x8f,
+0x63,0x83,0xe7,0x02,0x83,0x47,0x44,0x00,0x23,0x0e,0x04,0x02,0x81,0xe7,0x85,0x47,
+0x23,0x02,0xf4,0x00,0x01,0x45,0xf2,0x50,0x62,0x54,0xd2,0x54,0x42,0x59,0xb2,0x59,
+0x22,0x5a,0x21,0x61,0x82,0x80,0x1c,0x40,0x23,0xa0,0x07,0x06,0x23,0xa2,0x07,0x06,
+0xd1,0xbf,0x01,0x11,0x52,0xc4,0x13,0x0a,0x80,0x23,0x22,0xcc,0x03,0x54,0x0a,0x03,
+0x26,0xca,0x4a,0xc8,0x06,0xce,0x4e,0xc6,0x56,0xc2,0x2a,0x04,0xb2,0x84,0x2e,0x89,
+0x63,0x7d,0x86,0x00,0x01,0x45,0xb5,0xe8,0xf2,0x40,0x62,0x44,0xd2,0x44,0x42,0x49,
+0xb2,0x49,0x22,0x4a,0x92,0x4a,0x05,0x61,0x82,0x80,0xb3,0xf9,0x85,0x02,0xb3,0x0a,
+0x34,0x41,0x63,0x05,0x54,0x03,0xb7,0x07,0x02,0x20,0x83,0xa7,0x47,0xf1,0x83,0x25,
+0x8a,0x10,0x03,0x25,0x0a,0x00,0x9c,0x4f,0x56,0x87,0xca,0x86,0x13,0x06,0x8a,0x00,
+0x82,0x97,0x79,0xf1,0xa6,0x99,0xb3,0x84,0x89,0x40,0x56,0x99,0xe3,0x7c,0x94,0xfa,
+0x93,0x0a,0x00,0x24,0xb7,0x09,0x02,0x20,0x21,0xa0,0x22,0x99,0x63,0x71,0x94,0x02,
+0x83,0xa7,0x49,0xf1,0x83,0x25,0x8a,0x10,0x03,0x25,0x0a,0x00,0xdc,0x53,0xca,0x86,
+0x56,0x86,0x82,0x97,0x81,0x8c,0x75,0xd1,0x41,0xbf,0x93,0x0a,0x00,0x24,0xb7,0x07,
+0x02,0x20,0x83,0xa7,0x47,0xf1,0x62,0x44,0x83,0x25,0x8a,0x10,0x03,0x25,0x0a,0x00,
+0xf2,0x40,0xb2,0x49,0x22,0x4a,0x9c,0x4f,0x26,0x87,0xca,0x86,0xd2,0x44,0x42,0x49,
+0x56,0x86,0x92,0x4a,0x05,0x61,0x82,0x87,0xb7,0x07,0x02,0x20,0x83,0xa7,0x47,0xf1,
+0x13,0x08,0x80,0x23,0x83,0xa8,0x87,0x02,0x2e,0x87,0x03,0x25,0x08,0x00,0x83,0x25,
+0x88,0x10,0xb6,0x87,0xb2,0x86,0x13,0x06,0x88,0x00,0x82,0x88,0xb7,0x07,0x02,0x20,
+0x83,0xa7,0x47,0xf1,0x13,0x08,0x80,0x23,0x2e,0x83,0x83,0xa8,0xc7,0x02,0x83,0x25,
+0x88,0x10,0x03,0x25,0x08,0x00,0x32,0x87,0xb6,0x87,0x13,0x06,0x88,0x00,0x9a,0x86,
+0x82,0x88,0x81,0xcd,0x93,0x07,0x80,0x23,0x98,0x57,0x83,0xd7,0xe7,0x02,0x01,0x45,
+0x2a,0x07,0xaa,0x07,0x98,0xc1,0xdc,0xc1,0x82,0x80,0x09,0x45,0x82,0x80,0xb7,0x07,
+0x02,0x20,0x83,0xa7,0x47,0xf1,0x13,0x06,0x80,0x23,0x83,0x25,0x86,0x10,0x08,0x42,
+0xdc,0x4f,0x21,0x06,0x82,0x87,0x82,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x3d,0x43,0x2a,0x87,0x63,0x73,0xc3,0x02,0x93,0x77,0xf7,0x00,
+0xbd,0xef,0xad,0xe5,0x93,0x76,0x06,0xff,0x3d,0x8a,0xba,0x96,0x0c,0xc3,0x4c,0xc3,
+0x0c,0xc7,0x4c,0xc7,0x41,0x07,0xe3,0x6b,0xd7,0xfe,0x11,0xe2,0x82,0x80,0xb3,0x06,
+0xc3,0x40,0x8a,0x06,0x97,0x02,0x00,0x00,0x96,0x96,0x67,0x80,0xa6,0x00,0x23,0x07,
+0xb7,0x00,0xa3,0x06,0xb7,0x00,0x23,0x06,0xb7,0x00,0xa3,0x05,0xb7,0x00,0x23,0x05,
+0xb7,0x00,0xa3,0x04,0xb7,0x00,0x23,0x04,0xb7,0x00,0xa3,0x03,0xb7,0x00,0x23,0x03,
+0xb7,0x00,0xa3,0x02,0xb7,0x00,0x23,0x02,0xb7,0x00,0xa3,0x01,0xb7,0x00,0x23,0x01,
+0xb7,0x00,0xa3,0x00,0xb7,0x00,0x23,0x00,0xb7,0x00,0x82,0x80,0x93,0xf5,0xf5,0x0f,
+0x93,0x96,0x85,0x00,0xd5,0x8d,0x93,0x96,0x05,0x01,0xd5,0x8d,0x61,0xb7,0x93,0x96,
+0x27,0x00,0x97,0x02,0x00,0x00,0x96,0x96,0x86,0x82,0xe7,0x80,0x86,0xfa,0x96,0x80,
+0xc1,0x17,0x1d,0x8f,0x3e,0x96,0xe3,0x74,0xc3,0xf8,0xa5,0xb7,
+
diff --git a/contrib/loaders/flash/hpmicro/linker.ld 
b/contrib/loaders/flash/hpmicro/linker.ld
new file mode 100644
index 0000000000..25cf455928
--- /dev/null
+++ b/contrib/loaders/flash/hpmicro/linker.ld
@@ -0,0 +1,44 @@
+ENTRY(_init)
+
+SECTIONS
+{
+    .text : {
+        *(.func_table)
+        KEEP(*(.flash_algo.text*))
+        KEEP(*(.rodata))
+        KEEP(*(.rodata*))
+        KEEP(*(.flash_algo.data*))
+        *(.text)
+        *(.text*)
+        __etext = .;
+    }
+    .discard : {
+        __noncacheable_start__ = .;
+        __noncacheable_bss_start__ = .;
+        __bss_start__ = .;
+        __bss_end__ = .;
+        __noncacheable_bss_end__ = .;
+        _end = .;
+        __noncacheable_init_start__ = .;
+        __data_start__ = .;
+        __data_end__ = .;
+        __noncacheable_init_end__ = .;
+        __noncacheable_end__ = .;
+        __heap_start__ = .;
+        __heap_end__ = .;
+        __ramfunc_start__ = .;
+        __ramfunc_end__ = .;
+        __noncacheable_bss_start__ = .;
+        __noncacheable_bss_end__ = .;
+        __noncacheable_init_start__ = .;
+        __noncacheable_init_end__ = .;
+        __tdata_start__ = .;
+        __tdata_end__ = .;
+        __tbss_start__ = .;
+        __tbss_end__ = .;
+        __data_load_addr__ = .;
+        __fast_load_addr__ = .;
+        __tdata_load_addr__ = .;
+        __noncacheable_init_load_addr__ = .;
+    }
+}
diff --git a/contrib/loaders/flash/hpmicro/openocd_flash_algo.c 
b/contrib/loaders/flash/hpmicro/openocd_flash_algo.c
new file mode 100644
index 0000000000..510330633f
--- /dev/null
+++ b/contrib/loaders/flash/hpmicro/openocd_flash_algo.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2021 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "hpm_romapi.h"
+
+#define XPI0_MEM_START (0x80000000UL)
+#define XPI1_MEM_START (0x90000000UL)
+#define XPI_USE_PORT_B_MASK (0x100)
+#define XPI_USE_PORT_A_MASK (0)
+#define XPI_USE_PORT_SHIFT (0x8)
+
+typedef struct {
+    uint32_t total_sz_in_bytes;
+    uint32_t sector_sz_in_bytes;
+} hpm_flash_info_t;
+
+__attribute__ ((section(".flash_algo.data"))) xpi_nor_config_t nor_config;
+__attribute__ ((section(".flash_algo.data"))) bool xpi_inited = false;
+__attribute__ ((section(".flash_algo.data"))) uint32_t channel = 
xpi_channel_a1;
+__attribute__ ((section(".flash_algo.data"))) XPI_Type *xpi_base;
+
+
+__attribute__ ((section(".flash_algo.text"))) void 
refresh_device_size(XPI_Type *base, xpi_nor_config_option_t *option)
+{
+    volatile uint32_t *dev_size = (volatile uint32_t *)((uint32_t)base + 0x60);
+    bool enable_channelb = false;
+    if (option->header.words > 1) {
+        enable_channelb = option->option1.connection_sel == 
xpi_nor_connection_sel_chnb_cs0;
+    }
+    if (enable_channelb) {
+        dev_size[0] = 0;
+        dev_size[1] = 0;
+    }
+}
+
+__attribute__ ((section(".flash_algo.text"))) uint32_t flash_init(uint32_t 
flash_base, uint32_t header, uint32_t opt0, uint32_t opt1, uint32_t 
xpi_base_addr)
+{
+    uint32_t i = 0;
+    xpi_nor_config_option_t cfg_option;
+    hpm_stat_t stat = status_success;
+
+    xpi_base = (XPI_Type *)xpi_base_addr;
+    if (xpi_inited) {
+        return stat;
+    }
+
+    for (i = 0; i < sizeof(cfg_option); i++) {
+        *((uint8_t *)&cfg_option + i) = 0;
+    }
+    for (i = 0; i < sizeof(nor_config); i++) {
+        *((uint8_t *)&nor_config + i) = 0;
+    }
+
+    cfg_option.header.U = header;
+    cfg_option.option0.U = opt0;
+    cfg_option.option1.U = opt1;
+
+    if (opt1 & XPI_USE_PORT_B_MASK) {
+        channel = xpi_channel_b1;
+    } else {
+        channel = xpi_channel_a1;
+    }
+
+    stat = ROM_API_TABLE_ROOT->xpi_nor_driver_if->auto_config(xpi_base, 
&nor_config, &cfg_option);
+    if (stat) {
+        return stat;
+    }
+
+    refresh_device_size(xpi_base, &cfg_option);
+
+    nor_config.device_info.clk_freq_for_non_read_cmd = 0;
+    if (!xpi_inited) {
+        xpi_inited = true;
+    }
+    return stat;
+}
+
+__attribute__ ((section(".flash_algo.text"))) uint32_t flash_erase(uint32_t 
flash_base, uint32_t address, uint32_t size)
+{
+    hpm_stat_t stat = status_success;
+    uint32_t left, start, block_size, align;
+
+    left = size;
+    start = address;
+    block_size = nor_config.device_info.block_size_kbytes * 1024;
+    if (left >= block_size) {
+        align = block_size - (start % block_size);
+        if (align != block_size) {
+            stat = ROM_API_TABLE_ROOT->xpi_nor_driver_if->erase(xpi_base, 
channel, &nor_config, start, align);
+            if (stat != status_success) {
+                return stat;
+            }
+            left -= align;
+            start += align;
+        }
+        while (left > block_size) {
+            stat = 
ROM_API_TABLE_ROOT->xpi_nor_driver_if->erase_block(xpi_base, channel, 
&nor_config, start);
+            if (stat != status_success) {
+                break;
+            }
+            left -= block_size;
+            start += block_size;
+        }
+    }
+    if ((stat == status_success) && left) {
+        stat = ROM_API_TABLE_ROOT->xpi_nor_driver_if->erase(xpi_base, channel, 
&nor_config, start, left);
+    }
+    return stat;
+}
+
+__attribute__ ((section(".flash_algo.text"))) uint32_t flash_program(uint32_t 
flash_base, uint32_t address, uint32_t *buf, uint32_t size)
+{
+    hpm_stat_t stat;
+
+    stat = ROM_API_TABLE_ROOT->xpi_nor_driver_if->program(xpi_base, channel, 
&nor_config, buf, address, size);
+    return stat;
+}
+
+__attribute__ ((section(".flash_algo.text"))) uint32_t flash_read(uint32_t 
flash_base, uint32_t *buf, uint32_t address, uint32_t size)
+{
+    hpm_stat_t stat;
+
+    stat = ROM_API_TABLE_ROOT->xpi_nor_driver_if->read(xpi_base, channel, 
&nor_config, buf, address, size);
+    return stat;
+}
+
+__attribute__ ((section(".flash_algo.text"))) uint32_t flash_get_info(uint32_t 
flash_base, hpm_flash_info_t *flash_info)
+{
+    if (!flash_info) {
+        return status_invalid_argument;
+    }
+
+    flash_info->total_sz_in_bytes = nor_config.device_info.size_in_kbytes << 
10;
+    flash_info->sector_sz_in_bytes = nor_config.device_info.sector_size_kbytes 
<< 10;
+    return status_success;
+}
+
+__attribute__ ((section(".flash_algo.text"))) uint32_t 
flash_erase_chip(uint32_t flash_base)
+{
+    return ROM_API_TABLE_ROOT->xpi_nor_driver_if->erase_chip(xpi_base, 
channel, &nor_config);
+}
+
+__attribute__ ((section(".flash_algo.text"))) void flash_deinit(void)
+{
+    return;
+}

-- 

Reply via email to