[PATCH] ARM: Implement cpu_v7_reset.
Mika Westerberg
mika.westerberg at iki.fi
Mon Sep 6 13:24:02 EDT 2010
On Mon, Sep 06, 2010 at 08:58:25AM +0000, Per Fransson wrote:
>
> How do you run it via a 1-1 mapping? Do you call the physical address of
> cpu_reset() from machine_kexec() after calling setup_mm_for_reboot()? I.e.
>
> outer_inv_all();
> setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/
> (virt_to_phys(cpu_reset))(reboot_code_buffer_phys);
Yeah, I had something like that first but then I decided to isolate
this into proc-v7.S see [1]. I've tested that code on OMAP3430,
OMAP3530 and OMAP3630 and it works there. Unfortunately I don't
have any other v7 hardware except those :(
> In that case, we're relying on two pieces of code being identity mapped,
> cpu_v7_reset() and relocate_new_kernel(). I still promote limiting the scope of
> setup_mm_for_reboot() to the bare minimum, so as not to destroy the user-space
> mapping. If we set up a 1-1 around cpu_reset() for example, couldn't we idle
> away there until we are sure the MMU is off and *then* jump to the physical
> address of relocate_new_kernel() which wouldn't have to be 1-1 mapped?
I agree with you. Now that I've been playing with this kdump code,
it is indeed useful to be able to access memory of the panic'd
process.
> > "After a CP15 c1 instruction disables the MMU, the processor
> > flushes all following instructions in the pipeline. The
> > processor then begins refetching instructions and uses flat
> > address mapping. In flat address mapping, PA = VA."
> >
>
> If this is the case, the Qemu issue I mentioned here
>
> http://lists.infradead.org/pipermail/linux-arm-kernel/2010-July/019678.html
>
> wasn't so far off the mark after all =o)
This is exactly what is happening on Cortex-A8 (at least on those OMAPs which
I've been testing on).
Regards,
MW
[1] - cpu_v7_reset via 1:1 mappings
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 6a8506d..66c12c0 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -63,10 +63,53 @@ ENDPROC(cpu_v7_proc_fin)
*/
.align 5
ENTRY(cpu_v7_reset)
- mov pc, r0
+ /*
+ * ARM Cortex-A8 TRM chapter 6.4 says:
+ *
+ * After a CP15 c1 instruction disables the MMU, the processor
+ * flushes all following instructions in the pipeline. The processor
+ * then begins refetching instructions and uses flat address mapping.
+ * In flat address mapping, PA = VA.
+ *
+ * This means that in Cortex-A8 we need to disable the MMU through the
+ * identity mapped region.
+ */
+ mrc p15, 0, r5, c0, c0, 0 @ read main ID register
+ and r6, r5, #0xff000000 @ ARM?
+ teq r6, #0x41000000
+ bne __disable_mmu
+
+ mov r6, #0x0000ff00 @ check primary part number
+ orr r6, r6, #0x00f0 @ bits [15:4]
+ and r6, r6, r5
+
+ mov r5, #0xc000 @ is it Cortex-A8 (0xc080)?
+ orr r5, r5, #0x0080
+ teq r5, r6
+ bne __disable_mmu
+
+ /*
+ * This is Cortex-A8 so call via identity mapping.
+ */
+ ldr pc, =__virt_to_phys(__disable_mmu)
ENDPROC(cpu_v7_reset)
/*
+ * Disables the MMU and jumps into address given in r0.
+ */
+__disable_mmu:
+ mov ip, #0
+#ifdef CONFIG_MMU
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+#endif
+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
+ bic ip, ip, #0x000f @ ............wcam
+ bic ip, ip, #0x1100 @ ...i...s........
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
+ENDPROC(__disable_mmu)
+
+/*
* cpu_v7_do_idle()
*
* Idle the processor (eg, wait for interrupt).
More information about the linux-arm-kernel
mailing list