Skip to content

Commit 2a1bdb7

Browse files
committed
Add commands to flash PD controllers
Implements flashing of the CCGX PD controllers over the EC I2C passthrough using the HPI protocol. The controller holds two firmware images and can only write the one that is not running. `--flash-pd01`/`--flash-pd23` write the inactive image, jump to it, write the other one and reset. `--pd-image main|backup` restricts it to a single image. Before flashing, the row size and silicon ID of the binary are checked against the controller. The silicon ID is masked because the chip reports a revision that differs from the one in the firmware. During flashing the EC is notified with EC_CMD_FLASH_NOTIFIED so that it stops talking to the controller. The lock is released again on every exit path, including errors. Also adds debugging commands: `--validate-pd01/23` to compare the flash contents against a file, `--pd-validate` to check the images via HPI, `--pd-dump-fw` to dump the flash, and `--pd-jump-boot/backup/main`. `--pd-info` shows more details and skips absent controllers. Tested on Framework Laptop 13 (sakura and marigold). Signed-off-by: Daniel Schaefer <dhs@frame.work>
1 parent ecebf5f commit 2a1bdb7

14 files changed

Lines changed: 1883 additions & 240 deletions

File tree

‎EXAMPLES_ADVANCED.md‎

Lines changed: 173 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -76,28 +76,45 @@ Summary:
7676

7777
### Check PD state
7878

79-
Example on Framework Laptop 13 AMD Ryzen AI 300
79+
Example on Framework Laptop 13 (CCG8 CFP). The right controller is currently
80+
running the backup firmware, which supports fewer HPI features than the main
81+
firmware.
8082

8183
```
82-
> sudo framework_tool.exe --pd-info
84+
> sudo framework_tool --pd-info
8385
Right / Ports 01
84-
Silicon ID: 0x3580
85-
Mode: MainFw
86+
Silicon ID: 0x3E81
87+
Mode: BackupFw
8688
Flash Row Size: 256 B
8789
Ports Enabled: 0, 1
88-
Bootloader Version: Base: 3.6.0.009, App: 0.0.01
89-
FW1 (Backup) Version: Base: 3.7.0.197, App: 0.0.0B
90-
FW2 (Main) Version: Base: 3.7.0.197, App: 0.0.0B
90+
HPI Version: 2.4 (0x04006124) cyacd2
91+
Boot Reason: 0x00 (Both firmwares valid)
92+
WDT Resets: 0
93+
Config Table: v2.0
94+
Flash Layout: Bootloader rows 0-1, FW1 from row 2, FW2 from row 103
95+
Bootloader Version: Base: 3.6.0.044, App: 0.0.01
96+
FW1 (Backup) Version: Base: 3.8.50.00A, App: 1.0.09
97+
FW2 (Main) Version: Base: 3.8.50.00A, App: 1.0.0A
9198
Left / Ports 23
92-
Silicon ID: 0x3580
99+
Silicon ID: 0x3E81
93100
Mode: MainFw
94101
Flash Row Size: 256 B
95102
Ports Enabled: 0, 1
96-
Bootloader Version: Base: 3.6.0.009, App: 0.0.01
97-
FW1 (Backup) Version: Base: 3.7.0.197, App: 0.0.0B
98-
FW2 (Main) Version: Base: 3.7.0.197, App: 0.0.0B
103+
HPI Version: 2.4 (0x04237724) PD Commands, UCSI, EPR, cyacd2
104+
Boot Reason: 0x00 (Both firmwares valid)
105+
WDT Resets: 0
106+
Config Table: v2.0
107+
Flash Layout: Bootloader rows 0-1, FW1 from row 2, FW2 from row 103
108+
Bootloader Version: Base: 3.6.0.044, App: 0.0.01
109+
FW1 (Backup) Version: Base: 3.8.50.00A, App: 1.0.0A
110+
FW2 (Main) Version: Base: 3.8.50.00A, App: 1.0.0A
99111
```
100112

113+
The HPI Version, Boot Reason, WDT Resets, Config Table and Flash Layout lines
114+
are only shown if the PD firmware implements those registers. Boot Reason is
115+
only updated when the controller boots, it does not reflect firmware updates
116+
done since.
117+
101118
### Disable/enable/reset PD
102119

103120
```
@@ -281,6 +298,151 @@ This command has not been thoroughly tested on all Framework Computer systems
281298
> framework_tool --reboot-ec jump-rw
282299
```
283300

