diff options
-rwxr-xr-x | configure | 5 | ||||
-rw-r--r-- | kexec/arch/s390/Makefile | 6 | ||||
-rw-r--r-- | kexec/arch/s390/include/arch/options.h | 11 | ||||
-rw-r--r-- | kexec/arch/s390/kexec-elf-rel-s390.c | 23 | ||||
-rw-r--r-- | kexec/arch/s390/kexec-image.c | 137 | ||||
-rw-r--r-- | kexec/arch/s390/kexec-s390.c | 104 | ||||
-rw-r--r-- | kexec/arch/s390/kexec-s390.h | 25 | ||||
-rw-r--r-- | kexec/kexec-syscall.h | 7 | ||||
-rw-r--r-- | purgatory/arch/s390/Makefile | 7 | ||||
-rw-r--r-- | purgatory/arch/s390/include/limits.h | 54 | ||||
-rw-r--r-- | purgatory/arch/s390/include/stdint.h | 24 |
11 files changed, 402 insertions, 1 deletions
@@ -1384,12 +1384,15 @@ case $host_cpu in powerpc ) host_cpu="ppc" ;; + s390x ) + host_cpu="s390" + ;; * ) host_cpu="$host_cpu" ;; esac case $host_cpu in - i386|ppc|x86_64|alpha|ppc64|ia64) + i386|ppc|x86_64|alpha|ppc64|ia64|s390) ;; * ) { { echo "$as_me:$LINENO: error: unsupported architecture $host_cpu" >&5 diff --git a/kexec/arch/s390/Makefile b/kexec/arch/s390/Makefile new file mode 100644 index 0000000..1d26e81 --- /dev/null +++ b/kexec/arch/s390/Makefile @@ -0,0 +1,6 @@ +# +# kexec s390 (linux booting linux) +# +KEXEC_C_SRCS+= kexec/arch/s390/kexec-s390.c +KEXEC_C_SRCS+= kexec/arch/s390/kexec-image.c +KEXEC_C_SRCS+= kexec/arch/s390/kexec-elf-rel-s390.c diff --git a/kexec/arch/s390/include/arch/options.h b/kexec/arch/s390/include/arch/options.h new file mode 100644 index 0000000..2979617 --- /dev/null +++ b/kexec/arch/s390/include/arch/options.h @@ -0,0 +1,11 @@ +#ifndef KEXEC_ARCH_S390_OPTIONS_H +#define KEXEC_ARCH_S390_OPTIONS_H + +#define OPT_ARCH_MAX (OPT_MAX+0) + +#define KEXEC_ARCH_OPTIONS \ + KEXEC_OPTIONS \ + +#define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR "" + +#endif /* KEXEC_ARCH_S390_OPTIONS_H */ diff --git a/kexec/arch/s390/kexec-elf-rel-s390.c b/kexec/arch/s390/kexec-elf-rel-s390.c new file mode 100644 index 0000000..823b91c --- /dev/null +++ b/kexec/arch/s390/kexec-elf-rel-s390.c @@ -0,0 +1,23 @@ +/* + * kexec/arch/s390/kexec-elf-rel-s390.c + * + * (C) Copyright IBM Corp. 2005 + * + * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> + * + */ + +#include <stdio.h> +#include <elf.h> +#include "../../kexec.h" +#include "../../kexec-elf.h" + +int machine_verify_elf_rel(struct mem_ehdr *ehdr) +{ + return 0; +} + +void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type, + void *location, unsigned long address, unsigned long value) +{ +} diff --git a/kexec/arch/s390/kexec-image.c b/kexec/arch/s390/kexec-image.c new file mode 100644 index 0000000..e1849f0 --- /dev/null +++ b/kexec/arch/s390/kexec-image.c @@ -0,0 +1,137 @@ +/* + * kexec/arch/s390/kexec-image.c + * + * (C) Copyright IBM Corp. 2005 + * + * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com> + * Heiko Carstens <heiko.carstens@de.ibm.com> + * + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <getopt.h> +#include "../../kexec.h" +#include "kexec-s390.h" + +#define OPT_APPEND OPT_MAX+0 +#define OPT_RAMDISK OPT_MAX+1 + +int +image_s390_load(int argc, char **argv, const char *kernel_buf, + off_t kernel_size, struct kexec_info *info) +{ + void *krnl_buffer; + char *rd_buffer; + const char *command_line; + const char *ramdisk; + int command_line_len; + off_t ramdisk_len; + unsigned int ramdisk_origin; + int opt; + + static const struct option options[] = + { + KEXEC_OPTIONS + {"command-line", 1, 0, OPT_APPEND}, + {"initrd", 1, 0, OPT_RAMDISK}, + {0, 0, 0, 0}, + }; + static const char short_options[] = KEXEC_OPT_STR ""; + + ramdisk = NULL; + command_line = NULL; + ramdisk_len = 0; + ramdisk_origin = 0; + + while ((opt = getopt_long(argc,argv,short_options,options,0)) != -1) { + switch(opt) { + case '?': + usage(); + return -1; + break; + case OPT_APPEND: + command_line = optarg; + break; + case OPT_RAMDISK: + ramdisk = optarg; + break; + } + } + + /* Process a given command_line: */ + if (command_line) { + command_line_len = strlen(command_line) + 1; /* Remember the '\0' */ + if (command_line_len > COMMAND_LINESIZE) { + fprintf(stderr, "Command line too long.\n"); + return -1; + } + } + + /* Add kernel segment */ + add_segment(info, kernel_buf + IMAGE_READ_OFFSET, + kernel_size - IMAGE_READ_OFFSET, IMAGE_READ_OFFSET, + kernel_size - IMAGE_READ_OFFSET); + + /* We do want to change the kernel image */ + krnl_buffer = (void *) kernel_buf + IMAGE_READ_OFFSET; + + /* Load ramdisk if present */ + if (ramdisk) { + rd_buffer = slurp_file(ramdisk, &ramdisk_len); + if (rd_buffer == NULL) { + fprintf(stderr, "Could not read ramdisk.\n"); + return -1; + } + ramdisk_origin = RAMDISK_ORIGIN_ADDR; + add_segment(info, rd_buffer, ramdisk_len, RAMDISK_ORIGIN_ADDR, ramdisk_len); + } + + /* Register the ramdisk in the kernel. */ + { + unsigned long long *tmp; + + tmp = krnl_buffer + INITRD_START_OFFS; + *tmp = (unsigned long long) ramdisk_origin; + + tmp = krnl_buffer + INITRD_SIZE_OFFS; + *tmp = (unsigned long long) ramdisk_len; + } + + /* + * We will write a probably given command line. + * First, erase the old area, then setup the new parameters: + */ + if (command_line) { + memset(krnl_buffer + COMMAND_LINE_OFFS, 0, COMMAND_LINESIZE); + memcpy(krnl_buffer + COMMAND_LINE_OFFS, command_line, strlen(command_line)); + } + + info->entry = (void *) IMAGE_READ_OFFSET; + + return 0; +} + +int +image_s390_probe(const char *kernel_buf, off_t kernel_size) +{ + /* + * Can't reliably tell if an image is valid, + * therefore everything is valid. + */ + return 0; +} + +void +image_s390_usage(void) +{ + printf("--command-line=STRING Pass a custom command line STRING to the kernel.\n" + "--initrd=FILENAME Use the file FILENAME as a ramdisk.\n" + ); +} diff --git a/kexec/arch/s390/kexec-s390.c b/kexec/arch/s390/kexec-s390.c new file mode 100644 index 0000000..04d8ccc --- /dev/null +++ b/kexec/arch/s390/kexec-s390.c @@ -0,0 +1,104 @@ +/* + * kexec/arch/s390/kexec-s390.c + * + * (C) Copyright IBM Corp. 2005 + * + * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com> + * + */ + +#define _GNU_SOURCE +#include <stddef.h> +#include <stdio.h> +#include <errno.h> +#include <stdint.h> +#include <string.h> +#include <getopt.h> +#include <sys/utsname.h> +#include "../../kexec.h" +#include "../../kexec-syscall.h" +#include "kexec-s390.h" +#include <arch/options.h> + +#define MAX_MEMORY_RANGES 64 +static struct memory_range memory_range[MAX_MEMORY_RANGES]; + +/* + * get_memory_ranges: + * Return a list of memory ranges by parsing /proc/iomem + * + * INPUT: + * - Pointer to an array of memory_range structures. + * - Pointer to an integer with holds the number of memory ranges. + * + * RETURN: + * - 0 on normal execution. + * - (-1) if something went wrong. + */ + +int get_memory_ranges(struct memory_range **range, int *ranges) +{ + char sys_ram[] = "System RAM\n"; + char iomem[] = "/proc/iomem"; + FILE *fp; + char line[80]; + int current_range = 0; + + fp = fopen(iomem,"r"); + if(fp == 0) { + fprintf(stderr,"Unable to open %s: %s\n",iomem,strerror(errno)); + return -1; + } + + /* Setup the compare string properly. */ + while(fgets(line,sizeof(line),fp) != 0) { + unsigned long long start, end; + int cons; + char *str; + + if (current_range == MAX_MEMORY_RANGES) + break; + + sscanf(line,"%Lx-%Lx : %n", &start, &end, &cons); + str = line+cons; + if(memcmp(str,sys_ram,strlen(sys_ram)) == 0) { + memory_range[current_range].start = start; + memory_range[current_range].end = end; + memory_range[current_range].type = RANGE_RAM; + current_range++; + } + else { + continue; + } + } + fclose(fp); + *range = memory_range; + *ranges = current_range; + + return 0; +} + +/* Supported file types and callbacks */ +struct file_type file_type[] = { + { "image", image_s390_probe, image_s390_load, image_s390_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; +} + +int arch_compat_trampoline(struct kexec_info *info, unsigned long *flags) +{ + return 0; +} + +void arch_update_purgatory(struct kexec_info *info) +{ +} diff --git a/kexec/arch/s390/kexec-s390.h b/kexec/arch/s390/kexec-s390.h new file mode 100644 index 0000000..1159ceb --- /dev/null +++ b/kexec/arch/s390/kexec-s390.h @@ -0,0 +1,25 @@ +/* + * kexec/arch/s390/kexec-s390.h + * + * (C) Copyright IBM Corp. 2005 + * + * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com> + * + */ + +#ifndef KEXEC_S390_H +#define KEXEC_S390_H + +#define IMAGE_READ_OFFSET 0x10000 + +#define RAMDISK_ORIGIN_ADDR 0x800000 +#define INITRD_START_OFFS 0x408 +#define INITRD_SIZE_OFFS 0x410 +#define COMMAND_LINE_OFFS 0x480 +#define COMMAND_LINESIZE 896 + +extern int image_s390_load(int, char **, const char *, off_t, struct kexec_info *); +extern int image_s390_probe(const char *, off_t); +extern void image_s390_usage(void); + +#endif /* KEXEC_IA64_H */ diff --git a/kexec/kexec-syscall.h b/kexec/kexec-syscall.h index 7b2670c..3de05eb 100644 --- a/kexec/kexec-syscall.h +++ b/kexec/kexec-syscall.h @@ -37,6 +37,12 @@ #ifdef __x86_64__ #define __NR_kexec_load 246 #endif +#ifdef __s390x__ +#define __NR_kexec_load 277 +#endif +#ifdef __s390__ +#define __NR_kexec_load 277 +#endif #ifndef __NR_kexec_load #error Unknown processor architecture. Needs a kexec_load syscall number. #endif @@ -67,6 +73,7 @@ static inline long kexec_reboot(void) #define KEXEC_ARCH_PPC (20 << 16) #define KEXEC_ARCH_PPC64 (21 << 16) #define KEXEC_ARCH_IA_64 (50 << 16) +#define KEXEC_ARCH_S390 (22 << 16) #define KEXEC_MAX_SEGMENTS 8 diff --git a/purgatory/arch/s390/Makefile b/purgatory/arch/s390/Makefile new file mode 100644 index 0000000..63dac9d --- /dev/null +++ b/purgatory/arch/s390/Makefile @@ -0,0 +1,7 @@ +# +# Purgatory s390 +# + +PURGATORY_C_SRCS+= +PURGATORY_S_SRCS+= + diff --git a/purgatory/arch/s390/include/limits.h b/purgatory/arch/s390/include/limits.h new file mode 100644 index 0000000..3424298 --- /dev/null +++ b/purgatory/arch/s390/include/limits.h @@ -0,0 +1,54 @@ +#ifndef _LIMITS_H_ +#define _LIMITS_H_ + +/* Number of bits in a `char'. */ +# define CHAR_BIT 8 + +/* Minimum and maximum values a `signed char' can hold. */ +# define SCHAR_MIN (-128) +# define SCHAR_MAX 127 + +/* Maximum value an `unsigned char' can hold. (Minimum is 0.) */ +# define UCHAR_MAX 255 + +# define CHAR_MIN SCHAR_MIN +# define CHAR_MAX SCHAR_MAX + +/* Minimum and maximum values a `signed short int' can hold. */ +# define SHRT_MIN (-32768) +# define SHRT_MAX 32767 + +/* Maximum value an `unsigned short int' can hold. (Minimum is 0.) */ +# define USHRT_MAX 65535 + +/* Minimum and maximum values a `signed int' can hold. */ +# define INT_MIN (-INT_MAX - 1) +# define INT_MAX 2147483647 + +/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */ +# define UINT_MAX 4294967295U + +/* Minimum and maximum values a `signed long int' can hold. */ +#ifdef __s390x__ +# define LONG_MAX 9223372036854775807L +#else +# define LONG_MAX 2147483647L +#endif + +# define LONG_MIN (-LONG_MAX - 1L) + +/* Maximum value an `unsigned long int' can hold. (Minimum is 0.) */ +#ifdef __s390x__ +# define ULONG_MAX 18446744073709551615UL +#else +# define ULONG_MAX 4294967295UL +#endif + +/* Minimum and maximum values a `signed long long int' can hold. */ +# define LLONG_MAX 9223372036854775807LL +# define LLONG_MIN (-LLONG_MAX - 1LL) + +/* Maximum value an `unsigned long long int' can hold. (Minimum is 0.) */ +# define ULLONG_MAX 18446744073709551615ULL + +#endif /* !_LIMITS_H_ */ diff --git a/purgatory/arch/s390/include/stdint.h b/purgatory/arch/s390/include/stdint.h new file mode 100644 index 0000000..a713cf5 --- /dev/null +++ b/purgatory/arch/s390/include/stdint.h @@ -0,0 +1,24 @@ +#ifndef _STDINT_H +#define _STDINT_H + +typedef unsigned long size_t; + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +#ifdef __s390x__ +typedef unsigned long uint64_t; +#else +typedef unsigned long long uint64_t; +#endif + +typedef signed char int8_t; +typedef short int16_t; +typedef int int32_t; +#ifdef __s390x__ +typedef long int64_t; +#else +typedef long long int64_t; +#endif + +#endif |