blob: baa151c7dc0336fe712d0060ad9855ce597dabec [file] [log] [blame]
Dominik Ermel3d51e432021-06-25 17:29:50 +00001/*
2 * Copyright (c) 2021 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
Gerard Marull-Paretas34dd9e72022-05-09 12:13:12 +02007#include <zephyr/kernel.h>
Gerard Marull-Paretas3cd2cec2022-05-09 12:10:05 +02008#include <zephyr/drivers/flash.h>
9#include <zephyr/mgmt/mcumgr/zephyr_groups.h>
Dominik Ermel3d51e432021-06-25 17:29:50 +000010
11#include <flash_map_backend/flash_map_backend.h>
12#include <sysflash/sysflash.h>
13
14#include "bootutil/bootutil_log.h"
15#include "../boot_serial/src/boot_serial_priv.h"
Dominik Ermele6e48012023-06-19 11:37:20 +000016#include <zcbor_encode.h>
Dominik Ermel3d51e432021-06-25 17:29:50 +000017
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020018#include "bootutil/image.h"
Andrzej Puzdrowski2a29f5d2021-07-30 16:22:22 +020019#include "bootutil/bootutil_public.h"
20#include "bootutil/boot_hooks.h"
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020021
Andrzej Puzdrowskid16598f2022-01-10 10:49:09 +010022BOOT_LOG_MODULE_DECLARE(mcuboot);
Dominik Ermel3d51e432021-06-25 17:29:50 +000023
Dominik Ermel0435d5d2021-08-16 15:58:15 +000024#ifdef CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE
Dominik Ermel864d1042022-07-12 12:41:39 +000025static int bs_custom_storage_erase(zcbor_state_t *cs)
Dominik Ermel3d51e432021-06-25 17:29:50 +000026{
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020027 int rc;
Dominik Ermel3d51e432021-06-25 17:29:50 +000028
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020029 const struct flash_area *fa;
Dominik Ermel97b4c792021-06-25 17:32:38 +000030
Dominik Ermel2c539342022-08-24 14:37:11 +000031 rc = flash_area_open(FIXED_PARTITION_ID(storage_partition), &fa);
Dominik Ermel97b4c792021-06-25 17:32:38 +000032
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020033 if (rc < 0) {
Andrzej Puzdrowskid16598f2022-01-10 10:49:09 +010034 BOOT_LOG_ERR("failed to open flash area");
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020035 } else {
Dominik Ermel2c539342022-08-24 14:37:11 +000036 rc = flash_area_erase(fa, 0, flash_area_get_size(fa));
Dominik Ermel97b4c792021-06-25 17:32:38 +000037 if (rc < 0) {
Andrzej Puzdrowskid16598f2022-01-10 10:49:09 +010038 BOOT_LOG_ERR("failed to erase flash area");
Dominik Ermel97b4c792021-06-25 17:32:38 +000039 }
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020040 flash_area_close(fa);
41 }
42 if (rc == 0) {
43 rc = MGMT_ERR_OK;
44 } else {
45 rc = MGMT_ERR_EUNKNOWN;
Dominik Ermel3d51e432021-06-25 17:29:50 +000046 }
47
Dominik Ermel864d1042022-07-12 12:41:39 +000048 zcbor_map_start_encode(cs, 10);
49 zcbor_tstr_put_lit(cs, "rc");
50 zcbor_uint32_put(cs, rc);
51 zcbor_map_end_encode(cs, 10);
Dominik Ermel3d51e432021-06-25 17:29:50 +000052
53 return rc;
54}
Dominik Ermel0435d5d2021-08-16 15:58:15 +000055#endif
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020056
Andrzej Puzdrowski420ad9a2021-07-29 16:22:52 +020057#ifdef MCUBOOT_MGMT_CUSTOM_IMG_LIST
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020058static int custom_img_status(int image_index, uint32_t slot,char *buffer,
59 ssize_t len)
60{
61 uint32_t area_id;
62 struct flash_area const *fap;
63 struct image_header hdr;
64 int rc;
Andrzej Puzdrowski2a29f5d2021-07-30 16:22:22 +020065 int img_install_stat;
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020066
Andrzej Puzdrowski2a29f5d2021-07-30 16:22:22 +020067 rc = BOOT_HOOK_CALL(boot_img_install_stat_hook, BOOT_HOOK_REGULAR,
68 image_index, slot, &img_install_stat);
69 if (rc == BOOT_HOOK_REGULAR)
70 {
71 img_install_stat = 0;
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020072 }
73
Andrzej Puzdrowski2a29f5d2021-07-30 16:22:22 +020074 rc = BOOT_HOOK_CALL(boot_read_image_header_hook, BOOT_HOOK_REGULAR,
75 image_index, slot, &hdr);
76 if (rc == BOOT_HOOK_REGULAR)
77 {
78 area_id = flash_area_id_from_multi_image_slot(image_index, slot);
79
80 rc = flash_area_open(area_id, &fap);
81 if (rc) {
82 return rc;
83 }
84
85 rc = flash_area_read(fap, 0, &hdr, sizeof(hdr));
86
87 flash_area_close(fap);
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020088 }
89
Andrzej Puzdrowski2a29f5d2021-07-30 16:22:22 +020090 if (rc == 0) {
91 if (hdr.ih_magic == IMAGE_MAGIC) {
92 snprintf(buffer, len, "ver=%d.%d.%d.%d,install_stat=%d",
93 hdr.ih_ver.iv_major,
94 hdr.ih_ver.iv_minor,
95 hdr.ih_ver.iv_revision,
96 hdr.ih_ver.iv_build_num,
97 img_install_stat);
98 } else {
99 rc = 1;
100 }
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200101 }
102
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200103 return rc;
104}
105
Dominik Ermel864d1042022-07-12 12:41:39 +0000106static int bs_custom_img_list(zcbor_state_t *cs)
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200107{
108 int rc = 0;
109 char tmpbuf[64]; /* Buffer should fit version and flags */
110
Dominik Ermel864d1042022-07-12 12:41:39 +0000111 zcbor_map_start_encode(cs, 10);
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200112
113 for (int img = 0; img < MCUBOOT_IMAGE_NUMBER; img++) {
114 for (int slot = 0; slot < 2; slot++) {
115 rc = custom_img_status(img, slot, tmpbuf, sizeof(tmpbuf));
116
Dominik Ermel864d1042022-07-12 12:41:39 +0000117 zcbor_int32_put(cs, img * 2 + slot + 1);
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200118 if (rc == 0) {
Dominik Ermel864d1042022-07-12 12:41:39 +0000119 zcbor_tstr_put_term(cs, tmpbuf);
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200120 } else {
Dominik Ermel864d1042022-07-12 12:41:39 +0000121 zcbor_tstr_put_lit(cs, "");
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200122 }
123 }
124 }
125
Dominik Ermel864d1042022-07-12 12:41:39 +0000126 zcbor_tstr_put_lit(cs, "rc");
127 zcbor_uint32_put(cs, MGMT_ERR_OK);
128 zcbor_map_end_encode(cs, 10);
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200129
130 return rc;
131}
132
133#ifndef ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST
134 #define ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST 1
135#endif
Andrzej Puzdrowski420ad9a2021-07-29 16:22:52 +0200136#endif /*MCUBOOT_MGMT_CUSTOM_IMG_LIST*/
137
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200138int bs_peruser_system_specific(const struct nmgr_hdr *hdr, const char *buffer,
Dominik Ermel864d1042022-07-12 12:41:39 +0000139 int len, zcbor_state_t *cs)
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200140{
141 int mgmt_rc = MGMT_ERR_ENOTSUP;
142
143 if (hdr->nh_group == ZEPHYR_MGMT_GRP_BASE) {
144 if (hdr->nh_op == NMGR_OP_WRITE) {
Dominik Ermel0435d5d2021-08-16 15:58:15 +0000145#ifdef CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200146 if (hdr->nh_id == ZEPHYR_MGMT_GRP_BASIC_CMD_ERASE_STORAGE) {
147 mgmt_rc = bs_custom_storage_erase(cs);
148 }
Dominik Ermel0435d5d2021-08-16 15:58:15 +0000149#endif
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200150 } else if (hdr->nh_op == NMGR_OP_READ) {
Andrzej Puzdrowski420ad9a2021-07-29 16:22:52 +0200151#ifdef MCUBOOT_MGMT_CUSTOM_IMG_LIST
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200152 if (hdr->nh_id == ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST) {
153 mgmt_rc = bs_custom_img_list(cs);
154 }
Andrzej Puzdrowski420ad9a2021-07-29 16:22:52 +0200155#endif
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200156 }
157 }
158
159 if (mgmt_rc == MGMT_ERR_ENOTSUP) {
Dominik Ermel864d1042022-07-12 12:41:39 +0000160 zcbor_map_start_encode(cs, 10);
161 zcbor_tstr_put_lit(cs, "rc");
162 zcbor_uint32_put(cs, mgmt_rc);
163 zcbor_map_end_encode(cs, 10);
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200164 }
165
166 return MGMT_ERR_OK;
167}