test_context_save_clobber.c 1.3 KB

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