--- /dev/null
+ .section ".text.head", "ax", %progbits
+ .code 32
+
+#define ZIMAGE32_MAGIC 0x016f2818
+#define ZIMAGE32_LE 0x04030201
+
+ /*
+ * The Linux zImage32 header has no offical documentation.
+ *
+ * It is formed as:
+ *
+ * u32 nops[8]; // Old a.out header
+ * u32 code0; // Branch to start logic
+ * u32 zimage32_magic; // 0x016f2818
+ * u32 start; // Start in RAM, or 0 for relocatable
+ * u32 end; // End in RAM, or size for relocatable
+ * u32 endian_magic; // 0x04030201 for LE, 0x01020304 for BE
+ * u32 kexec_magic; // 0x45454545 (if kexec_addr present)
+ * u32 kexec_addr;
+ * ... // Future extentions
+ */
+.globl _start
+_start:
+
+ .rept 8
+ nop
+ .endr
+
+ b startup /* code0 */
+ .word ZIMAGE32_MAGIC /* zimage32_magic */
+ .word 0 /* start: 0 -> relocatable */
+ .word _end - _start /* end: (size) */
+ .word ZIMAGE32_LE /* endian_magic */
+
+startup:
+ /* Calculate r9 = phys-offset */
+ ldr r0, =_start
+ adr r8, _start
+ sub r9, r8, r0
+
+ /* sp = &stack[4096] + phys-offset */
+ ldr sp, =stack + 4096
+ add sp, sp, r9
+
+ bl test_main
+
+1: b 1b
+
+ .type startup, %function
+ .size startup, . - startup
+
+/*
+ * Local variables:
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
--- /dev/null
+ .section ".text.head", "ax", %progbits
+
+#define ZIMAGE64_MAGIC 0x644d5241
+
+#define ZIMAGE64_FLAGS_LE (0 << 0)
+#define ZIMAGE64_FLAGS_PG_UNK (0 << 1)
+#define ZIMAGE64_FLAGS_PHYS_ANY (1 << 3)
+
+#define ZIMAGE64_FLAGS \
+ (ZIMAGE64_FLAGS_LE | ZIMAGE64_FLAGS_PG_UNK | ZIMAGE64_FLAGS_PHYS_ANY)
+
+ /*
+ * zImage64 header:
+ * See https://www.kernel.org/doc/html/latest/arm64/booting.html
+ */
+.globl _start
+_start:
+ b startup /* code0 */
+ nop /* code1 */
+ .quad 0 /* text_offset: 0 -> relocatable */
+ .quad _end - _start /* size */
+ .quad ZIMAGE64_FLAGS /* flags */
+ .quad 0 /* reserved */
+ .quad 0 /* reserved */
+ .quad 0 /* reserved */
+ .long ZIMAGE64_MAGIC /* magic */
+ .long 0 /* reserved */
+
+startup:
+ /* Calculate x21 = phys-offset */
+ ldr x22, =_start
+ adr x21, _start
+ sub x21, x21, x22
+
+ /* sp = &stack[4096] + phys-offset */
+ ldr x0, =stack + 4096
+ add sp, x0, x21
+
+ bl test_main
+
+1: b 1b
+
+ .type startup, %function
+ .size startup, . - startup
+
+/*
+ * Local variables:
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
--- /dev/null
+/**
+ * @file arch/arm/include/arch/config.h
+ *
+ * A Linux-style configuration list.
+ */
+#ifndef XTF_ARM_CONFIG_H
+#define XTF_ARM_CONFIG_H
+
+#define XTF_VIRT_START 0x40000000
+
+#if defined(CONFIG_ENV_arm64)
+
+#define CONFIG_ARM 1
+#define CONFIG_ARM_64 1
+#define CONFIG_64BIT 1
+#define ENVIRONMENT_DESCRIPTION "ARM64"
+
+#undef CONFIG_ENV_arm64
+
+#elif defined(CONFIG_ENV_arm32)
+
+#define CONFIG_ARM 1
+#define CONFIG_ARM_32 1
+#define CONFIG_32BIT 1
+#define ENVIRONMENT_DESCRIPTION "ARM32"
+
+#undef CONFIG_ENV_arm32
+
+#else
+# error "Bad environment"
+#endif
+
+#endif /* XTF_ARM_CONFIG_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- /dev/null
+#ifdef LINKER_HEADER
+
+#if defined(__arm__)
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+
+#elif defined(__aarch64__)
+
+OUTPUT_FORMAT("elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+
+#else
+# error Bad architecture to link with
+#endif
+
+ENTRY(_start)
+
+#endif /* LINKER_HEADER */
--- /dev/null
+/**
+ * @file arch/arm/include/arch/page.h
+ */
+#ifndef XTF_ARM_PAGE_H
+#define XTF_ARM_PAGE_H
+
+#include <xtf/numbers.h>
+
+#define PAGE_SHIFT 12
+#define PAGE_SIZE (_AC(1, L) << PAGE_SHIFT)
+#define PAGE_MASK (~(PAGE_SIZE - 1))
+
+#endif /* XTF_ARM_PAGE_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
{
. = XTF_VIRT_START;
- _start = .;
+ PROVIDE(_start = .); /* arch may provide it's own _start symbol */
.text : {
*(.text.head)
--- /dev/null
+include $(ROOT)/build/common.mk
+
+NAME := stubarm
+CATEGORY := special
+TEST-ENVS := $(ALL_ENVIRONMENTS)
+
+obj-perenv += main.o
+
+include $(ROOT)/build/gen.mk
--- /dev/null
+/**
+ * Minimal C logic
+ */
+
+#ifdef __aarch64__
+# define COND(_32, _64) _64
+#else
+# define COND(_32, _64) _32
+#endif
+
+const char test_title[] = "Hello from ARM" COND("32", "64") "\n";
+
+char __attribute__((section(".bss.page_aligned"))) stack[4096];
+
+void test_main(void)
+{
+#if defined(__arm__) || defined(__aarch64__)
+ register unsigned long nr asm (COND("r12", "x16"));
+ register unsigned long a0 asm (COND("r0", "x0"));
+ register unsigned long a1 asm (COND("r1", "x1"));
+ register unsigned long a2 asm (COND("r2", "x2"));
+
+ nr = 18; /* __HYPERVISOR_console_io */
+ a0 = 0; /* CONSOLEIO_write */
+ a1 = sizeof(test_title); /* len */
+ a2 = (unsigned long)test_title; /* ptr */
+ asm volatile ("hvc #0xea1"
+ : [nr] "+r" (nr), [a0] "+r" (a0),
+ [a1] "+r" (a1), [a2] "+r" (a2)
+ :
+ : "memory");
+
+ unsigned int reason = 0; /* SHUTDOWN_poweroff */
+
+ nr = 29; /* __HYPERVISOR_sched_op */
+ a0 = 2; /* SCHEDOP_shutdown */
+ a1 = (unsigned long)&reason; /* ptr */
+ asm volatile ("hvc #0xea1"
+ : [nr] "+r" (nr), [a0] "+r" (a0), [a1] "+r" (a1)
+ :
+ : "memory");
+#endif
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */