1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <freertos/FreeRTOS.h>
5 #include <freertos/task.h>
6 #include <freertos/semphr.h>
7 
8 #include <unity.h>
9 #include <esp_spi_flash.h>
10 #include <esp_attr.h>
11 #include <esp_flash_encrypt.h>
12 
13 #include "../cache_utils.h"
14 
15 static QueueHandle_t result_queue;
16 
cache_test_task(void * arg)17 static IRAM_ATTR void cache_test_task(void *arg)
18 {
19     bool do_disable = (bool)arg;
20     bool result;
21     if(do_disable) {
22         spi_flash_disable_interrupts_caches_and_other_cpu();
23     }
24     result = spi_flash_cache_enabled();
25     if (do_disable) {
26         spi_flash_enable_interrupts_caches_and_other_cpu();
27     }
28 
29     TEST_ASSERT( xQueueSendToBack(result_queue, &result, 0) );
30     vTaskDelete(NULL);
31 }
32 
33 TEST_CASE("spi_flash_cache_enabled() works on both CPUs", "[spi_flash][esp_flash]")
34 {
35     result_queue = xQueueCreate(1, sizeof(bool));
36 
37     for(int cpu = 0; cpu < portNUM_PROCESSORS; cpu++) {
38         for(int disable = 0; disable <= 1; disable++) {
39             bool do_disable = disable;
40             bool result;
41             printf("Testing cpu %d disabled %d\n", cpu, do_disable);
42 
43             xTaskCreatePinnedToCore(cache_test_task, "cache_check_task",
44                                     2048, (void *)do_disable, configMAX_PRIORITIES-1, NULL, cpu);
45 
46             TEST_ASSERT( xQueueReceive(result_queue, &result, 2) );
47             TEST_ASSERT_EQUAL(!do_disable, result);
48         }
49     }
50 
51     vQueueDelete(result_queue);
52 }
53 
54 static const uint32_t s_in_rodata[] = { 0x12345678, 0xfedcba98 };
55 
cache_access_test_func(void * arg)56 static void IRAM_ATTR cache_access_test_func(void* arg)
57 {
58     spi_flash_disable_interrupts_caches_and_other_cpu();
59     volatile uint32_t* src = (volatile uint32_t*) s_in_rodata;
60     uint32_t v1 = src[0];
61     uint32_t v2 = src[1];
62     bool cache_enabled = spi_flash_cache_enabled();
63     spi_flash_enable_interrupts_caches_and_other_cpu();
64     printf("%d %x %x\n", cache_enabled, v1, v2);
65     vTaskDelete(NULL);
66 }
67 
68 // These tests works properly if they resets the chip with the
69 // "Cache disabled but cached memory region accessed" reason and the correct CPU is logged.
70 TEST_CASE("invalid access to cache raises panic (PRO CPU)", "[spi_flash][ignore]")
71 {
72     xTaskCreatePinnedToCore(&cache_access_test_func, "ia", 2048, NULL, 5, NULL, 0);
73     vTaskDelay(1000/portTICK_PERIOD_MS);
74 }
75 
76 #ifndef CONFIG_FREERTOS_UNICORE
77 
78 TEST_CASE("invalid access to cache raises panic (APP CPU)", "[spi_flash][ignore]")
79 {
80     xTaskCreatePinnedToCore(&cache_access_test_func, "ia", 2048, NULL, 5, NULL, 1);
81     vTaskDelay(1000/portTICK_PERIOD_MS);
82 }
83 
84 #endif
85