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
The core of VbExSleepMs() is simply
while (get_timer(start) < delay)
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.
TEST=500 iterations of firmware_ConsecutiveBoot
After this change, all 500 reboot iterations succeed.
Signed-off-by: Bill Richardson <firstname.lastname@example.org>
Reviewed-by: Stefan Reinauer <email@example.com>
(cherry picked from commit bf05d82b2132acbfed47e8bb3c616bb929fbfa39)
Signed-off-by: Duncan Laurie <firstname.lastname@example.org>
Reviewed-by: Shawn N <email@example.com>
2 files changed