├── .cmake-format.yaml ├── .github ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md └── workflows │ ├── hw-tests.yml │ ├── pr.yml │ ├── push.yml │ ├── sel4test-sim.yml │ └── trigger.yml ├── .gitignore ├── .licenseignore ├── .reuse └── dep5 ├── .stylefilter ├── LICENSE.md ├── LICENSES ├── BSD-2-Clause.txt ├── BSD-3-Clause.txt ├── CC-BY-SA-4.0.txt ├── GPL-2.0-only.txt └── GPL-2.0-or-later.txt ├── README.md ├── cmake-tool ├── README.md ├── all.cmake ├── base.cmake ├── common.cmake ├── default-CMakeLists.txt ├── griddle ├── helpers │ ├── Holmakefile.in │ ├── application_settings.cmake │ ├── buildScript.sml.in │ ├── cakeml.cmake │ ├── check_arch_compiler.cmake │ ├── cmakerepl │ ├── configure_file.cmake │ ├── cpio.cmake │ ├── cross_compiling.cmake │ ├── debug.cmake │ ├── dts.cmake │ ├── elf_sift.py │ ├── environment_flags.cmake │ ├── external-project-helpers.cmake │ ├── make-uimage │ ├── make.cmake │ ├── memoize.cmake │ ├── nanopb.cmake │ ├── pkg-config.in │ ├── platform_sift.py │ ├── rootserver.cmake │ ├── rust.cmake │ ├── shoehorn.py │ ├── simulation.cmake │ └── tls_rootserver.lds ├── init-build.sh ├── polly_toolchains │ ├── FindPolly.cmake │ └── linux-gcc-32bit-pic.cmake ├── projects.cmake ├── rust_targets │ ├── aarch32-sel4-none.json │ ├── aarch64-sel4-none.json │ └── x86_64-sel4-none.json └── simulate_scripts │ ├── launch_gdb.py │ └── simulate.py ├── elfloader-tool ├── CMakeLists.txt ├── Findelfloader-tool.cmake ├── README.md ├── helpers.cmake ├── include │ ├── abort.h │ ├── arch-arm │ │ ├── 32 │ │ │ └── mode │ │ │ │ ├── arm_generic_timer.h │ │ │ │ ├── assembler.h │ │ │ │ └── structures.h │ │ ├── 64 │ │ │ └── mode │ │ │ │ ├── arm_generic_timer.h │ │ │ │ ├── assembler.h │ │ │ │ └── structures.h │ │ ├── armv │ │ │ ├── armv7-a │ │ │ │ └── armv │ │ │ │ │ ├── assembler.h │ │ │ │ │ ├── machine.h │ │ │ │ │ └── smp.h │ │ │ ├── armv7ve │ │ │ └── armv8-a │ │ │ │ ├── 32 │ │ │ │ └── 64 │ │ │ │ └── armv │ │ │ │ ├── assembler.h │ │ │ │ ├── machine.h │ │ │ │ └── smp.h │ │ ├── cpuid.h │ │ ├── elfloader.h │ │ ├── psci.h │ │ └── scu.h │ ├── arch-riscv │ │ ├── elfloader.h │ │ └── sbi.h │ ├── assembler.h │ ├── binaries │ │ ├── efi │ │ │ └── efi.h │ │ └── elf │ │ │ ├── elf.h │ │ │ ├── elf32.h │ │ │ └── elf64.h │ ├── drivers.h │ ├── drivers │ │ ├── common.h │ │ ├── smp.h │ │ └── uart.h │ ├── elfloader_common.h │ ├── fdt.h │ ├── plat │ │ ├── zynq7000 │ │ │ └── sys_fputc.h │ │ └── zynqmp │ │ │ └── sys_fputc.h │ ├── printf.h │ ├── strops.h │ ├── types.h │ └── vargs.h └── src │ ├── arch-arm │ ├── 32 │ │ ├── cpuid.c │ │ ├── crt0.S │ │ ├── crt0_64.S │ │ ├── debug.c │ │ ├── idle.c │ │ ├── mmu.c │ │ ├── smp.c │ │ ├── structures.c │ │ └── traps.S │ ├── 64 │ │ ├── cpuid.c │ │ ├── crt0.S │ │ ├── debug.c │ │ ├── mmu.c │ │ ├── structures.c │ │ └── traps.S │ ├── README.md │ ├── armv │ │ ├── armv7-a │ │ │ └── 32 │ │ │ │ ├── mmu-hyp.S │ │ │ │ ├── mmu.S │ │ │ │ └── smc.S │ │ ├── armv7ve │ │ └── armv8-a │ │ │ ├── 32 │ │ │ └── 64 │ │ │ ├── mmu-hyp.S │ │ │ ├── mmu.S │ │ │ ├── psci_asm.S │ │ │ └── smp.c │ ├── cpuid.c │ ├── drivers │ │ ├── smp-imx6.c │ │ ├── smp-psci.c │ │ ├── smp-spin-table.c │ │ └── smp-zynq7000.c │ ├── psci.c │ ├── scu.c │ ├── smp_boot.c │ └── sys_boot.c │ ├── arch-riscv │ ├── boot.c │ ├── console.c │ └── crt0.S │ ├── archive.bin.lds │ ├── binaries │ ├── efi │ │ ├── efi_init.c │ │ ├── efi_utils.c │ │ └── gnuefi │ │ │ ├── crt0-efi-aarch64.S │ │ │ ├── crt0-efi-arm.S │ │ │ ├── elf_aarch64_efi.lds │ │ │ ├── elf_arm_efi.lds │ │ │ ├── reloc_aarch64.c │ │ │ └── reloc_arm.c │ └── elf │ │ ├── elf.c │ │ ├── elf32.c │ │ └── elf64.c │ ├── common.c │ ├── crypt_md5.h │ ├── crypt_sha256.h │ ├── defaults.c │ ├── drivers │ ├── driver.c │ ├── smp │ │ └── common.c │ ├── timer │ │ └── arm_generic_timer.c │ └── uart │ │ ├── 8250-uart.c │ │ ├── bcm-uart.c │ │ ├── common.c │ │ ├── exynos-uart.c │ │ ├── imx-lpuart.c │ │ ├── imx-uart.c │ │ ├── meson-uart.c │ │ ├── msm-uart.c │ │ ├── pl011-uart.c │ │ └── xilinx-uart.c │ ├── fdt.c │ ├── hash.h │ ├── linker.lds │ ├── plat │ ├── exynos5 │ │ └── platform_init.c │ ├── fvp │ │ └── platform_init.c │ ├── imx6 │ │ ├── monitor.S │ │ └── platform_init.c │ ├── imx7 │ │ ├── head_smp.S │ │ └── smp.c │ ├── tk1 │ │ ├── monitor.S │ │ └── platform_init.c │ ├── tx2 │ │ └── platform_init.c │ └── zynq7000 │ │ └── platform_init.c │ ├── printf.c │ ├── string.c │ └── utils │ ├── crypt_md5.c │ ├── crypt_sha256.c │ └── hash.c └── misc ├── .gitlint ├── Makefile.cpio_strip ├── README.md ├── astylerc ├── cobbler ├── cpio-strip.c ├── filter.py ├── is-valid-shell-script ├── style-all.sh ├── style-c.sh ├── style-changed.sh ├── style-cmake.sh ├── style-py.sh ├── style.py ├── style.sh └── whence.py /.cmake-format.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: GPL-2.0-only 5 | # 6 | additional_commands: 7 | config_option: 8 | flags: 9 | - UNQUOTE 10 | kwargs: 11 | DEFAULT: '*' 12 | DEFAULT_DISABLED: '*' 13 | DEPENDS: '*' 14 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | # Code of Conduct 8 | 9 | This repository and interactions with it fall under the [seL4 Code of Conduct][1] available from the [seL4 website][2]. 10 | 11 | [1]: https://docs.sel4.systems/processes/conduct.html 12 | [2]: https://sel4.systems 13 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | # Contributions Welcome 8 | 9 | Please see the [seL4 contributing guidelines][1] on the [seL4 website][2] for 10 | details. 11 | 12 | [1]: https://docs.sel4.systems/processes/contributing.html 13 | [2]: https://sel4.systems 14 | 15 | 16 | ## Contact 17 | 18 | If you have larger changes or additions, it is a good idea to get in contact 19 | with us as , so we can help you get started. 20 | 21 | The people responsible for the technical direction, procedures, and quality 22 | control are the [Technical Steering Committee][3] (TSC) of the seL4 23 | foundation. You can contact them either on the developer mailing list or on 24 | directly via email available from their profile pages. 25 | 26 | [3]: https://sel4.systems/Foundation/TSC 27 | 28 | 29 | ## Developer Certificate of Origin (DCO) 30 | 31 | This repository uses the same sign-off process as the Linux kernel. For every 32 | commit, use 33 | 34 | git commit -s 35 | 36 | to add a sign-off line to your commit message, which will come out as: 37 | 38 | Signed-off-by: name 39 | 40 | By adding this line, you make the declaration that you have the right to make 41 | this contribution under the open source license the files use that you changed 42 | or contributed. 43 | 44 | The full text of the declaration is at . 45 | -------------------------------------------------------------------------------- /.github/workflows/hw-tests.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2024, Proofcraft Pty Ltd 2 | # 3 | # SPDX-License-Identifier: BSD-2-Clause 4 | 5 | # sel4test and sel4bench hardware builds and runs 6 | # 7 | # See sel4test-hw/builds.yml and sel4bench-hw/builds.yml in the repo 8 | # seL4/ci-actions for configs. 9 | 10 | name: HW 11 | 12 | on: 13 | # needs PR target for secrets access; guard by requiring label 14 | pull_request_target: 15 | types: [synchronize, labeled] 16 | 17 | jobs: 18 | sel4test: 19 | name: seL4Test 20 | uses: seL4/ci-actions/.github/workflows/sel4test-hw.yml@master 21 | secrets: inherit 22 | 23 | sel4bench: 24 | name: seL4Bench 25 | uses: seL4/ci-actions/.github/workflows/sel4bench-hw.yml@master 26 | secrets: inherit 27 | -------------------------------------------------------------------------------- /.github/workflows/pr.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2025, Proofcraft Pty Ltd 2 | # 3 | # SPDX-License-Identifier: BSD-2-Clause 4 | 5 | # Actions to run on pull requests 6 | 7 | name: PR 8 | 9 | on: [pull_request, workflow_dispatch] 10 | 11 | jobs: 12 | pr-checks: 13 | name: Checks 14 | uses: seL4/ci-actions/.github/workflows/pr.yml@master 15 | -------------------------------------------------------------------------------- /.github/workflows/push.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 2 | # 3 | # SPDX-License-Identifier: BSD-2-Clause 4 | 5 | # Actions to run on Push and Pull Request 6 | name: CI 7 | 8 | on: 9 | push: 10 | branches: 11 | - master 12 | pull_request: 13 | workflow_dispatch: 14 | 15 | jobs: 16 | checks: 17 | name: Checks 18 | uses: seL4/ci-actions/.github/workflows/push.yml@master 19 | -------------------------------------------------------------------------------- /.github/workflows/sel4test-sim.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2021, Proofcraft Pty Ltd 2 | # 3 | # SPDX-License-Identifier: BSD-2-Clause 4 | 5 | # sel4test simulation runs 6 | # 7 | # See sel4test-sim/builds.yml in the repo seL4/ci-actions for configs. 8 | 9 | name: seL4Test 10 | 11 | on: 12 | pull_request: 13 | paths-ignore: 14 | - 'LICENSES/**' 15 | - '*.md' 16 | workflow_dispatch: 17 | 18 | jobs: 19 | sim: 20 | name: Sim 21 | uses: seL4/ci-actions/.github/workflows/sel4test-sim.yml@master 22 | -------------------------------------------------------------------------------- /.github/workflows/trigger.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2021, Proofcraft Pty Ltd 2 | # 3 | # SPDX-License-Identifier: BSD-2-Clause 4 | 5 | # Trigger repository dispatch on main test repos 6 | name: Trigger 7 | 8 | on: 9 | push: 10 | branches: [master] 11 | 12 | jobs: 13 | trigger: 14 | name: Repository Dispatch 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: seL4/ci-actions/trigger@master 18 | with: 19 | token: ${{ secrets.PRIV_REPO_TOKEN }} 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | 7 | # Generated python bytecode 8 | **/*.pyc 9 | -------------------------------------------------------------------------------- /.licenseignore: -------------------------------------------------------------------------------- 1 | .git 2 | LICENSES/*.txt 3 | .licenseignore 4 | .reuse/dep5 5 | kbuild-tool/* 6 | *.json 7 | *.pyc -------------------------------------------------------------------------------- /.reuse/dep5: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: seL4_tools 3 | Upstream-Contact: seL4 team 4 | Source: https://github.com/seL4/seL4_tools 5 | 6 | Files: cmake-tool/rust_targets/*.json 7 | Copyright: 2020, Data61, CSIRO (ABN 41 687 119 230) 8 | License: BSD-2-Clause 9 | 10 | Files: .licenseignore 11 | Copyright: 2020, Data61, CSIRO (ABN 41 687 119 230) 12 | License: BSD-2-Clause 13 | -------------------------------------------------------------------------------- /.stylefilter: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: GPL-2.0-only 5 | # 6 | 7 | # astyle doesn't understand the layout of these files 8 | *assembler.h 9 | # original ozlabs code, leave it alone 10 | *elfloader-tool/include/binaries* 11 | *elfloader-tool/src/binaries* 12 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | # License 8 | 9 | The files in this repository are released under standard open source licenses, 10 | identified by [SPDX license tags][1]. See the individual file headers for 11 | details, or use one of the publicly available SPDX tools to generate a bill of 12 | materials. The directory [`LICENSES`][2] contains the text for all licenses 13 | that are mentioned by files in this repository. 14 | 15 | [1]: https://spdx.org 16 | [2]: LICENSES/ 17 | -------------------------------------------------------------------------------- /LICENSES/BSD-2-Clause.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) . All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, 4 | are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, 7 | this list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 17 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 22 | USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /LICENSES/BSD-3-Clause.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) . All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, 4 | are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, 7 | this list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | 3. Neither the name of the copyright holder nor the names of its contributors 14 | may be used to endorse or promote products derived from this software without 15 | specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 26 | USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | # seL4\_tools 8 | 9 | Provides tools used to build seL4 projects. 10 | Also collects common config and tools for style checks. 11 | 12 | * [elfloader-tool](elfloader-tool/): loads the arm kernel. 13 | * [cmake-tool](cmake-tool/): most of the build system. 14 | * [misc](misc/): miscellaneous extra tools, including code style checks. 15 | 16 | 17 | ## Contributing 18 | 19 | Contributions welcome! 20 | 21 | See the [CONTRIBUTING](.github/CONTRIBUTING.md) file for more. 22 | -------------------------------------------------------------------------------- /cmake-tool/all.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | 7 | cmake_minimum_required(VERSION 3.16.0) 8 | 9 | # import some debug functions 10 | include("${CMAKE_CURRENT_LIST_DIR}/helpers/debug.cmake") 11 | 12 | # Include the base part of the build system and setup flags etc 13 | include("${CMAKE_CURRENT_LIST_DIR}/base.cmake") 14 | 15 | # Now that flags are setup include all the parts of the project 16 | include("${CMAKE_CURRENT_LIST_DIR}/projects.cmake") 17 | -------------------------------------------------------------------------------- /cmake-tool/base.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | 7 | cmake_minimum_required(VERSION 3.16.0) 8 | # Include our common helpers 9 | list( 10 | APPEND 11 | CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/helpers/ ${CMAKE_SOURCE_DIR}/projects/musllibc 12 | ) 13 | 14 | include(check_arch_compiler) 15 | 16 | enable_language(C) 17 | enable_language(CXX) 18 | enable_language(ASM) 19 | 20 | # Hide cmake variables that will just confuse the user 21 | mark_as_advanced( 22 | FORCE 23 | CMAKE_INSTALL_PREFIX 24 | CROSS_COMPILER_PREFIX 25 | EXECUTABLE_OUTPUT_PATH 26 | CMAKE_BACKWARDS_COMPATIBILITY 27 | LIBRARY_OUTPUT_PATH 28 | CMAKE_ASM_COMPILER 29 | CMAKE_C_COMPILER 30 | ) 31 | 32 | find_file(KERNEL_PATH kernel PATHS ${CMAKE_SOURCE_DIR} NO_CMAKE_FIND_ROOT_PATH) 33 | mark_as_advanced(FORCE KERNEL_PATH) 34 | if("${KERNEL_PATH}" STREQUAL "KERNEL_PATH-NOTFOUND") 35 | message(FATAL_ERROR "Failed to find kernel. Consider cmake -DKERNEL_PATH=/path/to/kernel") 36 | endif() 37 | 38 | # Give an explicit build directory as there is no guarantee this is actually 39 | # subdirectory from the root source hierarchy 40 | add_subdirectory("${KERNEL_PATH}" kernel) 41 | # Include helpers from the kernel 42 | include(${KERNEL_HELPERS_PATH}) 43 | 44 | include("${CMAKE_CURRENT_LIST_DIR}/common.cmake") 45 | 46 | # Due to some symlink madness in some project manifests we first get the realpath 47 | # for the current list directory and use that to find the elfloader 48 | # Both of these might not be subdirectories from our source root, so also 49 | # give them both explicit build directories 50 | get_filename_component(real_list "${CMAKE_CURRENT_LIST_DIR}" REALPATH) 51 | # Include the elfloader before setting up user mode flags, as the elfloader does 52 | # not run as a user under the kernel 53 | add_subdirectory("${real_list}/../elfloader-tool" elfloader-tool) 54 | 55 | find_package(musllibc REQUIRED) 56 | # Make build options a visible choice, default it to Debug 57 | set( 58 | CMAKE_BUILD_TYPE "Debug" 59 | CACHE STRING "Set the user mode build type (kernel build ignores this)" 60 | ) 61 | set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug;Release;RelWithDebInfo;MinSizeRel") 62 | mark_as_advanced(CLEAR CMAKE_BUILD_TYPE) 63 | 64 | # Declare build flags for using musllibc in targets 65 | musllibc_set_environment_flags() 66 | 67 | # Now all platform compilation flags have been set, we can check the compiler against flags 68 | check_arch_compiler() 69 | 70 | add_subdirectory("${KERNEL_PATH}/libsel4" libsel4) 71 | -------------------------------------------------------------------------------- /cmake-tool/common.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | 7 | cmake_minimum_required(VERSION 3.16.0) 8 | 9 | include("${CMAKE_CURRENT_LIST_DIR}/helpers/application_settings.cmake") 10 | include("${CMAKE_CURRENT_LIST_DIR}/helpers/cakeml.cmake") 11 | include("${CMAKE_CURRENT_LIST_DIR}/helpers/cross_compiling.cmake") 12 | include("${CMAKE_CURRENT_LIST_DIR}/helpers/external-project-helpers.cmake") 13 | include("${CMAKE_CURRENT_LIST_DIR}/helpers/rust.cmake") 14 | include("${CMAKE_CURRENT_LIST_DIR}/helpers/dts.cmake") 15 | include("${CMAKE_CURRENT_LIST_DIR}/helpers/simulation.cmake") 16 | include("${CMAKE_CURRENT_LIST_DIR}/helpers/cpio.cmake") 17 | include("${CMAKE_CURRENT_LIST_DIR}/helpers/rootserver.cmake") 18 | include("${CMAKE_CURRENT_LIST_DIR}/helpers/make.cmake") 19 | -------------------------------------------------------------------------------- /cmake-tool/default-CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | cmake_minimum_required(VERSION 3.16.0) 7 | project(sel4-application NONE) 8 | 9 | include(settings.cmake) 10 | 11 | # This is a default file that can be copied/symlinked into the top level of a project 12 | # if you have the expected directory layout and you want no customizations beyond 13 | # the defaults provided in the all.cmake 14 | 15 | # Try a bunch of different default locations for the script. The different locations 16 | # come about from different project layouts depending on how far through the transition 17 | # from the old build system they are 18 | include(tools/seL4/cmake-tool/all.cmake OPTIONAL RESULT_VARIABLE found_all_cmake) 19 | if(NOT found_all_cmake) 20 | include(tools/cmake-tool/all.cmake OPTIONAL RESULT_VARIABLE found_all_cmake) 21 | if(NOT found_all_cmake) 22 | message(FATAL_ERROR "No path for including cmake-tool/all.cmake was successful") 23 | endif() 24 | endif() 25 | -------------------------------------------------------------------------------- /cmake-tool/helpers/Holmakefile.in: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | 7 | CAKEML_DIR = @CAKEMLDIR@ 8 | INCLUDES = $(CAKEML_DIR)/characteristic $(CAKEML_DIR)/basis $(CAKEML_DIR)/misc $(CAKEML_DIR)/translator \ 9 | $(CAKEML_DIR)/semantics $(CAKEML_DIR)/unverified/sexpr-bootstrap $(CAKEML_DIR)/compiler/parsing \ 10 | @CAKEML_INCLUDES_SPACE_SEP@ 11 | OPTIONS = QUIT_ON_FAILURE 12 | 13 | THYFILES = $(patsubst %Script.sml,%Theory.uo,$(wildcard *.sml)) 14 | TARGETS0 = $(patsubst %Theory.sml,,$(THYFILES)) 15 | TARGETS = $(patsubst %.sml,%.uo,$(TARGETS0)) 16 | all: $(TARGETS) 17 | .PHONY: all 18 | -------------------------------------------------------------------------------- /cmake-tool/helpers/buildScript.sml.in: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: BSD-2-Clause 5 | *) 6 | 7 | open preamble basis fromSexpTheory astToSexprLib @PARSE_CML_LIB_TRANSLATION_THEORY@Theory; 8 | 9 | val _ = new_theory "build"; 10 | val _ = translation_extends "@PARSE_CML_LIB_TRANSLATION_THEORY@"; 11 | val st = ml_translatorLib.get_ml_prog_state(); 12 | val maincall = 13 | ``Dlet unknown_loc (Pcon NONE []) (App Opapp [Var (Short "@PARSE_CML_LIB_CAKEML_ENTRY@"); Con NONE []])``; 14 | val prog = ``SNOC ^maincall ^(get_prog st)`` 15 | |> EVAL |> concl |> rhs; 16 | val _ = astToSexprLib.write_ast_to_file "@SEXP_FILE@" prog; 17 | val _ = export_theory (); 18 | -------------------------------------------------------------------------------- /cmake-tool/helpers/check_arch_compiler.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | 7 | function(check_arch_clang) 8 | if("${KernelSel4Arch}" STREQUAL "ia32") 9 | string( 10 | REGEX 11 | MATCH 12 | "^x86_64" 13 | correct_triple 14 | "${TRIPLE}" 15 | ) 16 | elseif("${KernelSel4Arch}" STREQUAL "x86_64") 17 | string( 18 | REGEX 19 | MATCH 20 | "^x86_64" 21 | correct_triple 22 | "${TRIPLE}" 23 | ) 24 | elseif("${KernelSel4Arch}" STREQUAL "aarch32" OR "${KernelSel4Arch}" STREQUAL "arm_hyp") 25 | string( 26 | REGEX 27 | MATCH 28 | "^arm" 29 | correct_triple 30 | "${TRIPLE}" 31 | ) 32 | elseif("${KernelSel4Arch}" STREQUAL "aarch64") 33 | string( 34 | REGEX 35 | MATCH 36 | "^aarch64" 37 | correct_triple 38 | "${TRIPLE}" 39 | ) 40 | elseif("${KernelSel4Arch}" STREQUAL "riscv32") 41 | string( 42 | REGEX 43 | MATCH 44 | "^riscv(32|64)" 45 | correct_triple 46 | "${TRIPLE}" 47 | ) 48 | elseif("${KernelSel4Arch}" STREQUAL "riscv64") 49 | string( 50 | REGEX 51 | MATCH 52 | "^riscv64" 53 | correct_triple 54 | "${TRIPLE}" 55 | ) 56 | else() 57 | message(SEND_ERROR "KernelSel4Arch is not set to a valid arch") 58 | endif() 59 | 60 | if(NOT correct_triple) 61 | message(SEND_ERROR "Clang Triple: '${TRIPLE}' isn't for seL4_arch: ${KernelSel4Arch}") 62 | endif() 63 | 64 | endfunction() 65 | 66 | function(check_arch_gcc) 67 | if("${KernelSel4Arch}" STREQUAL "ia32") 68 | set(compiler_variable "defined(__i386)") 69 | elseif("${KernelSel4Arch}" STREQUAL "x86_64") 70 | set(compiler_variable "defined(__x86_64)") 71 | elseif("${KernelSel4Arch}" STREQUAL "aarch32" OR "${KernelSel4Arch}" STREQUAL "arm_hyp") 72 | if(KernelArchArmV7a OR KernelArchArmV7ve) 73 | set(compiler_variable "defined(__ARM_ARCH_7A__)") 74 | elseif(KernelArchArmV8a) 75 | set(compiler_variable "defined(__ARM_ARCH_8A__)") 76 | endif() 77 | elseif("${KernelSel4Arch}" STREQUAL "aarch64") 78 | set(compiler_variable "defined(__aarch64__)") 79 | elseif("${KernelSel4Arch}" STREQUAL "riscv32") 80 | set(compiler_variable "__riscv_xlen == 32") 81 | elseif("${KernelSel4Arch}" STREQUAL "riscv64") 82 | set(compiler_variable "__riscv_xlen == 64") 83 | else() 84 | message(SEND_ERROR "KernelSel4Arch is not set to a valid arch") 85 | endif() 86 | 87 | set(arch_test " 88 | #if ${compiler_variable} 89 | int main() {return 0;} 90 | #else 91 | #error Invalid arch 92 | #endif 93 | ") 94 | 95 | check_c_source_compiles("${arch_test}" compiler_arch_test) 96 | 97 | if(NOT compiler_arch_test) 98 | message(SEND_ERROR "Compiler: ${CMAKE_C_COMPILER} isn't for seL4_arch: ${KernelSel4Arch}") 99 | endif() 100 | 101 | endfunction() 102 | 103 | function(check_arch_compiler) 104 | if(CMAKE_C_COMPILER_ID STREQUAL "Clang") 105 | check_arch_clang() 106 | else() 107 | check_arch_gcc() 108 | endif() 109 | endfunction() 110 | -------------------------------------------------------------------------------- /cmake-tool/helpers/cmakerepl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S cmake -P 2 | # 3 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 4 | # 5 | # SPDX-License-Identifier: BSD-2-Clause 6 | # 7 | 8 | message("CMake REPL: Execute cmake commands interactively. (Ctrl-D to exit)") 9 | 10 | # If this file was included somewhere else then CMAKE_PARENT_LIST_FILE will be set 11 | if(NOT "${CMAKE_PARENT_LIST_FILE}" STREQUAL "") 12 | message(" Currently included in file: ${CMAKE_PARENT_LIST_FILE}") 13 | set(state_dir ${CMAKE_BINARY_DIR}/.repl/) 14 | set(history_file ${CMAKE_BINARY_DIR}/.repl/history) 15 | else() 16 | # If not included by anywhere else, then spew data into the user's home directory 17 | # Calculate a thread id to allow running multiple instances 18 | file(GLOB tids /proc/self/task/*) 19 | list(GET tids 0 tid_path) 20 | get_filename_component(tid ${tid_path} NAME) 21 | set(state_dir "$ENV{HOME}/.cmakerepl/tid/") 22 | set(history_file $ENV{HOME}/.cmakerepl/history) 23 | endif() 24 | 25 | file(MAKE_DIRECTORY ${state_dir}) 26 | file(TOUCH ${history_file}) 27 | 28 | set(prompt "> ") 29 | 30 | # Write a python read script out to disk. We use this to for obtaining user input 31 | # it uses readline to provide history and line editing. Unfortunately it isn't 32 | # featured enough to support multiline input. 33 | file(WRITE ${state_dir}/read.py "from __future__ import print_function 34 | import readline 35 | f = open(\"${state_dir}/test\", 'w') 36 | readline.read_history_file(\"${history_file}\") 37 | try: 38 | s = raw_input(\"${prompt}\") 39 | print(s, file=f) 40 | readline.write_history_file(\"${history_file}\") 41 | except EOFError: 42 | print(\"set(forever OFF)\", file=f) 43 | ") 44 | 45 | # Declare a short hand run function for executing something on the shell 46 | # if this starts name colliding with existing functions in scope it can just be deleted 47 | function(run) 48 | execute_process( 49 | COMMAND ${ARGV} 50 | INPUT_FILE /dev/stdin 51 | OUTPUT_FILE /dev/stdout 52 | ERROR_FILE /dev/stderr 53 | ) 54 | endfunction() 55 | 56 | # Start REPL. 57 | # This calls the python script that prompts the user for input. 58 | # The input is then written out to a file which cmake includes into itself 59 | # Including the file results in its execution. 60 | # Then we loop back again. 61 | # Exiting is implemented by setting the loop variable to false when an EOF exception 62 | # is caught in the python script. 63 | set(forever ON) 64 | while(forever) 65 | execute_process( 66 | COMMAND python ${state_dir}/read.py 67 | INPUT_FILE /dev/stdin 68 | OUTPUT_FILE /dev/stdout 69 | ERROR_FILE /dev/stderr 70 | ) 71 | include(${state_dir}/test) 72 | endwhile() 73 | -------------------------------------------------------------------------------- /cmake-tool/helpers/configure_file.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | 7 | cmake_minimum_required(VERSION 3.16.0) 8 | 9 | if(NOT CONFIGURE_INPUT_FILE) 10 | message(FATAL_ERROR "CONFIGURE_INPUT_FILE not set.") 11 | endif() 12 | 13 | if(NOT CONFIGURE_OUTPUT_FILE) 14 | message(FATAL_ERROR "CONFIGURE_OUTPUT_FILE not set.") 15 | endif() 16 | 17 | if(NOT EXISTS "${CONFIGURE_INPUT_FILE}") 18 | message(FATAL_ERROR "Configure file: ${CONFIGURE_INPUT_FILE} does not exist") 19 | endif() 20 | 21 | configure_file(${CONFIGURE_INPUT_FILE} ${CONFIGURE_OUTPUT_FILE} @ONLY) 22 | -------------------------------------------------------------------------------- /cmake-tool/helpers/cpio.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | 7 | # This module contains functions for creating a cpio archive containing a list 8 | # of input files and turning it into an object file that can be linked into a binary. 9 | 10 | include_guard(GLOBAL) 11 | 12 | # Checks the existence of an argument to cpio -o. 13 | # flag refers to a variable in the parent scope that contains the argument, if 14 | # the argument isn't supported then the flag is set to the empty string in the parent scope. 15 | function(CheckCPIOArgument var flag) 16 | if(NOT (DEFINED ${var})) 17 | file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/cpio-testfile "Testfile contents") 18 | execute_process( 19 | COMMAND bash -c "echo cpio-testfile | cpio ${flag} -o" 20 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 21 | OUTPUT_QUIET ERROR_QUIET 22 | RESULT_VARIABLE result 23 | ) 24 | if(result) 25 | set(${var} "" CACHE INTERNAL "") 26 | message(STATUS "CPIO test ${var} FAILED") 27 | else() 28 | set(${var} "${flag}" CACHE INTERNAL "") 29 | message(STATUS "CPIO test ${var} PASSED") 30 | endif() 31 | file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/cpio-testfile) 32 | endif() 33 | endfunction() 34 | 35 | # Function for declaring rules to build a cpio archive that can be linked 36 | # into another target 37 | function(MakeCPIO output_name input_files) 38 | cmake_parse_arguments(PARSE_ARGV 2 MAKE_CPIO "" "CPIO_SYMBOL" "DEPENDS") 39 | if(NOT "${MAKE_CPIO_UNPARSED_ARGUMENTS}" STREQUAL "") 40 | message(FATAL_ERROR "Unknown arguments to MakeCPIO") 41 | endif() 42 | set(archive_symbol "_cpio_archive") 43 | if(NOT "${MAKE_CPIO_CPIO_SYMBOL}" STREQUAL "") 44 | set(archive_symbol ${MAKE_CPIO_CPIO_SYMBOL}) 45 | endif() 46 | # Check that the reproducible flag is available. Don't use it if it isn't. 47 | CheckCPIOArgument(cpio_reproducible_flag "--reproducible") 48 | set( 49 | commands 50 | "bash;-c;cpio ${cpio_reproducible_flag} --quiet --create -H newc --file=${CMAKE_CURRENT_BINARY_DIR}/archive.${output_name}.cpio;&&" 51 | ) 52 | foreach(file IN LISTS input_files) 53 | # Try and generate reproducible cpio meta-data as we do this: 54 | # - touch -d @0 file sets the modified time to 0 55 | # - --owner=root:root sets user and group values to 0:0 56 | # - --reproducible creates reproducible archives with consistent inodes and device numbering 57 | list( 58 | APPEND 59 | commands 60 | "bash;-c; mkdir -p temp_${output_name} && cd temp_${output_name} && cp -a ${file} . && touch -d 1970-01-01T00:00:00Z `basename ${file}` && echo `basename ${file}` | cpio --append ${cpio_reproducible_flag} --owner=+0:+0 --quiet -o -H newc --file=${CMAKE_CURRENT_BINARY_DIR}/archive.${output_name}.cpio && rm `basename ${file}` && cd ../ && rmdir temp_${output_name};&&" 61 | ) 62 | endforeach() 63 | list(APPEND commands "true") 64 | separate_arguments(cmake_c_flags_sep NATIVE_COMMAND "${CMAKE_C_FLAGS}") 65 | if(CMAKE_C_COMPILER_ID STREQUAL "Clang") 66 | list(APPEND cmake_c_flags_sep "${CMAKE_C_COMPILE_OPTIONS_TARGET}${CMAKE_C_COMPILER_TARGET}") 67 | endif() 68 | 69 | add_custom_command( 70 | OUTPUT ${output_name} 71 | COMMAND rm -f archive.${output_name}.cpio 72 | COMMAND ${commands} 73 | COMMAND 74 | sh -c 75 | "echo 'X.section ._archive_cpio,\"aw\"X.globl ${archive_symbol}, ${archive_symbol}_endX${archive_symbol}:X.incbin \"archive.${output_name}.cpio\"X${archive_symbol}_end:X' | tr X '\\n'" 76 | > ${output_name}.S 77 | COMMAND 78 | ${CMAKE_C_COMPILER} ${cmake_c_flags_sep} -c -o ${output_name} ${output_name}.S 79 | DEPENDS ${input_files} ${MAKE_CPIO_DEPENDS} 80 | VERBATIM 81 | BYPRODUCTS 82 | archive.${output_name}.cpio 83 | ${output_name}.S 84 | COMMENT "Generate CPIO archive ${output_name}" 85 | ) 86 | endfunction(MakeCPIO) 87 | -------------------------------------------------------------------------------- /cmake-tool/helpers/cross_compiling.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | cmake_minimum_required(VERSION 3.16.0) 7 | include_guard(GLOBAL) 8 | 9 | # This path is guaranteed to exist 10 | find_path( 11 | CUSTOM_POLLY_TOOLCHAINS FindPolly.cmake 12 | PATHS ${CMAKE_CURRENT_LIST_DIR}/../polly_toolchains 13 | CMAKE_FIND_ROOT_PATH_BOTH 14 | ) 15 | 16 | function(FindCustomPollyToolchain location toolchain) 17 | find_file( 18 | ${location} ${toolchain}.cmake 19 | PATHS ${CUSTOM_POLLY_TOOLCHAINS} 20 | CMAKE_FIND_ROOT_PATH_BOTH 21 | ) 22 | endfunction() 23 | 24 | # This file is guaranteed to exist 25 | find_file( 26 | PKG_CONFIG_TEMPLATE pkg-config.in 27 | PATHS ${CMAKE_CURRENT_LIST_DIR} 28 | CMAKE_FIND_ROOT_PATH_BOTH 29 | ) 30 | function(CreatePkgConfigExecForDir exec_name sysroot) 31 | configure_file(${PKG_CONFIG_TEMPLATE} ${exec_name} @ONLY) 32 | endfunction() 33 | -------------------------------------------------------------------------------- /cmake-tool/helpers/debug.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | 7 | # This module declares a macro for debugging purposes. 8 | # Simply place a call to set_break() in your build files and you will get a prompt 9 | 10 | macro(set_break) 11 | include(cmakerepl) 12 | endmacro() 13 | 14 | # Mechanism for switching complex commands into and out of the foreground 15 | # Ninja restricts access to stdio for running commands by default. 16 | # Any output will only be printed once the task has completed. 17 | # This can be confusing for commands that take a long time to complete or hang 18 | # on failure instead of returning. 19 | # Foregrounding the tasks by setting USES_TERMINAL solves this problem as Ninja 20 | # lets the process directly access stdio. However this places the command into 21 | # a job pool that only allows one command to run at a time. 22 | # Therefore, CMakeForegroundComplexCommands is provided to allow bulk switching 23 | # of these commands between foreground and background. The intention is that it 24 | # is typically left off unless a build requires debugging in which case performance 25 | # is no longer as important as being able to get more helpful debug info of the 26 | # failing command. 27 | # Note: This requires correctly annotating complex commands with USES_TERMINAL_DEBUG 28 | # in the correct add_custom_command calls. 29 | set(CMakeForegroundComplexCommands OFF CACHE BOOL "Set USES_TERMINAL on specially marked tasks. \ 30 | This makes the task run in the foreground and can directly access stdio. This is helpful for \ 31 | debugging tasks that take a long time, or want to insert a breakpoint into the process. \ 32 | Note: Only one task can run in foreground at a time.") 33 | mark_as_advanced(CMakeForegroundComplexCommands) 34 | if(CMakeForegroundComplexCommands) 35 | set(USES_TERMINAL_DEBUG USES_TERMINAL) 36 | else() 37 | set(USES_TERMINAL_DEBUG "") 38 | endif() 39 | -------------------------------------------------------------------------------- /cmake-tool/helpers/dts.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | cmake_minimum_required(VERSION 3.16.0) 7 | include_guard(GLOBAL) 8 | 9 | # This path is guaranteed to exist 10 | find_path(DTS_PATH "sabre.dts" PATHS ${KERNEL_PATH}/tools/dts CMAKE_FIND_ROOT_PATH_BOTH) 11 | # find a dts file matching platform.dts and put into a cache variable named 12 | # _FOUND_DTS 13 | function(FindDTS var platform) 14 | find_file(${platform}_FOUND_DTS ${platform}.dts PATHS ${DTS_PATH} CMAKE_FIND_ROOT_PATH_BOTH) 15 | if("${${platform}_FOUND_DTS}}" STREQUAL "${platform}_FOUND_DTS-NOTFOUND") 16 | message(WARNING "Could not find default dts file ${PLATFORM.dts}") 17 | endif() 18 | set(${var} ${${platform}_FOUND_DTS} PARENT_SCOPE) 19 | endfunction() 20 | 21 | # generate a dtb from a dts file using the dtc tool 22 | function(GenDTB dts_file var) 23 | # find the dtc tool 24 | find_program(DTC_TOOL dtc) 25 | if("${DTC_TOOL}" STREQUAL "DTC_TOOL-NOTFOUND") 26 | message(FATAL_ERROR "Cannot find 'dtc' program.") 27 | endif() 28 | # check the dts we have been given exists 29 | if(NOT EXISTS "${dts_file}") 30 | message(FATAL_ERROR "Cannot find dts file ${dts_file}") 31 | endif() 32 | # put all the files into /dtb in the binary dir 33 | set(dtb_dir "${CMAKE_BINARY_DIR}/dtb") 34 | file(MAKE_DIRECTORY "${dtb_dir}") 35 | # generate a file name 36 | get_filename_component(FILE_NAME ${dts_file} NAME_WE) 37 | set(filename "${dtb_dir}/${FILE_NAME}.dtb") 38 | set(${var} ${filename} PARENT_SCOPE) 39 | # now add the command to generate the dtb 40 | execute_process( 41 | COMMAND 42 | ${DTC_TOOL} -I dts -O dtb -o ${filename} ${dts_file} 43 | OUTPUT_VARIABLE output 44 | ERROR_VARIABLE output 45 | ) 46 | if(NOT EXISTS "${filename}") 47 | message(FATAL_ERROR "${output} 48 | failed to gen ${filename}") 49 | endif() 50 | endfunction() 51 | -------------------------------------------------------------------------------- /cmake-tool/helpers/elf_sift.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 4 | # 5 | # SPDX-License-Identifier: GPL-2.0-only 6 | # 7 | """ 8 | Extract information of interest to the seL4 image build process from ELF files. 9 | 10 | THIS IS NOT A STABLE API. Use as a script, not a module. 11 | """ 12 | 13 | import argparse 14 | import elftools.elf.elffile 15 | import sys 16 | 17 | from typing import BinaryIO 18 | 19 | 20 | def get_aligned_size(n: int) -> int: 21 | """ 22 | Return the smallest multiple of 4KiB not less than the total of the loadable 23 | segments. (In other words, the size will be returned as-is if it is an 24 | exact multiple of 4KiB, otherwise it is rounded up to the next higher 25 | multiple of 4KiB.) 26 | """ 27 | return n if n % 4096 == 0 else ((n // 4096) + 1) * 4096 28 | 29 | 30 | def get_memory_usage(elf_file: BinaryIO, align: bool) -> int: 31 | """ 32 | Return the size in bytes occuped in memory of the loadable ELF segments from 33 | the ELF object file `elf_file`. 34 | """ 35 | 36 | elf = elftools.elf.elffile.ELFFile(elf_file) 37 | 38 | # We only care about loadable segments (p_type is "PT_LOAD"), and we 39 | # want the size in memory of those segments (p_memsz), which can be 40 | # greater than the size in the file (p_filesz). This is especially 41 | # important for the BSS section. See elf(5). 42 | 43 | # There may be gaps between segments; use the min+max vaddr of 44 | # the loaded segments to calculate total usage. 45 | min_vaddr = None 46 | max_vaddr: int = 0 47 | for seg in elf.iter_segments(): 48 | if seg['p_type'] == 'PT_LOAD': 49 | if min_vaddr is None: 50 | min_vaddr = seg['p_vaddr'] 51 | else: 52 | min_vaddr = min(seg['p_vaddr'], min_vaddr) 53 | max_vaddr = max(seg['p_vaddr'] + seg['p_memsz'], max_vaddr) 54 | 55 | total: int = max_vaddr - min_vaddr 56 | return get_aligned_size(total) if align else total 57 | 58 | 59 | def get_memory_usage_from_file(filename: str, align: bool) -> int: 60 | """ 61 | Return the size in bytes occuped in memory of the loadable ELF segments from 62 | the ELF object file `filename`. 63 | """ 64 | 65 | with open(filename, 'rb') as f: 66 | return get_memory_size(f) 67 | 68 | 69 | def main() -> int: 70 | parser = argparse.ArgumentParser( 71 | formatter_class=argparse.RawDescriptionHelpFormatter, 72 | description=""" 73 | Extract information of interest to the seL4 image build process from ELF files. 74 | 75 | We extract the sizes of loadable ELF segments from the ELF files given as 76 | operands and print their sum. 77 | 78 | If the "--align" flag is specified, the space "after" each ELF file is aligned 79 | to the next 4KiB boundary, increasing the total. 80 | """) 81 | parser.add_argument('elf_file', nargs='+', type=str, 82 | help='ELF object file to examine') 83 | parser.add_argument('--align', action='store_true', 84 | help='align to 4KiB between files') 85 | parser.add_argument('--reserve', metavar='BYTES', type=int, action='store', 86 | default=0, help='number of additional bytes to reserve') 87 | args = parser.parse_args() 88 | regions = [get_memory_usage_from_file(elf, args.align) 89 | for elf in args.elf_file] 90 | regions.append(args.reserve) 91 | total = sum(regions) 92 | 93 | if args.align: 94 | total = get_aligned_size(total) 95 | 96 | print(total) 97 | return 0 98 | 99 | 100 | if __name__ == '__main__': 101 | sys.exit(main()) 102 | -------------------------------------------------------------------------------- /cmake-tool/helpers/external-project-helpers.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | 7 | cmake_minimum_required(VERSION 3.16.0) 8 | 9 | include_guard(GLOBAL) 10 | 11 | # Function for declaring target object files that are produced by an external project. This adds a custom_command 12 | # that forces a stale check on the object file after the External projects install step. 13 | # external_proj_target: Target name of the external project 14 | # external_prog_output_dir: Location of binary or install directory for external project 15 | # FILES: List of object files that exist in the external project 16 | function(DeclareExternalProjObjectFiles external_proj_target external_proj_output_dir) 17 | # Parse the given files object files 18 | cmake_parse_arguments(PARSE_ARGV 2 EXT_OBJECT "" "" "FILES") 19 | if(NOT "${EXT_OBJECT_UNPARSED_ARGUMENTS}" STREQUAL "") 20 | message(FATAL_ERROR "Unknown arguments to DeclareExternalProjObjectFiles") 21 | endif() 22 | # Necessary for FILES to be passed 23 | if(NOT EXT_OBJECT_FILES) 24 | message(FATAL_ERROR "NO FILES declared for ${external_proj_target}") 25 | endif() 26 | # Get external project binary and stamp dir properties 27 | ExternalProject_Get_property(${external_proj_target} STAMP_DIR) 28 | foreach(obj_file IN LISTS EXT_OBJECT_FILES) 29 | # Generate a unique name based on the object files location 30 | set(file_path ${external_proj_output_dir}/${obj_file}) 31 | list(APPEND objfiles ${file_path}) 32 | endforeach() 33 | if(NOT (TARGET ${external_proj_target}-install)) 34 | ExternalProject_Add_StepTargets(${external_proj_target} install) 35 | endif() 36 | add_custom_command( 37 | OUTPUT ${objfiles} 38 | COMMAND true 39 | DEPENDS ${external_proj_target}-install ${STAMP_DIR}/${external_proj_target}-install 40 | ) 41 | endfunction(DeclareExternalProjObjectFiles) 42 | -------------------------------------------------------------------------------- /cmake-tool/helpers/make-uimage: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 4 | # 5 | # SPDX-License-Identifier: GPL-2.0-only 6 | # 7 | 8 | set -eu 9 | 10 | PROGNAME=${0##*/} 11 | 12 | # We use the following exit status conventions: 13 | # 0: normal operation, successful, "true" 14 | # 1: expected failure, "false" 15 | # 2: usage error 16 | # 3: other error 17 | EXIT_STATUS=3 18 | 19 | # Emit diagnostic message. 20 | # @params: a set of strings comprising a human-intelligible message 21 | _print () { 22 | echo "${PROGNAME:-(unknown program)}: $*" 23 | } 24 | 25 | # Emit error message to standard error. 26 | # @params: a set of strings comprising a human-intelligible message 27 | fail () { 28 | _print "error: $*" >&2 29 | } 30 | 31 | # Report unrecoverable error and terminate script. 32 | # @params: a set of strings comprising a human-intelligible message 33 | # 34 | # Note: $EXIT_STATUS, if set in the invoking scope, determines the exit status 35 | # used by this function. 36 | die () { 37 | _print "fatal error: $*" >&2 38 | exit ${EXIT_STATUS:-3} 39 | } 40 | 41 | # Display a usage message. 42 | show_usage () { 43 | cat < /dev/null 73 | then 74 | die "\"$ELF_FILE\" does not appear to be an ELF file" 75 | fi 76 | 77 | set -- $($READELF -s $ELF_FILE | grep -w _start) 78 | echo $2 79 | } 80 | 81 | if [ $# -ne 5 ] 82 | then 83 | fail "expected 5 arguments, got $#: \"$*\"" 84 | show_usage >&2 85 | exit 2 86 | fi 87 | 88 | OBJCOPY=$1 89 | READELF=$2 90 | ELF_FILE=$3 91 | ARCHITECTURE=$4 92 | OUTPUT=$5 93 | 94 | # Validate arguments. $ELF_FILE is validated by get_start_symbol(). We'll let 95 | # mkimage fail if $OUTPUT is not writable. 96 | 97 | if ! [ -x "$OBJCOPY" ] 98 | then 99 | die "\"$OBJCOPY\" does not exist or is not executable" 100 | fi 101 | 102 | case "$ARCHITECTURE" in 103 | (arm|arm64|riscv) 104 | ;; 105 | (*) 106 | EXIT_STATUS=2 107 | die "unrecognized architecture \"$ARCHITECTURE\"" 108 | ;; 109 | esac 110 | 111 | # $ARCHITECTURE is now known to be a safe string and no longer requires 112 | # quotation. 113 | 114 | TEMPFILE=$(mktemp) 115 | trap cleanup HUP INT QUIT TERM EXIT 116 | 117 | # Note: Because we are using a temporary file, the appending redirection is 118 | # important! Do not degenerate it to ">", which will unlink the destination 119 | # first and reintroduce the race that mktemp avoids. 120 | "$OBJCOPY" -O binary "$ELF_FILE" /dev/stdout >> $TEMPFILE 121 | START=$(get_start_symbol "$ELF_FILE") 122 | mkimage -A $ARCHITECTURE -O linux -T kernel -C none \ 123 | -a $START -e $START -d $TEMPFILE "$OUTPUT" 124 | 125 | exit 0 126 | -------------------------------------------------------------------------------- /cmake-tool/helpers/pkg-config.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 4 | # 5 | # SPDX-License-Identifier: BSD-2-Clause 6 | # 7 | @Ignore_the_below_comment@ 8 | # THIS IS A GENERATED FILE. ANY EDITS WILL BE DISCARDED UPON A CMAKE RECONFIGURE 9 | 10 | SYSROOT=@sysroot@ 11 | 12 | export PKG_CONFIG_LIBDIR=${SYSROOT}/lib/pkgconfig:${SYSROOT}/share/pkgconfig 13 | 14 | exec pkg-config "$@" 15 | -------------------------------------------------------------------------------- /cmake-tool/helpers/rust.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | 7 | cmake_minimum_required(VERSION 3.16.0) 8 | include_guard(GLOBAL) 9 | 10 | find_path( 11 | RUST_TARGET_PATH "x86_64-sel4-none.json" 12 | PATHS ${CMAKE_CURRENT_LIST_DIR}/../rust_targets 13 | CMAKE_FIND_ROOT_PATH_BOTH 14 | ) 15 | 16 | # Return absoulute filepath of the rust custom target directory 17 | function(RustGetCustomTargetPath return) 18 | set(${return} "${RUST_TARGET_PATH}" PARENT_SCOPE) 19 | endfunction() 20 | 21 | # add_library but for rust libraries. Invokes cargo in the SOURCE_DIR that is provided, 22 | # all build output is placed in BUILD_DIR or CMAKE_CURRENT_BINARY_DIR if BUILD_DIR isn't provided. 23 | # lib_name: Name of library that is created 24 | # SOURCE_DIR: source directory of cargo project 25 | # BUILD_DIR: directory for cargo build output 26 | # TARGET: custom target to use. See in ../rust_targets/ for list of available targets. 27 | # LIB_FILENAME: filename of library created by cargo 28 | # DEPENDS: And target or file dependencies that need to be run before cargo 29 | function(RustAddLibrary lib_name) 30 | cmake_parse_arguments(PARSE_ARGV 1 RUST "" "SOURCE_DIR;BUILD_DIR;TARGET;LIB_FILENAME" "DEPENDS") 31 | if(NOT "${RUST_UNPARSED_ARGUMENTS}" STREQUAL "") 32 | message(FATAL_ERROR "Unknown arguments to RustAddLibrary ${RUST_UNPARSED_ARGUMENTS}") 33 | endif() 34 | if("${RUST_SOURCE_DIR}" STREQUAL "") 35 | message(FATAL_ERROR "SOURCE_DIR must be set for RustAddLibrary") 36 | endif() 37 | if("${RUST_LIB_FILENAME}" STREQUAL "") 38 | message(FATAL_ERROR "LIB_FILENAME must be set for RustAddLibrary") 39 | endif() 40 | if("${RUST_BUILD_DIR}" STREQUAL "") 41 | set(RUST_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}) 42 | endif() 43 | RustGetCustomTargetPath(target_path) 44 | if("${RUST_TARGET}" STREQUAL "") 45 | message( 46 | FATAL_ERROR 47 | "TARGET must be set for RustAddLibrary. Valid options can be found in: ${target_path}" 48 | ) 49 | endif() 50 | string(FIND "${RUST_TARGET}" ".json" pos) 51 | if(NOT ${pos} EQUAL -1) 52 | message(FATAL_ERROR "${RUST_TARGET} cannot contain .json") 53 | endif() 54 | 55 | find_program(XARGO_TOOL xargo) 56 | if("${XARGO_TOOL}" STREQUAL "XARGO_TOOL-NOTFOUND") 57 | message(FATAL_ERROR "Could not find tool xargo. Install with `cargo install xargo` \ 58 | or see https://github.com/japaric/xargo") 59 | endif() 60 | 61 | add_custom_target( 62 | ${libmain}_custom 63 | BYPRODUCTS 64 | ${RUST_BUILD_DIR}/${RUST_LIB_FILENAME} 65 | ${USES_TERMINAL_DEBUG} 66 | DEPENDS ${RUST_DEPENDS} 67 | WORKING_DIRECTORY ${RUST_SOURCE_DIR} 68 | COMMAND 69 | ${CMAKE_COMMAND} -E env RUST_TARGET_PATH=${target_path} ${XARGO_TOOL} build 70 | --target ${RUST_TARGET} 71 | --target-dir ${RUST_BUILD_DIR} -Z unstable-options 72 | --out-dir ${RUST_BUILD_DIR} 73 | ) 74 | 75 | add_library(${lib_name} STATIC IMPORTED GLOBAL) 76 | set_property( 77 | TARGET ${lib_name} 78 | PROPERTY IMPORTED_LOCATION "${RUST_BUILD_DIR}/${RUST_LIB_FILENAME}" 79 | ) 80 | add_dependencies(${lib_name} ${libmain}_custom) 81 | endfunction() 82 | -------------------------------------------------------------------------------- /cmake-tool/helpers/tls_rootserver.lds: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: BSD-2-Clause 5 | */ 6 | 7 | SECTIONS 8 | { 9 | .tdata : 10 | { 11 | _tdata_start = . ; 12 | *(.tdata .tdata.* .gnu.linkonce.td.*) 13 | _tdata_end = . ; 14 | } 15 | .tbss (NOLOAD): 16 | { 17 | _tbss_start = . ; 18 | *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) 19 | _tbss_end = . ; 20 | } 21 | } 22 | INSERT AFTER .rodata; 23 | -------------------------------------------------------------------------------- /cmake-tool/init-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 4 | # 5 | # SPDX-License-Identifier: BSD-2-Clause 6 | # 7 | 8 | # This script is intended to be symlinked into the same location as your root 9 | # CMakeLists.txt file and then invoked from a clean build directory. 10 | 11 | set -eu 12 | 13 | # Determine path to this script (fast, cheap "dirname"). 14 | SCRIPT_PATH=${0%/*} 15 | # Save script name for diagnostic messages (fast, cheap "basename"). 16 | SCRIPT_NAME=${0##*/} 17 | 18 | # Ensure script path and current working directory are not the same. 19 | if [ "$PWD" = "$SCRIPT_PATH" ] 20 | then 21 | echo "\"$SCRIPT_NAME\" should not be invoked from top-level directory" >&2 22 | exit 1 23 | fi 24 | 25 | # Try and make sure we weren't invoked from a source directory by checking for a 26 | # CMakeLists.txt file. 27 | if [ -e CMakeLists.txt ] 28 | then 29 | echo "\"$SCRIPT_NAME\" should be invoked from a build directory and not" \ 30 | "source directories containing a CMakeLists.txt file" >&2 31 | exit 1 32 | fi 33 | 34 | if [ -d "$HOME/.sel4_cache" ] 35 | then 36 | CACHE_DIR="$HOME/.sel4_cache" 37 | else 38 | CACHE_DIR="$SCRIPT_PATH/.sel4_cache" 39 | fi 40 | 41 | if [ -e "$SCRIPT_PATH/CMakeLists.txt" ] 42 | then 43 | # If we have a CMakeLists.txt in the top level project directory, 44 | # initialize CMake. 45 | cmake -DCMAKE_TOOLCHAIN_FILE="$SCRIPT_PATH"/kernel/gcc.cmake -G Ninja "$@" \ 46 | -DSEL4_CACHE_DIR="$CACHE_DIR" -C "$SCRIPT_PATH/settings.cmake" "$SCRIPT_PATH" 47 | else 48 | # If we don't have a CMakeLists.txt in the top level project directory then 49 | # assume we use the project's directory tied to easy-settings.cmake and resolve 50 | # that to use as the CMake source directory. 51 | real_easy_settings="$(realpath $SCRIPT_PATH/easy-settings.cmake)" 52 | project_dir="$(dirname $real_easy_settings)" 53 | # Initialize CMake. 54 | cmake -G Ninja "$@" -DSEL4_CACHE_DIR="$CACHE_DIR" -C "$project_dir/settings.cmake" "$project_dir" 55 | fi 56 | -------------------------------------------------------------------------------- /cmake-tool/polly_toolchains/FindPolly.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | 7 | cmake_minimum_required(VERSION 3.16.0) 8 | 9 | # Save path to checkout of https://github.com/ruslo/polly 10 | macro(FindPolly) 11 | find_path(POLLY_DIR linux-gcc-x64.cmake ${CMAKE_CURRENT_LIST_DIR}/../../../../tools/polly) 12 | mark_as_advanced(FORCE POLLY_DIR) 13 | if("${POLLY_DIR}" STREQUAL "POLLY_DIR-NOTFOUND") 14 | message(FATAL_ERROR "Failed to find polly. Consider cmake -DPOLLY_DIR=/path/to/polly") 15 | endif() 16 | endmacro() 17 | -------------------------------------------------------------------------------- /cmake-tool/polly_toolchains/linux-gcc-32bit-pic.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | 7 | include(${CMAKE_CURRENT_LIST_DIR}/FindPolly.cmake) 8 | 9 | FindPolly() 10 | include("${POLLY_DIR}/utilities/polly_init.cmake") 11 | 12 | polly_init("Linux / gcc / PIC / c++11 support / 32 bit" "Ninja") 13 | 14 | include("${POLLY_DIR}/utilities/polly_common.cmake") 15 | 16 | include("${POLLY_DIR}/compiler/gcc.cmake") 17 | include("${POLLY_DIR}/flags/cxx11.cmake") 18 | include("${POLLY_DIR}/flags/fpic.cmake") 19 | include("${POLLY_DIR}/flags/32bit.cmake") 20 | -------------------------------------------------------------------------------- /cmake-tool/projects.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | 7 | cmake_minimum_required(VERSION 3.16.0) 8 | 9 | file(GLOB result RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" projects/*/CMakeLists.txt) 10 | 11 | # We sort the results to ensure that builds are deterministic. Whilst build scripts 12 | # should not be written to need a particular order of globbed results here, it is 13 | # better to have reliable builds than random failures 14 | list(SORT result) 15 | 16 | foreach(file ${result}) 17 | string( 18 | REPLACE 19 | "CMakeLists.txt" 20 | "" 21 | file 22 | "${file}" 23 | ) 24 | add_subdirectory("${file}") 25 | endforeach() 26 | -------------------------------------------------------------------------------- /cmake-tool/rust_targets/aarch32-sel4-none.json: -------------------------------------------------------------------------------- 1 | { 2 | "abi-blacklist": [ 3 | "stdcall", 4 | "fastcall", 5 | "vectorcall", 6 | "thiscall", 7 | "win64", 8 | "sysv64" 9 | ], 10 | "arch": "arm", 11 | "data-layout": "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", 12 | "dynamic-linking": true, 13 | "env": "gnu", 14 | "executables": true, 15 | "features": "+strict-align,+v6", 16 | "has-elf-tls": true, 17 | "has-rpath": true, 18 | "is-builtin": true, 19 | "linker-flavor": "gcc", 20 | "linker-is-gnu": true, 21 | "llvm-target": "arm-unknown-linux-gnueabi", 22 | "max-atomic-width": 64, 23 | "os": "linux", 24 | "position-independent-executables": true, 25 | "pre-link-args": { 26 | "gcc": [ 27 | "-Wl,--as-needed", 28 | "-Wl,-z,noexecstack" 29 | ] 30 | }, 31 | "panic-strategy": "abort", 32 | "relro-level": "full", 33 | "target-c-int-width": "32", 34 | "target-endian": "little", 35 | "target-family": "unix", 36 | "target-mcount": "\u0001__gnu_mcount_nc", 37 | "target-pointer-width": "32", 38 | "vendor": "unknown" 39 | } 40 | 41 | -------------------------------------------------------------------------------- /cmake-tool/rust_targets/aarch64-sel4-none.json: -------------------------------------------------------------------------------- 1 | { 2 | "arch": "aarch64", 3 | "os": "none", 4 | "llvm-target": "aarch64-unknown-none", 5 | "data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", 6 | "target-pointer-width": "64", 7 | "target-c-int-width": "32", 8 | "target-endian": "little", 9 | "env": "none", 10 | "pre-link-args" : { 11 | "gcc": ["-m64", "-ffreestanding", "-nodefaultlibs", "-nostdlib", "-fno-stack-protector"] 12 | }, 13 | "post-link-args" : { 14 | "gcc": ["-lgcc", "-lgcc_eh", "-lnosys", "-lm"] 15 | }, 16 | "disable-redzone": true, 17 | "executables": true, 18 | "has-elf-tls": false, 19 | "relocation-model": "static", 20 | "features": "+strict-align,+neon,+fp-armv8", 21 | "is-builtin": true, 22 | "linker-flavor": "gcc", 23 | "linker-is-gnu": true, 24 | "position-independent-executables": false, 25 | "dynamic_linking": false, 26 | "panic-strategy": "abort", 27 | "no-default-libraries": true, 28 | "no-compiler-rt": false, 29 | "max-atomic-width": 128 30 | } 31 | -------------------------------------------------------------------------------- /cmake-tool/rust_targets/x86_64-sel4-none.json: -------------------------------------------------------------------------------- 1 | { 2 | "arch": "x86_64", 3 | "os": "none", 4 | "llvm-target": "x86_64-elf", 5 | "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", 6 | "target-pointer-width": "64", 7 | "target-c-int-width": "64", 8 | "cpu" : "westmere", 9 | "target-endian": "little", 10 | "env": "none", 11 | "pre-link-args" : { 12 | "gcc": ["-m64", "-ffreestanding", "-nodefaultlibs", "-nostdlib", "-fno-stack-protector"] 13 | }, 14 | "post-link-args" : { 15 | "gcc": ["-lgcc", "-lgcc_eh", "-lnosys", "-lm"] 16 | }, 17 | "disable-redzone": false, 18 | "executables": true, 19 | "relocation-model": "pic", 20 | "has-elf-tls": false, 21 | "linker-is-gnu": true, 22 | "relocation-model": "static", 23 | "position-independent-executables": false, 24 | "dynamic_linking": false, 25 | "panic-strategy": "abort", 26 | "no-default-libraries": true, 27 | "no-compiler-rt": false, 28 | "linker-flavor": "gcc" 29 | } 30 | -------------------------------------------------------------------------------- /cmake-tool/simulate_scripts/launch_gdb.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 4 | # 5 | # SPDX-License-Identifier: BSD-2-Clause 6 | # 7 | 8 | import subprocess 9 | import sys 10 | import argparse 11 | import signal 12 | 13 | 14 | def parse_args(): 15 | parser = argparse.ArgumentParser() 16 | parser.add_argument('-b', '--binary', dest='gdb_binary', type=str, 17 | help='GDB binary', default='@GDB_BINARY@') 18 | parser.add_argument('-f', '--file', dest='target_executable', type=str, 19 | help='File to be passed to GDB', default='@QEMU_SIM_INITRD_FILE@') 20 | parser.add_argument('--extra-gdb-args', dest='extra_gdb_args', type=str, 21 | help='Additional arguments to pass to gdb', default='') 22 | args = parser.parse_args() 23 | return args 24 | 25 | 26 | if __name__ == "__main__": 27 | args = parse_args() 28 | 29 | gdb_command_opts = [args.gdb_binary, args.extra_gdb_args, 30 | '-ex "target remote :1234"', args.target_executable] 31 | gdb_command = " ".join(gdb_command_opts) 32 | 33 | print(gdb_command) 34 | # Extra newline to make the command easier to see 35 | print("\n") 36 | 37 | # Ignore SIGINT/Ctrl-C here and forward it to the gdb instance 38 | signal.signal(signal.SIGINT, signal.SIG_IGN) 39 | 40 | subprocess.call(gdb_command, shell=True) 41 | -------------------------------------------------------------------------------- /elfloader-tool/Findelfloader-tool.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | 7 | set(ELFLOADER_CURRENT_DIR "${CMAKE_CURRENT_LIST_DIR}" CACHE STRING "") 8 | mark_as_advanced(ELFLOADER_CURRENT_DIR) 9 | 10 | function(elfloader_import_project) 11 | add_subdirectory(${ELFLOADER_CURRENT_DIR} elfloader) 12 | endfunction() 13 | 14 | include(${ELFLOADER_CURRENT_DIR}/helpers.cmake) 15 | 16 | include(FindPackageHandleStandardArgs) 17 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(elfloader-tool DEFAULT_MSG ELFLOADER_CURRENT_DIR) 18 | -------------------------------------------------------------------------------- /elfloader-tool/helpers.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | 7 | cmake_minimum_required(VERSION 3.16.0) 8 | 9 | # Hook for CAmkES build system. This allows CAmkES projects to 10 | # force a particular rootserver location. 11 | function(SetElfloaderRootserversLast) 12 | set(ElfloaderRootserversLast ON CACHE BOOL "" FORCE) 13 | endfunction() 14 | -------------------------------------------------------------------------------- /elfloader-tool/include/abort.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * Copyright 2021, HENSOLDT Cyber 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-only 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | 12 | NORETURN void abort(void); 13 | 14 | -------------------------------------------------------------------------------- /elfloader-tool/include/arch-arm/32/mode/arm_generic_timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Platforms that use the ARM generic timer in the kernel use the 12 | * virtual counter when not in HYP mode. The offset value does not have 13 | * a fixed reset value so could produce a random starting value for the 14 | * virtual counter at boot. 15 | * 16 | * The offset must be explicitly set to zero in the elfloader before 17 | * dropping to EL1 for the kernel. 18 | */ 19 | static inline void reset_cntvoff(void) 20 | { 21 | if (is_hyp_mode()) { 22 | /* Set CNTVOFF_El2 to zero */ 23 | asm volatile("mcrr p15, 4, %0, %0, c14" :: "r"(0)); 24 | } else { 25 | printf("Not in hyp mode, cannot reset CNTVOFF_EL2\n"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /elfloader-tool/include/arch-arm/32/mode/assembler.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014, General Dynamics C4 Systems 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #pragma once 8 | 9 | /* This file contains useful macros for assembly code. */ 10 | 11 | #ifdef __ASSEMBLER__ 12 | 13 | #define SCTLR(reg) p15, 0, reg, c1, c0, 0 14 | #define CLIDR(reg) p15, 1, reg, c0, c0, 1 15 | #define TTBR0(reg) p15, 0, reg, c2, c0, 0 16 | #define TTBCR(reg) p15, 0, reg, c2, c0, 2 17 | #define DACR(reg) p15, 0, reg, c3, c0, 0 18 | #define IIALL(reg) p15, 0, reg, c7, c5, 0 19 | #define BPIALL(reg) p15, 0, reg, c7, c5, 6 20 | #define DTLBIALL(reg) p15, 0, reg, c8, c6, 0 21 | #define TLBIALL(reg) p15, 0, reg, c8, c7, 0 22 | #define DTLBIASID(reg) p15, 0, reg, c8, c6, 2 23 | #define TLBIASID(reg) p15, 0, reg, c8, c7, 2 24 | #define CONTEXTIDR(reg) p15, 0, reg, c13, c0, 1 25 | 26 | /* Processor mode encodings */ 27 | #define PMODE_USER 0x10 28 | #define PMODE_FIQ 0x11 29 | #define PMODE_IRQ 0x12 30 | #define PMODE_SUPERVISOR 0x13 31 | #define PMODE_ABORT 0x17 32 | #define PMODE_UNDEFINED 0x1b 33 | #define PMODE_SYSTEM 0x1f 34 | 35 | /* Processor exception mask bits */ 36 | #define PMASK_ASYNC_ABORT (1 << 8) 37 | #define PMASK_IRQ (1 << 7) 38 | #define PMASK_FIRQ (1 << 6) 39 | 40 | #define CPSR_SUPERVISOR ( PMASK_FIRQ \ 41 | | PMASK_IRQ \ 42 | | PMASK_ASYNC_ABORT \ 43 | | PMODE_SUPERVISOR ) 44 | 45 | #else /* !__ASSEMBLER__ */ 46 | #warning "Including assembly-specific header in C code" 47 | #endif 48 | 49 | -------------------------------------------------------------------------------- /elfloader-tool/include/arch-arm/32/mode/structures.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014, General Dynamics C4 Systems 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #pragma once 8 | 9 | #define ARM_SECTION_BITS 20 10 | #define ARM_1GB_BLOCK_BITS 30 11 | #define ARM_2MB_BLOCK_BITS 21 12 | 13 | #define PDE_SIZE_BITS 2 14 | #define PD_BITS 12 15 | #define PD_SIZE_BITS (PD_BITS + PDE_SIZE_BITS) 16 | 17 | #define PTE_SIZE_BITS 2 18 | #define PT_BITS 8 19 | #define PT_SIZE_BITS (PT_BITS + PTE_SIZE_BITS) 20 | 21 | #define HYP_PGDE_SIZE_BITS 3 22 | #define HYP_PGD_BITS 2 23 | #define HYP_PGD_SIZE_BITS (HYP_PGD_BITS + HYP_PGDE_SIZE_BITS) 24 | 25 | #define HYP_PMDE_SIZE_BITS 3 26 | #define HYP_PMD_BITS 9 27 | #define HYP_PMD_SIZE_BITS (HYP_PMD_BITS + HYP_PMDE_SIZE_BITS) 28 | 29 | #define GET_PT_INDEX(x) (((x) >> (PAGE_BITS)) & MASK(PT_BITS)) 30 | 31 | extern uint32_t _boot_pd[BIT(PD_BITS)]; 32 | extern uint32_t _boot_pt[BIT(PT_BITS)]; 33 | 34 | extern uint64_t _lpae_boot_pgd[BIT(HYP_PGD_BITS)]; 35 | extern uint64_t _lpae_boot_pmd[BIT(HYP_PGD_BITS + HYP_PMD_BITS)]; 36 | 37 | -------------------------------------------------------------------------------- /elfloader-tool/include/arch-arm/64/mode/arm_generic_timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* 11 | * Platforms that use the ARM generic timer in the kernel use the 12 | * virtual counter when not in HYP mode. The offset value does not have 13 | * a fixed reset value so could produce a random starting value for the 14 | * virtual counter at boot. 15 | * 16 | * The offset must be explicitly set to zero in the elfloader before 17 | * dropping to EL1 for the kernel. 18 | */ 19 | static inline void reset_cntvoff(void) 20 | { 21 | if (is_hyp_mode()) { 22 | /* Set CNTVOFF_El2 to zero */ 23 | asm volatile("msr cntvoff_el2, xzr"); 24 | } else { 25 | printf("Not in hyp mode, cannot reset CNTVOFF_EL2\n"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /elfloader-tool/include/arch-arm/64/mode/structures.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014, General Dynamics C4 Systems 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #pragma once 8 | 9 | #define ARM_1GB_BLOCK_BITS 30 10 | #define ARM_2MB_BLOCK_BITS 21 11 | 12 | #define PGDE_SIZE_BITS 3 13 | #define PGD_BITS 9 14 | #define PGD_SIZE_BITS (PGD_BITS + PGDE_SIZE_BITS) 15 | 16 | #define PUDE_SIZE_BITS 3 17 | #define PUD_BITS 9 18 | #define PUD_SIZE_BITS (PUD_BITS + PUDE_SIZE_BITS) 19 | 20 | #define PMDE_SIZE_BITS 3 21 | #define PMD_BITS 9 22 | #define PMD_SIZE_BITS (PMD_BITS + PMDE_SIZE_BITS) 23 | 24 | #define GET_PGD_INDEX(x) (((x) >> (ARM_2MB_BLOCK_BITS + PMD_BITS + PUD_BITS)) & MASK(PGD_BITS)) 25 | #define GET_PUD_INDEX(x) (((x) >> (ARM_2MB_BLOCK_BITS + PMD_BITS)) & MASK(PUD_BITS)) 26 | #define GET_PMD_INDEX(x) (((x) >> (ARM_2MB_BLOCK_BITS)) & MASK(PMD_BITS)) 27 | 28 | extern uint64_t _boot_pgd_up[BIT(PGD_BITS)]; 29 | extern uint64_t _boot_pud_up[BIT(PUD_BITS)]; 30 | extern uint64_t _boot_pmd_up[BIT(PMD_BITS)]; 31 | 32 | extern uint64_t _boot_pgd_down[BIT(PGD_BITS)]; 33 | extern uint64_t _boot_pud_down[BIT(PUD_BITS)]; 34 | 35 | -------------------------------------------------------------------------------- /elfloader-tool/include/arch-arm/armv/armv7-a/armv/assembler.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014, General Dynamics C4 Systems 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | /* This file contains useful macros for assembly code. */ 12 | 13 | #ifdef __ASSEMBLER__ 14 | 15 | #define CCSIDR(reg) p15, 1, reg, c0, c0, 0 16 | #define CSSELR(reg) p15, 2, reg, c0, c0, 0 17 | #define ACTLR(reg) p15, 0, reg, c1, c0, 1 18 | #define DISW(reg) p15, 0, reg, c7, c6, 2 19 | #define DCISW(reg) p15, 0, reg, c7, c14, 2 20 | #define HVBAR(reg) p15, 4, reg, c12, c0, 0 21 | #define HCR(reg) p15, 4, reg, c1 , c1, 0 22 | #define HSCTLR(reg) p15, 4, reg, c1 , c0, 0 23 | #define HACTLR(reg) p15, 4, reg, c1 , c0, 1 24 | #define HDCR(reg) p15, 4, reg, c1 , c1, 1 25 | #define HCPTR(reg) p15, 4, reg, c1 , c1, 2 26 | #define HSTR(reg) p15, 4, reg, c1 , c1, 3 27 | #define HACR(reg) p15, 4, reg, c1 , c1, 7 28 | #define HTCR(reg) p15, 4, reg, c2 , c0, 2 29 | #define HADFSR(reg) p15, 4, reg, c5 , c1, 0 30 | #define HAIFSR(reg) p15, 4, reg, c5 , c1, 1 31 | #define HSR(reg) p15, 4, reg, c5 , c2, 0 32 | #define HDFAR(reg) p15, 4, reg, c6 , c0, 0 33 | #define HIFAR(reg) p15, 4, reg, c6 , c0, 2 34 | #define HPFAR(reg) p15, 4, reg, c6 , c0, 4 35 | #define HMAIR0(reg) p15, 4, reg, c10, c2, 0 36 | #define HMAIR1(reg) p15, 4, reg, c10, c2, 1 37 | #define HAMAIR0(reg) p15, 4, reg, c10, c3, 0 38 | #define HAMAIR1(reg) p15, 4, reg, c10, c3, 1 39 | #define HTPIDR(reg) p15, 4, reg, c13, c0, 2 40 | #define HTTBR(rh,rl) p15, 4, rl, rh, c2 41 | 42 | .macro dcache op 43 | dmb 44 | mrc CLIDR(r0) 45 | mov r3, r0, lsr #23 //move LoC into position 46 | ands r3, r3, #7 << 1 //extract LoC*2 from clidr 47 | 48 | beq 5f //if loc is 0, then no need to clean 49 | mov r10, #0 //start clean at cache level 0 50 | 51 | 1: 52 | add r2, r10, r10, lsr #1 //work out 3x current cache level 53 | mov r1, r0, lsr r2 //extract cache type bits from clidr 54 | and r1, r1, #7 //mask of the bits for current cache only 55 | cmp r1, #2 //see what cache we have at this level 56 | blt 4f //skip if no cache, or just i-cache 57 | 58 | mcr CSSELR(r10) 59 | isb 60 | 61 | mrc CCSIDR(r1) 62 | and r2, r1, #7 //extract the length of the cache lines 63 | add r2, r2, #4 //add 4 (line length offset) 64 | movw r4, #0x3ff 65 | ands r4, r4, r1, lsr #3 //find maximum number on the way size 66 | clz r5, r4 //find bit position of way size increment 67 | movw r7, #0x7fff 68 | ands r7, r7, r1, lsr #13 //extract max number of the index size 69 | 70 | 2: 71 | mov r9, r7 //create working copy of max index 72 | 73 | 3: 74 | orr r11, r10, r4, lsl r5 //factor way and cache number into r11 75 | orr r11, r11, r9, lsl r2 //factor index number into r11 76 | .ifeqs "\op", "isw" 77 | mcr DISW(r11) 78 | .endif 79 | .ifeqs "\op", "cisw" 80 | mcr DCISW(r11) 81 | .endif 82 | subs r9, r9, #1 //decrement the index 83 | bge 3b 84 | subs r4, r4, #1 //decrement the way 85 | bge 2b 86 | 87 | 4: 88 | add r10, r10, #2 //increment cache number 89 | cmp r3, r10 90 | bgt 1b 91 | 92 | 5: 93 | mov r10, #0 //swith back to cache level 0 94 | mcr p15, 2, r10, c0, c0, 0 //select current cache level in cssr 95 | dsb st 96 | isb 97 | .endm 98 | 99 | #else /* !__ASSEMBLER__ */ 100 | #warning "Including assembly-specific header in C code" 101 | #endif 102 | 103 | -------------------------------------------------------------------------------- /elfloader-tool/include/arch-arm/armv/armv7-a/armv/machine.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #pragma once 8 | 9 | static inline void wfi(void) 10 | { 11 | asm volatile("wfi" ::: "memory"); 12 | } 13 | 14 | static inline void dsb(void) 15 | { 16 | asm volatile("dsb" ::: "memory"); 17 | } 18 | 19 | static inline void dmb(void) 20 | { 21 | asm volatile("dmb" ::: "memory"); 22 | } 23 | 24 | static inline void isb(void) 25 | { 26 | asm volatile("isb" ::: "memory"); 27 | } 28 | 29 | -------------------------------------------------------------------------------- /elfloader-tool/include/arch-arm/armv/armv7-a/armv/smp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #if CONFIG_MAX_NUM_NODES > 1 13 | 14 | #define STACK_SIZE 4096 15 | 16 | extern unsigned long core_stacks[CONFIG_MAX_NUM_NODES][STACK_SIZE / sizeof(unsigned long)] ALIGN(BIT(12)); 17 | void core_entry(uint32_t sp); 18 | int is_core_up(int id); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /elfloader-tool/include/arch-arm/armv/armv7ve: -------------------------------------------------------------------------------- 1 | armv7-a -------------------------------------------------------------------------------- /elfloader-tool/include/arch-arm/armv/armv8-a/32: -------------------------------------------------------------------------------- 1 | ../armv7-a/ -------------------------------------------------------------------------------- /elfloader-tool/include/arch-arm/armv/armv8-a/64/armv/assembler.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014, General Dynamics C4 Systems 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | /* This file contains useful macros for assembly code. */ 12 | 13 | #ifdef __ASSEMBLER__ 14 | 15 | #else /* !__ASSEMBLER__ */ 16 | #warning "Including assembly-specific header in C code" 17 | #endif 18 | 19 | -------------------------------------------------------------------------------- /elfloader-tool/include/arch-arm/armv/armv8-a/64/armv/machine.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #pragma once 8 | 9 | static inline void wfi(void) 10 | { 11 | asm volatile("wfi" ::: "memory"); 12 | } 13 | 14 | static inline void dsb(void) 15 | { 16 | asm volatile("dsb sy" ::: "memory"); 17 | } 18 | 19 | static inline void dmb(void) 20 | { 21 | asm volatile("dmb sy" ::: "memory"); 22 | } 23 | 24 | static inline void isb(void) 25 | { 26 | asm volatile("isb" ::: "memory"); 27 | } 28 | 29 | 30 | #define MRS(reg, v) asm volatile("mrs %0," reg : "=r"(v)) 31 | #define MSR(reg, v) \ 32 | do { \ 33 | word_t _v = v; \ 34 | asm volatile("msr " reg ",%0" :: "r" (_v));\ 35 | } while(0) 36 | -------------------------------------------------------------------------------- /elfloader-tool/include/arch-arm/armv/armv8-a/64/armv/smp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #if CONFIG_MAX_NUM_NODES > 1 13 | 14 | #define STACK_SIZE 4096 15 | 16 | extern unsigned long core_stacks[CONFIG_MAX_NUM_NODES][STACK_SIZE / sizeof(unsigned long)] ALIGN(BIT(12)); 17 | void core_entry(uint64_t sp); 18 | int is_core_up(int id); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /elfloader-tool/include/arch-arm/cpuid.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | /* read ID register from CPUID */ 12 | uint32_t read_cpuid_id(void); 13 | 14 | /* read MP ID register from CPUID */ 15 | uint32_t read_cpuid_mpidr(void); 16 | 17 | /* check if CPU is in HYP/EL2 mode */ 18 | word_t is_hyp_mode(void); 19 | 20 | /* Pretty print CPUID information */ 21 | void print_cpuid(void); 22 | 23 | /* Returns the Cortex-Ax part number, or -1 */ 24 | int get_cortex_a_part(void); 25 | 26 | -------------------------------------------------------------------------------- /elfloader-tool/include/arch-arm/elfloader.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * Copyright 2021, HENSOLDT Cyber 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-only 6 | */ 7 | #pragma once 8 | 9 | #include 10 | 11 | /* This is a low level binary interface, thus we do not preserve the type 12 | * information here. All parameters are just register values (or stack values 13 | * that are register-sized). 14 | */ 15 | typedef void (*init_arm_kernel_t)(word_t ui_p_reg_start, 16 | word_t ui_p_reg_end, 17 | word_t pv_offset, 18 | word_t v_entry, 19 | word_t dtb, 20 | word_t dtb_size); 21 | 22 | 23 | /* Enable the mmu. */ 24 | extern void arm_enable_mmu(void); 25 | extern void arm_enable_hyp_mmu(void); 26 | 27 | 28 | /* Setup boot VSpace. */ 29 | void init_boot_vspace(struct image_info *kernel_info); 30 | void init_hyp_boot_vspace(struct image_info *kernel_info); 31 | 32 | /* Assembly functions. */ 33 | extern void flush_dcache(void); 34 | extern void cpu_idle(void); 35 | 36 | 37 | void smp_boot(void); 38 | 39 | /* Secure monitor call */ 40 | uint32_t smc(uint32_t, uint32_t, uint32_t, uint32_t); 41 | -------------------------------------------------------------------------------- /elfloader-tool/include/arch-arm/psci.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #pragma once 8 | 9 | 10 | #define PSCI_SUCCESS 0 11 | #define PSCI_NOT_SUPPORTED -1 12 | #define PSCI_INVALID_PARAMETERS -2 13 | #define PSCI_DENIED -3 14 | #define PSCI_ALREADY_ON -4 15 | #define PSCI_ON_PENDING -5 16 | #define PSCI_INTERNAL_FAILURE -6 17 | #define PSCI_NOT_PRESETN -7 18 | #define PSCI_DISABLED -8 19 | #define PSCI_INVALID_ADDRESS -9 20 | 21 | #define PSCI_METHOD_SMC 1 22 | #define PSCI_METHOD_HVC 2 23 | 24 | int psci_version(void); 25 | int psci_cpu_suspend(int power_state, unsigned long entry_point, 26 | unsigned long context_id); 27 | /* this function does not return when successful */ 28 | int psci_cpu_off(void); 29 | int psci_cpu_on(unsigned long target_cpu, unsigned long entry_point, 30 | unsigned long context_id); 31 | int psci_system_reset(void); 32 | -------------------------------------------------------------------------------- /elfloader-tool/include/arch-arm/scu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #pragma once 8 | 9 | void scu_enable(void *_scu_base); 10 | unsigned int scu_get_core_count(void *_scu_base); 11 | 12 | -------------------------------------------------------------------------------- /elfloader-tool/include/arch-riscv/elfloader.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * Copyright 2021, HENSOLDT Cyber 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-only 6 | */ 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | /* This is a low level binary interface, thus we do not preserve the type 13 | * information here. All parameters are just register values (or stack values 14 | * that are register-sized). 15 | */ 16 | typedef void (*init_riscv_kernel_t)(word_t ui_p_reg_start, 17 | word_t ui_p_reg_end, 18 | word_t pv_offset, 19 | word_t v_entry, 20 | word_t dtb_addr_p, 21 | word_t dtb_size 22 | #if CONFIG_MAX_NUM_NODES > 1 23 | , 24 | word_t hart_id, 25 | word_t core_id 26 | #endif 27 | ); 28 | -------------------------------------------------------------------------------- /elfloader-tool/include/assembler.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014, General Dynamics C4 Systems 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #pragma once 8 | 9 | #ifdef __ASSEMBLER__ 10 | 11 | /* 12 | * Use BEGIN_FUNC(), END_FUNC() around assembly functions to annotate them 13 | * correctly to the assembler. 14 | */ 15 | #define BEGIN_FUNC(_name) \ 16 | .global _name ; \ 17 | .type _name, %function ; \ 18 | _name: 19 | 20 | #define END_FUNC(_name) \ 21 | .size _name, .-_name 22 | 23 | /* 24 | * BEGIN_FUNC_STATIC() and END_FUNC_STATIC() do as above, but without making a 25 | * global declaration. (c.f. static functions in C). 26 | */ 27 | #define BEGIN_FUNC_STATIC(_name) \ 28 | .type _name, %function ; \ 29 | _name: 30 | 31 | #define END_FUNC_STATIC(_name) \ 32 | .size _name, .-_name 33 | 34 | #else /* !__ASSEMBLER__ */ 35 | #warning "Including assembly-specific header in C code" 36 | #endif 37 | 38 | -------------------------------------------------------------------------------- /elfloader-tool/include/drivers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #pragma once 8 | 9 | int initialise_devices(void); 10 | int initialise_devices_non_boot(void); 11 | -------------------------------------------------------------------------------- /elfloader-tool/include/drivers/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #pragma once 8 | 9 | struct elfloader_device; 10 | struct elfloader_driver; 11 | 12 | typedef int (*driver_init_t)(struct elfloader_device *dev, void *match_data); 13 | 14 | /* 15 | * Each driver has an array of dtb_match_tables. 16 | * The last entry in the array should have compatible = NULL, 17 | * all others contain a compatible string that the driver accepts. 18 | * The match_data pointer will be passed to the driver's init() function. 19 | */ 20 | struct dtb_match_table { 21 | const char *compatible; 22 | void *match_data; 23 | }; 24 | 25 | enum driver_type { 26 | DRIVER_INVALID = 0, 27 | DRIVER_SMP, 28 | DRIVER_UART, 29 | DRIVER_TIMER, 30 | DRIVER_MAX 31 | }; 32 | 33 | struct elfloader_driver { 34 | const struct dtb_match_table *match_table; 35 | enum driver_type type; 36 | driver_init_t init; 37 | driver_init_t init_on_secondary_cores; 38 | /* ops struct, type depends on driver type. */ 39 | const void *ops; 40 | }; 41 | 42 | 43 | extern struct elfloader_driver *__start__driver_list[]; 44 | extern struct elfloader_driver *__stop__driver_list[]; 45 | 46 | #if defined(__has_attribute) && __has_attribute(retain) 47 | #define ELFLOADER_DRIVER(_name) \ 48 | const struct elfloader_driver *_driver_list_##_name \ 49 | __attribute__((unused,retain,section("_driver_list"))) = &_name; 50 | #else 51 | #define ELFLOADER_DRIVER(_name) \ 52 | const struct elfloader_driver *_driver_list_##_name \ 53 | __attribute__((unused,section("_driver_list"))) = &_name; 54 | #endif 55 | -------------------------------------------------------------------------------- /elfloader-tool/include/drivers/smp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | 9 | #pragma once 10 | 11 | #define dev_get_smp(dev) ((struct elfloader_smp_ops *)(dev->drv->ops)) 12 | 13 | struct elfloader_smp_ops { 14 | const char *enable_method; 15 | int (*cpu_on)(struct elfloader_device *smp_dev, struct elfloader_cpu *cpu, void *entry, void *stack); 16 | }; 17 | 18 | struct smp_cpu_data { 19 | void *entry; 20 | void *stack; 21 | }; 22 | 23 | extern struct smp_cpu_data secondary_data; 24 | void secondary_startup(void); 25 | void smp_register_handler(struct elfloader_device *dev); 26 | int plat_cpu_on(struct elfloader_cpu *cpu, void *entry, void *stack); 27 | -------------------------------------------------------------------------------- /elfloader-tool/include/drivers/uart.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | #define dev_get_uart(dev) ((struct elfloader_uart_ops *)(dev->drv->ops)) 12 | 13 | struct elfloader_uart_ops { 14 | int (*putc)(struct elfloader_device *dev, unsigned int c); 15 | }; 16 | 17 | volatile void *uart_get_mmio(void); 18 | void uart_set_out(struct elfloader_device *out); 19 | -------------------------------------------------------------------------------- /elfloader-tool/include/fdt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #pragma once 8 | 9 | size_t fdt_size( 10 | void const *fdt); 11 | -------------------------------------------------------------------------------- /elfloader-tool/include/plat/zynq7000/sys_fputc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #pragma once 8 | 9 | void enable_uart(void); 10 | 11 | -------------------------------------------------------------------------------- /elfloader-tool/include/plat/zynqmp/sys_fputc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017, DornerWorks 3 | * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230) 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-only 6 | * 7 | * This data was produced by DornerWorks, Ltd. of Grand Rapids, MI, USA under 8 | * a DARPA SBIR, Contract Number D16PC00107. 9 | * 10 | * Approved for Public Release, Distribution Unlimited. 11 | */ 12 | 13 | #pragma once 14 | 15 | void enable_uart(void); 16 | -------------------------------------------------------------------------------- /elfloader-tool/include/printf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #pragma once 8 | 9 | #define NULL ((void *)0) 10 | #define FILE void 11 | 12 | int printf(const char *format, ...); 13 | int sprintf(char *buff, const char *format, ...); 14 | 15 | -------------------------------------------------------------------------------- /elfloader-tool/include/strops.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | size_t strlen(const char *str); 12 | int strcmp(const char *a, const char *b); 13 | int strncmp(const char *s1, const char *s2, size_t n); 14 | void *memset(void *s, int c, size_t n); 15 | void *memmove(void *dest, const void *src, size_t n); 16 | void *memcpy(void *dest, const void *src, size_t n); 17 | 18 | -------------------------------------------------------------------------------- /elfloader-tool/include/vargs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | /* 8 | Authors: Ben Leslie 9 | */ 10 | /* 11 | Implementation based on C99 Section 7.15 Variable arguments 12 | */ 13 | 14 | #pragma once 15 | 16 | typedef __builtin_va_list va_list; 17 | 18 | #define va_arg(ap, type) __builtin_va_arg(ap, type) 19 | #define va_copy(dest, src) __builtin_va_copy(dest, src) 20 | #define va_end(ap) __builtin_va_end(ap) 21 | #define va_start(ap, parmN) __builtin_va_start(ap, parmN) 22 | 23 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/32/cpuid.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | 9 | /* we only care about affinity bits */ 10 | #define MPIDR_MASK (0x00ffffff) 11 | /* read MP ID register from CPUID */ 12 | word_t read_cpuid_mpidr(void) 13 | { 14 | uint32_t val; 15 | asm volatile("mrc p15, 0, %0, c0, c0, 5" : "=r"(val) :: "cc"); 16 | return val & MPIDR_MASK; 17 | } 18 | 19 | #define CPSR_MODE_MASK 0x1f 20 | #define CPSR_MODE_HYPERVISOR 0x1a 21 | word_t is_hyp_mode(void) 22 | { 23 | uint32_t val; 24 | asm volatile("mrs %0, cpsr" : "=r"(val) :: "cc"); 25 | return ((val & CPSR_MODE_MASK) == CPSR_MODE_HYPERVISOR); 26 | } 27 | 28 | /* read ID register from CPUID */ 29 | uint32_t read_cpuid_id(void) 30 | { 31 | uint32_t val; 32 | asm volatile("mrc p15, 0, %0, c0, c0, 0" : "=r"(val) :: "cc"); 33 | return val; 34 | } 35 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/32/crt0_64.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | /* This file is used to switch from aarch64 EL2 to aarch32 supervisor mode 8 | * before continuing in the aarch32 elfloader. This allows aarch32 seL4 kernel 9 | * configurations to be loaded from a 64bit entry point 10 | */ 11 | #include 12 | #include 13 | 14 | .section ".text.start" 15 | 16 | BEGIN_FUNC(_start) 17 | /* Clean EL2 dcache */ 18 | dcache cisw 19 | 20 | /* Ensure I-cache, D-cache and mmu are disabled for EL2/Stage1 */ 21 | disable_mmu sctlr_el2, x9 22 | 23 | /* 24 | * Invalidate the local I-cache so that any instructions fetched 25 | * speculatively are discarded. 26 | */ 27 | ic iallu 28 | dsb nsh 29 | isb 30 | 31 | msr sctlr_el1, xzr 32 | /* Ensure traps to EL2 are disabled */ 33 | mov x9, #0x33ff 34 | msr cptr_el2, x9 35 | msr hstr_el2, xzr 36 | msr mdcr_el2, xzr 37 | 38 | /* Set a zero VMID */ 39 | msr vttbr_el2, xzr 40 | 41 | /* Reset CNTVOFF */ 42 | msr cntvoff_el2, xzr 43 | 44 | /* Set lower level execution state to aarch32 */ 45 | msr hcr_el2, xzr 46 | mov x17, #0 47 | bic x17, x17, #(1 << 31) 48 | msr hcr_el2, x17 49 | 50 | /* Setup spsr to return to */ 51 | mov x18, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_MODE_SVC_32) 52 | msr spsr_el2, x18 53 | 54 | /* Set our return address to the instruction after eret. */ 55 | adr x19, 1f 56 | msr elr_el2, x19 57 | eret 58 | 1: 59 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/32/debug.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #define DFSR_FS_MASK 0x40f 12 | #define DFSR_FS_ASYNC_EXT_ABORT 0x406 13 | #define DFSR_FS_ASYNC_PARITY_ERR 0x408 14 | 15 | void check_data_abort_exception(word_t dfsr, UNUSED word_t dfar) 16 | { 17 | //* Check if the data exception is asynchronous external abort or 18 | //* asynchronous parity error on memory access */ 19 | word_t fs = dfsr & DFSR_FS_MASK; 20 | 21 | if ((fs == DFSR_FS_ASYNC_EXT_ABORT) || 22 | (fs == DFSR_FS_ASYNC_PARITY_ERR)) { 23 | return; 24 | } 25 | abort(); 26 | } 27 | 28 | void valid_exception(void) 29 | { 30 | 31 | } 32 | 33 | void invalid_exception(void) 34 | { 35 | abort(); 36 | } 37 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/32/idle.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | 9 | void cpu_idle(void) 10 | { 11 | dsb(); 12 | wfi(); 13 | } 14 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/32/mmu.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #define ARM_VECTOR_TABLE 0xffff0000 12 | extern char arm_vector_table[1]; 13 | /* 14 | * Create a "boot" page directory, which contains a 1:1 mapping below 15 | * the kernel's first vaddr, and a virtual-to-physical mapping above the 16 | * kernel's first vaddr. 17 | */ 18 | void init_boot_vspace(struct image_info *kernel_info) 19 | { 20 | uint32_t i; 21 | vaddr_t first_vaddr = kernel_info->virt_region_start; 22 | paddr_t first_paddr = kernel_info->phys_region_start; 23 | 24 | /* identity mapping below kernel window */ 25 | for (i = 0; i < (first_vaddr >> ARM_SECTION_BITS); i++) { 26 | _boot_pd[i] = (i << ARM_SECTION_BITS) 27 | | BIT(10) /* kernel-only access */ 28 | | BIT(1); /* 1M section */ 29 | } 30 | 31 | /* mapping of kernel window, except last 1M*/ 32 | for (i = 0; i < ((-first_vaddr) >> ARM_SECTION_BITS) - 1; i++) { 33 | _boot_pd[i + (first_vaddr >> ARM_SECTION_BITS)] 34 | = ((i << ARM_SECTION_BITS) + first_paddr) 35 | | BIT(10) /* kernel-only access */ 36 | | BIT(1); /* 1M section */ 37 | } 38 | 39 | /* map page table covering last 1M of virtual address space to page directory */ 40 | _boot_pd[i + (first_vaddr >> ARM_SECTION_BITS)] 41 | = ((uintptr_t)_boot_pt) 42 | | BIT(9) 43 | | BIT(0); /* page table */ 44 | 45 | /* map vector table */ 46 | _boot_pt[GET_PT_INDEX(ARM_VECTOR_TABLE)] 47 | = ((uintptr_t)arm_vector_table) 48 | | BIT(4) /* kernel-only access */ 49 | | BIT(1); /* 4K page */ 50 | } 51 | 52 | /** 53 | * Performs the same operation as init_boot_pd, but initialises 54 | * the LPAE page table. In this case, 3 L2 tables are concatenated. 55 | * PGD entries point to the appropriate L2 table. 56 | */ 57 | void init_hyp_boot_vspace(struct image_info *kernel_info) 58 | { 59 | uint32_t i, k; 60 | vaddr_t first_vaddr = kernel_info->virt_region_start; 61 | paddr_t first_paddr = kernel_info->phys_region_start; 62 | 63 | /* Map in L2 page tables */ 64 | for (i = 0; i < 4; i++) { 65 | _lpae_boot_pgd[i] = ((uintptr_t)_lpae_boot_pmd + (i << PAGE_BITS)) 66 | | BIT(1) /* Page table */ 67 | | BIT(0); /* Valid */ 68 | } 69 | /* identity mapping below kernel window */ 70 | for (i = 0; i < (first_vaddr >> ARM_2MB_BLOCK_BITS); i++) { 71 | _lpae_boot_pmd[i] = (i << ARM_2MB_BLOCK_BITS) 72 | | BIT(10) /* AF - Not always HW managed */ 73 | | BIT(0); /* Valid */ 74 | } 75 | /* mapping of kernel window */ 76 | for (k = 0; k < ((-first_vaddr) >> ARM_2MB_BLOCK_BITS); k++) { 77 | _lpae_boot_pmd[i + k] = ((k << ARM_2MB_BLOCK_BITS) + first_paddr) 78 | | BIT(10) /* AF - Not always HW managed */ 79 | | BIT(0); /* Valid */ 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/32/smp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #if CONFIG_MAX_NUM_NODES > 1 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | unsigned long core_stacks[CONFIG_MAX_NUM_NODES][STACK_SIZE / sizeof(unsigned long)] ALIGN(BIT(12)); 18 | volatile int core_up[CONFIG_MAX_NUM_NODES]; 19 | 20 | extern void core_entry_head(void); 21 | extern void non_boot_main(void); 22 | 23 | void core_entry(uint32_t sp) 24 | { 25 | int id; 26 | // get the logic ID 27 | id = (sp - (unsigned long)&core_stacks[0][0]) / STACK_SIZE; 28 | 29 | core_up[id] = id; 30 | dsb(); 31 | non_boot_main(); 32 | } 33 | 34 | int is_core_up(int i) 35 | { 36 | return core_up[i] == i; 37 | } 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/32/structures.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /* Page directory for Stage1 translation in PL1 (short-desc format)*/ 12 | uint32_t _boot_pd[BIT(PD_BITS)] ALIGN(BIT(PD_SIZE_BITS)); 13 | uint32_t _boot_pt[BIT(PT_BITS)] ALIGN(BIT(PT_SIZE_BITS)); 14 | 15 | /* Page global and middle directory for Stage1 in HYP mode (long-desc format) */ 16 | uint64_t _lpae_boot_pgd[BIT(HYP_PGD_BITS)] ALIGN(BIT(HYP_PGD_SIZE_BITS)); 17 | uint64_t _lpae_boot_pmd[BIT(HYP_PGD_BITS + HYP_PMD_BITS)] ALIGN(BIT(HYP_PMD_SIZE_BITS)); 18 | 19 | /* 20 | * These are helper functions which let the ASM work when we're relocated, 21 | * and save the ASM from manually having to figure out offsets to access these. 22 | */ 23 | void *get_boot_pd(void) 24 | { 25 | return _boot_pd; 26 | } 27 | 28 | void *get_lpae_boot_pgd(void) 29 | { 30 | return _lpae_boot_pgd; 31 | } 32 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/32/traps.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #define ABORTSTACK_SIZE 4096 11 | .text 12 | 13 | .align 12 14 | BEGIN_FUNC(arm_vector_table) 15 | ldr pc, =invalid_vector_entry 16 | ldr pc, =invalid_vector_entry 17 | ldr pc, =invalid_vector_entry 18 | ldr pc, =invalid_vector_entry 19 | ldr pc, =arm_data_abort_exception 20 | ldr pc, =invalid_vector_entry 21 | ldr pc, =arm_irq_exception 22 | ldr pc, =invalid_vector_entry 23 | arm_vector_literals: 24 | .globl arm_vector_literals 25 | .ltorg 26 | END_FUNC(arm_vector_table) 27 | 28 | .align 12 29 | /* 30 | * If any of the following exception happens, then there is something wrong 31 | * with our code, so abort explicitly: 32 | * - Undefined Instruction 33 | * - Supervisor Call 34 | * - Prefetch Abort 35 | */ 36 | BEGIN_FUNC(invalid_vector_entry) 37 | adr sp, _abortstack_bottom 38 | add sp, sp, #ABORTSTACK_SIZE 39 | bl invalid_exception 40 | END_FUNC(invalid_vector_entry) 41 | 42 | /* 43 | * Otherwise, we may receive some exceptions due to bootloader inappropriate 44 | * initialization, simply ignore them: 45 | * - Aborting instruction only if imprecise 46 | * - IRQ next instruction 47 | */ 48 | BEGIN_FUNC(arm_data_abort_exception) 49 | adr sp, _abortstack_bottom 50 | add sp, sp, #ABORTSTACK_SIZE 51 | 52 | /* Store CPSR and LR on stack */ 53 | sub lr, lr, #8 54 | srsdb sp!, #PMODE_ABORT 55 | 56 | mrc p15, 0, r0, c5, c0, 0 /* Get data fault status register. */ 57 | mrc p15, 0, r1, c6, c0, 0 /* Get fault address register. */ 58 | 59 | bl check_data_abort_exception 60 | 61 | /* Jump to NextPC and restore user CPSR */ 62 | rfeia sp! 63 | END_FUNC(arm_data_abort_exception) 64 | 65 | BEGIN_FUNC(arm_irq_exception) 66 | adr sp, _abortstack_bottom 67 | add sp, sp, #ABORTSTACK_SIZE 68 | 69 | /* Store CPSR and LR on stack */ 70 | sub lr, lr, #4 71 | srsdb sp!, #PMODE_IRQ 72 | 73 | bl valid_exception 74 | 75 | /* Jump to NextPC and restore CPSR */ 76 | rfeia sp! 77 | END_FUNC(arm_irq_exception) 78 | 79 | .align 3 80 | _abortstack_bottom: 81 | .space ABORTSTACK_SIZE 82 | _abortstack_top: 83 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/64/cpuid.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | /* we only care about the affinity bits */ 11 | #define MPIDR_MASK (0xff00ffffff) 12 | 13 | word_t read_cpuid_mpidr(void) 14 | { 15 | uint64_t val; 16 | asm volatile("mrs %x0, mpidr_el1" : "=r"(val) :: "cc"); 17 | return val & MPIDR_MASK; 18 | } 19 | 20 | #define CURRENTEL_EL2 (2 << 2) 21 | word_t is_hyp_mode(void) 22 | { 23 | uint32_t val; 24 | asm volatile("mrs %x0, CurrentEL" : "=r"(val) :: "cc"); 25 | return (val == CURRENTEL_EL2); 26 | } 27 | 28 | uint32_t read_cpuid_id(void) 29 | { 30 | uint32_t val; 31 | asm volatile("mrs %x0, midr_el1" : "=r"(val) :: "cc"); 32 | return val; 33 | } 34 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/64/crt0.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | #ifdef CONFIG_IMAGE_BINARY 10 | #include 11 | #endif 12 | 13 | #include 14 | 15 | .extern main 16 | 17 | .section ".text.start" 18 | BEGIN_FUNC(_start) 19 | adrp x19, core_stack_alloc 20 | add x19, x19, #0xff0 21 | mov sp, x19 22 | #ifdef CONFIG_IMAGE_BINARY 23 | /* Store our original arguments before calling subroutines */ 24 | stp x0, x1, [sp, #-16]! 25 | /* 26 | * Binary images may not be loaded in the correct location. 27 | * Try and move ourselves so we're in the right place. 28 | */ 29 | ldr x0, =IMAGE_START_ADDR 30 | adrp x1, _start 31 | add x1, x1, #:lo12:_start 32 | adrp x2, _end 33 | add x2, x2, #:lo12:_end 34 | mov x3, #0 /* Arg 4 of fixup_image_base is dtb=NULL */ 35 | bl fixup_image_base 36 | mov x2, x0 37 | /* fixup_image_base returns 0 if no need to move */ 38 | cmp x2, #0 39 | beq 1f 40 | /* otherwise, jump to the start of the new elfloader */ 41 | /* restore original arguments for restarting at new addr */ 42 | ldp x0, x1, [sp], #16 43 | 44 | br x2 45 | 1: 46 | /* Clear .bss section before calling main */ 47 | bl clear_bss 48 | /* restore original arguments for next step */ 49 | ldp x0, x1, [sp], #16 50 | #endif 51 | b main 52 | END_FUNC(_start) 53 | 54 | /* Move the elf loader out of the kernel's way */ 55 | BEGIN_FUNC(finish_relocation) 56 | /* 57 | * On aarch64 the kernel is loaded at a very high address: 58 | * at least above 0x0000ff8080000000. We assume that 59 | * the ELF loader will never get loaded in a way that overlaps 60 | * with the kernel, so reaching this function is an error. 61 | */ 62 | b abort // should never get here! 63 | END_FUNC(finish_relocation) 64 | 65 | /* secondary cpu startup */ 66 | BEGIN_FUNC(secondary_startup) 67 | /* 68 | * secondary_data is a struct that looks like this: 69 | * 0x0 void *entry 70 | * 0x8 void *stack 71 | */ 72 | adrp x19, secondary_data 73 | add x19, x19, #:lo12:secondary_data 74 | 75 | ldr x0, [x19, #0x8] // load stack 76 | mov sp, x0 77 | ldr x1, [x19, #0x0] // load entry point 78 | 79 | br x1 80 | END_FUNC(secondary_startup) 81 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/64/debug.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #define print_register(_r) do{ \ 12 | uint64_t val; \ 13 | asm volatile("mrs %0," #_r : "=r"(val)); \ 14 | printf(#_r": %lx\n", val); \ 15 | }while(0) 16 | 17 | void invalid_vector_entry(void) 18 | { 19 | printf("ELF-LOADER: Invalid exception received!\n"); 20 | abort(); 21 | } 22 | 23 | void el1_sync(void) 24 | { 25 | printf("ELF-LOADER: Synchronous exception received:\n"); 26 | print_register(esr_el1); 27 | print_register(elr_el1); 28 | print_register(spsr_el1); 29 | print_register(far_el1); 30 | abort(); 31 | } 32 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/64/mmu.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | /* 16 | * Create a "boot" page table, which contains a 1:1 mapping below 17 | * the kernel's first vaddr, and a virtual-to-physical mapping above the 18 | * kernel's first vaddr. 19 | */ 20 | void init_boot_vspace(struct image_info *kernel_info) 21 | { 22 | word_t i; 23 | 24 | vaddr_t first_vaddr = kernel_info->virt_region_start; 25 | vaddr_t last_vaddr = kernel_info->virt_region_end; 26 | paddr_t first_paddr = kernel_info->phys_region_start; 27 | 28 | _boot_pgd_down[0] = ((uintptr_t)_boot_pud_down) | BIT(1) | BIT(0); /* its a page table */ 29 | 30 | for (i = 0; i < BIT(PUD_BITS); i++) { 31 | _boot_pud_down[i] = (i << ARM_1GB_BLOCK_BITS) 32 | | BIT(10) /* access flag */ 33 | | (0 << 2) /* strongly ordered memory */ 34 | | BIT(0); /* 1G block */ 35 | } 36 | 37 | _boot_pgd_up[GET_PGD_INDEX(first_vaddr)] 38 | = ((uintptr_t)_boot_pud_up) | BIT(1) | BIT(0); /* its a page table */ 39 | 40 | _boot_pud_up[GET_PUD_INDEX(first_vaddr)] 41 | = ((uintptr_t)_boot_pmd_up) | BIT(1) | BIT(0); /* its a page table */ 42 | 43 | /* We only map in 1 GiB, so check that the kernel doesn't cross 1GiB boundary. */ 44 | if ((first_vaddr & ~MASK(ARM_1GB_BLOCK_BITS)) != (last_vaddr & ~MASK(ARM_1GB_BLOCK_BITS))) { 45 | printf("We only map 1GiB, but kernel vaddr range covers multiple GiB.\n"); 46 | abort(); 47 | } 48 | for (i = GET_PMD_INDEX(first_vaddr); i < BIT(PMD_BITS); i++) { 49 | _boot_pmd_up[i] = first_paddr 50 | | BIT(10) /* access flag */ 51 | #if CONFIG_MAX_NUM_NODES > 1 52 | | (3 << 8) /* make sure the shareability is the same as the kernel's */ 53 | #endif 54 | | (4 << 2) /* MT_NORMAL memory */ 55 | | BIT(0); /* 2M block */ 56 | first_paddr += BIT(ARM_2MB_BLOCK_BITS); 57 | } 58 | } 59 | 60 | void init_hyp_boot_vspace(struct image_info *kernel_info) 61 | { 62 | word_t i; 63 | word_t pmd_index; 64 | vaddr_t first_vaddr = kernel_info->virt_region_start; 65 | paddr_t first_paddr = kernel_info->phys_region_start; 66 | _boot_pgd_down[0] = ((uintptr_t)_boot_pud_down) | BIT(1) | BIT(0); 67 | 68 | for (i = 0; i < BIT(PUD_BITS); i++) { 69 | _boot_pud_down[i] = (i << ARM_1GB_BLOCK_BITS) 70 | | BIT(10) /* access flag */ 71 | | (0 << 2) /* strongly ordered memory */ 72 | | BIT(0); /* 1G block */ 73 | } 74 | 75 | _boot_pgd_down[GET_PGD_INDEX(first_vaddr)] 76 | = ((uintptr_t)_boot_pud_up) | BIT(1) | BIT(0); /* its a page table */ 77 | 78 | _boot_pud_up[GET_PUD_INDEX(first_vaddr)] 79 | = ((uintptr_t)_boot_pmd_up) | BIT(1) | BIT(0); /* its a page table */ 80 | 81 | pmd_index = GET_PMD_INDEX(first_vaddr); 82 | for (i = pmd_index; i < BIT(PMD_BITS); i++) { 83 | _boot_pmd_up[i] = (((i - pmd_index) << ARM_2MB_BLOCK_BITS) + first_paddr) 84 | | BIT(10) /* access flag */ 85 | #if CONFIG_MAX_NUM_NODES > 1 86 | | (3 << 8) 87 | #endif 88 | | (4 << 2) /* MT_NORMAL memory */ 89 | | BIT(0); /* 2M block */ 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/64/structures.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /* Paging structures for kernel mapping */ 12 | uint64_t _boot_pgd_up[BIT(PGD_BITS)] ALIGN(BIT(PGD_SIZE_BITS)); 13 | uint64_t _boot_pud_up[BIT(PUD_BITS)] ALIGN(BIT(PUD_SIZE_BITS)); 14 | uint64_t _boot_pmd_up[BIT(PMD_BITS)] ALIGN(BIT(PMD_SIZE_BITS)); 15 | 16 | /* Paging structures for identity mapping */ 17 | uint64_t _boot_pgd_down[BIT(PGD_BITS)] ALIGN(BIT(PGD_SIZE_BITS)); 18 | uint64_t _boot_pud_down[BIT(PUD_BITS)] ALIGN(BIT(PUD_SIZE_BITS)); 19 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/64/traps.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | .text 11 | 12 | .extern invalid_vector_entry 13 | .extern el1_sync 14 | 15 | .macro ventry label 16 | .align 7 17 | b \label 18 | .endm 19 | 20 | .align 12 21 | BEGIN_FUNC(arm_vector_table) 22 | ventry invalid_vector_entry // Synchronous EL1t 23 | ventry invalid_vector_entry // IRQ EL1t 24 | ventry invalid_vector_entry // FIQ EL1t 25 | ventry invalid_vector_entry // SError EL1t 26 | 27 | ventry el1_sync // Synchronous EL1h 28 | ventry invalid_vector_entry // IRQ EL1h 29 | ventry invalid_vector_entry // FIQ EL1h 30 | ventry invalid_vector_entry // SError EL1h 31 | 32 | ventry invalid_vector_entry // Synchronous 64-bit EL0 33 | ventry invalid_vector_entry // IRQ 64-bit EL0 34 | ventry invalid_vector_entry // FIQ 64-bit EL0 35 | ventry invalid_vector_entry // SError 64-bit EL0 36 | 37 | ventry invalid_vector_entry // Synchronous 32-bit EL0 38 | ventry invalid_vector_entry // IRQ 32-bit EL0 39 | ventry invalid_vector_entry // FIQ 32-bit EL0 40 | ventry invalid_vector_entry // SError 32-bit EL0 41 | END_FUNC(arm_vector_table) 42 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/README.md: -------------------------------------------------------------------------------- 1 | 11 | 12 | The elfloader Kconfig isn't accessable in most of the top-level Kconfigs. 13 | Therefore, there are two ways to use the hashing algorithms: 14 | 1. CONFIG_HASH_INSTRUCTIONS=y in your defconfig 15 | CONFIG_HASH_SHA (optional - remove if you want to md5 hash) 16 | 2. Include the elf-loader's Kconfig under a new menu in your top-level Kconfig 17 | like this: 18 | 19 | menu "Tools" 20 | source "tools/elfloader/Kconfig" 21 | endmenu 22 | 23 | Either one of these options will allow the user to select the hashing process. 24 | 25 | Please note, this process will add boottime, as hashing a very long file tends to take some time. 26 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/armv/armv7-a/32/mmu-hyp.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | .text 14 | 15 | .extern _lpae_boot_pgd 16 | .extern flush_dcache 17 | .extern invalidate_dcache 18 | .extern invalidate_icache 19 | 20 | BEGIN_FUNC(leave_hyp) 21 | .arch_extension virt 22 | ldr r0, =CPSR_SUPERVISOR 23 | msr spsr_hyp, r0 24 | msr sp_svc, sp 25 | msr elr_hyp, lr 26 | eret 27 | END_FUNC(leave_hyp) 28 | 29 | /* 30 | * Enable the ARM MMU. 31 | * 32 | * It is expected that the code of this function will be mapped 1:1 33 | * virtual/physical in the pagetable we activate. 34 | */ 35 | BEGIN_FUNC(arm_enable_hyp_mmu) 36 | stmfd sp!, {lr} 37 | 38 | /* Clean D-Cache if enabled */ 39 | mrc HSCTLR(r1) 40 | and r1, r1, #(1 << 2) 41 | cmp r1, #0 42 | bleq flush_dcache 43 | 44 | /* Ensure I-cache, D-cache and mmu are disabled. */ 45 | mrc HSCTLR(r1) 46 | bic r1, r1, #(1 << 12) /* Disable I-cache */ 47 | bic r1, r1, #(1 << 2) /* Disable D-Cache */ 48 | bic r1, r1, #(1 << 0) /* Disable MMU */ 49 | mcr HSCTLR(r1) 50 | 51 | /* invalidate caches. */ 52 | bl invalidate_dcache 53 | bl invalidate_icache 54 | 55 | /* Setup MAIR - Strongly ordered non-cachable for all index */ 56 | mov r1, #0 57 | mcr HMAIR0(r1) 58 | mcr HMAIR1(r1) 59 | 60 | /* Set up the page table */ 61 | bl get_lpae_boot_pgd 62 | mov r1, #0 63 | mov r2, #(1<<31) 64 | mcrr HTTBR(r1,r0) 65 | mcr HTCR(r2) 66 | 67 | /* Invalidate TLB */ 68 | mcr DTLBIALL(r1) 69 | 70 | /* Enable MMU, D-cache, and I-cache. */ 71 | mrc HSCTLR(r0) 72 | orr r0, r0, #(1 << 2) // enable dcache 73 | orr r0, r0, #(1 << 12) // enable icache 74 | orr r0, r0, #(1 << 0) // MMU enable 75 | mcr HSCTLR(r0) 76 | 77 | #if CONFIG_MAX_NUM_NODES > 1 78 | /* Enable SMP */ 79 | mrc p15, 0, r0, c1, c0, 1 80 | orr r0, r0, #(1 << 6) // enable SMP bit 81 | mcr p15, 0, r0, c1, c0, 1 82 | #endif /* CONFIG_MAX_NUM_NODES > 1 */ 83 | 84 | ldmfd sp!, {pc} 85 | END_FUNC(arm_enable_hyp_mmu) 86 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/armv/armv7-a/32/mmu.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | .text 14 | 15 | .extern _boot_pd 16 | 17 | BEGIN_FUNC(invalidate_dcache) 18 | stmfd sp!, {r4-r11,lr} 19 | dcache isw 20 | ldmfd sp!, {r4-r11,pc} 21 | END_FUNC(invalidate_dcache) 22 | 23 | BEGIN_FUNC(invalidate_icache) 24 | mcr IIALL(r1) 25 | bx lr 26 | END_FUNC(invalidate_icache) 27 | 28 | BEGIN_FUNC(flush_dcache) 29 | stmfd sp!, {r4-r11,lr} 30 | dcache cisw 31 | ldmfd sp!, {r4-r11,pc} 32 | END_FUNC(flush_dcache) 33 | 34 | /* 35 | * Enable the ARM MMU. 36 | * 37 | * It is expected that the code of this function will be mapped 1:1 38 | * virtual/physical in the pagetable we activate. 39 | */ 40 | BEGIN_FUNC(arm_enable_mmu) 41 | stmfd sp!, {lr} 42 | 43 | /* Clean D-Cache if enabled */ 44 | mrc SCTLR(r1) 45 | and r1, r1, #(1 << 2) 46 | cmp r1, #0 47 | beq 1f 48 | bl flush_dcache 49 | 1: 50 | /* Ensure I-cache, D-cache and mmu are disabled. */ 51 | mrc SCTLR(r1) 52 | bic r1, r1, #(1 << 12) /* Disable I-cache */ 53 | bic r1, r1, #(1 << 2) /* Disable D-Cache */ 54 | bic r1, r1, #(1 << 0) /* Disable MMU */ 55 | mcr SCTLR(r1) 56 | 57 | /* invalidate caches. */ 58 | bl invalidate_dcache 59 | bl invalidate_icache 60 | 61 | /* Set up TTBR0, enable caching of pagetables. */ 62 | bl get_boot_pd 63 | orr r1, r0, #0x19 64 | mcr TTBR0(r1) 65 | mcr TLBIALL(r1) 66 | 67 | /* Setup client to only have access to domain 0, and setup the DACR. */ 68 | mov r1, #1 69 | mcr DACR(r1) 70 | 71 | /* Setup misc MMU. */ 72 | mov r1, #0 73 | mcr CONTEXTIDR(r1) /* set ASID to 0 */ 74 | mcr TTBCR(r1) /* set TTBCR to 0 */ 75 | mcr BPIALL(r1) /* flush branch target cache */ 76 | isb 77 | 78 | /* Enable MMU, D-cache, and I-cache. */ 79 | mrc SCTLR(r0) 80 | orr r0, r0, #(1 << 13) /* selects the base address of the exception vectors */ 81 | orr r0, r0, #(1 << 12) /* Enable I-cache */ 82 | orr r0, r0, #(1 << 2) /* Enable D-cache */ 83 | orr r0, r0, #(1 << 0) /* Enable MMU */ 84 | mcr SCTLR(r0) 85 | 86 | /* Enable/disable Async aborts to drain pending bootloader aborts */ 87 | cpsie a 88 | dsb 89 | isb 90 | cpsid a 91 | 92 | ldmfd sp!, {pc} 93 | END_FUNC(arm_enable_mmu) 94 | 95 | BEGIN_FUNC(arm_disable_dcaches) 96 | stmfd sp!, {lr} 97 | 98 | /* Clean D-Cache if enabled */ 99 | mrc SCTLR(r1) 100 | and r1, r1, #(1 << 2) 101 | cmp r1, #0 102 | beq 1f 103 | bl flush_dcache 104 | 1: 105 | /* disable D-cache disabled. */ 106 | mrc SCTLR(r1) 107 | bic r1, r1, #(1 << 2) /* Disable D-Cache */ 108 | mcr SCTLR(r1) 109 | 110 | /* invalidate dcaches. */ 111 | bl invalidate_dcache 112 | 113 | ldmfd sp!, {pc} 114 | END_FUNC(arm_disable_dcaches) 115 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/armv/armv7-a/32/smc.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | 9 | .text 10 | 11 | BEGIN_FUNC(smc) 12 | .arch_extension sec 13 | stmfd sp!, {r3-r11, lr} 14 | dsb 15 | smc #0 16 | ldmfd sp!, {r3-r11, pc} 17 | END_FUNC(smc) 18 | 19 | BEGIN_FUNC(psci_func) 20 | .arch_extension sec 21 | stmfd sp!, {r3-r11, lr} 22 | dsb 23 | smc #0 24 | ldmfd sp!, {r3-r11, pc} 25 | END_FUNC(psci_func) 26 | 27 | 28 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/armv/armv7ve: -------------------------------------------------------------------------------- 1 | armv7-a -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/armv/armv8-a/32: -------------------------------------------------------------------------------- 1 | ../../armv/armv7-a/32/ -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/armv/armv8-a/64/mmu-hyp.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #ifdef CONFIG_ARM_PA_SIZE_BITS_40 12 | #define TCR_PS TCR_PS_1T 13 | #else 14 | #define TCR_PS TCR_PS_16T 15 | #endif 16 | 17 | .text 18 | 19 | .extern flush_dcache 20 | .extern invalidate_dcache 21 | .extern invalidate_icache 22 | .extern _boot_pgd_down 23 | 24 | BEGIN_FUNC(disable_caches_hyp) 25 | stp x29, x30, [sp, #-16]! 26 | mov x29, sp 27 | bl flush_dcache 28 | disable_id_cache sctlr_el2, x9 29 | ldp x29, x30, [sp], #16 30 | ret 31 | END_FUNC(disable_caches_hyp) 32 | 33 | BEGIN_FUNC(leave_hyp) 34 | /* We call nested functions, follow the ABI. */ 35 | stp x29, x30, [sp, #-16]! 36 | mov x29, sp 37 | 38 | bl flush_dcache 39 | 40 | /* Ensure I-cache, D-cache and mmu are disabled for EL2/Stage1 */ 41 | disable_mmu sctlr_el2, x9 42 | 43 | /* 44 | * Invalidate the local I-cache so that any instructions fetched 45 | * speculatively are discarded. 46 | */ 47 | bl invalidate_icache 48 | 49 | /* Ensure I-cache, D-cache and mmu are disabled for EL1/Stage2 */ 50 | mov x9, #(1 << 31) 51 | msr hcr_el2, x9 52 | 53 | /* Ensure traps to EL2 are disabled */ 54 | mov x9, #0x33ff 55 | msr cptr_el2, x9 56 | msr hstr_el2, xzr 57 | msr vttbr_el2, xzr 58 | 59 | /* Ensure I-cache, D-cache and mmu are disabled for EL1/Stage1 */ 60 | disable_mmu sctlr_el1 , x9 61 | 62 | mov x9, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT | PSR_MODE_EL1h) 63 | msr spsr_el2, x9 64 | 65 | /* Let's the caller use our stack, in case it needs to pop something */ 66 | ldp x29, x30, [sp], #16 67 | mov x10, sp 68 | msr sp_el1, x10 69 | msr elr_el2, x30 70 | eret 71 | END_FUNC(leave_hyp) 72 | 73 | BEGIN_FUNC(arm_enable_hyp_mmu) 74 | stp x29, x30, [sp, #-16]! 75 | mov x29, sp 76 | 77 | bl flush_dcache 78 | 79 | disable_mmu sctlr_el2, x8 80 | 81 | bl invalidate_icache 82 | 83 | /* 84 | * DEVICE_nGnRnE 000 00000000 85 | * DEVICE_nGnRE 001 00000100 86 | * DEVICE_GRE 010 00001100 87 | * NORMAL_NC 011 01000100 88 | * NORMAL 100 11111111 89 | * NORMAL_WT 101 10101010 90 | */ 91 | ldr x5, =MAIR(0x00, MT_DEVICE_nGnRnE) | \ 92 | MAIR(0x04, MT_DEVICE_nGnRE) | \ 93 | MAIR(0x0c, MT_DEVICE_GRE) | \ 94 | MAIR(0x44, MT_NORMAL_NC) | \ 95 | MAIR(0xff, MT_NORMAL) | \ 96 | MAIR(0xaa, MT_NORMAL_WT) 97 | msr mair_el2, x5 98 | ldr x8, =TCR_T0SZ(48) | TCR_IRGN0_WBWC | TCR_ORGN0_WBWC | TCR_SH0_ISH | TCR_TG0_4K | TCR_PS | TCR_EL2_RES1 99 | msr tcr_el2, x8 100 | isb 101 | 102 | adrp x8, _boot_pgd_down 103 | msr ttbr0_el2, x8 104 | isb 105 | 106 | tlbi alle2is 107 | dsb ish 108 | isb 109 | 110 | enable_mmu sctlr_el2, x8 111 | ic ialluis 112 | dsb ish 113 | isb 114 | tlbi alle2is 115 | dsb ish 116 | isb 117 | ldp x29, x30, [sp], #16 118 | ret 119 | END_FUNC(arm_enable_hyp_mmu) 120 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/armv/armv8-a/64/mmu.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #if CONFIG_MAX_NUM_NODES > 1 13 | #define TCR_ISH TCR_SHARED 14 | #else 15 | #define TCR_ISH 0 16 | #endif 17 | 18 | .text 19 | 20 | .extern _boot_pgd_up 21 | .extern _boot_pgd_down 22 | .extern arm_vector_table 23 | 24 | BEGIN_FUNC(invalidate_dcache) 25 | dcache isw 26 | ret 27 | END_FUNC(invalidate_dcache) 28 | 29 | BEGIN_FUNC(invalidate_icache) 30 | ic iallu 31 | dsb nsh 32 | isb 33 | ret 34 | END_FUNC(invalidate_icache) 35 | 36 | BEGIN_FUNC(flush_dcache) 37 | dcache cisw 38 | ret 39 | END_FUNC(flush_dcache) 40 | 41 | BEGIN_FUNC(arm_enable_mmu) 42 | /* We call nested functions, follow the ABI. */ 43 | stp x29, x30, [sp, #-16]! 44 | mov x29, sp 45 | 46 | bl flush_dcache 47 | 48 | /* Ensure I-cache, D-cache and mmu are disabled for EL1/Stage1 */ 49 | disable_mmu sctlr_el1 , x8 50 | 51 | /* 52 | * Invalidate the local I-cache so that any instructions fetched 53 | * speculatively are discarded. 54 | */ 55 | bl invalidate_icache 56 | 57 | /* 58 | * DEVICE_nGnRnE 000 00000000 59 | * DEVICE_nGnRE 001 00000100 60 | * DEVICE_GRE 010 00001100 61 | * NORMAL_NC 011 01000100 62 | * NORMAL 100 11111111 63 | * NORMAL_WT 101 10101010 64 | */ 65 | ldr x5, =MAIR(0x00, MT_DEVICE_nGnRnE) | \ 66 | MAIR(0x04, MT_DEVICE_nGnRE) | \ 67 | MAIR(0x0c, MT_DEVICE_GRE) | \ 68 | MAIR(0x44, MT_NORMAL_NC) | \ 69 | MAIR(0xff, MT_NORMAL) | \ 70 | MAIR(0xaa, MT_NORMAL_WT) 71 | msr mair_el1, x5 72 | 73 | ldr x10, =TCR_TxSZ(48) | TCR_IRGN_WBWA | TCR_ORGN_WBWA | TCR_TG0_4K | TCR_TG1_4K | TCR_ASID16 | TCR_ISH 74 | mrs x9, ID_AA64MMFR0_EL1 75 | bfi x10, x9, #32, #3 76 | msr tcr_el1, x10 77 | 78 | /* Setup page tables */ 79 | adrp x8, _boot_pgd_down 80 | msr ttbr0_el1, x8 81 | adrp x8, _boot_pgd_up 82 | msr ttbr1_el1, x8 83 | isb 84 | 85 | /* invalidate all TLB entries for EL1 */ 86 | tlbi vmalle1is 87 | dsb ish 88 | isb 89 | 90 | enable_mmu sctlr_el1 , x8 91 | 92 | adrp x8, arm_vector_table 93 | msr vbar_el1, x8 94 | 95 | ldp x29, x30, [sp], #16 96 | ret 97 | END_FUNC(arm_enable_mmu) 98 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/armv/armv8-a/64/psci_asm.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | .text 11 | 12 | BEGIN_FUNC(psci_func) 13 | smc #0 14 | ret 15 | END_FUNC(psci_func) 16 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/armv/armv8-a/64/smp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #if CONFIG_MAX_NUM_NODES > 1 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | unsigned long core_stacks[CONFIG_MAX_NUM_NODES][STACK_SIZE / sizeof(unsigned long)] ALIGN(BIT(12)); 18 | volatile int core_up[CONFIG_MAX_NUM_NODES]; 19 | 20 | extern void core_entry_head(void); 21 | extern void non_boot_main(void); 22 | 23 | void core_entry(uint64_t sp) 24 | { 25 | int id; 26 | // get the logic ID 27 | id = (sp - (unsigned long)&core_stacks[0][0]) / STACK_SIZE; 28 | // save the ID and pass it to the kernel 29 | MSR("tpidr_el1", id); 30 | 31 | core_up[id] = id; 32 | dmb(); 33 | non_boot_main(); 34 | } 35 | 36 | int is_core_up(int i) 37 | { 38 | return core_up[i] == i; 39 | } 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/drivers/smp-imx6.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Linux Kernel team 3 | * Copyright 2020, HENSOLDT Cyber GmbH 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-only 6 | * 7 | * The code in here is loosely derived from the Linux kernel 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #define REG(base, offs) ((volatile word_t *)(((uintptr_t)base) + (offs))) 24 | 25 | #define SRC_SCR 0x000 26 | #define SRC_GPR1 0x020 27 | #define BP_SRC_SCR_WARM_RESET_ENABLE 0 28 | #define BP_SRC_SCR_CORE1_RST 14 29 | #define BP_SRC_SCR_CORE1_ENABLE 22 30 | 31 | 32 | UNUSED static void *get_scu_base(void) 33 | { 34 | void *scu = NULL; 35 | #if CONFIG_ARCH_AARCH32 36 | asm("mrc p15, 4, %0, c15, c0, 0" : "=r"(scu)); 37 | #else 38 | abort(); 39 | #endif 40 | return scu; 41 | } 42 | 43 | UNUSED static void src_init(volatile void *mmio) 44 | { 45 | uint32_t val; 46 | val = *REG(mmio, SRC_SCR); 47 | val &= ~(1 << BP_SRC_SCR_WARM_RESET_ENABLE); 48 | *REG(mmio, SRC_SCR) = val; 49 | } 50 | 51 | static int smp_imx6_cpu_on(UNUSED struct elfloader_device *dev, 52 | UNUSED struct elfloader_cpu *cpu, UNUSED void *entry, UNUSED void *stack) 53 | { 54 | #if CONFIG_MAX_NUM_NODES > 1 55 | volatile void *mmio = dev->region_bases[0]; 56 | secondary_data.entry = entry; 57 | secondary_data.stack = stack; 58 | *REG(mmio, SRC_GPR1 + (cpu->cpu_id * 8)) = (word_t)secondary_startup; 59 | dsb(); 60 | 61 | if (cpu->cpu_id == 0) { 62 | /* there is no core0_enable bit in the SCR register */ 63 | printf("error: cannot power on CPU 0!\n"); 64 | return -1; 65 | } 66 | 67 | uint32_t mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + (cpu->cpu_id - 1)); 68 | *REG(mmio, SRC_SCR) |= mask; 69 | return 0; 70 | #else 71 | return -1; 72 | #endif 73 | } 74 | 75 | static int smp_imx6_init(UNUSED struct elfloader_device *dev, 76 | UNUSED void *match_data) 77 | { 78 | #if CONFIG_MAX_NUM_NODES > 1 79 | void *scu = get_scu_base(); 80 | scu_enable(scu); 81 | src_init(dev->region_bases[0]); 82 | smp_register_handler(dev); 83 | #endif 84 | return 0; 85 | } 86 | 87 | 88 | static const struct dtb_match_table smp_imx6_matches[] = { 89 | { .compatible = "fsl,imx6q-src" }, 90 | { .compatible = "fsl,imx6sx-src" }, 91 | { .compatible = NULL /* sentinel */ }, 92 | }; 93 | 94 | static const struct elfloader_smp_ops smp_imx6_ops = { 95 | .enable_method = NULL, 96 | .cpu_on = &smp_imx6_cpu_on, 97 | }; 98 | 99 | static const struct elfloader_driver smp_imx6 = { 100 | .match_table = smp_imx6_matches, 101 | .type = DRIVER_SMP, 102 | .init = &smp_imx6_init, 103 | .ops = &smp_imx6_ops, 104 | }; 105 | 106 | ELFLOADER_DRIVER(smp_imx6); 107 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/drivers/smp-psci.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | static int smp_psci_cpu_on(UNUSED struct elfloader_device *dev, 18 | UNUSED struct elfloader_cpu *cpu, UNUSED void *entry, UNUSED void *stack) 19 | { 20 | #if CONFIG_MAX_NUM_NODES > 1 21 | if (cpu->extra_data == PSCI_METHOD_HVC) { 22 | printf("HVC is not supported for PSCI!\n"); 23 | return -1; 24 | } 25 | secondary_data.entry = entry; 26 | secondary_data.stack = stack; 27 | dmb(); 28 | int ret = psci_cpu_on(cpu->cpu_id, (unsigned long)&secondary_startup, 0); 29 | if (ret != PSCI_SUCCESS) { 30 | printf("Failed to bring up core 0x%x with error %d\n", cpu->cpu_id, ret); 31 | return -1; 32 | } 33 | 34 | return 0; 35 | #else 36 | return -1; 37 | #endif 38 | } 39 | 40 | static int smp_psci_init(struct elfloader_device *dev, 41 | UNUSED void *match_data) 42 | { 43 | smp_register_handler(dev); 44 | return 0; 45 | } 46 | 47 | 48 | static const struct dtb_match_table smp_psci_matches[] = { 49 | { .compatible = "arm,psci-0.2" }, 50 | { .compatible = "arm,psci-1.0" }, 51 | { .compatible = NULL /* sentinel */ }, 52 | }; 53 | 54 | static const struct elfloader_smp_ops smp_psci_ops = { 55 | .enable_method = "psci", 56 | .cpu_on = &smp_psci_cpu_on, 57 | }; 58 | 59 | static const struct elfloader_driver smp_psci = { 60 | .match_table = smp_psci_matches, 61 | .type = DRIVER_SMP, 62 | .init = &smp_psci_init, 63 | .ops = &smp_psci_ops, 64 | }; 65 | 66 | ELFLOADER_DRIVER(smp_psci); 67 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/drivers/smp-spin-table.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2025, Kry10 Pty. Ltd. 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | static int smp_spin_table_cpu_on(UNUSED struct elfloader_device *dev, 18 | UNUSED struct elfloader_cpu *cpu, UNUSED void *entry, UNUSED void *stack) 19 | { 20 | #if CONFIG_MAX_NUM_NODES > 1 21 | secondary_data.entry = entry; 22 | secondary_data.stack = stack; 23 | // cpu->extra_data holds the address that the core is spinning on from the device tree 24 | // Writing a new program address to this spinning address will cause the core to jump execution. 25 | // Caches on the target cores are disabled, and our caches are disabled. 26 | // We use dmb() to ensure that once the update to the spin table address is observed, 27 | // the secondary_data writes are also observed by the remote core. 28 | dmb(); 29 | // This write is sandwiched between a system dmb and system dsb both of which have ::memory clobber 30 | // on the inline assembly. The effect is that the write here will be serialized after the previous writes, 31 | // And the dsb() will wait for the write to complete before starting the following sev. 32 | *((unsigned long *)(cpu->extra_data)) = (unsigned long)&secondary_startup; 33 | dsb(); 34 | // Send an event to other cores in the system that may be in a wfi/wfe loop. 35 | asm volatile("sev" ::: "memory"); 36 | return 0; 37 | #else 38 | return -1; 39 | #endif 40 | } 41 | 42 | static int smp_spin_table_init(struct elfloader_device *dev, 43 | UNUSED void *match_data) 44 | { 45 | smp_register_handler(dev); 46 | return 0; 47 | } 48 | 49 | 50 | static const struct dtb_match_table smp_spin_table_matches[] = { 51 | { .compatible = "raspberrypi,bcm2835-firmware" }, 52 | { .compatible = NULL /* sentinel */ }, 53 | }; 54 | 55 | static const struct elfloader_smp_ops smp_spin_table_ops = { 56 | .enable_method = "spin-table", 57 | .cpu_on = &smp_spin_table_cpu_on, 58 | }; 59 | 60 | static const struct elfloader_driver smp_spin_table = { 61 | .match_table = smp_spin_table_matches, 62 | .type = DRIVER_SMP, 63 | .init = &smp_spin_table_init, 64 | .ops = &smp_spin_table_ops, 65 | }; 66 | 67 | ELFLOADER_DRIVER(smp_spin_table); 68 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/drivers/smp-zynq7000.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #define REG(base, offs) ((volatile uint32_t *)(((uintptr_t)base) + (offs))) 22 | 23 | #define CPU_JUMP_PTR 0xFFFFFFF0 24 | 25 | /* 26 | * A9_CPU_RST_CTRL Register definitions. 27 | * See TRM B.28 System Level Control Registers (slcr) 28 | */ 29 | #define A9_CPU_RST_CTRL 0x44 30 | #define PERI_RST_BIT 8 31 | #define A9_CLKSTOPx_BIT(x) (4 + (x)) 32 | #define A9_RSTx_BIT(x) (0 + (x)) 33 | 34 | UNUSED static void *get_scu_base(void) 35 | { 36 | void *scu = NULL; 37 | #if CONFIG_ARCH_AARCH32 38 | asm("mrc p15, 4, %0, c15, c0, 0" : "=r"(scu)); 39 | #else 40 | abort(); 41 | #endif 42 | return scu; 43 | } 44 | 45 | 46 | static int smp_zynq7000_cpu_on(UNUSED struct elfloader_device *dev, 47 | UNUSED struct elfloader_cpu *cpu, UNUSED void *entry, UNUSED void *stack) 48 | { 49 | #if CONFIG_MAX_NUM_NODES > 1 50 | volatile void *mmio = dev->region_bases[0]; 51 | volatile word_t *jump_ptr = (volatile word_t *)CPU_JUMP_PTR; 52 | secondary_data.entry = entry; 53 | secondary_data.stack = stack; 54 | /* stop core - see TRM 3.7 Application Processing Unit (APU) Reset */ 55 | *REG(mmio, A9_CPU_RST_CTRL) |= BIT(A9_RSTx_BIT(cpu->cpu_id)); 56 | dsb(); 57 | *REG(mmio, A9_CPU_RST_CTRL) |= BIT(A9_CLKSTOPx_BIT(cpu->cpu_id)); 58 | dsb(); 59 | /* set where core should jump to when it's woken up */ 60 | *jump_ptr = (word_t)secondary_startup; 61 | /* start core */ 62 | *REG(mmio, A9_CPU_RST_CTRL) &= ~BIT(A9_RSTx_BIT(cpu->cpu_id)); 63 | dsb(); 64 | *REG(mmio, A9_CPU_RST_CTRL) &= ~BIT(A9_CLKSTOPx_BIT(cpu->cpu_id)); 65 | dsb(); 66 | /* the other core is in WFE, we need to wake it */ 67 | asm volatile("sev"); 68 | 69 | return 0; 70 | #else 71 | return -1; 72 | #endif 73 | } 74 | 75 | static int smp_zynq7000_init(UNUSED struct elfloader_device *dev, 76 | UNUSED void *match_data) 77 | { 78 | #if CONFIG_MAX_NUM_NODES > 1 79 | void *scu = get_scu_base(); 80 | scu_enable(scu); 81 | smp_register_handler(dev); 82 | #endif 83 | return 0; 84 | } 85 | 86 | 87 | static const struct dtb_match_table smp_zynq7000_matches[] = { 88 | { .compatible = "xlnx,zynq-reset" }, 89 | { .compatible = NULL /* sentinel */ }, 90 | }; 91 | 92 | static const struct elfloader_smp_ops smp_zynq7000_ops = { 93 | .enable_method = NULL, 94 | .cpu_on = &smp_zynq7000_cpu_on, 95 | }; 96 | 97 | static const struct elfloader_driver smp_zynq7000 = { 98 | .match_table = smp_zynq7000_matches, 99 | .type = DRIVER_SMP, 100 | .init = &smp_zynq7000_init, 101 | .ops = &smp_zynq7000_ops, 102 | }; 103 | 104 | ELFLOADER_DRIVER(smp_zynq7000); 105 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/psci.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #ifdef CONFIG_ARCH_AARCH64 12 | #define SMC_FID_VER 0x84000000 13 | #define SMC_FID_CPU_SUSPEND 0xc4000001 14 | #define SMC_FID_CPU_OFF 0x84000002 15 | #define SMC_FID_CPU_ON 0xc4000003 16 | #define SMC_FID_SYSTEM_RESET 0x84000009 17 | #else 18 | #define SMC_FID_VER 0x80000000 19 | #define SMC_FID_CPU_SUSPEND 0x80000001 20 | #define SMC_FID_CPU_OFF 0x80000002 21 | #define SMC_FID_CPU_ON 0x80000003 22 | #define SMC_FID_SYSTEM_RESET 0x80000009 23 | #endif 24 | 25 | 26 | extern int psci_func(unsigned int id, unsigned long param1, 27 | unsigned long param2, unsigned long param3); 28 | 29 | int psci_version(void) 30 | { 31 | int ver = psci_func(SMC_FID_VER, 0, 0, 0); 32 | return ver; 33 | } 34 | 35 | 36 | int psci_cpu_suspend(int power_state, unsigned long entry_point, 37 | unsigned long context_id) 38 | { 39 | int ret = psci_func(SMC_FID_CPU_SUSPEND, power_state, entry_point, context_id); 40 | return ret; 41 | } 42 | 43 | /* this function does not return when successful */ 44 | int psci_cpu_off(void) 45 | { 46 | int ret = psci_func(SMC_FID_CPU_OFF, 0, 0, 0); 47 | return ret; 48 | } 49 | 50 | int psci_cpu_on(unsigned long target_cpu, unsigned long entry_point, 51 | unsigned long context_id) 52 | { 53 | int ret = psci_func(SMC_FID_CPU_ON, target_cpu, entry_point, context_id); 54 | return ret; 55 | } 56 | 57 | int psci_system_reset(void) 58 | { 59 | int ret = psci_func(SMC_FID_SYSTEM_RESET, 0, 0, 0); 60 | return ret; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-arm/scu.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * Copyright: Linux Kernel team 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | * 6 | * The code in here is loosely derived from the Linux kernel 7 | */ 8 | 9 | /* Driver for the ARM Snoop Control Unit (SCU) used on multicore systems */ 10 | 11 | #include 12 | #include 13 | 14 | #if CONFIG_MAX_NUM_NODES > 1 15 | 16 | #include 17 | #include 18 | 19 | #include 20 | 21 | #define SCU_CTRL 0 22 | #define SCU_CONFIG 1 23 | 24 | /* Enable the SCU */ 25 | void scu_enable(void *_scu_base) 26 | { 27 | uint32_t scu_ctrl; 28 | volatile uint32_t *scu_base = (volatile uint32_t *)_scu_base; 29 | 30 | #ifdef CONFIG_ARM_ERRATA_764369 31 | /* Cortex-A9 only */ 32 | if ((read_cpuid_id() & 0xff0ffff0) == 0x410fc090) { 33 | scu_ctrl = scu_base[0x30 / 4]; 34 | if (!(scu_ctrl & 1)) { 35 | scu_base[0x30 / 4] = scu_ctrl | 0x1; 36 | } 37 | } 38 | #endif 39 | 40 | scu_ctrl = scu_base[SCU_CTRL]; 41 | /* already enabled? */ 42 | if (scu_ctrl & 1) { 43 | return; 44 | } 45 | 46 | scu_ctrl |= 1; 47 | scu_base[SCU_CTRL] = scu_ctrl; 48 | 49 | /* 50 | * Ensure that the data accessed by CPU0 before the SCU was 51 | * initialised is visible to the other CPUs. 52 | */ 53 | flush_dcache(); 54 | } 55 | 56 | /* 57 | * Get the number of CPU cores from the SCU configuration 58 | */ 59 | unsigned int scu_get_core_count(void *_scu_base) 60 | { 61 | volatile uint32_t *scu_base = (volatile uint32_t *)_scu_base; 62 | unsigned int ncores = (unsigned int)scu_base[SCU_CONFIG]; 63 | return (ncores & 0x03) + 1; 64 | } 65 | 66 | #endif /* CONFIG_MAX_NUM_NODES > 1 */ 67 | -------------------------------------------------------------------------------- /elfloader-tool/src/arch-riscv/console.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include "sbi.h" 9 | 10 | int plat_console_putchar(unsigned int c) 11 | { 12 | sbi_console_putchar(c); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /elfloader-tool/src/archive.bin.lds: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | SECTIONS 8 | { 9 | .archive_ar : 10 | { 11 | _archive_start = .; 12 | *(.*); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /elfloader-tool/src/binaries/efi/efi_init.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | void *__application_handle = NULL; // current efi application handler 11 | efi_system_table_t *__efi_system_table = NULL; // current efi system table 12 | 13 | extern void _start(void); 14 | unsigned int efi_main(uintptr_t application_handle, uintptr_t efi_system_table) 15 | { 16 | clear_bss(); 17 | __application_handle = (void *)application_handle; 18 | __efi_system_table = (efi_system_table_t *)efi_system_table; 19 | _start(); 20 | return 0; 21 | } 22 | 23 | void *efi_get_fdt(void) 24 | { 25 | efi_guid_t fdt_guid = make_efi_guid(0xb1b621d5, 0xf19c, 0x41a5, 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0); 26 | efi_config_table_t *tables = (efi_config_table_t *)__efi_system_table->tables; 27 | 28 | for (uint32_t i = 0; i < __efi_system_table->nr_tables; i++) { 29 | if (!efi_guideq(fdt_guid, tables[i].guid)) 30 | continue; 31 | 32 | return (void *)tables[i].table; 33 | } 34 | 35 | return NULL; 36 | } 37 | 38 | /* Before starting the kernel we should notify the UEFI firmware about it 39 | * otherwise the internal watchdog may reboot us after 5 min. 40 | * 41 | * This means boot time services are not available anymore. We should store 42 | * system information e.g. current memory map and pass them to kernel. 43 | */ 44 | unsigned long efi_exit_boot_services(void) 45 | { 46 | unsigned long status; 47 | efi_memory_desc_t *memory_map; 48 | unsigned long map_size; 49 | unsigned long desc_size, key; 50 | uint32_t desc_version; 51 | 52 | efi_boot_services_t *bts = get_efi_boot_services(); 53 | 54 | /* 55 | * As the number of existing memeory segments are unknown, 56 | * we need to resort to a trial and error to guess that. 57 | * We start from 32 and increase it by one until get a valid value. 58 | */ 59 | map_size = sizeof(*memory_map) * 32; 60 | 61 | again: 62 | status = bts->allocate_pool(EFI_LOADER_DATA, map_size, (void **)&memory_map); 63 | 64 | if (status != EFI_SUCCESS) 65 | return status; 66 | 67 | status = bts->get_memory_map(&map_size, memory_map, &key, &desc_size, &desc_version); 68 | if (status == EFI_BUFFER_TOO_SMALL) { 69 | bts->free_pool(memory_map); 70 | 71 | map_size += sizeof(*memory_map); 72 | goto again; 73 | } 74 | 75 | if (status != EFI_SUCCESS){ 76 | bts->free_pool(memory_map); 77 | return status; 78 | } 79 | 80 | status = bts->exit_boot_services(__application_handle, key); 81 | return status; 82 | } 83 | -------------------------------------------------------------------------------- /elfloader-tool/src/binaries/efi/efi_utils.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | 9 | int efi_guideq(efi_guid_t a, efi_guid_t b) 10 | { 11 | for (unsigned int i = 0; i < sizeof(efi_guid_t); i++) { 12 | if (a.b[i] != b.b[i]) 13 | return 0; 14 | } 15 | 16 | return 1; 17 | } 18 | 19 | efi_boot_services_t *get_efi_boot_services(void) 20 | { 21 | return ((efi_boot_services_t *)(__efi_system_table->boottime)); 22 | } 23 | -------------------------------------------------------------------------------- /elfloader-tool/src/binaries/efi/gnuefi/elf_aarch64_efi.lds: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * Copyright: Linux Kernel team 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | * 6 | * The code in here is derived from the Linux kernel 7 | */ 8 | 9 | OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64") 10 | OUTPUT_ARCH(aarch64) 11 | ENTRY(_gnuefi_start) 12 | SECTIONS 13 | { 14 | .text 0x0 : { 15 | _text = .; 16 | *(.text.head) 17 | *(.text) 18 | *(.text.*) 19 | *(.gnu.linkonce.t.*) 20 | *(.srodata) 21 | *(.rodata*) 22 | . = ALIGN(16); 23 | } 24 | _etext = .; 25 | _text_size = . - _text; 26 | .dynamic : { *(.dynamic) } 27 | .data : ALIGN(4096) 28 | { 29 | _data = .; 30 | *(.sdata) 31 | *(.data) 32 | *(.data1) 33 | *(.data.*) 34 | *(.got.plt) 35 | *(.got) 36 | 37 | /* the EFI loader doesn't seem to like a .bss section, so we stick 38 | it all into .data: */ 39 | . = ALIGN(16); 40 | _bss = .; 41 | *(.sbss) 42 | *(.scommon) 43 | *(.dynbss) 44 | *(.bss) 45 | *(COMMON) 46 | . = ALIGN(16); 47 | _bss_end = .; 48 | } 49 | 50 | .rela.dyn : { *(.rela.dyn) } 51 | .rela.plt : { *(.rela.plt) } 52 | .rela.got : { *(.rela.got) } 53 | .rela.data : { *(.rela.data) *(.rela.data*) } 54 | . = ALIGN(512); 55 | _edata = .; 56 | _data_size = . - _data; 57 | 58 | . = ALIGN(4096); 59 | .dynsym : { *(.dynsym) } 60 | . = ALIGN(4096); 61 | .dynstr : { *(.dynstr) } 62 | . = ALIGN(4096); 63 | .note.gnu.build-id : { *(.note.gnu.build-id) } 64 | /DISCARD/ : 65 | { 66 | *(.rel.reloc) 67 | *(.eh_frame) 68 | *(.note.GNU-stack) 69 | } 70 | .comment 0 : { *(.comment) } 71 | } 72 | -------------------------------------------------------------------------------- /elfloader-tool/src/binaries/efi/gnuefi/elf_arm_efi.lds: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * Copyright: Linux Kernel team 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | * 6 | * The code in here is derived from the Linux kernel 7 | */ 8 | 9 | OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") 10 | OUTPUT_ARCH(arm) 11 | ENTRY(_gnuefi_start) 12 | SECTIONS 13 | { 14 | .text 0x0 : { 15 | _text = .; 16 | *(.text.head) 17 | *(.text) 18 | *(.text.*) 19 | *(.gnu.linkonce.t.*) 20 | *(.srodata) 21 | *(.rodata*) 22 | . = ALIGN(16); 23 | } 24 | _etext = .; 25 | _text_size = . - _text; 26 | .dynamic : { *(.dynamic) } 27 | .data : 28 | { 29 | _data = .; 30 | *(.sdata) 31 | *(.data) 32 | *(.data1) 33 | *(.data.*) 34 | *(.got.plt) 35 | *(.got) 36 | 37 | __start__driver_list = .; 38 | *(_driver_list) 39 | __stop__driver_list = .; 40 | 41 | . = ALIGN(8); 42 | _archive_start = .; 43 | *(._archive_cpio) 44 | _archive_end = .; 45 | 46 | /* the EFI loader doesn't seem to like a .bss section, so we stick 47 | it all into .data: */ 48 | . = ALIGN(16); 49 | _bss = .; 50 | *(.sbss) 51 | *(.scommon) 52 | *(.dynbss) 53 | *(.bss) 54 | *(.bss.*) 55 | *(COMMON) 56 | . = ALIGN(16); 57 | _bss_end = .; 58 | } 59 | 60 | .rel.dyn : { *(.rel.dyn) } 61 | .rel.plt : { *(.rel.plt) } 62 | .rel.got : { *(.rel.got) } 63 | .rel.data : { *(.rel.data) *(.rel.data*) } 64 | _edata = .; 65 | _data_size = . - _etext; 66 | 67 | . = ALIGN(4096); 68 | .dynsym : { *(.dynsym) } 69 | . = ALIGN(4096); 70 | .dynstr : { *(.dynstr) } 71 | . = ALIGN(4096); 72 | .note.gnu.build-id : { *(.note.gnu.build-id) } 73 | 74 | _end = .; 75 | /DISCARD/ : 76 | { 77 | *(.rel.reloc) 78 | *(.eh_frame) 79 | *(.note.GNU-stack) 80 | } 81 | .comment 0 : { *(.comment) } 82 | } 83 | -------------------------------------------------------------------------------- /elfloader-tool/src/binaries/efi/gnuefi/reloc_aarch64.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: BSD-3-Clause */ 2 | 3 | /* 4 | * reloc_aarch64.c - position independent x86 ELF shared object relocator 5 | * Copyright (C) 2014 Linaro Ltd. 6 | * Copyright (C) 1999 Hewlett-Packard Co. 7 | * Contributed by David Mosberger . 8 | * 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions 13 | * are met: 14 | * 15 | * * Redistributions of source code must retain the above copyright 16 | * notice, this list of conditions and the following disclaimer. 17 | * * Redistributions in binary form must reproduce the above 18 | * copyright notice, this list of conditions and the following 19 | * disclaimer in the documentation and/or other materials 20 | * provided with the distribution. 21 | * * Neither the name of Hewlett-Packard Co. nor the names of its 22 | * contributors may be used to endorse or promote products derived 23 | * from this software without specific prior written permission. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 26 | * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 27 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 28 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 29 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 30 | * BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 31 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 32 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 33 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 35 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 36 | * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 | * SUCH DAMAGE. 38 | */ 39 | 40 | #include 41 | #include 42 | 43 | #include 44 | #include 45 | 46 | long unsigned int _relocate(unsigned long ldbase, struct Elf64_Dyn *dyn, 47 | void *image UNUSED, 48 | void *systab UNUSED) 49 | { 50 | long relsz = 0, relent = 0; 51 | struct Elf64_Rela *rel = 0; 52 | unsigned long *addr; 53 | int i; 54 | 55 | for (i = 0; dyn[i].d_tag != DT_NULL; ++i) { 56 | switch (dyn[i].d_tag) { 57 | case DT_RELA: 58 | rel = (struct Elf64_Rela *) 59 | ((unsigned long)dyn[i].d_un.d_ptr 60 | + ldbase); 61 | break; 62 | 63 | case DT_RELASZ: 64 | relsz = dyn[i].d_un.d_val; 65 | break; 66 | 67 | case DT_RELAENT: 68 | relent = dyn[i].d_un.d_val; 69 | break; 70 | 71 | default: 72 | break; 73 | } 74 | } 75 | 76 | if (!rel && relent == 0) { 77 | return EFI_SUCCESS; 78 | } 79 | 80 | if (!rel || relent == 0) { 81 | return EFI_LOAD_ERROR; 82 | } 83 | 84 | while (relsz > 0) { 85 | /* apply the relocs */ 86 | switch (ELF64_R_TYPE(rel->r_info)) { 87 | case R_AARCH64_NONE: 88 | break; 89 | 90 | case R_AARCH64_RELATIVE: 91 | addr = (unsigned long *) 92 | (ldbase + rel->r_offset); 93 | *addr = ldbase + rel->r_addend; 94 | break; 95 | 96 | default: 97 | break; 98 | } 99 | rel = (struct Elf64_Rela *)((char *) rel + relent); 100 | relsz -= relent; 101 | } 102 | return EFI_SUCCESS; 103 | } 104 | -------------------------------------------------------------------------------- /elfloader-tool/src/binaries/efi/gnuefi/reloc_arm.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: BSD-3-Clause */ 2 | 3 | /* 4 | * reloc_arm.c - position independent x86 ELF shared object relocator 5 | * Copyright (C) 2014 Linaro Ltd. 6 | * Copyright (C) 1999 Hewlett-Packard Co. 7 | * Contributed by David Mosberger . 8 | * 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions 13 | * are met: 14 | * 15 | * * Redistributions of source code must retain the above copyright 16 | * notice, this list of conditions and the following disclaimer. 17 | * * Redistributions in binary form must reproduce the above 18 | * copyright notice, this list of conditions and the following 19 | * disclaimer in the documentation and/or other materials 20 | * provided with the distribution. 21 | * * Neither the name of Hewlett-Packard Co. nor the names of its 22 | * contributors may be used to endorse or promote products derived 23 | * from this software without specific prior written permission. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 26 | * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 27 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 28 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 29 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 30 | * BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 31 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 32 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 33 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 35 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 36 | * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 | * SUCH DAMAGE. 38 | */ 39 | 40 | #include 41 | #include 42 | 43 | #include 44 | #include 45 | 46 | unsigned int _relocate(unsigned long ldbase, struct Elf32_Dyn *dyn, 47 | void *image, 48 | void *systab) 49 | { 50 | long relsz = 0, relent = 0; 51 | struct Elf32_Rel *rel = 0; 52 | unsigned long *addr; 53 | int i; 54 | 55 | 56 | unsigned long total_offs = ldbase; 57 | if (!systab) { 58 | total_offs = ((unsigned long)image); 59 | } 60 | for (i = 0; dyn[i].d_tag != DT_NULL; ++i) { 61 | switch (dyn[i].d_tag) { 62 | case DT_REL: 63 | rel = (struct Elf32_Rel *) 64 | ((unsigned long)dyn[i].d_un.d_ptr 65 | + total_offs); 66 | break; 67 | 68 | case DT_RELSZ: 69 | relsz = dyn[i].d_un.d_val; 70 | break; 71 | 72 | case DT_RELENT: 73 | relent = dyn[i].d_un.d_val; 74 | break; 75 | 76 | default: 77 | break; 78 | } 79 | } 80 | 81 | if (!rel && relent == 0) { 82 | return EFI_SUCCESS; 83 | } 84 | 85 | if (!rel || relent == 0) { 86 | return EFI_LOAD_ERROR; 87 | } 88 | 89 | while (relsz > 0) { 90 | /* apply the relocs */ 91 | switch (ELF32_R_TYPE(rel->r_info)) { 92 | case R_ARM_NONE: 93 | break; 94 | 95 | case R_ARM_RELATIVE: 96 | addr = (unsigned long *) 97 | (total_offs + rel->r_offset); 98 | if (!systab) { 99 | *addr -= ldbase; 100 | *addr += total_offs; 101 | } else { 102 | *addr += ldbase; 103 | } 104 | break; 105 | 106 | default: 107 | break; 108 | } 109 | rel = (struct Elf32_Rel *)((char *) rel + relent); 110 | relsz -= relent; 111 | } 112 | return EFI_SUCCESS; 113 | } 114 | -------------------------------------------------------------------------------- /elfloader-tool/src/crypt_md5.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017, DornerWorks 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | * 6 | * This data was produced by DornerWorks, Ltd. of Grand Rapids, MI, USA under 7 | * a DARPA SBIR, Contract Number D16PC00107. 8 | * 9 | * Approved for Public Release, Distribution Unlimited. 10 | * 11 | */ 12 | 13 | #pragma once 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | typedef struct { 20 | uint64_t len; /* processed message length */ 21 | uint32_t h[4]; /* hash state */ 22 | uint8_t buf[64]; /* message block buffer */ 23 | } md5_t; 24 | 25 | void md5_init(md5_t *s); 26 | void md5_sum(md5_t *s, uint8_t *md); 27 | void md5_update(md5_t *s, const void *m, unsigned long len); 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif 32 | 33 | -------------------------------------------------------------------------------- /elfloader-tool/src/crypt_sha256.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017, DornerWorks 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | * 6 | * This data was produced by DornerWorks, Ltd. of Grand Rapids, MI, USA under 7 | * a DARPA SBIR, Contract Number D16PC00107. 8 | * 9 | * Approved for Public Release, Distribution Unlimited. 10 | * 11 | */ 12 | 13 | #pragma once 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | typedef struct { 20 | uint64_t len; /* processed message length */ 21 | uint32_t h[8]; /* hash state */ 22 | uint8_t buf[64]; /* message block buffer */ 23 | } sha256_t; 24 | 25 | void sha256_init(sha256_t *s); 26 | void sha256_sum(sha256_t *s, uint8_t *md); 27 | void sha256_update(sha256_t *s, const void *m, unsigned long len); 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif 32 | 33 | -------------------------------------------------------------------------------- /elfloader-tool/src/defaults.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * Copyright 2021, HENSOLDT Cyber 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-only 6 | */ 7 | 8 | /* Default implementations of required utility functions. Override these under 9 | * plat-* if there is a more appropriate implementation for a given platform. 10 | */ 11 | 12 | #include 13 | #include 14 | 15 | WEAK NORETURN void abort(void) 16 | { 17 | printf("abort() called.\n"); 18 | 19 | while (1); 20 | 21 | UNREACHABLE(); 22 | } 23 | -------------------------------------------------------------------------------- /elfloader-tool/src/drivers/driver.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define DRIVER_COMMON 1 12 | #include 13 | #undef DRIVER_COMMON 14 | 15 | 16 | static int table_has_match(const char *compat, const struct dtb_match_table *table) 17 | { 18 | for (int i = 0; table[i].compatible != NULL; i++) { 19 | if (!strcmp(table[i].compatible, compat)) { 20 | return i; 21 | } 22 | } 23 | 24 | return -1; 25 | } 26 | 27 | static int init_device(struct elfloader_device *dev) 28 | { 29 | struct elfloader_driver **drvp = __start__driver_list; 30 | 31 | while (drvp < __stop__driver_list) { 32 | struct elfloader_driver *drv = *drvp; 33 | int ret = table_has_match(dev->compat, drv->match_table); 34 | if (ret >= 0) { 35 | dev->drv = drv; 36 | ret = drv->init(dev, drv->match_table[ret].match_data); 37 | if (ret) { 38 | return ret; 39 | } 40 | } 41 | drvp++; 42 | } 43 | 44 | return 0; 45 | 46 | } 47 | 48 | int initialise_devices(void) 49 | { 50 | for (unsigned int i = 0; i < ARRAY_SIZE(elfloader_devices); i++) { 51 | int ret = init_device(&elfloader_devices[i]); 52 | if (ret) { 53 | return ret; 54 | } 55 | } 56 | 57 | return 0; 58 | } 59 | 60 | static int init_device_non_boot(struct elfloader_device *dev) 61 | { 62 | struct elfloader_driver **drvp = __start__driver_list; 63 | 64 | while (drvp < __stop__driver_list) { 65 | struct elfloader_driver *drv = *drvp; 66 | if (drv->init_on_secondary_cores) { 67 | int ret = table_has_match(dev->compat, drv->match_table); 68 | if (ret >= 0) { 69 | dev->drv = drv; 70 | ret = drv->init_on_secondary_cores(dev, drv->match_table[ret].match_data); 71 | if (ret) { 72 | return ret; 73 | } 74 | } 75 | } 76 | drvp++; 77 | } 78 | return 0; 79 | } 80 | 81 | int initialise_devices_non_boot(void) 82 | { 83 | for (unsigned int i = 0; i < ARRAY_SIZE(elfloader_devices); i++) { 84 | int ret = init_device_non_boot(&elfloader_devices[i]); 85 | if (ret) { 86 | return ret; 87 | } 88 | } 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /elfloader-tool/src/drivers/smp/common.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * Copyright 2021, HENSOLDT Cyber 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-only 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | static struct elfloader_device *smp_ops = NULL; 17 | 18 | struct smp_cpu_data secondary_data; 19 | 20 | void smp_register_handler(struct elfloader_device *dev) 21 | { 22 | if (dev->drv->type != DRIVER_SMP) { 23 | return; 24 | } 25 | 26 | smp_ops = dev; 27 | } 28 | 29 | WEAK int plat_cpu_on(struct elfloader_cpu *cpu, void *entry, void *stack) 30 | { 31 | if (!smp_ops) { 32 | return -1; 33 | } 34 | 35 | if (cpu->enable_method == NULL || dev_get_smp(smp_ops)->enable_method == NULL) { 36 | /* if cpu has a NULL enable_method, expect a driver with a NULL enable_method too */ 37 | if (cpu->enable_method != NULL || dev_get_smp(smp_ops)-> enable_method != NULL) { 38 | return -1; 39 | } 40 | } else if (strcmp(cpu->enable_method, dev_get_smp(smp_ops)->enable_method)) { 41 | return -1; 42 | } 43 | 44 | return dev_get_smp(smp_ops)->cpu_on(smp_ops, cpu, entry, stack); 45 | } 46 | -------------------------------------------------------------------------------- /elfloader-tool/src/drivers/timer/arm_generic_timer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | 14 | static int generic_timer_init(UNUSED struct elfloader_device *dev, UNUSED void *match_data) 15 | { 16 | reset_cntvoff(); 17 | return 0; 18 | } 19 | 20 | static const struct dtb_match_table generic_timer_matches[] = { 21 | { .compatible = "arm,armv7-timer" }, 22 | { .compatible = "arm,armv8-timer" }, 23 | { .compatible = NULL /* sentinel */ }, 24 | }; 25 | 26 | static const struct elfloader_driver generic_timer = { 27 | .match_table = generic_timer_matches, 28 | .type = DRIVER_TIMER, 29 | .init = &generic_timer_init, 30 | .init_on_secondary_cores = &generic_timer_init, 31 | .ops = NULL, 32 | }; 33 | 34 | ELFLOADER_DRIVER(generic_timer); 35 | -------------------------------------------------------------------------------- /elfloader-tool/src/drivers/uart/8250-uart.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #define UTHR 0x00 /* UART Transmit Holding Register */ 16 | #define ULSR 0x14 /* UART Line Status Register */ 17 | #define ULSR_THRE (1 << 5) /* Transmit Holding Register Empty */ 18 | 19 | #define UART_REG(mmio, x) ((volatile uint32_t *)(((uintptr_t)mmio) + (x))) 20 | 21 | static int uart_8250_putchar(struct elfloader_device *dev, unsigned int c) 22 | { 23 | volatile void *mmio = dev->region_bases[0]; 24 | 25 | /* Wait until UART ready for the next character. */ 26 | while ((*UART_REG(mmio, ULSR) & ULSR_THRE) == 0); 27 | 28 | /* Add character to the buffer. */ 29 | *UART_REG(mmio, UTHR) = c; 30 | 31 | return 0; 32 | } 33 | 34 | static int uart_8250_init(struct elfloader_device *dev, 35 | UNUSED void *match_data) 36 | { 37 | uart_set_out(dev); 38 | return 0; 39 | } 40 | 41 | static const struct dtb_match_table uart_8250_matches[] = { 42 | { .compatible = "nvidia,tegra20-uart" }, 43 | { .compatible = "ti,omap3-uart" }, 44 | { .compatible = "snps,dw-apb-uart" }, 45 | { .compatible = NULL /* sentinel */ }, 46 | }; 47 | 48 | static const struct elfloader_uart_ops uart_8250_ops = { 49 | .putc = &uart_8250_putchar, 50 | }; 51 | 52 | static const struct elfloader_driver uart_8250 = { 53 | .match_table = uart_8250_matches, 54 | .type = DRIVER_UART, 55 | .init = &uart_8250_init, 56 | .ops = &uart_8250_ops, 57 | }; 58 | 59 | ELFLOADER_DRIVER(uart_8250); 60 | -------------------------------------------------------------------------------- /elfloader-tool/src/drivers/uart/bcm-uart.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | /* When DLAB=1, MU_IO is a baud rate register. 14 | * Otherwise, write to TX, read to RX */ 15 | #define MU_IO 0x00 16 | /* When DLAB=1, MU_IIR is a baud rate register. 17 | * Otherwise IRQ enable */ 18 | #define MU_IIR 0x04 19 | #define MU_IER 0x08 20 | #define MU_LCR 0x0C 21 | #define MU_MCR 0x10 22 | #define MU_LSR 0x14 23 | #define MU_MSR 0x18 24 | #define MU_SCRATCH 0x1C 25 | #define MU_CNTL 0x20 26 | 27 | /* This bit is set if the transmit FIFO can accept at least one byte.*/ 28 | #define MU_LSR_TXEMPTY BIT(5) 29 | /* This bit is set if the transmit FIFO is empty and the 30 | * transmitter is idle. (Finished shifting out the last bit). */ 31 | #define MU_LSR_TXIDLE BIT(6) 32 | 33 | #define MU_LCR_DLAB BIT(7) 34 | #define MU_LCR_BREAK BIT(6) 35 | #define MU_LCR_DATASIZE BIT(0) 36 | 37 | #define UART_REG(mmio, x) ((volatile uint32_t *)((mmio) + (x))) 38 | 39 | static int bcm2835_uart_putchar(struct elfloader_device *dev, unsigned int c) 40 | { 41 | volatile void *mmio = dev->region_bases[0]; 42 | 43 | /* Wait until UART ready for the next character. */ 44 | while (!(*UART_REG(mmio, MU_LSR) & MU_LSR_TXIDLE)); 45 | 46 | /* Put in the register to be sent*/ 47 | *UART_REG(mmio, MU_IO) = (c & 0xff); 48 | 49 | return 0; 50 | } 51 | 52 | static int bcm2835_uart_init(struct elfloader_device *dev, UNUSED void *match_data) 53 | { 54 | uart_set_out(dev); 55 | return 0; 56 | } 57 | 58 | static const struct dtb_match_table bcm2835_uart_matches[] = { 59 | { .compatible = "brcm,bcm2835-aux-uart" }, 60 | { .compatible = NULL /* sentinel */ }, 61 | }; 62 | 63 | static const struct elfloader_uart_ops bcm2835_uart_ops = { 64 | .putc = &bcm2835_uart_putchar, 65 | }; 66 | 67 | static const struct elfloader_driver bcm2835_uart = { 68 | .match_table = bcm2835_uart_matches, 69 | .type = DRIVER_UART, 70 | .init = &bcm2835_uart_init, 71 | .ops = &bcm2835_uart_ops, 72 | }; 73 | 74 | ELFLOADER_DRIVER(bcm2835_uart); 75 | -------------------------------------------------------------------------------- /elfloader-tool/src/drivers/uart/common.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * Copyright 2021, HENSOLDT Cyber 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-only 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | static struct elfloader_device *uart_out = NULL; 13 | 14 | 15 | void uart_set_out(struct elfloader_device *out) 16 | { 17 | if (out->drv->type != DRIVER_UART) { 18 | return; 19 | } 20 | uart_out = out; 21 | } 22 | 23 | volatile void *uart_get_mmio(void) 24 | { 25 | if (uart_out == NULL) { 26 | return NULL; 27 | } 28 | return uart_out->region_bases[0]; 29 | } 30 | 31 | WEAK int plat_console_putchar(unsigned int c) 32 | { 33 | if (uart_out == NULL) { 34 | return 0; 35 | } 36 | 37 | /* Currently no driver really implements a return code for putc(), they all 38 | * return 0 unconditionally. So we ignore it here completely. To comply with 39 | * UART terminal behavior, we print a '\r' (CR) before every '\n' (LF). 40 | */ 41 | if ('\n' == c) { 42 | (void)dev_get_uart(uart_out)->putc(uart_out, '\r'); 43 | } 44 | 45 | (void)dev_get_uart(uart_out)->putc(uart_out, c); 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /elfloader-tool/src/drivers/uart/exynos-uart.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #define ULCON 0x0000 /* line control */ 14 | #define UCON 0x0004 /*control */ 15 | #define UFCON 0x0008 /* fifo control */ 16 | #define UMCON 0x000C /* modem control */ 17 | #define UTRSTAT 0x0010 /* TX/RX status */ 18 | #define UERSTAT 0x0014 /* RX error status */ 19 | #define UFSTAT 0x0018 /* FIFO status */ 20 | #define UMSTAT 0x001C /* modem status */ 21 | #define UTXH 0x0020 /* TX buffer */ 22 | #define URXH 0x0024 /* RX buffer */ 23 | #define UBRDIV 0x0028 /* baud rate divisor */ 24 | #define UFRACVAL 0x002C /* divisor fractional value */ 25 | #define UINTP 0x0030 /* interrupt pending */ 26 | #define UINTSP 0x0034 /* interrupt source pending */ 27 | #define UINTM 0x0038 /* interrupt mask */ 28 | 29 | #define UART_REG(mmio, x) ((volatile uint32_t *)(mmio + (x))) 30 | 31 | /* ULCON */ 32 | #define WORD_LENGTH_8 (3<<0) 33 | 34 | /* UTRSTAT */ 35 | #define TX_EMPTY (1<<2) 36 | #define TXBUF_EMPTY (1<<1) 37 | 38 | static int exynos_uart_putchar(struct elfloader_device *dev, unsigned int c) 39 | { 40 | volatile void *mmio = dev->region_bases[0]; 41 | 42 | /* Wait until UART ready for the next character. */ 43 | while (!(*UART_REG(mmio, UTRSTAT) & TXBUF_EMPTY)); 44 | 45 | /* Put in the register to be sent*/ 46 | *UART_REG(mmio, UTXH) = (c & 0xff); 47 | 48 | return 0; 49 | } 50 | 51 | static int exynos_uart_init(struct elfloader_device *dev, UNUSED void *match_data) 52 | { 53 | uart_set_out(dev); 54 | return 0; 55 | } 56 | 57 | static const struct dtb_match_table exynos_uart_matches[] = { 58 | { .compatible = "samsung,exynos4210-uart" }, 59 | { .compatible = NULL /* sentinel */ }, 60 | }; 61 | 62 | static const struct elfloader_uart_ops exynos_uart_ops = { 63 | .putc = &exynos_uart_putchar, 64 | }; 65 | 66 | static const struct elfloader_driver exynos_uart = { 67 | .match_table = exynos_uart_matches, 68 | .type = DRIVER_UART, 69 | .init = &exynos_uart_init, 70 | .ops = &exynos_uart_ops, 71 | }; 72 | 73 | ELFLOADER_DRIVER(exynos_uart); 74 | -------------------------------------------------------------------------------- /elfloader-tool/src/drivers/uart/imx-lpuart.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021, Data61, CSIRO (ABN 41 687 119 230) 3 | * Copyright 2021, Breakaway Consulting Pty. Ltd. 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-only 6 | */ 7 | /* 8 | * A simple output only UART driver for the NXP i.MX Low Power UART. 9 | * 10 | * Technical Reference: 11 | * i.MX 8DualX/8DualXPlus/8QuadXPlus Applications Processor Reference Manual 12 | * Revision 0 (IMX8DQXPRM.pdf) 13 | * Chapter 16.13 (page 7908) 14 | * 15 | * SPDX-License-Identifier: GPL-2.0-only 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | #define STAT 0x14 25 | #define TRANSMIT 0x1c 26 | 27 | #define STAT_TDRE (1 << 23) 28 | 29 | #define UART_REG(mmio, x) ((volatile uint32_t *)(mmio + (x))) 30 | 31 | static int imx_lpuart_putchar(struct elfloader_device *dev, unsigned int c) 32 | { 33 | volatile void *mmio = dev->region_bases[0]; 34 | 35 | /* Wait to be able to transmit. */ 36 | while (!(*UART_REG(mmio, STAT) & STAT_TDRE)) { } 37 | 38 | *UART_REG(mmio, TRANSMIT) = c; 39 | 40 | return 0; 41 | } 42 | 43 | static int imx_lpuart_init(struct elfloader_device *dev, UNUSED void *match_data) 44 | { 45 | uart_set_out(dev); 46 | return 0; 47 | } 48 | 49 | static const struct dtb_match_table imx_lpuart_matches[] = { 50 | { .compatible = "fsl,imx7ulp-lpuart" }, 51 | { .compatible = "fsl,imx8qxp-lpuart" }, 52 | { .compatible = NULL /* sentinel */ }, 53 | }; 54 | 55 | static const struct elfloader_uart_ops imx_lpuart_ops = { 56 | .putc = &imx_lpuart_putchar, 57 | }; 58 | 59 | static const struct elfloader_driver imx_lpuart = { 60 | .match_table = imx_lpuart_matches, 61 | .type = DRIVER_UART, 62 | .init = &imx_lpuart_init, 63 | .ops = &imx_lpuart_ops, 64 | }; 65 | 66 | ELFLOADER_DRIVER(imx_lpuart); 67 | -------------------------------------------------------------------------------- /elfloader-tool/src/drivers/uart/imx-uart.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * Copyright 2020, HENSOLDT Cyber GmbH 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-only 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #define UART_TRANSMIT 0x40 15 | #define UART_CONTROL1 0x80 16 | #define UART_CONTROL2 0x84 17 | #define UART_CONTROL3 0x88 18 | #define UART_CONTROL4 0x8C 19 | #define UART_FIFO_CTRL 0x90 20 | #define UART_STAT1 0x94 21 | #define UART_STAT2 0x98 22 | 23 | /* Transmit buffer FIFO empty. */ 24 | #define TXFE (1U << 14) 25 | 26 | #define UART_REG(mmio, x) ((volatile uint32_t *)(mmio + (x))) 27 | 28 | static int imx_uart_putchar(struct elfloader_device *dev, unsigned int c) 29 | { 30 | volatile void *mmio = dev->region_bases[0]; 31 | 32 | /* Wait to be able to transmit. */ 33 | while (!(*UART_REG(mmio, UART_STAT2) & TXFE)); 34 | 35 | /* Transmit. */ 36 | *UART_REG(mmio, UART_TRANSMIT) = c; 37 | 38 | return 0; 39 | } 40 | 41 | static int imx_uart_init(struct elfloader_device *dev, UNUSED void *match_data) 42 | { 43 | uart_set_out(dev); 44 | return 0; 45 | } 46 | 47 | static const struct dtb_match_table imx_uart_matches[] = { 48 | { .compatible = "fsl,imx6q-uart" }, 49 | { .compatible = "fsl,imx6sx-uart" }, 50 | { .compatible = NULL /* sentinel */ }, 51 | }; 52 | 53 | static const struct elfloader_uart_ops imx_uart_ops = { 54 | .putc = &imx_uart_putchar, 55 | }; 56 | 57 | static const struct elfloader_driver imx_uart = { 58 | .match_table = imx_uart_matches, 59 | .type = DRIVER_UART, 60 | .init = &imx_uart_init, 61 | .ops = &imx_uart_ops, 62 | }; 63 | 64 | ELFLOADER_DRIVER(imx_uart); 65 | -------------------------------------------------------------------------------- /elfloader-tool/src/drivers/uart/meson-uart.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #define UART_WFIFO 0x0 14 | #define UART_STATUS 0xC 15 | #define UART_TX_FULL BIT(21) 16 | #define UART_REG(mmio, x) ((volatile uint32_t *)(mmio + (x))) 17 | 18 | static int meson_uart_putchar(struct elfloader_device *dev, unsigned int c) 19 | { 20 | volatile void *mmio = dev->region_bases[0]; 21 | 22 | /* Wait to be able to transmit. */ 23 | while ((*UART_REG(mmio, UART_STATUS) & UART_TX_FULL)); 24 | 25 | /* Transmit. */ 26 | *UART_REG(mmio, UART_WFIFO) = c; 27 | 28 | return 0; 29 | } 30 | 31 | static int meson_uart_init(struct elfloader_device *dev, UNUSED void *match_data) 32 | { 33 | uart_set_out(dev); 34 | return 0; 35 | } 36 | 37 | static const struct dtb_match_table meson_uart_matches[] = { 38 | { .compatible = "amlogic,meson-gx-uart" }, 39 | { .compatible = NULL /* sentinel */ }, 40 | }; 41 | 42 | static const struct elfloader_uart_ops meson_uart_ops = { 43 | .putc = &meson_uart_putchar, 44 | }; 45 | 46 | static const struct elfloader_driver meson_uart = { 47 | .match_table = meson_uart_matches, 48 | .type = DRIVER_UART, 49 | .init = &meson_uart_init, 50 | .ops = &meson_uart_ops, 51 | }; 52 | 53 | ELFLOADER_DRIVER(meson_uart); 54 | -------------------------------------------------------------------------------- /elfloader-tool/src/drivers/uart/msm-uart.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #define USR 0x08 14 | #define UTF 0x70 15 | #define UNTX 0x40 16 | 17 | #define USR_TXRDY (1U << 2) 18 | #define USR_TXEMP (1U << 3) 19 | 20 | #define UART_REG(mmio, x) ((volatile uint32_t *)(mmio + (x))) 21 | 22 | static int msm_uart_putchar(struct elfloader_device *dev, unsigned int c) 23 | { 24 | volatile void *mmio = dev->region_bases[0]; 25 | 26 | /* Wait for TX fifo to be empty */ 27 | while (!(*UART_REG(mmio, USR) & USR_TXEMP)); 28 | /* Tell the peripheral how many characters to send */ 29 | *UART_REG(mmio, UNTX) = 1; 30 | /* Write the character into the FIFO */ 31 | *UART_REG(mmio, UTF) = c & 0xff; 32 | 33 | return 0; 34 | } 35 | 36 | static int msm_uart_init(struct elfloader_device *dev, UNUSED void *match_data) 37 | { 38 | uart_set_out(dev); 39 | return 0; 40 | } 41 | 42 | static const struct dtb_match_table msm_uart_matches[] = { 43 | { .compatible = "qcom,msm-uartdm" }, 44 | { .compatible = NULL /* sentinel */ }, 45 | }; 46 | 47 | static const struct elfloader_uart_ops msm_uart_ops = { 48 | .putc = &msm_uart_putchar, 49 | }; 50 | 51 | static const struct elfloader_driver msm_uart = { 52 | .match_table = msm_uart_matches, 53 | .type = DRIVER_UART, 54 | .init = &msm_uart_init, 55 | .ops = &msm_uart_ops, 56 | }; 57 | 58 | ELFLOADER_DRIVER(msm_uart); 59 | -------------------------------------------------------------------------------- /elfloader-tool/src/drivers/uart/pl011-uart.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #define UARTDR 0x000 14 | #define UARTFR 0x018 15 | #define UARTFR_TXFF (1 << 5) 16 | 17 | #define UART_REG(mmio, x) ((volatile uint32_t *)(mmio + (x))) 18 | 19 | int pl011_uart_putchar(struct elfloader_device *dev, unsigned int c) 20 | { 21 | volatile void *mmio = dev->region_bases[0]; 22 | 23 | /* Wait until UART ready for the next character. */ 24 | while ((*UART_REG(mmio, UARTFR) & UARTFR_TXFF) != 0); 25 | 26 | /* Add character to the buffer. */ 27 | *UART_REG(mmio, UARTDR) = (c & 0xff); 28 | 29 | return 0; 30 | } 31 | 32 | static int pl011_uart_init(struct elfloader_device *dev, UNUSED void *match_data) 33 | { 34 | uart_set_out(dev); 35 | return 0; 36 | } 37 | 38 | static const struct dtb_match_table pl011_uart_matches[] = { 39 | { .compatible = "arm,pl011" }, 40 | { .compatible = NULL /* sentinel */ }, 41 | }; 42 | 43 | static const struct elfloader_uart_ops pl011_uart_ops = { 44 | .putc = &pl011_uart_putchar, 45 | }; 46 | 47 | static const struct elfloader_driver pl011_uart = { 48 | .match_table = pl011_uart_matches, 49 | .type = DRIVER_UART, 50 | .init = &pl011_uart_init, 51 | .ops = &pl011_uart_ops, 52 | }; 53 | 54 | ELFLOADER_DRIVER(pl011_uart); 55 | -------------------------------------------------------------------------------- /elfloader-tool/src/drivers/uart/xilinx-uart.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017, DornerWorks 3 | * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230) 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-only 6 | */ 7 | /* 8 | * This data was produced by DornerWorks, Ltd. of Grand Rapids, MI, USA under 9 | * a DARPA SBIR, Contract Number D16PC00107. 10 | * 11 | * Approved for Public Release, Distribution Unlimited. 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | /* 21 | * UART Hardware Constants 22 | */ 23 | #define XUARTPS_CR 0x00 24 | #define XUARTPS_SR 0x2C 25 | #define XUARTPS_FIFO 0x30 26 | 27 | #define XUARTPS_SR_TXEMPTY (1U << 3) 28 | 29 | #define XUARTPS_CR_TX_EN (1U << 4) 30 | #define XUARTPS_CR_TX_DIS (1U << 5) 31 | 32 | 33 | #define UART_REG(mmio, x) ((volatile uint32_t *)(mmio + (x))) 34 | 35 | static int xilinx_uart_putchar(struct elfloader_device *dev, unsigned int c) 36 | { 37 | volatile void *mmio = dev->region_bases[0]; 38 | 39 | /* Wait to be able to transmit. */ 40 | while (!(*UART_REG(mmio, XUARTPS_SR) & XUARTPS_SR_TXEMPTY)); 41 | 42 | /* Transmit. */ 43 | *UART_REG(mmio, XUARTPS_FIFO) = c; 44 | 45 | return 0; 46 | } 47 | 48 | static int xilinx_uart_init(struct elfloader_device *dev, UNUSED void *match_data) 49 | { 50 | volatile void *mmio = dev->region_bases[0]; 51 | uint32_t v = *UART_REG(mmio, XUARTPS_CR); 52 | v |= XUARTPS_CR_TX_EN; 53 | v &= ~XUARTPS_CR_TX_DIS; 54 | *UART_REG(mmio, XUARTPS_CR) = v; 55 | 56 | uart_set_out(dev); 57 | return 0; 58 | } 59 | 60 | static const struct dtb_match_table xilinx_uart_matches[] = { 61 | { .compatible = "xlnx,xuartps" }, 62 | { .compatible = NULL /* sentinel */ }, 63 | }; 64 | 65 | static const struct elfloader_uart_ops xilinx_uart_ops = { 66 | .putc = &xilinx_uart_putchar, 67 | }; 68 | 69 | static const struct elfloader_driver xilinx_uart = { 70 | .match_table = xilinx_uart_matches, 71 | .type = DRIVER_UART, 72 | .init = &xilinx_uart_init, 73 | .ops = &xilinx_uart_ops, 74 | }; 75 | 76 | ELFLOADER_DRIVER(xilinx_uart); 77 | -------------------------------------------------------------------------------- /elfloader-tool/src/fdt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | #include 7 | 8 | #define FDT_MAGIC (0xd00dfeed) 9 | /* Newest FDT version that we understand */ 10 | #define FDT_MAX_VER 17 11 | 12 | struct fdt_header { 13 | uint32_t magic; 14 | uint32_t totalsize; 15 | uint32_t off_dt_struct; 16 | uint32_t off_dt_strings; 17 | uint32_t off_mem_rsvmap; 18 | uint32_t version; 19 | uint32_t last_comp_version; 20 | uint32_t boot_cpuid_phys; 21 | uint32_t size_dt_strings; 22 | uint32_t size_dt_struct; 23 | }; 24 | 25 | uint32_t be32_to_le( 26 | uint32_t be) 27 | { 28 | return ((be & 0xff) << 24) | 29 | ((be & 0xff00) << 8) | 30 | ((be & 0xff0000) >> 8) | 31 | ((be & 0xff000000) >> 24); 32 | } 33 | 34 | size_t fdt_size( 35 | void const *fdt) 36 | { 37 | struct fdt_header const *hdr = fdt; 38 | 39 | if (be32_to_le(hdr->magic) != FDT_MAGIC || 40 | be32_to_le(hdr->last_comp_version) > FDT_MAX_VER) { 41 | return 0; 42 | } 43 | 44 | return be32_to_le(hdr->totalsize); 45 | } 46 | 47 | -------------------------------------------------------------------------------- /elfloader-tool/src/hash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017, DornerWorks 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | * 6 | * This data was produced by DornerWorks, Ltd. of Grand Rapids, MI, USA under 7 | * a DARPA SBIR, Contract Number D16PC00107. 8 | * 9 | * Approved for Public Release, Distribution Unlimited. 10 | * 11 | */ 12 | 13 | #pragma once 14 | 15 | #include "crypt_sha256.h" 16 | #include "crypt_md5.h" 17 | #include 18 | 19 | /* enum to store the hashing methods */ 20 | enum hash_methods { 21 | SHA_256, 22 | MD5 23 | }; 24 | 25 | /* Structure that contains a structure for each hash type and an integer 26 | * representation of the hashing method used 27 | */ 28 | typedef struct { 29 | sha256_t sha_structure; 30 | md5_t md5_structure; 31 | unsigned int hash_type; 32 | } hashes_t; 33 | 34 | void get_hash( 35 | hashes_t hashes, 36 | const void *data, 37 | size_t len, 38 | void *outputted_hash); 39 | 40 | void print_hash( 41 | void const *hash, 42 | size_t len); 43 | 44 | -------------------------------------------------------------------------------- /elfloader-tool/src/linker.lds: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | #include "image_start_addr.h" 10 | 11 | ENTRY( _start ) 12 | 13 | SECTIONS 14 | { 15 | . = IMAGE_START_ADDR; 16 | _text = .; 17 | .start : 18 | { 19 | *(.text.start) 20 | } 21 | .text : 22 | { 23 | *(.text) 24 | } 25 | . = ALIGN(16); 26 | .rodata : 27 | { 28 | *(.srodata*) 29 | . = ALIGN(16); 30 | *(.rodata) 31 | *(.rodata.*) 32 | /* 33 | * ld crashes when we add this here: *(_driver_list) 34 | */ 35 | . = ALIGN(16); 36 | _archive_start = .; 37 | *(._archive_cpio) 38 | _archive_end = .; 39 | } 40 | . = ALIGN(16); 41 | .data : 42 | { 43 | __global_pointer$ = . + 0x800; 44 | *(.sdata*) 45 | *(.data) 46 | *(.data.*) 47 | } 48 | . = ALIGN(16); 49 | .bss (NOLOAD) : 50 | { 51 | . = ALIGN(0x1000); 52 | core_stack_alloc = .; 53 | . = . + CONFIG_MAX_NUM_NODES * 1 << 12; 54 | core_stack_alloc_end = .; 55 | _bss = .; 56 | *(.sbss*) 57 | *(.bss) 58 | *(.bss.*) 59 | _bss_end = .; 60 | } 61 | _end = .; 62 | } 63 | -------------------------------------------------------------------------------- /elfloader-tool/src/plat/exynos5/platform_init.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #define BOOTCPU 0 15 | 16 | #define EXYNOS5_SYSRAM 0x02020000 17 | #define EXYNOS5_POWER 0x10040000 18 | 19 | #define EXYNOS5_SYSRAM_NS (EXYNOS5_SYSRAM + 0x53000) 20 | #define EXYNOS5_POWER_CPU_CFG (EXYNOS5_POWER + 0x2000) 21 | 22 | #define CORE_LOCAL_PWR_EN 0x3 23 | 24 | #define SMC_SHUTDOWN (-7) 25 | #define SMC_DISABLE_TRUSTZONE (-1024) 26 | 27 | /** 28 | * This structure and its location is defined by U-Boot 29 | * It controls the boot behaviour of secondary cores. 30 | */ 31 | typedef volatile struct { 32 | uint32_t bypass[2]; /* 0x00 */ 33 | uint32_t resume_addr; /* 0x08 */ 34 | uint32_t resume_flag; /* 0x0C */ 35 | uint32_t res0[3]; /* 0x10 */ 36 | uint32_t cpu1_boot_reg; /* 0x1C */ 37 | uint32_t direct_go_flag; /* 0x20 */ 38 | uint32_t direct_go_addr; /* 0x24 */ 39 | uint32_t cpustate[8]; /* 0x28 */ /* only 4 cpustate on 5410 */ 40 | uint32_t clusterstate[2]; /* 0x54 */ /* missing on 5410 */ 41 | } nscode_t; 42 | 43 | struct cso { 44 | uint32_t config; 45 | uint32_t status; 46 | uint32_t option; 47 | uint32_t res[5]; 48 | }; 49 | 50 | typedef volatile struct cpu_cfg { 51 | struct cso core; 52 | struct cso dis_irq_local; 53 | struct cso dis_irq_central; 54 | struct cso res[1]; 55 | } cpu_cfg_t; 56 | 57 | /* U-Boot control */ 58 | nscode_t *nsscode = (nscode_t *)EXYNOS5_SYSRAM_NS; 59 | 60 | /* CPU configuration */ 61 | cpu_cfg_t *cpu_cfg = (cpu_cfg_t *)EXYNOS5_POWER_CPU_CFG; 62 | 63 | extern char _start[]; 64 | 65 | void boot_cpu(int cpu, uintptr_t entry) 66 | { 67 | /* Setup the CPU's entry point */ 68 | nsscode->cpu1_boot_reg = entry; 69 | asm volatile("dmb"); 70 | /* Spin up the CPU */ 71 | cpu_cfg[cpu].core.config = CORE_LOCAL_PWR_EN; 72 | } 73 | 74 | void platform_init(void) 75 | { 76 | if (get_cortex_a_part() == 7) { 77 | printf("\nSwitching CPU...\n"); 78 | boot_cpu(BOOTCPU, (uintptr_t)_start); 79 | /* Shutdown */ 80 | for (;;) { 81 | /* 82 | * Turn off interrupts before going to 83 | * sleep --- otherwise they could wake us up. 84 | */ 85 | asm volatile( 86 | "msr CPSR_cxsf, #0xc" :: 87 | ); 88 | smc(SMC_SHUTDOWN, 0, 0, 0); 89 | } 90 | } else { 91 | nsscode->cpu1_boot_reg = 0; 92 | smc(SMC_DISABLE_TRUSTZONE, 0, 0, 0); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /elfloader-tool/src/plat/fvp/platform_init.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | 9 | void platform_init(void) 10 | { 11 | /* On FVP, The MPIDR_EL1 changes to 0x80000000 after 12 | * MMU is enabled for unknown reason. We save the 13 | * MPIDR_EL1 in TPIDR_EL0 before switching the MMU, and 14 | * the correct MPIDR_EL1 can be picked up by the kernel 15 | * from TPIDR_EL0. 16 | * The same operation is performed in smp_head.S as well 17 | * when SMP is enabled. 18 | */ 19 | asm volatile("mrs x0, mpidr_el1\n" 20 | "msr tpidr_el0, x0\n" 21 | ::: "x0"); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /elfloader-tool/src/plat/imx6/monitor.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * Copyright 2020, HENSOLDT Cyber GmbH 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-only 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | 12 | #ifndef CONFIG_ARM_MONITOR_HOOK 13 | #error This file is for CONFIG_ARM_MONITOR_HOOK only 14 | #endif 15 | 16 | #if defined(CONFIG_PLAT_IMX6DQ) 17 | #define VECTOR_BASE 0x10000000 18 | #elif defined(CONFIG_PLAT_IMX6SX) 19 | #define VECTOR_BASE 0x80000000 20 | #else 21 | #error "unknown i.MX6 SOC" 22 | #endif 23 | #define STACK_TOP (VECTOR_BASE + (1 << 12) - 0x10) 24 | 25 | /* vector table for monitor mode 26 | * 0x00: not used 27 | * 0x04: not used 28 | * 0x08: secure monitor call 29 | * 0x0c: prefetch abort 30 | * 0x10: data abort 31 | * 0x14: not used 32 | * 0x18: IRQ interrupt 33 | * 0x1c: FIQ interrupt 34 | */ 35 | .arch_extension sec 36 | .global arm_monitor_vector 37 | .global arm_monitor_vector_end 38 | .global smc_handler 39 | .global smc_halt 40 | 41 | /* pc contains the current instruction + 8 bytes 42 | * use pc-relative addressing so we can copy the 43 | * table. only the offset 0x08 is set up to call 44 | * smc_handler, other offsets halt the system. 45 | */ 46 | .align 12 47 | arm_monitor_vector: 48 | ldr pc, [pc, #28] 49 | ldr pc, [pc, #24] 50 | ldr pc, [pc, #16] 51 | ldr pc, [pc, #16] 52 | ldr pc, [pc, #12] 53 | ldr pc, [pc, #8] 54 | ldr pc, [pc, #4] 55 | ldr pc, [pc, #0] 56 | 57 | smc_handler_addr: 58 | .word VECTOR_BASE + (smc_handler - arm_monitor_vector) 59 | smc_halt_addr: 60 | .word VECTOR_BASE + (smc_halt - arm_monitor_vector) 61 | smc_stack: 62 | .word STACK_TOP 63 | 64 | /* r0: the start physical address for the code that the 65 | * caller wants to execute in monitor mode. I know, a huge 66 | * security hole. WARNING: the code to be executed should 67 | * not reference memory locations !!! 68 | */ 69 | smc_handler: 70 | /* always have a valid stack */ 71 | ldr sp, [pc, #-12] 72 | push {lr} 73 | blx r0 74 | isb 75 | mrc p15, 0, r12, c1, c1, 0 76 | /* set the NS bit */ 77 | orr r12, r12, #1 78 | mcr p15, 0, r12, c1, c1, 0 79 | pop {lr} 80 | isb 81 | movs pc, lr 82 | 83 | /* for all other exceptions, just hang */ 84 | smc_halt: 85 | ldr pc, [pc, #-48] 86 | 87 | arm_monitor_vector_end: 88 | -------------------------------------------------------------------------------- /elfloader-tool/src/plat/imx7/head_smp.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | .extern non_boot_core 14 | 15 | #if CONFIG_MAX_NUM_NODES > 1 16 | BEGIN_FUNC(imx_non_boot) 17 | /* Invalidate caches before proceeding... */ 18 | mov r0, #0 19 | mcr IIALL(r0) 20 | dcache isw 21 | 22 | b non_boot_core 23 | END_FUNC(imx_non_boot) 24 | 25 | BEGIN_FUNC(non_boot_core) 26 | /* Disable Async aborts that might be pending from bootloader */ 27 | cpsid ifa 28 | 29 | /* Enable SMP */ 30 | mrc ACTLR(r0) 31 | orr r0, r0, #(1 << 6) /* enable SMP bit */ 32 | #ifdef CONFIG_ARM_CORTEX_A9 33 | orr r0, r0, #1 /* enable FW bit */ 34 | #endif 35 | mcr ACTLR(r0) 36 | 37 | ldr r2, =smp_aps_index 38 | ldr r3, =core_stack_alloc - 0x10 39 | 40 | /* Get stack index */ 41 | mov r0, r2 42 | 1: ldrex r1, [r0] 43 | add r1, r1, #1 44 | strex r2, r1, [r0] 45 | teq r2, #0 46 | bne 1b 47 | 48 | /* Set up stack */ 49 | mov r0, #0x1000 50 | mul r1, r0 51 | add r3, r1 52 | mov sp, r3 53 | b non_boot_main 54 | END_FUNC(non_boot_core) 55 | #endif /* CONFIG_MAX_NUM_NODES */ 56 | 57 | -------------------------------------------------------------------------------- /elfloader-tool/src/plat/imx7/smp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * Copyright: Linux Kernel team 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | * 6 | * The code in here is derived from the Linux kernel 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #if CONFIG_MAX_NUM_NODES > 1 18 | VISIBLE volatile word_t smp_aps_index = 1; 19 | 20 | /* System Reset Controller base address */ 21 | #define SRC_BASE 0x30390000 22 | #define GPC_BASE 0x303a0000 23 | 24 | #define SRC_SCR 0x000 25 | #define SRC_GPR1 0x020 26 | #define BP_SRC_SCR_WARM_RESET_ENABLE 0 27 | #define BP_SRC_SCR_CORE1_RST 14 28 | #define BP_SRC_SCR_CORE1_ENABLE 22 29 | 30 | #define GPC_CPU_PGC_SW_PUP_REQ 0xf0 31 | #define BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7 0x2 32 | #define GPC_PGC_C1 0x840 33 | #define BP_SRC_A7RCR1_A7_CORE1_ENABLE 1 34 | 35 | #define SRC_A7RCR1 0x008 36 | #define SRC_GPR1_V2 0x074 37 | 38 | #define REG(base,offset) (*(volatile unsigned int*)(((void *)(base))+(offset))) 39 | 40 | void imx_non_boot(void); 41 | 42 | static void src_init(void) 43 | { 44 | unsigned int val; 45 | val = REG(SRC_BASE, SRC_SCR); 46 | val &= ~(1 << BP_SRC_SCR_WARM_RESET_ENABLE); 47 | REG(SRC_BASE, SRC_SCR) = val; 48 | } 49 | 50 | static void gpc_core1_up(void) 51 | { 52 | unsigned int val = REG(GPC_BASE, GPC_CPU_PGC_SW_PUP_REQ); 53 | 54 | REG(GPC_BASE, GPC_PGC_C1) = 1; 55 | 56 | val |= BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7; 57 | 58 | REG(GPC_BASE, GPC_CPU_PGC_SW_PUP_REQ) = val; 59 | 60 | while ((REG(GPC_BASE, GPC_CPU_PGC_SW_PUP_REQ) & BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7) != 0); 61 | 62 | REG(GPC_BASE, GPC_PGC_C1) = 0; 63 | } 64 | 65 | static void src_enable_cpu(int cpu) 66 | { 67 | unsigned int mask, val; 68 | 69 | gpc_core1_up(); 70 | mask = 1 << (BP_SRC_A7RCR1_A7_CORE1_ENABLE + cpu - 1); 71 | val = REG(SRC_BASE, SRC_A7RCR1); 72 | val |= mask; 73 | REG(SRC_BASE, SRC_A7RCR1) = val; 74 | } 75 | 76 | static void src_set_cpu_jump(int cpu, unsigned int jump_addr) 77 | { 78 | REG(SRC_BASE, SRC_GPR1_V2 + cpu * 8) = (unsigned int)jump_addr; 79 | dsb(); 80 | } 81 | 82 | void init_cpus(void) 83 | { 84 | unsigned int i, num; 85 | 86 | src_init(); 87 | 88 | /* get core count from L2CTLR */ 89 | asm volatile("mrc p15, 1, %0, c9, c0, 2": "=r"(num)); 90 | num = ((num >> 24) & 0x3) + 1; 91 | 92 | if (num > CONFIG_MAX_NUM_NODES) { 93 | num = CONFIG_MAX_NUM_NODES; 94 | } else if (num < CONFIG_MAX_NUM_NODES) { 95 | printf("Error: Unsupported number of CPUs! This platform has %u CPUs, while static configuration provided is %u CPUs\n", 96 | num, CONFIG_MAX_NUM_NODES); 97 | abort(); 98 | } 99 | 100 | printf("Bringing up %d other cpus\n", num - 1); 101 | for (i = 1; i < num; i++) { 102 | src_set_cpu_jump(i, (unsigned int)imx_non_boot); 103 | src_enable_cpu(i); 104 | } 105 | } 106 | #endif /* CONFIG_MAX_NUM_NODES */ 107 | -------------------------------------------------------------------------------- /elfloader-tool/src/plat/tk1/monitor.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | 8 | #include 9 | #include 10 | 11 | #ifndef CONFIG_ARM_MONITOR_HOOK 12 | #error This file is for CONFIG_ARM_MONITOR_HOOK only 13 | #endif 14 | 15 | #define VECTOR_BASE 0xa7f00000 16 | #define STACK_TOP (VECTOR_BASE + (1 << 20) - 0x10) 17 | 18 | /* vector table for monitor mode 19 | * 0x00: not used 20 | * 0x04: not used 21 | * 0x08: secure monitor call 22 | * 0x0c: prefetch abort 23 | * 0x10: data abort 24 | * 0x14: not used 25 | * 0x18: IRQ interrupt 26 | * 0x1c: FIQ interrupt 27 | */ 28 | 29 | .global arm_monitor_vector 30 | .global arm_monitor_vector_end 31 | .global smc_handler 32 | .global smc_halt 33 | 34 | /* pc contains the current instruction + 8 bytes 35 | * use pc-relative addressing so we can copy the 36 | * table. only the offset 0x08 is set up to call 37 | * smc_handler, other offsets halt the system. 38 | */ 39 | 40 | arm_monitor_vector: 41 | ldr pc, [pc, #28] 42 | ldr pc, [pc, #24] 43 | ldr pc, [pc, #16] 44 | ldr pc, [pc, #16] 45 | ldr pc, [pc, #12] 46 | ldr pc, [pc, #8] 47 | ldr pc, [pc, #4] 48 | ldr pc, [pc, #0] 49 | 50 | smc_handler_addr: 51 | .word VECTOR_BASE + (smc_handler - arm_monitor_vector) 52 | smc_halt_addr: 53 | .word VECTOR_BASE + (smc_halt - arm_monitor_vector) 54 | smc_stack: 55 | .word STACK_TOP 56 | 57 | /* r0: the start physical address for the code that the 58 | * caller wants to execute in monitor mode. I know, a huge 59 | * security hole. WARNING: the code to be executed should 60 | * not reference memory locations !!! 61 | */ 62 | smc_handler: 63 | /* always have a valid stack */ 64 | ldr sp, [pc, #-12] 65 | push {lr} 66 | blx r0 67 | mrc p15, 0, r12, c1, c1, 0 68 | /* set the NS bit */ 69 | orr r12, r12, #1 70 | mcr p15, 0, r12, c1, c1, 0 71 | pop {lr} 72 | movs pc, lr 73 | 74 | /* for all other exceptions, just hang */ 75 | smc_halt: 76 | ldr pc, [pc, #-48] 77 | 78 | arm_monitor_vector_end: 79 | -------------------------------------------------------------------------------- /elfloader-tool/src/plat/tx2/platform_init.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /* The code for enabling SError is from L4T (Linux for Tegra). 12 | * Read the Parker TRM 17.12 and 17.13 for NVIDIA-specific 13 | * SError extensions and the ARI (abstract request interface). 14 | */ 15 | 16 | 17 | #define SMC_SIP_INVOKE_MCE 0xc2ffff00 18 | #define MCE_SMC_ENUM_MAX 0xff 19 | #define ARI_MCA_GLOBAL_CONFIG 0x12 20 | #define ARI_MCA_WRITE_SERR 0x2 21 | #define NR_SMC_REGS 6 22 | 23 | typedef union { 24 | struct { 25 | uint8_t cmd; 26 | uint8_t subidx; 27 | uint8_t idx; 28 | uint8_t inst; 29 | }; 30 | struct { 31 | uint32_t low; 32 | uint32_t high; 33 | }; 34 | uint64_t data; 35 | } mca_cmd_t; 36 | 37 | struct mce_regs { 38 | uint64_t args[NR_SMC_REGS]; 39 | }; 40 | 41 | static __attribute__((noinline)) int send_smc(uint8_t func, struct mce_regs *regs) 42 | { 43 | uint32_t ret = SMC_SIP_INVOKE_MCE | (func & MCE_SMC_ENUM_MAX); 44 | asm volatile( 45 | "mov x0, %x0\n" 46 | "ldp x1, x2, [%1, #16 * 0] \n" 47 | "ldp x3, x4, [%1, #16 * 1] \n" 48 | "ldp x5, x6, [%1, #16 * 2] \n" 49 | "isb\n" 50 | "smc #0\n" 51 | "mov %x0, x0\n" 52 | "stp x0, x1, [%1, #16 * 0]\n" 53 | "stp x2, x3, [%1, #16 * 1]\n" 54 | : "+r"(ret) 55 | : "r"(regs) 56 | : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", 57 | "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17"); 58 | return ret; 59 | } 60 | 61 | 62 | static void tegra_mce_write_uncore_mca(mca_cmd_t cmd, uint64_t data, uint32_t *err) 63 | { 64 | struct mce_regs regs = {0}; 65 | regs.args[0] = cmd.data; 66 | regs.args[1] = data; 67 | send_smc(13, ®s); 68 | *err = (uint32_t)regs.args[3]; 69 | } 70 | 71 | static void enable_serr(void) 72 | { 73 | uint32_t err; 74 | mca_cmd_t cmd; 75 | cmd.data = 0; 76 | cmd.cmd = ARI_MCA_WRITE_SERR; 77 | cmd.idx = ARI_MCA_GLOBAL_CONFIG; 78 | tegra_mce_write_uncore_mca(cmd, 1, &err); 79 | printf("Enabling TX2 SError result %d\n", err); 80 | } 81 | 82 | /* Enable SError report for TX2 */ 83 | void platform_init(void) 84 | { 85 | enable_serr(); 86 | } 87 | -------------------------------------------------------------------------------- /elfloader-tool/src/plat/zynq7000/platform_init.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #define MPCORE_PRIV 0xF8F00000 11 | 12 | /* SCU */ 13 | #define SCU_BASE (MPCORE_PRIV + 0x0) 14 | #define SCU_CTRL_OFFSET 0x000 15 | #define SCU_FILTADDR_START_OFFSET 0x040 16 | #define SCU_FILTADDR_END_OFFSET 0x044 17 | 18 | #define SCU_CTRL_EN BIT(0) 19 | #define SCU_CTRL_ADDRFILT_EN BIT(1) 20 | 21 | /* SLCR */ 22 | #define SLCR_BASE 0xF8000000 23 | #define SLCR_LOCK_OFFSET 0x004 24 | #define SLCR_UNLOCK_OFFSET 0x008 25 | #define SLCR_OCM_CFG_OFFSET 0x910 26 | 27 | #define SLCR_LOCK_KEY 0x767B 28 | #define SLCR_UNLOCK_KEY 0xDF0D 29 | 30 | #define SLCR_OCM_CFG_RAMHI(x) BIT(x) 31 | #define SLCR_OCM_CFG_RAMHI_ALL ( SLCR_OCM_CFG_RAMHI(0) \ 32 | | SLCR_OCM_CFG_RAMHI(1) \ 33 | | SLCR_OCM_CFG_RAMHI(2) \ 34 | | SLCR_OCM_CFG_RAMHI(3) ) 35 | 36 | #define REG(a) *(volatile uint32_t*)(a) 37 | 38 | #define SCU(o) REG(SCU_BASE + SCU_##o##_OFFSET) 39 | #define SLCR(o) REG(SLCR_BASE + SLCR_##o##_OFFSET) 40 | 41 | /* Remaps the OCM and ensures DDR is accessible at 0x00000000 */ 42 | void remap_ram(void) 43 | { 44 | /*** 29.4.1 Changing Address Mapping ***/ 45 | /* 1: Complete outstanding transactions */ 46 | asm volatile("dsb"); 47 | asm volatile("isb"); 48 | 49 | /* 2-4: prime the icache with this function 50 | * skipped because icache is disabled and our remapping does not 51 | * affect .text section */ 52 | 53 | /* 5-7: unlock SLCR, Modify OCM_CFG, lock SLCR */ 54 | SLCR(UNLOCK) = SLCR_UNLOCK_KEY; 55 | SLCR(OCM_CFG) |= SLCR_OCM_CFG_RAMHI_ALL; 56 | SLCR(LOCK) = SLCR_LOCK_KEY; 57 | 58 | /* 8-9: Modify address filtering */ 59 | SCU(FILTADDR_START) = 0x00000000; 60 | SCU(FILTADDR_END) = 0xFFE00000; 61 | 62 | /* 10: Enable filtering */ 63 | SCU(CTRL) |= (SCU_CTRL_EN | SCU_CTRL_ADDRFILT_EN); 64 | 65 | /* Ensure completion */ 66 | asm volatile("dmb"); 67 | } 68 | 69 | void platform_init(void) 70 | { 71 | remap_ram(); 72 | } 73 | -------------------------------------------------------------------------------- /elfloader-tool/src/utils/hash.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017, DornerWorks 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-only 5 | * 6 | * This data was produced by DornerWorks, Ltd. of Grand Rapids, MI, USA under 7 | * a DARPA SBIR, Contract Number D16PC00107. 8 | * 9 | * Approved for Public Release, Distribution Unlimited. 10 | * 11 | */ 12 | 13 | #include 14 | #include 15 | 16 | #include "../hash.h" 17 | 18 | /* Function to perform all hash operations. 19 | * 20 | * The outputted hash is stored in the outputted_hash pointer after the "sum" 21 | * operation is used. This way beats having a bunch of #ifdefs in the source 22 | * code, and is scalable to any other hashing algorithm. 23 | */ 24 | void get_hash( 25 | hashes_t hashes, 26 | const void *data, 27 | size_t len, 28 | void *outputted_hash) 29 | { 30 | if (hashes.hash_type == SHA_256) { 31 | sha256_t calculated_hash = hashes.sha_structure; 32 | sha256_init(&calculated_hash); 33 | sha256_update(&calculated_hash, data, len); 34 | sha256_sum(&calculated_hash, outputted_hash); 35 | } else { 36 | md5_t calculated_hash = hashes.md5_structure; 37 | md5_init(&calculated_hash); 38 | md5_update(&calculated_hash, data, len); 39 | md5_sum(&calculated_hash, outputted_hash); 40 | } 41 | } 42 | 43 | /* Function to print the hash */ 44 | void print_hash( 45 | void const *hash, 46 | size_t len) 47 | { 48 | uint8_t const *hash_bytes = hash; 49 | for (size_t i = 0; i < len; i++) { 50 | printf("%02x", hash_bytes[i]); 51 | } 52 | printf("\n"); 53 | } 54 | -------------------------------------------------------------------------------- /misc/.gitlint: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | 7 | [general] 8 | # By default gitlint will ignore merge commits. Set to 'false' to disable. 9 | ignore-merge-commits=true 10 | 11 | # By default gitlint will ignore fixup commits. Set to 'false' to disable. 12 | ignore-fixup-commits=false 13 | 14 | # By default gitlint will ignore squash commits. Set to 'false' to disable. 15 | ignore-squash-commits=false 16 | 17 | # So far, gitlint uses Python's `re.match()` (match from start) by default, but 18 | # it will change to use the more generic `re.search()` (match anywhere) in the 19 | # future. With 'regex-style-search' the behaviour can be controlled. Since we 20 | # prefer `re.search()` anyway, the new behavior is enabled. For more details 21 | # see also https://jorisroovers.com/gitlint/configuration/#regex-style-search. 22 | regex-style-search=true 23 | 24 | 25 | [title-max-length] 26 | line-length=50 27 | 28 | [title-must-not-contain-word] 29 | # Comma-separated list of words that should not occur in the title. Matching is case 30 | # insensitive. It's fine if the keyword occurs as part of a larger word (so "WIPING" 31 | # will not cause a violation, but "WIP: my title" will. 32 | words=wip,squash,tosquash 33 | 34 | [body-max-line-length] 35 | line-length=72 36 | 37 | [body-min-length] 38 | min-length=0 39 | 40 | 41 | [ignore-by-title] 42 | # Ignore certain rules for commits of which the title matches a regex 43 | # E.g. Match commit titles that start with "Release" 44 | regex=^trivial(.*) 45 | # 46 | # Ignore certain rules, you can reference them by their id or by their full name 47 | # Use 'all' to ignore all rules 48 | ignore=B6 49 | -------------------------------------------------------------------------------- /misc/Makefile.cpio_strip: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | libcpio = ${SEL4_LIBS_PATH}/libcpio 7 | 8 | cpio-strip: cpio-strip.c ${libcpio}/src/cpio.c ${libcpio}/include/cpio/cpio.h 9 | @echo " [CC] $@" 10 | ${Q}${CC} -W -Wall -Wextra -std=c99 -I${libcpio}/include cpio-strip.c ${libcpio}/src/cpio.c -o $@ 11 | 12 | clean: 13 | rm cpio-strip 14 | -------------------------------------------------------------------------------- /misc/README.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | # seL4_tools misc tools 8 | 9 | These are a collection of tools or configuration files that relate to seL4 in some way. 10 | 11 | ## Style tools 12 | 13 | Many of the files are for use in styling sources for various languages. 14 | 15 | Files for styling a particular language: 16 | - `style-c.sh`, `astylerc`: Style a single c file using `astyle` and the astylerc config 17 | - `style-cmake.sh`: Style a CMake file using `cmake-format`. Will also look for `.cmake-format.yaml` 18 | files in repo directories. 19 | - `style-py.sh`: Style python files using `autopep8` 20 | - `.gitlint`: Configuration file for `gitlint` tool for checking Git commit messages. 21 | - `is-valid-shell-script`: Script for checking valid shell script syntax. 22 | 23 | Scripts for batching multiple style operations across different files: 24 | - `style.sh`: Finds any `.stylefilter` files in local directories and calls `style.py` 25 | - `style.py`, `filter.py`: Filters an input list of files based on `.stylefilter` and then calls the relevant 26 | style script based on the remaining file's extensions. 27 | - `style-changed.sh`: Styles all changed files in current Git repository 28 | - `style-all.sh`: Styles all files in current Git repository 29 | 30 | ## Other 31 | 32 | - `whence.py`: A tool for determining source code provenance for imported repositories without history. 33 | - `cpio-strip.c`/`Makefile.cpio_strip`: A program for stripping metadata from CPIO archives to enable 34 | reproducible builds. (Recent versions of cpio support this with the `--reproducible` flag) 35 | - `cobbler`: Build a qemu-bootable harddisk image. 36 | -------------------------------------------------------------------------------- /misc/astylerc: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 | # 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | 7 | style=otbs 8 | pad-header 9 | indent=spaces=4 10 | attach-closing-while 11 | pad-oper 12 | pad-comma 13 | unpad-paren 14 | align-pointer=name 15 | add-braces 16 | attach-return-type 17 | convert-tabs 18 | min-conditional-indent=0 19 | max-code-length=120 20 | max-continuation-indent=120 21 | 22 | -------------------------------------------------------------------------------- /misc/cobbler: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 4 | # 5 | # SPDX-License-Identifier: BSD-2-Clause 6 | # 7 | 8 | # Build a qemu-bootable harddisk image. 9 | # 10 | # Usage: 11 | # An optional kernel command line argument is provided with -a. 12 | # The kernel image is provided with -k. 13 | # The output harddisk image is specified with -o. 14 | # Userland images are provided after that (usually only one). 15 | # 16 | # Authors: 17 | # Benjamin Kalman, 2009 18 | # Michael von Tessin, 2010 19 | 20 | # Support build system debugging directive passed from above. 21 | if [ 0${V} -ge 3 ]; then 22 | set -x 23 | fi 24 | 25 | # Find syslinux 26 | SYSLINUX=`which syslinux` 27 | if [ -z "${SYSLINUX}" ]; then 28 | echo "syslinux not found." >&2 29 | exit 1 30 | fi 31 | SYSLINUXDIR=`echo $SYSLINUX | sed 's:/bin/:/share/:'` 32 | [ -d "$SYSLINUXDIR" ] || SYSLINUXDIR="`echo $SYSLINUXDIR | sed 's:/share/:/lib/:'`" 33 | 34 | [ -d "$SYSLINUXDIR" ] || { 35 | echo >&2 "Cannot find syslinux data directory!" 36 | exit 1 37 | } 38 | 39 | if [ -f "$SYSLINUXDIR"/mbr.bin ] 40 | then 41 | SYSLINUX_MODULES="$SYSLINUXDIR" 42 | MBR="$SYSLINUXDIR"/mbr.bin 43 | elif [ -d "$SYSLINUXDIR"/modules ] 44 | then 45 | SYSLINUX_MODULES="$SYSLINUXDIR"/modules/bios/ 46 | MBR="$SYSLINUXDIR"/mbr/mbr.bin 47 | fi 48 | 49 | [ -f "$MBR" ] || { 50 | echo >&2 "Can't find mbr.bin. Is syslinux installed?" 51 | exit 1 52 | } 53 | 54 | trap "rm -f mtoolsrc syslinux.cfg mbr.bin" 0 55 | 56 | # Parse options 57 | while getopts "k:o:a:" flag ; do 58 | case "$flag" in 59 | k) KERNEL="$OPTARG" ;; 60 | o) OUTIMG="$OPTARG" ;; 61 | a) CMDLINE="$OPTARG" ;; 62 | esac 63 | done 64 | shift $(($OPTIND-1)) 65 | UIMGS=$@ 66 | 67 | if [ ! -f "$KERNEL" -o -z "$OUTIMG" -o -z "$UIMGS" ] ; then 68 | echo "Usage: $0 [-a kernel_cmdline] -k kernel_image -o output_image userland_images ..." 69 | exit 1 70 | fi 71 | 72 | for UIMG in $UIMGS ; do 73 | if [ ! -f "$UIMG" ] ; then 74 | echo "Error: Userland image '$UIMG' not found!" 75 | exit 1 76 | fi 77 | done 78 | 79 | MODULES="$SYSLINUX_MODULES/mboot.c32" 80 | [ -f $SYSLINUX_MODULES/libcom32.c32 ] && MODULES="$MODULES $SYSLINUX_MODULES/libcom32.c32" 81 | # Calculate image size and number of cylinders 82 | 83 | IMGSIZE=`stat -c '%s' $UIMGS $KERNEL $MODULES | awk ' { sum += $1 } END { print sum }'` 84 | 85 | echo "final image size will be $IMGSIZE" 86 | 87 | HEADS=16 88 | SECTORS=63 89 | BLKSPERCYL=`expr $HEADS \* $SECTORS` 90 | CYLINDERS=`expr 2 + $IMGSIZE / 512 / $BLKSPERCYL` 91 | 92 | # Create a blank image 93 | dd if=/dev/zero of="$OUTIMG" count=1 seek=`expr $CYLINDERS \* $BLKSPERCYL - 1` bs=512 2>/dev/null 94 | 95 | # Set up mtools 96 | echo "drive c: file=\"$OUTIMG\" partition=1" > mtoolsrc 97 | export MTOOLSRC=mtoolsrc 98 | 99 | # Get mbr.bin and blow up/cut down to 512 bytes (required by mtools) 100 | cat "$MBR" /dev/zero 2>/dev/null | head -c 512 > mbr.bin 101 | 102 | # Create filesystem 103 | which mpartition >/dev/null 2>&1 104 | if [ $? -ne 0 ]; then 105 | echo "mpartition not found. Is mtools installed?" >&2 106 | exit 1 107 | fi 108 | mpartition -I -B mbr.bin c: 109 | mpartition -c -t $CYLINDERS -h $HEADS -s $SECTORS c: 110 | mpartition -a c: 111 | mformat c: 112 | syslinux --offset `expr $SECTORS \* 512` $OUTIMG 113 | 114 | # Write syslinux config file 115 | UIMGS_CFG="" 116 | for UIMG in $UIMGS 117 | do 118 | UIMGS_CFG="$UIMGS_CFG --- `basename $UIMG`" 119 | done 120 | 121 | cat > syslinux.cfg <&2 135 | exit 1 136 | } 137 | done 138 | 139 | # And we're done 140 | echo "Image '$OUTIMG' successfully created" 141 | -------------------------------------------------------------------------------- /misc/filter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 4 | # 5 | # SPDX-License-Identifier: BSD-2-Clause 6 | # 7 | import argparse 8 | import fnmatch 9 | import re 10 | import sys 11 | 12 | # never run the tools on anything git 13 | DEFAULT_FILTERS = ["*.git/*"] 14 | 15 | # support comments alone and trailing (comment with #) 16 | COMMENT = re.compile(r'^\s*#') 17 | TRAILING_COMMENT = re.compile(r'\s+#.*$') 18 | 19 | 20 | def parse_filter(line: str): 21 | """Parse a filter from a line of a filter file""" 22 | line = line.strip() 23 | if line and not COMMENT.search(line): 24 | return TRAILING_COMMENT.sub('', line) 25 | return None 26 | 27 | 28 | def parse_filters(filters_file: str): 29 | """Parse the filter file, returning a list of filters""" 30 | filters = DEFAULT_FILTERS 31 | if filters_file: 32 | try: 33 | with open(filters_file, 'r') as outfile: 34 | lines = outfile.readlines() 35 | filters += [parse_filter(l) for l in lines if parse_filter(l)] 36 | except IOError as exception: 37 | logging.warning("Failed to open filter file %s: %s", filters_file, exception) 38 | return filters 39 | 40 | 41 | def main(): 42 | parser = argparse.ArgumentParser("Filter files.") 43 | parser.add_argument('-f', '--filters', type=str, 44 | help='File with glob filters of files') 45 | parser.add_argument('files', nargs='*', type=str, 46 | help='List of files to be filtered') 47 | args = parser.parse_args() 48 | 49 | filters = parse_filters(args.filters) 50 | for fname in args.files: 51 | def matches(pattern, fname=fname): 52 | return fnmatch.fnmatch(fname, pattern) 53 | if not any(map(matches, filters)): 54 | print(fname) 55 | 56 | 57 | if __name__ == '__main__': 58 | sys.exit(main()) 59 | -------------------------------------------------------------------------------- /misc/style-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 4 | # 5 | # SPDX-License-Identifier: BSD-2-Clause 6 | # 7 | 8 | # Run style tools on all dirs passed in, or the current dir. 9 | if [ $# -eq 0 ] 10 | then 11 | set -- "$(pwd)" 12 | fi 13 | 14 | for DIR 15 | do 16 | find "$DIR" -type f | xargs "${0%/*}"/style.sh 17 | done 18 | -------------------------------------------------------------------------------- /misc/style-c.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 4 | # 5 | # SPDX-License-Identifier: BSD-2-Clause 6 | # 7 | set -e 8 | 9 | if ! command -v astyle >/dev/null 2>&1 10 | then 11 | echo "astyle could not be found, it must be available to run the script." 12 | exit 1 13 | fi 14 | 15 | # Format (in place) a list of files as C code. 16 | astyle --options="${0%/*}/astylerc" "$@" 17 | 18 | 19 | for f 20 | do 21 | python3 -m guardonce.guard2once -s "$f" 22 | done 23 | -------------------------------------------------------------------------------- /misc/style-changed.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 4 | # 5 | # SPDX-License-Identifier: BSD-2-Clause 6 | # 7 | 8 | # Run the style tools on all changed files in the current repository. 9 | git ls-files -mo | xargs "${0%/*}"/style.sh 10 | -------------------------------------------------------------------------------- /misc/style-cmake.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 4 | # 5 | # SPDX-License-Identifier: BSD-2-Clause 6 | # 7 | # 8 | 9 | # Style an input list of files as cmake files. 10 | 11 | PROGNAME=${0##*/} 12 | 13 | # Pass the cmake format as args such that cmake-format.py can be used 14 | # to provide definitions for custom function formatting. 15 | CMAKE_FMT="--line-width 100 \ 16 | --tab-size 4 \ 17 | --max-subargs-per-line 3 \ 18 | --separate-ctrl-name-with-space False \ 19 | --separate-fn-name-with-space False \ 20 | --dangle-parens True \ 21 | --command-case unchanged \ 22 | --keyword-case unchanged \ 23 | --enable-markup False" 24 | 25 | # cmake-format sends its version info to standard error. :-/ 26 | CF_VERSION=$(cmake-format --version 2>&1) 27 | DESIRED_VERSION=0.4.5 28 | 29 | case "$CF_VERSION" in 30 | ("") 31 | echo "$PROGNAME: fatal error: no output from \"cmake-format --version\"" 32 | exit 2 33 | ;; 34 | ($DESIRED_VERSION) 35 | # Good version; proceed. 36 | ;; 37 | (*) 38 | echo "$PROGNAME: fatal error: need version $DESIRED_VERSION of" \ 39 | "cmake-format; $CF_VERSION is installed" 40 | exit 2 41 | ;; 42 | esac 43 | 44 | cmake-format -i $CMAKE_FMT "$@" 45 | -------------------------------------------------------------------------------- /misc/style-py.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 4 | # 5 | # SPDX-License-Identifier: BSD-2-Clause 6 | # 7 | # 8 | 9 | # Format (in place) a list of files as Python code. 10 | autopep8 -i --max-line-length 100 "$@" 11 | -------------------------------------------------------------------------------- /misc/style.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 4 | # 5 | # SPDX-License-Identifier: BSD-2-Clause 6 | # 7 | """ 8 | run style tools over files 9 | """ 10 | 11 | import argparse 12 | import fnmatch 13 | import logging 14 | import os 15 | import re 16 | import subprocess 17 | import sys 18 | 19 | from filter import parse_filters 20 | 21 | # dict of style-tools to regex. The regex should match any full file path. 22 | # if the regex matches, that tool will be applied to that file. Multiple 23 | # tools can be defined for the same regex. 24 | STYLE_MAP = { 25 | 'style-c.sh': r'((\.c)|(\.h))$', 26 | 'style-cmake.sh': r'((\.cmake)|(CMakeLists.txt))$', 27 | 'style-py.sh': r'\.py$' 28 | } 29 | 30 | 31 | def main(): 32 | parser = argparse.ArgumentParser("Run style updates on files.") 33 | parser.add_argument('-f', '--filters', type=str, 34 | help='File with glob filters of files to filter') 35 | parser.add_argument('files', nargs='*', type=str, 36 | help='List of files to run style updates on.') 37 | args = parser.parse_args() 38 | 39 | filters = parse_filters(args.filters) 40 | regexmap = {k: re.compile(v) for k, v in STYLE_MAP.items()} 41 | filemap = {k: [] for k, v in STYLE_MAP.items()} 42 | 43 | args.files = filter(os.path.isfile, args.files) 44 | # construct a list of files to pass to each tool 45 | for fname in args.files: 46 | # strip leading `./` which `find` produces, but stylefilters don't expect 47 | if fname[0:2] == './': 48 | fname = fname[2:] 49 | 50 | def matches(pattern, fname=fname): 51 | """filter any files that match the filter filters""" 52 | return fnmatch.fnmatch(fname, pattern) 53 | if not any(map(matches, filters)): 54 | for k, regex in regexmap.items(): 55 | if regex.search(fname): 56 | filemap.get(k, list()).append(fname) 57 | 58 | # now spawn processes to style all the files 59 | # this is currently done sequentially to collect output. 60 | # if this becomes a bottle neck we can consider spawning more processes 61 | return_code = 0 62 | for k, files in filemap.items(): 63 | if files: 64 | script = os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), k) 65 | completed = subprocess.run([script] + files, stderr=subprocess.PIPE) 66 | if completed.returncode: 67 | logging.fatal("%s failed with error code %d\n%s", files, 68 | completed.returncode, completed.stderr) 69 | return_code = completed.returncode 70 | return return_code 71 | 72 | 73 | if __name__ == '__main__': 74 | sys.exit(main()) 75 | -------------------------------------------------------------------------------- /misc/style.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 4 | # 5 | # SPDX-License-Identifier: BSD-2-Clause 6 | # 7 | 8 | set -efu 9 | 10 | # A repo can keep its local style filter in its top-level directory. 11 | LOCAL_FILTER=.stylefilter 12 | 13 | if [ -f $LOCAL_FILTER ] 14 | then 15 | FILTER_ARG="-f $LOCAL_FILTER" 16 | else 17 | FILTER_ARG= 18 | fi 19 | 20 | # Run style tools over list of files passed as input. 21 | "${0%/*}"/style.py $FILTER_ARG "$@" 22 | --------------------------------------------------------------------------------