|
28 | 28 | #define RRAMC_REGION_FOR_NEXT_W 4 |
29 | 29 | #define NRF_RRAM_REGION_SIZE_UNIT 0x400 |
30 | 30 | #define NRF_RRAM_REGION_ADDRESS_RESOLUTION 0x400 |
31 | | -#define NEXT_W_SIZE_KB (PM_MCUBOOT_SIZE / NRF_RRAM_REGION_SIZE_UNIT) |
32 | 31 |
|
33 | | -BUILD_ASSERT((PM_MCUBOOT_ADDRESS % NRF_RRAM_REGION_ADDRESS_RESOLUTION) == 0, |
34 | | - "Start of protected region is not aligned"); |
| 32 | +#if defined(CONFIG_SOC_NRF54L15_CPUAPP) || defined(CONFIG_SOC_NRF54L05_CPUAPP) || \ |
| 33 | + defined(CONFIG_SOC_NRF54L10_CPUAPP) |
| 34 | +#define MAX_NEXT_W_SIZE (31 * 1024) |
| 35 | +#elif defined(CONFIG_SOC_NRF54LV10A_ENGA_CPUAPP) || defined(CONFIG_SOC_NRF54LM20A_ENGA_CPUAPP) |
| 36 | +#define MAX_NEXT_W_SIZE (127 * 1024) |
| 37 | +#elif defined(CONFIG_SOC_NRF54LS05B_ENGA_CPUAPP) |
| 38 | +#define MAX_NEXT_W_SIZE (1023 * 1024) |
| 39 | +#endif |
| 40 | + |
| 41 | +BUILD_ASSERT((PM_S0_IMAGE_ADDRESS % NRF_RRAM_REGION_ADDRESS_RESOLUTION) == 0, |
| 42 | + "Start of S0 image region is not aligned - not possible to protect"); |
| 43 | + |
| 44 | +BUILD_ASSERT((PM_S0_IMAGE_SIZE % NRF_RRAM_REGION_SIZE_UNIT) == 0, |
| 45 | + "Size of S0 image region is not aligned - not possible to protect"); |
| 46 | + |
| 47 | +BUILD_ASSERT(PM_S0_IMAGE_SIZE <= MAX_NEXT_W_SIZE, "Size of S0 partition is too big for protection"); |
| 48 | + |
| 49 | +#if defined(PM_S1_IMAGE_ADDRESS) |
| 50 | +BUILD_ASSERT((PM_S1_IMAGE_ADDRESS % NRF_RRAM_REGION_ADDRESS_RESOLUTION) == 0, |
| 51 | + "Start of S1 image region is not aligned - not possible to protect"); |
35 | 52 |
|
36 | | -BUILD_ASSERT((PM_MCUBOOT_SIZE % NRF_RRAM_REGION_SIZE_UNIT) == 0, |
37 | | - "Size of protected region is not aligned"); |
| 53 | +BUILD_ASSERT((PM_S1_IMAGE_SIZE % NRF_RRAM_REGION_SIZE_UNIT) == 0, |
| 54 | + "Size of S1 image region is not aligned - not possible to protect"); |
38 | 55 |
|
39 | | -BUILD_ASSERT(NEXT_W_SIZE_KB < 31, |
40 | | - "Size of requested protection is too big"); |
| 56 | +BUILD_ASSERT(PM_S1_IMAGE_SIZE <= MAX_NEXT_W_SIZE, "Size of S1 partition is too big for protection"); |
| 57 | +#endif /* defined(PM_S1_IMAGE_ADDRESS) */ |
41 | 58 |
|
42 | | -static int disable_next_w(void) |
| 59 | +static int disable_next_w(const uint32_t address) |
43 | 60 | { |
| 61 | + uint32_t region_size_kb = 0; |
| 62 | + |
| 63 | + /* Note: the protection is only applied to the image itself, not the header (pad). |
| 64 | + * When building with MCUBoot, applying protection to the header is not needed, as the |
| 65 | + * header is only used during DFU and is only left for compatibility. Without MCUBoot, the |
| 66 | + * header is not present. |
| 67 | + */ |
| 68 | + if (address == PM_S0_IMAGE_ADDRESS) { |
| 69 | + region_size_kb = PM_S0_IMAGE_SIZE / NRF_RRAM_REGION_SIZE_UNIT; |
| 70 | + } else if (address == PM_S1_IMAGE_ADDRESS) { |
| 71 | + region_size_kb = PM_S1_IMAGE_SIZE / NRF_RRAM_REGION_SIZE_UNIT; |
| 72 | + } else { |
| 73 | + return -EINVAL; |
| 74 | + } |
| 75 | + |
44 | 76 | nrf_rramc_region_config_t config = { |
45 | | - .address = PM_MCUBOOT_ADDRESS, |
| 77 | + .address = address, |
46 | 78 | .permissions = NRF_RRAMC_REGION_PERM_READ_MASK | |
47 | 79 | NRF_RRAMC_REGION_PERM_EXECUTE_MASK, |
48 | 80 | .writeonce = false, |
49 | | - .lock = false, |
50 | | - .size_kb = NEXT_W_SIZE_KB, |
| 81 | + /* There are no issues with locking the region here, |
| 82 | + * as the next stage can still impose more strict |
| 83 | + * protection by writing 0 to R/X disable bits. |
| 84 | + */ |
| 85 | + .lock = true, |
| 86 | + .size_kb = region_size_kb, |
51 | 87 | }; |
52 | 88 |
|
53 | 89 | nrf_rramc_region_config_set(NRF_RRAMC, RRAMC_REGION_FOR_NEXT_W, &config); |
54 | 90 | nrf_rramc_region_config_get(NRF_RRAMC, RRAMC_REGION_FOR_NEXT_W, &config); |
55 | 91 | if (config.permissions & (NRF_RRAMC_REGION_PERM_WRITE_MASK)) { |
56 | 92 | return -ENOSPC; |
57 | 93 | } |
58 | | - if (config.size_kb != NEXT_W_SIZE_KB) { |
| 94 | + if (config.size_kb != region_size_kb) { |
59 | 95 | return -ENOSPC; |
60 | 96 | } |
61 | 97 |
|
@@ -286,8 +322,8 @@ void bl_boot(const struct fw_info *fw_info) |
286 | 322 | uint32_t *vector_table = (uint32_t *)fw_info->address; |
287 | 323 |
|
288 | 324 | #if defined(CONFIG_SB_DISABLE_NEXT_W) |
289 | | - if (disable_next_w()) { |
290 | | - printk("Unable to disable writes on next stage."); |
| 325 | + if (disable_next_w(fw_info->address)) { |
| 326 | + printk("Unable to disable writes on next stage"); |
291 | 327 | return; |
292 | 328 | } |
293 | 329 | #endif |
|
0 commit comments