summaryrefslogtreecommitdiff
path: root/kexec/arch/sh/kexec-sh.c
diff options
context:
space:
mode:
Diffstat (limited to 'kexec/arch/sh/kexec-sh.c')
-rw-r--r--kexec/arch/sh/kexec-sh.c166
1 files changed, 166 insertions, 0 deletions
diff --git a/kexec/arch/sh/kexec-sh.c b/kexec/arch/sh/kexec-sh.c
new file mode 100644
index 0000000..6b485d1
--- /dev/null
+++ b/kexec/arch/sh/kexec-sh.c
@@ -0,0 +1,166 @@
+/*
+ * kexec-sh.c - kexec for the SH
+ * Copyright (C) 2004 kogiidena@eggplant.ddo.jp
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+#define _GNU_SOURCE
+#include <stddef.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <sys/utsname.h>
+#include "../../kexec.h"
+#include "../../kexec-syscall.h"
+#include "kexec-sh.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 available memory ranges. */
+int get_memory_ranges(struct memory_range **range, int *ranges)
+{
+ int memory_ranges;
+
+ memory_ranges = 0;
+ memory_range[memory_ranges].start = 0x08000000;
+ memory_range[memory_ranges].end = 0x10000000;
+ memory_range[memory_ranges].type = RANGE_RAM;
+ memory_ranges++;
+ *range = memory_range;
+ *ranges = memory_ranges;
+ return 0;
+}
+
+/* Supported file types and callbacks */
+struct file_type file_type[] = {
+ {"zImage-sh", zImage_sh_probe, zImage_sh_load, zImage_sh_usage},
+ {"netbsd-sh", netbsd_sh_probe, netbsd_sh_load, netbsd_sh_usage},
+};
+int file_types = sizeof(file_type) / sizeof(file_type[0]);
+
+
+void arch_usage(void)
+{
+
+ printf(
+ " none\n\n"
+ "Default options:\n"
+ " --append=\"%s\"\n"
+ " --empty-zero=0x%08x\n\n"
+ " STRING of --appned is set form /proc/cmdline as default.\n"
+ " ADDRESS of --empty-zero can be set SHELL environment variable\n"
+ " KEXEC_EMPTY_ZERO as default.\n\n"
+ " ADDRESS can be get in the following method in your system. \n"
+ " 1) \"grep empty_zero /proc/kallsyms\". \n"
+ " 2) \"grep empty_zero System.map\". \n"
+ " 3) CONFIG_MEMORY_START + CONFIG_ZERO_PAGE_OFFSET in your kernel\n"
+ " config file.\n"
+ ,get_append(), (unsigned int) get_empty_zero(NULL));
+
+}
+
+static struct {
+} arch_options = {
+};
+int arch_process_options(int argc, char **argv)
+{
+ static const struct option options[] = {
+ KEXEC_ARCH_OPTIONS
+ { 0, 0, NULL, 0 },
+ };
+ static const char short_options[] = KEXEC_ARCH_OPT_STR;
+ int opt;
+
+ opterr = 0; /* Don't complain about unrecognized options here */
+ while((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) {
+ switch(opt) {
+ default:
+ /* Ignore core options */
+ if (opt < OPT_MAX) {
+ break;
+ }
+ case '?':
+ usage();
+ return -1;
+ case OPT_APPEND:
+ case OPT_NBSD_HOWTO:
+ case OPT_NBSD_MROOT:
+ ;
+ }
+ }
+ /* Reset getopt for the next pass; called in other source modules */
+ opterr = 1;
+ optind = 1;
+ return 0;
+}
+
+int arch_compat_trampoline(struct kexec_info *info, unsigned long *flags)
+{
+ int result;
+ struct utsname utsname;
+ result = uname(&utsname);
+ if (result < 0) {
+ fprintf(stderr, "uname failed: %s\n",
+ strerror(errno));
+ return -1;
+ }
+ if ( (strcmp(utsname.machine, "sh3") == 0) ||
+ (strcmp(utsname.machine, "sh4") == 0))
+
+ {
+ /* For compatibility with older patches
+ * use KEXEC_ARCH_DEFAULT instead of KEXEC_ARCH_IA64 here.
+ */
+ *flags |= KEXEC_ARCH_DEFAULT;
+ }
+ else {
+ fprintf(stderr, "Unsupported machine type: %s\n",
+ utsname.machine);
+ return -1;
+ }
+ return 0;
+}
+
+void arch_update_purgatory(struct kexec_info *info)
+{
+}
+
+
+unsigned long get_empty_zero(char *s)
+{
+ char *env;
+
+ env = getenv("KEXEC_EMPTY_ZERO");
+
+ if(s){
+ env = s;
+ }else if(!env){
+ env = "0x0c001000";
+ }
+ return 0x1fffffff & strtoul(env,(char **)NULL,0);
+}
+
+char append_buf[256];
+
+char *get_append(void)
+{
+ FILE *fp;
+ int len;
+ if((fp = fopen("/proc/cmdline", "r")) == NULL){
+ printf("/proc/cmdline file open error !!\n");
+ exit(1);
+ }
+ fgets(append_buf, 256, fp);
+ len = strlen(append_buf);
+ append_buf[len-1] = 0;
+ fclose(fp);
+ return append_buf;
+}