Skip to content

Commit f4f78b4

Browse files
committed
feat: add xtensa trax memory helpers
1 parent 1451a70 commit f4f78b4

File tree

10 files changed

+333
-0
lines changed

10 files changed

+333
-0
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ target_include_directories(${ESP_STUB_LIB}
3434
INTERFACE include
3535
PRIVATE include/esp-stub-lib
3636
)
37+
# Public within the library
3738
include_directories(include)
39+
include_directories(include/esp-stub-lib)
3840

3941
# STUB_COMPILE_DEFS is optional definitions coming from the parent CMakeLists.txt
4042
target_compile_definitions(${ESP_STUB_LIB} PRIVATE ${STUB_COMPILE_DEFS})

include/esp-stub-lib/bit_utils.h

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0 OR MIT
5+
*/
6+
7+
#pragma once
8+
9+
#ifdef __cplusplus
10+
extern "C" {
11+
#endif
12+
13+
#ifndef BIT
14+
#define BIT(nr) (1UL << (nr))
15+
#endif
16+
17+
#ifndef BIT64
18+
#define BIT64(nr) (1ULL << (nr))
19+
#endif
20+
21+
#ifndef ALIGN_MASK
22+
#define ALIGN_MASK(x, mask) \
23+
({ \
24+
typeof(mask) _mask = (mask); \
25+
((x) + _mask) & ~_mask; \
26+
})
27+
#endif
28+
29+
#ifndef ALIGN_UP
30+
#define ALIGN_UP(x, a) ALIGN_MASK(x, (typeof(x))(a) - 1)
31+
#endif
32+
33+
#ifndef ALIGN_DOWN
34+
#define ALIGN_DOWN(x, a) ((x) & ~((typeof(x))(a) - 1))
35+
#endif
36+
37+
#ifndef IS_ALIGNED
38+
#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0)
39+
#endif
40+
41+
#ifndef MIN
42+
#define MIN(a, b) ((a) < (b) ? (a) : (b))
43+
#endif
44+
45+
#ifndef MAX
46+
#define MAX(a, b) ((a) > (b) ? (a) : (b))
47+
#endif
48+
49+
#ifdef __cplusplus
50+
}
51+
#endif

include/esp-stub-lib/trax_mem.h

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0 OR MIT
5+
*/
6+
7+
#pragma once
8+
9+
#include <stdint.h>
10+
11+
#define ERI_DEBUG_OFFSET 0x100000
12+
#define ERI_TRAX_OFFSET (ERI_DEBUG_OFFSET + 0x0)
13+
#define ERI_TRAX_TRAXCTRL (ERI_TRAX_OFFSET + 0x4)
14+
#define ERI_TRAX_TRIGGERPC (ERI_TRAX_OFFSET + 0x14)
15+
#define ERI_TRAX_DELAYCNT (ERI_TRAX_OFFSET + 0x1C)
16+
17+
#define TRAXCTRL_TRSTP (1 << 1) // Trace Stop. Make 1 to stop trace.
18+
#define TRAXCTRL_TMEN (1 << 7) // Trace Memory Enable. Always set.
19+
20+
#ifdef __cplusplus
21+
extern "C" {
22+
#endif
23+
24+
extern void stub_target_trax_mem_enable(void);
25+
extern void stub_target_trax_select_mem_block(int block);
26+
27+
static inline uint32_t eri_read(int addr)
28+
{
29+
uint32_t ret;
30+
asm volatile(
31+
"RER %0,%1"
32+
:"=r"(ret):"r"(addr)
33+
);
34+
return ret;
35+
}
36+
37+
static inline void eri_write(int addr, uint32_t data)
38+
{
39+
asm volatile(
40+
"WER %0,%1"
41+
::"r"(data), "r"(addr)
42+
);
43+
}
44+
45+
/*
46+
* Enable the TRAX memory. For ESP32 only.
47+
*/
48+
static inline void esp_stub_lib_trax_mem_enable(void)
49+
{
50+
stub_target_trax_mem_enable();
51+
}
52+
53+
/*
54+
* Select the memory block (0 or 1) to use.
55+
*/
56+
static inline void esp_stub_lib_trax_select_mem_block(int block)
57+
{
58+
stub_target_trax_select_mem_block(block);
59+
}
60+
61+
/*
62+
* Read a TRAX register using ERI.
63+
*/
64+
static inline uint32_t esp_stub_lib_trax_reg_read(int addr)
65+
{
66+
return eri_read(addr);
67+
}
68+
69+
/*
70+
* Write a TRAX register using ERI.
71+
*/
72+
static inline void esp_stub_lib_trax_reg_write(int addr, uint32_t data)
73+
{
74+
eri_write(addr, data);
75+
}
76+
77+
#ifdef __cplusplus
78+
}
79+
#endif

