v6 software reset fails on 1176

Will Deacon will.deacon at arm.com
Tue Aug 23 13:47:36 EDT 2011


On Tue, Aug 23, 2011 at 06:34:10PM +0100, Jamie Iles wrote:
> On Tue, Aug 23, 2011 at 06:09:55PM +0100, Will Deacon wrote:
> > Ok. How are you calling cpu_v6_reset? If you call it via arch_reset from
> > arm_machine_restart then there should be an identity mapping in place, so
> > you need to ensure that the reset code is called via this mapping in your
> > implementation of arch_reset.
> 
> Yes, this is being called from the arch_reset hook.

Good, good.

> > Unfortunately, the current flat mapping only covers userspace, so it relies
> > on the physical address of the reset code not aliasing with the kernel virtual
> > addresses.
> 
> The reset code is in our bootrom (at physical address 0xffff0000).

Sorry, I was referring to cpu_reset rather than the code that it then jumps
to (which can be anywhere).

> > With modern CPUs, you can't rely on characteristics of the pipeline to play
> > tricks like this. Instead, you need to ensure that the reset code is
> > executed with a 1:1 mapping.
> 
> Hmm, I don't really understand this - the cpu_v6_reset code turns off 
> the MMU, then issues an ISB.  So for as long as cpu_v6_reset is 
> executing in the kernel virtual address space I don't see how it can 
> ever fetch the "mov pc, r0" instruction after the ISB without those 
> instructions living in the 1:1 mapping?

You need to make sure you call cpu_reset by jumping to its *physical*
address. If that happens to alias with the virtual address of the kernel, it
won't currently work but I have a solution to this in my kexec branch.

You can do something like:

	typedef void (*phys_reset_t)(unsigned long);

	phys_reset = (phys_reset_t)virt_to_phys(cpu_reset);
	phys_reset(0xffff0000);

The problem with not having an ISB is that you can't guarantee at which point
the MMU is no longer active, so you're really walking on a tightrope in
that case.

Will



More information about the linux-arm-kernel mailing list