blob: 4723af1874a97e85c10537182fa937e8c22e7b7e [file] [log] [blame]
Andrzej Puzdrowskib788c712018-04-12 12:42:49 +02001/*
2 * Copyright (c) 2018 Nordic Semiconductor ASA
3 * Copyright (c) 2015 Runtime Inc
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#include <zephyr.h>
Peter Bigot54c1e3f2020-01-25 05:50:12 -06009#include <drivers/flash.h>
Andrzej Puzdrowskib788c712018-04-12 12:42:49 +020010
11#include "target.h"
12
13#include <flash_map_backend/flash_map_backend.h>
Andrzej Puzdrowskib788c712018-04-12 12:42:49 +020014#include <sysflash/sysflash.h>
15
16#include "bootutil/bootutil_log.h"
17
Emanuele Di Santo9f1933d2018-11-20 10:59:59 +010018MCUBOOT_LOG_MODULE_DECLARE(mcuboot);
19
Kumar Gala32b61f32020-04-08 12:02:03 -050020#if (!defined(CONFIG_XTENSA) && defined(DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL))
Andrzej Puzdrowskib788c712018-04-12 12:42:49 +020021#define FLASH_DEVICE_ID SOC_FLASH_0_ID
Rajavardhan Gundi73bb71b2019-01-28 15:07:04 +053022#define FLASH_DEVICE_BASE CONFIG_FLASH_BASE_ADDRESS
Rajavardhan Gundi24321c32019-02-08 12:48:34 +053023#elif (defined(CONFIG_XTENSA) && defined(DT_JEDEC_SPI_NOR_0_LABEL))
Rajavardhan Gundi40c28e32018-12-09 13:32:01 +053024#define FLASH_DEVICE_ID SPI_FLASH_0_ID
Rajavardhan Gundi73bb71b2019-01-28 15:07:04 +053025#define FLASH_DEVICE_BASE 0
Rajavardhan Gundi40c28e32018-12-09 13:32:01 +053026#else
27#error "FLASH_DEVICE_ID could not be determined"
28#endif
Andrzej Puzdrowskib788c712018-04-12 12:42:49 +020029
Emanuele Di Santo205c8c62018-07-20 11:42:31 +020030static struct device *flash_dev;
31
32struct device *flash_device_get_binding(char *dev_name)
33{
34 if (!flash_dev) {
35 flash_dev = device_get_binding(dev_name);
36 }
37 return flash_dev;
38}
39
Andrzej Puzdrowskib788c712018-04-12 12:42:49 +020040int flash_device_base(uint8_t fd_id, uintptr_t *ret)
41{
42 if (fd_id != FLASH_DEVICE_ID) {
43 BOOT_LOG_ERR("invalid flash ID %d; expected %d",
44 fd_id, FLASH_DEVICE_ID);
45 return -EINVAL;
46 }
47 *ret = FLASH_DEVICE_BASE;
48 return 0;
49}
50
51/*
Andrzej Puzdrowski419a4752019-01-23 16:31:19 +010052 * This depends on the mappings defined in sysflash.h.
David Vincze2d736ad2019-02-18 11:50:22 +010053 * MCUBoot uses continuous numbering for the primary slot, the secondary slot,
54 * and the scratch while zephyr might number it differently.
Andrzej Puzdrowskib788c712018-04-12 12:42:49 +020055 */
Fabio Utzigb0f04732019-07-31 09:49:19 -030056int flash_area_id_from_multi_image_slot(int image_index, int slot)
Andrzej Puzdrowskib788c712018-04-12 12:42:49 +020057{
Fabio Utzigb0f04732019-07-31 09:49:19 -030058 switch (slot) {
59 case 0: return FLASH_AREA_IMAGE_PRIMARY(image_index);
60 case 1: return FLASH_AREA_IMAGE_SECONDARY(image_index);
Fabio Utzigc58842e2019-11-28 10:30:01 -030061#if !defined(CONFIG_BOOT_SWAP_USING_MOVE)
Fabio Utzigb0f04732019-07-31 09:49:19 -030062 case 2: return FLASH_AREA_IMAGE_SCRATCH;
Fabio Utzigc58842e2019-11-28 10:30:01 -030063#endif
Andrzej Puzdrowski419a4752019-01-23 16:31:19 +010064 }
65
66 return -EINVAL; /* flash_area_open will fail on that */
Andrzej Puzdrowskib788c712018-04-12 12:42:49 +020067}
Emanuele Di Santo205c8c62018-07-20 11:42:31 +020068
Fabio Utzigb0f04732019-07-31 09:49:19 -030069int flash_area_id_from_image_slot(int slot)
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +010070{
Fabio Utzigb0f04732019-07-31 09:49:19 -030071 return flash_area_id_from_multi_image_slot(0, slot);
72}
73
74int flash_area_id_to_multi_image_slot(int image_index, int area_id)
75{
76 if (area_id == FLASH_AREA_IMAGE_PRIMARY(image_index)) {
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +010077 return 0;
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +010078 }
Fabio Utzigb0f04732019-07-31 09:49:19 -030079 if (area_id == FLASH_AREA_IMAGE_SECONDARY(image_index)) {
David Vinczeb75c12a2019-03-22 14:58:33 +010080 return 1;
81 }
82
83 BOOT_LOG_ERR("invalid flash area ID");
84 return -1;
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +010085}
86
Fabio Utzigb0f04732019-07-31 09:49:19 -030087int flash_area_id_to_image_slot(int area_id)
88{
89 return flash_area_id_to_multi_image_slot(0, area_id);
90}
91
Emanuele Di Santo205c8c62018-07-20 11:42:31 +020092int flash_area_sector_from_off(off_t off, struct flash_sector *sector)
93{
94 int rc;
95 struct flash_pages_info page;
96
97 rc = flash_get_page_info_by_offs(flash_dev, off, &page);
98 if (rc) {
99 return rc;
100 }
101
102 sector->fs_off = page.start_offset;
103 sector->fs_size = page.size;
104
105 return rc;
Fabio Utzig42ad4462018-08-14 08:55:23 -0300106}
107
Fabio Utzigcea90f92018-09-19 08:12:46 -0300108#define ERASED_VAL 0xff
Fabio Utzig42ad4462018-08-14 08:55:23 -0300109uint8_t flash_area_erased_val(const struct flash_area *fap)
110{
111 (void)fap;
Fabio Utzigcea90f92018-09-19 08:12:46 -0300112 return ERASED_VAL;
113}
114
115int flash_area_read_is_empty(const struct flash_area *fa, uint32_t off,
116 void *dst, uint32_t len)
117{
118 uint8_t i;
119 uint8_t *u8dst;
120 int rc;
121
Andrzej Puzdrowski5f81b122018-10-09 12:18:49 +0200122 rc = flash_area_read(fa, off, dst, len);
Fabio Utzigcea90f92018-09-19 08:12:46 -0300123 if (rc) {
124 return -1;
125 }
126
127 for (i = 0, u8dst = (uint8_t *)dst; i < len; i++) {
128 if (u8dst[i] != ERASED_VAL) {
129 return 0;
130 }
131 }
132
133 return 1;
Fabio Utzig42ad4462018-08-14 08:55:23 -0300134}