Skip to content

Add traxmem helpers #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ target_include_directories(${ESP_STUB_LIB}
INTERFACE include
PRIVATE include/esp-stub-lib
)
# Public within the library
include_directories(include)
include_directories(include/esp-stub-lib)

# STUB_COMPILE_DEFS is optional definitions coming from the parent CMakeLists.txt
target_compile_definitions(${ESP_STUB_LIB} PRIVATE ${STUB_COMPILE_DEFS})
Expand Down
51 changes: 51 additions & 0 deletions include/esp-stub-lib/bit_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*/

#pragma once

#ifdef __cplusplus
extern "C" {
#endif

#ifndef BIT
#define BIT(nr) (1UL << (nr))
#endif

#ifndef BIT64
#define BIT64(nr) (1ULL << (nr))
#endif

#ifndef ALIGN_MASK
#define ALIGN_MASK(x, mask) \
({ \
typeof(mask) _mask = (mask); \
((x) + _mask) & ~_mask; \
})
#endif

#ifndef ALIGN_UP
#define ALIGN_UP(x, a) ALIGN_MASK(x, (typeof(x))(a) - 1)
#endif

#ifndef ALIGN_DOWN
#define ALIGN_DOWN(x, a) ((x) & ~((typeof(x))(a) - 1))
#endif

#ifndef IS_ALIGNED
#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0)
#endif

#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif

#ifndef MAX
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif

#ifdef __cplusplus
}
#endif
82 changes: 82 additions & 0 deletions include/esp-stub-lib/trax_mem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*/

#pragma once

#include <stdint.h>

#include <target/trax.h>
#include "bit_utils.h"

#define ERI_DEBUG_OFFSET 0x100000
#define ERI_TRAX_OFFSET (ERI_DEBUG_OFFSET + 0x0)
#define ERI_PERFMON_OFFSET (ERI_DEBUG_OFFSET + 0x1000)
#define ERI_TRAX_TRAXCTRL (ERI_TRAX_OFFSET + 0x4)
#define ERI_TRAX_TRIGGERPC (ERI_TRAX_OFFSET + 0x14)
#define ERI_TRAX_DELAYCNT (ERI_TRAX_OFFSET + 0x1C)

#define ERI_PERFMON_PM1 (ERI_PERFMON_OFFSET + 0x84) /* used in apptrace module to store CRC16 */

#define TRAXCTRL_TRSTP BIT(1) // Trace Stop. Make 1 to stop trace.
#define TRAXCTRL_TMEN BIT(7) // Trace Memory Enable. Always set.

#ifdef __cplusplus
extern "C" {
#endif

static inline uint32_t eri_read(int addr)
{
uint32_t ret;
asm volatile(
"RER %0,%1"
:"=r"(ret):"r"(addr)
);
return ret;
}

static inline void eri_write(int addr, uint32_t data)
{
asm volatile(
"WER %0,%1"
::"r"(data), "r"(addr)
);
}

/*
* Enable the TRAX memory. For ESP32 only.
*/
static inline void esp_stub_lib_trax_mem_enable(void)
{
stub_target_trax_mem_enable();
}

/*
* Select the memory block (0 or 1) to use.
*/
static inline void esp_stub_lib_trax_select_mem_block(int block)
{
stub_target_trax_select_mem_block(block);
}

/*
* Read a TRAX register using ERI.
*/
static inline uint32_t esp_stub_lib_trax_reg_read(int addr)
{
return eri_read(addr);
}

/*
* Write a TRAX register using ERI.
*/
static inline void esp_stub_lib_trax_reg_write(int addr, uint32_t data)
{
eri_write(addr, data);
}

#ifdef __cplusplus
}
#endif
88 changes: 88 additions & 0 deletions include/private/soc_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*/

#pragma once

#define ETS_UNCACHED_ADDR(addr) (addr)
#define ETS_CACHED_ADDR(addr) (addr)

// Base register read/write macros
#define REG_READ(_r) ({ \
(*(volatile uint32_t *)(_r)); \
})

