diff options
-rw-r--r-- | Documentation/admin-guide/kernel-parameters.txt | 3 | ||||
-rw-r--r-- | Documentation/process/changes.rst | 9 | ||||
-rw-r--r-- | MAINTAINERS | 7 | ||||
-rw-r--r-- | arch/arm64/Makefile | 11 | ||||
-rw-r--r-- | arch/arm64/boot/.gitignore | 1 | ||||
-rw-r--r-- | arch/arm64/boot/Makefile | 6 | ||||
-rw-r--r-- | arch/arm64/include/asm/assembler.h | 6 | ||||
-rw-r--r-- | arch/arm64/include/asm/cputype.h | 2 | ||||
-rw-r--r-- | arch/arm64/include/asm/irqflags.h | 1 | ||||
-rw-r--r-- | arch/arm64/include/asm/jump_label.h | 28 | ||||
-rw-r--r-- | arch/arm64/include/asm/sysreg.h | 24 | ||||
-rw-r--r-- | arch/arm64/kernel/acpi.c | 10 | ||||
-rw-r--r-- | arch/arm64/kernel/pi/idreg-override.c | 2 | ||||
-rw-r--r-- | arch/arm64/kernel/setup.c | 11 | ||||
-rw-r--r-- | arch/arm64/kernel/smp.c | 7 | ||||
-rw-r--r-- | arch/arm64/mm/proc.S | 10 | ||||
-rw-r--r-- | drivers/acpi/acpica/tbfadt.c | 30 | ||||
-rw-r--r-- | drivers/acpi/acpica/tbutils.c | 7 | ||||
-rw-r--r-- | scripts/Makefile.lib | 16 | ||||
-rwxr-xr-x | scripts/make_fit.py | 290 | ||||
-rw-r--r-- | tools/arch/arm64/include/asm/sysreg.h | 24 |
21 files changed, 424 insertions, 81 deletions
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 623fce7d5fcd..afd6fcc1e8b9 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -431,6 +431,9 @@ arcrimi= [HW,NET] ARCnet - "RIM I" (entirely mem-mapped) cards Format: <io>,<irq>,<nodeID> + arm64.no32bit_el0 [ARM64] Unconditionally disable the execution of + 32 bit applications. + arm64.nobti [ARM64] Unconditionally disable Branch Target Identification support diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst index 7ef8de58f7f8..3a39395bd9d3 100644 --- a/Documentation/process/changes.rst +++ b/Documentation/process/changes.rst @@ -62,6 +62,7 @@ Sphinx\ [#f1]_ 2.4.4 sphinx-build --version cpio any cpio --version GNU tar 1.28 tar --version gtags (optional) 6.6.5 gtags --version +mkimage (optional) 2017.01 mkimage --version ====================== =============== ======================================== .. [#f1] Sphinx is needed only to build the Kernel documentation @@ -189,6 +190,14 @@ The kernel build requires GNU GLOBAL version 6.6.5 or later to generate tag files through ``make gtags``. This is due to its use of the gtags ``-C (--directory)`` flag. +mkimage +------- + +This tool is used when building a Flat Image Tree (FIT), commonly used on ARM +platforms. The tool is available via the ``u-boot-tools`` package or can be +built from the U-Boot source code. See the instructions at +https://docs.u-boot.org/en/latest/build/tools.html#building-tools-for-linux + System utilities **************** diff --git a/MAINTAINERS b/MAINTAINERS index aea47e04c3a5..9db17a2fe3b0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3051,6 +3051,13 @@ F: drivers/mmc/host/sdhci-of-arasan.c N: zynq N: xilinx +ARM64 FIT SUPPORT +M: Simon Glass <sjg@chromium.org> +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: arch/arm64/boot/Makefile +F: scripts/make_fit.py + ARM64 PORT (AARCH64 ARCHITECTURE) M: Catalin Marinas <catalin.marinas@arm.com> M: Will Deacon <will@kernel.org> diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 0e075d3c546b..b8b1d4f4a572 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -154,6 +154,10 @@ libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a # Default target when executing plain make boot := arch/arm64/boot +BOOT_TARGETS := Image vmlinuz.efi image.fit + +PHONY += $(BOOT_TARGETS) + ifeq ($(CONFIG_EFI_ZBOOT),) KBUILD_IMAGE := $(boot)/Image.gz else @@ -162,8 +166,10 @@ endif all: $(notdir $(KBUILD_IMAGE)) -vmlinuz.efi: Image -Image vmlinuz.efi: vmlinux +image.fit: dtbs + +vmlinuz.efi image.fit: Image +$(BOOT_TARGETS): vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ Image.%: Image @@ -215,6 +221,7 @@ virtconfig: define archhelp echo '* Image.gz - Compressed kernel image (arch/$(ARCH)/boot/Image.gz)' echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)' + echo ' image.fit - Flat Image Tree (arch/$(ARCH)/boot/image.fit)' echo ' install - Install uncompressed kernel' echo ' zinstall - Install compressed kernel' echo ' Install using (your) ~/bin/installkernel or' diff --git a/arch/arm64/boot/.gitignore b/arch/arm64/boot/.gitignore index af5dc61f8b43..abaae9de1bdd 100644 --- a/arch/arm64/boot/.gitignore +++ b/arch/arm64/boot/.gitignore @@ -2,3 +2,4 @@ Image Image.gz vmlinuz* +image.fit diff --git a/arch/arm64/boot/Makefile b/arch/arm64/boot/Makefile index a5a787371117..607a67a649c4 100644 --- a/arch/arm64/boot/Makefile +++ b/arch/arm64/boot/Makefile @@ -16,7 +16,8 @@ OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R .comment -S -targets := Image Image.bz2 Image.gz Image.lz4 Image.lzma Image.lzo Image.zst +targets := Image Image.bz2 Image.gz Image.lz4 Image.lzma Image.lzo \ + Image.zst image.fit $(obj)/Image: vmlinux FORCE $(call if_changed,objcopy) @@ -39,6 +40,9 @@ $(obj)/Image.lzo: $(obj)/Image FORCE $(obj)/Image.zst: $(obj)/Image FORCE $(call if_changed,zstd) +$(obj)/image.fit: $(obj)/Image $(obj)/dts/dtbs-list FORCE + $(call if_changed,fit) + EFI_ZBOOT_PAYLOAD := Image EFI_ZBOOT_BFD_TARGET := elf64-littleaarch64 EFI_ZBOOT_MACH_TYPE := ARM64 diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h index ab8b396428da..6f9ad2d2bb40 100644 --- a/arch/arm64/include/asm/assembler.h +++ b/arch/arm64/include/asm/assembler.h @@ -50,16 +50,12 @@ msr daif, \flags .endm - .macro enable_dbg - msr daifclr, #8 - .endm - .macro disable_step_tsk, flgs, tmp tbz \flgs, #TIF_SINGLESTEP, 9990f mrs \tmp, mdscr_el1 bic \tmp, \tmp, #DBG_MDSCR_SS msr mdscr_el1, \tmp - isb // Synchronise with enable_dbg + isb // Take effect before a subsequent clear of DAIF.D 9990: .endm diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index 52f076afeb96..936389e9aecb 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -86,6 +86,7 @@ #define ARM_CPU_PART_CORTEX_X2 0xD48 #define ARM_CPU_PART_NEOVERSE_N2 0xD49 #define ARM_CPU_PART_CORTEX_A78C 0xD4B +#define ARM_CPU_PART_NEOVERSE_V2 0xD4F #define APM_CPU_PART_XGENE 0x000 #define APM_CPU_VAR_POTENZA 0x00 @@ -159,6 +160,7 @@ #define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2) #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2) #define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C) +#define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V2) #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) diff --git a/arch/arm64/include/asm/irqflags.h b/arch/arm64/include/asm/irqflags.h index 0a7186a93882..d4d7451c2c12 100644 --- a/arch/arm64/include/asm/irqflags.h +++ b/arch/arm64/include/asm/irqflags.h @@ -5,7 +5,6 @@ #ifndef __ASM_IRQFLAGS_H #define __ASM_IRQFLAGS_H -#include <asm/alternative.h> #include <asm/barrier.h> #include <asm/ptrace.h> #include <asm/sysreg.h> diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h index 6aafbb789991..4e753908b801 100644 --- a/arch/arm64/include/asm/jump_label.h +++ b/arch/arm64/include/asm/jump_label.h @@ -15,17 +15,23 @@ #define JUMP_LABEL_NOP_SIZE AARCH64_INSN_SIZE +#define JUMP_TABLE_ENTRY(key, label) \ + ".pushsection __jump_table, \"aw\"\n\t" \ + ".align 3\n\t" \ + ".long 1b - ., %l["#label"] - .\n\t" \ + ".quad %c0 - .\n\t" \ + ".popsection\n\t" \ + : : "i"(key) : : label + static __always_inline bool arch_static_branch(struct static_key * const key, const bool branch) { + char *k = &((char *)key)[branch]; + asm goto( "1: nop \n\t" - " .pushsection __jump_table, \"aw\" \n\t" - " .align 3 \n\t" - " .long 1b - ., %l[l_yes] - . \n\t" - " .quad %c0 - . \n\t" - " .popsection \n\t" - : : "i"(&((char *)key)[branch]) : : l_yes); + JUMP_TABLE_ENTRY(k, l_yes) + ); return false; l_yes: @@ -35,15 +41,11 @@ l_yes: static __always_inline bool arch_static_branch_jump(struct static_key * const key, const bool branch) { + char *k = &((char *)key)[branch]; asm goto( "1: b %l[l_yes] \n\t" - " .pushsection __jump_table, \"aw\" \n\t" - " .align 3 \n\t" - " .long 1b - ., %l[l_yes] - . \n\t" - " .quad %c0 - . \n\t" - " .popsection \n\t" - : : "i"(&((char *)key)[branch]) : : l_yes); - + JUMP_TABLE_ENTRY(k, l_yes) + ); return false; l_yes: return true; diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 9e8999592f3a..af3b206fa423 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -1036,18 +1036,18 @@ * Permission Indirection Extension (PIE) permission encodings. * Encodings with the _O suffix, have overlays applied (Permission Overlay Extension). */ -#define PIE_NONE_O 0x0 -#define PIE_R_O 0x1 -#define PIE_X_O 0x2 -#define PIE_RX_O 0x3 -#define PIE_RW_O 0x5 -#define PIE_RWnX_O 0x6 -#define PIE_RWX_O 0x7 -#define PIE_R 0x8 -#define PIE_GCS 0x9 -#define PIE_RX 0xa -#define PIE_RW 0xc -#define PIE_RWX 0xe +#define PIE_NONE_O UL(0x0) +#define PIE_R_O UL(0x1) +#define PIE_X_O UL(0x2) +#define PIE_RX_O UL(0x3) +#define PIE_RW_O UL(0x5) +#define PIE_RWnX_O UL(0x6) +#define PIE_RWX_O UL(0x7) +#define PIE_R UL(0x8) +#define PIE_GCS UL(0x9) +#define PIE_RX UL(0xa) +#define PIE_RW UL(0xc) +#define PIE_RWX UL(0xe) #define PIRx_ELx_PERM(idx, perm) ((perm) << ((idx) * 4)) diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c index dba8fcec7f33..e0e7b93c16cc 100644 --- a/arch/arm64/kernel/acpi.c +++ b/arch/arm64/kernel/acpi.c @@ -26,6 +26,7 @@ #include <linux/libfdt.h> #include <linux/smp.h> #include <linux/serial_core.h> +#include <linux/suspend.h> #include <linux/pgtable.h> #include <acpi/ghes.h> @@ -227,6 +228,15 @@ done: if (earlycon_acpi_spcr_enable) early_init_dt_scan_chosen_stdout(); } else { +#ifdef CONFIG_HIBERNATION + struct acpi_table_header *facs = NULL; + acpi_get_table(ACPI_SIG_FACS, 1, &facs); + if (facs) { + swsusp_hardware_signature = + ((struct acpi_table_facs *)facs)->hardware_signature; + acpi_put_table(facs); + } +#endif acpi_parse_spcr(earlycon_acpi_spcr_enable, true); if (IS_ENABLED(CONFIG_ACPI_BGRT)) acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt); diff --git a/arch/arm64/kernel/pi/idreg-override.c b/arch/arm64/kernel/pi/idreg-override.c index aad399796e81..48c1aa456af9 100644 --- a/arch/arm64/kernel/pi/idreg-override.c +++ b/arch/arm64/kernel/pi/idreg-override.c @@ -108,6 +108,7 @@ static const struct ftr_set_desc pfr0 __prel64_initconst = { .override = &id_aa64pfr0_override, .fields = { FIELD("sve", ID_AA64PFR0_EL1_SVE_SHIFT, pfr0_sve_filter), + FIELD("el0", ID_AA64PFR0_EL1_EL0_SHIFT, NULL), {} }, }; @@ -223,6 +224,7 @@ static const struct { { "nokaslr", "arm64_sw.nokaslr=1" }, { "rodata=off", "arm64_sw.rodataoff=1" }, { "arm64.nolva", "id_aa64mmfr2.varange=0" }, + { "arm64.no32bit_el0", "id_aa64pfr0.el0=1" }, }; static int __init parse_hexdigit(const char *p, u64 *v) diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index 65a052bf741f..a096e2451044 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -298,8 +298,15 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p) dynamic_scs_init(); /* - * Unmask SError as soon as possible after initializing earlycon so - * that we can report any SErrors immediately. + * The primary CPU enters the kernel with all DAIF exceptions masked. + * + * We must unmask Debug and SError before preemption or scheduling is + * possible to ensure that these are consistently unmasked across + * threads, and we want to unmask SError as soon as possible after + * initializing earlycon so that we can report any SErrors immediately. + * + * IRQ and FIQ will be unmasked after the root irqchip has been + * detected and initialized. */ local_daif_restore(DAIF_PROCCTX_NOIRQ); diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 4ced34f62dab..31c8b3094dd7 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -264,6 +264,13 @@ asmlinkage notrace void secondary_start_kernel(void) set_cpu_online(cpu, true); complete(&cpu_running); + /* + * Secondary CPUs enter the kernel with all DAIF exceptions masked. + * + * As with setup_arch() we must unmask Debug and SError exceptions, and + * as the root irqchip has already been detected and initialized we can + * unmask IRQ and FIQ at the same time. + */ local_daif_restore(DAIF_PROCCTX); /* diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index 9d40f3ffd8d2..f4bc6c5bac06 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -135,14 +135,6 @@ SYM_FUNC_START(cpu_do_resume) msr tcr_el1, x8 msr vbar_el1, x9 - - /* - * __cpu_setup() cleared MDSCR_EL1.MDE and friends, before unmasking - * debug exceptions. By restoring MDSCR_EL1 here, we may take a debug - * exception. Mask them until local_daif_restore() in cpu_suspend() - * resets them. - */ - disable_daif msr mdscr_el1, x10 msr sctlr_el1, x12 @@ -466,8 +458,6 @@ SYM_FUNC_START(__cpu_setup) msr cpacr_el1, xzr // Reset cpacr_el1 mov x1, #1 << 12 // Reset mdscr_el1 and disable msr mdscr_el1, x1 // access to the DCC from EL0 - isb // Unmask debug exceptions now, - enable_dbg // since this is per-cpu reset_pmuserenr_el0 x1 // Disable PMU access from EL0 reset_amuserenr_el0 x1 // Disable AMU access from EL0 diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index 44267a92bce5..3c126c6d306b 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c @@ -315,23 +315,19 @@ void acpi_tb_parse_fadt(void) ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, NULL, FALSE, TRUE, &acpi_gbl_dsdt_index); - /* If Hardware Reduced flag is set, there is no FACS */ - - if (!acpi_gbl_reduced_hardware) { - if (acpi_gbl_FADT.facs) { - acpi_tb_install_standard_table((acpi_physical_address) - acpi_gbl_FADT.facs, - ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, - NULL, FALSE, TRUE, - &acpi_gbl_facs_index); - } - if (acpi_gbl_FADT.Xfacs) { - acpi_tb_install_standard_table((acpi_physical_address) - acpi_gbl_FADT.Xfacs, - ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, - NULL, FALSE, TRUE, - &acpi_gbl_xfacs_index); - } + if (acpi_gbl_FADT.facs) { + acpi_tb_install_standard_table((acpi_physical_address) + acpi_gbl_FADT.facs, + ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, + NULL, FALSE, TRUE, + &acpi_gbl_facs_index); + } + if (acpi_gbl_FADT.Xfacs) { + acpi_tb_install_standard_table((acpi_physical_address) + acpi_gbl_FADT.Xfacs, + ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, + NULL, FALSE, TRUE, + &acpi_gbl_xfacs_index); } } diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index bb4a56e5673a..15fa68a5ea6e 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c @@ -36,12 +36,7 @@ acpi_status acpi_tb_initialize_facs(void) { struct acpi_table_facs *facs; - /* If Hardware Reduced flag is set, there is no FACS */ - - if (acpi_gbl_reduced_hardware) { - acpi_gbl_FACS = NULL; - return (AE_OK); - } else if (acpi_gbl_FADT.Xfacs && + if (acpi_gbl_FADT.Xfacs && (!acpi_gbl_FADT.facs || !acpi_gbl_use32_bit_facs_addresses)) { (void)acpi_get_table_by_index(acpi_gbl_xfacs_index, diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 3179747cbd2c..afa1099b6b8e 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -504,6 +504,22 @@ quiet_cmd_uimage = UIMAGE $@ -a $(UIMAGE_LOADADDR) -e $(UIMAGE_ENTRYADDR) \ -n '$(UIMAGE_NAME)' -d $< $@ +# Flat Image Tree (FIT) +# This allows for packaging of a kernel and all devicetrees files, using +# compression. +# --------------------------------------------------------------------------- + +MAKE_FIT := $(srctree)/scripts/make_fit.py + +# Use this to override the compression algorithm +FIT_COMPRESSION ?= gzip + +quiet_cmd_fit = FIT $@ + cmd_fit = $(MAKE_FIT) -o $@ --arch $(UIMAGE_ARCH) --os linux \ + --name '$(UIMAGE_NAME)' \ + $(if $(findstring 1,$(KBUILD_VERBOSE)),-v) \ + --compress $(FIT_COMPRESSION) -k $< @$(word 2,$^) + # XZ # --------------------------------------------------------------------------- # Use xzkern to compress the kernel image and xzmisc to compress other things. diff --git a/scripts/make_fit.py b/scripts/make_fit.py new file mode 100755 index 000000000000..3de90c5a094b --- /dev/null +++ b/scripts/make_fit.py @@ -0,0 +1,290 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright 2024 Google LLC +# Written by Simon Glass <sjg@chromium.org> +# + +"""Build a FIT containing a lot of devicetree files + +Usage: + make_fit.py -A arm64 -n 'Linux-6.6' -O linux + -o arch/arm64/boot/image.fit -k /tmp/kern/arch/arm64/boot/image.itk + @arch/arm64/boot/dts/dtbs-list -E -c gzip + +Creates a FIT containing the supplied kernel and a set of devicetree files, +either specified individually or listed in a file (with an '@' prefix). + +Use -E to generate an external FIT (where the data is placed after the +FIT data structure). This allows parsing of the data without loading +the entire FIT. + +Use -c to compress the data, using bzip2, gzip, lz4, lzma, lzo and +zstd algorithms. + +The resulting FIT can be booted by bootloaders which support FIT, such +as U-Boot, Linuxboot, Tianocore, etc. + +Note that this tool does not yet support adding a ramdisk / initrd. +""" + +import argparse +import collections +import os +import subprocess +import sys +import tempfile +import time + +import libfdt + + +# Tool extension and the name of the command-line tools +CompTool = collections.namedtuple('CompTool', 'ext,tools') + +COMP_TOOLS = { + 'bzip2': CompTool('.bz2', 'bzip2'), + 'gzip': CompTool('.gz', 'pigz,gzip'), + 'lz4': CompTool('.lz4', 'lz4'), + 'lzma': CompTool('.lzma', 'lzma'), + 'lzo': CompTool('.lzo', 'lzop'), + 'zstd': CompTool('.zstd', 'zstd'), +} + + +def parse_args(): + """Parse the program ArgumentParser + + Returns: + Namespace object containing the arguments + """ + epilog = 'Build a FIT from a directory tree containing .dtb files' + parser = argparse.ArgumentParser(epilog=epilog, fromfile_prefix_chars='@') + parser.add_argument('-A', '--arch', type=str, required=True, + help='Specifies the architecture') + parser.add_argument('-c', '--compress', type=str, default='none', + help='Specifies the compression') + parser.add_argument('-E', '--external', action='store_true', + help='Convert the FIT to use external data') + parser.add_argument('-n', '--name', type=str, required=True, + help='Specifies the name') + parser.add_argument('-o', '--output', type=str, required=True, + help='Specifies the output file (.fit)') + parser.add_argument('-O', '--os', type=str, required=True, + help='Specifies the operating system') + parser.add_argument('-k', '--kernel', type=str, required=True, + help='Specifies the (uncompressed) kernel input file (.itk)') + parser.add_argument('-v', '--verbose', action='store_true', + help='Enable verbose output') + parser.add_argument('dtbs', type=str, nargs='*', + help='Specifies the devicetree files to process') + + return parser.parse_args() + + +def setup_fit(fsw, name): + """Make a start on writing the FIT + + Outputs the root properties and the 'images' node + + Args: + fsw (libfdt.FdtSw): Object to use for writing + name (str): Name of kernel image + """ + fsw.INC_SIZE = 65536 + fsw.finish_reservemap() + fsw.begin_node('') + fsw.property_string('description', f'{name} with devicetree set') + fsw.property_u32('#address-cells', 1) + + fsw.property_u32('timestamp', int(time.time())) + fsw.begin_node('images') + + +def write_kernel(fsw, data, args): + """Write out the kernel image + + Writes a kernel node along with the required properties + + Args: + fsw (libfdt.FdtSw): Object to use for writing + data (bytes): Data to write (possibly compressed) + args (Namespace): Contains necessary strings: + arch: FIT architecture, e.g. 'arm64' + fit_os: Operating Systems, e.g. 'linux' + name: Name of OS, e.g. 'Linux-6.6.0-rc7' + compress: Compression algorithm to use, e.g. 'gzip' + """ + with fsw.add_node('kernel'): + fsw.property_string('description', args.name) + fsw.property_string('type', 'kernel_noload') + fsw.property_string('arch', args.arch) + fsw.property_string('os', args.os) + fsw.property_string('compression', args.compress) + fsw.property('data', data) + fsw.property_u32('load', 0) + fsw.property_u32('entry', 0) + + +def finish_fit(fsw, entries): + """Finish the FIT ready for use + + Writes the /configurations node and subnodes + + Args: + fsw (libfdt.FdtSw): Object to use for writing + entries (list of tuple): List of configurations: + str: Description of model + str: Compatible stringlist + """ + fsw.end_node() + seq = 0 + with fsw.add_node('configurations'): + for model, compat in entries: + seq += 1 + with fsw.add_node(f'conf-{seq}'): + fsw.property('compatible', bytes(compat)) + fsw.property_string('description', model) + fsw.property_string('fdt', f'fdt-{seq}') + fsw.property_string('kernel', 'kernel') + fsw.end_node() + + +def compress_data(inf, compress): + """Compress data using a selected algorithm + + Args: + inf (IOBase): Filename containing the data to compress + compress (str): Compression algorithm, e.g. 'gzip' + + Return: + bytes: Compressed data + """ + if compress == 'none': + return inf.read() + + comp = COMP_TOOLS.get(compress) + if not comp: + raise ValueError(f"Unknown compression algorithm '{compress}'") + + with tempfile.NamedTemporaryFile() as comp_fname: + with open(comp_fname.name, 'wb') as outf: + done = False + for tool in comp.tools.split(','): + try: + subprocess.call([tool, '-c'], stdin=inf, stdout=outf) + done = True + break + except FileNotFoundError: + pass + if not done: + raise ValueError(f'Missing tool(s): {comp.tools}\n') + with open(comp_fname.name, 'rb') as compf: + comp_data = compf.read() + return comp_data + + +def output_dtb(fsw, seq, fname, arch, compress): + """Write out a single devicetree to the FIT + + Args: + fsw (libfdt.FdtSw): Object to use for writing + seq (int): Sequence number (1 for first) + fmame (str): Filename containing the DTB + arch: FIT architecture, e.g. 'arm64' + compress (str): Compressed algorithm, e.g. 'gzip' + + Returns: + tuple: + str: Model name + bytes: Compatible stringlist + """ + with fsw.add_node(f'fdt-{seq}'): + # Get the compatible / model information + with open(fname, 'rb') as inf: + data = inf.read() + fdt = libfdt.FdtRo(data) + model = fdt.getprop(0, 'model').as_str() + compat = fdt.getprop(0, 'compatible') + + fsw.property_string('description', model) + fsw.property_string('type', 'flat_dt') + fsw.property_string('arch', arch) + fsw.property_string('compression', compress) + fsw.property('compatible', bytes(compat)) + + with open(fname, 'rb') as inf: + compressed = compress_data(inf, compress) + fsw.property('data', compressed) + return model, compat + + +def build_fit(args): + """Build the FIT from the provided files and arguments + + Args: + args (Namespace): Program arguments + + Returns: + tuple: + bytes: FIT data + int: Number of configurations generated + size: Total uncompressed size of data + """ + seq = 0 + size = 0 + fsw = libfdt.FdtSw() + setup_fit(fsw, args.name) + entries = [] + + # Handle the kernel + with open(args.kernel, 'rb') as inf: + comp_data = compress_data(inf, args.compress) + size += os.path.getsize(args.kernel) + write_kernel(fsw, comp_data, args) + + for fname in args.dtbs: + # Ignore overlay (.dtbo) files + if os.path.splitext(fname)[1] == '.dtb': + seq += 1 + size += os.path.getsize(fname) + model, compat = output_dtb(fsw, seq, fname, args.arch, args.compress) + entries.append([model, compat]) + + finish_fit(fsw, entries) + + # Include the kernel itself in the returned file count + return fsw.as_fdt().as_bytearray(), seq + 1, size + + +def run_make_fit(): + """Run the tool's main logic""" + args = parse_args() + + out_data, count, size = build_fit(args) + with open(args.output, 'wb') as outf: + outf.write(out_data) + + ext_fit_size = None + if args.external: + mkimage = os.environ.get('MKIMAGE', 'mkimage') + subprocess.check_call([mkimage, '-E', '-F', args.output], + stdout=subprocess.DEVNULL) + + with open(args.output, 'rb') as inf: + data = inf.read() + ext_fit = libfdt.FdtRo(data) + ext_fit_size = ext_fit.totalsize() + + if args.verbose: + comp_size = len(out_data) + print(f'FIT size {comp_size:#x}/{comp_size / 1024 / 1024:.1f} MB', + end='') + if ext_fit_size: + print(f', header {ext_fit_size:#x}/{ext_fit_size / 1024:.1f} KB', + end='') + print(f', {count} files, uncompressed {size / 1024 / 1024:.1f} MB') + + +if __name__ == "__main__": + sys.exit(run_make_fit()) diff --git a/tools/arch/arm64/include/asm/sysreg.h b/tools/arch/arm64/include/asm/sysreg.h index ccc13e991376..cd8420e8c3ad 100644 --- a/tools/arch/arm64/include/asm/sysreg.h +++ b/tools/arch/arm64/include/asm/sysreg.h @@ -701,18 +701,18 @@ * Permission Indirection Extension (PIE) permission encodings. * Encodings with the _O suffix, have overlays applied (Permission Overlay Extension). */ -#define PIE_NONE_O 0x0 -#define PIE_R_O 0x1 -#define PIE_X_O 0x2 -#define PIE_RX_O 0x3 -#define PIE_RW_O 0x5 -#define PIE_RWnX_O 0x6 -#define PIE_RWX_O 0x7 -#define PIE_R 0x8 -#define PIE_GCS 0x9 -#define PIE_RX 0xa -#define PIE_RW 0xc -#define PIE_RWX 0xe +#define PIE_NONE_O UL(0x0) +#define PIE_R_O UL(0x1) +#define PIE_X_O UL(0x2) +#define PIE_RX_O UL(0x3) +#define PIE_RW_O UL(0x5) +#define PIE_RWnX_O UL(0x6) +#define PIE_RWX_O UL(0x7) +#define PIE_R UL(0x8) +#define PIE_GCS UL(0x9) +#define PIE_RX UL(0xa) +#define PIE_RW UL(0xc) +#define PIE_RWX UL(0xe) #define PIRx_ELx_PERM(idx, perm) ((perm) << ((idx) * 4)) |