diff --git a/CMakeLists.txt b/CMakeLists.txt index 790f64daa19..d6d3fed69a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -194,6 +194,14 @@ function(mbed_generate_bin_hex target) "executable:" VERBATIM ) + + if(TARGET mbed-post-build-bin) + add_custom_target(mbed-post-build + ALL + DEPENDS + mbed-post-build-bin + ) + endif() endfunction() # diff --git a/targets/TARGET_Cypress/TARGET_PSOC6/TARGET_CY8CKIT064B0S2_4343W/CMakeLists.txt b/targets/TARGET_Cypress/TARGET_PSOC6/TARGET_CY8CKIT064B0S2_4343W/CMakeLists.txt index 6c456babc8d..583879e5e30 100644 --- a/targets/TARGET_Cypress/TARGET_PSOC6/TARGET_CY8CKIT064B0S2_4343W/CMakeLists.txt +++ b/targets/TARGET_Cypress/TARGET_PSOC6/TARGET_CY8CKIT064B0S2_4343W/CMakeLists.txt @@ -1,6 +1,8 @@ # Copyright (c) 2020 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 +include(${MBED_PATH}/targets/TARGET_Cypress/scripts/mbed_set_post_build_cypress.cmake) + if("BSP_DESIGN_MODUS" IN_LIST MBED_TARGET_LABELS) target_include_directories(mbed-core INTERFACE @@ -58,3 +60,13 @@ target_sources(mbed-core ${SYSTEM_SOURCE} ${STARTUP_FILE} ) + +mbed_post_build_psoc6_sign_image( + "psoc6_02_cm0p_secure.hex" + "CY8CKIT064B0S2_4343W" + "policy_single_CM0_CM4.json" + "single_image" + "1" + "16" + "${MBED_PATH}/targets/TARGET_Cypress/TARGET_PSOC6/TARGET_CY8CKIT064B0S2_4343W/device/COMPONENT_CM4/hex/psoc6_02_cm0p_secure.hex" +) diff --git a/targets/TARGET_Cypress/TARGET_PSOC6/TARGET_CYSBSYSKIT_01/CMakeLists.txt b/targets/TARGET_Cypress/TARGET_PSOC6/TARGET_CYSBSYSKIT_01/CMakeLists.txt index 356f5696f30..bc6c3392c42 100644 --- a/targets/TARGET_Cypress/TARGET_PSOC6/TARGET_CYSBSYSKIT_01/CMakeLists.txt +++ b/targets/TARGET_Cypress/TARGET_PSOC6/TARGET_CYSBSYSKIT_01/CMakeLists.txt @@ -1,6 +1,8 @@ # Copyright (c) 2020 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 +include(${MBED_PATH}/targets/TARGET_Cypress/scripts/mbed_set_post_build_cypress.cmake) + if("BSP_DESIGN_MODUS" IN_LIST MBED_TARGET_LABELS) target_include_directories(mbed-core INTERFACE @@ -47,3 +49,5 @@ target_sources(mbed-core ${SYSTEM_SOURCE} ${STARTUP_FILE} ) + +mbed_post_build_psoc6_merge_hex() diff --git a/targets/TARGET_Cypress/TARGET_PSOC6/TARGET_CYTFM_064B0S2_4343W/CMakeLists.txt b/targets/TARGET_Cypress/TARGET_PSOC6/TARGET_CYTFM_064B0S2_4343W/CMakeLists.txt index c4e238d0163..06db911fc04 100644 --- a/targets/TARGET_Cypress/TARGET_PSOC6/TARGET_CYTFM_064B0S2_4343W/CMakeLists.txt +++ b/targets/TARGET_Cypress/TARGET_PSOC6/TARGET_CYTFM_064B0S2_4343W/CMakeLists.txt @@ -1,6 +1,8 @@ # Copyright (c) 2020 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 +include(${MBED_PATH}/targets/TARGET_Cypress/scripts/mbed_set_post_build_cypress.cmake) + if("BSP_DESIGN_MODUS" IN_LIST MBED_TARGET_LABELS) target_include_directories(mbed-core INTERFACE @@ -62,3 +64,13 @@ target_sources(mbed-core ${SYSTEM_SOURCE} ${STARTUP_FILE} ) + +mbed_post_build_psoc6_sign_image( + "tfm_s.hex" + "CYTFM_064B0S2_4343W" + "policy_multi_CM0_CM4_tfm.json" + "multi_image" + "1" + "16" + ${MBED_PATH}/targets/TARGET_Cypress/TARGET_PSOC6/TARGET_CYTFM_064B0S2_4343W/COMPONENT_TFM_S_FW/tfm_s.hex +) diff --git a/targets/TARGET_Cypress/scripts/PSOC6.py b/targets/TARGET_Cypress/scripts/PSOC6.py new file mode 100644 index 00000000000..75cf003fd9e --- /dev/null +++ b/targets/TARGET_Cypress/scripts/PSOC6.py @@ -0,0 +1,393 @@ +# +# Copyright (c) 2017-2018 Future Electronics +# Copyright (c) 2018-2019 Cypress Semiconductor Corporation +# Copyright (c) 2020-2021 Arm Limited +# +# 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. +# + +import argparse +import logging +import os +import sys +import subprocess +from array import array +from struct import (pack, unpack) +from shutil import copy2 +import json +from intelhex import IntelHex, hex2bin, bin2hex +from pathlib import Path + +SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) +MBED_OS_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, os.pardir, os.pardir, os.pardir)) + +# The size of the program data in Cypress HEX files is limited to 0x80000000 +# Higher addresses contain additional metadata (chip protection, eFuse data, etc..) +CY_PROGRAM_SIZE = 0x80000000 + +# The starting address of the program data checksum section +CY_CHECKSUM_ADDR = 0x90300000 + +# The starting address of the .cymeta section (12 bytes) +# Additional metadata include silicon revision, Silicon/JTAG ID, etc. +CY_META_ADDR = 0x90500000 + +# The address of the silicon ID (4 bytes) +CY_META_SILICON_ID_ADDR = 0x90500002 + +# The address of the metadata checksum (4 bytes) +CY_META_CHECKSUM_ADDR = 0x90500008 + +# Secure Boot defines +MCUBOOT_HEADER_SIZE = 1024 +SPE_IMAGE_ID = 1 +NSPE_IMAGE_ID = 16 +SMIF_MEM_MAP_START = 0x18000000 + +class AddSignatureError(Exception): + """ A simple class that represents all the exceptions associated with + adding signature to Secure Boot image + """ + +# Base class for all configuration exceptions +class ConfigException(Exception): + """Config system only exception. Makes it easier to distinguish config + errors""" + + +# Patch Cypress hex file: +# - update checksum +# - update metadata +# - align regions to page (256 bytes) boundary +def patch(message_func, ihex, hexf, align=256): + update_checksum = False + update_metadata = False + + # calculate checksum of the program section, detect metadata + checksum = 0 + for start, end in ihex.segments(): + if start == CY_CHECKSUM_ADDR: + # checksum section found in the original hex + update_checksum = True + if start == CY_META_ADDR: + # metadata section found in the original hex + update_metadata = True + if start >= CY_PROGRAM_SIZE: + continue + segment = ihex.tobinarray(start, end) + checksum += sum(segment) + + # only update checksum if it was found in the original hex + if update_checksum: + lowchecksum = checksum & 0x0FFFF + message_func("Calculated checksum for %s is 0x%04x" % (hexf, lowchecksum)) + + checksum_str = pack('>H', lowchecksum) + ihex.frombytes(array('B', checksum_str), offset=CY_CHECKSUM_ADDR) + + # only update metadata if it was found in the original hex + if update_metadata: + signature = unpack('>L', ihex.tobinstr(start=CY_META_SILICON_ID_ADDR, size=4))[0] + sigcheck = pack('>L', (checksum + signature) & 0x0FFFF) + ihex.frombytes(array('B', sigcheck), offset=CY_META_CHECKSUM_ADDR) + + # align flash segments + align_mask = align - 1 + alignments = IntelHex() + for start, end in ihex.segments(): + if start >= CY_PROGRAM_SIZE: + continue + aligned_start = start & ~align_mask + if start != aligned_start: + message_func("Aligning start from 0x%x to 0x%x" % (start, aligned_start)) + alignments.frombytes(ihex.tobinarray(aligned_start, start - 1), aligned_start) + aligned_end = end & ~align_mask + if end != aligned_end: + aligned_end += align + message_func("Aligning end from 0x%x to 0x%x" % (end, aligned_end)) + alignments.frombytes(ihex.tobinarray(end, aligned_end - 1), end) + ihex.merge(alignments, 'ignore') + + +def merge_images(hexf0, hexf1=None): + ihex = IntelHex() + ihex.padding = 0x00 + ihex.loadfile(hexf0, "hex") + if hexf1 is not None: + # Merge the CM0+ image + ihex1 = IntelHex(hexf1) + ihex.merge(ihex1, 'ignore') + return ihex + + +def complete_func(message_func, elf0, hexf0, hexf1=None, dest=None): + message_func("Postprocessing %s -> %s" % (elf0, hexf0)) + ihex = merge_images(hexf0, hexf1) + patch(message_func, ihex, hexf0) + ihex.write_hex_file(dest if dest else hexf0, write_start_addr=False, byte_count=16) + + +# Find Cortex M0 image. +def find_cm0_image(toolchain, resources, elf, hexf, hex_filename): + if hex_filename is None: + return None + # Locate user-specified image + from tools.resources import FileType + hex_files = resources.get_file_paths(FileType.HEX) + m0hexf = next((f for f in hex_files if os.path.basename(f) == hex_filename), None) + + if m0hexf: + toolchain.notify.info("M0 core image file found: %s." % m0hexf) + else: + toolchain.notify.info("M0 core hex image file %s not found. Aborting." % hex_filename) + raise ConfigException("Required M0 core hex image not found.") + + return m0hexf + +def sign_image(toolchain, resourses, elf, binf, m0hex): + sign_hex( + toolchain.build_dir, + toolchain.target.hex_filename, + toolchain.target.name, + toolchain.target.policy_file, + toolchain.notify, + toolchain.target.boot_scheme, + toolchain.target.cm0_img_id, + toolchain.target.cm4_img_id, + elf, + binf, + m0hexf + ) + +def sign_hex( + build_dir, m0hex_filename, target_name, policy, notification, boot_scheme, + cm0_img_id, cm4_img_id, elf, m4hex, m0hex +): + """ + Adds signature to a binary file being built, + using cysecuretools python package. + :param build_dir: The build directory + :param m0hex_filename: The file name of the Cortex-M0 hex + :param target_name: The name of the Mbed target + :param policy: The path to the policy file + :param notification: The object to output notification with + :param boot_scheme: The boot scheme + :param cm0_img_id: The Cortex-M0 image identifier + :param cm4_img_id: The Cortex-M4 image identifier + :param elf: An ELF file + :param m4hex: The path to the Cortex-M4 HEX file + :param m0hex: The path to the Cortex-M0 HEX file + """ + # Keep module import here so it is required only if building PSOC6 targets + # that need to be signed + + if m0hex != '': + m0hex_build = os.path.join(build_dir, m0hex_filename) + copy2(m0hex, m0hex_build) + m0hex = m0hex_build + + # Mapping from mbed target to cysecuretools target + TARGET_MAPPING = { + "CY8CKIT064B0S2_4343W": "cy8ckit-064b0s2-4343w", + "CYTFM_064B0S2_4343W" : "cy8ckit-064b0s2-4343w", + "CY8CPROTO_064B0S1_BLE": "cy8cproto-064b0s1-ble", + "CY8CPROTO_064S1_SB" : "cy8cproto-064s1-sb", + "CY8CPROTO_064B0S3" : "cy8cproto-064b0s3" + } + + try: + secure_target = TARGET_MAPPING[target_name] + except KeyError: + raise ConfigException("[PSOC6.sign_image] Target " + target_name + " is not supported in cysecuretools.") + + policy_file = find_policy( + policy, + notification.info, + target_name + ) + + notification.info("[PSOC6.sign_image] Using policy file: " + str(policy_file)) + + import cysecuretools + tools = cysecuretools.CySecureTools(secure_target, str(policy_file)) + + if str(boot_scheme) == 'single_image': + notification.info("[PSOC6.sign_image] single image signing") + sign_application(notification.debug, tools, m4hex, image_id=cm0_img_id) + + elif str(boot_scheme) == 'multi_image': + sign_application(notification.debug, tools, m0hex, image_id=cm0_img_id) + sign_application(notification.debug, tools, m4hex, image_id=cm4_img_id) + + complete(notification.debug, elf, hexf0=m4hex, hexf1=m0hex) + + else: + raise ConfigException("[PSOC6.sign_image] Boot scheme " + str(boot_scheme) + \ + "is not supported. Supported boot schemes are 'single_image' and 'multi_image' ") + + +def sign_application(message_func, tools, binary, image_id): + """ + Helper function for adding signature to binary + :param message_func: Function to print a status information + :param tools: CySecureTools object + :param binary: Path to binary file to add signature + :param image_id: ID of image slot in which binary will be flashed + """ + + # Get address and size of image slot from policy for passed image_id + # UPGRADE image will be generated automatically by cysecuretools + address, size = tools.flash_map(image_id=image_id, image_type="BOOT") + + tools.sign_image(binary, image_id) + message_func("[PSOC6.sign_image] Slot start address and size for image ID " \ + + str(image_id) + " is " + hex(address) + ", " + hex(size)) + + +def find_policy(policy, message_func, target_name=None): + """ + Locate path to policy file, by name defined in targets.json + :param policy: Path to the policy file + :param message_func: Function to print a status information + :param target_name: Name of the Mbed target + """ + mbed_os_root = Path(MBED_OS_ROOT) + + policy_path = Path(policy) + + # Absolute path provided + if policy_path.is_absolute(): + policy_file = policy_path + + # May also be relative to mbed-os file scturcture + else: + policy_path = mbed_os_root / policy_path + + if os.path.exists(str(policy_path)): + policy_file = policy_path + + else: + default_path = Path("targets/TARGET_Cypress/TARGET_PSOC6/") / \ + Path("TARGET_" + target_name) / Path("policy") / \ + policy + + # Consider default location + policy_file = mbed_os_root / default_path + + if not os.path.exists(str(policy_file)): + policy_file = mbed_os_root / "mbed-os" / default_path + + + if os.path.exists(str(policy_file)): + message_func("Policy file found: %s." % policy_file) + else: + message_func("Policy file %s not found. Aborting." % policy_path) + raise ConfigException("Required policy file not found.") + + return policy_file + + +def complete(message_func, elf0, hexf0, hexf1=None): + """ + Merge CM4 and CM0 images to a single binary + """ + complete_func(message_func, elf0, hexf0, hexf1) + + +def merge_action(args): + """Entry point for the "merge" CLI command.""" + complete_func( + print, args.elf, args.m4hex, args.m0hex + ) + + +def sign_action(args): + """Entry point for the "sign" CLI command.""" + sign_hex( + args.build_dir, + args.m0hex_filename, + args.target_name, + args.policy_file_name, + logging.getLogger(__name__), + args.boot_scheme, + args.cm0_img_id, + args.cm4_img_id, + args.elf, + args.m4hex, + args.m0hex + ) + + +def parse_args(): + """Parse the command line arguments.""" + parser = argparse.ArgumentParser( + description="PSOC6 post build application." + ) + + subcommands = parser.add_subparsers(description="The action to perform.") + + merge_subcommand = subcommands.add_parser( + "merge", help="Merge Cortex-M4 and Cortex-M0 HEX files." + ) + merge_subcommand.add_argument( + "--elf", required=True, help="the application ELF file." + ) + merge_subcommand.add_argument( + "--m4hex", required=True, help="the path to the Cortex-M4 HEX to merge." + ) + merge_subcommand.add_argument( + "--m0hex", help="the path to the Cortex-M0 HEX to merge." + ) + merge_subcommand.set_defaults(func=merge_action) + + sign_subcommand = subcommands.add_parser( + "sign", help="Sign a Cortex-M4 HEX files." + ) + sign_subcommand.add_argument( + "--build-dir", required=True, help="the build directory." + ) + sign_subcommand.add_argument( + "--m0hex-filename", required=True, help="the name of the HEX file." + ) + sign_subcommand.add_argument( + "--target-name", help="the Mbed target name." + ) + sign_subcommand.add_argument( + "--policy-file-name", help="the name of the policy file." + ) + sign_subcommand.add_argument( + "--boot-scheme", help="the boot scheme." + ) + sign_subcommand.add_argument( + "--cm0-img-id", help="the Cortex-M0 image ID." + ) + sign_subcommand.add_argument( + "--cm4-img-id", help="the Cortex-M4 image ID." + ) + sign_subcommand.add_argument( + "--elf", required=True, help="the application ELF file." + ) + sign_subcommand.add_argument( + "--m4hex", required=True, help="the path to the Cortex-M4 HEX to merge." + ) + sign_subcommand.add_argument( + "--m0hex", help="the path to the Cortex-M0 HEX to merge." + ) + sign_subcommand.set_defaults(func=sign_action) + + return parser.parse_args() + + +if __name__ == "__main__": + args = parse_args() + args.func(args) diff --git a/targets/TARGET_Cypress/scripts/mbed_set_post_build_cypress.cmake b/targets/TARGET_Cypress/scripts/mbed_set_post_build_cypress.cmake new file mode 100644 index 00000000000..804a7ea5e1a --- /dev/null +++ b/targets/TARGET_Cypress/scripts/mbed_set_post_build_cypress.cmake @@ -0,0 +1,68 @@ +# Copyright (c) 2021 ARM Limited. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +include(${MBED_PATH}/tools/cmake/mbed_set_post_build.cmake) + +# +# Merge Cortex-M4 HEX and a Cortex-M0 HEX. +# +function(mbed_post_build_psoc6_merge_hex) + find_package(Python3) + + set (extra_macro_args ${ARGN}) + + list(LENGTH cortex_m0_hex num_extra_args) + + if(${num_extra_args} GREATER 0) + list(GET extra_macro_args 0 cortex_m0_hex) + set(post_build_command + COMMAND ${Python3_EXECUTABLE} ${MBED_PATH}/targets/TARGET_Cypress/scripts/PSOC6.py + merge + --elf $ + --m4hex ${CMAKE_BINARY_DIR}/${APP_TARGET}.hex + --m0hex ${cortex_m0_hex} + ) + else() + set(post_build_command + COMMAND ${Python3_EXECUTABLE} ${MBED_PATH}/targets/TARGET_Cypress/scripts/PSOC6.py + merge + --elf $ + --m4hex ${CMAKE_BINARY_DIR}/${APP_TARGET}.hex + ) + endif() + + mbed_set_post_build_operation() +endfunction() + + +# +# Sign a Cortex-M4 HEX with Cortex-M0 HEX. +# +function(mbed_post_build_psoc6_sign_image + m0hex_filename + mbed_target_name + policy_file_name + boot_scheme + cm0_img_id + cm4_img_id + cortex_m0_hex +) + find_package(Python3) + + set(post_build_command + COMMAND ${Python3_EXECUTABLE} ${MBED_PATH}/targets/TARGET_Cypress/scripts/PSOC6.py + sign + --build-dir ${CMAKE_BINARY_DIR} + --m0hex-filename ${m0hex_filename} + --target-name ${mbed_target_name} + --policy-file-name ${policy_file_name} + --boot-scheme ${boot_scheme} + --cm0-img-id ${cm0_img_id} + --cm4-img-id ${cm4_img_id} + --elf $ + --m4hex ${CMAKE_BINARY_DIR}/${APP_TARGET}.hex + --m0hex ${cortex_m0_hex} + ) + + mbed_set_post_build_operation() +endfunction() diff --git a/targets/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11XX/CMakeLists.txt b/targets/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11XX/CMakeLists.txt index 3258f027630..bdfa738b8a9 100644 --- a/targets/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11XX/CMakeLists.txt +++ b/targets/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11XX/CMakeLists.txt @@ -1,6 +1,8 @@ # Copyright (c) 2021 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 +include(${MBED_PATH}/targets/TARGET_NXP/scripts/mbed_set_post_build_nxp.cmake) + add_library(mbed-lpc11xx INTERFACE) target_include_directories(mbed-lpc11xx @@ -14,3 +16,5 @@ target_sources(mbed-lpc11xx ) target_link_libraries(mbed-lpc11xx INTERFACE mbed-lpc11xx-11cxx) + +mbed_post_build_lpc_patch_vtable() diff --git a/targets/TARGET_NXP/TARGET_LPC176X/TARGET_ARCH_PRO/CMakeLists.txt b/targets/TARGET_NXP/TARGET_LPC176X/TARGET_ARCH_PRO/CMakeLists.txt index beb30ff0926..4ce9d41663e 100644 --- a/targets/TARGET_NXP/TARGET_LPC176X/TARGET_ARCH_PRO/CMakeLists.txt +++ b/targets/TARGET_NXP/TARGET_LPC176X/TARGET_ARCH_PRO/CMakeLists.txt @@ -1,6 +1,8 @@ # Copyright (c) 2021 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 +include(${MBED_PATH}/targets/TARGET_NXP/scripts/mbed_set_post_build_nxp.cmake) + add_library(mbed-arch-pro INTERFACE) target_include_directories(mbed-arch-pro @@ -9,3 +11,5 @@ target_include_directories(mbed-arch-pro ) target_link_libraries(mbed-arch-pro INTERFACE mbed-lpc176x) + +mbed_post_build_lpc_patch_vtable() diff --git a/targets/TARGET_NXP/TARGET_LPC176X/TARGET_MBED_LPC1768/CMakeLists.txt b/targets/TARGET_NXP/TARGET_LPC176X/TARGET_MBED_LPC1768/CMakeLists.txt index d7a0ec62596..dfe564388b5 100644 --- a/targets/TARGET_NXP/TARGET_LPC176X/TARGET_MBED_LPC1768/CMakeLists.txt +++ b/targets/TARGET_NXP/TARGET_LPC176X/TARGET_MBED_LPC1768/CMakeLists.txt @@ -1,6 +1,8 @@ # Copyright (c) 2021 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 +include(${MBED_PATH}/targets/TARGET_NXP/scripts/mbed_set_post_build_nxp.cmake) + add_library(mbed-mbed-lpc1768 INTERFACE) target_include_directories(mbed-mbed-lpc1768 @@ -13,3 +15,5 @@ target_link_libraries(mbed-mbed-lpc1768 INTERFACE mbed-lpc176x) add_library(mbed-lpc1768 INTERFACE) target_link_libraries(mbed-lpc1768 INTERFACE mbed-mbed-lpc1768) + +mbed_post_build_lpc_patch_vtable() diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC54114/device/TARGET_LPC54114_M4/CMakeLists.txt b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC54114/device/TARGET_LPC54114_M4/CMakeLists.txt index 63b3c1e6e40..487d3a3fb2e 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC54114/device/TARGET_LPC54114_M4/CMakeLists.txt +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC54114/device/TARGET_LPC54114_M4/CMakeLists.txt @@ -1,6 +1,8 @@ # Copyright (c) 2021 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 +include(${MBED_PATH}/targets/TARGET_NXP/scripts/mbed_set_post_build_nxp.cmake) + if(${MBED_TOOLCHAIN} STREQUAL "ARM") set(STARTUP_FILE TOOLCHAIN_ARM_STD/startup_LPC54114_cm4.S) set(LINKER_FILE TOOLCHAIN_ARM_STD/LPC54114J256_cm4.sct) @@ -30,3 +32,5 @@ target_sources(mbed-lpc54114-m4 ) mbed_set_linker_script(mbed-lpc54114-m4 ${CMAKE_CURRENT_SOURCE_DIR}/${LINKER_FILE}) + +mbed_post_build_lpc_patch_vtable() diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MCU_LPC546XX/CMakeLists.txt b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MCU_LPC546XX/CMakeLists.txt index f21330d7849..e4f9a1e3dac 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MCU_LPC546XX/CMakeLists.txt +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MCU_LPC546XX/CMakeLists.txt @@ -1,6 +1,8 @@ # Copyright (c) 2020-2021 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 +include(${MBED_PATH}/targets/TARGET_NXP/scripts/mbed_set_post_build_nxp.cmake) + add_subdirectory(TARGET_FF_LPC546XX EXCLUDE_FROM_ALL) add_subdirectory(TARGET_LPCXpresso EXCLUDE_FROM_ALL) @@ -91,3 +93,5 @@ target_link_libraries(mbed-lpc546xx mbed-mcu-lpc546xx mbed-lpc546xx-xpresso ) + +mbed_post_build_lpc_patch_vtable() diff --git a/targets/TARGET_NXP/scripts/LPC.py b/targets/TARGET_NXP/scripts/LPC.py new file mode 100644 index 00000000000..bfccbfb7563 --- /dev/null +++ b/targets/TARGET_NXP/scripts/LPC.py @@ -0,0 +1,52 @@ +""" +mbed SDK +Copyright (c) 2011-2021 ARM Limited + +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. + + +http://www.nxp.com/documents/user_manual/UM10360.pdf + +32.3.1.1 Criterion for Valid User Code +The reserved Cortex-M3 exception vector location 7 (offset 0x1C in the vector table) +should contain the 2's complement of the check-sum of table entries 0 through 6. This +causes the checksum of the first 8 table entries to be 0. The boot loader code checksums +the first 8 locations in sector 0 of the flash. If the result is 0, then execution control is +transferred to the user code. +""" +import os +import sys +from struct import unpack, pack + + +def patch(bin_path): + with open(bin_path, 'r+b') as bin: + # Read entries 0 through 6 (Little Endian 32bits words) + vector = [unpack('