[Top] [All Lists]

Re: kexec - not happening on mipsel?

To: Ralf Baechle <>
Subject: Re: kexec - not happening on mipsel?
From: Nicolas Schichan <>
Date: Fri, 10 Aug 2007 18:57:15 +0200
Cc: Andrew Sharp <>,
In-reply-to: <>
Organization: Freebox
Original-recipient: rfc822;
References: <> <> <>
User-agent: KMail/1.9.6
On Thursday 09 August 2007 14:35:30 Ralf Baechle wrote:


> I recently noticed the kernel part was fairly broken, did (if ever) only
> work for 32-bit machines.  I fixed what I could but I don't have the
> necessary test setup.  See

My appologies for this, I should have taken more care about 64 bit portability 
when writing this code.

I have also been trying to address the cache problem in the kexec code. please 
see the attached patch.

I now use __flush_cache_all(), since flush_cache_all() is mostly a noop on r4k 
if cpu_has_dc_aliases evaluates to 0 (and it is the case on the MIPS cpu I 
have access to). To avoid caching problem in the relocation code, I disable 
the cache in KSEG0 (using the K0 field in CP0 CONFIG register) before jumping 
to the relocation code. I don't know how clean this solution is, but this 
avoids having to add non-portable cache flush code to relocate_kernel.S.


Signed-off-by: Nicolas Schichan <>

--- linux/arch/mips/kernel/machine_kexec.c      (revision 5939)
+++ linux/arch/mips/kernel/machine_kexec.c      (revision 5941)
@@ -50,8 +50,10 @@
        reboot_code_buffer =
          (unsigned long)page_address(image->control_code_page);
+       printk(KERN_INFO "reboot code is at %08lx\n", reboot_code_buffer);
        kexec_start_address = image->start;
-       kexec_indirection_page = phys_to_virt(image->head & PAGE_MASK);
+       kexec_indirection_page = (long)phys_to_virt(image->head & PAGE_MASK);
        memcpy((void*)reboot_code_buffer, relocate_new_kernel,
@@ -75,11 +77,17 @@
-       flush_icache_range(reboot_code_buffer,
-                          reboot_code_buffer + KEXEC_CONTROL_CODE_SIZE);
+       __flush_cache_all();
+       flush_icache_all();
-       printk("Will call new kernel at %08x\n", image->start);
-       printk("Bye ...\n");
-       flush_cache_all();
+       /*
+        * avoid cache operation related headache in
+        * relocate_kernel.S: disable caches in kseg0, the new kernel
+        * will take care to re-enable cache in kseg0.
+        */
+       change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+       printk(KERN_INFO "Will call new kernel at %08lx\n", image->start);
+       printk(KERN_INFO "Bye ...\n");
        ((void (*)(void))reboot_code_buffer)();

Nicolas Schichan

<Prev in Thread] Current Thread [Next in Thread>