coreboot/src/lib/Makefile.mk
Alper Nebi Yasak 377157c7fb device_tree: Add function to get top of memory from a FDT blob
coreboot needs to figure out top of memory to place CBMEM data. On some
non-x86 QEMU virtual machines, this is achieved by probing the RAM space
to find where the VM starts discarding data since it's not backed by
actual RAM. This behaviour seems to have changed on the QEMU side since
then, VMs using the "virt" model have started raising exceptions/errors
instead of silently discarding data (likely [1] for example) which has
previously broken coreboot on these emulation boards.

The qemu-aarch64 and qemu-riscv mainboards are intended for the "virt"
models and had this issue, which were mostly fixed by using exception
handlers in the RAM detection process [2][3]. But on 32-bit RISC-V we
fail to initialize CBMEM if we have 2048 MiB or more of RAM, and on
64-bit RISC-V we had to limit probing to 16383 MiB because it can run
into MMIO regions otherwise.

The qemu-armv7 mainboard code is intended for the "vexpress-a9" model VM
which doesn't appear to suffer from this issue. Still, the issue can be
observed on the ARMv7 "virt" model via a port based on qemu-aarch64.

QEMU docs for ARM and RISC-V "virt" models [4][5] recommend reading the
device tree blob it provides for device information (incl. RAM size).
Implement functions that parse the device tree blob to find described
memory regions and calculate the top of memory in order to use it in
mainboard code as an alternative to probing RAM space. ARM64 code
initializes CBMEM in romstage where malloc isn't available, so take care
to do parsing without unflattening the blob and make the code available
in romstage as well.

[1] https://lore.kernel.org/qemu-devel/1504626814-23124-1-git-send-email-peter.maydell@linaro.org/T/#u
[2] https://review.coreboot.org/c/coreboot/+/34774
[3] https://review.coreboot.org/c/coreboot/+/36486
[4] https://qemu-project.gitlab.io/qemu/system/arm/virt.html
[5] https://qemu-project.gitlab.io/qemu/system/riscv/virt.html

Change-Id: I8bef09bc1bc4e324ebeaa37f78d67d3aa315f52c
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/80322
Reviewed-by: Maximilian Brune <maximilian.brune@9elements.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
2024-06-03 15:38:55 +00:00

421 lines
12 KiB
Makefile