include/private/soc_utils.h

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0 OR MIT
5+
*/
6+
7+
#pragma once
8+
9+
#define ETS_UNCACHED_ADDR(addr) (addr)
10+
#define ETS_CACHED_ADDR(addr) (addr)
11+
12+
//write value to register
13+
#define REG_WRITE(_r, _v) do { \
14+
(*(volatile uint32_t *)(_r)) = (_v); \
15+
} while(0)
16+
17+
//read value from register
18+
#define REG_READ(_r) ({ \
19+
(*(volatile uint32_t *)(_r)); \
20+
})
21+
22+
//get bit or get bits from register
23+
#define REG_GET_BIT(_r, _b) ({ \
24+
(*(volatile uint32_t*)(_r) & (_b)); \
25+
})
26+
27+
//set bit or set bits to register
28+
#define REG_SET_BIT(_r, _b) do { \
29+
*(volatile uint32_t*)(_r) = (*(volatile uint32_t*)(_r)) | (_b); \
30+
} while(0)
31+
32+
//clear bit or clear bits of register
33+
#define REG_CLR_BIT(_r, _b) do { \
34+
*(volatile uint32_t*)(_r) = (*(volatile uint32_t*)(_r)) & (~(_b)); \
35+
} while(0)
36+
37+
//set bits of register controlled by mask
38+
#define REG_SET_BITS(_r, _b, _m) do { \
39+
*(volatile uint32_t*)(_r) = (*(volatile uint32_t*)(_r) & ~(_m)) | ((_b) & (_m)); \
40+
} while(0)
41+
42+
//get field from register, uses field _S & _V to determine mask
43+
#define REG_GET_FIELD(_r, _f) ({ \
44+
((REG_READ(_r) >> (_f##_S)) & (_f##_V)); \
45+
})
46+
47+
//set field of a register from variable, uses field _S & _V to determine mask
48+
#define REG_SET_FIELD(_r, _f, _v) do { \
49+
REG_WRITE((_r),((REG_READ(_r) & ~((_f##_V) << (_f##_S)))|(((_v) & (_f##_V))<<(_f##_S)))); \
50+
} while(0)
51+
52+
//get field value from a variable, used when _f is not left shifted by _f##_S
53+
#define VALUE_GET_FIELD(_r, _f) (((_r) >> (_f##_S)) & (_f))
54+
55+
//get field value from a variable, used when _f is left shifted by _f##_S
56+
#define VALUE_GET_FIELD2(_r, _f) (((_r) & (_f))>> (_f##_S))
57+
58+
//set field value to a variable, used when _f is not left shifted by _f##_S
59+
#define VALUE_SET_FIELD(_r, _f, _v) ((_r)=(((_r) & ~((_f) << (_f##_S)))|((_v)<<(_f##_S))))
60+
61+
//set field value to a variable, used when _f is left shifted by _f##_S
62+
#define VALUE_SET_FIELD2(_r, _f, _v) ((_r)=(((_r) & ~(_f))|((_v)<<(_f##_S))))
63+
64+
//generate a value from a field value, used when _f is not left shifted by _f##_S
65+
#define FIELD_TO_VALUE(_f, _v) (((_v)&(_f))<<_f##_S)
66+
67+
//generate a value from a field value, used when _f is left shifted by _f##_S
68+
#define FIELD_TO_VALUE2(_f, _v) (((_v)<<_f##_S) & (_f))
69+
70+
//read value from register
71+
#define READ_PERI_REG(addr) ({ \
72+
(*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr))); \
73+
})
74+
75+
//write value to register
76+
#define WRITE_PERI_REG(addr, val) do { \
77+
(*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr))) = (uint32_t)(val); \
78+
} while(0)
79+
80+
//clear bits of register controlled by mask
81+
#define CLEAR_PERI_REG_MASK(reg, mask) do { \
82+
WRITE_PERI_REG((reg), (READ_PERI_REG(reg)&(~(mask)))); \
83+
} while(0)
84+
85+
//set bits of register controlled by mask
86+
#define SET_PERI_REG_MASK(reg, mask) do { \
87+
WRITE_PERI_REG((reg), (READ_PERI_REG(reg)|(mask))); \
88+
} while(0)
89+
90+
//get bits of register controlled by mask
91+
#define GET_PERI_REG_MASK(reg, mask) ({ \
92+
(READ_PERI_REG(reg) & (mask)); \
93+
})
94+
95+
//get bits of register controlled by highest bit and lowest bit
96+
#define GET_PERI_REG_BITS(reg, hipos,lowpos) ({ \
97+
((READ_PERI_REG(reg)>>(lowpos))&((1<<((hipos)-(lowpos)+1))-1)); \
98+
})
99+
100+
//set bits of register controlled by mask and shift
101+
#define SET_PERI_REG_BITS(reg,bit_map,value,shift) do { \
102+
WRITE_PERI_REG((reg),(READ_PERI_REG(reg)&(~((bit_map)<<(shift))))|(((value) & (bit_map))<<(shift)) ); \
103+
} while(0)
104+
105+
//get field of register
106+
#define GET_PERI_REG_BITS2(reg, mask,shift) ({ \
107+
((READ_PERI_REG(reg)>>(shift))&(mask)); \
108+
})

