Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Limited APU support (summary is partially broken + cannot replace module) #59

Open
belotv opened this issue Jun 8, 2024 · 1 comment

Comments

@belotv
Copy link

belotv commented Jun 8, 2024

I am attempting to replace modules in an APU BIOS and facing some issues:

  • Some warnings about sha256 that cannot be verified
  • a lot of "veri-failed" and "sha256_inconsistent", whereas the BIOS is the vendor one, so we can expect the checksums to be ok
  • replacing SMU Part 1 fails with Python error (trying to replace SMU Part 2 seems to work) - note: I am updating with a larger SMU file, extracted with -ukc parameters from another BIOS)

I guess most of the work was done on normal CPU and not APU so maybe there is some subtle differences, I am attaching 3 BIOS files (all Zen3 Renoir 5825U) for reference (outputs provided are for the file CWWK_CW56-58-0.22).

5825U Renoir APU BIOS.zip

Basic output:

Warning: Could not verify sha256 checksum for HeaderEntry(type=0x45, address=0x185400, size=0x1b70, len(references)=1)
Warning: Could not verify sha256 checksum for HeaderEntry(type=0x45, address=0x546000, size=0x1b70, len(references)=1)
Warning: Could not verify sha256 checksum for HeaderEntry(type=0x24, address=0x2af000, size=0x2eb0, len(references)=1)
Warning: Could not verify sha256 checksum for HeaderEntry(type=0x45, address=0x2b1f00, size=0x1b70, len(references)=1)
Warning: Could not verify sha256 checksum for HeaderEntry(type=0x24, address=0x6a0000, size=0x2eb0, len(references)=1)
Warning: Could not verify sha256 checksum for HeaderEntry(type=0x45, address=0x766800, size=0x1b70, len(references)=1)
Warning: Couldn't parse plain entry: 0x62
Warning: Entry of Directory(address=0x215000, type=BIOS, magic=b'$BHD', count=10) at 0xd02000 cannot be parsed
Warning: Couldn't parse plain entry: 0x62
Warning: Entry of Directory(address=0x5f8000, type=secondary, magic=b'$BL2', count=14) at 0xd02000 cannot be parsed
Warning: Couldn't parse entry at: 0x21000. Type: 0x6d. Size 0x40000
Warning: Couldn't parse entry at: 0x61000. Type: 0x6d. Size 0x10000
Warning: Couldn't parse plain entry: 0x62
Warning: Entry of Directory(address=0x3b0000, type=BIOS, magic=b'$BHD', count=10) at 0xd02000 cannot be parsed
Warning: Couldn't parse plain entry: 0x62
Warning: Entry of Directory(address=0x813000, type=secondary, magic=b'$BL2', count=15) at 0xd02000 cannot be parsed
Warning: Couldn't parse entry at: 0x21000. Type: 0x6d. Size 0x40000
Warning: Couldn't parse entry at: 0x61000. Type: 0x6d. Size 0x10000
Warning: Empty FET entry at ROM address 0x0
Warning: Empty FET entry at ROM address 0x5500
+-----+------+-----------+---------+---------------+
| ROM | Addr |    Size   |   FET   |     AGESA     |
+-----+------+-----------+---------+---------------+
|  0  | 0x0  | 0x1000000 | 0x20000 | AGESA_UNKNOWN |
+-----+------+-----------+---------+---------------+
+--+-----------+---------+------+------------+-------+---------------------+
|  | Directory |   Addr  | Type | Generation | Magic | Secondary Directory |
+--+-----------+---------+------+------------+-------+---------------------+
|  |     0     | 0xd2000 | PSP  |   Zen 3    |  $PSP |       0x408000      |
+--+-----------+---------+------+------------+-------+---------------------+
+--+---+-------+----------+---------+---------------------------------+----------+-----------+------------------------------------------+
|  |   | Entry |  Address |    Size |                            Type | Magic/ID |   Version |                                     Info |
+--+---+-------+----------+---------+---------------------------------+----------+-----------+------------------------------------------+
|  |   |     0 |  0xd2400 |   0x440 |              AMD_PUBLIC_KEY~0x0 |     6C9E |         1 |                            AMD_CODE_SIGN |
|  |   |     1 | 0x408400 | 0x10880 |          PSP_FW_BOOT_LOADER~0x1 |     $PS1 | 0.11.2.7B |                verified(6C9E), sha256_ok |
|  |   |     2 |  0xd2900 |  0xe5c0 | PSP_FW_RECOVERY_BOOT_LOADER~0x3 |     $PS1 | 0.11.2.7B |                verified(6C9E), sha256_ok |
|  |   |     3 |  0xe0f00 | 0x21100 |              SMU_OFFCHIP_FW~0x8 |     $PS1 | 0.40.3F.0 | compressed, veri-failed(96A0), sha256_ok |
|  |   |     4 |      0x1 |     0x0 |          SOFT_FUSE_CHAIN_01~0xb |          |           |                                          |
|  |   |     5 | 0x102000 | 0x11a40 |          SMU_OFF_CHIP_FW_2~0x12 |     $PS1 | 0.40.3F.0 | compressed, veri-failed(96A0), sha256_ok |
|  |   |     6 | 0x113b00 |    0x10 |               WRAPPED_IKEK~0x21 |          |           |                                          |
|  |   |     7 | 0x114000 |  0x1000 |               TOKEN_UNLOCK~0x22 |          |           |                                          |
|  |   |     8 | 0x115000 |  0x2e80 |                 SEC_GASKET~0x24 |     $PS1 | B.10.0.20 |                verified(3005), sha256_ok |
|  |   |     9 | 0x117f00 |   0x290 |                       ABL0~0x30 |          |   0.0.0.0 |                verified(259C), sha256_ok |
|  |   |    10 | 0x17e100 |  0x1900 |               KEY_DATABASE~0x50 |     $PS1 |         1 |                verified(6C9E), sha256_ok |
|  |   |    11 | 0x17fa00 |  0x5940 |              VBIOS_PRELOAD~0x3c |     $PS1 | 11.A.0.1D |                           verified(DE39) |
|  |   |    12 | 0x185400 |  0x1b70 |        TOS_SECURITY_POLICY~0x45 |     $PS1 | B.10.1.20 |      verified(3005), sha256_inconsistent |
|  |   |    13 | 0x408000 |   0x400 |   !PL2_SECONDARY_DIRECTORY~0x40 |          |           |                                          |
+--+---+-------+----------+---------+---------------------------------+----------+-----------+------------------------------------------+


