test_xtensa_loadstore_handler.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /*
  7. Test for LoadStore exception handlers. This test performs unaligned load and store in 32bit aligned addresses
  8. */
  9. #include <esp_types.h>
  10. #include <stdio.h>
  11. #include <esp_heap_caps.h>
  12. #include "sdkconfig.h"
  13. #include "esp_random.h"
  14. #include "unity.h"
  15. #if CONFIG_IDF_TARGET_ARCH_XTENSA
  16. #include "freertos/xtensa_api.h"
  17. #ifdef CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY
  18. TEST_CASE("LoadStore Exception handler", "[freertos]")
  19. {
  20. int32_t val0 = 0xDEADBEEF;
  21. int32_t val1 = 0xBBAA9988;
  22. int32_t val2 = 0x77665544;
  23. int32_t val3 = 0x33221100;
  24. int8_t val8_0 = val0 & 0xff;
  25. int8_t val8_1 = val1 & 0xff;
  26. int8_t val8_2 = val2 & 0xff;
  27. int8_t val8_3 = val3 & 0xff;
  28. int16_t val16_0 = val0 & 0xffff;
  29. int16_t val16_1 = val1 & 0xffff;
  30. int16_t val16_2 = val2 & 0xffff;
  31. int16_t val16_3 = val3 & 0xffff;
  32. uint32_t largest_free = heap_caps_get_largest_free_block(MALLOC_CAP_IRAM_8BIT);
  33. int8_t *arr = heap_caps_malloc(largest_free * sizeof(int8_t), MALLOC_CAP_IRAM_8BIT);
  34. TEST_ASSERT(arr != NULL);
  35. int8_t *arr8 = arr;
  36. int16_t *arr16 = (int16_t *)arr;
  37. int32_t *arr32 = (int32_t *)arr;
  38. for (int i = 0; i < 1024; i++) {
  39. // LoadStoreError
  40. uint32_t offset = esp_random() % (largest_free - 20);
  41. uint32_t offset8, offset16, offset32;
  42. // Get word aligned offset
  43. offset8 = offset & ~3;
  44. offset16 = offset8 / 2;
  45. offset32 = offset8 / 4;
  46. arr8[offset8] = val8_0;
  47. arr8[offset8+1] = val8_1;
  48. arr8[offset8+2] = val8_2;
  49. arr8[offset8+3] = val8_3;
  50. // Just to make sure compiler doesn't read stale data
  51. asm volatile("memw\n");
  52. TEST_ASSERT_EQUAL(val8_0, arr8[offset8]);
  53. TEST_ASSERT_EQUAL(val8_1, arr8[offset8+1]);
  54. TEST_ASSERT_EQUAL(val8_2, arr8[offset8+2]);
  55. TEST_ASSERT_EQUAL(val8_3, arr8[offset8+3]);
  56. arr16[offset16] = val16_0;
  57. arr16[offset16+1] = val16_1;
  58. arr16[offset16+2] = val16_2;
  59. arr16[offset16+3] = val16_3;
  60. // Just to make sure compiler doesn't read stale data
  61. asm volatile("memw\n");
  62. TEST_ASSERT_EQUAL(val16_0, arr16[offset16]);
  63. TEST_ASSERT_EQUAL(val16_1, arr16[offset16+1]);
  64. TEST_ASSERT_EQUAL(val16_2, arr16[offset16+2]);
  65. TEST_ASSERT_EQUAL(val16_3, arr16[offset16+3]);
  66. // LoadStoreAlignement Error
  67. // Check that it doesn't write to adjacent bytes
  68. int8_t *ptr8_0 = (void *)&arr8[offset8];
  69. int8_t *ptr8_1 = (void *)&arr8[offset8] + 5;
  70. int8_t *ptr8_2 = (void *)&arr8[offset8] + 10;
  71. int8_t *ptr8_3 = (void *)&arr8[offset8] + 15;
  72. *ptr8_0 = 0x73;
  73. *ptr8_1 = 0x73;
  74. *ptr8_2 = 0x73;
  75. *ptr8_3 = 0x73;
  76. int16_t *ptr16_0 = (void *)&arr16[offset16] + 1;
  77. int16_t *ptr16_1 = (void *)&arr16[offset16] + 3;
  78. *ptr16_0 = val16_0;
  79. *ptr16_1 = val16_1;
  80. // Just to make sure compiler doesn't read stale data
  81. asm volatile("memw\n");
  82. TEST_ASSERT_EQUAL(val16_0, *ptr16_0);
  83. TEST_ASSERT_EQUAL(0x73, *ptr8_0);
  84. TEST_ASSERT_EQUAL(val16_1, *ptr16_1);
  85. TEST_ASSERT_EQUAL(0x73, *ptr8_1);
  86. int32_t *ptr32_0 = (void *)&arr32[offset32] + 1;
  87. int32_t *ptr32_1 = (void *)&arr32[offset32] + 6;
  88. int32_t *ptr32_2 = (void *)&arr32[offset32] + 11;
  89. *ptr32_0 = val0;
  90. *ptr32_1 = val1;
  91. *ptr32_2 = val2;
  92. // Just to make sure compiler doesn't read stale data
  93. asm volatile ("memw");
  94. TEST_ASSERT_EQUAL(0x73, *ptr8_0);
  95. TEST_ASSERT_EQUAL(val0, *ptr32_0);
  96. TEST_ASSERT_EQUAL(0x73, *ptr8_1);
  97. TEST_ASSERT_EQUAL(val1, *ptr32_1);
  98. TEST_ASSERT_EQUAL(0x73, *ptr8_2);
  99. TEST_ASSERT_EQUAL(val2, *ptr32_2);
  100. TEST_ASSERT_EQUAL(0x73, *ptr8_3);
  101. }
  102. TEST_ASSERT_TRUE(heap_caps_check_integrity_all(true));
  103. heap_caps_free(arr);
  104. }
  105. #endif // CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY
  106. #endif // CONFIG_IDF_TARGET_ARCH_XTENSA