xtensa: Disable interrupts on entry to _Cstart

Zephyr isn't ready to handle interrupts yet, until the
threading/scheduler are set up and we make our first context switch.
This was a semi-hidden bug: only the timer interrupt would actually
get unmasked before the system was ready, and obviously would never
have time to fire a tick before the system completed initialization.
But a combination of system load and a new version of Qemu (which
seems to be more sensitive to non-deterministic timing glitchery) has
made this visible.  About 2-3% of the time when run under a full
sanitycheck, the qemu process will get swapped away for long enough
that the tick timer expires before _Cstart() has reached
enable_multithreading().

It looks like the original code was cut and pasted from another
implementation, which was expected to call into an "application"
main() routine that wanted interrupts ready.

Fixes #11182

(Note also that this code is not used for ESP-32, which has its own
startup path)

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
Andy Ross 2018-11-11 08:29:58 -08:00 committed by Anas Nashif
commit 0670ba6c92

View file

@ -56,8 +56,7 @@ _start:
*
* Assumptions on entry to _start:
* - low (level-one) and medium priority interrupts are disabled
* via PS.INTLEVEL and/or INTENABLE (PS.INTLEVEL is expected to
* be zeroed, to potentially enable them, before calling main)
* via PS.INTLEVEL and/or INTENABLE
* - C calling context not initialized:
* - PS not initialized
* - SP not initialized
@ -88,16 +87,16 @@ _start:
/*
* Now that sp (a1) is set, we can set PS as per the application (user
* vector mode, enable interrupts, enable window exceptions if
* vector mode, disable interrupts, enable window exceptions if
* applicable).
*/
#if XCHAL_HAVE_EXCEPTIONS
# ifdef __XTENSA_CALL0_ABI__
/* PS.WOE = 0, PS.UM = 1, PS.EXCM = 0, PS.INTLEVEL = 0 */
movi a3, PS_UM
/* PS.WOE = 0, PS.UM = 1, PS.EXCM = 0, PS.INTLEVEL = 15 */
movi a3, PS_UM|PS_INTLEVEL(15)
# else
/* PS.WOE = 1, PS.UM = 1, PS.EXCM = 0, PS.INTLEVEL = 0 */
movi a3, PS_UM|PS_WOE
/* PS.WOE = 1, PS.UM = 1, PS.EXCM = 0, PS.INTLEVEL = 15 */
movi a3, PS_UM|PS_WOE|PS_INTLEVEL(15)
# endif
wsr a3, PS
rsync