+--+-----------+----------+-----------+------------+-------+---------------------+
|  | Directory |   Addr   |    Type   | Generation | Magic | Secondary Directory |
+--+-----------+----------+-----------+------------+-------+---------------------+
|  |     1     | 0x408000 | secondary |   Zen 3    |  $PL2 |                     |
+--+-----------+----------+-----------+------------+-------+---------------------+
+--+---+-------+----------+---------+-----------------------------+----------+------------+------------------------------------------+
|  |   | Entry |  Address |    Size |                        Type | Magic/ID |    Version |                                     Info |
+--+---+-------+----------+---------+-----------------------------+----------+------------+------------------------------------------+
|  |   |     0 | 0x408400 | 0x10880 |      PSP_FW_BOOT_LOADER~0x1 |     $PS1 |  0.11.2.7B |                verified(6C9E), sha256_ok |
|  |   |     1 | 0x418d00 |   0x440 |          AMD_PUBLIC_KEY~0x0 |     6C9E |          1 |                            AMD_CODE_SIGN |
|  |   |     2 | 0x419200 | 0x16370 |       PSP_FW_TRUSTED_OS~0x2 |     $PS1 |  0.11.2.7B |                verified(24C6), sha256_ok |
|  |   |     3 |  0x71000 | 0x20000 |             PSP_NV_DATA~0x4 |          |            |                                          |
|  |   |     4 | 0x42f600 | 0x21100 |          SMU_OFFCHIP_FW~0x8 |     $PS1 |  0.40.3F.0 | compressed, veri-failed(96A0), sha256_ok |
|  |   |     5 | 0x450700 |   0x440 |      SEC_DBG_PUBLIC_KEY~0x9 |     10AC |          1 |     verified(6C9E), unknown_key_usage(3) |
|  |   |     6 |      0x1 |     0x0 |      SOFT_FUSE_CHAIN_01~0xb |          |            |                                          |
|  |   |     7 | 0x450c00 | 0x20100 | PSP_BOOT_TIME_TRUSTLETS~0xc |     $PS1 |   3.54.0.5 |                           verified(CC7D) |
|  |   |     8 | 0x470d00 | 0x11a40 |      SMU_OFF_CHIP_FW_2~0x12 |     $PS1 |  0.40.3F.0 | compressed, veri-failed(96A0), sha256_ok |
|  |   |     9 | 0x482800 |  0x2100 |           DEBUG_UNLOCK~0x13 |     $PS1 |  0.11.2.7B |                verified(B034), sha256_ok |
|  |   |    10 | 0x484900 |   0x670 |     HARDWARE_IP_CONFIG~0x20 |     $PS1 |    0.0.0.1 |                verified(118D), sha256_ok |
|  |   |    11 | 0x485000 |    0x10 |           WRAPPED_IKEK~0x21 |          |            |                                          |
|  |   |    12 | 0x486000 |  0x1000 |           TOKEN_UNLOCK~0x22 |          |            |                                          |
|  |   |    13 | 0x487000 |  0x2e80 |             SEC_GASKET~0x24 |     $PS1 |  B.10.0.20 |                verified(3005), sha256_ok |
|  |   |    14 | 0x489f00 | 0x2fb36 |                 MP2_FW~0x25 |          |   7.0.8.13 |                verified(C04C), sha256_ok |
|  |   |    15 | 0x4b9b00 | 0x1d770 |         DRIVER_ENTRIES~0x28 |     $PS1 |  0.11.2.7B |                verified(24C6), sha256_ok |
|  |   |    16 | 0x4d7300 |  0x3100 |              KVM_IMAGE~0x29 |     $PS1 | 1C.8.60.70 |                verified(CC7D), sha256_ok |
|  |   |    17 | 0x4d7300 |  0x3100 |            S0I3_DRIVER~0x2d |     $PS1 | 1C.8.60.70 |                verified(CC7D), sha256_ok |
|  |   |    18 | 0x4da400 |   0x290 |                   ABL0~0x30 |          |    0.0.0.0 |                verified(259C), sha256_ok |
|  |   |    19 | 0x540600 |  0x5940 |          VBIOS_PRELOAD~0x3c |     $PS1 |  11.A.0.1D |                           verified(DE39) |
|  |   |    20 | 0x546000 |  0x1b70 |    TOS_SECURITY_POLICY~0x45 |     $PS1 |  B.10.1.20 |      verified(3005), sha256_inconsistent |
|  |   |    21 | 0x547c00 |   0x210 |             FW_INVALID~0x44 |     $PS1 |    0.0.0.1 |                verified(ADC2), sha256_ok |
|  |   |    22 | 0x54e300 |  0x4100 |                DRTM_TA~0x47 |     $PS1 |  4.11.0.2F |                           verified(61CE) |
|  |   |    23 | 0x552400 |  0x1900 |           KEY_DATABASE~0x50 |     $PS1 |          1 |                verified(6C9E), sha256_ok |
|  |   |    24 | 0x553d00 |  0x12c0 |         TOS_PUBLIC_KEY~0x51 |     $PS1 |          1 |                verified(6C9E), sha256_ok |
|  |   |    25 | 0x555000 |  0x5b70 |                        0x58 |     $PS1 |    0.0.0.0 |                           verified(EBDF) |
|  |   |    26 | 0x55ac00 |   0xb20 |                   WMOS~0x5c |     $PS1 |  0.19.50.1 |                verified(8A19), sha256_ok |
|  |   |    27 | 0x55b800 |   0x220 |                        0x59 |     $PS1 |    0.0.0.0 |                           verified(EBDF) |
|  |   |    28 |  0x91000 | 0x40000 |              PSP_NVRAM~0x54 |          |            |                                          |
+--+---+-------+----------+---------+-----------------------------+----------+------------+------------------------------------------+


