Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@
branch = strix_2024.2
[submodule "third_party/bootgen"]
path = third_party/bootgen
url = https://github.com/jgmelber/bootgen.git
branch = c-api-support
url = https://github.com/Xilinx/bootgen.git
[submodule "third_party/aie_api"]
path = third_party/aie_api
url = https://github.com/Xilinx/aie_api
2 changes: 1 addition & 1 deletion third_party/bootgen
Submodule bootgen updated 303 files
2 changes: 1 addition & 1 deletion tools/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ add_subdirectory(aie-translate)
if(AIE_BUILD_VISUALIZE)
add_subdirectory(aie-visualize)
endif()
add_subdirectory(aiecc)
add_subdirectory(bootgen)
add_subdirectory(aiecc)
if(AIE_BUILD_CHESS_CLANG)
add_subdirectory(chess-clang)
endif()
211 changes: 123 additions & 88 deletions tools/bootgen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,95 +3,71 @@
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

set(BOOTGEN_SOURCE ${PROJECT_SOURCE_DIR}/third_party/bootgen)
set(libsources
cdo-alloc.c
cdo-binary.c
cdo-command.c
cdo-load.c
cdo-metadata.c
cdo-npi.c
cdo-overlay.c
cdo-raw.c
cdo-source.c
cJSON.c
authentication.cpp
authentication-versal.cpp
authentication-zynq.cpp
authentication-zynqmp.cpp
authkeys.cpp
authkeys-versal.cpp
bifoptions.cpp
bif.tab.cpp
bif.yy.cpp
binary.cpp
binary-versal.cpp
binfile.cpp
bitutils.cpp
bitutils-versal.cpp
bootheader.cpp
bootheader-versal.cpp
bootheader-zynq.cpp
bootheader-zynqmp.cpp
bootimage.cpp
bootimage-versal.cpp
bootimage-zynq.cpp
bootimage-zynqmp.cpp
checksum.cpp
checksum-versal.cpp
cmdoptions.tab.cpp
cmdoptions.yy.cpp
elftools.cpp
encryption.cpp
encryption-versal.cpp
encryption-versalnet.cpp
encryption-zynq.cpp
encryption-zynqmp.cpp
encryptutils.cpp
hash.cpp
imageheadertable.cpp
imageheadertable-versal.cpp
imageheadertable-zynq.cpp
imageheadertable-zynqmp.cpp
kdf.cpp
Keccak-compact.cpp
Keccak-compact-versal.cpp
logger.cpp
# main.cpp
mcsfile.cpp
options.cpp
outputfile.cpp
outputfile-versal.cpp
parsing.cpp
partition.cpp
partitionheadertable.cpp
partitionheadertable-versal.cpp
partitionheadertable-zynq.cpp
partitionheadertable-zynqmp.cpp
partition-versal.cpp
postprocess.cpp
readimage.cpp
readimage-versal.cpp
readimage-zynq.cpp
readimage-zynqmp.cpp
reginit.cpp
reginit.tab.cpp
reginit.yy.cpp
verifyimage-versal.cpp
verifyimage-zynqmp.cpp
bootgen_c_api.cpp)
list(TRANSFORM libsources PREPEND ${BOOTGEN_SOURCE}/)

