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