Add external memory support for cypress platform

Signed-off-by: Bohdan Kovalchuk <bohd@cypress.com>
Signed-off-by: Roman Okhrimenko <roman.okhrimenko@cypress.com>
diff --git a/boot/cypress/BlinkyApp/BlinkyApp.mk b/boot/cypress/BlinkyApp/BlinkyApp.mk
index 8c3dbfa..a4ae952 100644
--- a/boot/cypress/BlinkyApp/BlinkyApp.mk
+++ b/boot/cypress/BlinkyApp/BlinkyApp.mk
@@ -34,6 +34,10 @@
 # image type can be BOOT or UPGRADE
 IMG_TYPES = BOOT UPGRADE
 
+# possible values are 0 and 0xff
+# internal Flash by default
+ERASED_VALUE ?= 0
+
 ifneq ($(COMPILER), GCC_ARM)
 $(error Only GCC ARM is supported at this moment)
 endif
@@ -53,8 +57,8 @@
 
 # Define start of application, RAM start and size, slot size
 ifeq ($(PLATFORM), PSOC_062_2M)
-	DEFINES_APP += -DRAM_START=0x08000000
-	DEFINES_APP += -DRAM_SIZE=0x20000
+	DEFINES_APP += -DRAM_START=0x08040000
+	DEFINES_APP += -DRAM_SIZE=0x10000
 	DEFINES_APP += -DUSER_APP_START=0x10018000
 	SLOT_SIZE ?= 0x10000
 endif
@@ -80,7 +84,7 @@
 # We still need this for MCUBoot apps signing
 IMGTOOL_PATH ?=	../../scripts/imgtool.py
 
-SIGN_ARGS := sign --header-size 1024 --pad-header --align 8 -v "2.0" -S $(SLOT_SIZE) -M 512 --overwrite-only -R 0 -k keys/$(SIGN_KEY_FILE).pem
+SIGN_ARGS := sign --header-size 1024 --pad-header --align 8 -v "2.0" -S $(SLOT_SIZE) -M 512 --overwrite-only -R $(ERASED_VALUE) -k keys/$(SIGN_KEY_FILE).pem
 
 # Output folder
 OUT := $(APP_NAME)/out
diff --git a/boot/cypress/BlinkyApp/toolchains.mk b/boot/cypress/BlinkyApp/toolchains.mk
index 3868436..55c62d5 100644
--- a/boot/cypress/BlinkyApp/toolchains.mk
+++ b/boot/cypress/BlinkyApp/toolchains.mk
@@ -48,7 +48,7 @@
 # NOTE: Absolute pathes for now for the sake of development
 ifeq ($(HOST_OS), win)
 	ifeq ($(COMPILER), GCC_ARM)
-		TOOLCHAIN_PATH ?= c:/Users/$(USERNAME)/ModusToolbox_1.0/tools/gcc-7.2.1-1.0
+		TOOLCHAIN_PATH ?= c:/Users/$(USERNAME)/ModusToolbox/tools_2.1/gcc-7.2.1
 		MY_TOOLCHAIN_PATH:=$(subst \,/,$(TOOLCHAIN_PATH))
 		TOOLCHAIN_PATH := $(MY_TOOLCHAIN_PATH)
 		GCC_PATH := $(TOOLCHAIN_PATH)
diff --git a/boot/cypress/MCUBootApp/ExternalMemory.md b/boot/cypress/MCUBootApp/ExternalMemory.md
new file mode 100644
index 0000000..d2da582
--- /dev/null
+++ b/boot/cypress/MCUBootApp/ExternalMemory.md
@@ -0,0 +1,78 @@
+### External Memory support for Secondary Slot
+
+**Description**
+
+Given document describes the use of external memory module as a secondary (upgrade) slot with Cypress' PSoC6 devices.
+
+The demonstration device is CY8CPROTO-062-4343W board which is PSoC6 device with 2M of Flash available.
+The memory module present on board is S25FL512SAGMFI010 512-Mbit external Quad SPI NOR Flash.
+
+Using external memory for secondary slot allows to nearly double the size of Boot Image.
+
+**Operation Design and Flow**
+
+The design is based on using SFDP command's auto-discovery functionality of memory module IC and Cypress' SMIF PDL driver.
+
+It is assumed that user's design meets following:
+* The memory-module used is SFDP-compliant;
+* There only one module is being used for secondary slot;
+* Only "OWERWRITE" bootloading scheme is used;
+* The address for secondary slot should start from 0x18000000.
+This corresponds to PSoC6's SMIF (Serial Memory InterFace) IP block mapping.
+* The slot size for upgrade slot is even (or smaller) to erase size (0x40000) of given memory module.
+This requirement is accepted for code simplicity.
+
+The default flash map implemented is the following:
+* [0x10000000, 0x10018000] - MCUBootApp (bootloader) area;
+* [0x10018000, 0x10028000] - primary slot for BlinkyApp;
+* [0x18000000, 0x18010000] - secondary slot for BlinkyApp;
+* [0x10038000, 0x10039000] - scratch area (not used);
+
+Size of slots `0x10000` - 64kB
+
+**Note 1**: make sure primary, secondary slot and bootloader app sizes are appropriate and correspond to flash area size defined in Applications' linker files.
+
+**Note 2**: make sure secondary slot start address is aligned (or smaller) to erase size (0x40000 - 256kB).
+
+MCUBootApp's `main.c` contains the call to Init-SFDP API which performs required GPIO configurations, SMIF IP block configurations, SFDP protocol read and memory-config structure initialization.
+
+After that MCUBootApp is ready to accept upgrade image from external memory module.
+
+Once valid upgrade image was accepted the image in external memory will be erased.
+
+**How to enable external memory support:**
+
+1. Seek for `CY_BOOT_USE_EXTERNAL_FLASH` in sources and define it in any: MCUBootApp.mk or any suitable header file.
+2. Navigate to `cy_flash_map.c` and check if secondary slot start address and size meet the application's needs.
+3. Define which slave select is used for external memory on a board by setting `smif_id` value in `main.c`.
+4. Build MCUBootApp as described in `Readme.md`.
+
+**How to build upgrade image for external memory:**
+
+    make app APP_NAME=BlinkyApp PLATFORM=PSOC_062_2M IMG_TYPE=UPGRADE HEADER_OFFSET=0x7FE8000 ERASED_VALUE=0xff
+
+`HEADER_OFFSET` defines the offset from original boot image address. This one in line above suggests secondary slot will start from `0x18000000`.
+
+`ERASED_VALUE` defines the memory cell contents in erased state. It is `0x00` for PSoC6's internal Flash and `0xff` for S25FL512S.
+
+**Programming to external memory**
+
+The MCUBootApp programming can be done similarly to described in `Readme.md`:
+
+        export OPENOCD=/Applications/ModusToolbox/tools_2.1/openocd
+
+        ${OPENOCD}/bin/openocd -s ${OPENOCD}/scripts \
+                            -f ${OPENOCD}/scripts/interface/kitprog3.cfg \
+                            -f ${OPENOCD}/scripts/target/psoc6_2m.cfg \
+                            -c "init; psoc6 sflash_restrictions 1" \
+                            -c "init; reset init; program PATH_TO_APPLICATION.hex" \
+                            -c "resume; reset; exit" 
+
+There is a NULL-pointer placed for SMIF configuration pointer in TOC2 (Table Of Contents, `cy_serial_flash_prog.c`).
+This is done to force CY8PROTO-062-4343W DAP Link firmware to program external memory with hardcoded values.
+
+1. Press SW3 Mode button on a board to switch the board into DAP Link mode.
+2. Once DAP Link removable disk appeared drop (copy) the upgrade image HEX file to it.
+This will invoke firmware to program external memory.
+
+**Note 3:** the programming of external memory is limited to S25FL512S p/n only at this moment.
diff --git a/boot/cypress/MCUBootApp/MCUBootApp.ld b/boot/cypress/MCUBootApp/MCUBootApp.ld
index 832017b..c620479 100644
--- a/boot/cypress/MCUBootApp/MCUBootApp.ld
+++ b/boot/cypress/MCUBootApp/MCUBootApp.ld
@@ -63,7 +63,7 @@
      * Your changes must be aligned with the corresponding memory regions for the CM4 core in 'xx_cm4_dual.ld',
      * where 'xx' is the device group; for example, 'cy8c6xx7_cm4_dual.ld'.
      */