+--+-----------+----------+------+------------+-------+---------------------+
|  | Directory |   Addr   | Type | Generation | Magic | Secondary Directory |
+--+-----------+----------+------+------------+-------+---------------------+
|  |     2     | 0x26d000 | PSP  |   Zen 3    |  $PSP |       0x623000      |
+--+-----------+----------+------+------------+-------+---------------------+
+--+---+-------+----------+---------+---------------------------------+----------+-----------+------------------------------------------+
|  |   | Entry |  Address |    Size |                            Type | Magic/ID |   Version |                                     Info |
+--+---+-------+----------+---------+---------------------------------+----------+-----------+------------------------------------------+
|  |   |     0 | 0x26d400 |   0x440 |              AMD_PUBLIC_KEY~0x0 |     144E |         1 |                            AMD_CODE_SIGN |
|  |   |     1 | 0x623400 | 0x10880 |          PSP_FW_BOOT_LOADER~0x1 |     $PS1 | 0.11.2.7B |                verified(144E), sha256_ok |
|  |   |     2 | 0x26d900 |  0xe5c0 | PSP_FW_RECOVERY_BOOT_LOADER~0x3 |     $PS1 | 0.11.2.7B |                verified(144E), sha256_ok |
|  |   |     3 | 0x27bf00 | 0x20fb0 |              SMU_OFFCHIP_FW~0x8 |     $PS1 | 0.37.5B.0 | compressed, veri-failed(2C92), sha256_ok |
|  |   |     4 |      0x1 |     0x0 |          SOFT_FUSE_CHAIN_01~0xb |          |           |                                          |
|  |   |     5 | 0x29cf00 | 0x10070 |          SMU_OFF_CHIP_FW_2~0x12 |     $PS1 | 0.37.5B.0 | compressed, veri-failed(2C92), sha256_ok |
|  |   |     6 | 0x2ad000 |    0x10 |               WRAPPED_IKEK~0x21 |          |           |                                          |
|  |   |     7 | 0x2ae000 |  0x1000 |               TOKEN_UNLOCK~0x22 |          |           |                                          |
|  |   |     8 | 0x2af000 |  0x2eb0 |                 SEC_GASKET~0x24 |     $PS1 |  B.9.0.85 |      verified(BCC5), sha256_inconsistent |
|  |   |     9 | 0x2b1f00 |  0x1b70 |        TOS_SECURITY_POLICY~0x45 |     $PS1 |  B.9.1.85 |      verified(BCC5), sha256_inconsistent |
|  |   |    10 | 0x2b3b00 |   0x290 |                       ABL0~0x30 |          |   0.0.0.0 |                verified(CF65), sha256_ok |
|  |   |    11 | 0x323800 |  0x5940 |              VBIOS_PRELOAD~0x3c |     $PS1 | 11.A.0.1D |                           verified(2FCA) |
|  |   |    12 | 0x329200 |  0x1900 |               KEY_DATABASE~0x50 |     $PS1 |         1 |                verified(144E), sha256_ok |
|  |   |    13 | 0x623000 |   0x400 |   !PL2_SECONDARY_DIRECTORY~0x40 |          |           |                                          |
+--+---+-------+----------+---------+---------------------------------+----------+-----------+------------------------------------------+


+--+-----------+----------+-----------+------------+-------+---------------------+
|  | Directory |   Addr   |    Type   | Generation | Magic | Secondary Directory |
+--+-----------+----------+-----------+------------+-------+---------------------+
|  |     3     | 0x623000 | secondary |   Zen 3    |  $PL2 |                     |
+--+-----------+----------+-----------+------------+-------+---------------------+
+--+---+-------+----------+---------+-----------------------------+----------+------------+------------------------------------------+
|  |   | Entry |  Address |    Size |                        Type | Magic/ID |    Version |                                     Info |
+--+---+-------+----------+---------+-----------------------------+----------+------------+------------------------------------------+
|  |   |     0 | 0x623400 | 0x10880 |      PSP_FW_BOOT_LOADER~0x1 |     $PS1 |  0.11.2.7B |                verified(144E), sha256_ok |
|  |   |     1 | 0x633d00 |   0x440 |          AMD_PUBLIC_KEY~0x0 |     144E |          1 |                            AMD_CODE_SIGN |
|  |   |     2 | 0x634200 | 0x16370 |       PSP_FW_TRUSTED_OS~0x2 |     $PS1 |  0.11.2.7B |                verified(D945), sha256_ok |
|  |   |     3 |  0x71000 | 0x20000 |             PSP_NV_DATA~0x4 |          |            |                                          |
|  |   |     4 | 0x64a600 | 0x20fb0 |          SMU_OFFCHIP_FW~0x8 |     $PS1 |  0.37.5B.0 | compressed, veri-failed(2C92), sha256_ok |
|  |   |     5 | 0x66b600 |   0x440 |      SEC_DBG_PUBLIC_KEY~0x9 |     0475 |          1 |     verified(144E), unknown_key_usage(3) |
|  |   |     6 |      0x1 |     0x0 |      SOFT_FUSE_CHAIN_01~0xb |          |            |                                          |
|  |   |     7 | 0x66bb00 | 0x20100 | PSP_BOOT_TIME_TRUSTLETS~0xc |     $PS1 |   3.54.0.5 |                           verified(CC7D) |
|  |   |     8 | 0x68bc00 | 0x10070 |      SMU_OFF_CHIP_FW_2~0x12 |     $PS1 |  0.37.5B.0 | compressed, veri-failed(2C92), sha256_ok |
|  |   |     9 | 0x69bd00 |  0x2100 |           DEBUG_UNLOCK~0x13 |     $PS1 |  0.11.2.7B |                verified(11F8), sha256_ok |
|  |   |    10 | 0x69de00 |   0x664 |     HARDWARE_IP_CONFIG~0x20 |          |    0.0.0.0 |                           verified(76AC) |
|  |   |    11 | 0x69e500 |    0x10 |           WRAPPED_IKEK~0x21 |          |            |                                          |
|  |   |    12 | 0x69f000 |  0x1000 |           TOKEN_UNLOCK~0x22 |          |            |                                          |
|  |   |    13 | 0x6a0000 |  0x2eb0 |             SEC_GASKET~0x24 |     $PS1 |   B.9.0.85 |      verified(BCC5), sha256_inconsistent |
|  |   |    14 | 0x6a2f00 | 0x2d815 |                 MP2_FW~0x25 |          |    7.0.7.4 |                verified(7C83), sha256_ok |
|  |   |    15 | 0x6d0800 | 0x1d770 |         DRIVER_ENTRIES~0x28 |     $PS1 |  0.11.2.7B |                verified(D945), sha256_ok |
|  |   |    16 | 0x6ee000 |  0x3100 |              KVM_IMAGE~0x29 |     $PS1 | 8.17.30.30 |                verified(CC7D), sha256_ok |
|  |   |    17 | 0x6ee000 |  0x3100 |            S0I3_DRIVER~0x2d |     $PS1 | 8.17.30.30 |                verified(CC7D), sha256_ok |
|  |   |    18 | 0x6f1100 |   0x290 |                   ABL0~0x30 |          |    0.0.0.0 |                verified(CF65), sha256_ok |
|  |   |    19 | 0x760e00 |  0x5940 |          VBIOS_PRELOAD~0x3c |     $PS1 |  11.A.0.1D |                           verified(2FCA) |
|  |   |    20 | 0x766800 |  0x1b70 |    TOS_SECURITY_POLICY~0x45 |     $PS1 |   B.9.1.85 |      verified(BCC5), sha256_inconsistent |
|  |   |    21 | 0x768400 |   0x210 |             FW_INVALID~0x44 |     $PS1 |    0.0.0.0 |                           verified(462E) |
|  |   |    22 | 0x76eb00 |  0x1900 |           KEY_DATABASE~0x50 |     $PS1 |          1 |                verified(144E), sha256_ok |
|  |   |    23 | 0x770400 |  0x1070 |         TOS_PUBLIC_KEY~0x51 |     $PS1 |          1 |                verified(144E), sha256_ok |
|  |   |    24 | 0x771500 |  0x5b70 |                        0x58 |     $PS1 |    0.0.0.0 |                           verified(EBDF) |
|  |   |    25 | 0x777100 |   0x220 |                        0x59 |     $PS1 |    0.0.0.0 |                           verified(EBDF) |
|  |   |    26 | 0x777400 |   0xb20 |                   WMOS~0x5c |     $PS1 |  0.17.60.1 |                verified(8A19), sha256_ok |
|  |   |    27 | 0x778000 |  0x4100 |                DRTM_TA~0x47 |     $PS1 |  4.11.0.2F |                           verified(61CE) |
|  |   |    28 |  0x91000 | 0x40000 |              PSP_NVRAM~0x54 |          |            |                                          |
+--+---+-------+----------+---------+-----------------------------+----------+------------+------------------------------------------+


