mirror of
https://github.com/apache/nuttx.git
synced 2026-06-07 17:33:08 +08:00
xtensa/esp32: Configure the PID controller for privilege separation
Signed-off-by: Gustavo Henrique Nihei <gustavo.nihei@espressif.com>
This commit is contained in:
committed by
Xiang Xiao
parent
76acfef5ec
commit
27fc3c959d
@@ -129,6 +129,10 @@ config XTENSA_HAVE_DCACHE_LOCK
|
||||
bool
|
||||
default n
|
||||
|
||||
config XTENSA_HAVE_EXCEPTION_HOOKS
|
||||
bool
|
||||
default n
|
||||
|
||||
config XTENSA_ICACHE
|
||||
bool "Use I-Cache"
|
||||
default n
|
||||
|
||||
@@ -113,10 +113,19 @@
|
||||
#ifndef __XTENSA_CALL0_ABI__
|
||||
/* Temporary space for saving stuff during window spill. */
|
||||
|
||||
# define REG_TMP0 (_REG_WINDOW_TMPS + 0)
|
||||
# define _REG_OVLY_START (_REG_WINDOW_TMPS + 1)
|
||||
# define REG_TMP0 (_REG_WINDOW_TMPS + 0)
|
||||
# define _REG_INT_CTX_START (_REG_WINDOW_TMPS + 1)
|
||||
#else
|
||||
# define _REG_OVLY_START _REG_WINDOW_TMPS
|
||||
# define _REG_INT_CTX_START _REG_WINDOW_TMPS
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_BUILD_FLAT
|
||||
/* Temporary space for saving Interrupt Context information */
|
||||
|
||||
# define REG_INT_CTX (_REG_INT_CTX_START + 0)
|
||||
# define _REG_OVLY_START (_REG_INT_CTX_START + 1)
|
||||
#else
|
||||
# define _REG_OVLY_START _REG_INT_CTX_START
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_XTENSA_USE_OVLY
|
||||
@@ -155,6 +164,9 @@
|
||||
struct xcpt_syscall_s
|
||||
{
|
||||
uintptr_t sysreturn; /* The return PC */
|
||||
#ifndef CONFIG_BUILD_FLAT
|
||||
uintptr_t int_ctx; /* Interrupt context */
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -517,6 +517,55 @@ _xtensa_level6_handler:
|
||||
|
||||
#endif /* XCHAL_EXCM_LEVEL >= 6 */
|
||||
|
||||
#if XCHAL_HAVE_NMI
|
||||
.section HANDLER_SECTION, "ax"
|
||||
.type _xtensa_nmi_handler, @function
|
||||
.global _xtensa_nmi_handler
|
||||
.align 4
|
||||
|
||||
_xtensa_nmi_handler:
|
||||
/* For now, just panic */
|
||||
|
||||
exception_entry XCHAL_NMILEVEL
|
||||
|
||||
movi a2, XTENSA_NMI_EXCEPTION /* Argument 1: Error code */
|
||||
call0 _xtensa_panic /* Does not return */
|
||||
|
||||
.size _xtensa_nmi_handler, . -_xtensa_nmi_handler
|
||||
|
||||
#endif /* XCHAL_HAVE_NMI */
|
||||
|
||||
#if XCHAL_HAVE_DEBUG
|
||||
.section HANDLER_SECTION, "ax"
|
||||
.type _xtensa_debug_handler, @function
|
||||
.global _xtensa_debug_handler
|
||||
.align 4
|
||||
|
||||
_xtensa_debug_handler:
|
||||
|
||||
exception_entry XCHAL_DEBUGLEVEL
|
||||
|
||||
movi a2, XTENSA_DEBUG_EXCEPTION /* Argument 1: Error code */
|
||||
call0 _xtensa_panic /* Does not return */
|
||||
|
||||
.size _xtensa_debug_handler, . -_xtensa_debug_handler
|
||||
|
||||
#endif /* XCHAL_HAVE_DEBUG */
|
||||
|
||||
.section HANDLER_SECTION, "ax"
|
||||
.type _xtensa_kernel_handler, @function
|
||||
.global _xtensa_kernel_handler
|
||||
.align 4
|
||||
|
||||
_xtensa_kernel_handler:
|
||||
|
||||
exception_entry 1
|
||||
|
||||
movi a2, XTENSA_KERNEL_EXCEPTION /* Argument 1: Error code */
|
||||
call0 _xtensa_panic /* Does not return */
|
||||
|
||||
.size _xtensa_kernel_handler, . -_xtensa_kernel_handler
|
||||
|
||||
/****************************************************************************
|
||||
* HIGH PRIORITY (LEVEL > XCHAL_EXCM_LEVEL) LOW-LEVEL HANDLERS
|
||||
*
|
||||
|
||||
@@ -178,6 +178,13 @@
|
||||
s32i a0, sp, (4 * REG_PS)
|
||||
rsr a0, EPC_1 + \level - 1 /* Save interruptee's PC */
|
||||
s32i a0, sp, (4 * REG_PC)
|
||||
|
||||
#ifdef CONFIG_XTENSA_HAVE_EXCEPTION_HOOKS
|
||||
/* Perform chip-specific exception entry operations */
|
||||
|
||||
exception_entry_hook \level sp a0
|
||||
#endif
|
||||
|
||||
rsr a0, EXCSAVE_1 + \level - 1 /* Save interruptee's a0 */
|
||||
s32i a0, sp, (4 * REG_A0)
|
||||
s32i a2, sp, (4 * REG_A2)
|
||||
@@ -199,6 +206,13 @@
|
||||
ps_excp_write a0 \level
|
||||
l32i a0, a2, (4 * REG_PC) /* Retrieve interruptee's PC */
|
||||
wsr a0, EPC_1 + \level - 1
|
||||
|
||||
#ifdef CONFIG_XTENSA_HAVE_EXCEPTION_HOOKS
|
||||
/* Perform chip-specific exception exit operations */
|
||||
|
||||
exception_exit_hook \level a2 a0 a1
|
||||
#endif
|
||||
|
||||
l32i a0, a2, (4 * REG_A0) /* Retrieve interruptee's A0 */
|
||||
l32i sp, a2, (4 * REG_A1) /* Retrieve interrupt stack frame */
|
||||
l32i a2, a2, (4 * REG_A2) /* Retrieve interruptee's A2 */
|
||||
|
||||
@@ -32,10 +32,11 @@
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include "sched/sched.h"
|
||||
#include "xtensa.h"
|
||||
|
||||
#include "irq/irq.h"
|
||||
#include "sched/sched.h"
|
||||
|
||||
#include "chip.h"
|
||||
#include "xtensa.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
@@ -155,6 +156,9 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM |
|
||||
PS_WOE | PS_CALLINC(1));
|
||||
#endif
|
||||
#ifndef CONFIG_BUILD_FLAT
|
||||
xtensa_raiseprivilege(CURRENT_REGS);
|
||||
#endif
|
||||
|
||||
CURRENT_REGS[REG_A1] = (uint32_t)CURRENT_REGS +
|
||||
XCPTCONTEXT_SIZE;
|
||||
@@ -200,6 +204,9 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
tcb->xcp.regs[REG_PS] = (uint32_t)
|
||||
(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM |
|
||||
PS_WOE | PS_CALLINC(1));
|
||||
#endif
|
||||
#ifndef CONFIG_BUILD_FLAT
|
||||
xtensa_raiseprivilege(tcb->xcp.regs);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -306,6 +313,9 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
tcb->xcp.regs[REG_PS] = (uint32_t)
|
||||
(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM |
|
||||
PS_WOE | PS_CALLINC(1));
|
||||
#endif
|
||||
#ifndef CONFIG_BUILD_FLAT
|
||||
xtensa_raiseprivilege(tcb->xcp.regs);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@@ -348,6 +358,9 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
CURRENT_REGS[REG_PS] = (uint32_t)
|
||||
(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM |
|
||||
PS_WOE | PS_CALLINC(1));
|
||||
#endif
|
||||
#ifndef CONFIG_BUILD_FLAT
|
||||
xtensa_raiseprivilege(CURRENT_REGS);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -422,6 +435,9 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
tcb->xcp.regs[REG_PS] = (uint32_t)
|
||||
(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM |
|
||||
PS_WOE | PS_CALLINC(1));
|
||||
#endif
|
||||
#ifndef CONFIG_BUILD_FLAT
|
||||
xtensa_raiseprivilege(tcb->xcp.regs);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,16 +24,16 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <arch/xtensa/xtensa_specregs.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "signal/signal.h"
|
||||
#include "syscall.h"
|
||||
#include "xtensa.h"
|
||||
|
||||
/****************************************************************************
|
||||
@@ -84,13 +84,8 @@ int xtensa_swint(int irq, void *context, void *arg)
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_DEBUG_SYSCALL_INFO
|
||||
# ifndef CONFIG_DEBUG_SYSCALL
|
||||
if (cmd > SYS_switch_context)
|
||||
# endif
|
||||
{
|
||||
svcinfo("SYSCALL Entry: regs: %p cmd: %d\n", regs, cmd);
|
||||
xtensa_registerdump(regs);
|
||||
}
|
||||
svcinfo("SYSCALL Entry: regs: %p cmd: %" PRIu32 "\n", regs, cmd);
|
||||
xtensa_registerdump(regs);
|
||||
#endif
|
||||
|
||||
/* Handle the syscall according to the command in A2 */
|
||||
@@ -193,6 +188,9 @@ int xtensa_swint(int irq, void *context, void *arg)
|
||||
*/
|
||||
|
||||
regs[REG_PC] = rtcb->xcp.syscall[index].sysreturn;
|
||||
#ifndef CONFIG_BUILD_FLAT
|
||||
xtensa_restoreprivilege(regs, rtcb->xcp.syscall[index].int_ctx);
|
||||
#endif
|
||||
|
||||
/* The return value must be in A2-A5.
|
||||
* xtensa_dispatch_syscall() temporarily moved the value into A3.
|
||||
@@ -249,6 +247,10 @@ int xtensa_swint(int irq, void *context, void *arg)
|
||||
regs[REG_A7] = regs[REG_A5]; /* argv */
|
||||
#endif
|
||||
|
||||
/* Execute the task in User mode */
|
||||
|
||||
xtensa_lowerprivilege(regs); /* User mode */
|
||||
|
||||
/* User task rotates window, so pretend task was 'call4'd */
|
||||
|
||||
regs[REG_PS] = PS_UM | PS_WOE | PS_CALLINC(1);
|
||||
@@ -285,6 +287,10 @@ int xtensa_swint(int irq, void *context, void *arg)
|
||||
regs[REG_A6] = regs[REG_A4]; /* pthread entry */
|
||||
regs[REG_A7] = regs[REG_A5]; /* arg */
|
||||
|
||||
/* Execute the pthread in User mode */
|
||||
|
||||
xtensa_lowerprivilege(regs); /* User mode */
|
||||
|
||||
/* Startup task rotates window, so pretend task was 'call4'd */
|
||||
|
||||
regs[REG_PS] = PS_UM | PS_WOE | PS_CALLINC(1);
|
||||
@@ -322,6 +328,8 @@ int xtensa_swint(int irq, void *context, void *arg)
|
||||
|
||||
regs[REG_PC] = (uintptr_t)USERSPACE->signal_handler;
|
||||
|
||||
xtensa_lowerprivilege(regs); /* User mode */
|
||||
|
||||
/* Change the parameter ordering to match the expectation of struct
|
||||
* userpace_s signal_handler.
|
||||
*/
|
||||
@@ -353,6 +361,8 @@ int xtensa_swint(int irq, void *context, void *arg)
|
||||
DEBUGASSERT(rtcb->xcp.sigreturn != 0);
|
||||
regs[REG_PC] = rtcb->xcp.sigreturn;
|
||||
|
||||
xtensa_raiseprivilege(regs); /* Privileged mode */
|
||||
|
||||
rtcb->xcp.sigreturn = 0;
|
||||
}
|
||||
break;
|
||||
@@ -382,11 +392,18 @@ int xtensa_swint(int irq, void *context, void *arg)
|
||||
/* Setup to return to xtensa_dispatch_syscall in privileged mode. */
|
||||
|
||||
rtcb->xcp.syscall[index].sysreturn = regs[REG_PC];
|
||||
#ifndef CONFIG_BUILD_FLAT
|
||||
xtensa_saveprivilege(regs, rtcb->xcp.syscall[index].int_ctx);
|
||||
#endif
|
||||
|
||||
rtcb->xcp.nsyscalls = index + 1;
|
||||
|
||||
regs[REG_PC] = (uintptr_t)xtensa_dispatch_syscall;
|
||||
|
||||
#ifndef CONFIG_BUILD_FLAT
|
||||
xtensa_raiseprivilege(regs); /* Privileged mode */
|
||||
#endif
|
||||
|
||||
/* Offset A2 to account for the reserved values */
|
||||
|
||||
regs[REG_A2] -= CONFIG_SYS_RESERVED;
|
||||
@@ -428,21 +445,15 @@ int xtensa_swint(int irq, void *context, void *arg)
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_DEBUG_SYSCALL_INFO
|
||||
# ifndef CONFIG_DEBUG_SYSCALL
|
||||
if (cmd > SYS_switch_context)
|
||||
# else
|
||||
if (regs != CURRENT_REGS)
|
||||
# endif
|
||||
{
|
||||
svcinfo("SYSCALL Return: Context switch!\n");
|
||||
xtensa_registerdump((const uintptr_t *)CURRENT_REGS);
|
||||
}
|
||||
# ifdef CONFIG_DEBUG_SYSCALL
|
||||
else
|
||||
{
|
||||
svcinfo("SYSCALL Return: %" PRIu32 "\n", cmd);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
|
||||
@@ -183,30 +183,16 @@ _xtensa_level6_vector:
|
||||
.begin literal_prefix .nmi_vector
|
||||
.section .nmi_vector.text, "ax"
|
||||
.global _xtensa_nmi_vector
|
||||
.global _xtensa_nmi_handler
|
||||
.type _xtensa_nmi_vector, @function
|
||||
.align 4
|
||||
|
||||
_xtensa_nmi_vector:
|
||||
wsr a0, EXCSAVE + XCHAL_NMILEVEL /* Preserve a0 */
|
||||
call0 _xtensa_nmi_handler
|
||||
|
||||
#if 1
|
||||
/* For now, just panic */
|
||||
|
||||
wsr a0, EXCSAVE + XCHAL_NMILEVEL /* Preserve a0 */
|
||||
|
||||
exception_entry XCHAL_NMILEVEL
|
||||
|
||||
movi a2, XTENSA_NMI_EXCEPTION /* Argument 1: Error code */
|
||||
call0 _xtensa_panic /* Does not return */
|
||||
|
||||
#else
|
||||
/* Add high priority non-maskable interrupt (NMI) handler code here. */
|
||||
|
||||
rfi XCHAL_NMILEVEL
|
||||
|
||||
#endif
|
||||
|
||||
.size _xtensa_nmi_vector, . - _xtensa_nmi_vector
|
||||
.end literal_prefix
|
||||
.size _xtensa_nmi_vector, . - _xtensa_nmi_vector
|
||||
.end literal_prefix
|
||||
|
||||
#endif /* XCHAL_HAVE_NMI */
|
||||
|
||||
@@ -222,16 +208,15 @@ _xtensa_nmi_vector:
|
||||
.begin literal_prefix .debug_exception_vector
|
||||
.section .debug_exception_vector.text, "ax"
|
||||
.global _debug_exception_vector
|
||||
.global _xtensa_debug_handler
|
||||
.type _debug_exception_vector, @function
|
||||
.align 4
|
||||
|
||||
_debug_exception_vector:
|
||||
wsr a0, EXCSAVE + XCHAL_DEBUGLEVEL /* Preserve a0 */
|
||||
|
||||
exception_entry XCHAL_DEBUGLEVEL
|
||||
|
||||
movi a2, XTENSA_DEBUG_EXCEPTION /* Argument 1: Error code */
|
||||
call0 _xtensa_panic /* Does not return */
|
||||
wsr a0, EXCSAVE + XCHAL_DEBUGLEVEL /* Preserve a0 */
|
||||
call0 _xtensa_debug_handler
|
||||
|
||||
.size _debug_exception_vector, . - _debug_exception_vector
|
||||
.end literal_prefix
|
||||
|
||||
#endif /* XCHAL_HAVE_DEBUG */
|
||||
@@ -299,6 +284,8 @@ _double_exception_vector:
|
||||
.begin literal_prefix .kernel_exception_vector
|
||||
.section .kernel_exception_vector.text, "ax"
|
||||
.global _kernel_exception_vector
|
||||
.global _xtensa_kernel_handler
|
||||
.type _kernel_exception_vector, @function
|
||||
.align 4
|
||||
|
||||
_kernel_exception_vector:
|
||||
@@ -308,12 +295,9 @@ _kernel_exception_vector:
|
||||
#endif
|
||||
|
||||
wsr a0, EXCSAVE_1 /* Preserve a0 */
|
||||
call0 _xtensa_kernel_handler
|
||||
|
||||
exception_entry 1
|
||||
|
||||
movi a2, XTENSA_KERNEL_EXCEPTION /* Argument 1: Error code */
|
||||
call0 _xtensa_panic /* Does not return */
|
||||
|
||||
.size _kernel_exception_vector, . - _kernel_exception_vector
|
||||
.end literal_prefix
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
@@ -31,12 +31,14 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.file "xtensa_vectors.S"
|
||||
.file "xtensa_window_vector.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <arch/xtensa/xtensa_specregs.h>
|
||||
#include <arch/xtensa/core.h>
|
||||
#include <arch/chip/core-isa.h>
|
||||
@@ -96,7 +98,11 @@ _window_overflow4:
|
||||
s32e a1, a5, -12 /* Save a1 to call[j+1]'s stack frame */
|
||||
s32e a2, a5, -8 /* Save a2 to call[j+1]'s stack frame */
|
||||
s32e a3, a5, -4 /* Save a3 to call[j+1]'s stack frame */
|
||||
#ifdef CONFIG_XTENSA_HAVE_EXCEPTION_HOOKS
|
||||
j _overflow4_exit_hook
|
||||
#else
|
||||
rfwo /* Rotates back to call[i] position */
|
||||
#endif
|
||||
|
||||
/* Window Underflow Exception for Call4
|
||||
*
|
||||
@@ -119,7 +125,11 @@ _window_underflow4:
|
||||
l32e a1, a5, -12 /* Restore a1 from call[i+1]'s stack frame */
|
||||
l32e a2, a5, -8 /* Restore a2 from call[i+1]'s stack frame */
|
||||
l32e a3, a5, -4 /* Restore a3 from call[i+1]'s stack frame */
|
||||
#ifdef CONFIG_XTENSA_HAVE_EXCEPTION_HOOKS
|
||||
j _underflow4_exit_hook
|
||||
#else
|
||||
rfwu
|
||||
#endif
|
||||
|
||||
/* Handle alloca exception generated by interruptee executing 'movsp'.
|
||||
* This uses space between the window vectors, so is essentially "free".
|
||||
@@ -178,7 +188,11 @@ _window_overflow8:
|
||||
s32e a5, a0, -28 /* Save a5 to call[j]'s stack frame */
|
||||
s32e a6, a0, -24 /* Save a6 to call[j]'s stack frame */
|
||||
s32e a7, a0, -20 /* Save a7 to call[j]'s stack frame */
|
||||
#ifdef CONFIG_XTENSA_HAVE_EXCEPTION_HOOKS
|
||||
j _overflow8_exit_hook
|
||||
#else
|
||||
rfwo /* Rotates back to call[i] position */
|
||||
#endif
|
||||
|
||||
/* Window Underflow Exception for Call8
|
||||
*
|
||||
@@ -207,7 +221,11 @@ _window_underflow8:
|
||||
l32e a5, a7, -28 /* Restore a5 from call[i]'s stack frame */
|
||||
l32e a6, a7, -24 /* Restore a6 from call[i]'s stack frame */
|
||||
l32e a7, a7, -20 /* Restore a7 from call[i]'s stack frame */
|
||||
#ifdef CONFIG_XTENSA_HAVE_EXCEPTION_HOOKS
|
||||
j _underflow8_exit_hook
|
||||
#else
|
||||
rfwu
|
||||
#endif
|
||||
|
||||
/* Window Overflow Exception for Call12
|
||||
*
|
||||
|
||||
@@ -541,6 +541,13 @@ config ESP32_AES_ACCELERATOR
|
||||
bool "AES Accelerator"
|
||||
default n
|
||||
|
||||
config ESP32_PID
|
||||
bool "PID Controller"
|
||||
default n
|
||||
select ARCH_USE_MPU
|
||||
select XTENSA_HAVE_EXCEPTION_HOOKS if BUILD_PROTECTED
|
||||
depends on EXPERIMENTAL
|
||||
|
||||
endmenu # ESP32 Peripheral Selection
|
||||
|
||||
config ESP32_WIFI_BT_COEXIST
|
||||
|
||||
@@ -23,7 +23,11 @@ include common/Make.defs
|
||||
|
||||
# The start-up, "head", file. May be either a .S or a .c file.
|
||||
|
||||
HEAD_CSRC = esp32_start.c esp32_wdt.c
|
||||
HEAD_CSRC = esp32_start.c esp32_wdt.c
|
||||
|
||||
ifeq ($(CONFIG_XTENSA_HAVE_EXCEPTION_HOOKS),y)
|
||||
HEAD_ASRC += esp32_window_hooks.S
|
||||
endif
|
||||
|
||||
# Required ESP32 files (arch/xtensa/src/esp32)
|
||||
|
||||
|
||||
@@ -39,6 +39,10 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#if defined(CONFIG_ESP32_PID) && defined(CONFIG_BUILD_PROTECTED)
|
||||
#include "hardware/esp32_pid.h"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
@@ -49,6 +53,23 @@
|
||||
|
||||
#define HANDLER_SECTION .iram1
|
||||
|
||||
#if defined(CONFIG_ESP32_PID) && defined(CONFIG_BUILD_PROTECTED)
|
||||
|
||||
/* Definitions for the PIDs reserved for Kernel and Userspace */
|
||||
|
||||
#define PIDCTRL_PID_KERNEL 0 /* Privileged */
|
||||
#define PIDCTRL_PID_USER 5 /* Non-privileged */
|
||||
|
||||
/* Macros for privilege handling with the PID Controller peripheral */
|
||||
|
||||
#define xtensa_saveprivilege(regs,var) ((var) = (regs)[REG_INT_CTX])
|
||||
#define xtensa_restoreprivilege(regs,var) ((regs)[REG_INT_CTX] = (var))
|
||||
|
||||
#define xtensa_lowerprivilege(regs) ((regs)[REG_INT_CTX] = PIDCTRL_PID_USER)
|
||||
#define xtensa_raiseprivilege(regs) ((regs)[REG_INT_CTX] = PIDCTRL_PID_KERNEL)
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
@@ -95,6 +116,116 @@
|
||||
l32i a1, \tmp2, 0 /* a1 = *tmp2 */
|
||||
.endm
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: get_prev_pid
|
||||
*
|
||||
* Description:
|
||||
* Retrieve PID information from interruptee.
|
||||
*
|
||||
* Entry Conditions:
|
||||
* level - Interrupt level
|
||||
* out - Temporary and output register
|
||||
*
|
||||
* Exit Conditions:
|
||||
* PID value to be returned will be written to "out" register.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESP32_PID
|
||||
.macro get_prev_pid level out
|
||||
movi \out, PIDCTRL_FROM_1_REG + (\level - 1) * 0x4
|
||||
l32i \out, \out, 0
|
||||
extui \out, \out, 0, 3
|
||||
.endm
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: set_next_pid
|
||||
*
|
||||
* Description:
|
||||
* Configure the PID Controller for the new execution context.
|
||||
*
|
||||
* Entry Conditions:
|
||||
* in - PID to be set
|
||||
* tmp - Temporary register
|
||||
*
|
||||
* Exit Conditions:
|
||||
* Register "in" has been trashed.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESP32_PID
|
||||
.macro set_next_pid in tmp
|
||||
movi \tmp, PIDCTRL_PID_NEW_REG
|
||||
s32i \in, \tmp, 0 /* Set new PID */
|
||||
|
||||
movi \tmp, PIDCTRL_PID_DELAY_REG
|
||||
movi \in, 0x0
|
||||
s32i \in, \tmp, 0 /* Set delay (cycles) for PID change */
|
||||
|
||||
movi \tmp, PIDCTRL_PID_CONFIRM_REG
|
||||
movi \in, 0x1
|
||||
s32i \in, \tmp, 0 /* Confirm change to the new PID */
|
||||
.endm
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: exception_entry_hook
|
||||
*
|
||||
* Description:
|
||||
* Perform chip-specific exception entry operations.
|
||||
*
|
||||
* Entry Conditions:
|
||||
* level - Interrupt level
|
||||
* reg_sp - Stack pointer
|
||||
* tmp - Temporary register
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_XTENSA_HAVE_EXCEPTION_HOOKS
|
||||
.macro exception_entry_hook level reg_sp tmp
|
||||
|
||||
/* Save PID information from interruptee when handling User (Level 1) and
|
||||
* Software-triggered interrupts (Level 3).
|
||||
*/
|
||||
|
||||
.ifeq (\level - 1) & (\level - 3)
|
||||
get_prev_pid \level \tmp
|
||||
s32i \tmp, \reg_sp, (4 * REG_INT_CTX) /* Save PID into context area */
|
||||
.endif
|
||||
.endm
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: exception_exit_hook
|
||||
*
|
||||
* Description:
|
||||
* Perform chip-specific exception exit operations.
|
||||
*
|
||||
* Entry Conditions:
|
||||
* level - Interrupt level
|
||||
* reg_sp - Stack pointer
|
||||
* tmp1 - Temporary register 1
|
||||
* tmp2 - Temporary register 2
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_XTENSA_HAVE_EXCEPTION_HOOKS
|
||||
.macro exception_exit_hook level reg_sp tmp1 tmp2
|
||||
|
||||
/* Configure the PID Controller for the new execution context before
|
||||
* returning from User (Level 1) and Software-triggered interrupts
|
||||
* (Level 3).
|
||||
*/
|
||||
|
||||
.ifeq (\level - 1) & (\level - 3)
|
||||
l32i \tmp1, \reg_sp, (4 * REG_INT_CTX)
|
||||
set_next_pid \tmp1 \tmp2
|
||||
.endif
|
||||
.endm
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY */
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
@@ -141,6 +141,7 @@ uint32_t g_idlestack[IDLETHREAD_STACKWORDS]
|
||||
static noreturn_function void __esp32_start(void)
|
||||
{
|
||||
uint32_t sp;
|
||||
uint32_t regval unused_data;
|
||||
|
||||
/* Make sure that normal interrupts are disabled. This is really only an
|
||||
* issue when we are started in un-usual ways (such as from IRAM). In this
|
||||
@@ -163,17 +164,31 @@ static noreturn_function void __esp32_start(void)
|
||||
|
||||
esp32_region_protection();
|
||||
|
||||
#if defined(CONFIG_ESP32_PID) && defined(CONFIG_BUILD_PROTECTED)
|
||||
/* We have 2 VECBASE Addresses: one in CPU and one in DPORT peripheral.
|
||||
* CPU has no knowledge of PID hence any PID can change the CPU VECBASE
|
||||
* address thus jumping to malicious interrupt vectors with higher
|
||||
* privilege.
|
||||
* So we configure CPU to use the VECBASE address in DPORT peripheral.
|
||||
*/
|
||||
|
||||
regval = ((uint32_t)&_init_start) >> 10;
|
||||
putreg32(regval, DPORT_PRO_VECBASE_SET_REG);
|
||||
|
||||
regval = getreg32(DPORT_PRO_VECBASE_CTRL_REG);
|
||||
regval |= BIT(0) | BIT(1);
|
||||
putreg32(regval, DPORT_PRO_VECBASE_CTRL_REG);
|
||||
#else
|
||||
/* Move CPU0 exception vectors to IRAM */
|
||||
|
||||
__asm__ __volatile__ ("wsr %0, vecbase\n"::"r" (&_init_start));
|
||||
__asm__ __volatile__ ("wsr %0, vecbase\n"::"r"(&_init_start));
|
||||
#endif
|
||||
|
||||
/* Set .bss to zero */
|
||||
|
||||
memset(&_sbss, 0, (&_ebss - &_sbss) * sizeof(_sbss));
|
||||
|
||||
#ifndef CONFIG_SMP
|
||||
uint32_t regval;
|
||||
|
||||
/* Make sure that the APP_CPU is disabled for now */
|
||||
|
||||
regval = getreg32(DPORT_APPCPU_CTRL_B_REG);
|
||||
|
||||
@@ -33,9 +33,12 @@
|
||||
|
||||
#include <arch/board/board_memorymap.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "xtensa.h"
|
||||
#include "xtensa_attr.h"
|
||||
#include "esp32_userspace.h"
|
||||
#include "hardware/esp32_dport.h"
|
||||
#include "hardware/esp32_pid.h"
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
|
||||
@@ -153,18 +156,34 @@ static noinline_function IRAM_ATTR void configure_flash_mmu(void)
|
||||
drom_lma_aligned = app_drom_lma & MMU_FLASH_MASK;
|
||||
drom_vma_aligned = app_drom_vma & MMU_FLASH_MASK;
|
||||
drom_page_count = calc_mmu_pages(app_drom_size, app_drom_vma);
|
||||
DEBUGVERIFY(cache_flash_mmu_set(0, 0, drom_vma_aligned, drom_lma_aligned,
|
||||
64, (int)drom_page_count));
|
||||
DEBUGVERIFY(cache_flash_mmu_set(1, 0, drom_vma_aligned, drom_lma_aligned,
|
||||
64, (int)drom_page_count));
|
||||
ASSERT(cache_flash_mmu_set(0, PIDCTRL_PID_KERNEL, drom_vma_aligned,
|
||||
drom_lma_aligned, 64,
|
||||
(int)drom_page_count) == 0);
|
||||
ASSERT(cache_flash_mmu_set(1, PIDCTRL_PID_KERNEL, drom_vma_aligned,
|
||||
drom_lma_aligned, 64,
|
||||
(int)drom_page_count) == 0);
|
||||
ASSERT(cache_flash_mmu_set(0, PIDCTRL_PID_USER, drom_vma_aligned,
|
||||
drom_lma_aligned, 64,
|
||||
(int)drom_page_count) == 0);
|
||||
ASSERT(cache_flash_mmu_set(1, PIDCTRL_PID_USER, drom_vma_aligned,
|
||||
drom_lma_aligned, 64,
|
||||
(int)drom_page_count) == 0);
|
||||
|
||||
irom_lma_aligned = app_irom_lma & MMU_FLASH_MASK;
|
||||
irom_vma_aligned = app_irom_vma & MMU_FLASH_MASK;
|
||||
irom_page_count = calc_mmu_pages(app_irom_size, app_irom_vma);
|
||||
DEBUGVERIFY(cache_flash_mmu_set(0, 0, irom_vma_aligned, irom_lma_aligned,
|
||||
64, (int)irom_page_count));
|
||||
DEBUGVERIFY(cache_flash_mmu_set(1, 0, irom_vma_aligned, irom_lma_aligned,
|
||||
64, (int)irom_page_count));
|
||||
ASSERT(cache_flash_mmu_set(0, PIDCTRL_PID_KERNEL, irom_vma_aligned,
|
||||
irom_lma_aligned, 64,
|
||||
(int)irom_page_count) == 0);
|
||||
ASSERT(cache_flash_mmu_set(1, PIDCTRL_PID_KERNEL, irom_vma_aligned,
|
||||
irom_lma_aligned, 64,
|
||||
(int)irom_page_count) == 0);
|
||||
ASSERT(cache_flash_mmu_set(0, PIDCTRL_PID_USER, irom_vma_aligned,
|
||||
irom_lma_aligned, 64,
|
||||
(int)irom_page_count) == 0);
|
||||
ASSERT(cache_flash_mmu_set(1, PIDCTRL_PID_USER, irom_vma_aligned,
|
||||
irom_lma_aligned, 64,
|
||||
(int)irom_page_count) == 0);
|
||||
|
||||
cache_read_enable(0);
|
||||
}
|
||||
@@ -195,8 +214,8 @@ static noinline_function IRAM_ATTR const void *map_flash(uint32_t src_addr,
|
||||
|
||||
src_addr_aligned = src_addr & MMU_FLASH_MASK;
|
||||
page_count = calc_mmu_pages(size, src_addr);
|
||||
DEBUGVERIFY(cache_flash_mmu_set(0, 0, MMU_BLOCK50_VADDR, src_addr_aligned,
|
||||
64, (int)page_count));
|
||||
ASSERT(cache_flash_mmu_set(0, PIDCTRL_PID_KERNEL, MMU_BLOCK50_VADDR,
|
||||
src_addr_aligned, 64, (int)page_count) == 0);
|
||||
|
||||
cache_read_enable(0);
|
||||
|
||||
@@ -279,6 +298,71 @@ static void initialize_data(void)
|
||||
|
||||
static void configure_mpu(void)
|
||||
{
|
||||
/* 8K page size for mappings both IRAM and DRAM */
|
||||
|
||||
REG_SET_FIELD(DPORT_IMMU_PAGE_MODE_REG, DPORT_IMMU_PAGE_MODE, 0);
|
||||
REG_SET_FIELD(DPORT_DMMU_PAGE_MODE_REG, DPORT_DMMU_PAGE_MODE, 0);
|
||||
|
||||
/* 1:1 mapping for IRAM */
|
||||
|
||||
REG_SET_FIELD(DPORT_IMMU_TABLE0_REG, DPORT_IMMU_TABLE0, 0x00);
|
||||
REG_SET_FIELD(DPORT_IMMU_TABLE1_REG, DPORT_IMMU_TABLE1, 0x51);
|
||||
REG_SET_FIELD(DPORT_IMMU_TABLE2_REG, DPORT_IMMU_TABLE2, 0x52);
|
||||
REG_SET_FIELD(DPORT_IMMU_TABLE3_REG, DPORT_IMMU_TABLE3, 0x53);
|
||||
REG_SET_FIELD(DPORT_IMMU_TABLE4_REG, DPORT_IMMU_TABLE4, 0x54);
|
||||
REG_SET_FIELD(DPORT_IMMU_TABLE5_REG, DPORT_IMMU_TABLE5, 0x55);
|
||||
REG_SET_FIELD(DPORT_IMMU_TABLE6_REG, DPORT_IMMU_TABLE6, 0x56);
|
||||
REG_SET_FIELD(DPORT_IMMU_TABLE7_REG, DPORT_IMMU_TABLE7, 0x57);
|
||||
REG_SET_FIELD(DPORT_IMMU_TABLE8_REG, DPORT_IMMU_TABLE8, 0x08);
|
||||
REG_SET_FIELD(DPORT_IMMU_TABLE9_REG, DPORT_IMMU_TABLE9, 0x09);
|
||||
REG_SET_FIELD(DPORT_IMMU_TABLE10_REG, DPORT_IMMU_TABLE10, 0x0a);
|
||||
REG_SET_FIELD(DPORT_IMMU_TABLE11_REG, DPORT_IMMU_TABLE11, 0x0b);
|
||||
REG_SET_FIELD(DPORT_IMMU_TABLE12_REG, DPORT_IMMU_TABLE12, 0x0c);
|
||||
REG_SET_FIELD(DPORT_IMMU_TABLE13_REG, DPORT_IMMU_TABLE13, 0x0d);
|
||||
REG_SET_FIELD(DPORT_IMMU_TABLE14_REG, DPORT_IMMU_TABLE14, 0x0e);
|
||||
REG_SET_FIELD(DPORT_IMMU_TABLE15_REG, DPORT_IMMU_TABLE15, 0x0f);
|
||||
|
||||
REG_SET_FIELD(DPORT_DMMU_TABLE0_REG, DPORT_DMMU_TABLE0, 0x00);
|
||||
REG_SET_FIELD(DPORT_DMMU_TABLE1_REG, DPORT_DMMU_TABLE1, 0x01);
|
||||
REG_SET_FIELD(DPORT_DMMU_TABLE2_REG, DPORT_DMMU_TABLE2, 0x02);
|
||||
REG_SET_FIELD(DPORT_DMMU_TABLE3_REG, DPORT_DMMU_TABLE3, 0x03);
|
||||
REG_SET_FIELD(DPORT_DMMU_TABLE4_REG, DPORT_DMMU_TABLE4, 0x54);
|
||||
REG_SET_FIELD(DPORT_DMMU_TABLE5_REG, DPORT_DMMU_TABLE5, 0x55);
|
||||
REG_SET_FIELD(DPORT_DMMU_TABLE6_REG, DPORT_DMMU_TABLE6, 0x56);
|
||||
REG_SET_FIELD(DPORT_DMMU_TABLE7_REG, DPORT_DMMU_TABLE7, 0x57);
|
||||
REG_SET_FIELD(DPORT_DMMU_TABLE8_REG, DPORT_DMMU_TABLE8, 0x58);
|
||||
REG_SET_FIELD(DPORT_DMMU_TABLE9_REG, DPORT_DMMU_TABLE9, 0x59);
|
||||
REG_SET_FIELD(DPORT_DMMU_TABLE10_REG, DPORT_DMMU_TABLE10, 0x5a);
|
||||
REG_SET_FIELD(DPORT_DMMU_TABLE11_REG, DPORT_DMMU_TABLE11, 0x5b);
|
||||
REG_SET_FIELD(DPORT_DMMU_TABLE12_REG, DPORT_DMMU_TABLE12, 0x5c);
|
||||
REG_SET_FIELD(DPORT_DMMU_TABLE13_REG, DPORT_DMMU_TABLE13, 0x5d);
|
||||
REG_SET_FIELD(DPORT_DMMU_TABLE14_REG, DPORT_DMMU_TABLE14, 0x5e);
|
||||
REG_SET_FIELD(DPORT_DMMU_TABLE15_REG, DPORT_DMMU_TABLE15, 0x5f);
|
||||
|
||||
/* Configure interrupt vector addresses in PID Controller */
|
||||
|
||||
putreg32(PIDCTRL_INTERRUPT_ENABLE_M, PIDCTRL_INTERRUPT_ENABLE_REG);
|
||||
|
||||
/* Configure the PID Controller to switch to privileged mode (PID 0) when
|
||||
* the CPU fetches instruction from the following interrupt vectors:
|
||||
* 1) Level 1
|
||||
* 2) Window Overflow 4
|
||||
* 3) Level 3 (SWINT)
|
||||
* 4) Window Underflow 4
|
||||
* 5) Window Overflow 8
|
||||
* 6) Window Underflow 8
|
||||
* 7) NMI
|
||||
*/
|
||||
|
||||
putreg32(VECTORS_START + 0x340, PIDCTRL_INTERRUPT_ADDR_1_REG);
|
||||
putreg32(VECTORS_START + 0x000, PIDCTRL_INTERRUPT_ADDR_2_REG);
|
||||
putreg32(VECTORS_START + 0x1c0, PIDCTRL_INTERRUPT_ADDR_3_REG);
|
||||
putreg32(VECTORS_START + 0x040, PIDCTRL_INTERRUPT_ADDR_4_REG);
|
||||
putreg32(VECTORS_START + 0x080, PIDCTRL_INTERRUPT_ADDR_5_REG);
|
||||
putreg32(VECTORS_START + 0x0c0, PIDCTRL_INTERRUPT_ADDR_6_REG);
|
||||
putreg32(VECTORS_START + 0x2c0, PIDCTRL_INTERRUPT_ADDR_7_REG);
|
||||
|
||||
putreg32(0, PIDCTRL_LEVEL_REG);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
/****************************************************************************
|
||||
* arch/xtensa/src/esp32/esp32_window_hooks.S
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.file "esp32_window_hooks.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include "chip_macros.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_XTENSA_HAVE_EXCEPTION_HOOKS
|
||||
/* PID Controller is configured to switch to PID 0 when the CPU fetches
|
||||
* instruction from the following window exception vectors:
|
||||
* - Window Overflow 4: mapped as Level 2 vector entry address
|
||||
* - Window Underflow 4: mapped as Level 4 vector entry address
|
||||
* - Window Overflow 8: mapped as Level 5 vector entry address
|
||||
* - Window Underflow 8: mapped as Level 6 vector entry address
|
||||
*
|
||||
* See arch/xtensa/src/esp32/esp32_userspace.c
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: _overflow4_exit_hook
|
||||
****************************************************************************/
|
||||
|
||||
.section HANDLER_SECTION, "ax"
|
||||
.global _overflow4_exit_hook
|
||||
.type _overflow4_exit_hook, @function
|
||||
.align 4
|
||||
|
||||
_overflow4_exit_hook:
|
||||
wsr a0, misc0
|
||||
wsr a1, misc1
|
||||
|
||||
/* Restore PID to the same value prior to the exception */
|
||||
|
||||
get_prev_pid 2 a0
|
||||
set_next_pid a0 a1
|
||||
|
||||
rsr a0, misc0
|
||||
rsr a1, misc1
|
||||
rfwo /* rotates back to call[i] position */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: _underflow4_exit_hook
|
||||
****************************************************************************/
|
||||
|
||||
.section HANDLER_SECTION, "ax"
|
||||
.global _underflow4_exit_hook
|
||||
.type _underflow4_exit_hook, @function
|
||||
.align 4
|
||||
|
||||
_underflow4_exit_hook:
|
||||
wsr a0, misc0
|
||||
wsr a1, misc1
|
||||
|
||||
/* Restore PID to the same value prior to the exception */
|
||||
|
||||
get_prev_pid 4 a0
|
||||
set_next_pid a0 a1
|
||||
|
||||
rsr a0, misc0
|
||||
rsr a1, misc1
|
||||
rfwu
|
||||
|
||||
/****************************************************************************
|
||||
* Name: _overflow8_exit_hook
|
||||
****************************************************************************/
|
||||
|
||||
.section HANDLER_SECTION, "ax"
|
||||
.global _overflow8_exit_hook
|
||||
.type _overflow8_exit_hook, @function
|
||||
.align 4
|
||||
|
||||
_overflow8_exit_hook:
|
||||
wsr a0, misc0
|
||||
wsr a1, misc1
|
||||
|
||||
/* Restore PID to the same value prior to the exception */
|
||||
|
||||
get_prev_pid 5 a0
|
||||
set_next_pid a0 a1
|
||||
|
||||
rsr a0, misc0
|
||||
rsr a1, misc1
|
||||
rfwo /* rotates back to call[i] position */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: _underflow8_exit_hook
|
||||
****************************************************************************/
|
||||
|
||||
.section HANDLER_SECTION, "ax"
|
||||
.global _underflow8_exit_hook
|
||||
.type _underflow8_exit_hook, @function
|
||||
.align 4
|
||||
|
||||
_underflow8_exit_hook:
|
||||
wsr a0, misc0
|
||||
wsr a1, misc1
|
||||
|
||||
/* Restore PID to the same value prior to the exception */
|
||||
|
||||
get_prev_pid 6 a0
|
||||
set_next_pid a0 a1
|
||||
|
||||
rsr a0, misc0
|
||||
rsr a1, misc1
|
||||
rfwu
|
||||
|
||||
#endif /* CONFIG_XTENSA_HAVE_EXCEPTION_HOOKS */
|
||||
@@ -0,0 +1,127 @@
|
||||
/****************************************************************************
|
||||
* arch/xtensa/src/esp32/hardware/esp32_pid.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_XTENSA_SRC_ESP32_HARDWARE_ESP32_PID_H_
|
||||
#define __ARCH_XTENSA_SRC_ESP32_HARDWARE_ESP32_PID_H_
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define REG_PIDCTRL_BASE 0x3ff1f000
|
||||
|
||||
/* Bits 1..7: 1 if interrupt will be triggering PID change */
|
||||
|
||||
#define PIDCTRL_INTERRUPT_ENABLE_REG ((REG_PIDCTRL_BASE) + 0x000)
|
||||
|
||||
/* PIDCTRL_INTERRUPT_ENABLE : R/W; bitpos: [7:1]; default: 0;
|
||||
* These bits are used to enable interrupt identification and processing.
|
||||
*/
|
||||
|
||||
#define PIDCTRL_INTERRUPT_ENABLE 0x0000007f
|
||||
#define PIDCTRL_INTERRUPT_ENABLE_M (PIDCTRL_INTERRUPT_ENABLE_V << PIDCTRL_INTERRUPT_ENABLE_S)
|
||||
#define PIDCTRL_INTERRUPT_ENABLE_V 0x0000007f
|
||||
#define PIDCTRL_INTERRUPT_ENABLE_S 1
|
||||
|
||||
/* Vectors for the various interrupt handlers */
|
||||
|
||||
#define PIDCTRL_INTERRUPT_ADDR_1_REG ((REG_PIDCTRL_BASE) + 0x004)
|
||||
#define PIDCTRL_INTERRUPT_ADDR_2_REG ((REG_PIDCTRL_BASE) + 0x008)
|
||||
#define PIDCTRL_INTERRUPT_ADDR_3_REG ((REG_PIDCTRL_BASE) + 0x00c)
|
||||
#define PIDCTRL_INTERRUPT_ADDR_4_REG ((REG_PIDCTRL_BASE) + 0x010)
|
||||
#define PIDCTRL_INTERRUPT_ADDR_5_REG ((REG_PIDCTRL_BASE) + 0x014)
|
||||
#define PIDCTRL_INTERRUPT_ADDR_6_REG ((REG_PIDCTRL_BASE) + 0x018)
|
||||
#define PIDCTRL_INTERRUPT_ADDR_7_REG ((REG_PIDCTRL_BASE) + 0x01c)
|
||||
|
||||
/* Delay, in CPU cycles, before switching to new PID */
|
||||
|
||||
#define PIDCTRL_PID_DELAY_REG ((REG_PIDCTRL_BASE) + 0x020)
|
||||
|
||||
/* PIDCTRL_PID_DELAY : R/W; bitpos: [11:0]; default: 20;
|
||||
* Delay until newly assigned PID is valid.
|
||||
*/
|
||||
|
||||
#define PIDCTRL_PID_DELAY 0x00001fff
|
||||
#define PIDCTRL_PID_DELAY_M (PIDCTRL_PID_DELAY_V << PIDCTRL_PID_DELAY_S)
|
||||
#define PIDCTRL_PID_DELAY_V 0x00001fff
|
||||
#define PIDCTRL_PID_DELAY_S 0
|
||||
|
||||
#define PIDCTRL_NMI_DELAY_REG ((REG_PIDCTRL_BASE) + 0x024)
|
||||
|
||||
/* PIDCTRL_NMI_DELAY : R/W; bitpos: [11:0]; default: 16;
|
||||
* Delay for disabling CPU NMI interrupt mask signal.
|
||||
*/
|
||||
|
||||
#define PIDCTRL_NMI_DELAY 0x00001fff
|
||||
#define PIDCTRL_NMI_DELAY_M (PIDCTRL_NMI_DELAY_V << PIDCTRL_NMI_DELAY_S)
|
||||
#define PIDCTRL_NMI_DELAY_V 0x00001fff
|
||||
#define PIDCTRL_NMI_DELAY_S 0
|
||||
|
||||
/* Last detected interrupt. Set by hw on int. */
|
||||
|
||||
#define PIDCTRL_LEVEL_REG ((REG_PIDCTRL_BASE) + 0x028)
|
||||
|
||||
/* PID/prev int data for each int */
|
||||
|
||||
#define PIDCTRL_FROM_REG(i) ((REG_PIDCTRL_BASE) + 0x028 + (0x4 * i))
|
||||
|
||||
#define PIDCTRL_FROM_1_REG ((REG_PIDCTRL_BASE) + 0x02c)
|
||||
#define PIDCTRL_FROM_2_REG ((REG_PIDCTRL_BASE) + 0x030)
|
||||
#define PIDCTRL_FROM_3_REG ((REG_PIDCTRL_BASE) + 0x034)
|
||||
#define PIDCTRL_FROM_4_REG ((REG_PIDCTRL_BASE) + 0x038)
|
||||
#define PIDCTRL_FROM_5_REG ((REG_PIDCTRL_BASE) + 0x03c)
|
||||
#define PIDCTRL_FROM_6_REG ((REG_PIDCTRL_BASE) + 0x040)
|
||||
#define PIDCTRL_FROM_7_REG ((REG_PIDCTRL_BASE) + 0x044)
|
||||
|
||||
/* PIDCTRL_FROM_INT : R/W; bitpos: [6:3]; default: 0;
|
||||
* Interrupt status of the system before the interrupt occurs.
|
||||
*/
|
||||
|
||||
#define PIDCTRL_FROM_INT 0x0000000f
|
||||
#define PIDCTRL_FROM_INT_M (PIDCTRL_FROM_INT_V << PIDCTRL_FROM_INT_S)
|
||||
#define PIDCTRL_FROM_INT_V 0x0000000f
|
||||
#define PIDCTRL_FROM_INT_S 3
|
||||
|
||||
/* PIDCTRL_FROM_PID : R/W; bitpos: [2:0]; default: 0;
|
||||
* Process running on the CPU before the interrupt occurs.
|
||||
*/
|
||||
|
||||
#define PIDCTRL_FROM_PID 0x00000007
|
||||
#define PIDCTRL_FROM_PID_M (PIDCTRL_FROM_PID_V << PIDCTRL_FROM_PID_S)
|
||||
#define PIDCTRL_FROM_PID_V 0x00000007
|
||||
#define PIDCTRL_FROM_PID_S 0
|
||||
|
||||
/* PID to be set after confirm routine */
|
||||
|
||||
#define PIDCTRL_PID_NEW_REG ((REG_PIDCTRL_BASE) + 0x048)
|
||||
|
||||
/* Write to kick off PID change */
|
||||
|
||||
#define PIDCTRL_PID_CONFIRM_REG ((REG_PIDCTRL_BASE) + 0x04c)
|
||||
|
||||
/* Write to mask NMI */
|
||||
|
||||
#define PIDCTRL_NMI_MASK_ENABLE_REG ((REG_PIDCTRL_BASE) + 0x054)
|
||||
|
||||
/* Write to unmask NMI */
|
||||
|
||||
#define PIDCTRL_NMI_MASK_DISABLE_REG ((REG_PIDCTRL_BASE) + 0x058)
|
||||
|
||||
#endif /* __ARCH_XTENSA_SRC_ESP32_HARDWARE_ESP32_PID_H_ */
|
||||
@@ -18,7 +18,6 @@ CONFIG_ARCH_CHIP_ESP32=y
|
||||
CONFIG_ARCH_CHIP_ESP32WROVER=y
|
||||
CONFIG_ARCH_INTERRUPTSTACK=2048
|
||||
CONFIG_ARCH_STACKDUMP=y
|
||||
CONFIG_ARCH_USE_MPU=y
|
||||
CONFIG_ARCH_XTENSA=y
|
||||
CONFIG_BOARD_LOOPSPERMSEC=16717
|
||||
CONFIG_BUILD_PROTECTED=y
|
||||
@@ -30,7 +29,9 @@ CONFIG_DEBUG_FULLOPT=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_SYMBOLS=y
|
||||
CONFIG_DEBUG_WARN=y
|
||||
CONFIG_ESP32_PID=y
|
||||
CONFIG_ESP32_UART0=y
|
||||
CONFIG_EXPERIMENTAL=y
|
||||
CONFIG_FS_PROCFS=y
|
||||
CONFIG_HAVE_CXX=y
|
||||
CONFIG_HAVE_CXXINITIALIZE=y
|
||||
|
||||
Reference in New Issue
Block a user