test_context_save_clobber.c 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. #include "sdkconfig.h"
  2. #include "unity.h"
  3. #include "esp_intr_alloc.h"
  4. #if defined(__XTENSA__) && CONFIG_FREERTOS_CORETIMER_0
  5. #include "xtensa/config/core-isa.h"
  6. #include "xtensa/hal.h"
  7. #if defined(XCHAL_HAVE_WINDOWED)
  8. /* Regression test for a0 register being corrupted in _xt_context_save.
  9. *
  10. * The idea in this test is to have a function which recursively calls itself
  11. * with call4, eventually filling up all the register windows. At that point,
  12. * it does some lengthy operation. If an interrupt occurs at that point, and
  13. * corrupts a0 register of one of the windows, this will cause an exception
  14. * when the recursive function returns.
  15. */
  16. /* See test_context_save_clober_func.S */
  17. extern void test_context_save_clober_func(void);
  18. static void int_timer_handler(void *arg)
  19. {
  20. xthal_set_ccompare(1, xthal_get_ccount() + 10000);
  21. (*(int*) arg)++;
  22. }
  23. TEST_CASE("context save doesn't corrupt return address register", "[freertos]")
  24. {
  25. /* set up an interrupt */
  26. intr_handle_t ih;
  27. int int_triggered = 0;
  28. TEST_ESP_OK(esp_intr_alloc(ETS_INTERNAL_TIMER1_INTR_SOURCE, 0, int_timer_handler, &int_triggered, &ih));
  29. xthal_set_ccompare(1, xthal_get_ccount() + 10000);
  30. /* fill all the windows and delay a bit, waiting for an interrupt to happen */
  31. test_context_save_clober_func();
  32. esp_intr_free(ih);
  33. TEST_ASSERT_GREATER_THAN(0, int_triggered);
  34. }
  35. #endif // XCHAL_HAVE_WINDOWED
  36. #endif // __XTENSA__ && CONFIG_FREERTOS_CORETIMER_0