#define REG_WRITE(_r, _v) do { \
(*(volatile uint32_t *)(_r)) = (_v); \
} while(0)

// Bit manipulation macros
#define REG_GET_BIT(_r, _b) ({ \
(REG_READ(_r) & (_b)); \
})

#define REG_SET_BIT(_r, _b) do { \
REG_WRITE(_r, REG_READ(_r) | (_b)); \
} while(0)

#define REG_CLR_BIT(_r, _b) do { \
REG_WRITE(_r, REG_READ(_r) & (~(_b))); \
} while(0)

#define REG_SET_BITS(_r, _b, _m) do { \
REG_WRITE(_r, (REG_READ(_r) & ~(_m)) | ((_b) & (_m))); \
} while(0)

// Field manipulation macros
#define REG_GET_FIELD(_r, _f) ({ \
((REG_READ(_r) >> (_f##_S)) & (_f##_V)); \
})

#define REG_SET_FIELD(_r, _f, _v) do { \
REG_WRITE(_r, (REG_READ(_r) & ~((_f##_V) << (_f##_S))) | (((_v) & (_f##_V)) << (_f##_S))); \
} while(0)

// Value field manipulation macros
#define VALUE_GET_FIELD(_r, _f) (((_r) >> (_f##_S)) & (_f))

#define VALUE_GET_FIELD2(_r, _f) (((_r) & (_f)) >> (_f##_S))

#define VALUE_SET_FIELD(_r, _f, _v) ((_r) = ((_r) & ~((_f) << (_f##_S))) | ((_v) << (_f##_S)))

#define VALUE_SET_FIELD2(_r, _f, _v) ((_r) = ((_r) & ~(_f)) | ((_v) << (_f##_S)))

// Field to value conversion macros
#define FIELD_TO_VALUE(_f, _v) (((_v) & (_f)) << _f##_S)

#define FIELD_TO_VALUE2(_f, _v) (((_v) << _f##_S) & (_f))

// Peripheral register macros
#define READ_PERI_REG(addr) REG_READ(ETS_UNCACHED_ADDR(addr))

#define WRITE_PERI_REG(addr, val) REG_WRITE(ETS_UNCACHED_ADDR(addr), (uint32_t)(val))

#define CLEAR_PERI_REG_MASK(reg, mask) do { \
WRITE_PERI_REG(reg, READ_PERI_REG(reg) & (~(mask))); \
} while(0)

#define SET_PERI_REG_MASK(reg, mask) do { \
WRITE_PERI_REG(reg, READ_PERI_REG(reg) | (mask)); \
} while(0)

#define GET_PERI_REG_MASK(reg, mask) ({ \
(READ_PERI_REG(reg) & (mask)); \
})

#define GET_PERI_REG_BITS(reg, hipos, lowpos) ({ \
((READ_PERI_REG(reg) >> (lowpos)) & ((1 << ((hipos) - (lowpos) + 1)) - 1)); \
})

#define SET_PERI_REG_BITS(reg, bit_map, value, shift) do { \
WRITE_PERI_REG(reg, (READ_PERI_REG(reg) & (~((bit_map) << (shift)))) | (((value) & (bit_map)) << (shift))); \
} while(0)

#define GET_PERI_REG_BITS2(reg, mask, shift) ({ \
((READ_PERI_REG(reg) >> (shift)) & (mask)); \
})
10 changes: 10 additions & 0 deletions include/target/trax.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*/

#pragma once

void stub_target_trax_mem_enable(void);
void stub_target_trax_select_mem_block(int block);
1 change: 1 addition & 0 deletions src/esp32/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
set(srcs
src/uart.c
src/flash.c
src/trax.c
)

add_library(${ESP_TARGET_LIB} STATIC ${srcs})
Expand Down
28 changes: 28 additions & 0 deletions src/esp32/src/trax.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*/

#include <stdint.h>

#include <private/soc_utils.h>

#include "soc/reg_base.h"

