1# 2# Copyright (c) 2025-2026, Advanced Micro Devices, Inc. All rights reserved. 3# 4# SPDX-License-Identifier: BSD-3-Clause 5# 6# Custom Package Integration for AMD Platforms 7# 8 9# Flag to track if custom package is included 10CUSTOM_PKG_INCLUDED := 0 11 12# ============================================================================ 13# Custom Package Integration (supports multiple packages) 14# ============================================================================ 15# This framework: 16# 1. Includes each package's custom_pkg.mk for build rules and flags 17# 2. Discovers custom_pkg.ld.S files for linker script consolidation 18# 3. Prepares them for preprocessing into the final plat.ld.S 19# 20# Each package provides: 21# - custom_pkg.mk: Build configuration, source files, and package-specific macros 22# - custom_pkg.ld.S: Memory layout (MEMORY regions and SECTIONS) 23# ============================================================================ 24 25ifdef CUSTOM_PKG_PATH 26 # Split CUSTOM_PKG_PATH by space, colon, or semicolon to support multiple paths 27 _CUSTOM_PKG_PATHS := $(strip $(subst ;, ,$(subst :, ,$(CUSTOM_PKG_PATH)))) 28 # Normalize to absolute paths to handle both relative and absolute inputs 29 _CUSTOM_PKG_PATHS_ABS := $(foreach pkg_path,$(_CUSTOM_PKG_PATHS),$(abspath $(pkg_path))) 30 31 # Include each package's custom_pkg.mk 32 $(foreach pkg_path,$(_CUSTOM_PKG_PATHS_ABS), \ 33 $(eval PKG_PATH_CLEAN := $(strip $(pkg_path))) \ 34 $(eval PKG_MK := $(PKG_PATH_CLEAN)/custom_pkg.mk) \ 35 $(if $(wildcard $(PKG_MK)), \ 36 $(eval include $(PKG_MK)) \ 37 $(eval CUSTOM_PKG_INCLUDED := 1) \ 38 $(info Including custom package from: $(PKG_PATH_CLEAN)), \ 39 $(error CUSTOM_PKG_PATH contains $(PKG_PATH_CLEAN) but custom_pkg.mk not found) \ 40 ) \ 41 ) 42 43 # Find all custom_pkg.ld.S files in package directories (absolute paths) 44 CUSTOM_PKG_LD_SCRIPTS := $(wildcard $(addsuffix /custom_pkg.ld.S,$(_CUSTOM_PKG_PATHS_ABS))) 45 46 # Auto-discover package linker script (prefer first hit) and set TF-A flag 47 $(foreach pkg_path,$(_CUSTOM_PKG_PATHS_ABS), \ 48 $(eval _PKG_LS := $(wildcard $(pkg_path)/plat.ld.S $(pkg_path)/inc/plat.ld.S)) \ 49 $(if $(_PKG_LS), \ 50 $(if $(PLAT_EXTRA_LD_SCRIPT_PATH),, \ 51 $(eval PLAT_EXTRA_LD_SCRIPT_PATH := $(word 1,$(_PKG_LS))) \ 52 $(info Auto-discovered linker script: $(PLAT_EXTRA_LD_SCRIPT_PATH)) \ 53 ) \ 54 ) \ 55 ) 56 57 # If a package linker script is present, export the TF-A define (value = 1) 58 ifdef PLAT_EXTRA_LD_SCRIPT_PATH 59 PLAT_EXTRA_LD_SCRIPT := 1 60 $(eval $(call add_define_val,PLAT_EXTRA_LD_SCRIPT,1)) 61 $(info Enabling PLAT_EXTRA_LD_SCRIPT=1 (script: $(PLAT_EXTRA_LD_SCRIPT_PATH))) 62 endif 63 64 ifneq ($(CUSTOM_PKG_LD_SCRIPTS),) 65 $(info Custom Package Linker Scripts Found:) 66 $(foreach _LS,$(CUSTOM_PKG_LD_SCRIPTS),$(info - $(_LS))) 67 68 # Generate paths for preprocessed scripts (.ld.S -> .ld.pp) 69 CUSTOM_PKG_LD_SCRIPTS_PP := $(patsubst %.ld.S,%.ld.pp,$(CUSTOM_PKG_LD_SCRIPTS)) 70 71 # Collect include directories from all custom packages for linker script preprocessing 72 CUSTOM_PKG_LD_INCLUDES := $(foreach pkg_path,$(_CUSTOM_PKG_PATHS_ABS), \ 73 $(if $(wildcard $(pkg_path)/inc),-I$(pkg_path)/inc) \ 74 $(if $(wildcard $(pkg_path)/include),-I$(pkg_path)/include)) 75 76 # Make them available to linker script generation 77 export CUSTOM_PKG_LD_SCRIPTS_PP 78 export CUSTOM_PKG_LD_INCLUDES 79 else 80 $(info No custom_pkg.ld.S files found - using platform defaults) 81 CUSTOM_PKG_LD_INCLUDES := 82 endif 83endif 84 85# ============================================================================ 86# Note: Package-specific macros are defined in each package's custom_pkg.mk 87# and passed to preprocessor via ASFLAGS 88# ============================================================================ 89 90# ============================================================================ 91# Custom Package Linker Script Preprocessing 92# ============================================================================ 93# This handles preprocessing of custom package linker scripts 94# and generation of the final consolidated plat.ld.S 95# 96# Two-stage preprocessing using TF-A's standard C preprocessor: 97# Stage 1: Preprocess custom_pkg.ld.S files 98# Input: custom_pkg.ld.S (contains package-specific macros) 99# Process: $($(ARCH)-cpp) -E -P with ASFLAGS containing package macro definitions 100# Output: custom_pkg.ld.pp (macros expanded) 101# 102# Stage 2: Preprocess template with all preprocessed scripts included 103# Input: plat.ld.S.tpl (contains #include CUSTOM_PKG_LD_SCRIPTS_PP) 104# Process: $($(ARCH)-cpp) -E -P with all macro definitions 105# Output: build/versal2/release/bl31/plat.ld.S (final linker script) 106# ============================================================================ 107 108# Directories 109BUILD_DIR := $(shell pwd)/build/$(PLAT) 110BL31_BUILD_DIR := $(BUILD_DIR)/bl31 111 112# Linker script template and output 113PLAT_LD_TEMPLATE := plat/amd/versal2/plat.ld.S.tpl 114PLAT_LD_SCRIPT := $(BL31_BUILD_DIR)/plat.ld.S 115 116# Rule 1: Preprocess individual custom_pkg.ld.S files 117# Uses TF-A's standard architecture-specific C preprocessor 118# Includes custom package include directories for proper header resolution 119%.ld.pp: %.ld.S 120 @echo " PP $<" 121 $(Q)$($(ARCH)-cpp) -E -P $(CUSTOM_PKG_LD_INCLUDES) $(ASFLAGS) -o $@ $< 122 123# Rule 2: Generate final plat.ld.S from template + preprocessed scripts 124# Uses TF-A's standard architecture-specific C preprocessor 125# Includes custom package include directories for proper header resolution 126$(PLAT_LD_SCRIPT): $(PLAT_LD_TEMPLATE) $(CUSTOM_PKG_LD_SCRIPTS_PP) 127 @echo " GEN $@" 128 @mkdir -p $(BL31_BUILD_DIR) 129 $(Q)$($(ARCH)-cpp) -E -P \ 130 -DCUSTOM_PKG_LD_SCRIPTS_PP="$(CUSTOM_PKG_LD_SCRIPTS_PP)" \ 131 $(CUSTOM_PKG_LD_INCLUDES) \ 132 $(ASFLAGS) \ 133 -o $@ \ 134 $(PLAT_LD_TEMPLATE) 135 136# Ensure final linker script exists before linking BL31 137bl31: $(PLAT_LD_SCRIPT) 138 139# ============================================================================ 140# Build Summary 141# ============================================================================ 142$(info ============================================================) 143$(info Custom Package Configuration:) 144$(info Custom Package: $(if $(filter 1,$(CUSTOM_PKG_INCLUDED)),ENABLED,DISABLED)) 145$(if $(filter 1,$(CUSTOM_PKG_INCLUDED)), \ 146 $(foreach pkg_path,$(_CUSTOM_PKG_PATHS_ABS), \ 147 $(info - $(strip $(pkg_path))) \ 148 ) \ 149) 150$(info ============================================================) 151