+--+-----------+----------+------+------------+-------+---------------------+
|  | Directory |   Addr   | Type | Generation | Magic | Secondary Directory |
+--+-----------+----------+------+------------+-------+---------------------+
|  |     4     | 0x215000 | BIOS |   Zen 3    |  $BHD |       0x5f8000      |
+--+-----------+----------+------+------------+-------+---------------------+
+--+---+-------+----------+--------+-------------------------------+----------+----------+------------------------------------------+
|  |   | Entry |  Address |   Size |                          Type | Magic/ID |  Version |                                     Info |
+--+---+-------+----------+--------+-------------------------------+----------+----------+------------------------------------------+
|  |   |     0 | 0x216000 | 0x4000 |                     APCB~0x60 |          |          |                                          |
|  |   |     1 | 0x21a000 | 0x4000 |                APCB_COPY~0x68 |          |          |                                          |
|  |   |     2 | 0x21e000 | 0x4000 |                APCB_COPY~0x68 |          |          |                                          |
|  |   |     3 |      0x0 |    0x0 |                     APOB~0x61 |          |          |                                          |
|  |   |     4 | 0x222000 | 0x4890 |                 PMU_CODE~0x64 |     0x05 | 0.0.10.1 | compressed, veri-failed(4F75), sha256_ok |
|  |   |     5 | 0x226900 |  0x360 |                 PMU_DATA~0x65 |     0x05 | 0.0.10.1 | compressed, veri-failed(4F75), sha256_ok |
|  |   |     6 | 0x226d00 | 0x4ae0 |                 PMU_CODE~0x64 |     0x05 | 0.0.10.1 | compressed, veri-failed(4F75), sha256_ok |
|  |   |     7 | 0x22b800 |  0x340 |                 PMU_DATA~0x65 |     0x05 | 0.0.10.1 | compressed, veri-failed(4F75), sha256_ok |
|  |   |     8 | 0x5f8000 |  0x400 | !BL2_SECONDARY_DIRECTORY~0x70 |          |          |                                          |
+--+---+-------+----------+--------+-------------------------------+----------+----------+------------------------------------------+


