1 /*
2  Tests for D/IRAM support in heap capability allocator
3 */
4 
5 #include <esp_types.h>
6 #include <stdio.h>
7 #include "unity.h"
8 #include "esp_heap_caps.h"
9 #include "soc/soc_memory_layout.h"
10 
11 #define ALLOC_SZ 1024
12 
malloc_block_diram(uint32_t caps)13 static void *malloc_block_diram(uint32_t caps)
14 {
15     void *attempts[256] = { 0 }; // Allocate up to 256 ALLOC_SZ blocks to exhaust all non-D/IRAM memory temporarily
16     int count = 0;
17     void *result;
18 
19     while(count < sizeof(attempts)/sizeof(void *)) {
20         result = heap_caps_malloc(ALLOC_SZ, caps);
21         TEST_ASSERT_NOT_NULL_MESSAGE(result, "not enough free heap to perform test");
22 
23         if (esp_ptr_in_diram_dram(result) || esp_ptr_in_diram_iram(result)) {
24             break;
25         }
26 
27         attempts[count] = result;
28         result = NULL;
29         count++;
30     }
31 
32     for (int i = 0; i < count; i++) {
33         free(attempts[i]);
34     }
35 
36     TEST_ASSERT_NOT_NULL_MESSAGE(result, "not enough D/IRAM memory is free");
37     return result;
38 }
39 
40 TEST_CASE("Allocate D/IRAM as DRAM", "[heap]")
41 {
42     uint32_t *dram = malloc_block_diram(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
43 
44     for (int i = 0; i < ALLOC_SZ / sizeof(uint32_t); i++) {
45         uint32_t v = i + 0xAAAA;
46         dram[i] = v;
47         volatile uint32_t *iram = esp_ptr_diram_dram_to_iram(dram + i);
48         TEST_ASSERT_EQUAL(v, dram[i]);
49         TEST_ASSERT_EQUAL(v, *iram);
50         *iram = UINT32_MAX;
51         TEST_ASSERT_EQUAL(UINT32_MAX, *iram);
52         TEST_ASSERT_EQUAL(UINT32_MAX, dram[i]);
53     }
54 
55     free(dram);
56 }
57 
58 TEST_CASE("Allocate D/IRAM as IRAM", "[heap]")
59 {
60     uint32_t *iram = malloc_block_diram(MALLOC_CAP_EXEC);
61 
62     for (int i = 0; i < ALLOC_SZ / sizeof(uint32_t); i++) {
63         uint32_t v = i + 0xEEE;
64         iram[i] = v;
65         volatile uint32_t *dram = esp_ptr_diram_iram_to_dram(iram + i);
66         TEST_ASSERT_EQUAL_HEX32(v, iram[i]);
67         TEST_ASSERT_EQUAL_HEX32(v, *dram);
68         *dram = UINT32_MAX;
69         TEST_ASSERT_EQUAL_HEX32(UINT32_MAX, *dram);
70         TEST_ASSERT_EQUAL_HEX32(UINT32_MAX, iram[i]);
71     }
72 
73     free(iram);
74 }
75