# Upstream (xilinx_v2026.1) splits sources into per-architecture <dir>/src
# trees; glob each one, matching upstream's own Makefile.
set(bootgen_src_dirs
common
spartanup
versal
versal_2ve_2vm
zynq
zynqmp
utils)
set(libsources)
foreach(dir ${bootgen_src_dirs})
file(GLOB dir_sources CONFIGURE_DEPENDS
${BOOTGEN_SOURCE}/${dir}/src/*.cpp ${BOOTGEN_SOURCE}/${dir}/src/*.c)
list(APPEND libsources ${dir_sources})
Comment thread
jgmelber marked this conversation as resolved.
endforeach()
# main.cpp holds the CLI entry point and is only used by the bootgen
# executable below, not by bootgen-lib.
list(REMOVE_ITEM libsources ${BOOTGEN_SOURCE}/common/src/main.cpp)
# Pregenerated bison/flex grammar sources.
list(APPEND libsources
${BOOTGEN_SOURCE}/bisonflex/bif.tab.cpp
${BOOTGEN_SOURCE}/bisonflex/bif.yy.cpp
${BOOTGEN_SOURCE}/bisonflex/cmdoptions.tab.cpp
${BOOTGEN_SOURCE}/bisonflex/cmdoptions.yy.cpp
${BOOTGEN_SOURCE}/bisonflex/reginit.tab.cpp
${BOOTGEN_SOURCE}/bisonflex/reginit.yy.cpp)
# C API for exception-safe PDI generation, so tools like aiecc can call
# bootgen as a library instead of shelling out. Lives here rather than in
# the submodule since it's mlir-aie-specific and only adds new files (no
# upstream source is touched), letting third_party/bootgen track upstream
# Xilinx/bootgen directly.
list(APPEND libsources ${CMAKE_CURRENT_SOURCE_DIR}/bootgen_c_api.cpp)

set(bootgen_include_dirs
${BOOTGEN_SOURCE}/bisonflex
${BOOTGEN_SOURCE}/common/include
${BOOTGEN_SOURCE}/spartanup/include
${BOOTGEN_SOURCE}/versal/include
${BOOTGEN_SOURCE}/versal_2ve_2vm/include
${BOOTGEN_SOURCE}/zynq/include
${BOOTGEN_SOURCE}/zynqmp/include
${BOOTGEN_SOURCE}/utils/include
${BOOTGEN_SOURCE}/lms-hash-sigs
${BOOTGEN_SOURCE}/win_include)

# malloc.h is deprecated and should not be used
# https://stackoverflow.com/a/56463133
# If you want to use malloc, then include stdlib.h
file(READ ${BOOTGEN_SOURCE}/cdo-npi.c FILE_CONTENTS)
file(READ ${BOOTGEN_SOURCE}/utils/src/cdo-npi.c FILE_CONTENTS)
string(REPLACE "#include <malloc.h>" "" FILE_CONTENTS "${FILE_CONTENTS}")
file(WRITE ${BOOTGEN_SOURCE}/cdo-npi.c "${FILE_CONTENTS}")
file(WRITE ${BOOTGEN_SOURCE}/utils/src/cdo-npi.c "${FILE_CONTENTS}")

file(READ ${BOOTGEN_SOURCE}/cdo-alloc.c FILE_CONTENTS)
file(READ ${BOOTGEN_SOURCE}/utils/src/cdo-alloc.c FILE_CONTENTS)
string(REPLACE "#include <malloc.h>" "" FILE_CONTENTS "${FILE_CONTENTS}")
file(WRITE ${BOOTGEN_SOURCE}/cdo-alloc.c "${FILE_CONTENTS}")
file(WRITE ${BOOTGEN_SOURCE}/utils/src/cdo-alloc.c "${FILE_CONTENTS}")

# Strip the per-CDO-file "Generating: ..." printf: cdo_driver_mlir_aie is
# called directly (not via the bootgen executable) by mlir-aie's own CDO
# generation, once per emitted CDO file, and this pollutes aiecc's output.
file(READ ${BOOTGEN_SOURCE}/cdo-driver/cdo_driver.c FILE_CONTENTS)
string(REGEX REPLACE "\n[ \t]*printf\\(\"Generating: %s\\\\n\", cdoFileName\\);"
"" FILE_CONTENTS "${FILE_CONTENTS}")
file(WRITE ${BOOTGEN_SOURCE}/cdo-driver/cdo_driver.c "${FILE_CONTENTS}")

find_package(OpenSSL REQUIRED)
if (OPENSSL_FOUND)
Expand All @@ -101,10 +77,66 @@ else()
message (FATAL_ERROR "OpenSSL Not found.")
endif()

find_package(Threads REQUIRED)

# since we explicitly link OpenSSL::applink
file(READ ${BOOTGEN_SOURCE}/main.cpp FILE_CONTENTS)
file(READ ${BOOTGEN_SOURCE}/common/src/main.cpp FILE_CONTENTS)
string(REPLACE "#include \"openssl/ms/applink.c\"" "" FILE_CONTENTS "${FILE_CONTENTS}")
file(WRITE ${BOOTGEN_SOURCE}/main.cpp "${FILE_CONTENTS}")
file(WRITE ${BOOTGEN_SOURCE}/common/src/main.cpp "${FILE_CONTENTS}")

# Vendored LMS/HSS post-quantum signature library upstream added for newer
# secure-boot support; built as a static lib instead of shelling out to its
# own Makefile.
#
# Only the pthread threading backend is vendored (upstream's Makefile is
# Linux-only). MSVC has no <pthread.h>, so fall back to our own
# single-threaded implementation of the same API (hss_thread.h allows a
# NULL/0 collection as a valid non-threaded mode).
set(lms_hash_sigs_dir ${BOOTGEN_SOURCE}/lms-hash-sigs)
if(CMAKE_USE_PTHREADS_INIT)
set(bootgen_hss_thread_source ${lms_hash_sigs_dir}/hss_thread_pthread.c)
else()
set(bootgen_hss_thread_source ${CMAKE_CURRENT_SOURCE_DIR}/hss_thread_single.c)
endif()
add_library(bootgen-lms-hash-sigs STATIC
${lms_hash_sigs_dir}/endian.c
${lms_hash_sigs_dir}/fips202.c
${lms_hash_sigs_dir}/hss.c
${lms_hash_sigs_dir}/hss_alloc.c
${lms_hash_sigs_dir}/hss_aux.c
${lms_hash_sigs_dir}/hss_common.c
${lms_hash_sigs_dir}/hss_compute.c
${lms_hash_sigs_dir}/hss_derive.c
${lms_hash_sigs_dir}/hss_generate.c
${lms_hash_sigs_dir}/hss_keygen.c
${lms_hash_sigs_dir}/hss_param.c
${lms_hash_sigs_dir}/hss_reserve.c
${lms_hash_sigs_dir}/hss_sign.c
${lms_hash_sigs_dir}/hss_sign_inc.c
${bootgen_hss_thread_source}
${lms_hash_sigs_dir}/hss_verify.c
${lms_hash_sigs_dir}/hss_verify_inc.c
${lms_hash_sigs_dir}/hss_zeroize.c
${lms_hash_sigs_dir}/lm_common.c
${lms_hash_sigs_dir}/lm_ots_common.c
${lms_hash_sigs_dir}/lm_ots_sign.c
${lms_hash_sigs_dir}/lm_ots_verify.c
${lms_hash_sigs_dir}/lm_verify.c
${lms_hash_sigs_dir}/lms_hash.c
${lms_hash_sigs_dir}/lms_keys.c
${lms_hash_sigs_dir}/lms_sign.c
${lms_hash_sigs_dir}/sha256.c)
set_target_properties(bootgen-lms-hash-sigs PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_include_directories(bootgen-lms-hash-sigs PRIVATE ${lms_hash_sigs_dir} ${OPENSSL_INCLUDE_DIR})
# PUBLIC: static-lib consumers need these transitively on their link line.
target_link_libraries(bootgen-lms-hash-sigs PUBLIC OpenSSL::Crypto Threads::Threads)
if(CMAKE_C_COMPILER_ID MATCHES "Clang|GNU")
Comment thread
jgmelber marked this conversation as resolved.
target_compile_options(bootgen-lms-hash-sigs PRIVATE
-Wno-deprecated-declarations
-Wno-sign-compare
-Wno-type-limits
-Wno-unused)
endif()

add_library(bootgen-lib STATIC ${libsources})
# bootgen must be compiled with PIE/PIC, irrespective of the remainder of
Expand All @@ -121,6 +153,7 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
-Wno-deprecated-register
-Wno-dynamic-class-memaccess
-Wno-implicit-fallthrough
-Wno-incompatible-pointer-types
-Wno-incompatible-pointer-types-discards-qualifiers
Comment thread
jgmelber marked this conversation as resolved.
Outdated
-Wno-misleading-indentation
-Wno-non-virtual-dtor
Expand All @@ -144,22 +177,24 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
target_compile_options(bootgen-lib PRIVATE /wd4996 /wd4840 /wd4005 /wd5033)
endif()
target_compile_options(bootgen-lib PRIVATE ${bootgen_warning_ignores})
target_include_directories(bootgen-lib PRIVATE ${BOOTGEN_SOURCE} ${OPENSSL_INCLUDE_DIR})
target_include_directories(bootgen-lib PRIVATE ${bootgen_include_dirs} ${OPENSSL_INCLUDE_DIR})
# Make C API header available publicly
target_include_directories(bootgen-lib PUBLIC
$<BUILD_INTERFACE:${BOOTGEN_SOURCE}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>)
# PUBLIC: same reason as bootgen-lms-hash-sigs above.
target_link_libraries(bootgen-lib PUBLIC bootgen-lms-hash-sigs Threads::Threads)
install(
TARGETS bootgen-lib
DESTINATION lib
EXPORT bootgen-lib)
install(
FILES ${BOOTGEN_SOURCE}/bootgen_c_api.h
FILES ${CMAKE_CURRENT_SOURCE_DIR}/bootgen_c_api.h
DESTINATION include)

add_executable(bootgen ${BOOTGEN_SOURCE}/main.cpp)
add_executable(bootgen ${BOOTGEN_SOURCE}/common/src/main.cpp)
set_target_properties(bootgen PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_include_directories(bootgen PUBLIC ${BOOTGEN_SOURCE} ${OPENSSL_INCLUDE_DIR}
target_include_directories(bootgen PUBLIC ${bootgen_include_dirs} ${OPENSSL_INCLUDE_DIR}
${CMAKE_CURRENT_BINARY_DIR}/include)
target_compile_options(bootgen PRIVATE ${bootgen_warning_ignores})
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
Expand Down
91 changes: 91 additions & 0 deletions tools/bootgen/bootgen_c_api.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/******************************************************************************
* Copyright 2024-2026 Advanced Micro Devices, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/

#include "bootgen_c_api.h"
#include "bootimage.h"
Comment thread
jgmelber marked this conversation as resolved.
#include "options.h"
#include "bootgenexception.h"
Comment thread
jgmelber marked this conversation as resolved.
Outdated

#include <cstring>
#include <string>

// Helper to safely copy error message to output buffer
static void copy_error_message(char *error_msg, int error_msg_size,
const char *msg) {
if (error_msg && error_msg_size > 0) {
std::strncpy(error_msg, msg, error_msg_size - 1);
error_msg[error_msg_size - 1] = '\0';
}
}

int bootgen_generate_pdi(const char *bif_path, const char *pdi_path,
enum bootgen_arch_type arch, int overwrite,
char *error_msg, int error_msg_size) {
// Validate inputs
if (!bif_path || !pdi_path) {
copy_error_message(error_msg, error_msg_size,
"Invalid NULL path argument");
Comment thread
jgmelber marked this conversation as resolved.
Outdated
return BOOTGEN_ERROR_INVALID_BIF;
}
Comment thread
jgmelber marked this conversation as resolved.

// Map C enum to C++ enum
Arch::Type cppArch;
switch (arch) {
case BOOTGEN_ARCH_ZYNQ:
cppArch = Arch::ZYNQ;
break;
case BOOTGEN_ARCH_ZYNQMP:
cppArch = Arch::ZYNQMP;
break;
case BOOTGEN_ARCH_FPGA:
cppArch = Arch::FPGA;
break;
case BOOTGEN_ARCH_VERSAL:
cppArch = Arch::VERSAL;
break;
case BOOTGEN_ARCH_VERSALNET:
cppArch = Arch::VERSALNET;
break;
default:
copy_error_message(error_msg, error_msg_size, "Invalid architecture type");
return BOOTGEN_ERROR_INVALID_ARCH;
}

try {
Options options;
options.SetArchType(cppArch);
options.SetBifFilename(std::string(bif_path));
options.InsertOutputFileNames(std::string(pdi_path));
if (overwrite) {
options.SetOverwrite(true);
}

std::string bifStr(bif_path);
BIF_File bif(bifStr);
bif.Process(options);

return BOOTGEN_SUCCESS;
} catch (const BootGenExceptionClass &e) {
copy_error_message(error_msg, error_msg_size, e.what());
return BOOTGEN_ERROR_PROCESSING_FAILED;
} catch (const std::exception &e) {
copy_error_message(error_msg, error_msg_size, e.what());
return BOOTGEN_ERROR_INTERNAL;
} catch (...) {
copy_error_message(error_msg, error_msg_size, "Unknown error occurred");
return BOOTGEN_ERROR_INTERNAL;
}
}
Loading
Loading