Skip to content

Commit 82f2a62

Browse files
committed
Add simulator support for DUALBANK, test bank swap
1 parent a8afa74 commit 82f2a62

File tree

5 files changed

+189
-0
lines changed

5 files changed

+189
-0
lines changed

.github/workflows/test-sunnyday-simulator.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,20 @@ jobs:
9090
run: |
9191
tools/scripts/sim-sunnyday-update.sh
9292
93+
- name: Cleanup before dualbank simulator test
94+
run: |
95+
make keysclean
96+
97+
- name: Build wolfboot.elf (dualbank simulator)
98+
run: |
99+
make clean
100+
cp config/examples/sim-dualbank.config .config
101+
make test-sim-internal-flash-with-update
102+
103+
- name: Run dualbank swap simulation
104+
run: |
105+
tools/scripts/sim-dualbank-swap-update.sh
106+
93107
- name: Build wolfboot.elf (ECC256, WOLFBOOT_SMALL_STACK)
94108
run: |
95109
make clean && make test-sim-internal-flash-with-update SIGN=ECC256 WOLFBOOT_SMALL_STACK=1 SPMATH=1
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
ARCH=sim
2+
TARGET=sim
3+
SIGN?=ED25519
4+
HASH?=SHA256
5+
WOLFBOOT_SMALL_STACK?=0
6+
SPI_FLASH=0
7+
DEBUG=1
8+
DUALBANK_SWAP=1
9+
10+
# sizes should be multiple of system page size
11+
WOLFBOOT_PARTITION_SIZE=0x40000
12+
WOLFBOOT_SECTOR_SIZE=0x1000
13+
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x80000
14+
WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x100000
15+
WOLFBOOT_PARTITION_SWAP_ADDRESS=0x180000
16+
17+
# required for keytools
18+
WOLFBOOT_FIXED_PARTITIONS=1

hal/sim.c

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,15 @@ int extFlashLocked = 1;
7373
#define INTERNAL_FLASH_FILE "./internal_flash.dd"
7474
#define EXTERNAL_FLASH_FILE "./external_flash.dd"
7575

76+
#ifdef DUALBANK_SWAP
77+
#define SIM_REGISTER_FILE "./sim_registers.dd"
78+
#define SIM_FLASH_OPTR_SWAP_BANK (1U << 20)
79+
static uint32_t sim_flash_optr;
80+
static void sim_dualbank_register_load(void);
81+
static void sim_dualbank_register_store(void);
82+
uint32_t hal_sim_get_dualbank_state(void);
83+
#endif
84+
7685
/* global used to store command line arguments to forward to the test
7786
* application */
7887
char **main_argv;
@@ -224,6 +233,56 @@ static int mmap_file(const char *path, uint8_t *address, uint8_t** ret_address)
224233
return 0;
225234
}
226235

236+
#ifdef DUALBANK_SWAP
237+
static void sim_dualbank_register_store(void)
238+
{
239+
int fd = open(SIM_REGISTER_FILE, O_RDWR | O_CREAT, 0644);
240+
if (fd == -1) {
241+
wolfBoot_printf("Failed to open %s: %s\n", SIM_REGISTER_FILE, strerror(errno));
242+
return;
243+
}
244+
245+
if (pwrite(fd, &sim_flash_optr, sizeof(sim_flash_optr), 0) !=
246+
(ssize_t)sizeof(sim_flash_optr)) {
247+
wolfBoot_printf("Failed to store dualbank swap state: %s\n",
248+
strerror(errno));
249+
}
250+
251+
close(fd);
252+
}
253+
254+
static void sim_dualbank_register_load(void)
255+
{
256+
int fd = open(SIM_REGISTER_FILE, O_RDWR | O_CREAT, 0644);
257+
if (fd == -1) {
258+
wolfBoot_printf("Failed to open %s: %s\n", SIM_REGISTER_FILE,
259+
strerror(errno));
260+
exit(-1);
261+
}
262+
263+
uint32_t value = 0;
264+
ssize_t rd = pread(fd, &value, sizeof(value), 0);
265+
266+
if (rd == (ssize_t)sizeof(value)) {
267+
sim_flash_optr = value;
268+
} else {
269+
sim_flash_optr = 0;
270+
if (pwrite(fd, &sim_flash_optr, sizeof(sim_flash_optr), 0) !=
271+
(ssize_t)sizeof(sim_flash_optr)) {
272+
wolfBoot_printf("Failed to initialize dualbank swap state: %s\n",
273+
strerror(errno));
274+
}
275+
}
276+
277+
close(fd);
278+
}
279+
280+
uint32_t hal_sim_get_dualbank_state(void)
281+
{
282+
return (sim_flash_optr & SIM_FLASH_OPTR_SWAP_BANK) ? 1U : 0U;
283+
}
284+
#endif
285+
227286
void hal_flash_unlock(void)
228287
{
229288
flashLocked = 0;
@@ -234,6 +293,46 @@ void hal_flash_lock(void)
234293
flashLocked = 1;
235294
}
236295

296+
#ifdef DUALBANK_SWAP
297+
void hal_flash_dualbank_swap(void)
298+
{
299+
uint8_t *boot = (uint8_t *)WOLFBOOT_PARTITION_BOOT_ADDRESS;
300+
uint8_t *update = (uint8_t *)WOLFBOOT_PARTITION_UPDATE_ADDRESS;
301+
uint8_t *buffer;
302+
int was_locked = flashLocked;
303+
304+
buffer = (uint8_t *)malloc(WOLFBOOT_PARTITION_SIZE);
305+
if (buffer == NULL) {
306+
wolfBoot_printf("Simulator dualbank swap failed: out of memory\n");
307+
exit(-1);
308+
}
309+
310+
if (was_locked)
311+
hal_flash_unlock();
312+
313+
memcpy(buffer, boot, WOLFBOOT_PARTITION_SIZE);
314+
memcpy(boot, update, WOLFBOOT_PARTITION_SIZE);
315+
memcpy(update, buffer, WOLFBOOT_PARTITION_SIZE);
316+
317+
if (msync(boot, WOLFBOOT_PARTITION_SIZE, MS_SYNC) != 0) {
318+
wolfBoot_printf("msync boot partition failed: %s\n", strerror(errno));
319+
}
320+
if (msync(update, WOLFBOOT_PARTITION_SIZE, MS_SYNC) != 0) {
321+
wolfBoot_printf("msync update partition failed: %s\n", strerror(errno));
322+
}
323+
324+
free(buffer);
325+
326+
sim_flash_optr ^= SIM_FLASH_OPTR_SWAP_BANK;
327+
sim_dualbank_register_store();
328+
wolfBoot_printf("Simulator dualbank swap complete, register=%u\n",
329+
hal_sim_get_dualbank_state());
330+
331+
if (was_locked)
332+
hal_flash_lock();
333+
}
334+
#endif
335+
237336
void hal_prepare_boot(void)
238337
{
239338
/* no op */
@@ -312,6 +411,10 @@ void hal_init(void)
312411
}
313412
#endif /* EXT_FLASH */
314413

414+
#ifdef DUALBANK_SWAP
415+
sim_dualbank_register_load();
416+
#endif
417+
315418
for (i = 1; i < main_argc; i++) {
316419
if (strcmp(main_argv[i], "powerfail") == 0) {
317420
erasefail_address = strtol(main_argv[++i], NULL, 16);
@@ -480,6 +583,7 @@ void do_boot(const uint32_t *app_offset)
480583
#endif
481584
#endif
482585

586+
#if !defined(WOLFBOOT_DUALBOOT)
483587
int wolfBoot_fallback_is_possible(void)
484588
{
485589
return 0;
@@ -489,6 +593,7 @@ int wolfBoot_dualboot_candidate(void)
489593
{
490594
return 0;
491595
}
596+
#endif
492597

493598
#ifdef WOLFBOOT_ENABLE_WOLFHSM_CLIENT
494599

test-app/app_sim.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030

3131
#include "wolfboot/wolfboot.h"
3232

33+
#ifdef DUALBANK_SWAP
34+
uint32_t hal_sim_get_dualbank_state(void);
35+
#endif
36+
3337
#ifdef TARGET_sim
3438

3539
/* Matches all keys:
@@ -72,6 +76,12 @@ int do_cmd(const char *cmd)
7276
wolfBoot_success();
7377
return 0;
7478
}
79+
#ifdef DUALBANK_SWAP
80+
if (strcmp(cmd, "get_swap_state") == 0) {
81+
printf("%u\n", hal_sim_get_dualbank_state());
82+
return 0;
83+
}
84+
#endif
7585
if (strcmp(cmd, "update_trigger") == 0) {
7686
#if EXT_ENCRYPTED
7787
wolfBoot_set_encrypt_key((uint8_t *)enc_key,(uint8_t *)(enc_key + 32));
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
if [ ! -f ".config" ]; then
5+
echo "Missing .config. Run make config first." >&2
6+
exit 1
7+
fi
8+
9+
if ! grep -Eq '^(DUALBANK_SWAP(\?|)=1)' .config; then
10+
echo "DUALBANK_SWAP=1 is required for this simulation." >&2
11+
exit 1
12+
fi
13+
14+
if [ ! -x "./wolfboot.elf" ]; then
15+
echo "wolfboot.elf not found. Build the simulator first." >&2
16+
exit 1
17+
fi
18+
19+
rm -f sim_registers.dd
20+
21+
mapfile -t lines < <(./wolfboot.elf get_swap_state get_version 2>/dev/null)
22+
if [ "${#lines[@]}" -ne 2 ] || [ "${lines[0]}" != "1" ] || [ "${lines[1]}" != "2" ]; then
23+
echo "Unexpected output on first boot (got: ${lines[*]-})" >&2
24+
exit 1
25+
fi
26+
echo "dualbank: first boot reports swap=${lines[0]} active_version=${lines[1]}"
27+
28+
mapfile -t lines < <(./wolfboot.elf success get_swap_state get_version 2>/dev/null)
29+
if [ "${#lines[@]}" -ne 2 ] || [ "${lines[0]}" != "1" ] || [ "${lines[1]}" != "2" ]; then
30+
echo "Unexpected output while confirming update (got: ${lines[*]-})" >&2
31+
exit 1
32+
fi
33+
echo "dualbank: after wolfBoot_success swap=${lines[0]} active_version=${lines[1]}"
34+
35+
mapfile -t lines < <(./wolfboot.elf get_swap_state get_version 2>/dev/null)
36+
if [ "${#lines[@]}" -ne 2 ] || [ "${lines[0]}" != "1" ] || [ "${lines[1]}" != "2" ]; then
37+
echo "Unexpected output after confirmation (got: ${lines[*]-})" >&2
38+
exit 1
39+
fi
40+
echo "dualbank: persistent swap state confirmed swap=${lines[0]} active_version=${lines[1]}"
41+
42+
echo "Dualbank swap simulation successful."

0 commit comments

Comments
 (0)