programmer-core 1.0.29__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,921 @@
1
+ import logging
2
+ import os
3
+ from tabulate import tabulate
4
+ from construct import (
5
+ BitStruct,
6
+ BitsInteger,
7
+ ByteSwapped,
8
+ Bytes,
9
+ Container,
10
+ GreedyBytes,
11
+ Int16ul,
12
+ Int32ul,
13
+ Int8ul,
14
+ Padding,
15
+ Struct,
16
+ )
17
+
18
+ try:
19
+ from constants import (
20
+ REPORT_TYPE,
21
+ FLASH_DISCOVERY_CONF_SIZE_CC35XX,
22
+ FLASH_DISCOVERY_CONF_SIZE_CC35XXE,
23
+ )
24
+ from utility import ProgrammerUtility
25
+ except ImportError:
26
+ from .constants import (
27
+ REPORT_TYPE,
28
+ FLASH_DISCOVERY_CONF_SIZE_CC35XX,
29
+ FLASH_DISCOVERY_CONF_SIZE_CC35XXE,
30
+ )
31
+ from .utility import ProgrammerUtility
32
+
33
+ from flash_images_builder_core import FLASH_CALIBRATION_SIZE
34
+
35
+ PROGRAMMER_REPORT_LOGGER = logging.getLogger("report")
36
+
37
+
38
+ class ReportGenerator:
39
+
40
+ def __init__(
41
+ self,
42
+ report_type,
43
+ report_file_path,
44
+ programmer_artifacts_path,
45
+ fib_artifacts_path,
46
+ verbose=False,
47
+ ):
48
+
49
+ self.report_type = report_type
50
+ self.report_file_path = report_file_path
51
+ self.verbose = verbose
52
+ self.log_level = logging.INFO if verbose else logging.DEBUG
53
+ self.prog_utility = ProgrammerUtility(
54
+ programmer_artifacts_path, fib_artifacts_path
55
+ )
56
+ self.error_message = ""
57
+ self.report_container = None
58
+
59
+ self.report_struct = None
60
+
61
+ def get_report_struct_size(self):
62
+ return self.report_struct.sizeof()
63
+
64
+ def generate_report(self, report_bytes):
65
+ try:
66
+ # parse report from device
67
+ self.report_container = self.report_struct.parse(report_bytes)
68
+
69
+ report_table = self.prog_utility.create_table_from_json(
70
+ self.report_container
71
+ )
72
+ PROGRAMMER_REPORT_LOGGER.log(self.log_level, report_table)
73
+
74
+ except Exception as e:
75
+ self.error_message = f"Failed receiving report from device"
76
+ PROGRAMMER_REPORT_LOGGER.error(f"Report failed. Exception: {e}")
77
+ return False
78
+
79
+ self.report_file_path = self.prog_utility.fix_path(self.report_file_path)
80
+ with open(self.report_file_path, "w") as f:
81
+ f.write(report_table)
82
+
83
+ PROGRAMMER_REPORT_LOGGER.info(
84
+ f"Saved report image bin file at {self.report_file_path}",
85
+ )
86
+
87
+ return True
88
+
89
+
90
+ class ProgrammingReportGeneratorCC35XX(ReportGenerator):
91
+
92
+ def __init__(
93
+ self, report_file_path, programmer_artifacts_path, fib_artifacts_path, verbose
94
+ ):
95
+ super().__init__(
96
+ report_type=REPORT_TYPE.programming_pg1,
97
+ report_file_path=report_file_path,
98
+ programmer_artifacts_path=programmer_artifacts_path,
99
+ fib_artifacts_path=fib_artifacts_path,
100
+ verbose=verbose,
101
+ )
102
+
103
+ self.report_struct = Struct(
104
+ "report_header_version" / Int32ul,
105
+ "report_type" / Int8ul,
106
+ "type_version" / Int8ul,
107
+ "payload_length" / Int16ul,
108
+ "request_execution_status"
109
+ / ByteSwapped(
110
+ BitStruct(
111
+ "reserved" / Padding(22),
112
+ "secondary_vendor_sbl_done" / BitsInteger(1),
113
+ "secondary_vendor_image_done" / BitsInteger(1),
114
+ "secondary_ti_wsoc_image_done" / BitsInteger(1),
115
+ "primary_ti_wsoc_image_done" / BitsInteger(1),
116
+ "primary_vendor_sbl_done" / BitsInteger(1),
117
+ "primary_vendor_image_done" / BitsInteger(1),
118
+ "secondary_ti_bootloader_image_done" / BitsInteger(1),
119
+ "primary_ti_bootloader_image_done" / BitsInteger(1),
120
+ "boot_sector_done" / BitsInteger(1),
121
+ "fuse_programming_instructions_update_done" / BitsInteger(1),
122
+ )
123
+ ),
124
+ "request_validation_status"
125
+ / ByteSwapped(
126
+ BitStruct(
127
+ "reserved" / Padding(20),
128
+ "secondary_vendor_sbl_validate_pass" / BitsInteger(1),
129
+ "secondary_vendor_image_validate_pass" / BitsInteger(1),
130
+ "secondary_ti_wsoc_image_validate_pass" / BitsInteger(1),
131
+ "primary_ti_wsoc_image_validate_pass" / BitsInteger(1),
132
+ "primary_vendor_sbl_validate_pass" / BitsInteger(1),
133
+ "primary_vendor_image_validate_pass" / BitsInteger(1),
134
+ "secondary_ti_bootloader_image_validate_pass" / BitsInteger(1),
135
+ "primary_ti_bootloader_image_validate_pass" / BitsInteger(1),
136
+ "boot_sector_validate_pass" / BitsInteger(1),
137
+ "fuse_programming_instructions_alignment_verify_pass"
138
+ / BitsInteger(1),
139
+ "recoverable_fault" / BitsInteger(1),
140
+ "non_recoverable_failure" / BitsInteger(1),
141
+ )
142
+ ),
143
+ "vendor_fuse_report"
144
+ / Struct(
145
+ "rot" / Bytes(32),
146
+ # crc2 - not sure about the order
147
+ "crc2"
148
+ / ByteSwapped(
149
+ BitStruct(
150
+ "reserved" / Padding(23),
151
+ "security_failure_behavoral" / BitsInteger(1),
152
+ "use_ti_root_of_trust_secondary" / BitsInteger(3),
153
+ "boot_roll_back_protection_initial_version" / BitsInteger(5),
154
+ )
155
+ ),
156
+ # crc3 - not sure about the order
157
+ "crc3"
158
+ / ByteSwapped(
159
+ BitStruct(
160
+ "reserved" / Padding(7),
161
+ "permanently_lock_debug_enable" / BitsInteger(1),
162
+ "debug_rot_enable" / BitsInteger(1),
163
+ "otfde_protection_enable" / BitsInteger(1),
164
+ "action_request_authentication_enable" / BitsInteger(3),
165
+ "vendor_sbl_container_enable" / BitsInteger(1),
166
+ "vendor_container_authentication_enable" / BitsInteger(3),
167
+ "vendor_sbl_roll_back_protection_initial_version"
168
+ / BitsInteger(5),
169
+ "vendor_app_roll_back_protection_initial_version"
170
+ / BitsInteger(5),
171
+ "wsoc_fw_roll_back_initial_version" / BitsInteger(5),
172
+ )
173
+ ),
174
+ # crc4 - not sure about the order
175
+ "crc4"
176
+ / ByteSwapped(
177
+ BitStruct(
178
+ "reserved" / Padding(23),
179
+ "production_done" / BitsInteger(3),
180
+ "debug_crc_enable" / BitsInteger(3),
181
+ "sw_crc3_enable" / BitsInteger(3),
182
+ )
183
+ ),
184
+ # non crc - not sure about the order
185
+ "non_crc"
186
+ / ByteSwapped(
187
+ BitStruct(
188
+ "reserved" / Padding(13),
189
+ "qspi_ospi_flash_type" / BitsInteger(1),
190
+ "flash_exist" / BitsInteger(1),
191
+ "boot_sector_programmed" / BitsInteger(1),
192
+ "flash_reset_type" / BitsInteger(1),
193
+ "slow_clock_source" / BitsInteger(2),
194
+ "xtal_drift_calibration_room_temp" / BitsInteger(9),
195
+ "otp_structure_version" / BitsInteger(4),
196
+ )
197
+ ),
198
+ # vendor use
199
+ "vendor_use_1_2"
200
+ / ByteSwapped(
201
+ BitStruct(
202
+ "vendor_use_2" / BitsInteger(16),
203
+ "vendor_use_1" / BitsInteger(16),
204
+ )
205
+ ),
206
+ "vendor_use_3" / Int32ul,
207
+ "wsoc_fw_rollback_protection_1" / Int32ul,
208
+ "wsoc_fw_rollback_protection_2" / Int32ul,
209
+ "wsoc_fw_rollback_protection_3" / Int32ul,
210
+ "ti_bootloader_fw_rollback_protection_1" / Int32ul,
211
+ "ti_bootloader_fw_rollback_protection_2" / Int32ul,
212
+ "ti_bootloader_fw_rollback_protection_3" / Int32ul,
213
+ "vendor_sbl_fw_rollback_protection_1" / Int32ul,
214
+ "vendor_sbl_fw_rollback_protection_2" / Int32ul,
215
+ "vendor_sbl_fw_rollback_protection_3" / Int32ul,
216
+ "vendor_image_rollback_protection_1" / Int32ul,
217
+ "vendor_image_rollback_protection_2" / Int32ul,
218
+ "vendor_image_rollback_protection_3" / Int32ul,
219
+ # vendor debug tlv (MUST use if Debug ROT Enable is Enabled) or application otp tlv (use if Debug ROT Enable is Disabled)
220
+ "app_otp_or_debug_rot" / Bytes(32),
221
+ ),
222
+ )
223
+
224
+
225
+ class QueryReportGeneratorCC35XX(ReportGenerator):
226
+ BOOT_SECTOR_REPORT_SIZE = 1040
227
+ TBL_REPORT_SIZE = 16
228
+ VEBDOR_IMAGE_REPORT_SIZE = 16
229
+
230
+ def __init__(
231
+ self, report_file_path, programmer_artifacts_path, fib_artifacts_path, verbose
232
+ ):
233
+ super().__init__(
234
+ report_type=REPORT_TYPE.query_pg1,
235
+ report_file_path=report_file_path,
236
+ programmer_artifacts_path=programmer_artifacts_path,
237
+ fib_artifacts_path=fib_artifacts_path,
238
+ verbose=verbose,
239
+ )
240
+
241
+ self.report_struct = Struct(
242
+ "report_header_version" / Int32ul,
243
+ "report_type" / Int8ul,
244
+ "type_version" / Int8ul,
245
+ "payload_length" / Int16ul,
246
+ "query_response_content"
247
+ / ByteSwapped(
248
+ BitStruct(
249
+ "reserved" / Padding(23),
250
+ "secondary_vendor_sbl_query" / BitsInteger(1),
251
+ "secondary_vendor_image_query" / BitsInteger(1),
252
+ "secondary_ti_wsoc_query" / BitsInteger(1),
253
+ "primary_ti_wsoc_query" / BitsInteger(1),
254
+ "primary_vendor_sbl_query" / BitsInteger(1),
255
+ "primary_vendor_image_query" / BitsInteger(1),
256
+ "secondary_ti_bootloader_query" / BitsInteger(1),
257
+ "primary_ti_bootloader_query" / BitsInteger(1),
258
+ "boot_sector_query" / BitsInteger(1),
259
+ )
260
+ ),
261
+ "reserved" / Int32ul,
262
+ "payload" / GreedyBytes,
263
+ )
264
+
265
+ self.boot_sector_report_struct = Struct(
266
+ "flash_magic_and_map_content_raw"
267
+ / Struct(
268
+ # 5.2.2.1 - 4W
269
+ "ti_flash_magic"
270
+ / Struct(
271
+ "magic1" / Int32ul,
272
+ "magic2" / Int32ul,
273
+ "magic3" / Int32ul,
274
+ "magic4" / Int32ul,
275
+ ),
276
+ # 5.2.2.2 - 13W
277
+ # physical address
278
+ "flash_map"
279
+ / Struct(
280
+ "ti_bl_slot1" / Int32ul,
281
+ "ti_bl_slot2" / Int32ul,
282
+ "vendor_sbl_slot1" / Int32ul,
283
+ "vendor_sbl_slot2" / Int32ul,
284
+ "vendor_img_slot1" / Int32ul,
285
+ "vendor_img_slot2" / Int32ul,
286
+ "ti_wsoc_img_slot1" / Int32ul,
287
+ "ti_wsoc_img_slot2" / Int32ul,
288
+ "nvs_slot" / Int32ul,
289
+ "ti_img_slot" / Int32ul, # set FFFFFFFFh
290
+ "vendor_gang_slot" / Int32ul, # set FFFFFFFFh
291
+ "flash_calibration" / Int32ul, # calculated by the tool
292
+ "flash_disco_parameters_slot" / Int32ul,
293
+ ),
294
+ ),
295
+ "flash_calibration_content_raw" / Bytes(FLASH_CALIBRATION_SIZE),
296
+ "flash_discovery_configuration_content_raw"
297
+ / Bytes(FLASH_DISCOVERY_CONF_SIZE_CC35XX),
298
+ )
299
+ self.boot_sector_report_struct_size = self.boot_sector_report_struct.sizeof()
300
+
301
+ self.version_report_struct = Struct(
302
+ "iv_major" / Int8ul,
303
+ "iv_minor" / Int8ul,
304
+ "iv_revision" / Int16ul,
305
+ "iv_build_num" / Int32ul,
306
+ )
307
+ self.version_report_struct_size = self.version_report_struct.sizeof()
308
+
309
+ def _get_version(self, img_query_report):
310
+ iv_major = str(img_query_report.iv_major)
311
+ iv_minor = str(img_query_report.iv_minor)
312
+ iv_revision = str(img_query_report.iv_revision)
313
+ iv_build_num = str(img_query_report.iv_build_num)
314
+
315
+ return iv_major + "." + iv_minor + "." + iv_revision + "." + iv_build_num
316
+
317
+ def _add_row_to_table(self, raw_payload, image_name, table):
318
+ parsed_version = self.version_report_struct.parse(raw_payload)
319
+
320
+ version = self._get_version(parsed_version)
321
+
322
+ table.append([image_name, version])
323
+
324
+ raw_payload = raw_payload[self.version_report_struct_size :]
325
+
326
+ return raw_payload, table
327
+
328
+ def _get_expected_report_size(self, selected_images):
329
+ # reserved = None
330
+ # secondary_ti_wsoc_bl2_query = 0
331
+ # primary_ti_wsoc_bl2_query = 0
332
+ # secondary_vendor_sbl_query = 0
333
+ # secondary_vendor_image_query = 0
334
+ # secondary_ti_wsoc_query = 0
335
+ # primary_ti_wsoc_query = 0
336
+ # primary_vendor_sbl_query = 0
337
+ # primary_vendor_image_query = 0
338
+ # secondary_ti_bootloader_query = 0
339
+ # primary_ti_bootloader_query = 1
340
+ # boot_sector_query = 1
341
+
342
+ size = 16
343
+
344
+ for key in selected_images:
345
+ if key.endswith("_query") and selected_images[key] == 1:
346
+ if key == "boot_sector_query":
347
+ size += self.boot_sector_report_struct_size
348
+ else:
349
+ size += self.version_report_struct_size
350
+
351
+ return size
352
+
353
+ def _build_table(self, selected_images):
354
+ table = []
355
+ payload_content = self.report_container.payload
356
+ query_response_content = self.report_container.query_response_content
357
+
358
+ for key in reversed(query_response_content):
359
+ if key.endswith("_query") and query_response_content[key] == 1:
360
+ key_display_name = key.replace("_query", "").replace("_", " ").upper()
361
+
362
+ if key == "boot_sector_query":
363
+ # parse boot sector
364
+ boot_sector_query_report = self.boot_sector_report_struct.parse(
365
+ payload_content
366
+ )
367
+ boot_sector_exist = (
368
+ False
369
+ if hex(
370
+ boot_sector_query_report.flash_magic_and_map_content_raw.ti_flash_magic.magic1
371
+ )
372
+ == "0xffffffff"
373
+ else True
374
+ )
375
+ table.append([key_display_name, boot_sector_exist])
376
+
377
+ # get rest of payload
378
+ payload_content = payload_content[
379
+ self.boot_sector_report_struct_size :
380
+ ]
381
+ else:
382
+ payload_content, table = self._add_row_to_table(
383
+ payload_content, key_display_name, table
384
+ )
385
+
386
+ report_table = tabulate(
387
+ table, headers=["Image Name", "Programmed"], tablefmt="grid"
388
+ )
389
+
390
+ return report_table
391
+
392
+ def generate_report(self, report_bytes, selected_images):
393
+ try:
394
+ # parse report from device
395
+ self.report_container = self.report_struct.parse(report_bytes)
396
+
397
+ report_table = self._build_table(selected_images)
398
+ PROGRAMMER_REPORT_LOGGER.log(self.log_level, report_table)
399
+
400
+ except Exception as e:
401
+ self.error_message = f"Failed receiving report from device"
402
+ PROGRAMMER_REPORT_LOGGER.error(f"Report failed. Exception: {e}")
403
+ return False
404
+
405
+ self.report_file_path = self.prog_utility.fix_path(self.report_file_path)
406
+ with open(self.report_file_path, "w") as f:
407
+ f.write(report_table)
408
+
409
+ PROGRAMMER_REPORT_LOGGER.log(
410
+ self.log_level,
411
+ f"Saved report image bin file at {self.report_file_path}",
412
+ )
413
+
414
+ return True
415
+
416
+
417
+ class EnterRmaReportGeneratorCC35XX(ReportGenerator):
418
+
419
+ def __init__(
420
+ self, report_file_path, programmer_artifacts_path, fib_artifacts_path, verbose
421
+ ):
422
+ super().__init__(
423
+ report_type=REPORT_TYPE.enter_rma_pg1,
424
+ report_file_path=report_file_path,
425
+ programmer_artifacts_path=programmer_artifacts_path,
426
+ fib_artifacts_path=fib_artifacts_path,
427
+ verbose=verbose,
428
+ )
429
+
430
+ self.report_struct = Struct(
431
+ "report_header_version" / Int32ul,
432
+ "report_type" / Int8ul,
433
+ "type_version" / Int8ul,
434
+ "payload_length" / Int16ul,
435
+ "enter_rma_response_content"
436
+ / ByteSwapped(
437
+ BitStruct(
438
+ "reserved" / Padding(27),
439
+ "invalidate_internal_memory_done" / BitsInteger(1),
440
+ "invalidate_all_vendor_components_done" / BitsInteger(1),
441
+ "invalidate_other_vendor_fuses_done" / BitsInteger(1),
442
+ "invalidate_vendor_rot_fuses_done" / BitsInteger(1),
443
+ "rma_entry_done" / BitsInteger(1),
444
+ )
445
+ ),
446
+ )
447
+
448
+
449
+ # CC35XXE Report Generators
450
+ class ProgrammingReportGeneratorCC35XXE(ReportGenerator):
451
+
452
+ def __init__(
453
+ self, report_file_path, programmer_artifacts_path, fib_artifacts_path, verbose
454
+ ):
455
+ super().__init__(
456
+ report_type=REPORT_TYPE.programming_pg2,
457
+ report_file_path=report_file_path,
458
+ programmer_artifacts_path=programmer_artifacts_path,
459
+ fib_artifacts_path=fib_artifacts_path,
460
+ verbose=verbose,
461
+ )
462
+
463
+ self.report_struct = Struct(
464
+ "report_header_version" / Int32ul,
465
+ "report_type" / Int8ul,
466
+ "type_version" / Int8ul,
467
+ "payload_length" / Int16ul,
468
+ "request_execution_status"
469
+ / ByteSwapped(
470
+ BitStruct(
471
+ "reserved" / Padding(18),
472
+ "protected_storage" / BitsInteger(1),
473
+ "secondary_ti_wsoc_bl2_image_done" / BitsInteger(1),
474
+ "primary_ti_wsoc_bl2_image_done" / BitsInteger(1),
475
+ "secondary_vendor_sbl_done" / BitsInteger(1),
476
+ "secondary_vendor_image_done" / BitsInteger(1),
477
+ "secondary_ti_wsoc_image_done" / BitsInteger(1),
478
+ "primary_ti_wsoc_image_done" / BitsInteger(1),
479
+ "primary_vendor_sbl_done" / BitsInteger(1),
480
+ "primary_vendor_image_done" / BitsInteger(1),
481
+ "secondary_ti_bootloader_image_done" / BitsInteger(1),
482
+ "primary_ti_bootloader_image_done" / BitsInteger(1),
483
+ "boot_sector_done" / BitsInteger(1),
484
+ "flash_factory_reset" / BitsInteger(1),
485
+ "fuse_programming_instructions_update_done" / BitsInteger(1),
486
+ )
487
+ ),
488
+ "request_validation_status"
489
+ / ByteSwapped(
490
+ BitStruct(
491
+ "reserved" / Padding(16),
492
+ "protected_storage_validate_pass" / BitsInteger(1),
493
+ "secondary_ti_wsoc_bl2_image_validate_pass" / BitsInteger(1),
494
+ "primary_ti_wsoc_bl2_image_validate_pass" / BitsInteger(1),
495
+ "secondary_vendor_sbl_validate_pass" / BitsInteger(1),
496
+ "secondary_vendor_image_validate_pass" / BitsInteger(1),
497
+ "secondary_ti_wsoc_image_validate_pass" / BitsInteger(1),
498
+ "primary_ti_wsoc_image_validate_pass" / BitsInteger(1),
499
+ "primary_vendor_sbl_validate_pass" / BitsInteger(1),
500
+ "primary_vendor_image_validate_pass" / BitsInteger(1),
501
+ "secondary_ti_bootloader_image_validate_pass" / BitsInteger(1),
502
+ "primary_ti_bootloader_image_validate_pass" / BitsInteger(1),
503
+ "boot_sector_validate_pass" / BitsInteger(1),
504
+ "flash_factory_reset_validate_pass" / BitsInteger(1),
505
+ "fuse_programming_instructions_alignment_verify_pass"
506
+ / BitsInteger(1),
507
+ "recoverable_fault" / BitsInteger(1),
508
+ "non_recoverable_failure" / BitsInteger(1),
509
+ )
510
+ ),
511
+ "vendor_fuse_report"
512
+ / Struct(
513
+ "rot" / Bytes(32),
514
+ "crc_rom"
515
+ / ByteSwapped(
516
+ BitStruct(
517
+ "reserved" / Padding(23),
518
+ "security_failure_behavoral"
519
+ / BitsInteger(1), # defaulte or not config bit 8
520
+ "use_ti_root_of_trust_secondary"
521
+ / BitsInteger(
522
+ 3
523
+ ), # base on sysconfig, bit 5-7, Use the primary/secondary rot: 0 - Primary RoT (ROM) 1 to 7 - Secondary RoT (TI eFuse)
524
+ "reserved" / Padding(5),
525
+ )
526
+ ),
527
+ "crc_vendor"
528
+ / ByteSwapped(
529
+ BitStruct(
530
+ "reserved" / Padding(24),
531
+ "otfde_protection_enable"
532
+ / BitsInteger(
533
+ 1
534
+ ), # default is Bypass Authetication = 0 (Do no bypass (Perform Authetication) = 1), Based on SYSconfig SW
535
+ "action_request_authentication_enable"
536
+ / BitsInteger(
537
+ 3
538
+ ), # default is Bypass Authetication = 0 (Do no bypass (Perform Authetication) = 1-7), Based on SYSconfig SW
539
+ "vendor_sbl_container_enable"
540
+ / BitsInteger(
541
+ 1
542
+ ), # default is Bypass Authetication = 0 (Do no bypass (Perform Authetication) = 1), Based on SYSconfig SW
543
+ "vendor_container_authentication_enable"
544
+ / BitsInteger(
545
+ 3
546
+ ), # default is Bypass Authetication = 0 (Do no bypass (Perform Authetication) = 1-7), Based on SYSconfig SW
547
+ )
548
+ ),
549
+ "non_crc"
550
+ / Struct(
551
+ "general"
552
+ / ByteSwapped(
553
+ BitStruct(
554
+ "reserved" / Padding(21),
555
+ "application_otp_usage"
556
+ / BitsInteger(
557
+ 2
558
+ ), # defaulte should be 01. 00 -Vendor debug Key - Future Use (post RTM), 01- general purpose vendor configuration, 10- Module M3 Key - Future Use (post RTM), 11- Module M33 Key - Future Use (post RTM)
559
+ "crda_code_enable"
560
+ / BitsInteger(1), # enable country code check
561
+ "permanently_lock_debug_enable"
562
+ / BitsInteger(
563
+ 1
564
+ ), # (not implemented for RTM). 0 - Disable Permament Lock (Debug/JTAG can be open)
565
+ "wifi6_disable"
566
+ / BitsInteger(1), # 0 - WiFi6 not disabled by OTP fuse
567
+ "qspi_ospi_flash_type" / BitsInteger(1), # ??
568
+ "flash_exist" / BitsInteger(1), # ??
569
+ "boot_sector_programmed"
570
+ / BitsInteger(1), # 0 - Boot sector NOT programmed
571
+ "flash_reset_type" / BitsInteger(1), # ??
572
+ "otp_structure_version" / BitsInteger(2),
573
+ )
574
+ ),
575
+ "vendor_restricted_ini" / Int32ul, # Based on SYSconfig SW
576
+ "mac_address_31_0" / Int32ul, # Based on SYSconfig SW
577
+ "mac_address_47_32" / Int16ul, # Based on SYSconfig SW
578
+ "crda_country_code" / Int16ul, # Based on SYSconfig SW
579
+ "wsoc_fw_rollback_protection_1"
580
+ / Int32ul, # row 1 of up to 32 versions (1 bit per major version per row) - Based on SYSconfig SW set to 1 for all rows of respective version
581
+ "wsoc_fw_rollback_protection_2"
582
+ / Int32ul, # row 2 of up to 32 versions (1 bit per major version per row) - Based on SYSconfig SW set to 1 for all rows of respective version
583
+ "wsoc_fw_rollback_protection_3"
584
+ / Int32ul, # row 3 of up to 32 versions (1 bit per major version per row) - Based on SYSconfig SW set to 1 for all rows of respective version
585
+ "ti_bootloader_fw_rollback_protection_1"
586
+ / Int32ul, # row 1 of up to 16 versions (1 bit per major version per row) - Based on SYSconfig SW set to 1 for all rows of respective version
587
+ "ti_bootloader_fw_rollback_protection_2"
588
+ / Int32ul, # row 2 of up to 16 versions (1 bit per major version per row) - Based on SYSconfig SW set to 1 for all rows of respective version
589
+ "ti_bootloader_fw_rollback_protection_3"
590
+ / Int32ul, # row 3 of up to 16 versions (1 bit per major version per row) - Based on SYSconfig SW set to 1 for all rows of respective version
591
+ "vendor_sbl_fw_rollback_protection_1"
592
+ / Int32ul, # row 1 of up to 16 versions (1 bit per major version per row) - Based on SYSconfig SW set to 1 for all rows of respective version
593
+ "vendor_sbl_fw_rollback_protection_2"
594
+ / Int32ul, # row 2 of up to 16 versions (1 bit per major version per row) - Based on SYSconfig SW set to 1 for all rows of respective version
595
+ "vendor_sbl_fw_rollback_protection_3"
596
+ / Int32ul, # row 3 of up to 16 versions (1 bit per major version per row) - Based on SYSconfig SW set to 1 for all rows of respective version
597
+ "vendor_image_rollback_protection_1"
598
+ / Int32ul, # row 1 of up to 32 versions (1 bit per major version per row) - Based on SYSconfig SW set to 1 for all rows of respective version
599
+ "vendor_image_rollback_protection_2"
600
+ / Int32ul, # row 2 of up to 32 versions (1 bit per major version per row) - Based on SYSconfig SW set to 1 for all rows of respective version
601
+ ),
602
+ "app_otp_or_debug_rot"
603
+ / Bytes(
604
+ 32
605
+ ), # OTP for customer application or debug ROT. depened on "application_otp_usage"
606
+ ),
607
+ )
608
+
609
+
610
+ class QueryReportGeneratorCC35XXE(ReportGenerator):
611
+ BOOT_SECTOR_REPORT_SIZE = 1040
612
+ TBL_REPORT_SIZE = 16
613
+ VEBDOR_IMAGE_REPORT_SIZE = 16
614
+
615
+ def __init__(
616
+ self, report_file_path, programmer_artifacts_path, fib_artifacts_path, verbose
617
+ ):
618
+ super().__init__(
619
+ report_type=REPORT_TYPE.query_pg2,
620
+ report_file_path=report_file_path,
621
+ programmer_artifacts_path=programmer_artifacts_path,
622
+ fib_artifacts_path=fib_artifacts_path,
623
+ verbose=verbose,
624
+ )
625
+
626
+ self.report_struct = Struct(
627
+ "report_header_version" / Int32ul,
628
+ "report_type" / Int8ul,
629
+ "type_version" / Int8ul,
630
+ "payload_length" / Int16ul,
631
+ "query_response_content"
632
+ / ByteSwapped(
633
+ BitStruct(
634
+ "reserved" / Padding(20),
635
+ "protected_storage" / BitsInteger(1),
636
+ "secondary_ti_wsoc_bl2_query" / BitsInteger(1),
637
+ "primary_ti_wsoc_bl2_query" / BitsInteger(1),
638
+ "secondary_vendor_sbl_query" / BitsInteger(1),
639
+ "secondary_vendor_image_query" / BitsInteger(1),
640
+ "secondary_ti_wsoc_query" / BitsInteger(1),
641
+ "primary_ti_wsoc_query" / BitsInteger(1),
642
+ "primary_vendor_sbl_query" / BitsInteger(1),
643
+ "primary_vendor_image_query" / BitsInteger(1),
644
+ "secondary_ti_bootloader_query" / BitsInteger(1),
645
+ "primary_ti_bootloader_query" / BitsInteger(1),
646
+ "boot_sector_query" / BitsInteger(1),
647
+ )
648
+ ),
649
+ "reserved" / Int32ul,
650
+ "payload" / GreedyBytes,
651
+ )
652
+
653
+ self.boot_sector_report_struct = Struct(
654
+ "flash_magic_and_map_content_raw"
655
+ / Struct(
656
+ # 5.2.2.1 - 4W
657
+ "ti_flash_magic"
658
+ / Struct(
659
+ "magic1" / Int32ul,
660
+ "magic2" / Int32ul,
661
+ "magic3" / Int32ul,
662
+ "magic4" / Int32ul,
663
+ ),
664
+ # 5.2.2.2 - 13W
665
+ # physical address
666
+ "flash_map"
667
+ / Struct(
668
+ "ti_bl_slot1" / Int32ul,
669
+ "ti_bl_slot2" / Int32ul,
670
+ "vendor_sbl_slot1" / Int32ul,
671
+ "vendor_sbl_slot2" / Int32ul,
672
+ "vendor_img_slot1" / Int32ul,
673
+ "vendor_img_slot2" / Int32ul,
674
+ "ti_wsoc_img_slot1" / Int32ul,
675
+ "ti_wsoc_img_slot2" / Int32ul,
676
+ "ti_wsoc_bl2_img_slot1" / Int32ul,
677
+ "ti_wsoc_bl2_img_slot2" / Int32ul,
678
+ "nvs_slot" / Int32ul,
679
+ "ti_img_slot" / Int32ul, # set FFFFFFFFh
680
+ "vendor_gang_slot" / Int32ul, # set FFFFFFFFh
681
+ "flash_calibration" / Int32ul, # calculated by the tool
682
+ "flash_disco_parameters_slot" / Int32ul,
683
+ ),
684
+ ),
685
+ "flash_calibration_content_raw" / Bytes(FLASH_CALIBRATION_SIZE),
686
+ "flash_discovery_configuration_content_raw"
687
+ / Bytes(FLASH_DISCOVERY_CONF_SIZE_CC35XXE),
688
+ )
689
+ self.boot_sector_report_struct_size = self.boot_sector_report_struct.sizeof()
690
+
691
+ self.version_report_struct = Struct(
692
+ "iv_major" / Int8ul,
693
+ "iv_minor" / Int8ul,
694
+ "iv_revision" / Int16ul,
695
+ "iv_build_num" / Int32ul,
696
+ )
697
+ self.version_report_struct_size = self.version_report_struct.sizeof()
698
+
699
+ def _get_version(self, img_query_report):
700
+ iv_major = str(img_query_report.iv_major)
701
+ iv_minor = str(img_query_report.iv_minor)
702
+ iv_revision = str(img_query_report.iv_revision)
703
+ iv_build_num = str(img_query_report.iv_build_num)
704
+
705
+ return iv_major + "." + iv_minor + "." + iv_revision + "." + iv_build_num
706
+
707
+ def _add_row_to_table(self, raw_payload, image_name, table):
708
+ parsed_version = self.version_report_struct.parse(raw_payload)
709
+
710
+ version = self._get_version(parsed_version)
711
+
712
+ table.append([image_name, version])
713
+
714
+ raw_payload = raw_payload[self.version_report_struct_size :]
715
+
716
+ return raw_payload, table
717
+
718
+ def _get_expected_report_size(self, selected_images):
719
+ # reserved = None
720
+ # secondary_ti_wsoc_bl2_query = 0
721
+ # primary_ti_wsoc_bl2_query = 0
722
+ # secondary_vendor_sbl_query = 0
723
+ # secondary_vendor_image_query = 0
724
+ # secondary_ti_wsoc_query = 0
725
+ # primary_ti_wsoc_query = 0
726
+ # primary_vendor_sbl_query = 0
727
+ # primary_vendor_image_query = 0
728
+ # secondary_ti_bootloader_query = 0
729
+ # primary_ti_bootloader_query = 1
730
+ # boot_sector_query = 1
731
+
732
+ size = 16
733
+
734
+ for key in selected_images:
735
+ if key.endswith("_query") and selected_images[key] == 1:
736
+ if key == "boot_sector_query":
737
+ size += self.boot_sector_report_struct_size
738
+ else:
739
+ size += self.version_report_struct_size
740
+
741
+ return size
742
+
743
+ def _build_table(self, selected_images):
744
+ table = []
745
+ payload_content = self.report_container.payload
746
+ query_response_content = self.report_container.query_response_content
747
+
748
+ for key in reversed(query_response_content):
749
+ if key.endswith("_query") and query_response_content[key] == 1:
750
+ key_display_name = (
751
+ key.lower()
752
+ .replace("_query", "")
753
+ .replace("_", " ")
754
+ .replace("sbl", "bl3")
755
+ .upper()
756
+ )
757
+
758
+ if key == "boot_sector_query":
759
+ # parse boot sector
760
+ boot_sector_query_report = self.boot_sector_report_struct.parse(
761
+ payload_content
762
+ )
763
+ boot_sector_exist = (
764
+ False
765
+ if hex(
766
+ boot_sector_query_report.flash_magic_and_map_content_raw.ti_flash_magic.magic1
767
+ )
768
+ == "0xffffffff"
769
+ else True
770
+ )
771
+ table.append([key_display_name, boot_sector_exist])
772
+
773
+ # get rest of payload
774
+ payload_content = payload_content[
775
+ self.boot_sector_report_struct_size :
776
+ ]
777
+ else:
778
+ payload_content, table = self._add_row_to_table(
779
+ payload_content, key_display_name, table
780
+ )
781
+
782
+ report_table = tabulate(
783
+ table, headers=["Image Name", "Programmed"], tablefmt="grid"
784
+ )
785
+
786
+ return report_table
787
+
788
+ def generate_report(self, report_bytes, selected_images):
789
+ try:
790
+ # parse report from device
791
+ self.report_container = self.report_struct.parse(report_bytes)
792
+
793
+ report_table = self._build_table(selected_images)
794
+ # PROGRAMMER_REPORT_LOGGER.log(self.log_level, report_table)
795
+ PROGRAMMER_REPORT_LOGGER.info("\n" + report_table)
796
+
797
+ except Exception as e:
798
+ self.error_message = "Failed receiving report from device"
799
+ PROGRAMMER_REPORT_LOGGER.error(f"Report failed. Exception: {e}")
800
+ return False
801
+
802
+ self.report_file_path = self.prog_utility.fix_path(self.report_file_path)
803
+ with open(self.report_file_path, "w") as f:
804
+ f.write(report_table)
805
+
806
+ PROGRAMMER_REPORT_LOGGER.log(
807
+ self.log_level,
808
+ f"Saved report image bin file at {self.report_file_path}",
809
+ )
810
+
811
+ return True
812
+
813
+
814
+ class EnterRmaReportGeneratorCC35XXE(ReportGenerator):
815
+
816
+ def __init__(
817
+ self, report_file_path, programmer_artifacts_path, fib_artifacts_path, verbose
818
+ ):
819
+ super().__init__(
820
+ report_type=REPORT_TYPE.enter_rma_pg2,
821
+ report_file_path=report_file_path,
822
+ programmer_artifacts_path=programmer_artifacts_path,
823
+ fib_artifacts_path=fib_artifacts_path,
824
+ verbose=verbose,
825
+ )
826
+
827
+ self.report_struct = Struct(
828
+ "report_header_version" / Int32ul,
829
+ "report_type" / Int8ul,
830
+ "type_version" / Int8ul,
831
+ "payload_length" / Int16ul,
832
+ "enter_rma_response_content"
833
+ / ByteSwapped(
834
+ BitStruct(
835
+ "reserved" / Padding(27),
836
+ "invalidate_internal_memory_done" / BitsInteger(1),
837
+ "invalidate_all_vendor_components_done" / BitsInteger(1),
838
+ "invalidate_other_vendor_fuses_done" / BitsInteger(1),
839
+ "invalidate_vendor_rot_fuses_done" / BitsInteger(1),
840
+ "rma_entry_done" / BitsInteger(1),
841
+ )
842
+ ),
843
+ )
844
+
845
+
846
+ class MemoryValidationReportGeneratorCC35XXE(ReportGenerator):
847
+ def __init__(
848
+ self, report_file_path, programmer_artifacts_path, fib_artifacts_path, verbose
849
+ ):
850
+ super().__init__(
851
+ report_type=REPORT_TYPE.memory_validation_pg2,
852
+ report_file_path=report_file_path,
853
+ programmer_artifacts_path=programmer_artifacts_path,
854
+ fib_artifacts_path=fib_artifacts_path,
855
+ verbose=verbose,
856
+ )
857
+
858
+ self.report_struct = Struct(
859
+ "flash_type" / Int16ul,
860
+ "flash_memory_validation_result"
861
+ / ByteSwapped(
862
+ BitStruct(
863
+ "reserved" / Padding(7),
864
+ "valid" / BitsInteger(1),
865
+ "Radius" / BitsInteger(8),
866
+ "RxDelayLine" / BitsInteger(8),
867
+ "TxDelayLine" / BitsInteger(8),
868
+ )
869
+ ),
870
+ "psram_type" / Int16ul,
871
+ "psarm_memory_validation_result"
872
+ / ByteSwapped(
873
+ BitStruct(
874
+ "reserved" / Padding(7),
875
+ "valid" / BitsInteger(1),
876
+ "Radius" / BitsInteger(8),
877
+ "RxDelayLine" / BitsInteger(8),
878
+ "TxDelayLine" / BitsInteger(8),
879
+ )
880
+ ),
881
+ )
882
+
883
+
884
+ if __name__ == "__main__":
885
+
886
+ def test_report_generator(class_instance):
887
+
888
+ report = class_instance(
889
+ report_file_path=f"report_{class_instance.__name__}.txt",
890
+ verbose=True,
891
+ )
892
+
893
+ # generate random bytes
894
+ report_bytes = bytearray(2000)
895
+
896
+ if (
897
+ class_instance == QueryReportGeneratorCC35XXE
898
+ or class_instance == QueryReportGeneratorCC35XX
899
+ ):
900
+ selected_images = Container(
901
+ boot_sector_query=1,
902
+ primary_ti_bootloader_query=0,
903
+ primary_vendor_image_query=1,
904
+ )
905
+
906
+ report.generate_report(
907
+ report_bytes=report_bytes, selected_images=selected_images
908
+ )
909
+ else:
910
+ report.generate_report(report_bytes=report_bytes)
911
+
912
+ # for each class run test
913
+ for class_instance in [
914
+ EnterRmaReportGeneratorCC35XX,
915
+ EnterRmaReportGeneratorCC35XXE,
916
+ ProgrammingReportGeneratorCC35XX,
917
+ ProgrammingReportGeneratorCC35XXE,
918
+ QueryReportGeneratorCC35XXE,
919
+ QueryReportGeneratorCC35XX,
920
+ ]:
921
+ test_report_generator(class_instance)