#define TRACEMEM_MUX_MODE_REG (DR_REG_DPORT_BASE + 0x070)
#define TRACEMEM_ENA_REG (DR_REG_DPORT_BASE + 0x074)
#define TRACEMEM_ENA_M (0x1)

#define TRACEMEM_MUX_BLK0_ONLY 1
#define TRACEMEM_MUX_BLK1_ONLY 2

void stub_target_trax_mem_enable(void)
{
WRITE_PERI_REG(TRACEMEM_ENA_REG, TRACEMEM_ENA_M);
}

void stub_target_trax_select_mem_block(int block)
{
WRITE_PERI_REG(TRACEMEM_MUX_MODE_REG, block ? TRACEMEM_MUX_BLK0_ONLY : TRACEMEM_MUX_BLK1_ONLY);
}
1 change: 1 addition & 0 deletions src/esp32s2/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
set(srcs
src/uart.c
src/flash.c
src/trax.c
)

add_library(${ESP_TARGET_LIB} STATIC ${srcs})
Expand Down
27 changes: 27 additions & 0 deletions src/esp32s2/src/trax.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*/

#include <stdint.h>

#include <bit_utils.h>
#include <private/soc_utils.h>

#include "soc/reg_base.h"

#define PMS_OCCUPY_3_REG (DR_REG_SENSITIVE_BASE + 0x0E0)

#define TRACEMEM_MUX_BLK0_NUM 19
#define TRACEMEM_MUX_BLK1_NUM 20

void stub_target_trax_mem_enable(void)
{
/* nothing to do for ESP32S2 */
}

void stub_target_trax_select_mem_block(int block)
{
WRITE_PERI_REG(PMS_OCCUPY_3_REG, block ? BIT(TRACEMEM_MUX_BLK0_NUM - 4) : BIT(TRACEMEM_MUX_BLK1_NUM - 4));
}
1 change: 1 addition & 0 deletions src/esp32s3/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
set(srcs
src/uart.c
src/flash.c
src/trax.c
)

add_library(${ESP_TARGET_LIB} STATIC ${srcs})
Expand Down
35 changes: 35 additions & 0 deletions src/esp32s3/src/trax.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*/

#include <stdint.h>

#include <bit_utils.h>
#include <private/soc_utils.h>

#include "soc/reg_base.h"

#define SENSITIVE_INTERNAL_SRAM_USAGE_2_REG (DR_REG_SENSITIVE_BASE + 0x18)

#define TRACEMEM_MUX_BLK0_NUM 22
#define TRACEMEM_MUX_BLK1_NUM 26

#define TRACEMEM_MUX_BLK_ALLOC(_n_) (((_n_) - 2UL) % 4UL)
#define TRACEMEM_CORE0_MUX_BLK_BITS(_n_) (BIT(((_n_) - 2UL) / 4UL) | (TRACEMEM_MUX_BLK_ALLOC(_n_) << 14))
#define TRACEMEM_CORE1_MUX_BLK_BITS(_n_) (BIT(7UL + ((_n_) - 2UL) / 4UL) | (TRACEMEM_MUX_BLK_ALLOC(_n_) << 16))

void stub_target_trax_mem_enable(void)
{
/* nothing to do for ESP32S3 */
}

void stub_target_trax_select_mem_block(int block)
{
uint32_t block_bits = block ? TRACEMEM_CORE0_MUX_BLK_BITS(TRACEMEM_MUX_BLK0_NUM)
: TRACEMEM_CORE0_MUX_BLK_BITS(TRACEMEM_MUX_BLK1_NUM);
block_bits |= block ? TRACEMEM_CORE1_MUX_BLK_BITS(TRACEMEM_MUX_BLK0_NUM)
: TRACEMEM_CORE1_MUX_BLK_BITS(TRACEMEM_MUX_BLK1_NUM);
WRITE_PERI_REG(SENSITIVE_INTERNAL_SRAM_USAGE_2_REG, block_bits);
}