+--+-----------+----------+-----------+------------+-------+---------------------+
|  | Directory |   Addr   |    Type   | Generation | Magic | Secondary Directory |
+--+-----------+----------+-----------+------------+-------+---------------------+
|  |     5     | 0x5f8000 | secondary |   Zen 3    |  $BL2 |                     |
+--+-----------+----------+-----------+------------+-------+---------------------+
+--+---+-------+----------+---------+----------------------+----------+----------+------------------------------------------+
|  |   | Entry |  Address |    Size |                 Type | Magic/ID |  Version |                                     Info |
+--+---+-------+----------+---------+----------------------+----------+----------+------------------------------------------+
|  |   |     0 | 0x5f9000 |  0x4000 |            APCB~0x60 |          |          |                                          |
|  |   |     1 | 0x5fd000 |  0x4000 |       APCB_COPY~0x68 |          |          |                                          |
|  |   |     2 | 0x601000 |  0x4000 |       APCB_COPY~0x68 |          |          |                                          |
|  |   |     3 |      0x0 |     0x0 |            APOB~0x61 |          |          |                                          |
|  |   |     4 | 0x605000 | 0x10000 |    APOB_NV_COPY~0x63 |          |          |                                          |
|  |   |     5 | 0x615000 |  0x4890 |        PMU_CODE~0x64 |     0x05 | 0.0.10.1 | compressed, veri-failed(4F75), sha256_ok |
|  |   |     6 | 0x619900 |   0x360 |        PMU_DATA~0x65 |     0x05 | 0.0.10.1 | compressed, veri-failed(4F75), sha256_ok |
|  |   |     7 | 0x619d00 |  0x4ae0 |        PMU_CODE~0x64 |     0x05 | 0.0.10.1 | compressed, veri-failed(4F75), sha256_ok |
|  |   |     8 | 0x61e800 |   0x340 |        PMU_DATA~0x65 |     0x05 | 0.0.10.1 | compressed, veri-failed(4F75), sha256_ok |
|  |   |     9 | 0x61ec00 |  0x15c0 | MICROCODE_PATCH~0x66 |          |          |                                          |
|  |   |    10 | 0x620200 |   0x248 |      MP2_FW_CFG~0x6a |          |  0.0.0.0 |                verified(C04C), sha256_ok |
|  |   |    11 |  0x21000 | 0x40000 |                 0x6d |          |          |                                          |
|  |   |    12 |  0x61000 | 0x10000 |                 0x6d |          |          |                                          |
+--+---+-------+----------+---------+----------------------+----------+----------+------------------------------------------+


+--+-----------+----------+------+------------+-------+---------------------+
|  | Directory |   Addr   | Type | Generation | Magic | Secondary Directory |
+--+-----------+----------+------+------------+-------+---------------------+
|  |     6     | 0x3b0000 | BIOS |   Zen 3    |  $BHD |       0x813000      |
+--+-----------+----------+------+------------+-------+---------------------+
+--+---+-------+----------+--------+-------------------------------+----------+----------+-------------------------------+
|  |   | Entry |  Address |   Size |                          Type | Magic/ID |  Version |                          Info |
+--+---+-------+----------+--------+-------------------------------+----------+----------+-------------------------------+
|  |   |     0 | 0x3b1000 | 0x2000 |                     APCB~0x60 |          |          |                               |
|  |   |     1 | 0x3b3000 | 0x2000 |                APCB_COPY~0x68 |          |          |                               |
|  |   |     2 | 0x3b5000 | 0x2000 |                APCB_COPY~0x68 |          |          |                               |
|  |   |     3 |      0x0 |    0x0 |                     APOB~0x61 |          |          |                               |
|  |   |     4 | 0x3b7000 | 0x4890 |                 PMU_CODE~0x64 |     0x05 | 0.0.10.1 | compressed, veri-failed(38D0) |
|  |   |     5 | 0x3bb900 |  0x360 |                 PMU_DATA~0x65 |     0x05 | 0.0.10.1 | compressed, veri-failed(38D0) |
|  |   |     6 | 0x3bbd00 | 0x4ae0 |                 PMU_CODE~0x64 |     0x05 | 0.0.10.1 | compressed, veri-failed(38D0) |
|  |   |     7 | 0x3c0800 |  0x340 |                 PMU_DATA~0x65 |     0x05 | 0.0.10.1 | compressed, veri-failed(38D0) |
|  |   |     8 | 0x813000 |  0x400 | !BL2_SECONDARY_DIRECTORY~0x70 |          |          |                               |
+--+---+-------+----------+--------+-------------------------------+----------+----------+-------------------------------+


+--+-----------+----------+-----------+------------+-------+---------------------+
|  | Directory |   Addr   |    Type   | Generation | Magic | Secondary Directory |
+--+-----------+----------+-----------+------------+-------+---------------------+
|  |     7     | 0x813000 | secondary |   Zen 3    |  $BL2 |                     |
+--+-----------+----------+-----------+------------+-------+---------------------+
+--+---+-------+----------+---------+----------------------+----------+----------+-------------------------------+
|  |   | Entry |  Address |    Size |                 Type | Magic/ID |  Version |                          Info |
+--+---+-------+----------+---------+----------------------+----------+----------+-------------------------------+
|  |   |     0 | 0x814000 |  0x2000 |            APCB~0x60 |          |          |                               |
|  |   |     1 | 0x816000 |  0x2000 |       APCB_COPY~0x68 |          |          |                               |
|  |   |     2 | 0x818000 |  0x2000 |       APCB_COPY~0x68 |          |          |                               |
|  |   |     3 |      0x0 |     0x0 |            APOB~0x61 |          |          |                               |
|  |   |     4 | 0x81a000 | 0x10000 |    APOB_NV_COPY~0x63 |          |          |                               |
|  |   |     5 | 0x82a000 |  0x4890 |        PMU_CODE~0x64 |     0x05 | 0.0.10.1 | compressed, veri-failed(38D0) |
|  |   |     6 | 0x82e900 |   0x360 |        PMU_DATA~0x65 |     0x05 | 0.0.10.1 | compressed, veri-failed(38D0) |
|  |   |     7 | 0x82ed00 |  0x4ae0 |        PMU_CODE~0x64 |     0x05 | 0.0.10.1 | compressed, veri-failed(38D0) |
|  |   |     8 | 0x833800 |   0x340 |        PMU_DATA~0x65 |     0x05 | 0.0.10.1 | compressed, veri-failed(38D0) |
|  |   |     9 | 0x833c00 |   0xc80 | MICROCODE_PATCH~0x66 |          |          |                               |
|  |   |    10 | 0x834900 |   0xc80 | MICROCODE_PATCH~0x66 |          |          |                               |
|  |   |    11 | 0x835600 |   0x248 |      MP2_FW_CFG~0x6a |          |  7.0.0.5 |     verified(7C83), sha256_ok |
|  |   |    12 |  0x21000 | 0x40000 |                 0x6d |          |          |                               |
|  |   |    13 |  0x61000 | 0x10000 |                 0x6d |          |          |                               |
+--+---+-------+----------+---------+----------------------+----------+----------+-------------------------------+

Output of replacement of SMU Part 1:

