summaryrefslogtreecommitdiffstats
path: root/src/arch/arm64
Commit message (Collapse)AuthorAgeFilesLines
* [arm] Avoid unaligned accesses for memcpy() and memset()Michael Brown2025-11-191-74/+100
| | | | | | | | | | | | | iPXE runs only in environments that support unaligned accesses to RAM. However, memcpy() and memset() are also used to write to graphical framebuffer memory, which may support only aligned accesses on some CPU architectures such as ARM. Restructure the 64-bit ARM memcpy() and memset() routines along the lines of the RISC-V implementations, which split the region into pre-aligned, aligned, and post-aligned sections. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [lkrn] Add basic support for the RISC-V Linux kernel image formatMichael Brown2025-05-201-0/+30
| | | | | | | | | | | | | | | | | | | | | | The RISC-V and AArch64 bare-metal kernel images share a common header format, and require essentially the same execution environment: loaded close to the start of RAM, entered with paging disabled, and passed a pointer to a flattened device tree that describes the hardware and any boot arguments. Implement basic support for executing bare-metal RISC-V and AArch64 kernel images. The (trivial) AArch64-specific code path is untested since we do not yet have the ability to build for any bare-metal AArch64 platforms. Constructing and passing an initramfs image is not yet supported. Rename the IMAGE_BZIMAGE build configuration option to IMAGE_LKRN, since "bzImage" is specific to x86. To retain backwards compatibility with existing local build configurations, we leave IMAGE_BZIMAGE as the enabled option in config/default/pcbios.h and treat IMAGE_LKRN as a synonym for IMAGE_BZIMAGE when building for x86 BIOS. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [build] Allow for 32-bit and 64-bit versions of util/zbinMichael Brown2025-05-061-0/+4
| | | | | | | | | | Parsing ELF data is simpler if we don't have to build a single binary to handle both 32-bit and 64-bit ELF formats. Allow for separate 32-bit and 64-bit binaries built from util/zbin.c (as is already done for util/elf2efi.c). Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [crypto] Expose shifted out bit from big integer shiftsMichael Brown2025-02-131-13/+18
| | | | | | | Expose the bit shifted out as a result of shifting a big integer left or right. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [crypto] Expose carry flag from big integer addition and subtractionMichael Brown2024-11-261-6/+13
| | | | | | | | Expose the effective carry (or borrow) out flag from big integer addition and subtraction, and use this to elide an explicit bit test when performing x25519 reduction. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [crypto] Use architecture-independent bigint_is_set()Michael Brown2024-10-101-19/+0Star
| | | | | | | | | | | Every architecture uses the same implementation for bigint_is_set(), and there is no reason to suspect that a future CPU architecture will provide a more efficient way to implement this operation. Simplify the code by providing a single architecture-independent implementation of bigint_is_set(). Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [crypto] Rename bigint_rol()/bigint_ror() to bigint_shl()/bigint_shr()Michael Brown2024-10-071-4/+4
| | | | | | | | | | | The big integer shift operations are misleadingly described as rotations since the original x86 implementations are essentially trivial loops around the relevant rotate-through-carry instruction. The overall operation performed is a shift rather than a rotation. Update the function names and descriptions to reflect this. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [crypto] Eliminate temporary carry space for big integer multiplicationMichael Brown2024-09-271-8/+9
| | | | | | | | | | | | An n-bit multiplication product may be added to up to two n-bit integers without exceeding the range of a (2n)-bit integer: (2^n - 1)*(2^n - 1) + (2^n - 1) + (2^n - 1) = 2^(2n) - 1 Exploit this to perform big integer multiplication in constant time without requiring the caller to provide temporary carry space. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [profile] Standardise return type of profile_timestamp()Michael Brown2024-09-241-1/+1
| | | | | | | | | | | | | | | | All consumers of profile_timestamp() currently treat the value as an unsigned long. Only the elapsed number of ticks is ever relevant: the absolute value of the timestamp is not used. Profiling is used to measure short durations that are generally fewer than a million CPU cycles, for which an unsigned long is easily large enough. Standardise the return type of profile_timestamp() as unsigned long across all CPU architectures. This allows 32-bit architectures such as i386 and riscv32 to omit all logic associated with retrieving the upper 32 bits of the 64-bit hardware counter, which simplifies the code and allows riscv32 and riscv64 to share the same implementation. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [crypto] Use constant-time big integer multiplicationMichael Brown2024-09-232-112/+30Star
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Big integer multiplication currently performs immediate carry propagation from each step of the long multiplication, relying on the fact that the overall result has a known maximum value to minimise the number of carries performed without ever needing to explicitly check against the result buffer size. This is not a constant-time algorithm, since the number of carries performed will be a function of the input values. We could make it constant-time by always continuing to propagate the carry until reaching the end of the result buffer, but this would introduce a large number of redundant zero carries. Require callers of bigint_multiply() to provide a temporary carry storage buffer, of the same size as the result buffer. This allows the carry-out from the accumulation of each double-element product to be accumulated in the temporary carry space, and then added in via a single call to bigint_add() after the multiplication is complete. Since the structure of big integer multiplication is identical across all current CPU architectures, provide a single shared implementation of bigint_multiply(). The architecture-specific operation then becomes the multiplication of two big integer elements and the accumulation of the double-element product. Note that any intermediate carry arising from accumulating the lower half of the double-element product may be added to the upper half of the double-element product without risk of overflow, since the result of multiplying two n-bit integers can never have all n bits set in its upper half. This simplifies the carry calculations for architectures such as RISC-V and LoongArch64 that do not have a carry flag. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Remove redundant EFI_BOOT_FILE definitionsMichael Brown2024-09-161-4/+0Star
| | | | | | | | | | | | As of commit 79c0173 ("[build] Create util/genfsimg for building filesystem-based images"), the EFI boot file name for each CPU architecture is defined within the genfsimg script itself, rather than being passed in as a Makefile parameter. Remove the now-redundant Makefile definitions for EFI_BOOT_FILE. Reported-by: Christian I. Nilsson <nikize@gmail.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [libc] Centralise architecture-independent portions of setjmp.hMichael Brown2024-09-121-9/+3Star
| | | | | | | | | | | The definitions of the setjmp() and longjmp() functions are common to all architectures, with only the definition of the jump buffer structure being architecture-specific. Move the architecture-specific portions to bits/setjmp.h and provide a common setjmp.h for the function definitions. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [gdb] Allow CPU architectures to omit support for GDBMichael Brown2024-09-051-45/+0Star
| | | | | | | | Move the <gdbmach.h> file to <bits/gdbmach.h>, and provide a common dummy implementation for all architectures that have not yet implemented support for GDB. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [crypto] Allow multiplicand and multiplier to differ in sizeMichael Brown2024-01-162-12/+18
| | | | | | | | | | | Big integer multiplication is currently used only as part of modular exponentiation, where both multiplicand and multiplier will be the same size. Relax this requirement to allow for the use of big integer multiplication in other contexts. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [build] Inhibit linker warnings about an implied executable stackGeert Stappers2023-06-301-0/+1
| | | | | | Signed-off-by: Geert Stappers <stappers@stappers.it> Modified-by: Michael Brown <mcb30@ipxe.org> Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [build] Allow for per-architecture unprefixed constant operand modifierMichael Brown2023-02-061-0/+3
| | | | | | | | | | | | | | | | | | Over the years, the undocumented operand modifier used to produce the unprefixed constant values in __einfo_error() has varied from "%c0" to "%a0" in commit 1a77466 ("[build] Fix use of inline assembly on GCC 4.8 ARM64 builds") and back to "%c0" in commit 3fb3ffc ("[build] Fix use of inline assembly on GCC 8 ARM64 builds"), according to the evolving demands of the toolchain. LoongArch64 suffers from a similar issue: GCC 13 will allow either, but the currently released GCC 12 allows only the "%a0" form. Introduce a macro ASM_NO_PREFIX, defined in bits/compiler.h, to abstract away this difference and allow different architectures to use different operand modifiers. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [arm] Support building as a Linux userspace binary for AArch64Michael Brown2023-01-221-0/+10
| | | | | | | | | | | | | | | | | | | | Add support for building as a Linux userspace binary for AArch64. This allows the self-test suite to be more easily run for the 64-bit ARM code. For example: # On a native AArch64 system: # make bin-arm64-efi/tests.linux && ./bin-arm64-efi/tests.linux # On a non-AArch64 system (e.g. x86_64) via cross-compilation, # assuming that kernel and glibc headers are present within # /usr/aarch64-linux-gnu/sys-root/: # make bin-arm64-linux/tests.linux CROSS=aarch64-linux-gnu- && \ qemu-aarch64 -L /usr/aarch64-linux-gnu/sys-root/ \ ./bin-arm64-linux/tests.linux Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [dhcp] Simplify platform-specific client architecture definitionsMichael Brown2023-01-222-40/+20Star
| | | | | | | | | | | | | | | | Move the platform-specific DHCP client architecture definitions to header files of the form <ipxe/$(PLATFORM)/dhcparch.h>. This simplifies the directory structure and allows the otherwise unused arch/$(ARCH)/include/$(PLATFORM) to be removed from the include directory search path, which avoids the confusing situation in which a header file may potentially be accessed through more than one path. For Linux userspace binaries on any architecture, use the EFI values for that architecture by delegating to the EFI header file. This avoids the need to explicitly select values for Linux userspace binaries for each architecture. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [build] Work around -fPIE patched versions of gcc on all architecturesMichael Brown2021-02-041-4/+0Star
| | | | | | | | | | | | | | | | | | | | | | | Several distributions include versions of gcc that are patched to create position-independent executables by default. These have caused multiple problems over the years: see e.g. commits fe61f6d ("[build] Fix compilation when gcc is patched to default to -fPIE -Wl,-pie"), 5de1346 ("[build] Apply the "-fno-PIE -nopie" workaround only to i386 builds"), 7c395b0 ("[build] Use -no-pie on newer versions of gcc"), and decee20 ("[build] Disable position-independent code for ARM64 EFI builds"). The build system currently attempts to work around these mildly broken patched versions of gcc for the i386 and arm64 architectures. This misses the relatively obscure bin-x86_64-pcbios build platform, which turns out to also require the same workaround. Attempt to preempt the next such required workaround by moving the existing i386 version to apply to all platforms and all architectures, unless -fpie has been requested explicitly by another Makefile (as is done by arch/x86_64/Makefile.efi). Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [build] Disable position-independent code for ARM64 EFI buildsMichael Brown2020-06-271-0/+4
| | | | | | | | | | | | | | Some versions of gcc (observed with the cross-compiling gcc 9.3.0 in Ubuntu 20.04) default to enabling -fPIE. Experimentation shows that this results in the emission of R_AARCH64_ADR_GOT_PAGE relocation records for __stack_chk_guard. These relocation types are not supported by elf2efi.c. Fix by explicitly disabling position-independent code for ARM64 EFI builds. Debugged-by: Antony Messerli <antony@mes.ser.li> Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [build] Conditionalise use of -mabi=lp64 for ARM64 buildsMichael Brown2017-07-281-1/+12
| | | | | | | | The -mabi option was added in GCC 4.9. Test for the existence of this option to allow for building with earlier versions of GCC. Reported-by: Benjamin S. Allen <bsallen@alcf.anl.gov> Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [dhcp] Automatically generate vendor class identifier stringMichael Brown2016-07-041-5/+0Star
| | | | | | | | | | | | The vendor class identifier strings in DHCP_ARCH_VENDOR_CLASS_ID are out of sync with the (correct) client architecture values in DHCP_ARCH_CLIENT_ARCHITECTURE. Fix by removing all definitions of DHCP_ARCH_VENDOR_CLASS_ID, and instead generating the vendor class identifier string automatically based on DHCP_ARCH_CLIENT_ARCHITECTURE and DHCP_ARCH_CLIENT_NDI. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [dhcp] Allow for variable encapsulation of architecture-specific optionsMichael Brown2016-07-041-7/+6Star
| | | | | | | | | | | | | DHCPv4 and DHCPv6 share some values in common for the architecture- specific options (such as the client system architecture type), but use different encapsulations: DHCPv4 has a single byte for the option length while DHCPv6 has a 16-bit field for the option length. Move the containing DHCP_OPTION() and related wrappers from the individual dhcp_arch.h files to dhcp.c, thus allowing for the architecture-specific values to be reused in dhcpv6.c. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [arm] Use correct DHCP client architecture valuesMichael Brown2016-05-261-1/+1
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [arm] Use CNTVCT_EL0 as profiling timestampMichael Brown2016-05-121-3/+1Star
| | | | | | | | | | | | The raw cycle counter at PMCCNTR_EL0 works in qemu but seems to always read as zero on physical hardware (tested on Juno r1 and Cavium ThunderX), even after ensuring that PMCR_EL0.E and PMCNTENSET_EL0.C are both enabled. Use CNTVCT_EL0 instead; this seems to count at a lower resolution (tens of CPU cycles), but is usable for profiling. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [arm] Add optimised TCP/IP checksumming for 64-bit ARMMichael Brown2016-05-112-0/+190
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [arm] Add optimised string functions for 64-bit ARMMichael Brown2016-05-112-0/+355
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [arm] Add support for 64-bit ARM (Aarch64)Michael Brown2016-05-0815-0/+989
Signed-off-by: Michael Brown <mcb30@ipxe.org>