src/esp32/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
set(srcs
22
src/uart.c
33
src/flash.c
4+
src/trax.c
45
)
56

67
add_library(${ESP_TARGET_LIB} STATIC ${srcs})

src/esp32/src/trax.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0 OR MIT
5+
*/
6+
7+
#include <stdint.h>
8+
9+
#include <private/soc_utils.h>
10+
11+
#include "reg_base.h"
12+
13+
#define TRACEMEM_MUX_MODE_REG (DR_REG_DPORT_BASE + 0x070)
14+
#define TRACEMEM_ENA_REG (DR_REG_DPORT_BASE + 0x074)
15+
#define TRACEMEM_ENA_M (0x1)
16+
17+
#define TRACEMEM_MUX_BLK0_ONLY 1
18+
#define TRACEMEM_MUX_BLK1_ONLY 2
19+
20+
void stub_target_trax_mem_enable(void)
21+
{
22+
WRITE_PERI_REG(TRACEMEM_ENA_REG, TRACEMEM_ENA_M);
23+
}
24+
25+
void stub_target_trax_select_mem_block(int block)
26+
{
27+
WRITE_PERI_REG(TRACEMEM_MUX_MODE_REG, block ? TRACEMEM_MUX_BLK0_ONLY : TRACEMEM_MUX_BLK1_ONLY);
28+
}

src/esp32s2/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
set(srcs
22
src/uart.c
33
src/flash.c
4+
src/trax.c
45
)
56

67
add_library(${ESP_TARGET_LIB} STATIC ${srcs})

src/esp32s2/src/trax.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0 OR MIT
5+
*/
6+
7+
#include <stdint.h>
8+
9+
#include <bit_utils.h>
10+
#include <private/soc_utils.h>
11+
12+
#include "reg_base.h"
13+
14+
#define PMS_OCCUPY_3_REG (DR_REG_SENSITIVE_BASE + 0x0E0)
15+
16+
#define TRACEMEM_MUX_BLK0_NUM 19
17+
#define TRACEMEM_MUX_BLK1_NUM 20
18+
19+
void stub_target_trax_mem_enable(void)
20+
{
21+
/* nothing to do for ESP32S2 */
22+
}
23+
24+
void stub_target_trax_select_mem_block(int block)
25+
{
26+
WRITE_PERI_REG(PMS_OCCUPY_3_REG, block ? BIT(TRACEMEM_MUX_BLK0_NUM - 4) : BIT(TRACEMEM_MUX_BLK1_NUM - 4));
27+
}

src/esp32s3/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
set(srcs
22
src/uart.c
33
src/flash.c
4+
src/trax.c
45
)
56

67
add_library(${ESP_TARGET_LIB} STATIC ${srcs})

src/esp32s3/src/trax.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0 OR MIT
5+
*/
6+
7+
#include <stdint.h>
8+
9+
#include <bit_utils.h>
10+
#include <private/soc_utils.h>
11+
12+
#include "reg_base.h"
13+
14+
#define SENSITIVE_INTERNAL_SRAM_USAGE_2_REG (DR_REG_SENSITIVE_BASE + 0x18)
15+
16+
#define TRACEMEM_MUX_BLK0_NUM 22
17+
#define TRACEMEM_MUX_BLK1_NUM 26
18+
19+
#define TRACEMEM_MUX_BLK_ALLOC(_n_) (((_n_) - 2UL) % 4UL)
20+
#define TRACEMEM_CORE0_MUX_BLK_BITS(_n_) (BIT(((_n_) - 2UL) / 4UL) | (TRACEMEM_MUX_BLK_ALLOC(_n_) << 14))
21+
#define TRACEMEM_CORE1_MUX_BLK_BITS(_n_) (BIT(7UL + ((_n_) - 2UL) / 4UL) | (TRACEMEM_MUX_BLK_ALLOC(_n_) << 16))
22+
23+
void stub_target_trax_mem_enable(void)
24+
{
25+
/* nothing to do for ESP32S3 */
26+
}
27+
28+
void stub_target_trax_select_mem_block(int block)
29+
{
30+
uint32_t block_bits = block ? TRACEMEM_CORE0_MUX_BLK_BITS(TRACEMEM_MUX_BLK0_NUM)
31+
: TRACEMEM_CORE0_MUX_BLK_BITS(TRACEMEM_MUX_BLK1_NUM);
32+
block_bits |= block ? TRACEMEM_CORE1_MUX_BLK_BITS(TRACEMEM_MUX_BLK0_NUM)
33+
: TRACEMEM_CORE1_MUX_BLK_BITS(TRACEMEM_MUX_BLK1_NUM);
34+
WRITE_PERI_REG(SENSITIVE_INTERNAL_SRAM_USAGE_2_REG, block_bits);
35+
}

0 commit comments

Comments
 (0)