diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 02:56:35 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 02:56:35 +0000 |
commit | eba0cfa6b0bef4f2e73c8630a7efa3944df8b0f8 (patch) | |
tree | 74c37eede1f0634cc5de1c63c934edaa1630c6bc /kexec/arch/cris | |
parent | Initial commit. (diff) | |
download | kexec-tools-upstream/1%2.0.27.tar.xz kexec-tools-upstream/1%2.0.27.zip |
Adding upstream version 1:2.0.27.upstream/1%2.0.27upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'kexec/arch/cris')
-rw-r--r-- | kexec/arch/cris/Makefile | 13 | ||||
-rw-r--r-- | kexec/arch/cris/cris-setup-simple.S | 31 | ||||
-rw-r--r-- | kexec/arch/cris/include/arch/options.h | 35 | ||||
-rw-r--r-- | kexec/arch/cris/kexec-cris.c | 111 | ||||
-rw-r--r-- | kexec/arch/cris/kexec-cris.h | 9 | ||||
-rw-r--r-- | kexec/arch/cris/kexec-elf-cris.c | 133 | ||||
-rw-r--r-- | kexec/arch/cris/kexec-elf-rel-cris.c | 43 |
7 files changed, 375 insertions, 0 deletions
diff --git a/kexec/arch/cris/Makefile b/kexec/arch/cris/Makefile new file mode 100644 index 0000000..4982f3e --- /dev/null +++ b/kexec/arch/cris/Makefile @@ -0,0 +1,13 @@ +cris_KEXEC_SRCS = kexec/arch/cris/kexec-cris.c +cris_KEXEC_SRCS += kexec/arch/cris/kexec-elf-cris.c +cris_KEXEC_SRCS += kexec/arch/cris/cris-setup-simple.S +cris_KEXEC_SRCS += kexec/arch/cris/kexec-elf-rel-cris.c + +cris_ADD_BUFFER = +cris_ADD_SEGMENT = +cris_VIRT_TO_PHYS = + +dist += kexec/arch/cris/Makefile $(cris_KEXEC_SRCS) \ + kexec/arch/cris/kexec-cris.h \ + kexec/arch/cris/include/arch/options.h + diff --git a/kexec/arch/cris/cris-setup-simple.S b/kexec/arch/cris/cris-setup-simple.S new file mode 100644 index 0000000..764f188 --- /dev/null +++ b/kexec/arch/cris/cris-setup-simple.S @@ -0,0 +1,31 @@ +/* + * cris-setup-simple.S - code to execute before stepping into the new kernel. + * Copyright (C) 2008 AXIS Communications AB + * Written by Edgar E. Iglesias + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ + + .data + .globl cris_trampoline +cris_trampoline: + .balign 4 + lapc cris_regframe, $sp + moveq 0, $r0 + move $r0, $pid + + movem [$sp+], $r14 + jump $r0 + nop + + .globl cris_regframe +cris_regframe: + .balign 4 + .fill 16, 4, 0 +cris_trampoline_end: + + .globl cris_trampoline_size +cris_trampoline_size: + .long cris_trampoline_end - cris_trampoline + diff --git a/kexec/arch/cris/include/arch/options.h b/kexec/arch/cris/include/arch/options.h new file mode 100644 index 0000000..1c1a029 --- /dev/null +++ b/kexec/arch/cris/include/arch/options.h @@ -0,0 +1,35 @@ +#ifndef KEXEC_ARCH_CRIS_OPTIONS_H +#define KEXEC_ARCH_CRIS_OPTIONS_H + +#define OPT_ARCH_MAX (OPT_MAX+0) +#define OPT_APPEND (OPT_ARCH_MAX+0) + +/* Options relevant to the architecture (excluding loader-specific ones), + * in this case none: + */ +#define KEXEC_ARCH_OPTIONS \ + KEXEC_OPTIONS \ + +#define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR "" + +/* The following two #defines list ALL of the options added by all of the + * architecture's loaders. + * o main() uses this complete list to scan for its options, ignoring + * arch-specific/loader-specific ones. + * o Then, arch_process_options() uses this complete list to scan for its + * options, ignoring general/loader-specific ones. + * o Then, the file_type[n].load re-scans for options, using + * KEXEC_ARCH_OPTIONS plus its loader-specific options subset. + * Any unrecognised options cause an error here. + * + * This is done so that main()'s/arch_process_options()'s getopt_long() calls + * don't choose a kernel filename from random arguments to options they don't + * recognise -- as they now recognise (if not act upon) all possible options. + */ +#define KEXEC_ALL_OPTIONS \ + KEXEC_ARCH_OPTIONS \ + {"append", 1, 0, OPT_APPEND}, + +#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR + +#endif /* KEXEC_ARCH_CRIS_OPTIONS_H */ diff --git a/kexec/arch/cris/kexec-cris.c b/kexec/arch/cris/kexec-cris.c new file mode 100644 index 0000000..3b69709 --- /dev/null +++ b/kexec/arch/cris/kexec-cris.c @@ -0,0 +1,111 @@ +/* + * kexec-cris.c + * Copyright (C) 2008 AXIS Communications AB + * Written by Edgar E. Iglesias + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ + +#include <stddef.h> +#include <stdio.h> +#include <errno.h> +#include <stdint.h> +#include <string.h> +#include <getopt.h> +#include "../../kexec.h" +#include "../../kexec-syscall.h" +#include "kexec-cris.h" +#include <arch/options.h> + +#define MAX_MEMORY_RANGES 64 +#define MAX_LINE 160 +static struct memory_range memory_range[MAX_MEMORY_RANGES]; + +/* Return a sorted list of memory ranges. */ +int get_memory_ranges(struct memory_range **range, int *ranges, + unsigned long UNUSED(kexec_flags)) +{ + int memory_ranges = 0; + + memory_range[memory_ranges].start = 0x40000000; + memory_range[memory_ranges].end = 0x41000000; + memory_range[memory_ranges].type = RANGE_RAM; + memory_ranges++; + + memory_range[memory_ranges].start = 0xc0000000; + memory_range[memory_ranges].end = 0xc1000000; + memory_range[memory_ranges].type = RANGE_RAM; + memory_ranges++; + + *range = memory_range; + *ranges = memory_ranges; + return 0; +} + +struct file_type file_type[] = { + {"elf-cris", elf_cris_probe, elf_cris_load, elf_cris_usage}, +}; +int file_types = sizeof(file_type) / sizeof(file_type[0]); + +void arch_usage(void) +{ +} + +int arch_process_options(int argc, char **argv) +{ + return 0; +} + +const struct arch_map_entry arches[] = { + { "cris", KEXEC_ARCH_CRIS }, + { "crisv32", KEXEC_ARCH_CRIS }, + { 0 }, +}; + +int arch_compat_trampoline(struct kexec_info *UNUSED(info)) +{ + return 0; +} + +void arch_update_purgatory(struct kexec_info *UNUSED(info)) +{ +} + +int is_crashkernel_mem_reserved(void) +{ + return 0; +} + +int get_crash_kernel_load_range(uint64_t *start, uint64_t *end) +{ + /* Crash kernel region size is not exposed by the system */ + return -1; +} + +unsigned long virt_to_phys(unsigned long addr) +{ + return (addr) & 0x7fffffff; +} + +/* + * add_segment() should convert base to a physical address on cris, + * while the default is just to work with base as is */ +void add_segment(struct kexec_info *info, const void *buf, size_t bufsz, + unsigned long base, size_t memsz) +{ + add_segment_phys_virt(info, buf, bufsz, base, memsz, 1); +} + +/* + * add_buffer() should convert base to a physical address on cris, + * while the default is just to work with base as is */ +unsigned long add_buffer(struct kexec_info *info, const void *buf, + unsigned long bufsz, unsigned long memsz, + unsigned long buf_align, unsigned long buf_min, + unsigned long buf_max, int buf_end) +{ + return add_buffer_phys_virt(info, buf, bufsz, memsz, buf_align, + buf_min, buf_max, buf_end, 1); +} + diff --git a/kexec/arch/cris/kexec-cris.h b/kexec/arch/cris/kexec-cris.h new file mode 100644 index 0000000..7ee9945 --- /dev/null +++ b/kexec/arch/cris/kexec-cris.h @@ -0,0 +1,9 @@ +#ifndef KEXEC_CRIS_H +#define KEXEC_CRIS_H + +int elf_cris_probe(const char *buf, off_t len); +int elf_cris_load(int argc, char **argv, const char *buf, off_t len, + struct kexec_info *info); +void elf_cris_usage(void); + +#endif /* KEXEC_CRIS_H */ diff --git a/kexec/arch/cris/kexec-elf-cris.c b/kexec/arch/cris/kexec-elf-cris.c new file mode 100644 index 0000000..7e251e6 --- /dev/null +++ b/kexec/arch/cris/kexec-elf-cris.c @@ -0,0 +1,133 @@ +/* + * kexec: Linux boots Linux + * + * Copyright (C) 2008 AXIS Communications AB + * Written by Edgar E. Iglesias + * + * Based on x86 implementation, + * Copyright (C) 2003-2005 Eric Biederman (ebiederm@xmission.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation (version 2 of the License). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include <limits.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <getopt.h> +#include <elf.h> +#include "../../kexec.h" +#include "../../kexec-syscall.h" +#include "../../kexec-elf.h" +#include "../../kexec-elf-boot.h" +#include <arch/options.h> +#include "kexec-cris.h" + +int elf_cris_probe(const char *buf, off_t len) +{ + struct mem_ehdr ehdr; + int result; + result = build_elf_exec_info(buf, len, &ehdr, 0); + if (result < 0) + goto out; + + /* Verify the architecuture specific bits */ + if (ehdr.e_machine != EM_CRIS) { + result = -1; + goto out; + } + + result = 0; + out: + free_elf_info(&ehdr); + return result; +} + +void elf_cris_usage(void) +{ + printf(" --append=STRING Set the kernel command line to STRING\n" + ); +} + +#define CRAMFS_MAGIC 0x28cd3d45 +#define JHEAD_MAGIC 0x1FF528A6 +#define JHEAD_SIZE 8 +#define RAM_INIT_MAGIC 0x56902387 +#define COMMAND_LINE_MAGIC 0x87109563 +#define NAND_BOOT_MAGIC 0x9a9db001 + +int elf_cris_load(int argc, char **argv, const char *buf, off_t len, + struct kexec_info *info) +{ + struct mem_ehdr ehdr; + char *command_line; + unsigned int *trampoline_buf; + unsigned long trampoline_base; + int opt; + extern void cris_trampoline(void); + extern unsigned long cris_trampoline_size; + extern struct regframe_t { + unsigned int regs[16]; + } cris_regframe; + + /* See options.h -- add any more there, too. */ + static const struct option options[] = { + KEXEC_ARCH_OPTIONS + {"append", 1, 0, OPT_APPEND}, + { 0, 0, 0, 0 }, + }; + + static const char short_options[] = KEXEC_OPT_STR ""; + + /* + * Parse the command line arguments + */ + command_line = 0; + while((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) { + switch(opt) { + default: + /* Ignore core options */ + if (opt < OPT_ARCH_MAX) { + break; + } + case OPT_APPEND: + command_line = optarg; + break; + } + } + + /* Load the ELF executable */ + elf_exec_build_load(info, &ehdr, buf, len, 0); + + cris_regframe.regs[0] = virt_to_phys(ehdr.e_entry); + cris_regframe.regs[8] = RAM_INIT_MAGIC; + cris_regframe.regs[12] = NAND_BOOT_MAGIC; + + trampoline_buf = xmalloc(cris_trampoline_size); + trampoline_base = add_buffer_virt(info, + trampoline_buf, + cris_trampoline_size, + cris_trampoline_size, + 4, 0, elf_max_addr(&ehdr), 1); + memcpy(trampoline_buf, + cris_trampoline, cris_trampoline_size); + info->entry = (void *)trampoline_base; + return 0; +} diff --git a/kexec/arch/cris/kexec-elf-rel-cris.c b/kexec/arch/cris/kexec-elf-rel-cris.c new file mode 100644 index 0000000..255cc2c --- /dev/null +++ b/kexec/arch/cris/kexec-elf-rel-cris.c @@ -0,0 +1,43 @@ +/* + * kexec-elf-rel-cris.c - kexec Elf relocation routines + * Copyright (C) 2008 AXIS Communications AB + * Written by Edgar E. Iglesias + * + * derived from ../ppc/kexec-elf-rel-ppc.c + * Copyright (C) 2004 Albert Herranz + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. +*/ + +#include <stdio.h> +#include <elf.h> +#include "../../kexec.h" +#include "../../kexec-elf.h" + +int machine_verify_elf_rel(struct mem_ehdr *ehdr) +{ + if (ehdr->ei_data != ELFDATA2MSB) { + return 0; + } + if (ehdr->ei_class != ELFCLASS32) { + return 0; + } + if (ehdr->e_machine != EM_CRIS) { + return 0; + } + return 1; +} + +void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), + struct mem_sym *UNUSED(sym), unsigned long r_type, void *location, + unsigned long address, unsigned long value) +{ + switch(r_type) { + + default: + die("Unknown rela relocation: %lu\n", r_type); + break; + } + return; +} |