7
7
#include "pico/bootrom.h"
8
8
#include "boot/picoboot.h"
9
9
#include "boot/picobin.h"
10
+ #if !PICO_RP2040
11
+ #include "hardware/rcp.h"
12
+ #endif
10
13
11
14
/// \tag::table_lookup[]
12
15
@@ -59,6 +62,23 @@ void __attribute__((noreturn)) rom_reset_usb_boot(uint32_t usb_activity_gpio_pin
59
62
}
60
63
61
64
#if !PICO_RP2040
65
+
66
+
67
+ // Generated from adding the following code into the bootrom
68
+ // scan_workarea_t* scan_workarea = (scan_workarea_t*)workarea;
69
+ // printf("VERSION_DOWNGRADE_ERASE_ADDR %08x\n", &(always->zero_init.version_downgrade_erase_flash_addr));
70
+ // printf("TBYB_FLAG_ADDR %08x\n", &(always->zero_init.tbyb_flag_flash_addr));
71
+ // printf("IMAGE_DEF_VERIFIED %08x\n", (uint32_t)&(scan_workarea->parsed_block_loops[0].image_def.core.verified) - (uint32_t)scan_workarea);
72
+ // printf("IMAGE_DEF_TBYB_FLAGGED %08x\n", (uint32_t)&(scan_workarea->parsed_block_loops[0].image_def.core.tbyb_flagged) - (uint32_t)scan_workarea);
73
+ // printf("IMAGE_DEF_BASE %08x\n", (uint32_t)&(scan_workarea->parsed_block_loops[0].image_def.core.enclosing_window.base) - (uint32_t)scan_workarea);
74
+ // printf("IMAGE_DEF_REL_BLOCK_OFFSET %08x\n", (uint32_t)&(scan_workarea->parsed_block_loops[0].image_def.core.window_rel_block_offset) - (uint32_t)scan_workarea);
75
+ #define VERSION_DOWNGRADE_ERASE_ADDR *(uint32_t*)0x400e0338
76
+ #define TBYB_FLAG_ADDR *(uint32_t*)0x400e0348
77
+ #define IMAGE_DEF_VERIFIED (scan_workarea ) *(uint32_t*)(0x64 + (uint32_t)scan_workarea)
78
+ #define IMAGE_DEF_TBYB_FLAGGED (scan_workarea ) *(uint32_t*)(0x4c + (uint32_t)scan_workarea)
79
+ #define IMAGE_DEF_BASE (scan_workarea ) *(uint32_t*)(0x54 + (uint32_t)scan_workarea)
80
+ #define IMAGE_DEF_REL_BLOCK_OFFSET (scan_workarea ) *(uint32_t*)(0x5c + (uint32_t)scan_workarea)
81
+
62
82
bool rom_get_boot_random (uint32_t out [4 ]) {
63
83
uint32_t result [5 ];
64
84
rom_get_sys_info_fn func = (rom_get_sys_info_fn ) rom_func_lookup_inline (ROM_FUNC_GET_SYS_INFO );
@@ -99,4 +119,62 @@ int rom_add_flash_runtime_partition(uint32_t start_offset, uint32_t size, uint32
99
119
}
100
120
return PICO_ERROR_INSUFFICIENT_RESOURCES ;
101
121
}
122
+
123
+ int rom_pick_ab_update_partition (uint32_t * workarea_base , uint32_t workarea_size , uint partition_a_num ) {
124
+ uint32_t flash_update_base = 0 ;
125
+ bool tbyb_boot = false;
126
+ uint32_t saved_erase_addr = 0 ;
127
+ if (rom_get_last_boot_type () == BOOT_TYPE_FLASH_UPDATE ) {
128
+ // For a flash update boot, get the flash update base
129
+ boot_info_t boot_info = {};
130
+ int ret = rom_get_boot_info (& boot_info );
131
+ if (ret ) {
132
+ flash_update_base = boot_info .reboot_params [0 ];
133
+ if (boot_info .tbyb_and_update_info & BOOT_TBYB_AND_UPDATE_FLAG_BUY_PENDING ) {
134
+ // A buy is pending, so the main software has not been bought
135
+ tbyb_boot = true;
136
+ // Save the erase address, as this will be overwritten by rom_pick_ab_partition
137
+ saved_erase_addr = VERSION_DOWNGRADE_ERASE_ADDR ;
138
+ }
139
+ }
140
+ }
141
+
142
+ int rc = rom_pick_ab_partition ((uint8_t * )workarea_base , workarea_size , partition_a_num , flash_update_base );
143
+
144
+ if (IMAGE_DEF_VERIFIED (workarea_base ) != RCP_MASK_TRUE ) {
145
+ // Chosen partition failed verification
146
+ return BOOTROM_ERROR_NOT_FOUND ;
147
+ }
148
+
149
+ if (IMAGE_DEF_TBYB_FLAGGED (workarea_base )) {
150
+ // The chosen partition is TBYB
151
+ if (tbyb_boot ) {
152
+ // The boot partition is also TBYB - cannot update both, so prioritise boot partition
153
+ // Restore the erase address saved earlier
154
+ VERSION_DOWNGRADE_ERASE_ADDR = saved_erase_addr ;
155
+ return BOOTROM_ERROR_NOT_PERMITTED ;
156
+ } else {
157
+ // Update the tbyb flash address, so that explicit_buy will clear the flag for the chosen partition
158
+ TBYB_FLAG_ADDR =
159
+ IMAGE_DEF_BASE (workarea_base )
160
+ + IMAGE_DEF_REL_BLOCK_OFFSET (workarea_base ) + 4 ;
161
+ }
162
+ } else {
163
+ // The chosen partition is not TBYB
164
+ if (tbyb_boot && saved_erase_addr ) {
165
+ // The boot partition was TBYB, and requires an erase
166
+ if (VERSION_DOWNGRADE_ERASE_ADDR ) {
167
+ // But both the chosen partition requires an erase too
168
+ // As before, prioritise the boot partition, and restore it's saved erase_address
169
+ VERSION_DOWNGRADE_ERASE_ADDR = saved_erase_addr ;
170
+ return BOOTROM_ERROR_NOT_PERMITTED ;
171
+ } else {
172
+ // The chosen partition doesn't require an erase, so we're fine
173
+ VERSION_DOWNGRADE_ERASE_ADDR = saved_erase_addr ;
174
+ }
175
+ }
176
+ }
177
+
178
+ return rc ;
179
+ }
102
180
#endif
0 commit comments