1 /***************************************************************************//**
2 * \file cy_smif_psoc6.c
3 * \version 1.0
4 *
5 * \brief
6 *  This is the source file of external flash driver adoption layer between PSoC6
7 *  and standard MCUBoot code.
8 *
9 ********************************************************************************
10 * \copyright
11 *
12 * (c) 2020, Cypress Semiconductor Corporation
13 * or a subsidiary of Cypress Semiconductor Corporation. All rights
14 * reserved.
15 *
16 * This software, including source code, documentation and related
17 * materials ("Software"), is owned by Cypress Semiconductor
18 * Corporation or one of its subsidiaries ("Cypress") and is protected by
19 * and subject to worldwide patent protection (United States and foreign),
20 * United States copyright laws and international treaty provisions.
21 * Therefore, you may use this Software only as provided in the license
22 * agreement accompanying the software package from which you
23 * obtained this Software ("EULA").
24 *
25 * If no EULA applies, Cypress hereby grants you a personal, non-
26 * exclusive, non-transferable license to copy, modify, and compile the
27 * Software source code solely for use in connection with Cypress?s
28 * integrated circuit products. Any reproduction, modification, translation,
29 * compilation, or representation of this Software except as specified
30 * above is prohibited without the express written permission of Cypress.
31 *
32 * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO
33 * WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING,
34 * BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED
35 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
36 * PARTICULAR PURPOSE. Cypress reserves the right to make
37 * changes to the Software without notice. Cypress does not assume any
38 * liability arising out of the application or use of the Software or any
39 * product or circuit described in the Software. Cypress does not
40 * authorize its products for use in any products where a malfunction or
41 * failure of the Cypress product may reasonably be expected to result in
42 * significant property damage, injury or death ("High Risk Product"). By
43 * including Cypress's product in a High Risk Product, the manufacturer
44 * of such system or application assumes all risk of such use and in doing
45 * so agrees to indemnify Cypress against all liability.
46 *
47 ******************************************************************************/
48 #include "string.h"
49 #include "stdlib.h"
50 #include "stdbool.h"
51 
52 #ifdef MCUBOOT_HAVE_ASSERT_H
53 #include "mcuboot_config/mcuboot_assert.h"
54 #else
55 #include <assert.h>
56 #endif
57 
58 #include "flash_map_backend/flash_map_backend.h"
59 #include <sysflash/sysflash.h>
60 
61 #include "cy_device_headers.h"
62 #include "cy_smif_psoc6.h"
63 #include "cy_flash.h"
64 #include "cy_syspm.h"
65 
66 #include "flash_qspi.h"
67 
68 #define PSOC6_WR_SUCCESS                    (0)
69 #define PSOC6_WR_ERROR_INVALID_PARAMETER    (1)
70 #define PSOC6_WR_ERROR_FLASH_WRITE          (2)
71 
72 #define PSOC6_FLASH_ERASE_BLOCK_SIZE	CY_FLASH_SIZEOF_ROW /* PSoC6 Flash erases by Row */
73 
psoc6_smif_read(const struct flash_area * fap,off_t addr,void * data,size_t len)74 int psoc6_smif_read(const struct flash_area *fap,
75                                         off_t addr,
76                                         void *data,
77                                         size_t len)
78 {
79     int rc = -1;
80     cy_stc_smif_mem_config_t *cfg;
81     cy_en_smif_status_t st;
82     uint32_t address;
83 
84     cfg = qspi_get_memory_config(FLASH_DEVICE_GET_EXT_INDEX(fap->fa_device_id));
85 
86     address = addr - CY_SMIF_BASE_MEM_OFFSET;
87 
88     st = Cy_SMIF_MemRead(qspi_get_device(), cfg, address, data, len, qspi_get_context());
89     if (st == CY_SMIF_SUCCESS) {
90         rc = 0;
91     }
92     return rc;
93 }
94 
psoc6_smif_write(const struct flash_area * fap,off_t addr,const void * data,size_t len)95 int psoc6_smif_write(const struct flash_area *fap,
96                                         off_t addr,
97                                         const void *data,
98                                         size_t len)
99 {
100     int rc = -1;
101     cy_en_smif_status_t st;
102     cy_stc_smif_mem_config_t *cfg;
103     uint32_t address;
104 
105     cfg =  qspi_get_memory_config(FLASH_DEVICE_GET_EXT_INDEX(fap->fa_device_id));
106 
107     address = addr - CY_SMIF_BASE_MEM_OFFSET;
108 
109     st = Cy_SMIF_MemWrite(qspi_get_device(), cfg, address, data, len, qspi_get_context());
110     if (st == CY_SMIF_SUCCESS) {
111         rc = 0;
112     }
113     return rc;
114 }
115 
psoc6_smif_erase(off_t addr,size_t size)116 int psoc6_smif_erase(off_t addr, size_t size)
117 {
118     int rc = -1;
119     cy_en_smif_status_t st;
120     uint32_t address;
121 
122     /* It is erase sector-only
123      *
124      * There is no power-safe way to erase flash partially
125      * this leads upgrade slots have to be at least
126      * eraseSectorSize far from each other;
127      */
128     cy_stc_smif_mem_config_t *memCfg = qspi_get_memory_config(0);
129 
130     address = (addr - CY_SMIF_BASE_MEM_OFFSET ) & ~((uint32_t)(memCfg->deviceCfg->eraseSize - 1u));
131 
132     (void)size;
133 
134     st = Cy_SMIF_MemEraseSector(qspi_get_device(),
135                                     memCfg,
136                                     address,
137                                     memCfg->deviceCfg->eraseSize,
138                                     qspi_get_context());
139     if (st == CY_SMIF_SUCCESS) {
140         rc = 0;
141     }
142     return rc;
143 }
144