Disable interrupts early, don't use get_timer() in vboot

After disabling the RO_NORMAL flag so that the RW BIOS was loaded instead of
staying in RO, occasionally (every 40 or 50 tries), we'd get a complete hang
at the dev-mode screen. The AP was getting stuck inside a call to
VbExSleepMs(), which was needed to calibrate the fast-running timer used by
VbExGetTimer().

The core of VbExSleepMs() is simply

	while (get_timer(start) < delay)
		udelay(100);

which seems pretty simple. get_timer() increments once per millisecond by
means of an interrupt. The first problem is that interrupts are not being
disabled by the RO firmware prior to invoking the RW firmware. That can't be
fixed with a RW update, so the next best thing is to disable them as soon as
possible in the RW firmware.

That cut the frequency of the hang by 50%, but didn't solve the problem
completely. udelay() doesn't rely on interrupts, but instead just busy-waits
on a free-running counter (the same one that triggers the millisecond
interrupt). Since get_timer() still has unresolved issues, we'll just
implement the VbExSleepMs() with a single call to udelay().

That seems to have fixed the problem.

BUG=chrome-os-partner:28461
BRANCH=firmware-link-2695.B
TEST=500 iterations of firmware_ConsecutiveBoot

After this change, all 500 reboot iterations succeed.

Change-Id: I363a769a6ca60f8c907b0b964f22bf59183f0a7c
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/199927
Reviewed-by: Stefan Reinauer <reinauer@chromium.org>
2 files changed