blob: 5511c9a173cb43fccee27e762351a9d9e22a6914 [file] [log] [blame]
Roman Okhrimenkodc0ca082023-06-21 20:49:51 +03001"""MCUBoot Flash Map Converter (JSON to .h)
2Copyright (c) 2022 Infineon Technologies AG
3"""
4
5import sys
6import getopt
7import json
8from enum import Enum
9import os.path
10
11class Error(Enum):
12 ''' Application error codes '''
13 ARG = 1
14 POLICY = 2
15 FLASH = 3
16 IO = 4
17 JSON = 5
18 VALUE = 6
19 CONFIG_MISMATCH = 7
20
21SERVICE_APP_SZ = 0x20
22
23c_array = 'flash_areas'
24
25# Supported Platforms
26cm0pCore = {
27 'cortex-m0+': 'CM0P',
28 'cm0+': 'CM0P',
29 'm0+': 'CM0P',
30 'cortex-m0p': 'CM0P',
31 'cm0p': 'CM0P',
32 'm0p': 'CM0P',
33 'cortex-m0plus': 'CM0P',
34 'cm0plus': 'CM0P',
35 'm0plus': 'CM0P'
36}
37
38cm4Core = {
39 'cortex-m4': 'CM4',
40 'cm4': 'CM4',
41 'm4': 'CM4'
42}
43
44cm33Core = {
45 'cortex-m33': 'CM33',
46 'cm33': 'CM33',
47 'm33': 'CM33'
48}
49
50cm7Core = {
51 'cortex-m7': 'CM7',
52 'cm7': 'CM7',
53 'm7': 'CM7'
54}
55
56allCores_PSOC_06x = {**cm0pCore, **cm4Core}
57
58common_PSOC_061 = {
59 'flashAddr': 0x10000000,
60 'eraseSize': 0x200, # 512 bytes
61 'smifAddr': 0x18000000,
62 'smifSize': 0x8000000, # i.e., window size
63 'VTAlign': 0x400, # Vector Table alignment
64 'allCores': cm4Core,
65 'bootCore': 'Cortex-M4',
66 'appCore': 'Cortex-M4'
67}
68
69common_PSOC_06x = {
70 'flashAddr': 0x10000000,
71 'eraseSize': 0x200, # 512 bytes
72 'smifAddr': 0x18000000,
73 'smifSize': 0x8000000, # i.e., window size
74 'VTAlign': 0x400, # Vector Table alignment
75 'allCores': allCores_PSOC_06x,
76 'bootCore': 'Cortex-M0+',
77 'appCore': 'Cortex-M4'
78}
79
80common_XMC7000 = {
81 'flashAddr': 0x10000000,
82 'eraseSize': 0x8000, # 512 bytes
83 'smifAddr': 0x18000000,
84 'smifSize': 0x8000000, # i.e., window size
85 'VTAlign': 0x400, # Vector Table alignment
86 'allCores': cm7Core,
87 'bootCore': 'Cortex-M7',
88 'appCore': 'Cortex-M7'
89}
90
91common_PSE84 = {
92 'flashAddr': 0x32000000,
93 'flashSize': 0x40000,
94 'eraseSize': 0x20, # 32 bytes
95 'smifAddr': 0x60000000, #secure address
96 'smifSize': 0x4000000, # i.e., window size
97 'VTAlign': 0x400, # Vector Table alignment
98 'allCores': cm33Core,
99 'bootCore': 'Cortex-M33',
100 'appCore': 'Cortex-M33'
101}
102
103platDict = {
104 'PSOC_061_2M': {
105 'flashSize': 0x200000, # 2 MBytes
106 **common_PSOC_061
107 },
108 'PSOC_061_1M': {
109 'flashSize': 0x100000, # 1 MByte
110 **common_PSOC_061
111 },
112 'PSOC_061_512K': {
113 'flashSize': 0x80000, # 512 KBytes
114 **common_PSOC_061
115 },
116
117 'PSOC_062_2M': {
118 'flashSize': 0x200000, # 2 MBytes
119 **common_PSOC_06x
120 },
121 'PSOC_062_1M': {
122 'flashSize': 0x100000, # 1 MByte
123 **common_PSOC_06x
124 },
125 'PSOC_062_512K': {
126 'flashSize': 0x80000, # 512 KBytes
127 **common_PSOC_06x
128 },
129
130 'PSOC_063_1M': {
131 'flashSize': 0x100000, # 1 MByte
132 **common_PSOC_06x
133 },
134
135 'XMC7200': {
136 'flashSize': 0x100000, # 1 MByte
137 **common_XMC7000
138 },
139
140 'XMC7100': {
141 'flashSize': 0x100000, # 1 MByte
142 **common_PSOC_06x
143 },
144
145 'CYW20829': {
146 'flashSize': 0, # n/a
147 'smifAddr': 0x60000000,
148 'smifSize': 0x8000000, # i.e., window size
149 'VTAlign': 0x200, # Vector Table alignment
150 'allCores': cm33Core,
151 'bootCore': 'Cortex-M33',
152 'appCore': 'Cortex-M33',
153 'bitsPerCnt': False
154 },
155
156 'PSE84_L4': {
157 **common_PSE84
158 },
159
160 'PSE84_L2': {
161 **common_PSE84
162 }
163}
164
165# Supported SPI Flash ICs
166flashDict = {
167 # Fudan
168 'FM25Q04': {
169 'flashSize': 0x80000, # 4 Mbits
170 'eraseSize': 0x1000, # 128 uniform sectors with 4K-byte each
171 },
172 'FM25W04': {
173 'flashSize': 0x80000, # 4 Mbits
174 'eraseSize': 0x1000, # 128 uniform sectors with 4K-byte each
175 },
176 'FM25Q08': {
177 'flashSize': 0x100000, # 8 Mbits
178 'eraseSize': 0x1000, # 256 uniform sectors with 4K-byte each
179 },
180 'FM25W08': {
181 'flashSize': 0x100000, # 8 Mbits
182 'eraseSize': 0x1000, # 256 uniform sectors with 4K-byte each
183 },
184 # Puya
185 'P25Q05H': {
186 'flashSize': 0x10000, # 512 Kbits
187 'eraseSize': 0x1000, # Uniform 4K-byte Sector Erase
188 },
189 'P25Q10H': {
190 'flashSize': 0x20000, # 1 Mbit
191 'eraseSize': 0x1000, # Uniform 4K-byte Sector Erase
192 },
193 'P25Q20H': {
194 'flashSize': 0x40000, # 2 Mbits
195 'eraseSize': 0x1000, # Uniform 4K-byte Sector Erase
196 },
197 'P25Q40H': {
198 'flashSize': 0x80000, # 4 Mbits
199 'eraseSize': 0x1000, # Uniform 4K-byte Sector Erase
200 },
201 # Infineon
202 'S25HS256T': {
203 'flashSize': 0x2000000, # 256 Mbits
204 'eraseSize': 0x40000, # Uniform Sector Architecture
205 },
206 'S25HS512T': {
207 'flashSize': 0x4000000, # 512 Mbits
208 'eraseSize': 0x40000, # Uniform Sector Architecture
209 },
210 'S25HS01GT': {
211 'flashSize': 0x8000000, # 1 Gbit
212 'eraseSize': 0x40000, # Uniform Sector Architecture
213 }
214}
215
216
217def is_overlap(fa1off, fa1size, fa2off, fa2size, align):
218 """Check if two flash areas on the same device overlap"""
219 mask = align - 1
220 assert align > 0 and (align & mask) == 0 # ensure align is a power of 2
221 fa1end = (fa1off + fa1size + mask) & ~mask
222 fa2end = (fa2off + fa2size + mask) & ~mask
223 fa1off = fa1off & ~mask
224 fa2off = fa2off & ~mask
225 return fa1off < fa2end and fa2off < fa1end
226
227
228def is_same_mem(fa1addr, fa2addr):
229 """Check if two addresses belong to the same memory"""
230 if fa1addr is None or fa2addr is None:
231 return False
232 mask = 0xFF000000
233 return (fa1addr & mask) == (fa2addr & mask)
234
235
236class CmdLineParams:
237 """Command line parameters"""
238
239 def __init__(self):
240 self.plat_id = ''
241 self.in_file = ''
242 self.out_file = ''
243 self.fa_file = ''
244 self.img_id = None
245 self.policy = None
246 self.set_core = False
247 self.image_boot_config = False
248
249 usage = 'USAGE:\n' + sys.argv[0] + \
250 ''' -p <platform> -i <flash_map.json> -o <memorymap.c> -a <memorymap.h> -d <img_id> -c <policy.json>
251
252OPTIONS:
253-h --help Display the usage information
254-p --platform= Target (e.g., PSOC_062_512K)
255-i --ifile= JSON flash map file
256-o --ofile= C file to be generated
257-a --fa_file= path where to create 'memorymap.h'
258-d --img_id ID of application to build
259-c --policy Policy file in JSON format
260-m --core Detect and set Cortex-M CORE
261-x --image_boot_config Generate image boot config structure
262'''
263
264 try:
265 opts, unused = getopt.getopt(
266 sys.argv[1:], 'hi:o:a:p:d:c:x:m',
267 ['help', 'platform=', 'ifile=', 'ofile=', "fa_file=", 'img_id=', 'policy=', 'core', 'image_boot_config'])
268 except getopt.GetoptError:
269 print(usage, file=sys.stderr)
270 sys.exit(Error.ARG)
271
272 for opt, arg in opts:
273 if opt in ('-h', '--help'):
274 print(usage, file=sys.stderr)
275 sys.exit()
276 elif opt in ('-p', '--platform'):
277 self.plat_id = arg
278 elif opt in ('-i', '--ifile'):
279 self.in_file = arg
280 elif opt in ('-o', '--ofile'):
281 self.out_file = arg
282 elif opt in ('-a', '--fa_file'):
283 self.fa_file = arg
284 elif opt in ('-d', '--img_id'):
285 self.img_id = arg
286 elif opt in ('-c', '--policy'):
287 self.policy = arg
288 elif opt in ('-m', '--core'):
289 self.set_core = True
290 elif opt in ('x', '--image_boot_config'):
291 self.image_boot_config = True
292
293 if len(self.in_file) == 0 or len(self.out_file) == 0 or len(self.fa_file) == 0:
294 print(usage, file=sys.stderr)
295 sys.exit(Error.ARG)
296
297
298class AreaList:
299 '''
300 A List of flash areas
301 ...
302
303 Attributes
304 ----------
305 plat : dict
306 Platform settings
307
308 flash : dict
309 External flash settings
310
311 use_overwrite : bool
312 Overwrite configuration in use
313
314 areas : list
315 Flash area parameter list
316
317 peers : set
318 Peers
319
320 trailers : set
321 Flash area trailers
322
323 internal_flash : bool
324 Internal flash in use
325
326 external_flash : bool
327 External flash in use
328
329 external_flash_xip : bool
330 External XIP in use
331
332 Methods
333 -------
334 get_min_erase_size:
335 Calculate minimum erase block size for int./ext. Flash
336
337 get_img_trailer_size:
338 Calculate image trailer size
339
340 process_int_area:
341 Process internal flash area
342
343 process_ext_area:
344 Process external flash area
345
346 chk_area:
347 Check area location (internal/external flash)
348
349 add_area:
350 Add flash area to AreaList.
351 Internal/external flash is detected by address.
352
353 generate_c_source:
354 Generate C source
355
356 create_flash_area_id:
357 Creates flash_area_id.h file.
358 '''
359
360 def __init__(self, plat, flash, use_overwrite):
361 self.plat = plat
362 self.flash = flash
363 self.use_overwrite = use_overwrite
364 self.areas = []
365 self.peers = {}
366 self.trailers = {}
367 self.internal_flash = False
368 self.external_flash = False
369 self.external_flash_xip = False
370
371 def get_min_erase_size(self):
372 '''Calculate minimum erase block size for int./ext. Flash '''
373 return self.plat['eraseSize'] if self.plat['flashSize'] > 0 \
374 else self.flash['eraseSize']
375
376 def get_img_trailer_size(self):
377 '''Calculate image trailer size'''
378 return self.get_min_erase_size()
379
380 def process_int_area(self, title, addr, fa_size,
381 img_trailer_size, shared_slot):
382 '''
383 Process internal flash area
384 Parameters:
385 ----------
386 title : str
387 Area name
388
389 addr : int
390 Area address
391
392 fa_size : int
393 Area size
394
395 img_trailer_size : int
396 Trailer size
397
398 shared_slot : bool
399 Shared slot option in use
400
401 Returns:
402 ----------
403 fa_device_id : str
404
405 fa_off : int
406
407 slot_sectors : int
408 '''
409 fa_device_id = 'FLASH_DEVICE_INTERNAL_FLASH'
410 fa_off = addr - self.plat['flashAddr']
411 if img_trailer_size is not None:
412 if self.use_overwrite:
413 if shared_slot:
414 print('Shared slot', title,
415 'is not supported in OVERWRITE mode',
416 file=sys.stderr)
417 sys.exit(Error.CONFIG_MISMATCH)
418 else:
419 # Check trailer alignment (start at the sector boundary)
420 align = (fa_off + fa_size - img_trailer_size) % \
421 self.plat['eraseSize']
422 if align != 0:
423 addr += self.plat['eraseSize'] - align
424 if addr + fa_size <= \
425 self.plat['flashAddr'] + self.plat['flashSize']:
426 print('Misaligned', title,
427 '- suggested address', hex(addr),
428 file=sys.stderr)
429 else:
430 print('Misaligned', title, file=sys.stderr)
431 sys.exit(Error.CONFIG_MISMATCH)
432 else:
433 # Check alignment (flash area should start at the sector boundary)
434 if fa_off % self.plat['eraseSize'] != 0:
435 print('Misaligned', title, file=sys.stderr)
436 sys.exit(Error.CONFIG_MISMATCH)
437 slot_sectors = int((fa_off % self.plat['eraseSize'] +
438 fa_size + self.plat['eraseSize'] - 1) //
439 self.plat['eraseSize'])
440 return fa_device_id, fa_off, slot_sectors
441
442 def process_ext_area(self, title, addr, fa_size,
443 img_trailer_size, shared_slot):
444 '''
445 Process external flash area
446 Parameters:
447 ----------
448 title : str
449 Area name
450
451 addr : int
452 Area address
453
454 fa_size : int
455 Area size
456
457 img_trailer_size : int
458 Trailer size
459
460 shared_slot : bool
461 Shared slot option in use
462
463 Returns:
464 ----------
465 fa_device_id : str
466
467 fa_off : int
468
469 slot_sectors : int
470 '''
471 if self.flash is None:
472 print('Unspecified SPI Flash IC',
473 file=sys.stderr)
474 sys.exit(Error.FLASH)
475 if addr + fa_size <= \
476 self.plat['smifAddr'] + self.flash['flashSize']:
477 flash_idx = 'CY_BOOT_EXTERNAL_DEVICE_INDEX'
478 fa_device_id = f'FLASH_DEVICE_EXTERNAL_FLASH({flash_idx})'
479 fa_off = addr - self.plat['smifAddr']
480 else:
481 print('Misfitting', title, file=sys.stderr)
482 sys.exit(Error.CONFIG_MISMATCH)
483 if img_trailer_size is not None:
484 if self.use_overwrite:
485 if shared_slot:
486 print('Shared slot', title,
487 'is not supported in OVERWRITE mode',
488 file=sys.stderr)
489 sys.exit(Error.CONFIG_MISMATCH)
490 else:
491 # Check trailer alignment (start at the sector boundary)
492 align = (fa_off + fa_size - img_trailer_size) % \
493 self.flash['eraseSize']
494 if align != 0:
495 peer_addr = self.peers.get(addr)
496 if shared_slot:
497 # Special case when using both int. and ext. memory
498 if self.plat['flashSize'] > 0 and \
499 align % self.plat['eraseSize'] == 0:
500 print('Note:', title, 'requires', align,
501 'padding bytes before trailer',
502 file=sys.stderr)
503 else:
504 print('Misaligned', title, file=sys.stderr)
505 sys.exit(Error.CONFIG_MISMATCH)
506 elif is_same_mem(addr, peer_addr) and \
507 addr % self.flash['eraseSize'] == \
508 peer_addr % self.flash['eraseSize']:
509 pass # postpone checking
510 else:
511 addr += self.flash['eraseSize'] - align
512 if addr + fa_size <= \
513 self.plat['smifAddr'] + self.flash['flashSize']:
514 print('Misaligned', title,
515 '- suggested address', hex(addr),
516 file=sys.stderr)
517 else:
518 print('Misaligned', title, file=sys.stderr)
519 sys.exit(Error.CONFIG_MISMATCH)
520 else:
521 # Check alignment (flash area should start at the sector boundary)
522 if fa_off % self.flash['eraseSize'] != 0:
523 print('Misaligned', title, file=sys.stderr)
524 sys.exit(Error.CONFIG_MISMATCH)
525 slot_sectors = int((fa_off % self.flash['eraseSize'] +
526 fa_size + self.flash['eraseSize'] - 1) //
527 self.flash['eraseSize'])
528 self.external_flash = True
529 if self.flash['XIP']:
530 self.external_flash_xip = True
531 return fa_device_id, fa_off, slot_sectors
532
533 def chk_area(self, addr, fa_size, peer_addr=None):
534 '''
535 Check area location (internal/external flash)
536 Parameters:
537 ----------
538 addr : int
539 Area address
540
541 fa_size : int
542 Area size
543
544 peer_addr : bool (optional)
545 Shared slot option in use
546
547 Returns:
548 ----------
549 None
550 '''
551 if peer_addr is not None:
552 self.peers[peer_addr] = addr
553 fa_limit = addr + fa_size
554 if self.plat['flashSize'] and \
555 addr >= self.plat['flashAddr'] and \
556 fa_limit <= self.plat['flashAddr'] + self.plat['flashSize']:
557 # Internal flash
558 self.internal_flash = True
559
560 def add_area(self, title,
561 fa_id, addr, fa_size,
562 img_trailer_size=None, shared_slot=False):
563 '''
564 Add flash area to AreaList.
565 Internal/external flash is detected by address.
566 Parameters:
567 ----------
568 title : str
569 Area name
570
571 fa_id : str
572 Area id
573
574 addr : int
575 Area address
576
577 fa_size : int
578 Area size
579
580 img_trailer_size : int
581 Trailer size (optional)
582
583 shared_slot : bool
584 Shared slot option in use (optional)
585
586 Returns:
587 ----------
588 slot_sectors : int
589 Number of sectors in a slot
590 '''
591 if fa_size == 0:
592 print('Empty', title, file=sys.stderr)
593 sys.exit(Error.CONFIG_MISMATCH)
594
595 fa_limit = addr + fa_size
596 if self.plat['flashSize'] and \
597 addr >= self.plat['flashAddr'] and \
598 fa_limit <= self.plat['flashAddr'] + self.plat['flashSize']:
599 # Internal flash
600 fa_device_id, fa_off, slot_sectors = self.process_int_area(
601 title, addr, fa_size, img_trailer_size, shared_slot)
602 align = self.plat['eraseSize']
603 elif self.plat['smifSize'] and \
604 addr >= self.plat['smifAddr'] and \
605 fa_limit <= self.plat['smifAddr'] + self.plat['smifSize']:
606 # External flash
607 fa_device_id, fa_off, slot_sectors = self.process_ext_area(
608 title, addr, fa_size, img_trailer_size, shared_slot)
609 align = self.flash['eraseSize']
610 else:
611 print('Invalid', title, file=sys.stderr)
612 sys.exit(Error.CONFIG_MISMATCH)
613
614 if shared_slot:
615 assert img_trailer_size is not None
616 tr_addr = addr + fa_size - img_trailer_size
617 tr_name = self.trailers.get(tr_addr)
618 if tr_name is not None:
619 print('Same trailer address for', title, 'and', tr_name,
620 file=sys.stderr)
621 sys.exit(Error.CONFIG_MISMATCH)
622 self.trailers[tr_addr] = title
623
624 # Ensure no flash areas on this device will overlap, except the
625 # shared slot
626 for area in self.areas:
627 if fa_device_id == area['fa_device_id']:
628 over = is_overlap(fa_off, fa_size,
629 area['fa_off'], area['fa_size'],
630 align)
631 if shared_slot and area['shared_slot']:
632 if not over: # images in shared slot should overlap
633 print(title, 'is not shared with', area['title'],
634 file=sys.stderr)
635 sys.exit(Error.CONFIG_MISMATCH)
636 elif over:
637 print(title, 'overlaps with', area['title'],
638 file=sys.stderr)
639 sys.exit(Error.CONFIG_MISMATCH)
640
641 self.areas.append({'title': title,
642 'shared_slot': shared_slot,
643 'fa_id': fa_id,
644 'fa_device_id': fa_device_id,
645 'fa_off': fa_off,
646 'fa_size': fa_size})
647 return slot_sectors
648
649 def generate_c_source(self, params):
650 '''
651 Generate C source
652 Parameters:
653 ----------
654 params : CmdLineParams
655 Application parameters
656
657 Returns:
658 ----------
659 None
660 '''
661 c_array = 'flash_areas'
662
663 try:
664 with open(params.out_file, "w", encoding='UTF-8') as out_f:
665
666 out_f.write(f'#include "{params.fa_file}"\n')
667 out_f.write(f'#include "flash_map_backend.h"\n\n')
668 out_f.write(f'#include "flash_map_backend_platform.h"\n\n')
669 out_f.write(f'struct flash_area {c_array}[] = {{\n')
670 comma = len(self.areas)
671 area_count = 0
672 for area in self.areas:
673 comma -= 1
674 if area['fa_id'] is not None:
675 sss = ' /* Shared secondary slot */' \
676 if area['shared_slot'] else ''
677 out_f.writelines('\n'.join([
678 ' {' + sss,
679 f" .fa_id = {area['fa_id']},",
680 f" .fa_device_id = {area['fa_device_id']},",
681 f" .fa_off = {hex(area['fa_off'])}U,",
682 f" .fa_size = {hex(area['fa_size'])}U",
683 ' },' if comma else ' }', '']))
684 area_count += 1
685 out_f.write('};\n\n'
686 'struct flash_area *boot_area_descs[] = {\n')
687 for area_index in range(area_count):
688 out_f.write(f' &{c_array}[{area_index}U],\n')
689 out_f.write(' NULL\n};\n')
690 out_f.close()
691
692 except (FileNotFoundError, OSError):
693 print('Cannot create', params.out_file, file=sys.stderr)
694 sys.exit(Error.IO)
695
696 def create_flash_area_id(self, img_number, params):
697 """ Get 'img_number' and generate flash_area_id.h file' """
698
699 #check if params.fa_file already exists and it has FLASH_AREA_ID
700 if os.path.exists(params.fa_file):
701 with open(params.fa_file, "r", encoding='UTF-8') as fa_f:
702 content = fa_f.read()
703 res = content.find(f"FLASH_AREA_IMG_{img_number}_SECONDARY")
704 if res != -1:
705 fa_f.close()
706 return
707
708 fa_f.close()
709
710 try:
711 with open(params.fa_file, "w", encoding='UTF-8') as fa_f:
712 fa_f.write("#ifndef MEMORYMAP_H\n")
713 fa_f.write("#define MEMORYMAP_H\n\n")
714 fa_f.write('/* AUTO-GENERATED FILE, DO NOT EDIT.'
715 ' ALL CHANGES WILL BE LOST! */\n')
716 fa_f.write(f'#include "flash_map_backend.h"\n\n')
717
718 fa_f.write(f'extern struct flash_area {c_array}[];\n')
719 fa_f.write(f'extern struct flash_area *boot_area_descs[];\n')
720
721 #we always have BOOTLOADER and IMG_1_
722 fa_f.write("#define FLASH_AREA_BOOTLOADER ( 0u)\n\n")
723 fa_f.write("#define FLASH_AREA_IMG_1_PRIMARY ( 1u)\n")
724 fa_f.write("#define FLASH_AREA_IMG_1_SECONDARY ( 2u)\n\n")
725
726 fa_f.write("#define FLASH_AREA_IMAGE_SCRATCH ( 3u)\n")
727 fa_f.write("#define FLASH_AREA_IMAGE_SWAP_STATUS ( 7u)\n\n")
728
729 for img in range(2, img_number + 1):
730 """ img_id_primary and img_id_secondary must be aligned with the
731 flash_area_id, calculated in the functions
732 __STATIC_INLINE uint8_t FLASH_AREA_IMAGE_PRIMARY(uint32_t img_idx) and
733 __STATIC_INLINE uint8_t FLASH_AREA_IMAGE_SECONDARY(uint32_t img_idx),
734 in boot/cypress/platforms/memory/sysflash/sysflash.h
735 """
736
737 slots_for_image = 2
738 img_id_primary = None
739 img_id_secondary = None
740
741 if img == 2:
742 img_id_primary = int(slots_for_image * img)
743 img_id_secondary = int(slots_for_image * img + 1)
744
745 #number 7 is used for FLASH_AREA_IMAGE_SWAP_STATUS, so the next is 8
746 if img >= 3:
747 img_id_primary = int(slots_for_image * img + 2)
748 img_id_secondary = int(slots_for_image * img + 3)
749
750 fa_f.write(f"#define FLASH_AREA_IMG_{img}_PRIMARY ( {img_id_primary}u)\n")
751 fa_f.write(f"#define FLASH_AREA_IMG_{img}_SECONDARY ( {img_id_secondary}u)\n\n")
752
753 if self.plat.get('bitsPerCnt'):
754 fa_f.close()
755
756 list_counters = process_policy_20829(params.policy)
757 if list_counters is not None:
758 form_max_counter_array(list_counters, params.fa_file)
759 else:
760 fa_f.write("#endif /* MEMORYMAP_H */")
761 fa_f.close()
762
763 except (FileNotFoundError, OSError):
764 print('\nERROR: Cannot create ', params.fa_file, file=sys.stderr)
765 sys.exit(Error.IO)
766
767
768def cvt_dec_or_hex(val, desc):
769 """Convert (hexa)decimal string to number"""
770 try:
771 return int(val, 0)
772 except ValueError:
773 print('Invalid value', val, 'for', desc, file=sys.stderr)
774 sys.exit(Error.VALUE)
775
776
777def get_val(obj, attr):
778 """Get JSON 'value'"""
779 obj = obj[attr]
780 try:
781 return cvt_dec_or_hex(obj['value'], obj['description'])
782 except KeyError as key:
783 print('Malformed JSON:', key,
784 'is missing in', "'" + attr + "'",
785 file=sys.stderr)
786 sys.exit(Error.JSON)
787
788
789def get_bool(obj, attr, def_val=False):
790 """Get JSON boolean value (returns def_val if it is missing)"""
791 ret_val = def_val
792 obj = obj.get(attr)
793 if obj is not None:
794 try:
795 val = str(obj['value']).lower()
796 desc = obj['description']
797 if val == 'true':
798 ret_val = True
799 elif val == 'false':
800 ret_val = False
801 else:
802 print('Invalid value', val, 'for', desc, file=sys.stderr)
803 sys.exit(Error.VALUE)
804 except KeyError as key:
805 print('Malformed JSON:', key,
806 'is missing in', "'" + attr + "'",
807 file=sys.stderr)
808 sys.exit(Error.JSON)
809 return ret_val
810
811
812def get_str(obj, attr, def_val=None):
813 """Get JSON string value (returns def_val if it is missing)"""
814 ret_val = def_val
815 obj = obj.get(attr)
816 if obj is not None:
817 try:
818 ret_val = str(obj['value'])
819 except KeyError as key:
820 print('Malformed JSON:', key,
821 'is missing in', "'" + attr + "'",
822 file=sys.stderr)
823 sys.exit(Error.JSON)
824 return ret_val
825
826
827class AddrSize:
828 """Bootloader area"""
829
830 def __init__(self, bootloader, addr_name, size_name):
831 self.addr = get_val(bootloader, addr_name)
832 self.size = get_val(bootloader, size_name)
833
834
835def calc_status_size(boot_swap_status_row_sz, max_img_sectors,
836 img_number, scratch_flag=True):
837 """Estimate status size, see swap_status.h"""
838 boot_swap_status_cnt_sz = 4
839 boot_swap_status_crc_sz = 4
840 boot_swap_status_mgcrec_sz = 4
841 boot_swap_status_trailer_size = 64
842 boot_swap_status_payld_sz = \
843 boot_swap_status_row_sz - boot_swap_status_mgcrec_sz - \
844 boot_swap_status_cnt_sz - boot_swap_status_crc_sz
845 boot_swap_status_sect_rows_num = \
846 int((max_img_sectors - 1) //
847 boot_swap_status_payld_sz) + 1
848 boot_swap_status_trail_rows_num = \
849 int((boot_swap_status_trailer_size - 1) //
850 boot_swap_status_payld_sz) + 1
851 boot_swap_status_d_size = \
852 boot_swap_status_row_sz * \
853 (boot_swap_status_sect_rows_num + boot_swap_status_trail_rows_num)
854 boot_swap_status_mult = 2
855 boot_swap_status_size = boot_swap_status_mult * boot_swap_status_d_size
856 status_zone_cnt = 2 * img_number
857 if scratch_flag:
858 status_zone_cnt += 1
859 return boot_swap_status_size * status_zone_cnt
860
861
862def process_json(in_file):
863 """Process JSON"""
864 try:
865 with open(in_file, encoding='UTF-8') as in_f:
866 try:
867 flash_map = json.load(in_f)
868 except ValueError:
869 print('Cannot parse', in_file, file=sys.stderr)
870 sys.exit(Error.IO)
871 except (FileNotFoundError, OSError):
872 print('Cannot open', in_file, file=sys.stderr)
873 sys.exit(Error.IO)
874 flash = flash_map.get('external_flash')
875 if flash is not None:
876 flash = flash[0]
877 model = flash.get('model')
878 mode = flash.get('mode')
879 if model is not None:
880 try:
881 flash = flashDict[model]
882 except KeyError:
883 print('Supported SPI Flash ICs are:',
884 ', '.join(flashDict.keys()),
885 file=sys.stderr)
886 sys.exit(Error.FLASH)
887 else:
888 try:
889 flash = {'flashSize': cvt_dec_or_hex(flash['flash-size'],
890 'flash-size'),
891 'eraseSize': cvt_dec_or_hex(flash['erase-size'],
892 'erase-size')}
893 except KeyError as key:
894 print('Malformed JSON:', key,
895 "is missing in 'external_flash'",
896 file=sys.stderr)
897 sys.exit(Error.FLASH)
898 flash.update({'XIP': str(mode).upper() == 'XIP'})
899 return flash_map.get('boot_and_upgrade', None), flash_map.get('ram_app_staging', None), flash
900
901def process_boot_type(boot_and_upgrade):
902 image_boot_mode = []
903
904 for app_index in range(1, 5):
905 app_ident = f'application_{app_index}'
906 application = boot_and_upgrade.get(app_ident)
907
908 if application:
909 ram = application.get('ram', application.get('ram_boot'))
910
911 if ram:
912 image_boot_mode.append(
913 {
914 'mode': 'IMAGE_BOOT_MODE_FLASH' if application.get('ram') else 'IMAGE_BOOT_MODE_RAM',
915 'address': ram.get('address', {}).get('value', 0),
916 'size': ram.get('size', {}).get('value', 0),
917 }
918 )
919
920 return image_boot_mode
921
922def generate_boot_type(image_boot_mode):
923 c_file = "image_boot_config.c"
924 h_file = "image_boot_config.h"
925 try:
926 with open(c_file, "w", encoding='UTF-8') as out_f:
927 out_f.write('/* AUTO-GENERATED FILE, DO NOT EDIT.'
928 ' ALL CHANGES WILL BE LOST! */\n')
929
930 out_f.write(f'#include "{h_file}"\n')
931 out_f.write('\nimage_boot_config_t image_boot_config[BOOT_IMAGE_NUMBER] = {\n')
932 for mode in image_boot_mode:
933 out_f.writelines('\n'.join([
934 '\t{\n'
935 f"\t\t.mode = {mode['mode']},",
936 f"\t\t.address = {mode['address']},",
937 f"\t\t.size = {mode['size']},",
938 '\t},\n']))
939 out_f.write('};\n')
940
941 with open(h_file, "w", encoding='UTF-8') as out_f:
942 out_f.write('/* AUTO-GENERATED FILE, DO NOT EDIT.'
943 ' ALL CHANGES WILL BE LOST! */\n')
944 out_f.write('#ifndef IMAGE_BOOT_CONFIG_H\n')
945 out_f.write('#define IMAGE_BOOT_CONFIG_H\n')
946 out_f.write('#include "bootutil/bootutil.h"\n')
947 out_f.writelines('\n'.join([
948 ' ',
949 'typedef enum',
950 '{',
951 '\tIMAGE_BOOT_MODE_FLASH = 0U,',
952 '\tIMAGE_BOOT_MODE_RAM = 1U,',
953 '} image_boot_mode_t;',
954 '',
955 'typedef struct image_boot_config_s {',
956 '\timage_boot_mode_t mode;',
957 '\tuint32_t address;',
958 '\tuint32_t size;',
959 '} image_boot_config_t;',
960 '',
961 'extern image_boot_config_t image_boot_config[BOOT_IMAGE_NUMBER];'
962 ]))
963 out_f.write('\n#endif /* IMAGE_BOOT_CONFIG_H */\n')
964
965 except (FileNotFoundError, OSError):
966 print('Cannot create', out_f, file=sys.stderr)
967 sys.exit(Error.IO)
968
969
970def process_images(area_list, boot_and_upgrade):
971 """Process images"""
972 app_count = 0
973 slot_sectors_max = 0
974 all_shared = get_bool(boot_and_upgrade['bootloader'], 'shared_slot')
975 any_shared = all_shared
976 app_core = None
977 apps_flash_map = [None, ]
978 apps_ram_map = [None, ]
979
980 for stage in range(2):
981 for app_index in range(1, 5):
982
983 app_flash_map = {}
984 app_ram_map = {}
985 app_ram_boot = False
986
987 try:
988 app_ident = f'application_{app_index}'
989 application = boot_and_upgrade[app_ident]
990
991 try:
992 flash = application['flash']
993 except KeyError:
994 #Backward compatibility
995 flash = application
996
997 try:
998 config = application['config']
999 except KeyError:
1000 #Backward compatibility
1001 config = application
1002
1003 try:
1004 ram = application['ram']
1005 except KeyError:
1006 try:
1007 ram = application['ram_boot']
1008 app_ram_boot = True
1009 except KeyError:
1010 ram = None
1011
1012 try:
1013 primary_addr = get_val(flash, 'address')
1014 primary_size = get_val(flash, 'size')
1015 secondary_addr = get_val(flash, 'upgrade_address')
1016 secondary_size = get_val(flash, 'upgrade_size')
1017
1018 if ram is not None:
1019 app_ram_addr = get_val(ram, 'address')
1020 app_ram_size = get_val(ram, 'size')
1021 else:
1022 app_ram_addr = None
1023 app_ram_size = None
1024
1025 except KeyError as key:
1026 print('Malformed JSON:', key, 'is missing',
1027 file=sys.stderr)
1028 sys.exit(Error.JSON)
1029 if stage == 0:
1030 if primary_size != secondary_size:
1031 print('Primary and secondary slot sizes'
1032 ' are different for', app_ident,
1033 file=sys.stderr)
1034 sys.exit(Error.VALUE)
1035 area_list.chk_area(primary_addr, primary_size)
1036 area_list.chk_area(secondary_addr, secondary_size,
1037 primary_addr)
1038 if config is None or config.get('core') is None:
1039 if app_index == 1:
1040 app_core = area_list.plat['appCore']
1041 elif app_index > 1:
1042 print('"core" makes sense only for the 1st app',
1043 file=sys.stderr)
1044 sys.exit(Error.VALUE)
1045 else:
1046 app_core = get_str(config, 'core',
1047 area_list.plat['appCore'])
1048 if app_index == 1:
1049 app_core = area_list.plat['allCores'].get(app_core.lower())
1050 if app_core is None:
1051 print('Unknown "core"', file=sys.stderr)
1052 sys.exit(Error.VALUE)
1053 else:
1054 slot_sectors_max = max(
1055 slot_sectors_max,
1056 area_list.add_area(
1057 f'{app_ident} (primary slot)',
1058 f'FLASH_AREA_IMG_{app_index}_PRIMARY',
1059 primary_addr, primary_size,
1060 area_list.get_img_trailer_size()))
1061 shared_slot = get_bool(flash, 'shared_slot', all_shared)
1062 any_shared = any_shared or shared_slot
1063 slot_sectors_max = max(
1064 slot_sectors_max,
1065 area_list.add_area(
1066 f'{app_ident} (secondary slot)',
1067 f'FLASH_AREA_IMG_{app_index}_SECONDARY',
1068 secondary_addr, secondary_size,
1069 area_list.get_img_trailer_size(),
1070 shared_slot))
1071
1072 app_slot_prim = {"address": hex(primary_addr), "size": hex(primary_size)}
1073 app_slot_sec = {"address": hex(secondary_addr), "size": hex(secondary_size)}
1074
1075 app_flash_map.update({"primary": app_slot_prim, "secondary": app_slot_sec})
1076 apps_flash_map.append(app_flash_map)
1077
1078 if ram is not None:
1079 app_ram_map.update({"address": app_ram_addr
1080 , "size": app_ram_size
1081 , "ram_boot": app_ram_boot})
1082 apps_ram_map.append(app_ram_map)
1083 else:
1084 apps_ram_map = None
1085
1086 app_count = app_index
1087
1088 except KeyError:
1089 break
1090 if app_count == 0:
1091 print('Malformed JSON: no application(s) found',
1092 file=sys.stderr)
1093 sys.exit(Error.JSON)
1094
1095 return app_core, app_count, slot_sectors_max, apps_flash_map, apps_ram_map, any_shared
1096
1097
1098def process_policy_20829(in_policy):
1099 """Process policy file to get data of NV-counter"""
1100 list_counters = None
1101
1102 try:
1103 with open(in_policy, encoding='UTF-8') as in_f:
1104 try:
1105 policy = json.load(in_f)
1106 except ValueError:
1107 print('\nERROR: Cannot parse', in_policy,'\n', file=sys.stderr)
1108 sys.exit(Error.IO)
1109 finally:
1110 in_f.close()
1111 except (FileNotFoundError, OSError):
1112 print('Cannot open', in_policy, file=sys.stderr)
1113 sys.exit(Error.IO)
1114
1115 try:
1116 nv_cnt = policy["device_policy"]['reprovisioning']['nv_counter']
1117 list_values = nv_cnt["value"]
1118 list_counters = nv_cnt["bits_per_cnt"]
1119 except KeyError:
1120 print("\nERROR: Check path to 'nv_counter' and its correctness in policy file", in_policy,
1121 ".\n", file=sys.stderr)
1122 sys.exit(Error.POLICY)
1123
1124 #Check correctness of NV-counter
1125 try:
1126 len_list_value = len(list_values)
1127 len_list_counters = len(list_counters)
1128 except TypeError:
1129 print("\nERROR: Fields 'value' and 'bits_per_cnt' of 'nv_counter' in policy file",
1130 in_policy,"must be arrays.\n", file=sys.stderr)
1131 sys.exit(Error.POLICY)
1132
1133 if len_list_value != len_list_counters:
1134 print("\nERROR: Fields 'value' and 'bits_per_cnt' of 'nv_counter' in policy file",
1135 in_policy,"must have the same size.\n", file=sys.stderr)
1136 sys.exit(Error.POLICY)
1137
1138 sum_all_counters = 0
1139 for i in range(len_list_value):
1140 sum_all_counters += list_counters[i]
1141 if list_values[i] > list_counters[i]:
1142 print("\nERROR: Field 'value' cannot be more then 'bits_per_cnt'.", file=sys.stderr)
1143 print("Check 'nv_counter' in policy file", in_policy,"\n", file=sys.stderr)
1144 sys.exit(Error.POLICY)
1145
1146 sum_all_bit_nv_counter = 32
1147 if sum_all_counters != sum_all_bit_nv_counter:
1148 print("\nERROR: The sum of all 'bits_per_cnt' must be equal to 32.", file=sys.stderr)
1149 print("Check 'nv_counter' in policy file", in_policy,"\n", file=sys.stderr)
1150 sys.exit(Error.POLICY)
1151
1152 return list_counters
1153
1154
1155def form_max_counter_array(in_list, out_file):
1156 '''Write bit_per_count array to output file
1157 There is expected, that "out_file" already exists'''
1158
1159 #ifdef here is needed to fix Rule 12.2 MISRA violation
1160 out_array_str = "\n#ifdef NEED_MAX_COUNTERS\nstatic const uint8_t bits_per_cnt[] = {"
1161
1162 #in_list is checked in prior function 'process_policy()'
1163 for i, list_member in enumerate(in_list):
1164 out_array_str += str(list_member)
1165 if i < len(in_list) - 1:
1166 out_array_str += ", "
1167 out_array_str += "};\n#endif\n"
1168
1169 try:
1170 with open(out_file, "a", encoding='UTF-8') as out_f:
1171 out_f.write(out_array_str)
1172 out_f.write("\n#endif /* MEMORYMAP_H */")
1173 except (FileNotFoundError, OSError):
1174 print('\nERROR: Cannot open ', out_file, file=sys.stderr)
1175 sys.exit(Error.CONFIG_MISMATCH)
1176
1177
1178def main():
1179 """Flash map converter"""
1180 params = CmdLineParams()
1181
1182 try:
1183 plat = platDict[params.plat_id]
1184 except KeyError:
1185 print('Supported platforms are:', ', '.join(platDict.keys()),
1186 file=sys.stderr)
1187 sys.exit(Error.POLICY)
1188
1189 try:
1190 boot_and_upgrade, ram_app_staging, flash = process_json(params.in_file)
1191 bootloader = boot_and_upgrade['bootloader']
1192 try:
1193 bootloader_config = bootloader['config']
1194 except KeyError:
1195 #Backward compatibility
1196 bootloader_config = bootloader
1197
1198 if ram_app_staging is not None:
1199 try:
1200 ram_app_staging_size = get_val(ram_app_staging, 'size')
1201 ram_app_staging_ext_mem_addr = get_val(ram_app_staging, 'external_mememory_address')
1202 ram_app_staging_sram_stage_addr = get_val(ram_app_staging, 'sram_stage_address')
1203 ram_app_staging_reset_trigger = get_bool(ram_app_staging, 'reset_after_staging')
1204 except KeyError:
1205 ram_app_staging = None
1206
1207 try:
1208 bootloader_flash = bootloader['flash']
1209 except KeyError:
1210 #Backward compatibility
1211 bootloader_flash = bootloader
1212
1213 try:
1214 bootloader_ram = bootloader['ram']
1215 except KeyError:
1216 #Backward compatibility
1217 bootloader_ram = bootloader
1218
1219 boot_flash_area = AddrSize(bootloader_flash, 'address', 'size')
1220 boot_ram_area = AddrSize(bootloader_ram, 'address', 'size')
1221 except KeyError as key:
1222 print('Malformed JSON:', key, 'is missing',
1223 file=sys.stderr)
1224 sys.exit(Error.JSON)
1225
1226 try:
1227 scratch = AddrSize(bootloader_flash, 'scratch_address', 'scratch_size')
1228 except KeyError:
1229 scratch = None
1230
1231 try:
1232 swap_status = AddrSize(bootloader_flash, 'status_address', 'status_size')
1233 except KeyError:
1234 swap_status = None
1235
1236 try:
1237 bootloader_shared_data = bootloader['shared_data']
1238 boot_shared_data_area = AddrSize(bootloader_shared_data, 'address', 'size')
1239 except KeyError:
1240 boot_shared_data_area = None
1241
1242 try:
1243 bootloader_startup = get_bool(bootloader_config, 'startup')
1244 except KeyError:
1245 bootloader_startup = None
1246
1247 try:
1248 ram_app_area = AddrSize(bootloader_config['ram_boot'], 'address', 'size')
1249 except KeyError:
1250 ram_app_area = None
1251
1252
1253 # Create flash areas
1254 area_list = AreaList(plat, flash, scratch is None and swap_status is None)
1255 area_list.add_area('bootloader', 'FLASH_AREA_BOOTLOADER',
1256 boot_flash_area.addr, boot_flash_area.size)
1257
1258 # Service RAM app (optional)
1259 service_app = boot_and_upgrade.get('service_app')
1260 app_binary = None
1261 input_params = None
1262 app_desc = None
1263 if service_app is not None:
1264 if plat['flashSize'] > 0:
1265 print('service_app is unsupported on this platform',
1266 file=sys.stderr)
1267 sys.exit(Error.CONFIG_MISMATCH)
1268 try:
1269 app_binary = AddrSize(service_app, 'address', 'size')
1270 input_params = AddrSize(service_app, 'params_address', 'params_size')
1271 app_desc = AddrSize(service_app, 'desc_address', 'desc_size')
1272 if input_params.addr != app_binary.addr + app_binary.size or \
1273 app_desc.addr != input_params.addr + input_params.size or \
1274 app_desc.size != SERVICE_APP_SZ:
1275 print('Malformed service_app definition', file=sys.stderr)
1276 sys.exit(Error.CONFIG_MISMATCH)
1277 area_list.add_area('service_app', None, app_binary.addr,
1278 app_binary.size + input_params.size + app_desc.size)
1279 except KeyError as key:
1280 print('Malformed JSON:', key, 'is missing',
1281 file=sys.stderr)
1282 sys.exit(Error.JSON)
1283
1284 # Fill flash areas
1285 app_core, app_count, slot_sectors_max, apps_flash_map, apps_ram_map, shared_slot = \
1286 process_images(area_list, boot_and_upgrade)
1287
1288 if params.image_boot_config:
1289 image_boot_mode = process_boot_type(boot_and_upgrade)
1290
1291 if image_boot_mode:
1292 generate_boot_type(image_boot_mode)
1293
1294 cy_img_hdr_size = 0x400
1295 app_start = int(apps_flash_map[1].get("primary").get("address"), 0) + cy_img_hdr_size
1296
1297 if app_start % plat['VTAlign'] != 0:
1298 print('Starting address', apps_flash_map[1].get("primary").get("address"),
1299 '+', hex(cy_img_hdr_size),
1300 'must be aligned to', hex(plat['VTAlign']),
1301 file=sys.stderr)
1302 sys.exit(Error.CONFIG_MISMATCH)
1303
1304 slot_sectors_max = max(slot_sectors_max, 32)
1305
1306 if swap_status is not None:
1307 status_size_min = calc_status_size(area_list.get_min_erase_size(),
1308 slot_sectors_max,
1309 app_count,
1310 scratch is not None)
1311
1312 if swap_status.size < status_size_min:
1313 print('Insufficient swap status area - suggested size',
1314 hex(status_size_min),
1315 file=sys.stderr)
1316 sys.exit(Error.CONFIG_MISMATCH)
1317 area_list.add_area('swap status partition',
1318 'FLASH_AREA_IMAGE_SWAP_STATUS',
1319 swap_status.addr, swap_status.size)
1320
1321 if scratch is not None:
1322 area_list.add_area('scratch area',
1323 'FLASH_AREA_IMAGE_SCRATCH',
1324 scratch.addr, scratch.size)
1325
1326 # Compare size 'bit_per_cnt' and number of images.
1327 # 'service_app' is used only when HW rollback counter exists
1328 if plat.get('bitsPerCnt') is not None and service_app is not None:
1329 plat['bitsPerCnt'] = True
1330 list_counters = process_policy_20829(params.policy)
1331 if list_counters is not None and len(list_counters) != app_count:
1332 print("\nERROR: 'bits_per_cnt' must be present for each image!",
1333 file=sys.stderr)
1334 print("Please, check secure provisioning and reprovisioning policies.\n",
1335 file=sys.stderr)
1336 sys.exit(Error.CONFIG_MISMATCH)
1337
1338 # Image id parameter is not used for MCUBootApp
1339 if params.img_id is None:
1340 area_list.generate_c_source(params)
1341
1342 area_list.create_flash_area_id(app_count, params)
1343
1344 # Report necessary values back to make
1345 print('# AUTO-GENERATED FILE, DO NOT EDIT. ALL CHANGES WILL BE LOST!')
1346 if params.set_core:
1347 print('CORE :=', plat['allCores'][plat['bootCore'].lower()])
1348
1349 if ram_app_staging is not None:
1350 print('USE_STAGE_RAM_APPS := 1')
1351 print('RAM_APP_STAGING_EXT_MEM_ADDR := ', hex(ram_app_staging_ext_mem_addr))
1352 print('RAM_APP_STAGING_SRAM_MEM_ADDR :=', hex(ram_app_staging_sram_stage_addr))
1353 print('RAM_APP_STAGING_SIZE := ', hex(ram_app_staging_size))
1354 if ram_app_staging_reset_trigger is True:
1355 print('RAM_APP_RESET_TRIGGER := 1')
1356
1357 if bootloader_startup is True:
1358 print('BOOTLOADER_STARTUP := 1')
1359
1360 if ram_app_area is not None:
1361 print('USE_MCUBOOT_RAM_LOAD := 1')
1362 print('IMAGE_EXECUTABLE_RAM_START :=', hex(ram_app_area.addr))
1363 print('IMAGE_EXECUTABLE_RAM_SIZE :=', hex(ram_app_area.size))
1364
1365 if boot_shared_data_area is not None:
1366 print('USE_MEASURED_BOOT := 1')
1367 print('USE_DATA_SHARING := 1')
1368 print('BOOT_SHARED_DATA_ADDRESS :=', hex(boot_shared_data_area.addr)+'U')
1369 print('BOOT_SHARED_DATA_SIZE :=', hex(boot_shared_data_area.size)+'U')
1370 print('BOOT_SHARED_DATA_RECORD_SIZE :=', hex(boot_shared_data_area.size)+'U')
1371
1372 print('BOOTLOADER_ORIGIN :=', hex(boot_flash_area.addr))
1373 print('BOOTLOADER_SIZE :=', hex(boot_flash_area.size))
1374 print('BOOTLOADER_RAM_ORIGIN :=', hex(boot_ram_area.addr))
1375 print('BOOTLOADER_RAM_SIZE :=', hex(boot_ram_area.size))
1376 print('APP_CORE :=', app_core)
1377
1378 if params.img_id is not None:
1379 primary_img_start = apps_flash_map[int(params.img_id)].get("primary").get("address")
1380 secondary_img_start = apps_flash_map[int(params.img_id)].get("secondary").get("address")
1381 slot_size = apps_flash_map[int(params.img_id)].get("primary").get("size")
1382
1383 if apps_ram_map:
1384 image_ram_address = apps_ram_map[int(params.img_id)].get("address")
1385 image_ram_size = apps_ram_map[int(params.img_id)].get("size")
1386 image_ram_boot = apps_ram_map[int(params.img_id)].get("ram_boot")
1387 if image_ram_address and image_ram_size:
1388 print('IMG_RAM_ORIGIN := ' + hex(image_ram_address))
1389 print('IMG_RAM_SIZE := ' + hex(image_ram_size))
1390 if image_ram_boot is True:
1391 print('USE_MCUBOOT_RAM_LOAD := 1')
1392
1393 print('PRIMARY_IMG_START := ' + primary_img_start)
1394 print('SECONDARY_IMG_START := ' + secondary_img_start)
1395 print('SLOT_SIZE := ' + slot_size)
1396 else:
1397 if apps_ram_map:
1398 ram_load_counter = 0
1399 for img in apps_ram_map:
1400 if img is not None and img.get("ram_boot"):
1401 ram_load_counter += 1
1402
1403 if ram_load_counter != 0:
1404 if ram_load_counter == 1 and app_count == 1:
1405 print('USE_MCUBOOT_RAM_LOAD := 1')
1406 print(f'IMAGE_EXECUTABLE_RAM_START := {hex(apps_ram_map[1].get("address"))}')
1407 print(f'IMAGE_EXECUTABLE_RAM_SIZE := {hex(apps_ram_map[1].get("size"))}')
1408 else:
1409 print('USE_MCUBOOT_MULTI_MEMORY_LOAD := 1')
1410
1411 print('MAX_IMG_SECTORS :=', slot_sectors_max)
1412
1413 print('MCUBOOT_IMAGE_NUMBER :=', app_count)
1414 if area_list.external_flash:
1415 print('USE_EXTERNAL_FLASH := 1')
1416 if area_list.external_flash_xip:
1417 print('USE_XIP := 1')
1418
1419 if area_list.use_overwrite:
1420 print('USE_OVERWRITE := 1')
1421 if shared_slot:
1422 print('USE_SHARED_SLOT := 1')
1423 if service_app is not None:
1424 print('PLATFORM_SERVICE_APP_OFFSET :=',
1425 hex(app_binary.addr - plat['smifAddr']))
1426 print('PLATFORM_SERVICE_APP_INPUT_PARAMS_OFFSET :=',
1427 hex(input_params.addr - plat['smifAddr']))
1428 print('PLATFORM_SERVICE_APP_DESC_OFFSET :=',
1429 hex(app_desc.addr - plat['smifAddr']))
1430 print('USE_HW_ROLLBACK_PROT := 1')
1431
1432
1433if __name__ == '__main__':
1434 main()