Warning: Could not verify sha256 checksum for HeaderEntry(type=0x45, address=0x185400, size=0x1b70, len(references)=1)
Warning: Could not verify sha256 checksum for HeaderEntry(type=0x45, address=0x546000, size=0x1b70, len(references)=1)
Warning: Could not verify sha256 checksum for HeaderEntry(type=0x24, address=0x2af000, size=0x2eb0, len(references)=1)
Warning: Could not verify sha256 checksum for HeaderEntry(type=0x45, address=0x2b1f00, size=0x1b70, len(references)=1)
Warning: Could not verify sha256 checksum for HeaderEntry(type=0x24, address=0x6a0000, size=0x2eb0, len(references)=1)
Warning: Could not verify sha256 checksum for HeaderEntry(type=0x45, address=0x766800, size=0x1b70, len(references)=1)
Warning: Couldn't parse plain entry: 0x62
Warning: Entry of Directory(address=0x215000, type=BIOS, magic=b'$BHD', count=10) at 0xd02000 cannot be parsed
Warning: Couldn't parse plain entry: 0x62
Warning: Entry of Directory(address=0x5f8000, type=secondary, magic=b'$BL2', count=14) at 0xd02000 cannot be parsed
Warning: Couldn't parse entry at: 0x21000. Type: 0x6d. Size 0x40000
Warning: Couldn't parse entry at: 0x61000. Type: 0x6d. Size 0x10000
Warning: Couldn't parse plain entry: 0x62
Warning: Entry of Directory(address=0x3b0000, type=BIOS, magic=b'$BHD', count=10) at 0xd02000 cannot be parsed
Warning: Couldn't parse plain entry: 0x62
Warning: Entry of Directory(address=0x813000, type=secondary, magic=b'$BL2', count=15) at 0xd02000 cannot be parsed
Warning: Couldn't parse entry at: 0x21000. Type: 0x6d. Size 0x40000
Warning: Couldn't parse entry at: 0x61000. Type: 0x6d. Size 0x10000
Warning: Empty FET entry at ROM address 0x0
Warning: Empty FET entry at ROM address 0x5500
Replacing PubkeyEntity(96A0, @17ede0)
Resigning SignedEntity(@42f600:40100) (HeaderEntry(type=0x8, address=0x42f600, size=0x40100, len(references)=1))
    Checking sha256 checksum of HeaderEntry(type=0x8, address=0x42f600, size=0x40100, len(references)=1)
        Need to rehash
        Done
Resigning SignedEntity(@102000:11a40) (HeaderEntry(type=0x12, address=0x102000, size=0x11a40, len(references)=1))
    Checking sha256 checksum of HeaderEntry(type=0x12, address=0x102000, size=0x11a40, len(references)=1)
        sha256 still valid!
Resigning SignedEntity(@e0f00:21100) (HeaderEntry(type=0x8, address=0xe0f00, size=0x21100, len(references)=1))
    Checking sha256 checksum of HeaderEntry(type=0x8, address=0xe0f00, size=0x21100, len(references)=1)
        sha256 still valid!
Resigning SignedEntity(@470d00:11a40) (HeaderEntry(type=0x12, address=0x470d00, size=0x11a40, len(references)=1))
    Checking sha256 checksum of HeaderEntry(type=0x12, address=0x470d00, size=0x11a40, len(references)=1)
        sha256 still valid!
Replacing PubkeyEntity(6C9E, @d2404)
Resigning SignedEntity(@d2900:e5c0) (HeaderEntry(type=0x3, address=0xd2900, size=0xe5c0, len(references)=1))
    Checking sha256 checksum of HeaderEntry(type=0x3, address=0xd2900, size=0xe5c0, len(references)=1)
        sha256 still valid!
Resigning SignedEntity(@17e100:1900) (KeyStoreEntry(type=0x50, address=0x17e100, size=0x1900, len(references)=1))
    Checking sha256 checksum of KeyStoreEntry(type=0x50, address=0x17e100, size=0x1900, len(references)=1)
        Need to rehash
        Done
Resigning SignedEntity(@408400:10880) (HeaderEntry(type=0x1, address=0x408400, size=0x10880, len(references)=2))
    Checking sha256 checksum of HeaderEntry(type=0x1, address=0x408400, size=0x10880, len(references)=2)
        sha256 still valid!
Resigning SignedEntity(@552400:1900) (KeyStoreEntry(type=0x50, address=0x552400, size=0x1900, len(references)=1))
    Checking sha256 checksum of KeyStoreEntry(type=0x50, address=0x552400, size=0x1900, len(references)=1)
        sha256 still valid!
Resigning SignedEntity(@450700:440) (PubkeyEntry(type=0x9, address=0x450700, size=0x440, len(references)=1))
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Users\protoxis\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\Scripts\psptool.exe\__main__.py", line 7, in <module>
  File "C:\Users\protoxis\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\psptool\__main__.py", line 193, in main
    entry.signed_entity.resign_and_replace(privkeys=privkeys, recursive=True)
  File "C:\Users\protoxis\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\psptool\cert_tree.py", line 122, in resign_and_replace
    pk.replace_and_resign(privkeys, recursive=recursive)
  File "C:\Users\protoxis\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\psptool\cert_tree.py", line 250, in replace_and_resign
    se.resign_and_replace(privkeys=privkeys, recursive=True)
  File "C:\Users\protoxis\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\psptool\cert_tree.py", line 122, in resign_and_replace
    pk.replace_and_resign(privkeys, recursive=recursive)
  File "C:\Users\protoxis\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\psptool\cert_tree.py", line 238, in replace_and_resign
    se.resign_only(privkey)
  File "C:\Users\protoxis\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\psptool\cert_tree.py", line 111, in resign_only
    signature = privkey.sign_blob(self.entry.get_signed_bytes())
                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\protoxis\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\psptool\entry.py", line 751, in get_signed_bytes
    return self.get_bytes(0, self.buffer_size - self.signature_size)
                                                ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\protoxis\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\psptool\entry.py", line 732, in signature_size
    return self.buffer_size - self.HEADER_LEN - self.pubexp_size - self.modulus_size
                                                ^^^^^^^^^^^^^^^^
  File "C:\Users\protoxis\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\psptool\entry.py", line 722, in pubexp_size
    assert self.pubexp_bits & 0x3 == 0
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError

Output of replacement of SMU Part 2:

Warning: Could not verify sha256 checksum for HeaderEntry(type=0x45, address=0x185400, size=0x1b70, len(references)=1)
Warning: Could not verify sha256 checksum for HeaderEntry(type=0x45, address=0x546000, size=0x1b70, len(references)=1)
Warning: Could not verify sha256 checksum for HeaderEntry(type=0x24, address=0x2af000, size=0x2eb0, len(references)=1)
Warning: Could not verify sha256 checksum for HeaderEntry(type=0x45, address=0x2b1f00, size=0x1b70, len(references)=1)
Warning: Could not verify sha256 checksum for HeaderEntry(type=0x24, address=0x6a0000, size=0x2eb0, len(references)=1)
Warning: Could not verify sha256 checksum for HeaderEntry(type=0x45, address=0x766800, size=0x1b70, len(references)=1)
Warning: Couldn't parse plain entry: 0x62
Warning: Entry of Directory(address=0x215000, type=BIOS, magic=b'$BHD', count=10) at 0xd02000 cannot be parsed
Warning: Couldn't parse plain entry: 0x62
Warning: Entry of Directory(address=0x5f8000, type=secondary, magic=b'$BL2', count=14) at 0xd02000 cannot be parsed
Warning: Couldn't parse entry at: 0x21000. Type: 0x6d. Size 0x40000
Warning: Couldn't parse entry at: 0x61000. Type: 0x6d. Size 0x10000
Warning: Couldn't parse plain entry: 0x62
Warning: Entry of Directory(address=0x3b0000, type=BIOS, magic=b'$BHD', count=10) at 0xd02000 cannot be parsed
Warning: Couldn't parse plain entry: 0x62
Warning: Entry of Directory(address=0x813000, type=secondary, magic=b'$BL2', count=15) at 0xd02000 cannot be parsed
Warning: Couldn't parse entry at: 0x21000. Type: 0x6d. Size 0x40000
Warning: Couldn't parse entry at: 0x61000. Type: 0x6d. Size 0x10000
Warning: Empty FET entry at ROM address 0x0
Warning: Empty FET entry at ROM address 0x5500
Replacing PubkeyEntity(96A0, @17ede0)
Resigning SignedEntity(@42f600:21100) (HeaderEntry(type=0x8, address=0x42f600, size=0x21100, len(references)=1))
    Checking sha256 checksum of HeaderEntry(type=0x8, address=0x42f600, size=0x21100, len(references)=1)
        sha256 still valid!
Resigning SignedEntity(@102000:11a40) (HeaderEntry(type=0x12, address=0x102000, size=0x11a40, len(references)=1))
    Checking sha256 checksum of HeaderEntry(type=0x12, address=0x102000, size=0x11a40, len(references)=1)
        sha256 still valid!
Resigning SignedEntity(@e0f00:21100) (HeaderEntry(type=0x8, address=0xe0f00, size=0x21100, len(references)=1))
    Checking sha256 checksum of HeaderEntry(type=0x8, address=0xe0f00, size=0x21100, len(references)=1)
        sha256 still valid!
Resigning SignedEntity(@470d00:40100) (HeaderEntry(type=0x12, address=0x470d00, size=0x40100, len(references)=1))
    Checking sha256 checksum of HeaderEntry(type=0x12, address=0x470d00, size=0x40100, len(references)=1)
        Need to rehash
        Done
Replacing PubkeyEntity(6C9E, @d2404)
Resigning SignedEntity(@d2900:e5c0) (HeaderEntry(type=0x3, address=0xd2900, size=0xe5c0, len(references)=1))
    Checking sha256 checksum of HeaderEntry(type=0x3, address=0xd2900, size=0xe5c0, len(references)=1)
        sha256 still valid!
Resigning SignedEntity(@17e100:1900) (KeyStoreEntry(type=0x50, address=0x17e100, size=0x1900, len(references)=1))
    Checking sha256 checksum of KeyStoreEntry(type=0x50, address=0x17e100, size=0x1900, len(references)=1)
        Need to rehash
        Done
Resigning SignedEntity(@408400:10880) (HeaderEntry(type=0x1, address=0x408400, size=0x10880, len(references)=2))
    Checking sha256 checksum of HeaderEntry(type=0x1, address=0x408400, size=0x10880, len(references)=2)
        sha256 still valid!
Resigning SignedEntity(@552400:1900) (KeyStoreEntry(type=0x50, address=0x552400, size=0x1900, len(references)=1))
    Checking sha256 checksum of KeyStoreEntry(type=0x50, address=0x552400, size=0x1900, len(references)=1)
        sha256 still valid!
Resigning SignedEntity(@450700:440) (PubkeyEntry(type=0x9, address=0x450700, size=0x440, len(references)=1))
Resigning SignedEntity(@553d00:12c0) (KeyStoreEntry(type=0x51, address=0x553d00, size=0x12c0, len(references)=1))
    Checking sha256 checksum of KeyStoreEntry(type=0x51, address=0x553d00, size=0x12c0, len(references)=1)
        sha256 still valid!
Replacing PubkeyEntity(6C9E, @418d04)
Resigning SignedEntity(@d2900:e5c0) (HeaderEntry(type=0x3, address=0xd2900, size=0xe5c0, len(references)=1))
    Checking sha256 checksum of HeaderEntry(type=0x3, address=0xd2900, size=0xe5c0, len(references)=1)
        sha256 still valid!
Resigning SignedEntity(@17e100:1900) (KeyStoreEntry(type=0x50, address=0x17e100, size=0x1900, len(references)=1))
    Checking sha256 checksum of KeyStoreEntry(type=0x50, address=0x17e100, size=0x1900, len(references)=1)
        sha256 still valid!
Resigning SignedEntity(@408400:10880) (HeaderEntry(type=0x1, address=0x408400, size=0x10880, len(references)=2))
    Checking sha256 checksum of HeaderEntry(type=0x1, address=0x408400, size=0x10880, len(references)=2)
        sha256 still valid!