301+
## Flashing PD firmware
302+
303+
**IMPORTANT** Flashing PD firmware yourself is not recommended. Please update
304+
your firmware using the official BIOS update methods (Windows .exe,
305+
LVFS/FWUPD, EFI updater)!
306+
307+
The PD controllers hold two copies of the firmware, FW1 (backup) and FW2
308+
(main). Each firmware can only update the other one, so to update both the
309+
tool writes the inactive image, switches the controller to it, writes the other
310+
image and finally resets the controller. Normally the main firmware is running
311+
and gets booted after the reset.
312+
313+
While the PD controller is being updated, the EC does not talk to it and the
314+
ports get disabled. Make sure the battery is present and charged.
315+
316+
Tested on Framework Laptop 13 (CCG8 CFP).
317+
318+
### Check the firmware on the controller against a file
319+
320+
Runs the same checks as flashing without writing anything, asks the controller
321+
to validate both images and compares the inactive image with the file.
322+
323+
```
324+
> sudo framework_tool --validate-pd01 framework_lib/test_bins/sakura-pd-1.0.0A.bin
325+
Device
326+
Silicon ID: 0x3E81
327+
Mode: MainFw
328+
Flash Row Size: 256 B
329+
Backup FW: 1.0.0A
330+
Main FW: 1.0.0A
331+
File
332+
Silicon ID: 0x3E81 (Ccg8Cfp)
333+
Backup FW: 1.0.0A (rows 2-101)
334+
Main FW: 1.0.0A (rows 103-416)
335+
Validating firmware on the controller
336+
Firmware file layout matches the controller
337+
Main FW (FW2) Valid: true
338+
Backup FW (FW1) Valid: true
339+
Comparing Backup FW (FW1) on the controller with the file
340+
Row 1/100
341+
Row 33/100
342+
Row 65/100
343+
Row 97/100
344+
Row 100/100
345+
Backup FW (FW1) on the controller is identical to the file
346+
```
347+
348+
If the file is not what is on the controller, the command fails:
349+
350+
```
351+
> sudo framework_tool --validate-pd01 Compal_Sakura_8229_PD1_0x5253_v0.0.02.bin
352+
[...]
353+
Backup FW (FW1) on the controller differs from the file in 84 of 99 rows
354+
Failed to validate PD 01: DeviceError("Firmware on the controller does not match the file")
355+
Error: "Fail"
356+
```
357+
358+
### Flash
359+
360+
Flash only the backup image and jump to it to test the new firmware. The main
361+
image stays untouched, so a reset of the PD controller boots the known-good
362+
firmware again. With `--pd-image main` the main image is written instead.
363+
If the selected image is the one currently running, the controller is switched
364+
to the other one first.
365+
366+
```
367+
# Update the backup firmware on PD 0 (right side)
368+
> sudo framework_tool --flash-pd01 pd-1.0.09.bin --pd-image backup
369+
Device
370+
Silicon ID: 0x3E81
371+
Mode: MainFw
372+
Flash Row Size: 256 B
373+
Backup FW: 1.0.0A
374+
Main FW: 1.0.0A
375+
File
376+
Silicon ID: 0x3E81 (Ccg8Cfp)
377+
Backup FW: 1.0.09 (rows 2-101)
378+
Main FW: 1.0.09 (rows 103-416)
379+
380+
Flashing BackupFw (1.0.09) from MainFw
381+
Writing rows 2 to 101 (100 rows)
382+
Row 1/100
383+
Row 33/100
384+
Row 65/100
385+
Row 97/100
386+
Row 100/100
387+
Controller validated BackupFw: true
388+
389+
Restarting controller
390+
Resetting PD controller Right01
391+
Controller is running MainFw
392+
Bootloader Version: Base: 3.6.0.044, App: 0.0.01
393+
FW1 (Backup) Version: Base: 3.8.50.00A, App: 1.0.09
394+
FW2 (Main) Version: Base: 3.8.50.00A, App: 1.0.0A
395+
396+
# Boot the new backup firmware on PD 0 to test it
397+
> sudo framework_tool --pd-jump-backup 0
398+
Jumping PD 0 to backup firmware...
399+
Current mode: MainFw, jumping to BackupFw
400+
Disabling PD ports
401+
Jumping from MainFw to BackupFw
402+
Now running BackupFw
403+
404+
# Once it works, update the main image too
405+
> sudo framework_tool --flash-pd01 pd-1.0.09.bin --pd-image main
406+
```
407+
408+
### Switch between the firmwares
409+
410+
For debugging it is possible to boot the other firmware copy. The switch lasts
411+
until the next reset of the PD controller, then the main firmware is booted
412+
again (if it is valid).
413+
414+
```
415+
> sudo framework_tool --pd-jump-backup 0
416+
Jumping PD 0 to backup firmware...
417+
Current mode: MainFw, jumping to BackupFw
418+
Disabling PD ports
419+
Jumping from MainFw to BackupFw
420+
Now running BackupFw
421+
422+
> sudo framework_tool --pd-jump-main 0
423+
Jumping PD 0 to main firmware...
424+
Current mode: BackupFw, jumping to MainFw
425+
Disabling PD ports
426+
Jumping from BackupFw to MainFw
427+
Now running MainFw
428+
429+
# A reset also boots the main firmware again
430+
> sudo framework_tool --pd-reset 0
431+
Resetting PD 0...
432+
Disabling PD ports
433+
Resetting PD controller Right01
434+
Controller is running MainFw
435+
```
436+
437+
### Dump the flash
438+
439+
The controller only allows reading the inactive firmware image. The rows of
440+
the bootloader and the running firmware are filled with zeros.
441+
442+
```
443+
> sudo framework_tool --pd-dump-fw 0:pd0-dump.bin
444+
```
445+
284446
## Flashing Expansion Bay EEPROM (Framework Laptop 16)
285447

286448
This will render your dGPU unsuable if you flash the wrong file!

0 commit comments

Comments
 (0)