# SPDX-License-Identifier: GPL-2.0-only
subdirs-y += gnat
ifeq ($(CONFIG_UBSAN),y)
ramstage-y += ubsan.c
CFLAGS_ramstage += -fsanitize=undefined
endif
# Ensure that asan_shadow_offset_callback patch is applied to GCC before ASan is used.
CFLAGS_asan += -fsanitize=kernel-address --param asan-use-shadow-offset-callback=1 \
--param asan-stack=1 -fsanitize-address-use-after-scope \
--param asan-instrumentation-with-call-threshold=0 \
--param use-after-scope-direct-emission-threshold=0
ifeq ($(CONFIG_ASAN_IN_ROMSTAGE),y)
romstage-y += asan.c
CFLAGS_asan += --param asan-globals=0
CFLAGS_romstage += $(CFLAGS_asan)
# Allow memory access without __asan_load and __asan_store checks.
$(obj)/romstage/lib/asan.o: CFLAGS_asan =
endif
ifeq ($(CONFIG_ASAN_IN_RAMSTAGE),y)
ramstage-y += asan.c
CFLAGS_asan += --param asan-globals=1
CFLAGS_ramstage += $(CFLAGS_asan)
$(obj)/ramstage/lib/asan.o: CFLAGS_asan =
endif
decompressor-y += decompressor.c
$(call src-to-obj,decompressor,$(dir)/decompressor.c): $(objcbfs)/bootblock.lz4
$(call src-to-obj,decompressor,$(dir)/decompressor.c): CCACHE_EXTRAFILES=$(objcbfs)/bootblock.lz4
# Must reset CCACHE_EXTRAFILES or make applies it transitively to dependencies.
$(objcbfs)/bootblock.lz4: CCACHE_EXTRAFILES=
decompressor-y += delay.c
decompressor-$(CONFIG_GENERIC_GPIO_LIB) += gpio.c
decompressor-y += memchr.c
decompressor-y += memcmp.c
decompressor-$(CONFIG_CBFS_VERIFICATION) += metadata_hash.c
decompressor-y += prog_ops.c
decompressor-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
bootblock-y += bootblock.c
bootblock-y += prog_loaders.c
bootblock-y += prog_ops.c
bootblock-y += cbfs.c
bootblock-$(CONFIG_GENERIC_GPIO_LIB) += gpio.c
bootblock-y += libgcc.c
ifneq ($(CONFIG_VBOOT_STARTS_BEFORE_BOOTBLOCK),y)
bootblock-$(CONFIG_CBFS_VERIFICATION) += metadata_hash.c
else # ($(CONFIG_VBOOT_STARTS_BEFORE_BOOTBLOCK),y)
verstage-$(CONFIG_CBFS_VERIFICATION) += metadata_hash.c
endif # ($(CONFIG_VBOOT_STARTS_BEFORE_BOOTBLOCK),y)
bootblock-$(CONFIG_GENERIC_UDELAY) += timer.c
bootblock-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
bootblock-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c
bootblock-y += delay.c
bootblock-y += memchr.c
bootblock-y += memcmp.c
bootblock-y += boot_device.c
bootblock-y += fmap.c
verstage-y += prog_loaders.c
verstage-y += prog_ops.c
verstage-y += delay.c
verstage-y += cbfs.c
verstage-y += halt.c
verstage-y += fmap.c
verstage-y += libgcc.c
verstage-y += memcmp.c
verstage-y += string.c
verstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
verstage-y += boot_device.c
verstage-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c
verstage-$(CONFIG_GENERIC_UDELAY) += timer.c
verstage-$(CONFIG_GENERIC_GPIO_LIB) += gpio.c
romstage-$(CONFIG_PROBE_RAM) += ramdetect.c
romstage-y += prog_loaders.c
romstage-y += prog_ops.c
romstage-y += memchr.c
romstage-y += memcmp.c
$(foreach arch,$(ARCH_SUPPORTED),\
$(eval rmodules_$(arch)-y += memcmp.c) \
$(eval rmodules_$(arch)-y += rmodule.ld))
romstage-y += fmap.c
romstage-y += delay.c
romstage-y += cbfs.c
ifneq ($(CONFIG_COMPRESS_RAMSTAGE_LZMA)$(CONFIG_FSP_COMPRESS_FSP_M_LZMA),)
romstage-y += lzma.c lzmadecode.c
endif
romstage-y += libgcc.c
romstage-y += memrange.c
romstage-$(CONFIG_PRIMITIVE_MEMTEST) += primitive_memtest.c
ramstage-$(CONFIG_PRIMITIVE_MEMTEST) += primitive_memtest.c
romstage-y += ramtest.c
romstage-$(CONFIG_GENERIC_GPIO_LIB) += gpio.c
ramstage-y += region_file.c
romstage-y += region_file.c
ramstage-y += romstage_handoff.c
romstage-y += romstage_handoff.c
romstage-y += selfboot.c
romstage-y += stack.c
romstage-y += rtc.c
ramstage-y += rtc.c
romstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
romstage-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c
romstage-y += dimm_info_util.c
ifeq ($(CONFIG_COMPILER_GCC),y)
bootblock-$(CONFIG_ARCH_BOOTBLOCK_X86_32) += gcc.c
verstage-$(CONFIG_ARCH_VERSTAGE_X86_32) += gcc.c
romstage-$(CONFIG_ARCH_ROMSTAGE_X86_32) += gcc.c
ramstage-$(CONFIG_ARCH_RAMSTAGE_X86_32) += gcc.c
smm-y += gcc.c
endif
romstage-$(CONFIG_GENERIC_UDELAY) += timer.c
ramstage-$(CONFIG_PROBE_RAM) += ramdetect.c
ramstage-y += prog_loaders.c
ramstage-y += prog_ops.c
ramstage-y += hardwaremain.c
ramstage-y += selfboot.c
ramstage-y += coreboot_table.c
ramstage-$(CONFIG_GENERATE_SMBIOS_TABLES) += smbios.c
ramstage-$(CONFIG_GENERATE_SMBIOS_TABLES) += smbios_defaults.c
ramstage-y += bootmem.c
ramstage-y += fmap.c
ramstage-y += memchr.c
ramstage-y += memcmp.c
ramstage-y += malloc.c
ramstage-y += dimm_info_util.c
ramstage-y += delay.c
ramstage-y += fallback_boot.c
ramstage-y += cbfs.c
ramstage-y += lzma.c lzmadecode.c
ramstage-y += stack.c
ramstage-y += hexstrtobin.c
ramstage-y += wrdd.c
ramstage-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c
ramstage-$(CONFIG_BMP_LOGO) += bmp_logo.c
ramstage-$(CONFIG_BOOTSPLASH) += bootsplash.c
ramstage-$(CONFIG_BOOTSPLASH) += jpeg.c
ramstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
ramstage-$(CONFIG_COVERAGE) += libgcov.c
ramstage-y += dp_aux.c
ramstage-y += edid.c
ramstage-y += edid_fill_fb.c
ramstage-y += memrange.c
ramstage-$(CONFIG_GENERIC_GPIO_LIB) += gpio.c
ramstage-$(CONFIG_GENERIC_UDELAY) += timer.c
ramstage-y += b64_decode.c
ramstage-$(CONFIG_ACPI_NHLT) += nhlt.c
ramstage-$(CONFIG_PAYLOAD_FIT_SUPPORT) += fit.c
ramstage-$(CONFIG_PAYLOAD_FIT_SUPPORT) += fit_payload.c
romstage-$(CONFIG_FLATTENED_DEVICE_TREE) += device_tree.c
ramstage-$(CONFIG_FLATTENED_DEVICE_TREE) += device_tree.c
romstage-$(CONFIG_TIMER_QUEUE) += timer_queue.c
ramstage-$(CONFIG_TIMER_QUEUE) += timer_queue.c
romstage-$(CONFIG_COOP_MULTITASKING) += thread.c
ramstage-$(CONFIG_COOP_MULTITASKING) += thread.c
romstage-y += cbmem_common.c
romstage-y += imd_cbmem.c
romstage-y += imd.c
ramstage-y += cbmem_common.c
ramstage-y += imd_cbmem.c
ramstage-y += imd.c
postcar-$(CONFIG_PROBE_RAM) += ramdetect.c
postcar-y += cbmem_common.c
postcar-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c
postcar-y += imd_cbmem.c
postcar-y += imd.c
postcar-y += romstage_handoff.c
bootblock-y += hexdump.c
postcar-y += hexdump.c
ramstage-y += hexdump.c
romstage-y += hexdump.c
verstage-y += hexdump.c
smm-y += hexdump.c
bootblock-$(CONFIG_FW_CONFIG) += fw_config.c
verstage-$(CONFIG_FW_CONFIG) += fw_config.c
romstage-$(CONFIG_FW_CONFIG) += fw_config.c
ramstage-$(CONFIG_FW_CONFIG) += fw_config.c
bootblock-$(CONFIG_ESPI_DEBUG) += espi_debug.c
verstage-$(CONFIG_ESPI_DEBUG) += espi_debug.c
romstage-$(CONFIG_ESPI_DEBUG) += espi_debug.c
ramstage-$(CONFIG_ESPI_DEBUG) += espi_debug.c
bootblock-$(CONFIG_REG_SCRIPT) += reg_script.c
verstage-$(CONFIG_REG_SCRIPT) += reg_script.c
romstage-$(CONFIG_REG_SCRIPT) += reg_script.c
ramstage-$(CONFIG_REG_SCRIPT) += reg_script.c
ramstage-$(CONFIG_TSEG_STAGE_CACHE) += ext_stage_cache.c
romstage-$(CONFIG_TSEG_STAGE_CACHE) += ext_stage_cache.c
postcar-$(CONFIG_TSEG_STAGE_CACHE) += ext_stage_cache.c
ramstage-$(CONFIG_CBMEM_STAGE_CACHE) += cbmem_stage_cache.c
romstage-$(CONFIG_CBMEM_STAGE_CACHE) += cbmem_stage_cache.c
postcar-$(CONFIG_CBMEM_STAGE_CACHE) += cbmem_stage_cache.c
romstage-y += boot_device.c
ramstage-y += boot_device.c
smm-y += boot_device.c
smm-y += delay.c
smm-y += fmap.c
smm-y += cbfs.c memcmp.c
smm-$(CONFIG_GENERIC_UDELAY) += timer.c
ifeq ($(CONFIG_DEBUG_SMI),y)
smm-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c
endif
all-y += identity.c version.c
smm-y += identity.c version.c
$(call src-to-obj,bootblock,$(dir)/version.c) : $(obj)/build.h
$(call src-to-obj,romstage,$(dir)/version.c) : $(obj)/build.h
$(call src-to-obj,ramstage,$(dir)/version.c) : $(obj)/build.h
$(call src-to-obj,smm,$(dir)/version.c) : $(obj)/build.h
$(call src-to-obj,verstage,$(dir)/version.c) : $(obj)/build.h
$(call src-to-obj,postcar,$(dir)/version.c) : $(obj)/build.h
bootblock-y += bootmode.c
romstage-y += bootmode.c
ramstage-y += bootmode.c
verstage-y += bootmode.c
decompressor-y += halt.c
bootblock-y += halt.c
romstage-y += halt.c
ramstage-y += halt.c
smm-y += halt.c
decompressor-y += reset.c
bootblock-y += reset.c
verstage-y += reset.c
romstage-y += reset.c
postcar-y += reset.c
ramstage-y += reset.c
smm-y += reset.c
decompressor-y += string.c
bootblock-y += string.c
verstage-y += string.c
romstage-y += string.c
postcar-y += string.c
ramstage-y += string.c
smm-y += string.c
decompressor-y += crc_byte.c
bootblock-y += crc_byte.c
verstage-y += crc_byte.c
romstage-y += crc_byte.c
postcar-y += crc_byte.c
ramstage-y += crc_byte.c
smm-y += crc_byte.c
romstage-y += xxhash.c
ramstage-y += xxhash.c
postcar-y += bootmode.c
postcar-y += boot_device.c
postcar-y += cbfs.c
postcar-y += delay.c
postcar-y += fmap.c
postcar-y += gcc.c
postcar-y += halt.c
postcar-y += libgcc.c
postcar-$(CONFIG_COMPRESS_RAMSTAGE_LZMA) += lzma.c lzmadecode.c
postcar-y += memchr.c
postcar-y += memcmp.c
postcar-y += prog_loaders.c
postcar-y += prog_ops.c
postcar-y += rmodule.c
postcar-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
postcar-$(CONFIG_GENERIC_UDELAY) += timer.c
# Use program.ld for all the platforms which use C fo the bootblock.
bootblock-y += program.ld
decompressor-y += program.ld
postcar-y += program.ld
romstage-y += program.ld
ramstage-y += program.ld
verstage-y += program.ld
ifeq ($(CONFIG_RELOCATABLE_MODULES),y)
ramstage-y += rmodule.c
romstage-y += rmodule.c
RMODULE_LDFLAGS := -z defs -Bsymbolic
# rmodule_link_rules is a function that should be called with:
# (1) the object name to link
# (2) the dependencies
# (3) arch for which the rmodules are to be linked
# It will create the necessary Make rules to create a rmodule. The resulting
# rmdoule is named $(1).rmod
define rmodule_link
$(strip $(1)): $(strip $(2)) $$(COMPILER_RT_rmodules_$(3)) $(call src-to-obj,rmodules_$(3),src/lib/rmodule.ld) | $$(RMODTOOL)
$$(LD_rmodules_$(3)) $$(LDFLAGS_rmodules_$(3)) $(RMODULE_LDFLAGS) $($(1)-ldflags) -T $(call src-to-obj,rmodules_$(3),src/lib/rmodule.ld) -o $$@ --whole-archive --start-group $(filter-out %.ld,$(2)) --end-group
$$(NM_rmodules_$(3)) -n $$@ > $$(basename $$@).map
endef
endif
$(objcbfs)/%.debug.rmod: $(objcbfs)/%.debug | $(RMODTOOL)
$(RMODTOOL) -i $< -o $@
$(obj)/%.elf.rmod: $(obj)/%.elf | $(RMODTOOL)
$(RMODTOOL) -i $< -o $@
romstage-$(CONFIG_ROMSTAGE_ADA) += cb.ads
ramstage-$(CONFIG_RAMSTAGE_ADA) += cb.ads
ifneq (,$(filter y, $(CONFIG_RAMSTAGE_LIBHWBASE) $(CONFIG_ROMSTAGE_LIBHWBASE)))
to-ada-hex = $(eval $(1) := 16\\\#$(patsubst 0x%,%,$($(1)))\\\#)
$(call to-ada-hex,CONFIG_HWBASE_DEFAULT_MMCONF)
libhwbase-stages = $(foreach stage, romstage ramstage, \
$(if $(filter y,$(CONFIG_$(call toupper,$(stage))_LIBHWBASE)),$(stage)))
$(call add-special-class,hw)
hw-handler +=$(foreach stage, $(libhwbase-stages), \
$(eval $(stage)-srcs += $$(addprefix $(1),$(2))))
$(call add-special-class,hw-gen)
hw-gen-handler = \
$(eval additional-dirs += $(dir $(2))) \
$(foreach stage, $(libhwbase-stages), \
$(eval $(stage)-srcs += $(2)) \
$(eval $(stage)-ads-deps += $(2)) \
$(eval $(stage)-adb-deps += $(2))) \
$(eval $(2): $(obj)/config.h)
subdirs-y += ../../3rdparty/libhwbase
$(foreach stage,$(libhwbase-stages), \
$(eval $(stage)-$(CONFIG_HAVE_MONOTONIC_TIMER) += hw-time-timer.adb))
endif # CONFIG_ROMSTAGE_LIBHWBASE || CONFIG_RAMSTAGE_LIBHWBASE
romstage-y += spd_bin.c
ifeq ($(CONFIG_HAVE_SPD_IN_CBFS),y)
LIB_SPD_BIN = $(obj)/spd.bin
LIB_SPD_DEPS = $(foreach f, $(SPD_SOURCES), src/mainboard/$(MAINBOARDDIR)/spd/$(f).spd.hex)
# Include spd ROM data
$(LIB_SPD_BIN): $(LIB_SPD_DEPS)
test -n "$(SPD_SOURCES)" || \
(echo "HAVE_SPD_IN_CBFS is set but SPD_SOURCES is empty" && exit 1)
test -n "$(LIB_SPD_DEPS)" || \
(echo "SPD_SOURCES is set but no SPD file was found" && exit 1)
if [ "$(SPD_SOURCES)" = "placeholder" ]; then \
printf '\0'; \
else \
for f in $(LIB_SPD_DEPS); do \
if [ ! -f $$f ]; then \
echo "File not found: $$f" >&2; \
exit 1; \
fi; \
for c in $$(cat $$f | grep --binary-files=text -v ^#); \
do printf $$(printf '\\%o' 0x$$c); \
done; \
done; \
fi > $@
cbfs-files-y += spd.bin
spd.bin-file := $(LIB_SPD_BIN)
spd.bin-type := spd
endif
ramstage-y += uuid.c
romstage-$(CONFIG_SPD_CACHE_IN_FMAP) += spd_cache.c
cbfs-files-y += cbfs_master_header
cbfs_master_header-file := cbfs_master_header.c:struct
cbfs_master_header-type := "cbfs header"
cbfs_master_header-position := 0
bootblock-$(CONFIG_ARCH_X86) += master_header_pointer.c
NEED_CBFS_POINTER=
ifneq ($(CONFIG_ARCH_X86),y)
NEED_CBFS_POINTER=y
endif
ifneq ($(CONFIG_BOOTBLOCK_IN_CBFS),y)
NEED_CBFS_POINTER=y
endif
cbfs-files-$(NEED_CBFS_POINTER) += header_pointer
header_pointer-file := master_header_pointer.c:struct
header_pointer-position := -4
header_pointer-type := "cbfs header"
romstage-y += ux_locales.c