diff --git a/src/arch/x86/Kconfig b/src/arch/x86/Kconfig index 6af3fa8b69..207654d8a9 100644 --- a/src/arch/x86/Kconfig +++ b/src/arch/x86/Kconfig @@ -340,4 +340,23 @@ config MEMLAYOUT_LD_FILE string default "src/arch/x86/memlayout.ld" +# Some EC need an "EC firmware pointer" (a data structure hinting the address +# of its firmware blobs) being put at a fixed position. Its space +# (__section__(".ecfw_ptr")) should be reserved if it lies in the range of a +# stage. Different EC may have different format and/or value for it. The actual +# address of EC firmware pointer should be provided in the Kconfig of the EC +# requiring it, and its value could be filled by linking a read-only global +# data object to the section above. + +config ECFW_PTR_ADDR + hex + help + Address of reserved space for EC firmware pointer, which should not + overlap other data such as reset vector or FIT pointer if present. + +config ECFW_PTR_SIZE + int + help + Size of reserved space for EC firmware pointer + endif diff --git a/src/arch/x86/bootblock.ld b/src/arch/x86/bootblock.ld index 4ab2275998..0b908bbec6 100644 --- a/src/arch/x86/bootblock.ld +++ b/src/arch/x86/bootblock.ld @@ -31,7 +31,7 @@ SECTIONS { */ PROGRAM_SZ = SIZEOF(.text) + 512; - . = MIN(_ID_SECTION, _FIT_POINTER) - EARLYASM_SZ; + . = MIN(_ECFW_PTR, MIN(_ID_SECTION, _FIT_POINTER)) - EARLYASM_SZ; . = CONFIG(SIPI_VECTOR_IN_ROM) ? ALIGN(4096) : ALIGN(16); BOOTBLOCK_TOP = .; .init (.) : { @@ -56,6 +56,13 @@ SECTIONS { _ID_SECTION_END = SIZEOF(.fit_pointer) && SIZEOF(.id) > 0x28 ? 0xffffff80 : _X86_RESET_VECTOR; _ID_SECTION = _ID_SECTION_END - SIZEOF(.id); + . = _ECFW_PTR; + .ecfw_ptr (.): { + ASSERT((SIZEOF(.ecfw_ptr) == CONFIG_ECFW_PTR_SIZE), "Size of ecfw_ptr is incorrect"); + KEEP(*(.ecfw_ptr)); + } + _ECFW_PTR = SIZEOF(.ecfw_ptr) ? CONFIG_ECFW_PTR_ADDR : _X86_RESET_VECTOR; + . = _FIT_POINTER; .fit_pointer (.): { KEEP(*(.fit_pointer)); diff --git a/src/ec/hp/kbc1126/Kconfig b/src/ec/hp/kbc1126/Kconfig index cb4ddec7e4..5e6edd6a69 100644 --- a/src/ec/hp/kbc1126/Kconfig +++ b/src/ec/hp/kbc1126/Kconfig @@ -27,6 +27,12 @@ config KBC1126_FIRMWARE Select this option to add the two firmware blobs for KBC1126. You need these two blobs to power on your machine. +config ECFW_PTR_ADDR + default 0xffffff00 + +config ECFW_PTR_SIZE + default 8 + config KBC1126_FW1 string "KBC1126 firmware #1 path and filename" depends on KBC1126_FIRMWARE @@ -37,9 +43,9 @@ config KBC1126_FW1 vendor firmware. config KBC1126_FW1_OFFSET - string "Offset of KBC1126 firmware #1" + hex "Offset of KBC1126 firmware #1" depends on KBC1126_FIRMWARE - default "0xfffe8000" + default 0xfffe8000 config KBC1126_FW2 string "KBC1126 filename #2 path and filename" @@ -51,8 +57,8 @@ config KBC1126_FW2 vendor firmware. config KBC1126_FW2_OFFSET - string "Offset of KBC1126 firmware #2" + hex "Offset of KBC1126 firmware #2" depends on KBC1126_FIRMWARE - default "0xfffd0000" + default 0xfffd0000 endif diff --git a/src/ec/hp/kbc1126/Makefile.inc b/src/ec/hp/kbc1126/Makefile.inc index 4d7d46d9e7..3f7fa19b5d 100644 --- a/src/ec/hp/kbc1126/Makefile.inc +++ b/src/ec/hp/kbc1126/Makefile.inc @@ -1,7 +1,8 @@ ## SPDX-License-Identifier: GPL-2.0-only ifeq ($(CONFIG_EC_HP_KBC1126_ECFW_IN_CBFS),y) -KBC1126_EC_INSERT:=$(top)/util/kbc1126/kbc1126_ec_insert + +bootblock-y += ecfw_ptr.c ifeq ($(CONFIG_KBC1126_FIRMWARE),y) cbfs-files-y += ecfw1.bin @@ -16,15 +17,6 @@ ecfw2.bin-position := $(CONFIG_KBC1126_FW2_OFFSET) ecfw2.bin-type := raw endif -$(call add_intermediate, kbc1126_ec_insert) -ifeq ($(CONFIG_KBC1126_FIRMWARE),y) - printf " Building kbc1126_ec_insert.\n" - $(MAKE) -C util/kbc1126 - printf " KBC1126 Inserting KBC1126 firmware blobs.\n" - $(KBC1126_EC_INSERT) $(obj)/coreboot.pre \ - $(CONFIG_KBC1126_FW1_OFFSET) $(CONFIG_KBC1126_FW2_OFFSET) -endif - build_complete:: ifeq ($(CONFIG_KBC1126_FIRMWARE),) printf "\n** WARNING **\n" diff --git a/src/ec/hp/kbc1126/ecfw_ptr.c b/src/ec/hp/kbc1126/ecfw_ptr.c new file mode 100644 index 0000000000..8a29c6cd33 --- /dev/null +++ b/src/ec/hp/kbc1126/ecfw_ptr.c @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include "ecfw_ptr.h" + +/* + * Address info for EC SMSC KBC1098/KBC1126 to find their firmware blobs, + * linked to CONFIG_ECFW_PTR_ADDR via src/arch/x86/bootblock.ld + */ +__attribute__((used, __section__(".ecfw_ptr"))) +const struct ecfw_ptr ecfw_ptr = { + .fw1.off = cpu_to_be16((uint16_t)(CONFIG_KBC1126_FW1_OFFSET >> 8)), + .fw1.inv = cpu_to_be16((uint16_t)~(CONFIG_KBC1126_FW1_OFFSET >> 8)), + .fw2.off = cpu_to_be16((uint16_t)(CONFIG_KBC1126_FW2_OFFSET >> 8)), + .fw2.inv = cpu_to_be16((uint16_t)~(CONFIG_KBC1126_FW2_OFFSET >> 8)), +}; diff --git a/src/ec/hp/kbc1126/ecfw_ptr.h b/src/ec/hp/kbc1126/ecfw_ptr.h new file mode 100644 index 0000000000..acf54f20dd --- /dev/null +++ b/src/ec/hp/kbc1126/ecfw_ptr.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _EC_HP_KBC1126_PTR_H +#define _EC_HP_KBC1126_PTR_H + +#include + +struct __attribute__((__packed__)) ecfw_addr { + /* 8-byte offset of firmware blob in big endian */ + uint16_t off; + /* bitwise inverse of "off", for error checking */ + uint16_t inv; +}; + +struct __attribute__((__packed__)) ecfw_ptr { + struct ecfw_addr fw1; + struct ecfw_addr fw2; +}; + +#endif