The new thread stack layout is as follow:
|---------------------|
| user stack |
|---------------------|
| stack guard (opt.) |
|---------------------|
| privilege stack |
-----------------------
For MPUv2
* user stack is aligned to the power of 2 of user stack size
* the stack guard is 2048 bytes
* the default size of privileg stack is 256 bytes.
For user thread, the following MPU regions are needded
* one region for user stack, no need of stack guard for user stack
* one region for stack guard when stack guard is enbaled
* regions for memory domain.
For kernel thread, the stack guard region will be at the top, adn
The user stack and privilege stack will be merged.
MPUv3 is the same as V2's layout, except no need of power of 2
alignment.
* reimplement the user mode enter function. Now it's possible for
kernel thread to drop privileg to user thread.
* add a separate entry for user thread
* bug fixes in the cleanup of regs when go to user mode
Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
92 lines
1.9 KiB
C
92 lines
1.9 KiB
C
/*
|
|
* Copyright (c) 2014-2016 Wind River Systems, Inc.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
* @brief Private kernel definitions
|
|
*
|
|
* This file contains private kernel structures definitions and various
|
|
* other definitions for the ARCv2 processor architecture.
|
|
*
|
|
* This file is also included by assembly language files which must #define
|
|
* _ASMLANGUAGE before including this header file. Note that kernel
|
|
* assembly source files obtains structure offset values via "absolute
|
|
* symbols" in the offsets.o module.
|
|
*/
|
|
|
|
#ifndef _kernel_arch_func__h_
|
|
#define _kernel_arch_func__h_
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#if !defined(_ASMLANGUAGE)
|
|
|
|
#ifdef CONFIG_CPU_ARCV2
|
|
#include <v2/cache.h>
|
|
#include <v2/irq.h>
|
|
#endif
|
|
|
|
static ALWAYS_INLINE void kernel_arch_init(void)
|
|
{
|
|
_irq_setup();
|
|
}
|
|
|
|
static ALWAYS_INLINE void
|
|
_set_thread_return_value(struct k_thread *thread, unsigned int value)
|
|
{
|
|
thread->arch.return_value = value;
|
|
}
|
|
|
|
static ALWAYS_INLINE int _is_in_isr(void)
|
|
{
|
|
u32_t act = _arc_v2_aux_reg_read(_ARC_V2_AUX_IRQ_ACT);
|
|
#if CONFIG_IRQ_OFFLOAD
|
|
/* Check if we're in a TRAP_S exception as well */
|
|
if (_arc_v2_aux_reg_read(_ARC_V2_STATUS32) & _ARC_V2_STATUS32_AE &&
|
|
_ARC_V2_ECR_VECTOR(_arc_v2_aux_reg_read(_ARC_V2_ECR)) == EXC_EV_TRAP
|
|
) {
|
|
return 1;
|
|
}
|
|
#endif
|
|
return ((act & 0xffff) != 0);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @brief Indicates the interrupt number of the highest priority
|
|
* active interrupt
|
|
*
|
|
* @return IRQ number
|
|
*/
|
|
static ALWAYS_INLINE int _INTERRUPT_CAUSE(void)
|
|
{
|
|
u32_t irq_num = _arc_v2_aux_reg_read(_ARC_V2_ICAUSE);
|
|
|
|
return irq_num;
|
|
}
|
|
|
|
|
|
extern void _thread_entry_wrapper(void);
|
|
extern void _user_thread_entry_wrapper(void);
|
|
|
|
static inline void _IntLibInit(void)
|
|
{
|
|
/* nothing needed, here because the kernel requires it */
|
|
}
|
|
|
|
extern void _arc_userspace_enter(k_thread_entry_t user_entry, void *p1,
|
|
void *p2, void *p3, u32_t stack, u32_t size);
|
|
|
|
#endif /* _ASMLANGUAGE */
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* _kernel_arch_func__h_ */
|