@@ -198,6 +198,98 @@ class Uicr(c.LittleEndianStructure):
198
198
]
199
199
200
200
201
+ def validate_secure_storage_partitions (
202
+ secure_storage_address : int ,
203
+ cpuapp_crypto_address : int ,
204
+ cpuapp_crypto_size : int ,
205
+ cpurad_crypto_address : int ,
206
+ cpurad_crypto_size : int ,
207
+ cpuapp_its_address : int ,
208
+ cpuapp_its_size : int ,
209
+ cpurad_its_address : int ,
210
+ cpurad_its_size : int ,
211
+ ) -> None :
212
+ """
213
+ Validate that secure storage partitions are laid out correctly.
214
+
215
+ Args:
216
+ secure_storage_address: Absolute address of secure storage partition
217
+ cpuapp_crypto_address: Absolute address of cpuapp_crypto_partition
218
+ cpuapp_crypto_size: Size of cpuapp_crypto_partition
219
+ cpurad_crypto_address: Absolute address of cpurad_crypto_partition
220
+ cpurad_crypto_size: Size of cpurad_crypto_partition
221
+ cpuapp_its_address: Absolute address of cpuapp_its_partition
222
+ cpuapp_its_size: Size of cpuapp_its_partition
223
+ cpurad_its_address: Absolute address of cpurad_its_partition
224
+ cpurad_its_size: Size of cpurad_its_partition
225
+
226
+ Raises:
227
+ ScriptError: If validation fails
228
+ """
229
+ # Expected order: cpuapp_crypto_partition, cpurad_crypto_partition,
230
+ # cpuapp_its_partition, cpurad_its_partition
231
+ partitions = [
232
+ (cpuapp_crypto_address , cpuapp_crypto_size , "cpuapp_crypto_partition" ),
233
+ (cpurad_crypto_address , cpurad_crypto_size , "cpurad_crypto_partition" ),
234
+ (cpuapp_its_address , cpuapp_its_size , "cpuapp_its_partition" ),
235
+ (cpurad_its_address , cpurad_its_size , "cpurad_its_partition" ),
236
+ ]
237
+
238
+ # Filter out zero-sized partitions (missing partitions)
239
+ present_partitions = []
240
+ for i , (addr , size , name ) in enumerate (partitions ):
241
+ if size > 0 :
242
+ present_partitions .append ((i , addr , size , name ))
243
+
244
+ if not present_partitions :
245
+ # No partitions present - this is valid
246
+ return
247
+
248
+ # Check that the first present partition starts at the secure storage address
249
+ _ , first_addr , _ , first_name = present_partitions [0 ]
250
+ if first_addr != secure_storage_address :
251
+ raise ScriptError (
252
+ f"First partition { first_name } starts at { first_addr } , but must start at "
253
+ f"secure storage address { secure_storage_address } "
254
+ )
255
+
256
+ # Check that all present partitions have sizes that are multiples of 1KB
257
+ for _ , _ , size , name in present_partitions :
258
+ if size % 1024 != 0 :
259
+ raise ScriptError (
260
+ f"Partition { name } has size { size } bytes, but must be a multiple of "
261
+ f"1024 bytes (1KB)"
262
+ )
263
+
264
+ # Check that partitions are in correct order and don't overlap
265
+ for i in range (len (present_partitions ) - 1 ):
266
+ _ , curr_addr , curr_size , curr_name = present_partitions [i ]
267
+ _ , next_addr , _________ , next_name = present_partitions [i + 1 ]
268
+
269
+ # Check order - partitions should be in ascending address order
270
+ if curr_addr >= next_addr :
271
+ raise ScriptError (
272
+ f"Partition { curr_name } (starts at { curr_addr } ) must come before "
273
+ f"{ next_name } (starts at { next_addr } )"
274
+ )
275
+
276
+ # Check for overlap
277
+ curr_end = curr_addr + curr_size
278
+ if curr_end > next_addr :
279
+ raise ScriptError (
280
+ f"Partition { curr_name } (ends at { curr_end } ) overlaps with "
281
+ f"{ next_name } (starts at { next_addr } )"
282
+ )
283
+
284
+ # Check for gaps (should be no gaps between consecutive partitions)
285
+ if curr_end < next_addr :
286
+ gap = next_addr - curr_end
287
+ raise ScriptError (
288
+ f"Gap of { gap } bytes between { curr_name } (ends at { curr_end } ) and "
289
+ f"{ next_name } (starts at { next_addr } )"
290
+ )
291
+
292
+
201
293
def main () -> None :
202
294
parser = argparse .ArgumentParser (
203
295
allow_abbrev = False ,
@@ -255,6 +347,65 @@ def main() -> None:
255
347
type = lambda s : int (s , 0 ),
256
348
help = "Absolute flash address of the UICR region (decimal or 0x-prefixed hex)" ,
257
349
)
350
+ parser .add_argument (
351
+ "--securestorage" ,
352
+ action = "store_true" ,
353
+ help = "Enable secure storage support in UICR" ,
354
+ )
355
+ parser .add_argument (
356
+ "--securestorage-address" ,
357
+ default = None ,
358
+ type = lambda s : int (s , 0 ),
359
+ help = "Absolute flash address of the secure storage partition (decimal or 0x-prefixed hex)" ,
360
+ )
361
+ parser .add_argument (
362
+ "--cpuapp-crypto-address" ,
363
+ default = 0 ,
364
+ type = lambda s : int (s , 0 ),
365
+ help = "Absolute flash address of cpuapp_crypto_partition (decimal or 0x-prefixed hex)" ,
366
+ )
367
+ parser .add_argument (
368
+ "--cpuapp-crypto-size" ,
369
+ default = 0 ,
370
+ type = lambda s : int (s , 0 ),
371
+ help = "Size in bytes of cpuapp_crypto_partition (decimal or 0x-prefixed hex)" ,
372
+ )
373
+ parser .add_argument (
374
+ "--cpurad-crypto-address" ,
375
+ default = 0 ,
376
+ type = lambda s : int (s , 0 ),
377
+ help = "Absolute flash address of cpurad_crypto_partition (decimal or 0x-prefixed hex)" ,
378
+ )
379
+ parser .add_argument (
380
+ "--cpurad-crypto-size" ,
381
+ default = 0 ,
382
+ type = lambda s : int (s , 0 ),
383
+ help = "Size in bytes of cpurad_crypto_partition (decimal or 0x-prefixed hex)" ,
384
+ )
385
+ parser .add_argument (
386
+ "--cpuapp-its-address" ,
387
+ default = 0 ,
388
+ type = lambda s : int (s , 0 ),
389
+ help = "Absolute flash address of cpuapp_its_partition (decimal or 0x-prefixed hex)" ,
390
+ )
391
+ parser .add_argument (
392
+ "--cpuapp-its-size" ,
393
+ default = 0 ,
394
+ type = lambda s : int (s , 0 ),
395
+ help = "Size in bytes of cpuapp_its_partition (decimal or 0x-prefixed hex)" ,
396
+ )
397
+ parser .add_argument (
398
+ "--cpurad-its-address" ,
399
+ default = 0 ,
400
+ type = lambda s : int (s , 0 ),
401
+ help = "Absolute flash address of cpurad_its_partition (decimal or 0x-prefixed hex)" ,
402
+ )
403
+ parser .add_argument (
404
+ "--cpurad-its-size" ,
405
+ default = 0 ,
406
+ type = lambda s : int (s , 0 ),
407
+ help = "Size in bytes of cpurad_its_partition (decimal or 0x-prefixed hex)" ,
408
+ )
258
409
parser .add_argument (
259
410
"--secondary" ,
260
411
action = "store_true" ,
@@ -327,12 +478,43 @@ def main() -> None:
327
478
"--out-secondary-periphconf-hex is used"
328
479
)
329
480
481
+ # Validate secure storage argument dependencies
482
+ if args .securestorage :
483
+ if args .securestorage_address is None :
484
+ raise ScriptError (
485
+ "--securestorage-address is required when --securestorage is used"
486
+ )
487
+
488
+ # Validate partition layout
489
+ validate_secure_storage_partitions (
490
+ args .securestorage_address ,
491
+ args .cpuapp_crypto_address ,
492
+ args .cpuapp_crypto_size ,
493
+ args .cpurad_crypto_address ,
494
+ args .cpurad_crypto_size ,
495
+ args .cpuapp_its_address ,
496
+ args .cpuapp_its_size ,
497
+ args .cpurad_its_address ,
498
+ args .cpurad_its_size ,
499
+ )
500
+
330
501
init_values = DISABLED_VALUE .to_bytes (4 , "little" ) * (c .sizeof (Uicr ) // 4 )
331
502
uicr = Uicr .from_buffer_copy (init_values )
332
503
333
504
uicr .VERSION .MAJOR = UICR_FORMAT_VERSION_MAJOR
334
505
uicr .VERSION .MINOR = UICR_FORMAT_VERSION_MINOR
335
506
507
+ # Handle secure storage configuration
508
+ if args .securestorage :
509
+ uicr .SECURESTORAGE .ENABLE = ENABLED_VALUE
510
+ uicr .SECURESTORAGE .ADDRESS = args .securestorage_address
511
+
512
+ # Set partition sizes in 1KB units
513
+ uicr .SECURESTORAGE .CRYPTO .APPLICATIONSIZE1KB = args .cpuapp_crypto_size // 1024
514
+ uicr .SECURESTORAGE .CRYPTO .RADIOCORESIZE1KB = args .cpurad_crypto_size // 1024
515
+ uicr .SECURESTORAGE .ITS .APPLICATIONSIZE1KB = args .cpuapp_its_size // 1024
516
+ uicr .SECURESTORAGE .ITS .RADIOCORESIZE1KB = args .cpurad_its_size // 1024
517
+
336
518
# Process periphconf data first and configure UICR completely before creating hex objects
337
519
periphconf_hex = IntelHex ()
338
520
secondary_periphconf_hex = IntelHex ()
0 commit comments