1
1
#
2
2
# Copyright (c) 2017-2018 Future Electronics
3
+ # Copyright (c) 2018-2019 Cypress Semiconductor Corporation
3
4
#
4
5
# Licensed under the Apache License, Version 2.0 (the "License");
5
6
# you may not use this file except in compliance with the License.
20
21
import errno
21
22
from array import array
22
23
from struct import (pack , unpack )
23
- from distutils .spawn import find_executable
24
24
from shutil import copyfile
25
25
from intelhex import IntelHex
26
26
from intelhex .compat import asbytes
27
27
28
28
from ..config import ConfigException
29
- from ..targets import HookError
29
+
30
+ # The size of the program data in Cypress HEX files is limited to 0x80000000
31
+ # Higher addresses contain additional metadata (chip protection, eFuse data, etc..)
32
+ CY_PROGRAM_SIZE = 0x80000000
33
+
34
+ # The starting address of the program data checksum section
35
+ CY_CHECKSUM_ADDR = 0x90300000
36
+
37
+ # The starting address of the .cymeta section (12 bytes)
38
+ # Additional metadata include silicon revision, Silicon/JTAG ID, etc.
39
+ CY_META_ADDR = 0x90500000
40
+
41
+ # The address of the silicon ID (4 bytes)
42
+ CY_META_SILICON_ID_ADDR = 0x90500002
43
+
44
+ # The address of the metadata checksum (4 bytes)
45
+ CY_META_CHECKSUM_ADDR = 0x90500008
30
46
31
47
32
48
# Patch Cypress hex file:
33
49
# - update checksum
34
50
# - update metadata
35
51
# - align regions to page (256 bytes) boundary
36
52
def patch (message_func , ihex , hexf , align = 256 ):
37
- #calculate checksum
53
+ update_checksum = False
54
+ update_metadata = False
55
+
56
+ # calculate checksum of the program section, detect metadata
38
57
checksum = 0
39
58
for start , end in ihex .segments ():
40
- if start >= 0x090000000 :
59
+ if start == CY_CHECKSUM_ADDR :
60
+ # checksum section found in the original hex
61
+ update_checksum = True
62
+ if start == CY_META_ADDR :
63
+ # metadata section found in the original hex
64
+ update_metadata = True
65
+ if start >= CY_PROGRAM_SIZE :
41
66
continue
42
67
segment = ihex .tobinarray (start , end )
43
68
checksum += sum (segment )
44
69
45
- lowchecksum = checksum & 0x0FFFF
46
- message_func ("Calculated checksum for %s is 0x%04x" % (hexf , lowchecksum ))
70
+ # only update checksum if it was found in the original hex
71
+ if update_checksum :
72
+ lowchecksum = checksum & 0x0FFFF
73
+ message_func ("Calculated checksum for %s is 0x%04x" % (hexf , lowchecksum ))
47
74
48
- # update checksum
49
- checksum_str = pack ('>H' , lowchecksum )
50
- ihex .frombytes (array ('B' , checksum_str ), offset = 0x90300000 )
75
+ checksum_str = pack ('>H' , lowchecksum )
76
+ ihex .frombytes (array ('B' , checksum_str ), offset = CY_CHECKSUM_ADDR )
51
77
52
- # update metadata
53
- signature = unpack ('>L' , ihex .tobinstr (start = 0x90500002 , size = 4 ))[0 ]
54
- sigcheck = pack ('>L' , (checksum + signature ) & 0x0FFFF )
55
- ihex .frombytes (array ('B' ,sigcheck ), offset = 0x90500008 )
78
+ # only update metadata if it was found in the original hex
79
+ if update_metadata :
80
+ signature = unpack ('>L' , ihex .tobinstr (start = CY_META_SILICON_ID_ADDR , size = 4 ))[0 ]
81
+ sigcheck = pack ('>L' , (checksum + signature ) & 0x0FFFF )
82
+ ihex .frombytes (array ('B' ,sigcheck ), offset = CY_META_CHECKSUM_ADDR )
56
83
57
84
# align flash segments
58
85
align_mask = align - 1
59
86
alignments = IntelHex ()
60
87
for start , end in ihex .segments ():
61
- if start >= 0x090000000 :
88
+ if start >= CY_PROGRAM_SIZE :
62
89
continue
63
90
aligned_start = start & ~ align_mask
64
91
if start != aligned_start :
@@ -76,14 +103,8 @@ def merge_images(hexf0, hexf1=None):
76
103
ihex .padding = 0x00
77
104
ihex .loadfile (hexf0 , "hex" )
78
105
if hexf1 is not None :
79
- # get chip ID from metadata and compare
106
+ # Merge the CM0+ image
80
107
ihex1 = IntelHex (hexf1 )
81
- type0 = ihex .tobinarray (start = 0x90500002 , size = 4 )
82
- type1 = ihex1 .tobinarray (start = 0x90500002 , size = 4 )
83
- if type0 != type1 :
84
- raise HookError (
85
- "Incompatible processor type: %s in '%s' and 0x%s in '%s'"
86
- % (hexf0 , type0 , hexf1 , type1 ))
87
108
ihex .merge (ihex1 , 'ignore' )
88
109
return ihex
89
110
@@ -94,18 +115,18 @@ def complete_func(message_func, elf0, hexf0, hexf1=None, dest=None):
94
115
ihex .write_hex_file (dest if dest else hexf0 , write_start_addr = False , byte_count = 64 )
95
116
96
117
# Find Cortex M0 image.
97
- def find_cm0_image (toolchain , resources , elf , hexf ):
118
+ def find_cm0_image (toolchain , resources , elf , hexf , hex_filename ):
98
119
# Locate user-specified image
99
120
from tools .resources import FileType
100
121
hex_files = resources .get_file_paths (FileType .HEX )
101
- m0hexf = next ((f for f in hex_files if os .path .basename (f ) == toolchain . target . m0_core_img ), None )
122
+ m0hexf = next ((f for f in hex_files if os .path .basename (f ) == hex_filename ), None )
102
123
if toolchain .target .name .endswith ('_PSA' ):
103
124
m0hexf = next ((f for f in hex_files if os .path .basename (f ) == os .path .basename (hexf )), m0hexf )
104
125
105
126
if m0hexf :
106
127
toolchain .notify .debug ("M0 core image file found: %s." % os .path .basename (m0hexf ))
107
128
else :
108
- toolchain .notify .debug ("M0 core hex image file %s not found. Aborting." % toolchain . target . m0_core_img )
129
+ toolchain .notify .debug ("M0 core hex image file %s not found. Aborting." % hex_filename )
109
130
raise ConfigException ("Required M0 core hex image not found." )
110
131
111
132
return m0hexf
0 commit comments