arch: arc: Add the support of secure mode for em
In ARC's SecureShield, a new secure mode (currently only em) is added. The secure/normal mode is orthogonal to kernel/user mode. The differences between secure mode and normal mode are following: * different irq stack frame. so need to change the definition of _irq_stack_frame, assembly code. * new aux regs, e.g, secure status(SEC_STAT), secure vector base (VECT_BASE_S) * interrupts and exceptions, secure mode has its own vector base; interrupt can be configured as secure or normal through the interrupt priority aux reg. * secure timers. Two secure timers (secure timer 0 and timer 1) are added.Here, for simplicity and backwards compatibility original internal timers (timer 0 and timer1) are used as sys clock of zephyr * on reset, the processor is in secure mode and secure vector base is used. Note: the mix of secure and normal mode is not supported, i.e. it's assumed that the processor is always in secure mode. Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
This commit is contained in:
parent
52e4c197f3
commit
528c960ae7
|
@ -149,6 +149,13 @@ config CODE_DENSITY
|
||||||
help
|
help
|
||||||
Enable code density option to get better code density
|
Enable code density option to get better code density
|
||||||
|
|
||||||
|
config ARC_HAS_SECURE
|
||||||
|
bool
|
||||||
|
# a hidden option
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
This opiton is enabled when ARC core supports secure mode
|
||||||
|
|
||||||
menu "ARC MPU Options"
|
menu "ARC MPU Options"
|
||||||
depends on CPU_HAS_MPU
|
depends on CPU_HAS_MPU
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,10 @@ static void invalidate_dcache(void)
|
||||||
|
|
||||||
static void adjust_vector_table_base(void)
|
static void adjust_vector_table_base(void)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_ARC_HAS_SECURE
|
||||||
|
#undef _ARC_V2_IRQ_VECT_BASE
|
||||||
|
#define _ARC_V2_IRQ_VECT_BASE _ARC_V2_IRQ_VECT_BASE_S
|
||||||
|
#endif
|
||||||
extern struct vector_table _VectorTable;
|
extern struct vector_table _VectorTable;
|
||||||
unsigned int vbr;
|
unsigned int vbr;
|
||||||
/* if the compiled-in vector table is different
|
/* if the compiled-in vector table is different
|
||||||
|
|
|
@ -192,12 +192,29 @@ _rirq_return_from_coop:
|
||||||
|
|
||||||
/* carve fake stack */
|
/* carve fake stack */
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARC_HAS_SECURE
|
||||||
|
/* a) status32/pc are already on the stack
|
||||||
|
* pc
|
||||||
|
* status
|
||||||
|
* b) make a space for sec_stat
|
||||||
|
* c) adjust the right place for sec_stat and pc
|
||||||
|
* pc
|
||||||
|
* sec_stat
|
||||||
|
* status
|
||||||
|
* d) a real value will be pushed in r0
|
||||||
|
*/
|
||||||
|
ld_s r0, [sp]
|
||||||
|
push_s r0
|
||||||
|
lr r0, [_ARC_V2_SEC_STAT]
|
||||||
|
st_s r0, [sp, 4]
|
||||||
|
sub sp, sp, (___isf_t_SIZEOF - 16)
|
||||||
|
#else
|
||||||
/*
|
/*
|
||||||
* a) status32/pc are already on the stack
|
* a) status32/pc are already on the stack
|
||||||
* b) a real value will be pushed in r0
|
* b) a real value will be pushed in r0
|
||||||
*/
|
*/
|
||||||
sub sp, sp, (___isf_t_SIZEOF - 12)
|
sub sp, sp, (___isf_t_SIZEOF - 12)
|
||||||
|
#endif
|
||||||
/* push return value on stack */
|
/* push return value on stack */
|
||||||
ld_s r0, [r2, _thread_offset_to_return_value]
|
ld_s r0, [r2, _thread_offset_to_return_value]
|
||||||
push_s r0
|
push_s r0
|
||||||
|
|
|
@ -164,7 +164,7 @@ _swap_already_in_irq:
|
||||||
.balign 4
|
.balign 4
|
||||||
_return_from_exc_irq:
|
_return_from_exc_irq:
|
||||||
_pop_irq_stack_frame
|
_pop_irq_stack_frame
|
||||||
sub_s sp, sp, 8
|
sub_s sp, sp, ___isf_t_status32_OFFSET - ___isf_t_pc_OFFSET + 4
|
||||||
|
|
||||||
_return_from_exc:
|
_return_from_exc:
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ _return_from_exc:
|
||||||
sr ilink, [_ARC_V2_ERET]
|
sr ilink, [_ARC_V2_ERET]
|
||||||
|
|
||||||
/* put status32 into estatus */
|
/* put status32 into estatus */
|
||||||
ld ilink, [sp, 4] /* status32 into ilink */
|
ld ilink, [sp, ___isf_t_status32_OFFSET - ___isf_t_pc_OFFSET] /* status32 into ilink */
|
||||||
sr ilink, [_ARC_V2_ERSTATUS]
|
sr ilink, [_ARC_V2_ERSTATUS]
|
||||||
add_s sp, sp, 8
|
add_s sp, sp, ___isf_t_status32_OFFSET - ___isf_t_pc_OFFSET + 4
|
||||||
rtie
|
rtie
|
||||||
|
|
|
@ -39,6 +39,41 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _ASMLANGUAGE
|
#ifndef _ASMLANGUAGE
|
||||||
|
#ifdef CONFIG_ARC_HAS_SECURE
|
||||||
|
struct _irq_stack_frame {
|
||||||
|
u32_t lp_end;
|
||||||
|
u32_t lp_start;
|
||||||
|
u32_t lp_count;
|
||||||
|
#ifdef CONFIG_CODE_DENSITY
|
||||||
|
/*
|
||||||
|
* Currently unsupported. This is where those registers are
|
||||||
|
* automatically pushed on the stack by the CPU when taking a regular
|
||||||
|
* IRQ.
|
||||||
|
*/
|
||||||
|
u32_t ei_base;
|
||||||
|
u32_t ldi_base;
|
||||||
|
u32_t jli_base;
|
||||||
|
#endif
|
||||||
|
u32_t r0;
|
||||||
|
u32_t r1;
|
||||||
|
u32_t r2;
|
||||||
|
u32_t r3;
|
||||||
|
u32_t r4;
|
||||||
|
u32_t r5;
|
||||||
|
u32_t r6;
|
||||||
|
u32_t r7;
|
||||||
|
u32_t r8;
|
||||||
|
u32_t r9;
|
||||||
|
u32_t r10;
|
||||||
|
u32_t r11;
|
||||||
|
u32_t r12;
|
||||||
|
u32_t r13;
|
||||||
|
u32_t blink;
|
||||||
|
u32_t pc;
|
||||||
|
u32_t sec_stat;
|
||||||
|
u32_t status32;
|
||||||
|
};
|
||||||
|
#else
|
||||||
struct _irq_stack_frame {
|
struct _irq_stack_frame {
|
||||||
u32_t r0;
|
u32_t r0;
|
||||||
u32_t r1;
|
u32_t r1;
|
||||||
|
@ -71,6 +106,7 @@ struct _irq_stack_frame {
|
||||||
u32_t pc;
|
u32_t pc;
|
||||||
u32_t status32;
|
u32_t status32;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct _irq_stack_frame _isf_t;
|
typedef struct _irq_stack_frame _isf_t;
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,11 @@ extern void *_VectorTable;
|
||||||
#include <kernel_structs.h>
|
#include <kernel_structs.h>
|
||||||
#include <v2/irq.h>
|
#include <v2/irq.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARC_HAS_SECURE
|
||||||
|
#undef _ARC_V2_IRQ_VECT_BASE
|
||||||
|
#define _ARC_V2_IRQ_VECT_BASE _ARC_V2_IRQ_VECT_BASE_S
|
||||||
|
#endif
|
||||||
|
|
||||||
static u32_t _arc_v2_irq_unit_device_power_state = DEVICE_PM_ACTIVE_STATE;
|
static u32_t _arc_v2_irq_unit_device_power_state = DEVICE_PM_ACTIVE_STATE;
|
||||||
struct arc_v2_irq_unit_ctx {
|
struct arc_v2_irq_unit_ctx {
|
||||||
u32_t irq_ctrl; /* Interrupt Context Saving Control Register. */
|
u32_t irq_ctrl; /* Interrupt Context Saving Control Register. */
|
||||||
|
@ -68,8 +73,14 @@ static int _arc_v2_irq_unit_init(struct device *unused)
|
||||||
*/
|
*/
|
||||||
for (irq = 16; irq < CONFIG_NUM_IRQS; irq++) {
|
for (irq = 16; irq < CONFIG_NUM_IRQS; irq++) {
|
||||||
_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
|
_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
|
||||||
|
#ifdef CONFIG_ARC_HAS_SECURE
|
||||||
|
_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY,
|
||||||
|
(CONFIG_NUM_IRQ_PRIO_LEVELS-1) |
|
||||||
|
_ARC_V2_IRQ_PRIORITY_SECURE); /* lowest priority */
|
||||||
|
#else
|
||||||
_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY,
|
_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY,
|
||||||
(CONFIG_NUM_IRQ_PRIO_LEVELS-1)); /* lowest priority */
|
(CONFIG_NUM_IRQ_PRIO_LEVELS-1)); /* lowest priority */
|
||||||
|
#endif
|
||||||
_arc_v2_aux_reg_write(_ARC_V2_IRQ_ENABLE, _ARC_V2_INT_DISABLE);
|
_arc_v2_aux_reg_write(_ARC_V2_IRQ_ENABLE, _ARC_V2_INT_DISABLE);
|
||||||
_arc_v2_aux_reg_write(_ARC_V2_IRQ_TRIGGER, _ARC_V2_INT_LEVEL);
|
_arc_v2_aux_reg_write(_ARC_V2_IRQ_TRIGGER, _ARC_V2_INT_LEVEL);
|
||||||
}
|
}
|
||||||
|
@ -138,8 +149,14 @@ static int _arc_v2_irq_unit_resume(struct device *dev)
|
||||||
*/
|
*/
|
||||||
for (irq = 16; irq < CONFIG_NUM_IRQS; irq++) {
|
for (irq = 16; irq < CONFIG_NUM_IRQS; irq++) {
|
||||||
_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
|
_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
|
||||||
|
#ifdef CONFIG_ARC_HAS_SECURE
|
||||||
|
_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY,
|
||||||
|
ctx.irq_config[irq - 16] >> 2 |
|
||||||
|
_ARC_V2_IRQ_PRIORITY_SECURE);
|
||||||
|
#else
|
||||||
_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY,
|
_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY,
|
||||||
ctx.irq_config[irq - 16] >> 2);
|
ctx.irq_config[irq - 16] >> 2);
|
||||||
|
#endif
|
||||||
_arc_v2_aux_reg_write(_ARC_V2_IRQ_TRIGGER,
|
_arc_v2_aux_reg_write(_ARC_V2_IRQ_TRIGGER,
|
||||||
(ctx.irq_config[irq - 16] >> 1) & BIT(0));
|
(ctx.irq_config[irq - 16] >> 1) & BIT(0));
|
||||||
_arc_v2_aux_reg_write(_ARC_V2_IRQ_ENABLE,
|
_arc_v2_aux_reg_write(_ARC_V2_IRQ_ENABLE,
|
||||||
|
|
|
@ -94,7 +94,13 @@ static inline void _arc_v2_irq_unit_int_disable(int irq)
|
||||||
static inline void _arc_v2_irq_unit_prio_set(int irq, unsigned char prio)
|
static inline void _arc_v2_irq_unit_prio_set(int irq, unsigned char prio)
|
||||||
{
|
{
|
||||||
_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
|
_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
|
||||||
|
#ifdef CONFIG_ARC_HAS_SECURE
|
||||||
|
/* if ARC has secure mode, all interrupt should be secure */
|
||||||
|
_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY, prio |
|
||||||
|
_ARC_V2_IRQ_PRIORITY_SECURE);
|
||||||
|
#else
|
||||||
_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY, prio);
|
_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY, prio);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -22,6 +22,7 @@ extern "C" {
|
||||||
#define _ARC_V2_LP_START 0x002
|
#define _ARC_V2_LP_START 0x002
|
||||||
#define _ARC_V2_LP_END 0x003
|
#define _ARC_V2_LP_END 0x003
|
||||||
#define _ARC_V2_IDENTITY 0x004
|
#define _ARC_V2_IDENTITY 0x004
|
||||||
|
#define _ARC_V2_SEC_STAT 0x09
|
||||||
#define _ARC_V2_STATUS32 0x00a
|
#define _ARC_V2_STATUS32 0x00a
|
||||||
#define _ARC_V2_STATUS32_P0 0x00b
|
#define _ARC_V2_STATUS32_P0 0x00b
|
||||||
#define _ARC_V2_AUX_IRQ_CTRL 0x00e
|
#define _ARC_V2_AUX_IRQ_CTRL 0x00e
|
||||||
|
@ -34,6 +35,7 @@ extern "C" {
|
||||||
#define _ARC_V2_TMR0_CONTROL 0x022
|
#define _ARC_V2_TMR0_CONTROL 0x022
|
||||||
#define _ARC_V2_TMR0_LIMIT 0x023
|
#define _ARC_V2_TMR0_LIMIT 0x023
|
||||||
#define _ARC_V2_IRQ_VECT_BASE 0x025
|
#define _ARC_V2_IRQ_VECT_BASE 0x025
|
||||||
|
#define _ARC_V2_IRQ_VECT_BASE_S 0x26
|
||||||
#define _ARC_V2_AUX_IRQ_ACT 0x043
|
#define _ARC_V2_AUX_IRQ_ACT 0x043
|
||||||
#define _ARC_V2_DC_IVDC 0x047
|
#define _ARC_V2_DC_IVDC 0x047
|
||||||
#define _ARC_V2_DC_CTRL 0x048
|
#define _ARC_V2_DC_CTRL 0x048
|
||||||
|
@ -113,6 +115,9 @@ extern "C" {
|
||||||
#define _ARC_V2_STATUS32_RB(x) ((x) << 16)
|
#define _ARC_V2_STATUS32_RB(x) ((x) << 16)
|
||||||
#define _ARC_V2_STATUS32_IE (1 << 31)
|
#define _ARC_V2_STATUS32_IE (1 << 31)
|
||||||
|
|
||||||
|
/* interrupt related bits */
|
||||||
|
#define _ARC_V2_IRQ_PRIORITY_SECURE 0x100
|
||||||
|
|
||||||
/* exception cause register masks */
|
/* exception cause register masks */
|
||||||
#define _ARC_V2_ECR_VECTOR(X) ((X & 0xff0000) >> 16)
|
#define _ARC_V2_ECR_VECTOR(X) ((X & 0xff0000) >> 16)
|
||||||
#define _ARC_V2_ECR_CODE(X) ((X & 0xff00) >> 8)
|
#define _ARC_V2_ECR_CODE(X) ((X & 0xff00) >> 8)
|
||||||
|
|
Loading…
Reference in a new issue