blob: c5832cb33b3825105d0ef38adaa815b19e210ed1 [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>
Gerard Marull-Paretasaa041a22022-03-25 12:22:29 +01009#include <devicetree.h>
Peter Bigot54c1e3f2020-01-25 05:50:12 -060010#include <drivers/flash.h>
Andrzej Puzdrowskib788c712018-04-12 12:42:49 +020011
12#include "target.h"
13
14#include <flash_map_backend/flash_map_backend.h>
Andrzej Puzdrowskib788c712018-04-12 12:42:49 +020015#include <sysflash/sysflash.h>
16
17#include "bootutil/bootutil_log.h"
18
Carlos Falgueras GarcĂ­aa4b4b0f2021-06-22 10:00:22 +020019BOOT_LOG_MODULE_DECLARE(mcuboot);
Emanuele Di Santo9f1933d2018-11-20 10:59:59 +010020
Gerard Marull-Paretasaa041a22022-03-25 12:22:29 +010021#if (!defined(CONFIG_XTENSA) && DT_HAS_CHOSEN(zephyr_flash_controller))
Andrzej Puzdrowskib788c712018-04-12 12:42:49 +020022#define FLASH_DEVICE_ID SOC_FLASH_0_ID
Rajavardhan Gundi73bb71b2019-01-28 15:07:04 +053023#define FLASH_DEVICE_BASE CONFIG_FLASH_BASE_ADDRESS
Rajavardhan Gundi24321c32019-02-08 12:48:34 +053024#elif (defined(CONFIG_XTENSA) && defined(DT_JEDEC_SPI_NOR_0_LABEL))
Rajavardhan Gundi40c28e32018-12-09 13:32:01 +053025#define FLASH_DEVICE_ID SPI_FLASH_0_ID
Rajavardhan Gundi73bb71b2019-01-28 15:07:04 +053026#define FLASH_DEVICE_BASE 0
Rajavardhan Gundi40c28e32018-12-09 13:32:01 +053027#else
28#error "FLASH_DEVICE_ID could not be determined"
29#endif
Andrzej Puzdrowskib788c712018-04-12 12:42:49 +020030
Fabio Utzig0b6b51f2020-09-02 11:39:43 -030031static const struct device *flash_dev;
Emanuele Di Santo205c8c62018-07-20 11:42:31 +020032
Fabio Utzig0b6b51f2020-09-02 11:39:43 -030033const struct device *flash_device_get_binding(char *dev_name)
Emanuele Di Santo205c8c62018-07-20 11:42:31 +020034{
35 if (!flash_dev) {
36 flash_dev = device_get_binding(dev_name);
37 }
38 return flash_dev;
39}
40
Andrzej Puzdrowskib788c712018-04-12 12:42:49 +020041int flash_device_base(uint8_t fd_id, uintptr_t *ret)
42{
43 if (fd_id != FLASH_DEVICE_ID) {
44 BOOT_LOG_ERR("invalid flash ID %d; expected %d",
45 fd_id, FLASH_DEVICE_ID);
46 return -EINVAL;
47 }
48 *ret = FLASH_DEVICE_BASE;
49 return 0;
50}
51
52/*
Andrzej Puzdrowski419a4752019-01-23 16:31:19 +010053 * This depends on the mappings defined in sysflash.h.
David Vincze2d736ad2019-02-18 11:50:22 +010054 * MCUBoot uses continuous numbering for the primary slot, the secondary slot,
55 * and the scratch while zephyr might number it differently.
Andrzej Puzdrowskib788c712018-04-12 12:42:49 +020056 */
Fabio Utzigb0f04732019-07-31 09:49:19 -030057int flash_area_id_from_multi_image_slot(int image_index, int slot)
Andrzej Puzdrowskib788c712018-04-12 12:42:49 +020058{
Fabio Utzigb0f04732019-07-31 09:49:19 -030059 switch (slot) {
60 case 0: return FLASH_AREA_IMAGE_PRIMARY(image_index);
Andrzej Puzdrowskifdff3e12020-09-15 08:23:25 +020061#if !defined(CONFIG_SINGLE_APPLICATION_SLOT)
Fabio Utzigb0f04732019-07-31 09:49:19 -030062 case 1: return FLASH_AREA_IMAGE_SECONDARY(image_index);
Fabio Utzigc58842e2019-11-28 10:30:01 -030063#endif
Andrzej Puzdrowskic49d7c92021-05-13 12:52:34 +020064#if defined(CONFIG_BOOT_SWAP_USING_SCRATCH)
65 case 2: return FLASH_AREA_IMAGE_SCRATCH;
Dominik Ermel8101c0c2020-05-19 13:01:16 +000066#endif
Andrzej Puzdrowski419a4752019-01-23 16:31:19 +010067 }
68
69 return -EINVAL; /* flash_area_open will fail on that */
Andrzej Puzdrowskib788c712018-04-12 12:42:49 +020070}
Emanuele Di Santo205c8c62018-07-20 11:42:31 +020071
Fabio Utzigb0f04732019-07-31 09:49:19 -030072int flash_area_id_from_image_slot(int slot)
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +010073{
Fabio Utzigb0f04732019-07-31 09:49:19 -030074 return flash_area_id_from_multi_image_slot(0, slot);
75}
76
77int flash_area_id_to_multi_image_slot(int image_index, int area_id)
78{
79 if (area_id == FLASH_AREA_IMAGE_PRIMARY(image_index)) {
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +010080 return 0;
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +010081 }
Andrzej Puzdrowskifdff3e12020-09-15 08:23:25 +020082#if !defined(CONFIG_SINGLE_APPLICATION_SLOT)
Fabio Utzigb0f04732019-07-31 09:49:19 -030083 if (area_id == FLASH_AREA_IMAGE_SECONDARY(image_index)) {
David Vinczeb75c12a2019-03-22 14:58:33 +010084 return 1;
85 }
Dominik Ermel8101c0c2020-05-19 13:01:16 +000086#endif
David Vinczeb75c12a2019-03-22 14:58:33 +010087
88 BOOT_LOG_ERR("invalid flash area ID");
89 return -1;
Andrzej Puzdrowskie575fe92019-03-14 12:20:19 +010090}
91
Fabio Utzigb0f04732019-07-31 09:49:19 -030092int flash_area_id_to_image_slot(int area_id)
93{
94 return flash_area_id_to_multi_image_slot(0, area_id);
95}
96
Dominik Ermel6c8932e2021-07-09 10:28:40 +000097#if defined(CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD)
98int flash_area_id_from_direct_image(int image_id)
99{
100 switch (image_id) {
101 case 0:
102 case 1:
103 return FLASH_AREA_ID(image_0);
104#if DT_HAS_FIXED_PARTITION_LABEL(image_1)
105 case 2:
106 return FLASH_AREA_ID(image_1);
107#endif
108#if DT_HAS_FIXED_PARTITION_LABEL(image_2)
109 case 3:
110 return FLASH_AREA_ID(image_2);
111#endif
112#if DT_HAS_FIXED_PARTITION_LABEL(image_3)
113 case 4:
114 return FLASH_AREA_ID(image_3);
115#endif
116 }
117 return -EINVAL;
118}
119#endif
120
Emanuele Di Santo205c8c62018-07-20 11:42:31 +0200121int flash_area_sector_from_off(off_t off, struct flash_sector *sector)
122{
123 int rc;
124 struct flash_pages_info page;
125
126 rc = flash_get_page_info_by_offs(flash_dev, off, &page);
127 if (rc) {
128 return rc;
129 }
130
131 sector->fs_off = page.start_offset;
132 sector->fs_size = page.size;
133
134 return rc;
Fabio Utzig42ad4462018-08-14 08:55:23 -0300135}
136
Dominik Ermeldc1b9f02021-04-23 05:28:25 +0000137uint8_t flash_area_get_device_id(const struct flash_area *fa)
138{
139 (void)fa;
140 return FLASH_DEVICE_ID;
141}
142
Fabio Utzigcea90f92018-09-19 08:12:46 -0300143#define ERASED_VAL 0xff
Andrzej Puzdrowskic0dbdd42020-10-27 13:17:59 +0100144__weak uint8_t flash_area_erased_val(const struct flash_area *fap)
Fabio Utzig42ad4462018-08-14 08:55:23 -0300145{
146 (void)fap;
Fabio Utzigcea90f92018-09-19 08:12:46 -0300147 return ERASED_VAL;
148}