changed Makefile and profiles, added patches for kernel 2.6.24 (stable-branch of...
[openwrt/staging/florian.git] / target / linux / s3c24xx / patches-2.6.24 / 1070-kexec-atags.patch.patch
1 From 68bcfea9ab5d8947f711a97dcc291cb9da47c7da Mon Sep 17 00:00:00 2001
2 From: mokopatches <mokopatches@openmoko.org>
3 Date: Sun, 13 Apr 2008 07:23:59 +0100
4 Subject: [PATCH] kexec-atags.patch
5 Leapfrogged from upstream (ARM Linux)
6 http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=4736/1
7
8 ---
9 arch/arm/Kconfig | 7 +++
10 arch/arm/kernel/Makefile | 1 +
11 arch/arm/kernel/atags.c | 86 +++++++++++++++++++++++++++++++++++++
12 arch/arm/kernel/atags.h | 5 ++
13 arch/arm/kernel/machine_kexec.c | 2 +
14 arch/arm/kernel/relocate_kernel.S | 30 ++-----------
15 arch/arm/kernel/setup.c | 32 +-------------
16 include/asm-arm/kexec.h | 3 +
17 8 files changed, 110 insertions(+), 56 deletions(-)
18 create mode 100644 arch/arm/kernel/atags.c
19 create mode 100644 arch/arm/kernel/atags.h
20
21 diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
22 index 23e3d6b..ef7b9ff 100644
23 --- a/arch/arm/Kconfig
24 +++ b/arch/arm/Kconfig
25 @@ -865,6 +865,13 @@ config KEXEC
26 initially work for you. It may help to enable device hotplugging
27 support.
28
29 +config ATAGS_PROC
30 + bool "Export atags in procfs"
31 + default n
32 + help
33 + Should the atags used to boot the kernel be exported in an "atags"
34 + file in procfs. Useful with kexec.
35 +
36 endmenu
37
38 if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX )
39 diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
40 index 593b565..5cf694c 100644
41 --- a/arch/arm/kernel/Makefile
42 +++ b/arch/arm/kernel/Makefile
43 @@ -19,6 +19,7 @@ obj-$(CONFIG_ISA_DMA) += dma-isa.o
44 obj-$(CONFIG_PCI) += bios32.o isa.o
45 obj-$(CONFIG_SMP) += smp.o
46 obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
47 +obj-$(CONFIG_ATAGS_PROC) += atags.o
48 obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
49
50 obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o
51 diff --git a/arch/arm/kernel/atags.c b/arch/arm/kernel/atags.c
52 new file mode 100644
53 index 0000000..e2e934c
54 --- /dev/null
55 +++ b/arch/arm/kernel/atags.c
56 @@ -0,0 +1,86 @@
57 +#include <linux/slab.h>
58 +#include <linux/kexec.h>
59 +#include <linux/proc_fs.h>
60 +#include <asm/setup.h>
61 +#include <asm/types.h>
62 +#include <asm/page.h>
63 +
64 +struct buffer {
65 + size_t size;
66 + char *data;
67 +};
68 +static struct buffer tags_buffer;
69 +
70 +static int
71 +read_buffer(char* page, char** start, off_t off, int count,
72 + int* eof, void* data)
73 +{
74 + struct buffer *buffer = (struct buffer *)data;
75 +
76 + if (off >= buffer->size) {
77 + *eof = 1;
78 + return 0;
79 + }
80 +
81 + count = min((int) (buffer->size - off), count);
82 +
83 + memcpy(page, &buffer->data[off], count);
84 +
85 + return count;
86 +}
87 +
88 +
89 +static int
90 +create_proc_entries(void)
91 +{
92 + struct proc_dir_entry* tags_entry;
93 +
94 + tags_entry = create_proc_read_entry("atags", 0400, &proc_root, read_buffer, &tags_buffer);
95 + if (!tags_entry)
96 + return -ENOMEM;
97 +
98 + return 0;
99 +}
100 +
101 +
102 +static char __initdata atags_copy_buf[KEXEC_BOOT_PARAMS_SIZE];
103 +static char __initdata *atags_copy;
104 +
105 +void __init save_atags(const struct tag *tags)
106 +{
107 + atags_copy = atags_copy_buf;
108 + memcpy(atags_copy, tags, KEXEC_BOOT_PARAMS_SIZE);
109 +}
110 +
111 +
112 +static int __init init_atags_procfs(void)
113 +{
114 + struct tag *tag;
115 + int error;
116 +
117 + if (!atags_copy) {
118 + printk(KERN_WARNING "Exporting ATAGs: No saved tags found\n");
119 + return -EIO;
120 + }
121 +
122 + for (tag = (struct tag *) atags_copy; tag->hdr.size; tag = tag_next(tag))
123 + ;
124 +
125 + tags_buffer.size = ((char *) tag - atags_copy) + sizeof(tag->hdr);
126 + tags_buffer.data = kmalloc(tags_buffer.size, GFP_KERNEL);
127 + if (tags_buffer.data == NULL)
128 + return -ENOMEM;
129 + memcpy(tags_buffer.data, atags_copy, tags_buffer.size);
130 +
131 + error = create_proc_entries();
132 + if (error) {
133 + printk(KERN_ERR "Exporting ATAGs: not enough memory\n");
134 + kfree(tags_buffer.data);
135 + tags_buffer.size = 0;
136 + tags_buffer.data = NULL;
137 + }
138 +
139 + return error;
140 +}
141 +
142 +arch_initcall(init_atags_procfs);
143 diff --git a/arch/arm/kernel/atags.h b/arch/arm/kernel/atags.h
144 new file mode 100644
145 index 0000000..e5f028d
146 --- /dev/null
147 +++ b/arch/arm/kernel/atags.h
148 @@ -0,0 +1,5 @@
149 +#ifdef CONFIG_ATAGS_PROC
150 +extern void save_atags(struct tag *tags);
151 +#else
152 +static inline void save_atags(struct tag *tags) { }
153 +#endif
154 diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
155 index 863c664..db8f54a 100644
156 --- a/arch/arm/kernel/machine_kexec.c
157 +++ b/arch/arm/kernel/machine_kexec.c
158 @@ -21,6 +21,7 @@ extern void setup_mm_for_reboot(char mode);
159 extern unsigned long kexec_start_address;
160 extern unsigned long kexec_indirection_page;
161 extern unsigned long kexec_mach_type;
162 +extern unsigned long kexec_boot_atags;
163
164 /*
165 * Provide a dummy crash_notes definition while crash dump arrives to arm.
166 @@ -62,6 +63,7 @@ void machine_kexec(struct kimage *image)
167 kexec_start_address = image->start;
168 kexec_indirection_page = page_list;
169 kexec_mach_type = machine_arch_type;
170 + kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
171
172 /* copy our kernel relocation code to the control code page */
173 memcpy(reboot_code_buffer,
174 diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S
175 index 062c111..61930eb 100644
176 --- a/arch/arm/kernel/relocate_kernel.S
177 +++ b/arch/arm/kernel/relocate_kernel.S
178 @@ -7,23 +7,6 @@
179 .globl relocate_new_kernel
180 relocate_new_kernel:
181
182 - /* Move boot params back to where the kernel expects them */
183 -
184 - ldr r0,kexec_boot_params_address
185 - teq r0,#0
186 - beq 8f
187 -
188 - ldr r1,kexec_boot_params_copy
189 - mov r6,#KEXEC_BOOT_PARAMS_SIZE/4
190 -7:
191 - ldr r5,[r1],#4
192 - str r5,[r0],#4
193 - subs r6,r6,#1
194 - bne 7b
195 -
196 -8:
197 - /* Boot params moved, now go on with the kernel */
198 -
199 ldr r0,kexec_indirection_page
200 ldr r1,kexec_start_address
201
202 @@ -67,7 +50,7 @@ relocate_new_kernel:
203 mov lr,r1
204 mov r0,#0
205 ldr r1,kexec_mach_type
206 - ldr r2,kexec_boot_params_address
207 + ldr r2,kexec_boot_atags
208 mov pc,lr
209
210 .globl kexec_start_address
211 @@ -82,14 +65,9 @@ kexec_indirection_page:
212 kexec_mach_type:
213 .long 0x0
214
215 - /* phy addr where new kernel will expect to find boot params */
216 - .globl kexec_boot_params_address
217 -kexec_boot_params_address:
218 - .long 0x0
219 -
220 - /* phy addr where old kernel put a copy of orig boot params */
221 - .globl kexec_boot_params_copy
222 -kexec_boot_params_copy:
223 + /* phy addr of the atags for the new kernel */
224 + .globl kexec_boot_atags
225 +kexec_boot_atags:
226 .long 0x0
227
228 relocate_new_kernel_end:
229 diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
230 index bf56eb3..ae3712d 100644
231 --- a/arch/arm/kernel/setup.c
232 +++ b/arch/arm/kernel/setup.c
233 @@ -24,7 +24,6 @@
234 #include <linux/interrupt.h>
235 #include <linux/smp.h>
236 #include <linux/fs.h>
237 -#include <linux/kexec.h>
238
239 #include <asm/cpu.h>
240 #include <asm/elf.h>
241 @@ -39,6 +38,7 @@
242 #include <asm/mach/time.h>
243
244 #include "compat.h"
245 +#include "atags.h"
246
247 #ifndef MEM_SIZE
248 #define MEM_SIZE (16*1024*1024)
249 @@ -784,23 +784,6 @@ static int __init customize_machine(void)
250 }
251 arch_initcall(customize_machine);
252
253 -#ifdef CONFIG_KEXEC
254 -
255 -/* Physical addr of where the boot params should be for this machine */
256 -extern unsigned long kexec_boot_params_address;
257 -
258 -/* Physical addr of the buffer into which the boot params are copied */
259 -extern unsigned long kexec_boot_params_copy;
260 -
261 -/* Pointer to the boot params buffer, for manipulation and display */
262 -unsigned long kexec_boot_params;
263 -EXPORT_SYMBOL(kexec_boot_params);
264 -
265 -/* The buffer itself - make sure it is sized correctly */
266 -static unsigned long kexec_boot_params_buf[(KEXEC_BOOT_PARAMS_SIZE + 3) / 4];
267 -
268 -#endif
269 -
270 void __init setup_arch(char **cmdline_p)
271 {
272 struct tag *tags = (struct tag *)&init_tags;
273 @@ -819,18 +802,6 @@ void __init setup_arch(char **cmdline_p)
274 else if (mdesc->boot_params)
275 tags = phys_to_virt(mdesc->boot_params);
276
277 -#ifdef CONFIG_KEXEC
278 - kexec_boot_params_copy = virt_to_phys(kexec_boot_params_buf);
279 - kexec_boot_params = (unsigned long)kexec_boot_params_buf;
280 - if (__atags_pointer) {
281 - kexec_boot_params_address = __atags_pointer;
282 - memcpy((void *)kexec_boot_params, tags, KEXEC_BOOT_PARAMS_SIZE);
283 - } else if (mdesc->boot_params) {
284 - kexec_boot_params_address = mdesc->boot_params;
285 - memcpy((void *)kexec_boot_params, tags, KEXEC_BOOT_PARAMS_SIZE);
286 - }
287 -#endif
288 -
289 /*
290 * If we have the old style parameters, convert them to
291 * a tag list.
292 @@ -846,6 +817,7 @@ void __init setup_arch(char **cmdline_p)
293 if (tags->hdr.tag == ATAG_CORE) {
294 if (meminfo.nr_banks != 0)
295 squash_mem_tags(tags);
296 + save_atags(tags);
297 parse_tags(tags);
298 }
299
300 diff --git a/include/asm-arm/kexec.h b/include/asm-arm/kexec.h
301 index 46dcc4d..1ee17b6 100644
302 --- a/include/asm-arm/kexec.h
303 +++ b/include/asm-arm/kexec.h
304 @@ -16,6 +16,9 @@
305
306 #define KEXEC_BOOT_PARAMS_SIZE 1536
307
308 +#define KEXEC_ARM_ATAGS_OFFSET 0x1000
309 +#define KEXEC_ARM_ZIMAGE_OFFSET 0x8000
310 +
311 #ifndef __ASSEMBLY__
312
313 struct kimage;
314 --
315 1.5.6.5
316