6b7b37681dd402febe58c07a480465beb56a366a
[openwrt/svn-archive/archive.git] / package / kexec-tools / patches / 0005-ps3-kexec-load-legacy-kernel-hack.patch
1 Hack to load PS3 legacy kernels (2.6.16 and fc7 installer) with the 2.6.23
2 mainline linux kernel.
3
4 ---
5 kexec/arch/ppc64/fs2dt.c | 47 +++++++++++++++++++++++++++++++++++++
6 kexec/arch/ppc64/kexec-elf-ppc64.c | 44 ++++++++++++++++++++++++++++++++++
7 kexec/arch/ppc64/kexec-ppc64.c | 5 +++
8 kexec/arch/ppc64/kexec-ppc64.h | 2 +
9 4 files changed, 98 insertions(+)
10
11 --- a/kexec/arch/ppc64/fs2dt.c
12 +++ b/kexec/arch/ppc64/fs2dt.c
13 @@ -262,6 +262,33 @@ static void putprops(char *fn, struct di
14 die("unrecoverable error: could not read \"%s\": %s\n",
15 pathname, strerror(errno));
16
17 + /* ps3 legacy - Add 'PS3PF' to compatible */
18 +
19 + if (ps3_legacy && !strcmp(dp->d_name, "compatible")) {
20 + static const char s[] = "PS3PF";
21 + char *const tmp = (char *)dt + len;
22 +
23 + memcpy(tmp, s, sizeof(s));
24 + len += sizeof(s);
25 + *dt_len = len;
26 +
27 + fprintf(stdout, "ps3 legacy: Changed dt entry "
28 + "/compatible: <%s> -> <%s %s>\n",
29 + (char *)dt, (char *)dt, tmp);
30 + }
31 +
32 + /* ps3 legacy - force memory.reg to 224 MiB */
33 +
34 + if (ps3_legacy && !strcmp(dp->d_name, "reg") && len == 16) {
35 + uint64_t tmp = *((uint64_t *)dt + 1);
36 +
37 + *((uint64_t *)dt + 1) = 0xe000000ULL;
38 + fprintf(stdout, "ps3 legacy: Changed dt entry "
39 + "/memory/reg: <%llx> -> <%llx>\n",
40 + (unsigned long long)tmp,
41 + *((unsigned long long *)dt + 1));
42 + }
43 +
44 checkprop(fn, dt, len);
45
46 dt += (len + 3)/4;
47 @@ -360,6 +387,26 @@ static void putnode(void)
48 reserve(initrd_base, initrd_size);
49 }
50
51 + /* ps3 legacy - add entry linux,platform <801> */
52 +
53 + if (ps3_legacy && !strcmp(basename,"/chosen/")) {
54 + int len = 4;
55 + static const uint32_t data = 0x801UL;
56 +
57 + *dt++ = 3;
58 + *dt++ = len;
59 + *dt++ = propnum("linux,platform");
60 +
61 + if ((len >= 8) && ((unsigned long)dt & 0x4))
62 + dt++;
63 +
64 + memcpy(dt,&data,len);
65 + dt += (len + 3)/4;
66 +
67 + fprintf(stdout, "ps3 legacy: Added dt entry "
68 + "/chosen/linux,platform = <801>\n");
69 + }
70 +
71 /* Add cmdline to the second kernel. Check to see if the new
72 * cmdline has a root=. If not, use the old root= cmdline. */
73 if (!strcmp(basename,"/chosen/")) {
74 --- a/kexec/arch/ppc64/kexec-elf-ppc64.c
75 +++ b/kexec/arch/ppc64/kexec-elf-ppc64.c
76 @@ -45,6 +45,7 @@
77 uint64_t initrd_base, initrd_size;
78 unsigned char reuse_initrd = 0;
79 const char *ramdisk;
80 +int ps3_legacy = -1; /* default to probe */
81
82 int create_flatten_tree(struct kexec_info *, unsigned char **, unsigned long *,
83 char *);
84 @@ -76,6 +77,33 @@ void arch_reuse_initrd(void)
85 reuse_initrd = 1;
86 }
87
88 +/**
89 + * ps3_legacy_probe - Probe kernel version.
90 + */
91 +
92 +static int ps3_legacy_probe(const char *p, off_t len)
93 +{
94 + static const char d1[] = "linux,platform"; /* legacy 2.6.16 */
95 + static const char d2[] = "2.6.21-1.3194.fc7"; /* fedora 7 installer */
96 + const char *const end = p + len - sizeof(d2);
97 +
98 + while(p < end) {
99 + if (p[0] == d1[0] && !memcmp(p, d1, sizeof(d1) - 1)) {
100 + fprintf(stdout, "ps3 legacy: Legacy kernel found: "
101 + "'%s'\n", d1);
102 + break;
103 + }
104 + if (p[0] == d2[0] && !memcmp(p, d2, sizeof(d2) - 1)) {
105 + fprintf(stdout, "ps3 legacy: Legacy kernel found: "
106 + "'%s'\n", d2);
107 + break;
108 + }
109 + p++;
110 + }
111 +
112 + return (p != end);
113 +}
114 +
115 int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len,
116 struct kexec_info *info)
117 {
118 @@ -102,6 +130,8 @@ int elf_ppc64_load(int argc, char **argv
119 #define OPT_RAMDISK (OPT_ARCH_MAX+1)
120 #define OPT_DEVICETREEBLOB (OPT_ARCH_MAX+2)
121 #define OPT_ARGS_IGNORE (OPT_ARCH_MAX+3)
122 +#define OPT_PS3_LEGACY (OPT_ARCH_MAX+4)
123 +#define OPT_PS3_LEGACY_NO (OPT_ARCH_MAX+5)
124
125 static const struct option options[] = {
126 KEXEC_ARCH_OPTIONS
127 @@ -111,6 +141,8 @@ int elf_ppc64_load(int argc, char **argv
128 { "initrd", 1, NULL, OPT_RAMDISK },
129 { "devicetreeblob", 1, NULL, OPT_DEVICETREEBLOB },
130 { "args-linux", 0, NULL, OPT_ARGS_IGNORE },
131 + { "ps3-legacy", 0, NULL, OPT_PS3_LEGACY },
132 + { "ps3-no-legacy", 0, NULL, OPT_PS3_LEGACY_NO },
133 { 0, 0, NULL, 0 },
134 };
135
136 @@ -146,9 +178,18 @@ int elf_ppc64_load(int argc, char **argv
137 break;
138 case OPT_ARGS_IGNORE:
139 break;
140 + case OPT_PS3_LEGACY:
141 + ps3_legacy = 1;
142 + break;
143 + case OPT_PS3_LEGACY_NO:
144 + ps3_legacy = 0;
145 + break;
146 }
147 }
148
149 + if (ps3_legacy == -1)
150 + ps3_legacy = ps3_legacy_probe(buf, len);
151 +
152 cmdline_len = 0;
153 if (cmdline)
154 cmdline_len = strlen(cmdline) + 1;
155 @@ -158,6 +199,9 @@ int elf_ppc64_load(int argc, char **argv
156 if (ramdisk && reuse_initrd)
157 die("Can't specify --ramdisk or --initrd with --reuseinitrd\n");
158
159 + if (ps3_legacy && devicetreeblob)
160 + die("Can't specify --devicetreeblob with --ps3-legacy\n");
161 +
162 setup_memory_ranges(info->kexec_flags);
163
164 /* Need to append some command line parameters internally in case of
165 --- a/kexec/arch/ppc64/kexec-ppc64.c
166 +++ b/kexec/arch/ppc64/kexec-ppc64.c
167 @@ -650,6 +650,11 @@ void arch_usage(void)
168 fprintf(stderr, " --initrd=<filename> same as --ramdisk.\n");
169 fprintf(stderr, " --devicetreeblob=<filename> Specify device tree blob file.\n");
170 fprintf(stderr, " --elf64-core-headers Prepare core headers in ELF64 format\n");
171 + fprintf(stderr, " --ps3-legacy Make fixups needed to boot PS3 legacy kernels.\n");
172 + fprintf(stderr, " The default is to probe the kernel type.\n");
173 + fprintf(stderr, " --ps3-no-legacy Do not make fixups needed to boot PS3 legacy\n");
174 + fprintf(stderr, " kernels. The default is to probe the kernel\n");
175 + fprintf(stderr, " type.\n");
176 }
177
178 struct arch_options_t arch_options = {
179 --- a/kexec/arch/ppc64/kexec-ppc64.h
180 +++ b/kexec/arch/ppc64/kexec-ppc64.h
181 @@ -41,4 +41,6 @@ typedef struct mem_rgns {
182
183 extern mem_rgns_t usablemem_rgns;
184
185 +extern int ps3_legacy;
186 +
187 #endif /* KEXEC_PPC64_H */