Files
esp-idf/components/riscv/include/riscv/rvruntime-frames.h
Omar Chebib 55acc5e5e7 feat(riscv): add support for PIE coprocessor and HWLP feature
FreeRTOS tasks may now freely use the PIE coprocessor and HWLP feature.
Just like the FPU, usiing these coprocessors result in the task being pinned
to the core it is currently running on.
2024-05-20 10:47:58 +08:00

257 lines
9.8 KiB
C

/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __RVRUNTIME_FRAMES_H__
#define __RVRUNTIME_FRAMES_H__
#include "soc/soc_caps.h"
/* Align a value up to nearest n-byte boundary, where n is a power of 2. */
#define ALIGNUP(n, val) (((val) + (n) - 1) & -(n))
#ifdef STRUCT_BEGIN
#undef STRUCT_BEGIN
#undef STRUCT_FIELD
#undef STRUCT_AFIELD
#undef STRUCT_END
#endif
#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
#ifdef __clang__
#define STRUCT_BEGIN .set RV_STRUCT_OFFSET, 0
#define STRUCT_FIELD(ctype,size,asname,name) .set asname, RV_STRUCT_OFFSET; .set RV_STRUCT_OFFSET, asname + size
#define STRUCT_AFIELD(ctype,size,asname,name,n) .set asname, RV_STRUCT_OFFSET;\
.set RV_STRUCT_OFFSET, asname + (size)*(n);
#define STRUCT_END(sname) .set sname##Size, RV_STRUCT_OFFSET;
#else // __clang__
#define STRUCT_BEGIN .pushsection .text; .struct 0
#define STRUCT_FIELD(ctype,size,asname,name) asname: .space size
#define STRUCT_AFIELD(ctype,size,asname,name,n) asname: .space (size)*(n)
#define STRUCT_END(sname) sname##Size:; .popsection
#endif // __clang__
#else
#define STRUCT_BEGIN typedef struct {
#define STRUCT_FIELD(ctype,size,asname,name) ctype name;
#define STRUCT_AFIELD(ctype,size,asname,name,n) ctype name[n];
#define STRUCT_END(sname) } sname;
#endif
/*
-------------------------------------------------------------------------------
INTERRUPT/EXCEPTION STACK FRAME FOR A EXCEPTION OR NESTED INTERRUPT
-------------------------------------------------------------------------------
*/
STRUCT_BEGIN
STRUCT_FIELD (long, 4, RV_STK_MEPC, mepc) /* Machine Exception Program Counter */
STRUCT_FIELD (long, 4, RV_STK_RA, ra) /* Return address */
STRUCT_FIELD (long, 4, RV_STK_SP, sp) /* Stack pointer */
STRUCT_FIELD (long, 4, RV_STK_GP, gp) /* Global pointer */
STRUCT_FIELD (long, 4, RV_STK_TP, tp) /* Thread pointer */
STRUCT_FIELD (long, 4, RV_STK_T0, t0) /* Temporary/alternate link register */
STRUCT_FIELD (long, 4, RV_STK_T1, t1) /* t1-2: Temporaries */
STRUCT_FIELD (long, 4, RV_STK_T2, t2)
STRUCT_FIELD (long, 4, RV_STK_S0, s0) /* Saved register/frame pointer */
STRUCT_FIELD (long, 4, RV_STK_S1, s1) /* Saved register */
STRUCT_FIELD (long, 4, RV_STK_A0, a0) /* a0-1: Function arguments/return address */
STRUCT_FIELD (long, 4, RV_STK_A1, a1)
STRUCT_FIELD (long, 4, RV_STK_A2, a2) /* a2-7: Function arguments */
STRUCT_FIELD (long, 4, RV_STK_A3, a3)
STRUCT_FIELD (long, 4, RV_STK_A4, a4)
STRUCT_FIELD (long, 4, RV_STK_A5, a5)
STRUCT_FIELD (long, 4, RV_STK_A6, a6)
STRUCT_FIELD (long, 4, RV_STK_A7, a7)
STRUCT_FIELD (long, 4, RV_STK_S2, s2) /* s2-11: Saved registers */
STRUCT_FIELD (long, 4, RV_STK_S3, s3)
STRUCT_FIELD (long, 4, RV_STK_S4, s4)
STRUCT_FIELD (long, 4, RV_STK_S5, s5)
STRUCT_FIELD (long, 4, RV_STK_S6, s6)
STRUCT_FIELD (long, 4, RV_STK_S7, s7)
STRUCT_FIELD (long, 4, RV_STK_S8, s8)
STRUCT_FIELD (long, 4, RV_STK_S9, s9)
STRUCT_FIELD (long, 4, RV_STK_S10, s10)
STRUCT_FIELD (long, 4, RV_STK_S11, s11)
STRUCT_FIELD (long, 4, RV_STK_T3, t3) /* t3-6: Temporaries */
STRUCT_FIELD (long, 4, RV_STK_T4, t4)
STRUCT_FIELD (long, 4, RV_STK_T5, t5)
STRUCT_FIELD (long, 4, RV_STK_T6, t6)
STRUCT_FIELD (long, 4, RV_STK_MSTATUS, mstatus) /* Machine Status */
STRUCT_FIELD (long, 4, RV_STK_MTVEC, mtvec) /* Machine Trap-Vector Base Address */
STRUCT_FIELD (long, 4, RV_STK_MCAUSE, mcause) /* Machine Trap Cause */
STRUCT_FIELD (long, 4, RV_STK_MTVAL, mtval) /* Machine Trap Value */
STRUCT_FIELD (long, 4, RV_STK_MHARTID, mhartid) /* Hardware Thread ID in machine mode */
STRUCT_END(RvExcFrame)
#if SOC_CPU_COPROC_NUM > 0
/* Define the default size of each coprocessor save area */
#define RV_COPROC0_SIZE 0
#define RV_COPROC1_SIZE 0
#define RV_COPROC2_SIZE 0
/* And the alignment for each of them */
#define RV_COPROC0_ALIGN 4
#define RV_COPROC1_ALIGN 4
#define RV_COPROC2_ALIGN 4
#if SOC_CPU_HAS_FPU
/* Floating-Point Unit coprocessor is now considered coprocessor 0 */
#define FPU_COPROC_IDX 0
/**
* @brief Floating-Point Unit save area
*/
STRUCT_BEGIN
STRUCT_FIELD (long, 4, RV_FPU_FT0, ft0) /* ft0-ft7: Floating Point temporaries */
STRUCT_FIELD (long, 4, RV_FPU_FT1, ft1)
STRUCT_FIELD (long, 4, RV_FPU_FT2, ft2)
STRUCT_FIELD (long, 4, RV_FPU_FT3, ft3)
STRUCT_FIELD (long, 4, RV_FPU_FT4, ft4)
STRUCT_FIELD (long, 4, RV_FPU_FT5, ft5)
STRUCT_FIELD (long, 4, RV_FPU_FT6, ft6)
STRUCT_FIELD (long, 4, RV_FPU_FT7, ft7)
STRUCT_FIELD (long, 4, RV_FPU_FS0, fs0) /* fs0-fs1: Floating Point saved registers */
STRUCT_FIELD (long, 4, RV_FPU_FS1, fs1)
STRUCT_FIELD (long, 4, RV_FPU_FA0, fa0) /* fa0-fa1: Floating Point arguments/return values */
STRUCT_FIELD (long, 4, RV_FPU_FA1, fa1)
STRUCT_FIELD (long, 4, RV_FPU_FA2, fa2) /* fa2-fa7: Floating Point arguments */
STRUCT_FIELD (long, 4, RV_FPU_FA3, fa3)
STRUCT_FIELD (long, 4, RV_FPU_FA4, fa4)
STRUCT_FIELD (long, 4, RV_FPU_FA5, fa5)
STRUCT_FIELD (long, 4, RV_FPU_FA6, fa6)
STRUCT_FIELD (long, 4, RV_FPU_FA7, fa7)
STRUCT_FIELD (long, 4, RV_FPU_FS2, fs2) /* fs2-fs11: Floating Point saved registers */
STRUCT_FIELD (long, 4, RV_FPU_FS3, fs3)
STRUCT_FIELD (long, 4, RV_FPU_FS4, fs4)
STRUCT_FIELD (long, 4, RV_FPU_FS5, fs5)
STRUCT_FIELD (long, 4, RV_FPU_FS6, fs6)
STRUCT_FIELD (long, 4, RV_FPU_FS7, fs7)
STRUCT_FIELD (long, 4, RV_FPU_FS8, fs8)
STRUCT_FIELD (long, 4, RV_FPU_FS9, fs9)
STRUCT_FIELD (long, 4, RV_FPU_FS10, fs10)
STRUCT_FIELD (long, 4, RV_FPU_FS11, fs11)
STRUCT_FIELD (long, 4, RV_FPU_FT8, ft8) /* ft8-ft11: Floating Point temporary registers */
STRUCT_FIELD (long, 4, RV_FPU_FT9, ft9)
STRUCT_FIELD (long, 4, RV_FPU_FT10, ft10)
STRUCT_FIELD (long, 4, RV_FPU_FT11, ft11)
STRUCT_FIELD (long, 4, RV_FPU_FCSR, fcsr) /* fcsr special register */
STRUCT_END(RvFPUSaveArea)
/* Redefine the coprocessor area size previously defined to 0 */
#undef RV_COPROC0_SIZE
#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
#define RV_COPROC0_SIZE RvFPUSaveAreaSize
#else
#define RV_COPROC0_SIZE sizeof(RvFPUSaveArea)
#endif /* defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) */
#endif /* SOC_CPU_HAS_FPU */
#if SOC_CPU_HAS_HWLOOP
/* Hardware Loop extension is "coprocessor" 1 */
#define HWLP_COPROC_IDX 1
/**
* @brief Hardware loop save area
*/
STRUCT_BEGIN
STRUCT_FIELD (long, 4, RV_HWLOOP_START0, start0)
STRUCT_FIELD (long, 4, RV_HWLOOP_END0, end0)
STRUCT_FIELD (long, 4, RV_HWLOOP_COUNT0, count0)
STRUCT_FIELD (long, 4, RV_HWLOOP_START1, start1)
STRUCT_FIELD (long, 4, RV_HWLOOP_END1, end1)
STRUCT_FIELD (long, 4, RV_HWLOOP_COUNT1, count1)
STRUCT_END(RvHWLPSaveArea)
/* Redefine the coprocessor area size previously defined to 0 */
#undef RV_COPROC1_SIZE
#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
#define RV_COPROC1_SIZE RvHWLPSaveAreaSize
#else
#define RV_COPROC1_SIZE sizeof(RvHWLPSaveArea)
#endif /* defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) */
#endif /* SOC_CPU_HAS_HWLOOP */
#if SOC_CPU_HAS_PIE
/* PIE/AIA coprocessor is now considered coprocessor 2 */
#define PIE_COPROC_IDX 2
/**
* @brief PIE save area
*/
STRUCT_BEGIN
STRUCT_AFIELD (long, 4, RV_PIE_Q0, q0, 4)
STRUCT_AFIELD (long, 4, RV_PIE_Q1, q1, 4)
STRUCT_AFIELD (long, 4, RV_PIE_Q2, q2, 4)
STRUCT_AFIELD (long, 4, RV_PIE_Q3, q3, 4)
STRUCT_AFIELD (long, 4, RV_PIE_Q4, q4, 4)
STRUCT_AFIELD (long, 4, RV_PIE_Q5, q5, 4)
STRUCT_AFIELD (long, 4, RV_PIE_Q6, q6, 4)
STRUCT_AFIELD (long, 4, RV_PIE_Q7, q7, 4)
STRUCT_AFIELD (long, 4, RV_PIE_QACC_L_L, qacc_l_l, 4)
STRUCT_AFIELD (long, 4, RV_PIE_QACC_L_H, qacc_l_h, 4)
STRUCT_AFIELD (long, 4, RV_PIE_QACC_H_L, qacc_h_l, 4)
STRUCT_AFIELD (long, 4, RV_PIE_QACC_H_H, qacc_h_h, 4)
STRUCT_AFIELD (long, 4, RV_PIE_UA_STATE, ua_state, 4)
STRUCT_FIELD (long, 4, RV_PIE_XACC, xacc)
/* This register contains SAR, SAR_BYTES and FFT_BIT_WIDTH in this order (from top to low) */
STRUCT_FIELD (long, 4, RV_PIE_MISC, misc)
STRUCT_END(RvPIESaveArea)
/* Redefine the coprocessor area size previously defined to 0 */
#undef RV_COPROC2_SIZE
#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
#define RV_COPROC2_SIZE RvPIESaveAreaSize
#else
#define RV_COPROC2_SIZE sizeof(RvPIESaveArea)
#endif /* defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) */
/* The PIE save area structure must be aligned on 16 bytes */
#undef RV_COPROC2_ALIGN
#define RV_COPROC2_ALIGN 16
#endif /* SOC_CPU_HAS_PIE */
/**
* @brief Coprocessors save area, containing each coprocessor save area
*/
STRUCT_BEGIN
/* Enable bitmap: BIT(i) represents coprocessor i, 1 is used, 0 else */
STRUCT_FIELD (long, 4, RV_COPROC_ENABLE, sa_enable)
/* Address of the original lowest stack address, convenient when the stack needs to be re-initialized */
STRUCT_FIELD (void*, 4, RV_COPROC_TCB_STACK, sa_tcbstack)
/* Address of the pool of memory used to allocate coprocessors save areas */
STRUCT_FIELD (long, 4, RV_COPROC_ALLOCATOR, sa_allocator)
/* Pointer to the coprocessors save areas */
STRUCT_AFIELD (void*, 4, RV_COPROC_SA, sa_coprocs, SOC_CPU_COPROC_NUM)
STRUCT_END(RvCoprocSaveArea)
#endif /* SOC_CPU_COPROC_NUM > 0 */
#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
#define RV_STK_SZ1 RvExcFrameSize
#else
#define RV_STK_SZ1 sizeof(RvExcFrame)
#endif
/*
* Exception stack frame size, after align up to 16 bytes boundary
*/
#define RV_STK_FRMSZ (ALIGNUP(0x10, RV_STK_SZ1))
#endif /* #ifndef __RVRUNTIME_FRAMES_H__ */