-    ram               (rwx)   : ORIGIN = 0x08000000, LENGTH = 0x20000
+    ram               (rwx)   : ORIGIN = 0x08020000, LENGTH = 0x20000
     flash             (rx)    : ORIGIN = 0x10000000, LENGTH = 0x18000
 
     /* This is a 32K flash region used for EEPROM emulation. This region can also be used as the general purpose flash.
diff --git a/boot/cypress/MCUBootApp/MCUBootApp.mk b/boot/cypress/MCUBootApp/MCUBootApp.mk
index 14cccf6..d2a8ff8 100644
--- a/boot/cypress/MCUBootApp/MCUBootApp.mk
+++ b/boot/cypress/MCUBootApp/MCUBootApp.mk
@@ -45,6 +45,7 @@
 DEFINES_APP += -DECC256_KEY_FILE="\"keys/$(SIGN_KEY_FILE).pub\""
 DEFINES_APP += -DCORE=$(CORE)
 DEFINES_APP += -DMCUBOOT_IMAGE_NUMBER=$(MCUBOOT_IMAGE_NUMBER)
+DEFINES_APP += -DCY_BOOT_USE_EXTERNAL_FLASH
 
 ifeq ($(USE_CRYPTO_HW), 1)
 DEFINES_APP += -DMBEDTLS_USER_CONFIG_FILE="\"mcuboot_crypto_acc_config.h\""
@@ -53,8 +54,10 @@
 SOURCES_MCUBOOT := $(wildcard $(CURDIR)/../bootutil/src/*.c)
 # Collect MCUBoot Application sources
 SOURCES_APP_SRC := $(wildcard $(CUR_APP_PATH)/*.c)
+
 # Collect Flash Layer port sources
 SOURCES_FLASH_PORT := $(wildcard $(CURDIR)/cy_flash_pal/*.c)
+SOURCES_FLASH_PORT += $(wildcard $(CURDIR)/cy_flash_pal/flash_qspi/*.c)
 # Collect all the sources
 SOURCES_APP := $(SOURCES_MCUBOOT)
 SOURCES_APP += $(SOURCES_APP_SRC)
@@ -65,6 +68,7 @@
 INCLUDE_DIRS_MCUBOOT += $(addprefix -I, $(CURDIR)/..)
 
 INCLUDE_DIRS_APP := $(addprefix -I, $(CURDIR))
+INCLUDE_DIRS_APP += $(addprefix -I, $(CURDIR)/cy_flash_pal/flash_qspi)
 INCLUDE_DIRS_APP += $(addprefix -I, $(CURDIR)/cy_flash_pal/include)
 INCLUDE_DIRS_APP += $(addprefix -I, $(CURDIR)/cy_flash_pal/include/flash_map_backend)
 INCLUDE_DIRS_APP += $(addprefix -I, $(CUR_APP_PATH))
diff --git a/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_logging.h b/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_logging.h
index 3a8eafe..0d6f787 100644
--- a/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_logging.h
+++ b/boot/cypress/MCUBootApp/config/mcuboot_config/mcuboot_logging.h
@@ -94,4 +94,6 @@
 #define MCUBOOT_LOG_DBG(...) IGNORE(__VA_ARGS__)
 #endif
 
+#define MCUBOOT_LOG_MODULE_DECLARE(...)
+
 #endif /* MCUBOOT_LOGGING_H */
diff --git a/boot/cypress/MCUBootApp/cy_serial_flash_prog.c b/boot/cypress/MCUBootApp/cy_serial_flash_prog.c
new file mode 100644
index 0000000..512df93
--- /dev/null
+++ b/boot/cypress/MCUBootApp/cy_serial_flash_prog.c
@@ -0,0 +1,100 @@
+/***************************************************************************//**
+* \file cy_serial_flash_prog.c
+*
+* \brief
+* Provides variables necessary to inform programming tools how to program the
+* attached serial flash memory. The variables used here must be placed at
+* specific locations in order to be detected and used by programming tools
+* to know that there is an attached memory and its characteristics. Uses the
+* configuration provided as part of BSP.
+*
+********************************************************************************
+* \copyright
+* Copyright 2018-2019 Cypress Semiconductor Corporation
+* SPDX-License-Identifier: Apache-2.0
+*
+* Licensed 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.
+*******************************************************************************/
+
+/**
+* \addtogroup group_serial_flash Serial Flash
+* \{
+* Variables for informing programming tools that there is an attached memory device and what
+* its characteristics are so it can be programmed just like the on-chip memory.
+*
+* \defgroup group_serial_flash_variables Variables
+*/
+
+#include <stdint.h>
+#include "flash_qspi.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+typedef struct
+{
+    const cy_stc_smif_block_config_t * smifCfg; /* Pointer to SMIF top-level configuration */
+    const uint32_t null_t; /* NULL termination */
+} stc_smif_ipblocks_arr_t;
+
+/**
+* \addtogroup group_serial_flash_variables
+* \{
+*/
+
+/**
+ * This data can be placed anywhere in the internal memory, but it must be at a location that
+ * can be determined and used for the calculation of the CRC16 checksum in the cyToc below. There
+ * are multiple ways this can be accomplished including:
+ * 1) Placing it in a dedicated memory block with a known address. (as done here)
+ * 2) Placing it at an absolute location via a the linker script
+ * 3) Using 'cymcuelftool -S' to recompute the checksum and patch the elf file after linking
+ */
+CY_SECTION(".cy_sflash_user_data") __attribute__( (used) )
+/* const stc_smif_ipblocks_arr_t smifIpBlocksArr = {&smifBlockConfig_sfdp, 0x00000000}; */
+/* if used zero-pointer to config, DAP link will use hardcoded config for CY8CPROTO-062-4343W */
+const stc_smif_ipblocks_arr_t smifIpBlocksArr = {0x00000000, 0x00000000};
+
+/**
+ * This data is used to populate the table of contents part 2. When present, it is used by the boot
+ * process and programming tools to determine key characteristics about the memory usage including
+ * where the boot process should start the application from and what external memories are connected
+ * (if any). This must consume a full row of flash memory row. The last entry is a checksum of the
+ * other values in the ToC which must be updated if any other value changes. This can be done manually
+ * or by running 'cymcuelftool -S' to recompute the checksum.
+ */
+CY_SECTION(".cy_toc_part2") __attribute__( (used) )
+const uint32_t cyToc[128] =
+{
+    0x200-4,                /* Offset=0x0000: Object Size, bytes */
+    0x01211220,             /* Offset=0x0004: Magic Number (TOC Part 2, ID) */
+    0,                      /* Offset=0x0008: Key Storage Address */
+    (int)&smifIpBlocksArr,  /* Offset=0x000C: This points to a null terminated array of SMIF structures. */
+    0x10000000u,            /* Offset=0x0010: App image start address */
+                            /* Offset=0x0014-0x01F7: Reserved */
+    [126] =  0x000002C2,    /* Offset=0x01F8: Bits[ 1: 0] CLOCK_CONFIG (0=8MHz, 1=25MHz, 2=50MHz, 3=100MHz)
+                                              Bits[ 4: 2] LISTEN_WINDOW (0=20ms, 1=10ms, 2=1ms, 3=0ms, 4=100ms)
+                                              Bits[ 6: 5] SWJ_PINS_CTL (0/1/3=Disable SWJ, 2=Enable SWJ)
+                                              Bits[ 8: 7] APP_AUTHENTICATION (0/2/3=Enable, 1=Disable)
+                                              Bits[10: 9] FB_BOOTLOADER_CTL: UNUSED */
+    [127] =  0x3BB30000     /* Offset=0x01FC: CRC16-CCITT (the upper 2 bytes contain the CRC and the lower 2 bytes are 0) */
+};
+
+/** \} group_serial_flash_variables */
+
+#if defined(__cplusplus)
+}
+#endif
+
+/** \} group_serial_flash */
diff --git a/boot/cypress/MCUBootApp/main.c b/boot/cypress/MCUBootApp/main.c
index e908d07..968f0b6 100644
--- a/boot/cypress/MCUBootApp/main.c
+++ b/boot/cypress/MCUBootApp/main.c
@@ -22,6 +22,11 @@
 #include "cy_retarget_io_pdl.h"
 #include "cy_result.h"
 
+#include "cycfg_clocks.h"
+#include "cycfg_peripherals.h"
+#include "cycfg_pins.h"
+
+#include "flash_qspi.h"
 #include "sysflash/sysflash.h"
 #include "flash_map_backend/flash_map_backend.h"
 
@@ -56,6 +61,7 @@
 int main(void)
 {
     struct boot_rsp rsp ;
+    cy_rslt_t rc = !CY_RSLT_SUCCESS;
 
     init_cycfg_clocks();
     init_cycfg_peripherals();
@@ -68,11 +74,29 @@
 
     BOOT_LOG_INF("MCUBoot Bootloader Started");
 
-    if (boot_go(&rsp) == 0) {
-        BOOT_LOG_INF("User Application validated successfully");
-        do_boot(&rsp);
-    } else
-        BOOT_LOG_INF("MCUBoot Bootloader found none of bootable images") ;
-
+#ifdef CY_BOOT_USE_EXTERNAL_FLASH
+    int smif_id = 1; /* Assume SlaveSelect_0 is used for External Memory */
+    /* Acceptable values are:
+    * 0 - SMIF disabled (no external memory);
+    * 1, 2, 3 or 4 - slave select line memory module is connected to.
+    */
+    rc = qspi_init_sfdp(smif_id);
+    if(rc == CY_SMIF_SUCCESS)
+    {
+        BOOT_LOG_INF("External Memory initialized w/ SFDP.");
+    }
+    else
+    {
+        BOOT_LOG_ERR("External Memory initialization w/ SFDP FAILED: 0x%02x", (int)rc);
+    }
+    if(0 == rc)
+#endif
+    {
+        if (boot_go(&rsp) == 0) {
+            BOOT_LOG_INF("User Application validated successfully");
+            do_boot(&rsp);
+        } else
+            BOOT_LOG_INF("MCUBoot Bootloader found none of bootable images") ;
+    }
     return 0;
 }
diff --git a/boot/cypress/MCUBootApp/sysflash/sysflash.h b/boot/cypress/MCUBootApp/sysflash/sysflash.h
index 2a905ee..f1fc841 100644
--- a/boot/cypress/MCUBootApp/sysflash/sysflash.h
+++ b/boot/cypress/MCUBootApp/sysflash/sysflash.h
@@ -12,6 +12,12 @@
 #define FLASH_AREA_IMAGE_2 5
 #define FLASH_AREA_IMAGE_3 6
 
+/* Uncomment if external flash is being used */
+/* #define CY_BOOT_USE_EXTERNAL_FLASH */
+
+/* use PDL-defined offset or one from SMFI config */
+#define CY_SMIF_BASE_MEM_OFFSET             (0x18000000)
+
 #define CY_FLASH_ALIGN                      (CY_FLASH_SIZEOF_ROW)
 #define CY_FLASH_DEVICE_BASE                (CY_FLASH_BASE)
 
diff --git a/boot/cypress/MCUBootApp/toolchains.mk b/boot/cypress/MCUBootApp/toolchains.mk
index d250931..562ce73 100644
--- a/boot/cypress/MCUBootApp/toolchains.mk
+++ b/boot/cypress/MCUBootApp/toolchains.mk
@@ -48,7 +48,7 @@
 # NOTE: Absolute pathes for now for the sake of development
 ifeq ($(HOST_OS), win)
 	ifeq ($(COMPILER), GCC_ARM)
-		TOOLCHAIN_PATH ?= c:/Users/$(USERNAME)/ModusToolbox_1.0/tools/gcc-7.2.1-1.0
+		TOOLCHAIN_PATH ?= c:/Users/$(USERNAME)/ModusToolbox/tools_2.1/gcc-7.2.1
 		MY_TOOLCHAIN_PATH:=$(subst \,/,$(TOOLCHAIN_PATH))
 		TOOLCHAIN_PATH := $(MY_TOOLCHAIN_PATH)
 		GCC_PATH := $(TOOLCHAIN_PATH)
diff --git a/boot/cypress/Makefile b/boot/cypress/Makefile
index b91f279..3868c80 100644
--- a/boot/cypress/Makefile
+++ b/boot/cypress/Makefile
@@ -139,7 +139,7 @@
 	$(MAKE) post_build
 
 build: $(OUT_APP)/$(APP_NAME).hex
-	$(GCC_PATH)/bin/arm-none-eabi-objdump $(OUT_APP)/$(APP_NAME).hex -s > $(OUT_APP)/$(APP_NAME).lst
+	$(GCC_PATH)/bin/arm-none-eabi-objdump $(OUT_APP)/$(APP_NAME).elf -S --disassemble > $(OUT_APP)/$(APP_NAME).lst
 	$(GCC_PATH)/bin/arm-none-eabi-objdump -h $(OUT_APP)/$(APP_NAME).elf
 	$(GCC_PATH)/bin/arm-none-eabi-size --format=SysV $(OUT_APP)/$(APP_NAME).elf
 
diff --git a/boot/cypress/cy_flash_pal/cy_flash_map.c b/boot/cypress/cy_flash_pal/cy_flash_map.c
index 2b51795..427c6c7 100644
--- a/boot/cypress/cy_flash_pal/cy_flash_map.c
+++ b/boot/cypress/cy_flash_pal/cy_flash_map.c
@@ -36,12 +36,14 @@
 
 #include "flash_map_backend/flash_map_backend.h"
 #include <sysflash/sysflash.h>
-#include "cy_flash_psoc6.h"
 
 #include "bootutil/bootutil_log.h"
 
 #include "cy_pdl.h"
 
+#ifdef CY_BOOT_USE_EXTERNAL_FLASH
+#include "cy_smif_psoc6.h"
+#endif
 /*
  * For now, we only support one flash device.
  *
@@ -86,6 +88,7 @@
     .fa_size = CY_BOOT_PRIMARY_1_SIZE
 };
 
+#ifndef CY_BOOT_USE_EXTERNAL_FLASH
 static struct flash_area secondary_1 =
 {
     .fa_id = FLASH_AREA_IMAGE_SECONDARY(0),
@@ -95,7 +98,15 @@
                 CY_BOOT_PRIMARY_1_SIZE,
     .fa_size = CY_BOOT_SECONDARY_1_SIZE
 };
-
+#else
+static struct flash_area secondary_1 =
+{
+    .fa_id = FLASH_AREA_IMAGE_SECONDARY(0),
+    .fa_device_id = FLASH_DEVICE_EXTERNAL_FLASH(CY_BOOT_EXTERNAL_DEVICE_INDEX),
+    .fa_off = CY_SMIF_BASE_MEM_OFFSET,
+    .fa_size = CY_BOOT_SECONDARY_1_SIZE
+};
+#endif
 #if (MCUBOOT_IMAGE_NUMBER == 2) /* if dual-image */
 static struct flash_area primary_2 =
 {
@@ -199,26 +210,30 @@
     (void)fa;/* Nothing to do there */
 }
 
-/* Reads `len` bytes of flash memory at `off` to the buffer at `dst` */
+/*
+* Reads `len` bytes of flash memory at `off` to the buffer at `dst`
+*/
 int flash_area_read(const struct flash_area *fa, uint32_t off, void *dst,
                      uint32_t len)
 {
     int rc = 0;
     size_t addr;
 
-    if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH)
-    {
-        assert(off < fa->fa_off);
-        assert(off + len < fa->fa_off);
-
+    /* check if requested offset not less then flash area (fa) start */
+    assert(off < fa->fa_off);
+    assert(off + len < fa->fa_off);
+    /* convert to absolute address inside a device*/
         addr = fa->fa_off + off;
 
-        rc = psoc6_flash_read(addr, dst, len);
+    if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH)
+    {
+        /* flash read by simple memory copying */
+        memcpy((void *)dst, (const void*)addr, (size_t)len);
     }
-#ifdef CY_USE_EXTERNAL_FLASH
+#ifdef CY_BOOT_USE_EXTERNAL_FLASH
     else if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG)
     {
-        // TODO: implement/split into psoc6_smif_read()
+        rc = psoc6_smif_read(fa, addr, dst, len);
     }
 #endif
     else
@@ -230,29 +245,52 @@
     if (rc != 0) {
         BOOT_LOG_ERR("Flash area read error, rc = %d", (int)rc);
     }
-
     return rc;
 }
 
-/* Writes `len` bytes of flash memory at `off` from the buffer at `src` */
+/*
+* Writes `len` bytes of flash memory at `off` from the buffer at `src`
+ */
 int flash_area_write(const struct flash_area *fa, uint32_t off,
                      const void *src, uint32_t len)
 {
-    int rc = 0;
-    size_t addr;
+    cy_en_flashdrv_status_t rc = CY_FLASH_DRV_SUCCESS;
+    size_t write_start_addr;
+    size_t write_end_addr;
+    const uint32_t * row_ptr = NULL;
+
+    assert(off < fa->fa_off);
+    assert(off + len < fa->fa_off);
+
+    /* convert to absolute address inside a device */
+    write_start_addr = fa->fa_off + off;
+    write_end_addr = fa->fa_off + off + len;
 
     if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH)
     {
-        assert(off < fa->fa_off);
-        assert(off + len < fa->fa_off);
+        uint32_t row_number = 0;
+        uint32_t row_addr = 0;
 
-        addr = fa->fa_off + off;
-        rc = psoc6_flash_write(addr, src, len);
+        assert(!(len % CY_FLASH_SIZEOF_ROW));
+
+        row_number = (write_end_addr - write_start_addr) / CY_FLASH_SIZEOF_ROW;
+        row_addr = write_start_addr;
+
+        row_ptr = (uint32_t *) src;
+
+        for (uint32_t i = 1; i <= row_number + 1; i++){
+
+            rc = Cy_Flash_WriteRow(row_addr, row_ptr);
+            row_addr = write_start_addr + i * (uint32_t) CY_FLASH_SIZEOF_ROW;
+
+            row_number--;
+            row_ptr = row_ptr + CY_FLASH_SIZEOF_ROW / 4;
+        }
     }
-#ifdef CY_USE_EXTERNAL_FLASH
+#ifdef CY_BOOT_USE_EXTERNAL_FLASH
     else if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG)
     {
-        // TODO: implement/split into psoc6_smif_write()
+        rc = psoc6_smif_write(fa, write_start_addr, src, len);
     }
 #endif
     else
@@ -261,27 +299,41 @@
         rc = -1;
     }
 
-    return rc;
+    return (int) rc;
 }
 
-/* Erases `len` bytes of flash memory at `off` */
+/*< Erases `len` bytes of flash memory at `off` */
 int flash_area_erase(const struct flash_area *fa, uint32_t off, uint32_t len)
 {
-    int rc = 0;
-    size_t addr;
+    cy_en_flashdrv_status_t rc = CY_FLASH_DRV_SUCCESS;
+    size_t erase_start_addr;
+    size_t erase_end_addr;
+
+    assert(off < fa->fa_off);
+    assert(off + len < fa->fa_off);
+    assert(!(len % CY_FLASH_SIZEOF_ROW));
+
+    /* convert to absolute address inside a device*/
+    erase_start_addr = fa->fa_off + off;
+    erase_end_addr = fa->fa_off + off + len;
 
     if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH)
     {
-        assert(off < fa->fa_off);
-        assert(off + len < fa->fa_off);
+        int row_number = 0;
+        uint32_t row_addr = 0;
 
-        addr = fa->fa_off + off;
-        rc = psoc6_flash_erase(addr, len);
-    }
-#ifdef CY_USE_EXTERNAL_FLASH
+        row_number = (erase_end_addr - erase_start_addr) / CY_FLASH_SIZEOF_ROW;
+
+        while (row_number != 0)
+        {
+            row_number--;
+            row_addr = erase_start_addr + row_number * (uint32_t) CY_FLASH_SIZEOF_ROW;
+            rc = Cy_Flash_EraseRow(row_addr);
+        }
+#ifdef CY_BOOT_USE_EXTERNAL_FLASH
     else if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG)
     {
-        // TODO: implement/split into psoc6_smif_erase()
+        rc = psoc6_smif_erase(erase_start_addr, len);
     }
 #endif
     else
@@ -289,21 +341,21 @@
         /* incorrect/non-existing flash device id */
         rc = -1;
     }
-    return rc;
+    return (int) rc;
 }
 
-/* Returns this `flash_area`s alignment */
+/*< Returns this `flash_area`s alignment */
 size_t flash_area_align(const struct flash_area *fa)
 {
-    uint8_t ret = -1;
+    int ret = -1;
     if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH)
     {
         ret = CY_FLASH_ALIGN;
     }
-#ifdef CY_USE_EXTERNAL_FLASH
+#ifdef CY_BOOT_USE_EXTERNAL_FLASH
     else if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG)
     {
-        // TODO: implement for SMIF WR/ERASE size
+        return qspi_get_prog_size();
     }
 #endif
     else
@@ -315,22 +367,23 @@
 }
 
 #ifdef MCUBOOT_USE_FLASH_AREA_GET_SECTORS
-/* Initializes an array of flash_area elements for the slot's sectors */
+/*< Initializes an array of flash_area elements for the slot's sectors */
 int     flash_area_to_sectors(int idx, int *cnt, struct flash_area *fa)
 {
     int rc = 0;
 
     if (fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH)
     {
-        // TODO:
         (void)idx;
         (void)cnt;
         rc = 0;
     }
-#ifdef CY_USE_EXTERNAL_FLASH
+#ifdef CY_BOOT_USE_EXTERNAL_FLASH
     else if ((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG)
     {
-        // TODO: implement/split into psoc6_smif_erase()
+        (void)idx;
+        (void)cnt;
+        rc = 0;
     }
 #endif
     else
@@ -338,7 +391,6 @@
         /* incorrect/non-existing flash device id */
         rc = -1;
     }
-
     return rc;
 }
 #endif
@@ -387,12 +439,12 @@
 
     if (fap->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH)
     {
-        ret = CY_BOOT_INTERNAL_FLASH_ERASE_VALUE ;
+        ret = CY_BOOT_INTERNAL_FLASH_ERASE_VALUE;
     }