Resigning SignedEntity(@552400:1900) (KeyStoreEntry(type=0x50, address=0x552400, size=0x1900, len(references)=1))
    Checking sha256 checksum of KeyStoreEntry(type=0x50, address=0x552400, size=0x1900, len(references)=1)
        sha256 still valid!
Resigning SignedEntity(@450700:440) (PubkeyEntry(type=0x9, address=0x450700, size=0x440, len(references)=1))
Resigning SignedEntity(@553d00:12c0) (KeyStoreEntry(type=0x51, address=0x553d00, size=0x12c0, len(references)=1))
    Checking sha256 checksum of KeyStoreEntry(type=0x51, address=0x553d00, size=0x12c0, len(references)=1)
        sha256 still valid!
Replacing PubkeyEntity(96A0, @5530e0)
Resigning SignedEntity(@42f600:21100) (HeaderEntry(type=0x8, address=0x42f600, size=0x21100, len(references)=1))
    Checking sha256 checksum of HeaderEntry(type=0x8, address=0x42f600, size=0x21100, len(references)=1)
        sha256 still valid!
Resigning SignedEntity(@102000:11a40) (HeaderEntry(type=0x12, address=0x102000, size=0x11a40, len(references)=1))
    Checking sha256 checksum of HeaderEntry(type=0x12, address=0x102000, size=0x11a40, len(references)=1)
        sha256 still valid!
Resigning SignedEntity(@e0f00:21100) (HeaderEntry(type=0x8, address=0xe0f00, size=0x21100, len(references)=1))
    Checking sha256 checksum of HeaderEntry(type=0x8, address=0xe0f00, size=0x21100, len(references)=1)
        sha256 still valid!
Resigning SignedEntity(@470d00:40100) (HeaderEntry(type=0x12, address=0x470d00, size=0x40100, len(references)=1))
    Checking sha256 checksum of HeaderEntry(type=0x12, address=0x470d00, size=0x40100, len(references)=1)
        sha256 still valid!
Replacing PubkeyEntity(6C9E, @d2404)
Resigning SignedEntity(@d2900:e5c0) (HeaderEntry(type=0x3, address=0xd2900, size=0xe5c0, len(references)=1))
    Checking sha256 checksum of HeaderEntry(type=0x3, address=0xd2900, size=0xe5c0, len(references)=1)
        sha256 still valid!
Resigning SignedEntity(@17e100:1900) (KeyStoreEntry(type=0x50, address=0x17e100, size=0x1900, len(references)=1))
    Checking sha256 checksum of KeyStoreEntry(type=0x50, address=0x17e100, size=0x1900, len(references)=1)
        sha256 still valid!
Resigning SignedEntity(@408400:10880) (HeaderEntry(type=0x1, address=0x408400, size=0x10880, len(references)=2))
    Checking sha256 checksum of HeaderEntry(type=0x1, address=0x408400, size=0x10880, len(references)=2)
        sha256 still valid!
Resigning SignedEntity(@552400:1900) (KeyStoreEntry(type=0x50, address=0x552400, size=0x1900, len(references)=1))
    Checking sha256 checksum of KeyStoreEntry(type=0x50, address=0x552400, size=0x1900, len(references)=1)
        Need to rehash
        Done
Resigning SignedEntity(@450700:440) (PubkeyEntry(type=0x9, address=0x450700, size=0x440, len(references)=1))
Resigning SignedEntity(@553d00:12c0) (KeyStoreEntry(type=0x51, address=0x553d00, size=0x12c0, len(references)=1))
    Checking sha256 checksum of KeyStoreEntry(type=0x51, address=0x553d00, size=0x12c0, len(references)=1)
        sha256 still valid!
Replacing PubkeyEntity(6C9E, @418d04)
Resigning SignedEntity(@d2900:e5c0) (HeaderEntry(type=0x3, address=0xd2900, size=0xe5c0, len(references)=1))
    Checking sha256 checksum of HeaderEntry(type=0x3, address=0xd2900, size=0xe5c0, len(references)=1)
        sha256 still valid!
Resigning SignedEntity(@17e100:1900) (KeyStoreEntry(type=0x50, address=0x17e100, size=0x1900, len(references)=1))
    Checking sha256 checksum of KeyStoreEntry(type=0x50, address=0x17e100, size=0x1900, len(references)=1)
        sha256 still valid!
Resigning SignedEntity(@408400:10880) (HeaderEntry(type=0x1, address=0x408400, size=0x10880, len(references)=2))
    Checking sha256 checksum of HeaderEntry(type=0x1, address=0x408400, size=0x10880, len(references)=2)
        sha256 still valid!
Resigning SignedEntity(@552400:1900) (KeyStoreEntry(type=0x50, address=0x552400, size=0x1900, len(references)=1))
    Checking sha256 checksum of KeyStoreEntry(type=0x50, address=0x552400, size=0x1900, len(references)=1)
        sha256 still valid!
Resigning SignedEntity(@450700:440) (PubkeyEntry(type=0x9, address=0x450700, size=0x440, len(references)=1))
Resigning SignedEntity(@553d00:12c0) (KeyStoreEntry(type=0x51, address=0x553d00, size=0x12c0, len(references)=1))
    Checking sha256 checksum of KeyStoreEntry(type=0x51, address=0x553d00, size=0x12c0, len(references)=1)
        sha256 still valid!
@belotv belotv changed the title Limited APU are support (summary is partially broken + cannot replace module) Limited APU support (summary is partially broken + cannot replace module) Jun 8, 2024
@Ragebone
Copy link

Ragebone commented Jul 14, 2024

I did encounter similar issues in the past.
What i specifically remember is that replacing with smaller or equal sized blobs would work.
Only larger blobs would fail.

What i find a bit confusing is the messages about resigning.
I don't see a reason to sign anything in this case, so why is it printing about that?

OpenSIL AGCL-R has you covered with the official python tool.
https://github.com/openSIL/AGCL-R/tree/0a60473007604550bd0fb708cc1a820240d1bc51/AgesaModulePkg/AMDTools/NewPspKit/PspDirectoryTool

Otherwise the amdfwtool from coreboot might be an option as well

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants