tegra124: When leaving the bootblock/AVP, really stop the AVP.

We'd been stopping the AVP by calling hlt, but this just puts it into a loop
which it busily executes forever. If the memory the loop is in is replaced,
however, the AVP will race off and do something random. It turns out that it
was writing the early parts of the rom stage into memory on top of the kernel
as it ran, either by coincidence or because it had rebooted and was actually
reloading the stage into memory.

Many thanks to Hung-Te for determining what was being overwritten by what
which helped determine who was doing the overwriting.

BUG=None
TEST=Before this change, booting in normal mode would cause the kernel to
behave strangely, often crashing. With this change, the kernel seems to boot
fine in normal mode.
BRANCH=None

Change-Id: I292c039c28691387e72386d2a9321c29437076ed
Signed-off-by: Gabe Black <gabeblack@google.com>
Reviewed-on: https://chromium-review.googlesource.com/177086
Reviewed-by: Julius Werner <jwerner@chromium.org>
Tested-by: Gabe Black <gabeblack@chromium.org>
Commit-Queue: Gabe Black <gabeblack@chromium.org>
This commit is contained in:
Gabe Black 2013-11-15 16:29:07 -08:00 committed by chrome-internal-fetch
commit 06c10df889
3 changed files with 11 additions and 1 deletions

View file

@ -63,5 +63,5 @@ void main(void)
if (entry)
clock_cpu0_config_and_reset(entry);
hlt();
clock_halt_avp();
}

View file

@ -372,6 +372,15 @@ void clock_cpu0_config_and_reset(void *entry)
&clk_rst->rst_cpug_cmplx_clr);
}
void clock_halt_avp(void)
{
for (;;) {
write32(FLOW_EVENT_JTAG | FLOW_EVENT_LIC_IRQ |
FLOW_EVENT_GIC_IRQ | FLOW_MODE_WAITEVENT,
&flow->halt_cop_events);
}
}
void clock_init(void)
{
u32 osc = clock_get_osc_bits();

View file

@ -248,6 +248,7 @@ int clock_get_osc_khz(void);
void clock_early_uart(void);
void clock_external_output(int clk_id);
void clock_cpu0_config_and_reset(void * entry);
void clock_halt_avp(void);
void clock_enable_clear_reset(u32 l, u32 h, u32 u, u32 v, u32 w, u32 x);
void clock_init(void);
void clock_init_arm_generic_timer(void);