-#ifdef CY_USE_EXTERNAL_FLASH
+#ifdef CY_BOOT_USE_EXTERNAL_FLASH
     else if ((fap->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG)
     {
-        ret = CY_BOOT_EXTERNAL_FLASH_ERASE_VALUE ;
+        ret = CY_BOOT_EXTERNAL_FLASH_ERASE_VALUE;
     }
 #endif
     else
@@ -406,7 +458,6 @@
 int flash_area_read_is_empty(const struct flash_area *fa, uint32_t off,
         void *dst, uint32_t len)
 {
-    uint8_t i = 0;
     uint8_t *mem_dest;
     int rc;
 
@@ -416,7 +467,7 @@
         return -1;
     }
 
-    for (i = 0; i < len; i++) {
+    for (uint8_t i = 0; i < len; i++) {
         if (mem_dest[i] != flash_area_erased_val(fa)) {
             return 0;
         }
@@ -424,14 +475,12 @@
     return 1;
 }
 
+#ifdef MCUBOOT_USE_FLASH_AREA_GET_SECTORS
 int flash_area_get_sectors(int idx, uint32_t *cnt, struct flash_sector *ret)
 {
     int rc = 0;
     uint32_t i = 0;
-    struct flash_area *fa;
-    size_t sector_size = 0;
-    size_t sectors_n = 0;
-    uint32_t addr = 0;
+    struct flash_area *fa = NULL;
 
     while(NULL != boot_area_descs[i])
     {
@@ -443,17 +492,20 @@
         i++;
     }
 
-
     if(NULL != boot_area_descs[i])
     {
+        size_t sector_size = 0;
+
         if(fa->fa_device_id == FLASH_DEVICE_INTERNAL_FLASH)
         {
             sector_size = CY_FLASH_SIZEOF_ROW;
         }
-#ifdef CY_USE_EXTERNAL_FLASH
+#ifdef CY_BOOT_USE_EXTERNAL_FLASH
         else if((fa->fa_device_id & FLASH_DEVICE_EXTERNAL_FLAG) == FLASH_DEVICE_EXTERNAL_FLAG)
         {
-            // TODO: implement for SMIF
+            /* implement for SMIF */
+            /* lets assume they are equal */
+            sector_size = CY_FLASH_SIZEOF_ROW;
         }
 #endif
         else
@@ -463,6 +515,9 @@
 
         if(0 == rc)
         {
+            uint32_t addr = 0;
+            size_t sectors_n = 0;
+
             sectors_n = (fa->fa_size + (sector_size - 1)) / sector_size;
             assert(sectors_n <= *cnt);
 
@@ -484,3 +539,4 @@
 
     return rc;
 }
+#endif
diff --git a/boot/cypress/cy_flash_pal/cy_flash_psoc6.c b/boot/cypress/cy_flash_pal/cy_flash_psoc6.c
deleted file mode 100644
index 35dc30f..0000000
--- a/boot/cypress/cy_flash_pal/cy_flash_psoc6.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Copyright (c) 2020 Cypress Semiconductors
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- /*
- * 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.
- */
- /*******************************************************************************/
-
-#include "string.h"
-#include "stdlib.h"
-#include "stdbool.h"
-
-#ifdef MCUBOOT_HAVE_ASSERT_H
-#include "mcuboot_config/mcuboot_assert.h"
-#else
-#include <assert.h>
-#endif
-
-#include "cy_device_headers.h"
-#include "cy_flash_psoc6.h"
-
-#include "cy_flash.h"
-#include "cy_syspm.h"
-
-#define PSOC6_WR_SUCCESS 0
-#define PSOC6_WR_ERROR_INVALID_PARAMETER 1
-#define PSOC6_WR_ERROR_FLASH_WRITE 2
-
-#define PSOC6_FLASH_ERASE_BLOCK_SIZE	CY_FLASH_SIZEOF_ROW /* PSoC6 Flash erases by Row */
-
-int psoc6_flash_read(off_t addr, void *data, size_t len)
-{
-    /* flash read by simple memory copying */
-    memcpy((void *)data, (const void*)addr, (size_t)len);
-
-    return 0;
-}
-
-int psoc6_flash_write(off_t addr,
-                const void *data, size_t len)
-{
-    int rc;
-
-    rc = psoc6_flash_write_hal((uint8_t *)data, addr, len);
-
-    return rc;
-}
-
-int psoc6_flash_erase(off_t addr, size_t size)
-{
-    int rc = 0;
-
-    uint32_t addrStart, addrEnd, address;
-    uint32_t remStart, remEnd;
-    uint32_t rowIdxStart, rowIdxEnd, rowNum;
-    uint8_t  buff[CY_FLASH_SIZEOF_ROW];
-
-    addrStart = addr;
-    addrEnd   = addrStart + size;
-
-    /* find if area bounds are aligned to rows */
-    remStart = addrStart%CY_FLASH_SIZEOF_ROW;
-    remEnd   = addrEnd%CY_FLASH_SIZEOF_ROW;
-
-    /* find which row numbers are affected for full Erase */
-    rowIdxStart = addrStart/CY_FLASH_SIZEOF_ROW;
-    rowIdxEnd   = addrEnd/CY_FLASH_SIZEOF_ROW;
-
-    if(remStart != 0)
-    {/* first row is fragmented, move to next */
-        rowIdxStart++;
-    }
-
-    /* total number of rows for full erase */
-    rowNum = rowIdxEnd - rowIdxStart;
-    address = rowIdxStart*CY_FLASH_SIZEOF_ROW;
-
-    while(rowNum>0)
-    {
-        rc = Cy_Flash_EraseRow(address);
-        assert(rc == 0);
-        address += CY_FLASH_SIZEOF_ROW;
-        rowNum--;
-    }
-
-    /* if Start of erase area is unaligned */
-    if(remStart != 0)
-    {
-        /* first row is fragmented, shift left by one*/
-        rowIdxStart--;
-
-        /* find start address of fragmented row */
-        address = rowIdxStart*CY_FLASH_SIZEOF_ROW;
-
-        /* store fragmented row contents first */
-        memcpy((void *)buff, (const void*)address, remStart);
-
-        /* erase fragmented row */
-        rc = Cy_Flash_EraseRow(address);
-        assert(rc == 0);
-
-        /* write stored back */
-        rc = psoc6_flash_write_hal(buff, address, remStart);
-        assert(rc == 0);
-    }
-    /* if End of erase area is unaligned */
-    if(remEnd != 0)
-    {
-        /* find start address of fragmented row */
-        address = rowIdxEnd*CY_FLASH_SIZEOF_ROW;
-
-        /* store fragmented row contents first */
-        memcpy((void *)buff, (const void*)addrEnd, CY_FLASH_SIZEOF_ROW-remEnd);
-
-        /* erase fragmented row */
-        rc = Cy_Flash_EraseRow(address);
-        assert(rc == 0);
-
-        /* write stored back */
-        rc = psoc6_flash_write_hal(buff, addrEnd, CY_FLASH_SIZEOF_ROW-remEnd);
-        assert(rc == 0);
-    }
-    return rc;
-}
-
-/*******************************************************************************
-* Function Name: psoc6_flash_write_hal
-****************************************************************************//**
-*
-*  This function writes the data to the PSOC6's Flash. It will check the
-*  appropriate alignment of a start address and also perform an address range
-*  check based on the length before performing the write operation.
-*  This function performs memory compare and writes only row where there are new
-*  data to write.
-*
-*  \param addr:   Pointer to the buffer containing the data to be stored.
-*  \param data:   Pointer to the array or variable in the flash.
-*  \param len:    The length of the data in bytes.
-*
-* \return
-*  PSOC6_WR_SUCCESS                     A successful write
-*  PSOC6_WR_ERROR_INVALID_PARAMETER     At least one of the input parameters is invalid
-*  PSOC6_WR__ERROR_FLASH_WRITE          Error in flash Write
-*
-*******************************************************************************/
-int psoc6_flash_write_hal(uint8_t data[],
-                             uint32_t address,
-                             uint32_t len)
-{
-    int retCode;
-    cy_en_flashdrv_status_t rc = CY_FLASH_DRV_SUCCESS;
-
-    uint32_t writeBuffer[CY_FLASH_SIZEOF_ROW / sizeof(uint32_t)];
-    uint32_t rowId;
-    uint32_t dstIndex;
-    uint32_t srcIndex = 0u;
-    uint32_t eeOffset;
-    uint32_t byteOffset;
-    uint32_t rowsNotEqual;
-    uint8_t *writeBufferPointer;
-
-    eeOffset = (uint32_t)address;
-    writeBufferPointer = (uint8_t*)writeBuffer;
-
-    bool cond1;
-
-    /* Make sure, that varFlash[] points to Flash */
-    cond1 = ((eeOffset >= CY_FLASH_BASE) &&
-            ((eeOffset + len) <= (CY_FLASH_BASE + CY_FLASH_SIZE)));
-
-    if(cond1)
-    {
-        eeOffset -= CY_FLASH_BASE;
-        rowId = eeOffset / CY_FLASH_SIZEOF_ROW;
-        byteOffset = CY_FLASH_SIZEOF_ROW * rowId;
-
-        while((srcIndex < len) && (rc == CY_FLASH_DRV_SUCCESS))
-        {
-            rowsNotEqual = 0u;
-            /* Copy data to the write buffer either from the source buffer or from the flash */
-            for(dstIndex = 0u; dstIndex < CY_FLASH_SIZEOF_ROW; dstIndex++)
-            {
-                if((byteOffset >= eeOffset) && (srcIndex < len))
-                {
-                    writeBufferPointer[dstIndex] = data[srcIndex];
-                    /* Detect that row programming is required */
-                    if((rowsNotEqual == 0u) && (CY_GET_REG8(CY_FLASH_BASE + byteOffset) != data[srcIndex]))
-                    {
-                        rowsNotEqual = 1u;
-                    }
-                    srcIndex++;
-                }
-                else
-                {
-                    writeBufferPointer[dstIndex] = CY_GET_REG8(CY_FLASH_BASE + byteOffset);
-                }
-                byteOffset++;
-            }
-
-            if(rowsNotEqual != 0u)
-            {
-                /* Write flash row */
-                rc = Cy_Flash_WriteRow((rowId * CY_FLASH_SIZEOF_ROW) + CY_FLASH_BASE, writeBuffer);
-            }
-
-            /* Go to the next row */
-            rowId++;
-        }
-    }
-    else
-    {
-        rc = CY_FLASH_DRV_INVALID_INPUT_PARAMETERS;
-    }
-
-    /* Return error code */
-    switch(rc)
-    {
-        case CY_FLASH_DRV_SUCCESS:
-            retCode = PSOC6_WR_SUCCESS;
-            break;
-
-        case CY_FLASH_DRV_INVALID_INPUT_PARAMETERS:
-        case CY_FLASH_DRV_INVALID_FLASH_ADDR:
-            retCode = PSOC6_WR_ERROR_INVALID_PARAMETER;
-            break;
-
-        default:
-            retCode = PSOC6_WR_ERROR_FLASH_WRITE;
-            break;
-    }
-    return(retCode);
-}
diff --git a/boot/cypress/cy_flash_pal/cy_smif_psoc6.c b/boot/cypress/cy_flash_pal/cy_smif_psoc6.c
new file mode 100644
index 0000000..62f7137
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/cy_smif_psoc6.c
@@ -0,0 +1,143 @@
+/***************************************************************************//**
+* \file cy_smif_psoc6.c
+* \version 1.0
+*
+* \brief
+*  This is the source file of external flash driver adoption layer between PSoC6
+*  and standard MCUBoot code.
+*
+********************************************************************************
+* \copyright
+*
+* (c) 2020, Cypress Semiconductor Corporation
+* or a subsidiary of Cypress Semiconductor Corporation. All rights
+* reserved.
+*
+* This software, including source code, documentation and related
+* materials ("Software"), is owned by Cypress Semiconductor
+* Corporation or one of its subsidiaries ("Cypress") and is protected by
+* and subject to worldwide patent protection (United States and foreign),
+* United States copyright laws and international treaty provisions.
+* Therefore, you may use this Software only as provided in the license
+* agreement accompanying the software package from which you
+* obtained this Software ("EULA").
+*
+* If no EULA applies, Cypress hereby grants you a personal, non-
+* exclusive, non-transferable license to copy, modify, and compile the
+* Software source code solely for use in connection with Cypress?s
+* integrated circuit products. Any reproduction, modification, translation,
+* compilation, or representation of this Software except as specified
+* above is prohibited without the express written permission of Cypress.
+*
+* Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO
+* WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING,
+* BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+* PARTICULAR PURPOSE. Cypress reserves the right to make
+* changes to the Software without notice. Cypress does not assume any
+* liability arising out of the application or use of the Software or any
+* product or circuit described in the Software. Cypress does not
+* authorize its products for use in any products where a malfunction or
+* failure of the Cypress product may reasonably be expected to result in
+* significant property damage, injury or death ("High Risk Product"). By
+* including Cypress's product in a High Risk Product, the manufacturer
+* of such system or application assumes all risk of such use and in doing
+* so agrees to indemnify Cypress against all liability.
+*
+******************************************************************************/
+#include "string.h"
+#include "stdlib.h"
+#include "stdbool.h"
+
+#ifdef MCUBOOT_HAVE_ASSERT_H
+#include "mcuboot_config/mcuboot_assert.h"
+#else
+#include <assert.h>
+#endif
+
+#include "flash_map_backend/flash_map_backend.h"
+#include <sysflash/sysflash.h>
+
+#include "cy_device_headers.h"
+#include "cy_smif_psoc6.h"
+#include "cy_flash.h"
+#include "cy_syspm.h"
+
+#include "flash_qspi.h"
+
+#define PSOC6_WR_SUCCESS                    (0)
+#define PSOC6_WR_ERROR_INVALID_PARAMETER    (1)
+#define PSOC6_WR_ERROR_FLASH_WRITE          (2)
+
+#define PSOC6_FLASH_ERASE_BLOCK_SIZE	CY_FLASH_SIZEOF_ROW /* PSoC6 Flash erases by Row */
+
+int psoc6_smif_read(const struct flash_area *fap,
+                                        off_t addr,
+                                        void *data,
+                                        size_t len)
+{
+    int rc = -1;
+    cy_stc_smif_mem_config_t *cfg;
+    cy_en_smif_status_t st;
+    uint32_t address;
+
+    cfg = qspi_get_memory_config(FLASH_DEVICE_GET_EXT_INDEX(fap->fa_device_id));
+
+    address = addr - CY_SMIF_BASE_MEM_OFFSET;
+
+    st = Cy_SMIF_MemRead(qspi_get_device(), cfg, address, data, len, qspi_get_context());
+    if (st == CY_SMIF_SUCCESS) {
+        rc = 0;
+    }
+    return rc;
+}
+
+int psoc6_smif_write(const struct flash_area *fap,
+                                        off_t addr,
+                                        const void *data,
+                                        size_t len)
+{
+    int rc = -1;
+    cy_en_smif_status_t st;
+    cy_stc_smif_mem_config_t *cfg;
+    uint32_t address;
+
+    cfg =  qspi_get_memory_config(FLASH_DEVICE_GET_EXT_INDEX(fap->fa_device_id));
+
+    address = addr - CY_SMIF_BASE_MEM_OFFSET;
+
+    st = Cy_SMIF_MemWrite(qspi_get_device(), cfg, address, data, len, qspi_get_context());
+    if (st == CY_SMIF_SUCCESS) {
+        rc = 0;
+    }
+    return rc;
+}
+
+int psoc6_smif_erase(off_t addr, size_t size)
+{
+    int rc = -1;
+    cy_en_smif_status_t st;
+    uint32_t address;
+
+    /* It is erase sector-only
+     *
+     * There is no power-safe way to erase flash partially
+     * this leads upgrade slots have to be at least
+     * eraseSectorSize far from each other;
+     */
+    cy_stc_smif_mem_config_t *memCfg = qspi_get_memory_config(0);
+
+    address = (addr - CY_SMIF_BASE_MEM_OFFSET ) & ~((uint32_t)(memCfg->deviceCfg->eraseSize - 1u));
+
+    (void)size;
+
+    st = Cy_SMIF_MemEraseSector(qspi_get_device(),
+                                    memCfg,
+                                    address,
+                                    memCfg->deviceCfg->eraseSize,
+                                    qspi_get_context());
+    if (st == CY_SMIF_SUCCESS) {
+        rc = 0;
+    }
+    return rc;
+}
diff --git a/boot/cypress/cy_flash_pal/flash_qspi/flash_qspi.c b/boot/cypress/cy_flash_pal/flash_qspi/flash_qspi.c
new file mode 100644
index 0000000..83e1855
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_qspi/flash_qspi.c
@@ -0,0 +1,475 @@
+/*
+ * 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.
+ */
+/***************************************************************************//**
+* \file flash_qspi.c
+* \version 1.0
+*
+* \brief
+*  This is the source file of external flash driver adaptation layer between PSoC6
+*  and standard MCUBoot code.
+*
+********************************************************************************
+* \copyright
+*
+* (c) 2020, Cypress Semiconductor Corporation
+* or a subsidiary of Cypress Semiconductor Corporation. All rights
+* reserved.
+*
+* This software, including source code, documentation and related
+* materials ("Software"), is owned by Cypress Semiconductor
+* Corporation or one of its subsidiaries ("Cypress") and is protected by
+* and subject to worldwide patent protection (United States and foreign),
+* United States copyright laws and international treaty provisions.
+* Therefore, you may use this Software only as provided in the license
+* agreement accompanying the software package from which you
+* obtained this Software ("EULA").
+*
+* If no EULA applies, Cypress hereby grants you a personal, non-
+* exclusive, non-transferable license to copy, modify, and compile the
+* Software source code solely for use in connection with Cypress?s
+* integrated circuit products. Any reproduction, modification, translation,
+* compilation, or representation of this Software except as specified
+* above is prohibited without the express written permission of Cypress.
+*
+* Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO
+* WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING,
+* BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+* PARTICULAR PURPOSE. Cypress reserves the right to make
+* changes to the Software without notice. Cypress does not assume any
+* liability arising out of the application or use of the Software or any
+* product or circuit described in the Software. Cypress does not
+* authorize its products for use in any products where a malfunction or
+* failure of the Cypress product may reasonably be expected to result in
+* significant property damage, injury or death ("High Risk Product"). By
+* including Cypress's product in a High Risk Product, the manufacturer
+* of such system or application assumes all risk of such use and in doing
+* so agrees to indemnify Cypress against all liability.
+*
+******************************************************************************/
+#include "cy_pdl.h"
+#include <stdio.h>
+#include "flash_qspi.h"
+
+#define CY_SMIF_SYSCLK_HFCLK_DIVIDER     CY_SYSCLK_CLKHF_DIVIDE_BY_4
+
+/* This is the board specific stuff that should align with your board.
+ *
+ * QSPI resources:
+ *
+ * SS0  - P11_2
+ * SS1  - P11_1
+ * SS2  - P11_0
+ * SS3  - P12_4
+ *
+ * D3  - P11_3
+ * D2  - P11_4
+ * D1  - P11_5
+ * D0  - P11_6
+ *
+ * SCK - P11_7
+ *
+ * SMIF Block - SMIF0
+ *
+ */
+
+/* SMIF SlaveSelect Configurations */
+struct qspi_ss_config
+{
+    GPIO_PRT_Type* SS_Port;
+    int SS_Pin;
+    en_hsiom_sel_t SS_Mux;
+};
+
+#if (defined(PSOC_064_2M) || \
+    defined(PSOC_064_1M) || \
+    defined(PSOC_062_2M))
+    #define CY_BOOTLOADER_SMIF_SS_CFG_NUM 4
+#elif defined(PSOC_064_512K)
+    #define CY_BOOTLOADER_SMIF_SS_CFG_NUM 3
+#else
+#error "Platform device name is unsupported."
+#endif
+struct qspi_ss_config qspi_SS_Configuration[CY_BOOTLOADER_SMIF_SS_CFG_NUM] =
+{
+    {
+        .SS_Port = GPIO_PRT11,
+        .SS_Pin = 2,
+        .SS_Mux = P11_2_SMIF_SPI_SELECT0
+    },
+    {
+        .SS_Port = GPIO_PRT11,
+        .SS_Pin = 1,
+        .SS_Mux = P11_1_SMIF_SPI_SELECT1
+    },
+    {
+        .SS_Port = GPIO_PRT11,
+        .SS_Pin = 0,
+        .SS_Mux = P11_0_SMIF_SPI_SELECT2
+    },
+#if(CY_BOOTLOADER_SMIF_SS_CFG_NUM > 3)
+    {
+        .SS_Port = GPIO_PRT12,
+        .SS_Pin = 4,
+        .SS_Mux = P12_4_SMIF_SPI_SELECT3
+    }
+#endif
+};
+
+static GPIO_PRT_Type *D3Port = GPIO_PRT11;
+static int D3Pin = 3;
+static en_hsiom_sel_t D3MuxPort = P11_3_SMIF_SPI_DATA3;
+
+static GPIO_PRT_Type *D2Port = GPIO_PRT11;
+static int D2Pin = 4;
+static en_hsiom_sel_t D2MuxPort = P11_4_SMIF_SPI_DATA2;
+
+static GPIO_PRT_Type *D1Port = GPIO_PRT11;
+static int D1Pin = 5;
+static en_hsiom_sel_t D1MuxPort = P11_5_SMIF_SPI_DATA1;
+
+static GPIO_PRT_Type *D0Port = GPIO_PRT11;
+static int D0Pin = 6;
+static en_hsiom_sel_t D0MuxPort = P11_6_SMIF_SPI_DATA0;
+
+static GPIO_PRT_Type *SCKPort = GPIO_PRT11;
+static int SCKPin = 7;
+static en_hsiom_sel_t SCKMuxPort = P11_7_SMIF_SPI_CLK;
+
+static SMIF_Type *QSPIPort  = SMIF0;
+
+cy_stc_smif_mem_cmd_t sfdpcmd =
+{
+    .command = 0x5A,
+    .cmdWidth = CY_SMIF_WIDTH_SINGLE,
+    .addrWidth = CY_SMIF_WIDTH_SINGLE,
+    .mode = 0xFFFFFFFFU,
+    .dummyCycles = 8,
+    .dataWidth = CY_SMIF_WIDTH_SINGLE,
+};
+
+static cy_stc_smif_mem_cmd_t rdcmd0;
+static cy_stc_smif_mem_cmd_t wrencmd0;
+static cy_stc_smif_mem_cmd_t wrdiscmd0;
+static cy_stc_smif_mem_cmd_t erasecmd0;
+static cy_stc_smif_mem_cmd_t chiperasecmd0;
+static cy_stc_smif_mem_cmd_t pgmcmd0;
+static cy_stc_smif_mem_cmd_t readsts0;
+static cy_stc_smif_mem_cmd_t readstsqecmd0;
+static cy_stc_smif_mem_cmd_t writestseqcmd0;
+
+static cy_stc_smif_mem_device_cfg_t dev_sfdp_0 =
+{
+    .numOfAddrBytes = 4,
+    .readSfdpCmd = &sfdpcmd,
+    .readCmd = &rdcmd0,
+    .writeEnCmd = &wrencmd0,
+    .writeDisCmd = &wrdiscmd0,
+    .programCmd = &pgmcmd0,
+    .eraseCmd = &erasecmd0,
+    .chipEraseCmd = &chiperasecmd0,
+    .readStsRegWipCmd = &readsts0,
+    .readStsRegQeCmd = &readstsqecmd0,
+    .writeStsRegQeCmd = &writestseqcmd0,
+};
+
+static cy_stc_smif_mem_config_t mem_sfdp_0 =
+{
+    /* The base address the memory slave is mapped to in the PSoC memory map.
+    Valid when the memory-mapped mode is enabled. */
+    .baseAddress = 0x18000000U,
+    /* The size allocated in the PSoC memory map, for the memory slave device.
+    The size is allocated from the base address. Valid when the memory mapped mode is enabled. */
+/*    .memMappedSize = 0x4000000U, */
+    .flags = CY_SMIF_FLAG_DETECT_SFDP,
+    .slaveSelect = CY_SMIF_SLAVE_SELECT_0,
+    .dataSelect = CY_SMIF_DATA_SEL0,
+    .deviceCfg = &dev_sfdp_0
+};
+
+cy_stc_smif_mem_config_t *mems_sfdp[1] =
+{
+    &mem_sfdp_0
+};
+
+/* make it exported if used in TOC (cy_serial_flash_prog.c) */
+/* cy_stc_smif_block_config_t smifBlockConfig_sfdp = */
+static cy_stc_smif_block_config_t smifBlockConfig_sfdp =
+{
+    .memCount = 1,
+    .memConfig = mems_sfdp,
+};
+
+static cy_stc_smif_block_config_t *smif_blk_config;
+
+static cy_stc_smif_context_t QSPI_context;
+
+cy_stc_smif_config_t const QSPI_config =
+{
+    .mode = CY_SMIF_NORMAL,
+    .deselectDelay = 1,
+    .rxClockSel = CY_SMIF_SEL_INV_INTERNAL_CLK,
+    .blockEvent = CY_SMIF_BUS_ERROR
+};
+
+cy_stc_sysint_t smifIntConfig =
+{/* ATTENTION: make sure proper Interrupts configured for CM0p or M4 cores */
+    .intrSrc = NvicMux7_IRQn,
+    .cm0pSrc = smif_interrupt_IRQn,
+    .intrPriority = 1
+};
+
+/* SMIF pinouts configurations */
+static cy_stc_gpio_pin_config_t QSPI_SS_config =
+{
+    .outVal = 1,
+    .driveMode = CY_GPIO_DM_STRONG_IN_OFF,
+    .hsiom = P11_2_SMIF_SPI_SELECT0, /* lets use SS0 by default */
+    .intEdge = CY_GPIO_INTR_DISABLE,
+    .intMask = 0UL,
+    .vtrip = CY_GPIO_VTRIP_CMOS,
+    .slewRate = CY_GPIO_SLEW_FAST,
+    .driveSel = CY_GPIO_DRIVE_1_2,
+    .vregEn = 0UL,
+    .ibufMode = 0UL,
+    .vtripSel = 0UL,
+    .vrefSel = 0UL,
+    .vohSel = 0UL,
+};
+const cy_stc_gpio_pin_config_t QSPI_DATA3_config =
+{
+    .outVal = 1,
+    .driveMode = CY_GPIO_DM_STRONG,
+    .hsiom = P11_3_SMIF_SPI_DATA3,
+    .intEdge = CY_GPIO_INTR_DISABLE,
+    .intMask = 0UL,
+    .vtrip = CY_GPIO_VTRIP_CMOS,
+    .slewRate = CY_GPIO_SLEW_FAST,
+    .driveSel = CY_GPIO_DRIVE_1_2,
+    .vregEn = 0UL,
+    .ibufMode = 0UL,
+    .vtripSel = 0UL,
+    .vrefSel = 0UL,
+    .vohSel = 0UL,
+};
+const cy_stc_gpio_pin_config_t QSPI_DATA2_config =
+{
+    .outVal = 1,
+    .driveMode = CY_GPIO_DM_STRONG,
+    .hsiom = P11_4_SMIF_SPI_DATA2,
+    .intEdge = CY_GPIO_INTR_DISABLE,
+    .intMask = 0UL,
+    .vtrip = CY_GPIO_VTRIP_CMOS,
+    .slewRate = CY_GPIO_SLEW_FAST,
+    .driveSel = CY_GPIO_DRIVE_1_2,
+    .vregEn = 0UL,
+    .ibufMode = 0UL,
+    .vtripSel = 0UL,
+    .vrefSel = 0UL,
+    .vohSel = 0UL,
+};
+const cy_stc_gpio_pin_config_t QSPI_DATA1_config =
+{
+    .outVal = 1,
+    .driveMode = CY_GPIO_DM_STRONG,
+    .hsiom = P11_5_SMIF_SPI_DATA1,
+    .intEdge = CY_GPIO_INTR_DISABLE,
+    .intMask = 0UL,
+    .vtrip = CY_GPIO_VTRIP_CMOS,
+    .slewRate = CY_GPIO_SLEW_FAST,
+    .driveSel = CY_GPIO_DRIVE_1_2,
+    .vregEn = 0UL,
+    .ibufMode = 0UL,
+    .vtripSel = 0UL,
+    .vrefSel = 0UL,
+    .vohSel = 0UL,
+};
+const cy_stc_gpio_pin_config_t QSPI_DATA0_config =
+{
+    .outVal = 1,
+    .driveMode = CY_GPIO_DM_STRONG,
+    .hsiom = P11_6_SMIF_SPI_DATA0,
+    .intEdge = CY_GPIO_INTR_DISABLE,
+    .intMask = 0UL,
+    .vtrip = CY_GPIO_VTRIP_CMOS,
+    .slewRate = CY_GPIO_SLEW_FAST,
+    .driveSel = CY_GPIO_DRIVE_1_2,
+    .vregEn = 0UL,
+    .ibufMode = 0UL,
+    .vtripSel = 0UL,
+    .vrefSel = 0UL,
+    .vohSel = 0UL,
+};
+const cy_stc_gpio_pin_config_t QSPI_SCK_config =
+{
+    .outVal = 1,
+    .driveMode = CY_GPIO_DM_STRONG_IN_OFF,
+    .hsiom = P11_7_SMIF_SPI_CLK,
+    .intEdge = CY_GPIO_INTR_DISABLE,
+    .intMask = 0UL,
+    .vtrip = CY_GPIO_VTRIP_CMOS,
+    .slewRate = CY_GPIO_SLEW_FAST,
+    .driveSel = CY_GPIO_DRIVE_1_2,
+    .vregEn = 0UL,
+    .ibufMode = 0UL,
+    .vtripSel = 0UL,
+    .vrefSel = 0UL,
+    .vohSel = 0UL,
+};
+
+void Isr_SMIF(void)
+{
+    Cy_SMIF_Interrupt(QSPIPort, &QSPI_context);
+}
+
+cy_en_smif_status_t qspi_init_hardware()
+{
+    cy_en_smif_status_t st;
+
+
+    Cy_GPIO_Pin_Init(D3Port, D3Pin, &QSPI_DATA3_config);
+    Cy_GPIO_SetHSIOM(D3Port, D3Pin, D3MuxPort);
+
+    Cy_GPIO_Pin_Init(D2Port, D2Pin, &QSPI_DATA2_config);
+    Cy_GPIO_SetHSIOM(D2Port, D2Pin, D2MuxPort);
+
+    Cy_GPIO_Pin_Init(D1Port, D1Pin, &QSPI_DATA1_config);
+    Cy_GPIO_SetHSIOM(D1Port, D1Pin, D1MuxPort);
+
+    Cy_GPIO_Pin_Init(D0Port, D0Pin, &QSPI_DATA0_config);
+    Cy_GPIO_SetHSIOM(D0Port, D0Pin, D0MuxPort);
+
+    Cy_GPIO_Pin_Init(SCKPort, SCKPin, &QSPI_SCK_config);
+    Cy_GPIO_SetHSIOM(SCKPort, SCKPin, SCKMuxPort);
+
+    Cy_SysClk_ClkHfSetSource(CY_SYSCLK_CLKHF_IN_CLKPATH2, CY_SYSCLK_CLKHF_IN_CLKPATH0);
+    Cy_SysClk_ClkHfSetDivider(CY_SYSCLK_CLKHF_IN_CLKPATH2, CY_SMIF_SYSCLK_HFCLK_DIVIDER);
+    Cy_SysClk_ClkHfEnable(CY_SYSCLK_CLKHF_IN_CLKPATH2);
+
+    /*
+     * Setup the interrupt for the SMIF block.  For the CM0 there
+     * is a two stage process to setup the interrupts.
+     */
+    Cy_SysInt_Init(&smifIntConfig, Isr_SMIF);
+
+    st = Cy_SMIF_Init(QSPIPort, &QSPI_config, 1000, &QSPI_context);
+    if (st != CY_SMIF_SUCCESS)
+    {
+        return st;
+    }
+    NVIC_EnableIRQ(smifIntConfig.intrSrc); /* Finally, Enable the SMIF interrupt */
+
+    Cy_SMIF_Enable(QSPIPort, &QSPI_context);
+
+    return CY_SMIF_SUCCESS;
+}
+
+cy_stc_smif_mem_config_t *qspi_get_memory_config(int index)
+{
+    return smif_blk_config->memConfig[index];
+}
+
+SMIF_Type *qspi_get_device()
+{
+    return QSPIPort;
+}
+
+cy_stc_smif_context_t *qspi_get_context()
+{
+    return &QSPI_context;
+}
+
+cy_en_smif_status_t qspi_init(cy_stc_smif_block_config_t *blk_config)
+{
+    cy_en_smif_status_t st;
+
+    st = qspi_init_hardware();
+    if (st == CY_SMIF_SUCCESS)
+    {
+        smif_blk_config = blk_config;
+        st = Cy_SMIF_MemInit(QSPIPort, smif_blk_config, &QSPI_context);
+    }
+    return st;
+}
+
+cy_en_smif_status_t qspi_init_sfdp(uint32_t smif_id)
+{
+    cy_en_smif_status_t stat = CY_SMIF_SUCCESS;
+
+    cy_stc_smif_mem_config_t **memCfg = smifBlockConfig_sfdp.memConfig;
+
+    GPIO_PRT_Type *SS_Port;
+    int SS_Pin;
+    en_hsiom_sel_t SS_MuxPort;
+
+    switch(smif_id)
+    {
+    case 1:
+        (*memCfg)->slaveSelect = CY_SMIF_SLAVE_SELECT_0;
+        break;
+    case 2:
+        (*memCfg)->slaveSelect = CY_SMIF_SLAVE_SELECT_1;
+        break;
+    case 3:
+        (*memCfg)->slaveSelect = CY_SMIF_SLAVE_SELECT_2;
+        break;
+#if(CY_BOOTLOADER_SMIF_SS_CFG_NUM > 3)
+    case 4:
+        (*memCfg)->slaveSelect = CY_SMIF_SLAVE_SELECT_3;
+        break;
+#endif
+    default:
+        stat = -1;
+        break;
+    }
+
+    if(CY_SMIF_SUCCESS == stat)
+    {
+        SS_Port = qspi_SS_Configuration[smif_id-1].SS_Port;
+        SS_Pin = qspi_SS_Configuration[smif_id-1].SS_Pin;
+        SS_MuxPort = qspi_SS_Configuration[smif_id-1].SS_Mux;
+
+        QSPI_SS_config.hsiom = SS_MuxPort;
+
+        Cy_GPIO_Pin_Init(SS_Port, SS_Pin, &QSPI_SS_config);
+        Cy_GPIO_SetHSIOM(SS_Port, SS_Pin, SS_MuxPort);
+
+        stat = qspi_init(&smifBlockConfig_sfdp);
+    }
+    return stat;
+}
+
+uint32_t qspi_get_prog_size(void)
+{
+    cy_stc_smif_mem_config_t **memCfg = smifBlockConfig_sfdp.memConfig;
+    return (*memCfg)->deviceCfg->programSize;
+}
+
+uint32_t qspi_get_erase_size(void)
+{
+    cy_stc_smif_mem_config_t **memCfg = smifBlockConfig_sfdp.memConfig;
+    return (*memCfg)->deviceCfg->eraseSize;
+}
+
+uint32_t qspi_get_mem_size(void)
+{
+    cy_stc_smif_mem_config_t **memCfg = smifBlockConfig_sfdp.memConfig;
+    return (*memCfg)->deviceCfg->memSize;
+}
+
diff --git a/boot/cypress/cy_flash_pal/flash_qspi/flash_qspi.h b/boot/cypress/cy_flash_pal/flash_qspi/flash_qspi.h
new file mode 100644
index 0000000..e7e213b
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/flash_qspi/flash_qspi.h
@@ -0,0 +1,68 @@
+/***************************************************************************//**
+* \file flash_qspi.h
+* \version 1.0
+*
+* \brief
+*  This is the header file for PSoC6 external flash driver adoption layer.
+*
+********************************************************************************
+* \copyright
+*
+* © 2020, Cypress Semiconductor Corporation
+* or a subsidiary of Cypress Semiconductor Corporation. All rights
+* reserved.
+*
+* This software, including source code, documentation and related
+* materials ("Software"), is owned by Cypress Semiconductor
+* Corporation or one of its subsidiaries ("Cypress") and is protected by
+* and subject to worldwide patent protection (United States and foreign),
+* United States copyright laws and international treaty provisions.
+* Therefore, you may use this Software only as provided in the license
+* agreement accompanying the software package from which you
+* obtained this Software ("EULA").
+*
+* If no EULA applies, Cypress hereby grants you a personal, non-
+* exclusive, non-transferable license to copy, modify, and compile the
+* Software source code solely for use in connection with Cypress?s
+* integrated circuit products. Any reproduction, modification, translation,
+* compilation, or representation of this Software except as specified
+* above is prohibited without the express written permission of Cypress.
+*
+* Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO
+* WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING,
+* BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+* PARTICULAR PURPOSE. Cypress reserves the right to make
+* changes to the Software without notice. Cypress does not assume any
+* liability arising out of the application or use of the Software or any
+* product or circuit described in the Software. Cypress does not
+* authorize its products for use in any products where a malfunction or
+* failure of the Cypress product may reasonably be expected to result in
+* significant property damage, injury or death ("High Risk Product"). By
+* including Cypress's product in a High Risk Product, the manufacturer
+* of such system or application assumes all risk of such use and in doing
+* so agrees to indemnify Cypress against all liability.
+*
+******************************************************************************/
+#ifndef __FLASH_QSPI_H__
+#define __FLASH_QSPI_H__
+
+#include <stdint.h>
+#include "cy_pdl.h"
+
+/* make it exported if used in TOC (cy_serial_flash_prog.c) */
+/* cy_stc_smif_block_config_t smifBlockConfig_sfdp; */
+
+cy_en_smif_status_t qspi_init_sfdp(uint32_t smif_id);
+cy_en_smif_status_t qspi_init(cy_stc_smif_block_config_t *blk_config);
+cy_en_smif_status_t qspi_init_hardware(void);
+uint32_t qspi_get_prog_size(void);
+uint32_t qspi_get_erase_size(void);
+uint32_t qspi_get_mem_size(void);
+
+SMIF_Type *qspi_get_device(void);
+cy_stc_smif_context_t *qspi_get_context(void);
+cy_stc_smif_mem_config_t *qspi_get_memory_config(int index);
+void qspi_dump_device(cy_stc_smif_mem_device_cfg_t *dev);
+
+#endif /* __FLASH_QSPI_H__ */
diff --git a/boot/cypress/cy_flash_pal/include/cy_flash_psoc6.h b/boot/cypress/cy_flash_pal/include/cy_flash_psoc6.h
deleted file mode 100644
index 09cea98..0000000
--- a/boot/cypress/cy_flash_pal/include/cy_flash_psoc6.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2018 Nordic Semiconductor ASA
- * Copyright (c) 2015 Runtime Inc
- * Copyright (c) 2020 Cypress Semiconductor Corporation
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- /*
- * 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.
- */
- /*******************************************************************************/
-
-#ifndef CY_FLASH_PSOC6_H_
-#define CY_FLASH_PSOC6_H_
-
-#include "stddef.h"
-#include "stdbool.h"
-
-#ifndef off_t
-typedef long int off_t;
-#endif
-
-int psoc6_flash_read(off_t addr, void *data, size_t len);
-int psoc6_flash_write(off_t addr, const void *data, size_t len);
-int psoc6_flash_erase(off_t addr, size_t size);
-
-int psoc6_flash_write_hal(uint8_t data[],
-                            uint32_t address,
-                            uint32_t len);
-#endif /* CY_FLASH_PSOC6_H_ */
diff --git a/boot/cypress/cy_flash_pal/include/cy_smif_psoc6.h b/boot/cypress/cy_flash_pal/include/cy_smif_psoc6.h
new file mode 100644
index 0000000..fe1150d
--- /dev/null
+++ b/boot/cypress/cy_flash_pal/include/cy_smif_psoc6.h
@@ -0,0 +1,64 @@
+/***************************************************************************//**
+* \file cy_smif_psoc6.h
+* \version 1.0
+*
+* \brief
+*  This is the header file for PSoC6 SMIF driver adoption layer.
+*
+********************************************************************************
+* \copyright
+*
+* © 2019, Cypress Semiconductor Corporation
+* or a subsidiary of Cypress Semiconductor Corporation. All rights
+* reserved.
+*
+* This software, including source code, documentation and related
+* materials ("Software"), is owned by Cypress Semiconductor
+* Corporation or one of its subsidiaries ("Cypress") and is protected by
+* and subject to worldwide patent protection (United States and foreign),
+* United States copyright laws and international treaty provisions.
+* Therefore, you may use this Software only as provided in the license
+* agreement accompanying the software package from which you
+* obtained this Software ("EULA").
+*
+* If no EULA applies, Cypress hereby grants you a personal, non-
+* exclusive, non-transferable license to copy, modify, and compile the
+* Software source code solely for use in connection with Cypress?s
+* integrated circuit products. Any reproduction, modification, translation,
+* compilation, or representation of this Software except as specified
+* above is prohibited without the express written permission of Cypress.
+*
+* Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO
+* WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING,
+* BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+* PARTICULAR PURPOSE. Cypress reserves the right to make
+* changes to the Software without notice. Cypress does not assume any
+* liability arising out of the application or use of the Software or any
+* product or circuit described in the Software. Cypress does not
+* authorize its products for use in any products where a malfunction or
+* failure of the Cypress product may reasonably be expected to result in
+* significant property damage, injury or death ("High Risk Product"). By
+* including Cypress's product in a High Risk Product, the manufacturer
+* of such system or application assumes all risk of such use and in doing
+* so agrees to indemnify Cypress against all liability.
+*
+******************************************************************************/
+
+#ifndef CY_SMIF_PSOC6_H_
+#define CY_SMIF_PSOC6_H_
+
+#include "stddef.h"
+#include "stdbool.h"
+
+#include "flash_qspi.h"
+
+#ifndef off_t
+typedef long int off_t;
+#endif
+
+int psoc6_smif_read(const struct flash_area *fap, off_t addr, void *data, size_t len);
+int psoc6_smif_write(const struct flash_area *fap, off_t addr, const void *data, size_t len);
+int psoc6_smif_erase(off_t addr, size_t size);
+
+#endif /* CY_SMIF_PSOC6_H_ */
diff --git a/boot/cypress/cy_flash_pal/include/flash_map_backend/flash_map_backend.h b/boot/cypress/cy_flash_pal/include/flash_map_backend/flash_map_backend.h
index 5357232..da68618 100644
--- a/boot/cypress/cy_flash_pal/include/flash_map_backend/flash_map_backend.h
+++ b/boot/cypress/cy_flash_pal/include/flash_map_backend/flash_map_backend.h
@@ -30,6 +30,16 @@
 
 #include <mcuboot_config/mcuboot_config.h>
 #include "cy_flash.h"
+#define FLASH_DEVICE_INDEX_MASK                 (0x7F)
+#define FLASH_DEVICE_GET_EXT_INDEX(n)           ((n) & FLASH_DEVICE_INDEX_MASK)
+#define FLASH_DEVICE_EXTERNAL_FLAG              (0x80)
+#define FLASH_DEVICE_INTERNAL_FLASH             (0x7F)
+#define FLASH_DEVICE_EXTERNAL_FLASH(index)      (FLASH_DEVICE_EXTERNAL_FLAG | index)
+
+#ifndef CY_BOOT_EXTERNAL_DEVICE_INDEX
+/* assume first(one) SMIF device is used */
+#define CY_BOOT_EXTERNAL_DEVICE_INDEX            (0)
+#endif
 
 /**
  *
@@ -137,7 +147,9 @@
 
 int flash_area_id_from_multi_image_slot(int image_index, int slot);
 int flash_area_id_to_multi_image_slot(int image_index, int area_id);
-
+#ifdef MCUBOOT_USE_FLASH_AREA_GET_SECTORS
+int flash_area_get_sectors(int idx, uint32_t *cnt, struct flash_sector *ret);
+#endif
 /*
  * Returns the value expected to be read when accesing any erased
  * flash byte.