summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta/recipes-kernel/kexec/kexec-tools/kexec-aarch64.patch801
1 files changed, 0 insertions, 801 deletions
diff --git a/meta/recipes-kernel/kexec/kexec-tools/kexec-aarch64.patch b/meta/recipes-kernel/kexec/kexec-tools/kexec-aarch64.patch
deleted file mode 100644
index b03f582576..0000000000
--- a/meta/recipes-kernel/kexec/kexec-tools/kexec-aarch64.patch
+++ /dev/null
@@ -1,801 +0,0 @@
1From: Geoff Levand <geoff@infradead.org>
2Date: Mon, 15 Jul 2013 23:32:36 +0000 (-0700)
3Subject: Add arm64 support
4X-Git-Url: https://git.linaro.org/gitweb?p=people%2Fgeoff%2Fkexec-tools.git;a=commitdiff_plain;h=fbf5ac6c2c70ec0f6da2b9ff563e573999752c01
5
6Add arm64 support
7
8Signed-off-by: Geoff Levand <geoff@infradead.org>
9
10Get patch from:
11https://fedorapeople.org/~hrw/aarch64/for-fedora/kexec-aarch64.patch
12
13Upstream-Status: Pending
14
15Signed-off-by: Kai Kang <kai.kang@windriver.com>
16---
17
18---
19 configure.ac | 3
20 kexec/Makefile | 1
21 kexec/arch/arm64/Makefile | 13 +
22 kexec/arch/arm64/crashdump-arm64.c | 305 ++++++++++++++++++++++++++++++++
23 kexec/arch/arm64/include/arch/options.h | 26 ++
24 kexec/arch/arm64/kexec-arm64.c | 177 ++++++++++++++++++
25 kexec/arch/arm64/kexec-arm64.h | 20 ++
26 kexec/arch/arm64/kexec-elf-arm64.c | 114 +++++++++++
27 kexec/kexec-syscall.h | 9
28 kexec/kexec.c | 2
29 purgatory/arch/arm64/Makefile | 7
30 11 files changed, 675 insertions(+), 2 deletions(-)
31
32Index: kexec-tools-2.0.10/configure.ac
33===================================================================
34--- kexec-tools-2.0.10.orig/configure.ac
35+++ kexec-tools-2.0.10/configure.ac
36@@ -36,6 +36,9 @@ case $target_cpu in
37 ARCH="ppc64"
38 SUBARCH="LE"
39 ;;
40+ aarch64* )
41+ ARCH="arm64"
42+ ;;
43 arm* )
44 ARCH="arm"
45 ;;
46Index: kexec-tools-2.0.10/kexec/Makefile
47===================================================================
48--- kexec-tools-2.0.10.orig/kexec/Makefile
49+++ kexec-tools-2.0.10/kexec/Makefile
50@@ -71,6 +71,7 @@ KEXEC_SRCS += $($(ARCH)_FS2DT)
51
52 include $(srcdir)/kexec/arch/alpha/Makefile
53 include $(srcdir)/kexec/arch/arm/Makefile
54+include $(srcdir)/kexec/arch/arm64/Makefile
55 include $(srcdir)/kexec/arch/i386/Makefile
56 include $(srcdir)/kexec/arch/ia64/Makefile
57 include $(srcdir)/kexec/arch/m68k/Makefile
58Index: kexec-tools-2.0.10/kexec/arch/arm64/Makefile
59===================================================================
60--- /dev/null
61+++ kexec-tools-2.0.10/kexec/arch/arm64/Makefile
62@@ -0,0 +1,13 @@
63+
64+arm64_KEXEC_SRCS += \
65+ kexec/arch/arm64/kexec-arm64.c \
66+ kexec/arch/arm64/kexec-elf-arm64.c \
67+ kexec/arch/arm64/crashdump-arm64.c
68+
69+arm64_ARCH_REUSE_INITRD =
70+arm64_ADD_SEGMENT =
71+arm64_VIRT_TO_PHYS =
72+
73+dist += $(arm64_KEXEC_SRCS) \
74+ kexec/arch/arm64/Makefile \
75+ kexec/arch/arm64/kexec-arm64.h
76Index: kexec-tools-2.0.10/kexec/arch/arm64/crashdump-arm64.c
77===================================================================
78--- /dev/null
79+++ kexec-tools-2.0.10/kexec/arch/arm64/crashdump-arm64.c
80@@ -0,0 +1,305 @@
81+/*
82+ * This program is free software; you can redistribute it and/or modify
83+ * it under the terms of the GNU General Public License as published by
84+ * the Free Software Foundation (version 2 of the License).
85+ */
86+
87+#include "../../kexec.h"
88+#include "../../kexec-elf.h"
89+#include "../../crashdump.h"
90+
91+int is_crashkernel_mem_reserved(void)
92+{
93+ return 0;
94+}
95+
96+#if 0
97+/*
98+ * Used to save various memory ranges/regions needed for the captured
99+ * kernel to boot. (lime memmap= option in other archs)
100+ */
101+static struct memory_range crash_memory_ranges[CRASH_MAX_MEMORY_RANGES];
102+struct memory_ranges usablemem_rgns = {
103+ .size = 0,
104+ .ranges = crash_memory_ranges,
105+};
106+
107+/* memory range reserved for crashkernel */
108+static struct memory_range crash_reserved_mem;
109+
110+static struct crash_elf_info elf_info = {
111+ .class = ELFCLASS32,
112+ .data = ELFDATA2LSB,
113+ .machine = EM_ARM,
114+ .page_offset = PAGE_OFFSET,
115+};
116+
117+unsigned long phys_offset;
118+
119+/**
120+ * crash_range_callback() - callback called for each iomem region
121+ * @data: not used
122+ * @nr: not used
123+ * @str: name of the memory region
124+ * @base: start address of the memory region
125+ * @length: size of the memory region
126+ *
127+ * This function is called once for each memory region found in /proc/iomem. It
128+ * locates system RAM and crashkernel reserved memory and places these to
129+ * variables: @crash_memory_ranges and @crash_reserved_mem. Number of memory
130+ * regions is placed in @crash_memory_nr_ranges.
131+ */
132+static int crash_range_callback(void *UNUSED(data), int UNUSED(nr),
133+ char *str, unsigned long base,
134+ unsigned long length)
135+{
136+ struct memory_range *range;
137+
138+ if (usablemem_rgns.size >= CRASH_MAX_MEMORY_RANGES)
139+ return 1;
140+
141+ range = usablemem_rgns.ranges + usablemem_rgns.size;
142+
143+ if (strncmp(str, "System RAM\n", 11) == 0) {
144+ range->start = base;
145+ range->end = base + length - 1;
146+ range->type = RANGE_RAM;
147+ usablemem_rgns.size++;
148+ } else if (strncmp(str, "Crash kernel\n", 13) == 0) {
149+ crash_reserved_mem.start = base;
150+ crash_reserved_mem.end = base + length - 1;
151+ crash_reserved_mem.type = RANGE_RAM;
152+ }
153+
154+ return 0;
155+}
156+
157+/**
158+ * crash_exclude_range() - excludes memory region reserved for crashkernel
159+ *
160+ * Function locates where crashkernel reserved memory is and removes that region
161+ * from the available memory regions.
162+ */
163+static void crash_exclude_range(void)
164+{
165+ const struct memory_range *range = &crash_reserved_mem;
166+ int i;
167+
168+ for (i = 0; i < usablemem_rgns.size; i++) {
169+ struct memory_range *r = usablemem_rgns.ranges + i;
170+
171+ /*
172+ * We assume that crash area is fully contained in
173+ * some larger memory area.
174+ */
175+ if (r->start <= range->start && r->end >= range->end) {
176+ struct memory_range *new;
177+ /*
178+ * Let's split this area into 2 smaller ones and
179+ * remove excluded range from between. First create
180+ * new entry for the remaining area.
181+ */
182+ new = usablemem_rgns.ranges + usablemem_rgns.size;
183+ new->start = range->end + 1;
184+ new->end = r->end;
185+ usablemem_rgns.size++;
186+ /*
187+ * Next update this area to end before excluded range.
188+ */
189+ r->end = range->start - 1;
190+ break;
191+ }
192+ }
193+}
194+
195+static int range_cmp(const void *a1, const void *a2)
196+{
197+ const struct memory_range *r1 = a1;
198+ const struct memory_range *r2 = a2;
199+
200+ if (r1->start > r2->start)
201+ return 1;
202+ if (r1->start < r2->start)
203+ return -1;
204+
205+ return 0;
206+}
207+
208+/**
209+ * crash_get_memory_ranges() - read system physical memory
210+ *
211+ * Function reads through system physical memory and stores found memory regions
212+ * in @crash_memory_ranges. Number of memory regions found is placed in
213+ * @crash_memory_nr_ranges. Regions are sorted in ascending order.
214+ *
215+ * Returns %0 in case of success and %-1 otherwise (errno is set).
216+ */
217+static int crash_get_memory_ranges(void)
218+{
219+ /*
220+ * First read all memory regions that can be considered as
221+ * system memory including the crash area.
222+ */
223+ kexec_iomem_for_each_line(NULL, crash_range_callback, NULL);
224+
225+ if (usablemem_rgns.size < 1) {
226+ errno = EINVAL;
227+ return -1;
228+ }
229+
230+ /*
231+ * Exclude memory reserved for crashkernel (this may result a split memory
232+ * region).
233+ */
234+ crash_exclude_range();
235+
236+ /*
237+ * Make sure that the memory regions are sorted.
238+ */
239+ qsort(usablemem_rgns.ranges, usablemem_rgns.size,
240+ sizeof(*usablemem_rgns.ranges), range_cmp);
241+
242+ return 0;
243+}
244+
245+/**
246+ * cmdline_add_elfcorehdr() - adds elfcorehdr= to @cmdline
247+ * @cmdline: buffer where parameter is placed
248+ * @elfcorehdr: physical address of elfcorehdr
249+ *
250+ * Function appends 'elfcorehdr=start' at the end of the command line given in
251+ * @cmdline. Note that @cmdline must be at least %COMMAND_LINE_SIZE bytes long
252+ * (inclunding %NUL).
253+ */
254+static void cmdline_add_elfcorehdr(char *cmdline, unsigned long elfcorehdr)
255+{
256+ char buf[COMMAND_LINE_SIZE];
257+ int buflen;
258+
259+ buflen = snprintf(buf, sizeof(buf), "%s elfcorehdr=%#lx",
260+ cmdline, elfcorehdr);
261+ if (buflen < 0)
262+ die("Failed to construct elfcorehdr= command line parameter\n");
263+ if (buflen >= sizeof(buf))
264+ die("Command line overflow\n");
265+
266+ (void) strncpy(cmdline, buf, COMMAND_LINE_SIZE);
267+ cmdline[COMMAND_LINE_SIZE - 1] = '\0';
268+}
269+
270+/**
271+ * cmdline_add_mem() - adds mem= parameter to kernel command line
272+ * @cmdline: buffer where parameter is placed
273+ * @size: size of the kernel reserved memory (in bytes)
274+ *
275+ * This function appends 'mem=size' at the end of the command line given in
276+ * @cmdline. Note that @cmdline must be at least %COMMAND_LINE_SIZE bytes long
277+ * (including %NUL).
278+ */
279+static void cmdline_add_mem(char *cmdline, unsigned long size)
280+{
281+ char buf[COMMAND_LINE_SIZE];
282+ int buflen;
283+
284+ buflen = snprintf(buf, sizeof(buf), "%s mem=%ldK", cmdline, size >> 10);
285+ if (buflen < 0)
286+ die("Failed to construct mem= command line parameter\n");
287+ if (buflen >= sizeof(buf))
288+ die("Command line overflow\n");
289+
290+ (void) strncpy(cmdline, buf, COMMAND_LINE_SIZE);
291+ cmdline[COMMAND_LINE_SIZE - 1] = '\0';
292+}
293+
294+static unsigned long long range_size(const struct memory_range *r)
295+{
296+ return r->end - r->start + 1;
297+}
298+
299+static void dump_memory_ranges(void)
300+{
301+ int i;
302+
303+ if (!kexec_debug)
304+ return;
305+
306+ dbgprintf("crashkernel: [%#llx - %#llx] (%ldM)\n",
307+ crash_reserved_mem.start, crash_reserved_mem.end,
308+ (unsigned long)range_size(&crash_reserved_mem) >> 20);
309+
310+ for (i = 0; i < usablemem_rgns.size; i++) {
311+ struct memory_range *r = usablemem_rgns.ranges + i;
312+ dbgprintf("memory range: [%#llx - %#llx] (%ldM)\n",
313+ r->start, r->end, (unsigned long)range_size(r) >> 20);
314+ }
315+}
316+
317+/**
318+ * load_crashdump_segments() - loads additional segments needed for kdump
319+ * @info: kexec info structure
320+ * @mod_cmdline: kernel command line
321+ *
322+ * This function loads additional segments which are needed for the dump capture
323+ * kernel. It also updates kernel command line passed in @mod_cmdline to have
324+ * right parameters for the dump capture kernel.
325+ *
326+ * Return %0 in case of success and %-1 in case of error.
327+ */
328+int load_crashdump_segments(struct kexec_info *info, char *mod_cmdline)
329+{
330+ unsigned long elfcorehdr;
331+ unsigned long bufsz;
332+ void *buf;
333+ int err;
334+
335+ /*
336+ * First fetch all the memory (RAM) ranges that we are going to pass to
337+ * the crashdump kernel during panic.
338+ */
339+ err = crash_get_memory_ranges();
340+ if (err)
341+ return err;
342+
343+ /*
344+ * Now that we have memory regions sorted, we can use first memory
345+ * region as PHYS_OFFSET.
346+ */
347+ phys_offset = usablemem_rgns.ranges->start;
348+ dbgprintf("phys_offset: %#lx\n", phys_offset);
349+
350+ err = crash_create_elf32_headers(info, &elf_info,
351+ usablemem_rgns.ranges,
352+ usablemem_rgns.size, &buf, &bufsz,
353+ ELF_CORE_HEADER_ALIGN);
354+ if (err)
355+ return err;
356+
357+ /*
358+ * We allocate ELF core header from the end of the memory area reserved
359+ * for the crashkernel. We align the header to SECTION_SIZE (which is
360+ * 1MB) so that available memory passed in kernel command line will be
361+ * aligned to 1MB. This is because kernel create_mapping() wants memory
362+ * regions to be aligned to SECTION_SIZE.
363+ */
364+ elfcorehdr = add_buffer_phys_virt(info, buf, bufsz, bufsz, 1 << 20,
365+ crash_reserved_mem.start,
366+ crash_reserved_mem.end, -1, 0);
367+
368+ dbgprintf("elfcorehdr: %#lx\n", elfcorehdr);
369+ cmdline_add_elfcorehdr(mod_cmdline, elfcorehdr);
370+
371+ /*
372+ * Add 'mem=size' parameter to dump capture kernel command line. This
373+ * prevents the dump capture kernel from using any other memory regions
374+ * which belong to the primary kernel.
375+ */
376+ cmdline_add_mem(mod_cmdline, elfcorehdr - crash_reserved_mem.start);
377+
378+ dump_memory_ranges();
379+ dbgprintf("kernel command line: \"%s\"\n", mod_cmdline);
380+
381+ return 0;
382+}
383+
384+#endif
385+
386Index: kexec-tools-2.0.10/kexec/arch/arm64/include/arch/options.h
387===================================================================
388--- /dev/null
389+++ kexec-tools-2.0.10/kexec/arch/arm64/include/arch/options.h
390@@ -0,0 +1,26 @@
391+#ifndef KEXEC_ARCH_ARM64_OPTIONS_H
392+#define KEXEC_ARCH_ARM64_OPTIONS_H
393+
394+//#define OPT_ARCH_MAX ((OPT_MAX)+0)
395+
396+#define OPT_APPEND ((OPT_MAX)+0)
397+#define OPT_RAMDISK ((OPT_MAX)+1)
398+#define OPT_DTB ((OPT_MAX)+2)
399+
400+#define OPT_ARCH_MAX ((OPT_MAX)+3)
401+
402+
403+#define KEXEC_ARCH_OPTIONS \
404+ KEXEC_OPTIONS \
405+ { "append", 1, NULL, OPT_APPEND }, \
406+ { "command-line", 1, NULL, OPT_APPEND }, \
407+ { "dtb", 1, NULL, OPT_DTB }, \
408+ { "initrd", 1, NULL, OPT_RAMDISK }, \
409+ { "ramdisk", 1, NULL, OPT_RAMDISK }, \
410+
411+#define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR /* Only accept long arch options. */
412+
413+#define KEXEC_ALL_OPTIONS KEXEC_ARCH_OPTIONS
414+#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR
415+
416+#endif /* KEXEC_ARCH_ARM64_OPTIONS_H */
417Index: kexec-tools-2.0.10/kexec/arch/arm64/kexec-arm64.c
418===================================================================
419--- /dev/null
420+++ kexec-tools-2.0.10/kexec/arch/arm64/kexec-arm64.c
421@@ -0,0 +1,177 @@
422+/*
423+ * ARM64 kexec support.
424+ */
425+
426+#define _GNU_SOURCE
427+
428+#include <errno.h>
429+#include <stddef.h>
430+
431+//#include <linux/kexec.h>
432+
433+#include "../../kexec.h"
434+#include "../../kexec-syscall.h"
435+#include "kexec-arm64.h"
436+
437+
438+void arch_usage(void)
439+{
440+ fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
441+
442+ printf(
443+" --append=STRING Set the kernel command line to STRING.\n"
444+" --command-line=STRING Set the kernel command line to STRING.\n"
445+" --dtb=FILE Use FILE as the device tree blob.\n"
446+" --initrd=FILE Use FILE as the kernel initial ramdisk.\n"
447+" --ramdisk=FILE Use FILE as the kernel initial ramdisk.\n");
448+
449+ fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
450+}
451+
452+int arch_process_options(int UNUSED(argc), char **UNUSED(argv))
453+{
454+ fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
455+ return 0;
456+}
457+
458+const struct arch_map_entry arches[] = {
459+ { "aarch64", KEXEC_ARCH_ARM64 },
460+ { NULL, 0 },
461+};
462+
463+void arch_update_purgatory(struct kexec_info *UNUSED(info))
464+{
465+ fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
466+}
467+
468+unsigned long virt_to_phys(unsigned long addr)
469+{
470+ fprintf(stderr, "%s:%d: %016lx -> %016lx\n", __func__, __LINE__, addr,
471+ addr + 0x080000000UL);
472+ return addr + 0x080000000UL;
473+}
474+
475+void add_segment(struct kexec_info *info, const void *buf, size_t bufsz,
476+ unsigned long base, size_t memsz)
477+{
478+ fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
479+ add_segment_phys_virt(info, buf, bufsz, base, memsz, 1);
480+ fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
481+}
482+
483+static int get_memory_ranges_1(struct memory_range **range, int *ranges,
484+ unsigned long kexec_flags)
485+{
486+ static struct memory_range memory_range[KEXEC_SEGMENT_MAX];
487+ const char *iomem;
488+ int range_count = 0;
489+ char line[MAX_LINE];
490+ FILE *fp;
491+
492+ iomem = proc_iomem();
493+ fp = fopen(iomem, "r");
494+
495+ if (!fp) {
496+ fprintf(stderr, "Cannot open %s: %s\n",
497+ iomem, strerror(errno));
498+ return -1;
499+ }
500+
501+ dbgprintf("memory ranges:\n");
502+
503+ while(fgets(line, sizeof(line), fp) != 0) {
504+ struct memory_range r;
505+ char *str;
506+ int consumed;
507+
508+ if (range_count >= KEXEC_SEGMENT_MAX)
509+ break;
510+
511+ if (sscanf(line, "%Lx-%Lx : %n", &r.start, &r.end, &consumed)
512+ != 2)
513+ continue;
514+
515+ str = line + consumed;
516+ r.end++;
517+
518+ if (memcmp(str, "System RAM\n", 11)) {
519+ dbgprintf(" Skip: %016Lx - %016Lx : %s", r.start, r.end,
520+ str);
521+ continue;
522+ }
523+
524+ r.type = RANGE_RAM;
525+ memory_range[range_count] = r;
526+ range_count++;
527+
528+ dbgprintf(" Add: %016Lx - %016Lx : %s", r.start, r.end, str);
529+ }
530+
531+ fclose(fp);
532+ *range = memory_range;
533+ *ranges = range_count;
534+
535+ return 0;
536+}
537+
538+static int get_memory_ranges_2(struct memory_range **range, int *ranges,
539+ unsigned long UNUSED(kexec_flags))
540+{
541+ static struct memory_range memory_range[2];
542+
543+ memory_range[0].start = 0x080000000;
544+ memory_range[0].end = 0x100000000;
545+ memory_range[0].type = RANGE_RAM;
546+
547+ memory_range[1].start = 0x900000000;
548+ memory_range[1].end = 0x880000000;
549+ memory_range[1].type = RANGE_RAM;
550+
551+ *range = memory_range;
552+ *ranges = sizeof(memory_range) / sizeof(memory_range[0]);
553+
554+ return 0;
555+}
556+
557+int get_memory_ranges(struct memory_range **range, int *ranges,
558+ unsigned long kexec_flags)
559+{
560+ /* FIXME: Should get this info from device tree. */
561+
562+ return get_memory_ranges_1(range, ranges, kexec_flags);
563+}
564+
565+struct file_type file_type[] = {
566+ { "elf-arm64", elf_arm64_probe, elf_arm64_load, elf_arm64_usage },
567+};
568+
569+int file_types = sizeof(file_type) / sizeof(file_type[0]);
570+
571+int arch_compat_trampoline(struct kexec_info *info)
572+{
573+ fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
574+ return 0;
575+}
576+
577+void arch_reuse_initrd(void)
578+{
579+}
580+
581+int machine_verify_elf_rel(struct mem_ehdr *ehdr)
582+{
583+ (void)ehdr;
584+
585+ fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
586+ return 0;
587+}
588+
589+void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type,
590+ void *location, unsigned long address, unsigned long value)
591+{
592+ (void)ehdr;
593+ (void)r_type;
594+ (void)location;
595+ (void)address;
596+ (void)value;
597+ fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
598+}
599Index: kexec-tools-2.0.10/kexec/arch/arm64/kexec-arm64.h
600===================================================================
601--- /dev/null
602+++ kexec-tools-2.0.10/kexec/arch/arm64/kexec-arm64.h
603@@ -0,0 +1,20 @@
604+/*
605+ * ARM64 kexec support.
606+ */
607+
608+#if !defined(KEXEC_ARM64_H)
609+#define KEXEC_ARM64_H
610+
611+/* #include <linux/kexec.h> FIXME: this is broken */
612+#include <sys/types.h>
613+
614+#include "../../kexec.h"
615+
616+#define KEXEC_SEGMENT_MAX 16 /* FIXME: this should come from <linux/kexec.h> */
617+
618+int elf_arm64_probe(const char *buf, off_t len);
619+int elf_arm64_load(int argc, char **argv, const char *buf, off_t len,
620+ struct kexec_info *info);
621+void elf_arm64_usage(void);
622+
623+#endif
624\ No newline at end of file
625Index: kexec-tools-2.0.10/kexec/arch/arm64/kexec-elf-arm64.c
626===================================================================
627--- /dev/null
628+++ kexec-tools-2.0.10/kexec/arch/arm64/kexec-elf-arm64.c
629@@ -0,0 +1,114 @@
630+/*
631+ * ARM64 kexec support.
632+ */
633+
634+#define _GNU_SOURCE
635+
636+#include <elf.h>
637+#include <getopt.h>
638+
639+#include "../../kexec-syscall.h"
640+
641+#include "kexec-arm64.h"
642+#include "arch/options.h"
643+
644+#if !defined(EM_AARCH64)
645+# define EM_AARCH64 183
646+#endif
647+
648+int elf_arm64_probe(const char *buf, off_t len)
649+{
650+ int result;
651+ struct mem_ehdr ehdr;
652+
653+ fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
654+
655+ result = build_elf_exec_info(buf, len, &ehdr, 0);
656+
657+ if (result < 0) {
658+ dbgprintf("Not an ELF executable\n");
659+ goto out;
660+ }
661+
662+ if (ehdr.e_machine != EM_AARCH64) {
663+ dbgprintf("Not an AARCH64 executable\n");
664+ result = -1;
665+ goto out;
666+ }
667+
668+ result = 0;
669+
670+out:
671+ free_elf_info(&ehdr);
672+ fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
673+ return result;
674+}
675+
676+int elf_arm64_load(int argc, char **argv, const char *buf, off_t len,
677+ struct kexec_info *info)
678+{
679+ static const struct option options[] = {
680+ KEXEC_ARCH_OPTIONS
681+ { 0 }
682+ };
683+ static const char short_options[] = KEXEC_OPT_STR "";
684+ const char *command_line = NULL;
685+ unsigned int command_line_len = 0;
686+ const char *ramdisk = NULL;
687+ const char *dtb = NULL;
688+ int opt;
689+ struct mem_ehdr ehdr;
690+ int result;
691+
692+ fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
693+
694+ while ((opt = getopt_long(argc, argv, short_options, options, 0))
695+ != -1) {
696+ switch (opt) {
697+ default:
698+ if (opt < OPT_MAX) /* Ignore core options */
699+ break;
700+ case OPT_APPEND:
701+ command_line = optarg;
702+ command_line_len = strlen(command_line) + 1;
703+ break;
704+ case OPT_RAMDISK:
705+ ramdisk = optarg;
706+ break;
707+ case OPT_DTB:
708+ dtb = optarg;
709+ break;
710+ }
711+ }
712+
713+ fprintf(stderr, "%s:%d: command_line: %s\n", __func__, __LINE__, command_line);
714+ fprintf(stderr, "%s:%d: ramdisk: %s\n", __func__, __LINE__, ramdisk);
715+ fprintf(stderr, "%s:%d: dtb: %s\n", __func__, __LINE__, dtb);
716+
717+ if (info->kexec_flags & KEXEC_ON_CRASH) {
718+ fprintf(stderr, "kexec: kdump not yet supported on arm64\n");
719+ return -1;
720+ }
721+
722+ result = build_elf_exec_info(buf, len, &ehdr, 0);
723+
724+ if (result < 0) {
725+ free_elf_info(&ehdr);
726+ fprintf(stderr, "%s:%d: free_elf_info failed\n", __func__,
727+ __LINE__);
728+ return result;
729+ }
730+
731+ elf_exec_build_load(info, &ehdr, buf, len, 0);
732+
733+ info->entry = (void*)0x80080000UL; // FIXME
734+
735+ fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
736+ return 0;
737+}
738+
739+void elf_arm64_usage(void)
740+{
741+ fprintf(stderr, "%s:%d: ->\n", __func__, __LINE__);
742+ fprintf(stderr, "%s:%d: <-\n", __func__, __LINE__);
743+}
744Index: kexec-tools-2.0.10/kexec/kexec-syscall.h
745===================================================================
746--- kexec-tools-2.0.10.orig/kexec/kexec-syscall.h
747+++ kexec-tools-2.0.10/kexec/kexec-syscall.h
748@@ -39,8 +39,8 @@
749 #ifdef __s390__
750 #define __NR_kexec_load 277
751 #endif
752-#ifdef __arm__
753-#define __NR_kexec_load __NR_SYSCALL_BASE + 347
754+#if defined(__arm__) || defined(__arm64__)
755+#define __NR_kexec_load __NR_SYSCALL_BASE + 347
756 #endif
757 #if defined(__mips__)
758 #define __NR_kexec_load 4311
759@@ -108,6 +108,8 @@ static inline long kexec_file_load(int k
760 #define KEXEC_ARCH_PPC64 (21 << 16)
761 #define KEXEC_ARCH_IA_64 (50 << 16)
762 #define KEXEC_ARCH_ARM (40 << 16)
763+#define KEXEC_ARCH_ARM64 (183 << 16)
764+/* #define KEXEC_ARCH_AARCH64 (183 << 16) */
765 #define KEXEC_ARCH_S390 (22 << 16)
766 #define KEXEC_ARCH_SH (42 << 16)
767 #define KEXEC_ARCH_MIPS_LE (10 << 16)
768@@ -153,5 +155,8 @@ static inline long kexec_file_load(int k
769 #ifdef __m68k__
770 #define KEXEC_ARCH_NATIVE KEXEC_ARCH_68K
771 #endif
772+#if defined(__arm64__)
773+#define KEXEC_ARCH_NATIVE KEXEC_ARCH_ARM64
774+#endif
775
776 #endif /* KEXEC_SYSCALL_H */
777Index: kexec-tools-2.0.10/kexec/kexec.c
778===================================================================
779--- kexec-tools-2.0.10.orig/kexec/kexec.c
780+++ kexec-tools-2.0.10/kexec/kexec.c
781@@ -664,6 +664,8 @@ static int my_load(const char *type, int
782 memset(&info, 0, sizeof(info));
783 info.kexec_flags = kexec_flags;
784
785+ fprintf(stderr, "%s:%d: do\n", __func__, __LINE__);
786+
787 result = 0;
788 if (argc - fileind <= 0) {
789 fprintf(stderr, "No kernel specified\n");
790Index: kexec-tools-2.0.10/purgatory/arch/arm64/Makefile
791===================================================================
792--- /dev/null
793+++ kexec-tools-2.0.10/purgatory/arch/arm64/Makefile
794@@ -0,0 +1,7 @@
795+#
796+# Purgatory arm64
797+#
798+
799+arm64_PURGATORY_SRCS =
800+
801+dist += purgatory/arch/arm64/Makefile $(arm64_PURGATORY_SRCS)