summaryrefslogtreecommitdiff
path: root/kexec/arch/s390/kexec-s390.c
blob: e303db946c2b8fa4935caec5ff38da75a842e184 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
 * 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 the file returned by
 *  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, unsigned long flags)
{
	char sys_ram[] = "System RAM\n";
	char *iomem = proc_iomem(flags & KEXEC_ON_CRASH);
	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)
{
	info->kexec_flags |= KEXEC_ARCH_S390;
	return 0;
}

void arch_update_purgatory(struct kexec_info *info)
{
}

int is_crashkernel_mem_reserved(void)
{
	return 0; /* kdump is not supported on this platform (yet) */
}