mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-31 22:24:28 +00:00
feat(riscv): add support for the DSP coprocessor
This commit is contained in:
@@ -136,7 +136,11 @@ BaseType_t xPortStartScheduler(void)
|
|||||||
#if SOC_CPU_HAS_PIE
|
#if SOC_CPU_HAS_PIE
|
||||||
/* Similarly, disable PIE */
|
/* Similarly, disable PIE */
|
||||||
rv_utils_disable_pie();
|
rv_utils_disable_pie();
|
||||||
#endif /* SOC_CPU_HAS_FPU */
|
#endif /* SOC_CPU_HAS_PIE */
|
||||||
|
|
||||||
|
#if SOC_CPU_HAS_DSP
|
||||||
|
rv_utils_disable_dsp();
|
||||||
|
#endif /* SOC_CPU_HAS_DSP */
|
||||||
|
|
||||||
#if SOC_CPU_HAS_HWLOOP
|
#if SOC_CPU_HAS_HWLOOP
|
||||||
/* Initialize the Hardware loop feature */
|
/* Initialize the Hardware loop feature */
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#include "riscv/rvruntime-frames.h"
|
#include "riscv/rvruntime-frames.h"
|
||||||
#include "riscv/csr_hwlp.h"
|
#include "riscv/csr_hwlp.h"
|
||||||
#include "riscv/csr_pie.h"
|
#include "riscv/csr_pie.h"
|
||||||
|
#include "riscv/csr_dsp.h"
|
||||||
|
|
||||||
.extern pxCurrentTCBs
|
.extern pxCurrentTCBs
|
||||||
|
|
||||||
@@ -329,6 +330,59 @@ generate_coprocessor_routine pie, PIE_COPROC_IDX, pie_enable, pie_save_regs, pie
|
|||||||
#endif /* SOC_CPU_HAS_PIE */
|
#endif /* SOC_CPU_HAS_PIE */
|
||||||
|
|
||||||
|
|
||||||
|
#if SOC_CPU_HAS_DSP
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Macros to enable and disable the DSP coprocessor on the current core
|
||||||
|
*/
|
||||||
|
.macro dsp_enable scratch_reg=a0
|
||||||
|
li \scratch_reg, 1
|
||||||
|
csrw CSR_DSP_STATE_REG, \scratch_reg
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable the DSP coprocessor while returning the former status in the given register
|
||||||
|
*/
|
||||||
|
.macro dsp_disable reg
|
||||||
|
csrrw \reg, CSR_DSP_STATE_REG, zero
|
||||||
|
/* Only keep the lowest two bits, if register is 0, DSP was off */
|
||||||
|
andi \reg, \reg, 0b11
|
||||||
|
beqz \reg, 1f
|
||||||
|
/* It was ON, return the enable bit in \reg */
|
||||||
|
li \reg, 1 << DSP_COPROC_IDX
|
||||||
|
1:
|
||||||
|
.endm
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Macros to save and restore the DSP coprocessor registers to and from the given frame
|
||||||
|
*/
|
||||||
|
.macro dsp_save_regs frame=a0
|
||||||
|
csrr a1, CSR_DSP_XACC_L
|
||||||
|
sw a1, RV_DSP_XACC_L(\frame)
|
||||||
|
csrr a1, CSR_DSP_XACC_H
|
||||||
|
sw a1, RV_DSP_XACC_H(\frame)
|
||||||
|
csrr a1, CSR_DSP_SAR
|
||||||
|
sw a1, RV_DSP_SAR(\frame)
|
||||||
|
csrr a1, CSR_DSP_STATUS
|
||||||
|
sw a1, RV_DSP_STATUS(\frame)
|
||||||
|
.endm
|
||||||
|
|
||||||
|
|
||||||
|
.macro dsp_restore_regs frame=a0
|
||||||
|
lw a1, RV_DSP_XACC_L(\frame)
|
||||||
|
csrw CSR_DSP_XACC_L, a1
|
||||||
|
lw a1, RV_DSP_XACC_H(\frame)
|
||||||
|
csrw CSR_DSP_XACC_H, a1
|
||||||
|
lw a1, RV_DSP_SAR(\frame)
|
||||||
|
csrw CSR_DSP_SAR, a1
|
||||||
|
lw a1, RV_DSP_STATUS(\frame)
|
||||||
|
csrw CSR_DSP_STATUS, a1
|
||||||
|
.endm
|
||||||
|
|
||||||
|
generate_coprocessor_routine dsp, DSP_COPROC_IDX, dsp_enable, dsp_save_regs, dsp_restore_regs
|
||||||
|
|
||||||
|
#endif /* SOC_CPU_HAS_DSP */
|
||||||
|
|
||||||
#if SOC_CPU_HAS_FPU
|
#if SOC_CPU_HAS_FPU
|
||||||
|
|
||||||
/* Bit to set in mstatus to enable the FPU */
|
/* Bit to set in mstatus to enable the FPU */
|
||||||
@@ -513,6 +567,12 @@ rtos_int_enter:
|
|||||||
or s2, s2, a0
|
or s2, s2, a0
|
||||||
#endif /* SOC_CPU_HAS_PIE */
|
#endif /* SOC_CPU_HAS_PIE */
|
||||||
|
|
||||||
|
#if SOC_CPU_HAS_DSP
|
||||||
|
/* The current DSP coprocessor status will be returned in a0 */
|
||||||
|
dsp_disable a0
|
||||||
|
or s2, s2, a0
|
||||||
|
#endif /* SOC_CPU_HAS_DSP */
|
||||||
|
|
||||||
#if SOC_CPU_HAS_FPU
|
#if SOC_CPU_HAS_FPU
|
||||||
fpu_disable a0
|
fpu_disable a0
|
||||||
#endif /* SOC_CPU_HAS_FPU */
|
#endif /* SOC_CPU_HAS_FPU */
|
||||||
@@ -675,6 +735,14 @@ no_context_switch:
|
|||||||
pie_enable a1
|
pie_enable a1
|
||||||
1:
|
1:
|
||||||
#endif /* SOC_CPU_HAS_PIE */
|
#endif /* SOC_CPU_HAS_PIE */
|
||||||
|
|
||||||
|
#if SOC_CPU_HAS_DSP
|
||||||
|
/* Re-enable the DSP coprocessor if it was used */
|
||||||
|
andi a1, s8, 1 << DSP_COPROC_IDX
|
||||||
|
beqz a1, 1f
|
||||||
|
dsp_enable a1
|
||||||
|
1:
|
||||||
|
#endif /* SOC_CPU_HAS_DSP */
|
||||||
j restore_stack_pointer
|
j restore_stack_pointer
|
||||||
|
|
||||||
context_switch_requested:
|
context_switch_requested:
|
||||||
|
27
components/riscv/include/riscv/csr_dsp.h
Normal file
27
components/riscv/include/riscv/csr_dsp.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
|
|
||||||
|
#if SOC_CPU_HAS_DSP
|
||||||
|
|
||||||
|
#define CSR_DSP_XACC_L 0x806
|
||||||
|
#define CSR_DSP_XACC_H 0x807
|
||||||
|
#define CSR_DSP_SAR 0x809
|
||||||
|
#define CSR_DSP_STATUS 0x80a
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CSR lowest 2 bits describe the following states:
|
||||||
|
* 00: Off
|
||||||
|
* 01: Initial
|
||||||
|
* 10: Clean
|
||||||
|
* 11: Dirty
|
||||||
|
*/
|
||||||
|
#define CSR_DSP_STATE_REG 0x7f3
|
||||||
|
|
||||||
|
#endif /* SOC_CPU_HAS_DSP */
|
@@ -14,6 +14,7 @@
|
|||||||
#include "riscv/csr.h"
|
#include "riscv/csr.h"
|
||||||
#include "riscv/interrupt.h"
|
#include "riscv/interrupt.h"
|
||||||
#include "riscv/csr_pie.h"
|
#include "riscv/csr_pie.h"
|
||||||
|
#include "riscv/csr_dsp.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
#if CONFIG_SECURE_ENABLE_TEE && !NON_OS_BUILD
|
#if CONFIG_SECURE_ENABLE_TEE && !NON_OS_BUILD
|
||||||
@@ -275,7 +276,27 @@ FORCE_INLINE_ATTR void rv_utils_disable_pie(void)
|
|||||||
RV_WRITE_CSR(CSR_PIE_STATE_REG, 0);
|
RV_WRITE_CSR(CSR_PIE_STATE_REG, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SOC_CPU_HAS_FPU */
|
#endif /* SOC_CPU_HAS_PIE */
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------- DSP Related ----------------------------------------------------
|
||||||
|
*
|
||||||
|
* ------------------------------------------------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
#if SOC_CPU_HAS_DSP
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR void rv_utils_enable_dsp(void)
|
||||||
|
{
|
||||||
|
RV_WRITE_CSR(CSR_DSP_STATE_REG, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR void rv_utils_disable_dsp(void)
|
||||||
|
{
|
||||||
|
RV_WRITE_CSR(CSR_DSP_STATE_REG, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* SOC_CPU_HAS_DSP */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -179,6 +179,36 @@ STRUCT_END(RvHWLPSaveArea)
|
|||||||
#endif /* SOC_CPU_HAS_HWLOOP */
|
#endif /* SOC_CPU_HAS_HWLOOP */
|
||||||
|
|
||||||
|
|
||||||
|
#if SOC_CPU_HAS_DSP
|
||||||
|
|
||||||
|
/* DSP coprocessor is considered coprocessor 1, just like the HWLP, make sure both are not present on the same target */
|
||||||
|
#define DSP_COPROC_IDX 1
|
||||||
|
|
||||||
|
#ifdef SOC_CPU_HAS_HWLOOP
|
||||||
|
#error "HWLP and DSP share the same coprocessor index!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief DSP save area
|
||||||
|
*/
|
||||||
|
STRUCT_BEGIN
|
||||||
|
STRUCT_FIELD (long, 4, RV_DSP_XACC_L, xacc_l)
|
||||||
|
STRUCT_FIELD (long, 4, RV_DSP_XACC_H, xacc_h)
|
||||||
|
STRUCT_FIELD (long, 4, RV_DSP_SAR, sar)
|
||||||
|
STRUCT_FIELD (long, 4, RV_DSP_STATUS, status)
|
||||||
|
STRUCT_END(RvDSPSaveArea)
|
||||||
|
|
||||||
|
/* Redefine the coprocessor area size previously defined to 0 */
|
||||||
|
#undef RV_COPROC1_SIZE
|
||||||
|
|
||||||
|
#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
|
||||||
|
#define RV_COPROC1_SIZE RvDSPSaveAreaSize
|
||||||
|
#else
|
||||||
|
#define RV_COPROC1_SIZE sizeof(RvDSPSaveArea)
|
||||||
|
#endif /* defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) */
|
||||||
|
|
||||||
|
#endif /* SOC_CPU_HAS_DSP */
|
||||||
|
|
||||||
|
|
||||||
#if SOC_CPU_HAS_PIE
|
#if SOC_CPU_HAS_PIE
|
||||||
|
|
||||||
|
@@ -20,22 +20,18 @@
|
|||||||
|
|
||||||
#if ( SOC_CPU_COPROC_NUM > 0 )
|
#if ( SOC_CPU_COPROC_NUM > 0 )
|
||||||
/* Targets with coprocessors present a special CSR to get Illegal Instruction exception reason */
|
/* Targets with coprocessors present a special CSR to get Illegal Instruction exception reason */
|
||||||
#ifdef __clang__
|
|
||||||
/* Clang does not support constant declared via `equ` as operand for csrrw
|
|
||||||
* TODO: LLVM-369
|
|
||||||
*/
|
|
||||||
#define EXT_ILL_CSR 0x7F0
|
#define EXT_ILL_CSR 0x7F0
|
||||||
#else
|
|
||||||
.equ EXT_ILL_CSR, 0x7F0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* EXT_ILL CSR reasons are stored as follows:
|
/* EXT_ILL CSR reasons are stored as follows:
|
||||||
* - Bit 0: FPU core instruction (Load/Store instructions NOT concerned)
|
* - Bit 0: FPU core instruction (Load/Store instructions NOT concerned)
|
||||||
* - Bit 1: Hardware Loop instructions
|
* - Bit 1: Hardware Loop instructions
|
||||||
* - Bit 2: PIE core */
|
* - Bit 2: PIE core
|
||||||
|
* - Bit 3: DSP core
|
||||||
|
*/
|
||||||
.equ EXT_ILL_RSN_FPU, 1
|
.equ EXT_ILL_RSN_FPU, 1
|
||||||
.equ EXT_ILL_RSN_HWLP, 2
|
.equ EXT_ILL_RSN_HWLP, 2
|
||||||
.equ EXT_ILL_RSN_PIE, 4
|
.equ EXT_ILL_RSN_PIE, 4
|
||||||
|
.equ EXT_ILL_RSN_DSP, 8
|
||||||
#endif /* SOC_CPU_COPROC_NUM > 0 */
|
#endif /* SOC_CPU_COPROC_NUM > 0 */
|
||||||
|
|
||||||
/* Macro which first allocates space on the stack to save general
|
/* Macro which first allocates space on the stack to save general
|
||||||
@@ -252,6 +248,12 @@ _panic_handler:
|
|||||||
bnez a1, rtos_save_pie_coproc
|
bnez a1, rtos_save_pie_coproc
|
||||||
#endif /* SOC_CPU_HAS_PIE */
|
#endif /* SOC_CPU_HAS_PIE */
|
||||||
|
|
||||||
|
#if SOC_CPU_HAS_DSP
|
||||||
|
/* Check if the DSP bit is set. */
|
||||||
|
andi a1, a0, EXT_ILL_RSN_DSP
|
||||||
|
bnez a1, rtos_save_dsp_coproc
|
||||||
|
#endif /* SOC_CPU_HAS_DSP */
|
||||||
|
|
||||||
/* We cannot check the HWLP bit in a0 since a hardware bug may set this bit even though no HWLP
|
/* We cannot check the HWLP bit in a0 since a hardware bug may set this bit even though no HWLP
|
||||||
* instruction was executed in the program at all, so check mtval (`t0`) */
|
* instruction was executed in the program at all, so check mtval (`t0`) */
|
||||||
#if SOC_CPU_HAS_HWLOOP
|
#if SOC_CPU_HAS_HWLOOP
|
||||||
|
@@ -183,6 +183,10 @@ config SOC_CPU_HAS_FPU_EXT_ILL_BUG
|
|||||||
bool
|
bool
|
||||||
default n
|
default n
|
||||||
|
|
||||||
|
config SOC_CPU_HAS_DSP
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
config SOC_CPU_COPROC_NUM
|
config SOC_CPU_COPROC_NUM
|
||||||
int
|
int
|
||||||
default 2
|
default 2
|
||||||
|
@@ -161,6 +161,7 @@
|
|||||||
#define SOC_BRANCH_PREDICTOR_SUPPORTED 1
|
#define SOC_BRANCH_PREDICTOR_SUPPORTED 1
|
||||||
#define SOC_CPU_HAS_FPU 1
|
#define SOC_CPU_HAS_FPU 1
|
||||||
#define SOC_CPU_HAS_FPU_EXT_ILL_BUG 0 // EXT_ILL CSR doesn't support FLW/FSW
|
#define SOC_CPU_HAS_FPU_EXT_ILL_BUG 0 // EXT_ILL CSR doesn't support FLW/FSW
|
||||||
|
#define SOC_CPU_HAS_DSP 1
|
||||||
#define SOC_CPU_COPROC_NUM 2
|
#define SOC_CPU_COPROC_NUM 2
|
||||||
|
|
||||||
#define SOC_CPU_BREAKPOINTS_NUM 4
|
#define SOC_CPU_BREAKPOINTS_NUM 4
|
||||||
|
Reference in New Issue
Block a user