arch: arc: add user space support for arc
* add the implementation of syscall
* based on 'trap_s' intruction, id = 3
* add the privilege stack
* the privilege stack is allocted with thread stack
* for the kernel thread, the privilege stack is also a
part of thread stack, the start of stack can be configured
as stack guard
* for the user thread, no stack guard, when the user stack is
overflow, it will fall into kernel memory area which requires
kernel privilege, privilege violation will be raised
* modify the linker template and add MPU_ADDR_ALIGN
* add user space corresponding codes in mpu
* the user sp aux reg will be part of thread context
* When user thread is interruptted for the 1st time, the context is
saved in user stack (U bit of IRQ_CTLR is set to 1). When nest
interrupt comes, the context is saved in thread's privilege stack
* the arc_mpu_regions.c is moved to board folder, as it's board
specific
* the above codes have been tested through tests/kernel/mem_protect/
userspace for MPU version 2
Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
2018-01-23 10:13:09 +01:00
|
|
|
/*
|
2018-05-24 08:29:37 +02:00
|
|
|
* Copyright (c) 2018 Synopsys.
|
arch: arc: add user space support for arc
* add the implementation of syscall
* based on 'trap_s' intruction, id = 3
* add the privilege stack
* the privilege stack is allocted with thread stack
* for the kernel thread, the privilege stack is also a
part of thread stack, the start of stack can be configured
as stack guard
* for the user thread, no stack guard, when the user stack is
overflow, it will fall into kernel memory area which requires
kernel privilege, privilege violation will be raised
* modify the linker template and add MPU_ADDR_ALIGN
* add user space corresponding codes in mpu
* the user sp aux reg will be part of thread context
* When user thread is interruptted for the 1st time, the context is
saved in user stack (U bit of IRQ_CTLR is set to 1). When nest
interrupt comes, the context is saved in thread's privilege stack
* the arc_mpu_regions.c is moved to board folder, as it's board
specific
* the above codes have been tested through tests/kernel/mem_protect/
userspace for MPU version 2
Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
2018-01-23 10:13:09 +01:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <offsets_short.h>
|
|
|
|
#include <toolchain.h>
|
|
|
|
#include <linker/sections.h>
|
|
|
|
#include <kernel_structs.h>
|
|
|
|
#include <arch/cpu.h>
|
|
|
|
#include <syscall.h>
|
2018-06-01 08:00:22 +02:00
|
|
|
#include <swap_macros.h>
|
2019-06-13 11:21:52 +02:00
|
|
|
#include <v2/irq.h>
|
arch: arc: add user space support for arc
* add the implementation of syscall
* based on 'trap_s' intruction, id = 3
* add the privilege stack
* the privilege stack is allocted with thread stack
* for the kernel thread, the privilege stack is also a
part of thread stack, the start of stack can be configured
as stack guard
* for the user thread, no stack guard, when the user stack is
overflow, it will fall into kernel memory area which requires
kernel privilege, privilege violation will be raised
* modify the linker template and add MPU_ADDR_ALIGN
* add user space corresponding codes in mpu
* the user sp aux reg will be part of thread context
* When user thread is interruptted for the 1st time, the context is
saved in user stack (U bit of IRQ_CTLR is set to 1). When nest
interrupt comes, the context is saved in thread's privilege stack
* the arc_mpu_regions.c is moved to board folder, as it's board
specific
* the above codes have been tested through tests/kernel/mem_protect/
userspace for MPU version 2
Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
2018-01-23 10:13:09 +01:00
|
|
|
|
2018-02-02 07:31:11 +01:00
|
|
|
.macro clear_scratch_regs
|
2019-08-29 12:52:04 +02:00
|
|
|
mov_s r1, 0
|
|
|
|
mov_s r2, 0
|
|
|
|
mov_s r3, 0
|
|
|
|
mov_s r4, 0
|
|
|
|
mov_s r5, 0
|
|
|
|
mov_s r6, 0
|
|
|
|
mov_s r7, 0
|
|
|
|
mov_s r8, 0
|
|
|
|
mov_s r9, 0
|
|
|
|
mov_s r10, 0
|
|
|
|
mov_s r11, 0
|
|
|
|
mov_s r12, 0
|
2018-02-02 07:31:11 +01:00
|
|
|
.endm
|
|
|
|
|
|
|
|
.macro clear_callee_regs
|
2019-08-29 12:52:04 +02:00
|
|
|
mov_s r25, 0
|
|
|
|
mov_s r24, 0
|
|
|
|
mov_s r23, 0
|
|
|
|
mov_s r22, 0
|
|
|
|
mov_s r21, 0
|
|
|
|
mov_s r20, 0
|
|
|
|
mov_s r19, 0
|
|
|
|
mov_s r18, 0
|
|
|
|
mov_s r17, 0
|
|
|
|
mov_s r16, 0
|
|
|
|
|
|
|
|
mov_s r15, 0
|
|
|
|
mov_s r14, 0
|
|
|
|
mov_s r13, 0
|
2018-02-02 07:31:11 +01:00
|
|
|
.endm
|
|
|
|
|
2019-03-14 16:20:46 +01:00
|
|
|
GTEXT(z_arc_userspace_enter)
|
arch: arc: add user space support for arc
* add the implementation of syscall
* based on 'trap_s' intruction, id = 3
* add the privilege stack
* the privilege stack is allocted with thread stack
* for the kernel thread, the privilege stack is also a
part of thread stack, the start of stack can be configured
as stack guard
* for the user thread, no stack guard, when the user stack is
overflow, it will fall into kernel memory area which requires
kernel privilege, privilege violation will be raised
* modify the linker template and add MPU_ADDR_ALIGN
* add user space corresponding codes in mpu
* the user sp aux reg will be part of thread context
* When user thread is interruptted for the 1st time, the context is
saved in user stack (U bit of IRQ_CTLR is set to 1). When nest
interrupt comes, the context is saved in thread's privilege stack
* the arc_mpu_regions.c is moved to board folder, as it's board
specific
* the above codes have been tested through tests/kernel/mem_protect/
userspace for MPU version 2
Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
2018-01-23 10:13:09 +01:00
|
|
|
GTEXT(_arc_do_syscall)
|
2019-03-14 16:20:46 +01:00
|
|
|
GTEXT(z_user_thread_entry_wrapper)
|
2019-11-07 21:43:29 +01:00
|
|
|
GTEXT(arch_user_string_nlen)
|
2019-10-31 10:03:29 +01:00
|
|
|
GTEXT(z_arc_user_string_nlen_fault_start)
|
|
|
|
GTEXT(z_arc_user_string_nlen_fault_end)
|
|
|
|
GTEXT(z_arc_user_string_nlen_fixup)
|
2018-02-12 12:42:37 +01:00
|
|
|
/*
|
2019-03-08 22:19:05 +01:00
|
|
|
* @brief Wrapper for z_thread_entry in the case of user thread
|
2018-08-20 16:39:39 +02:00
|
|
|
* The init parameters are in privileged stack
|
2018-02-12 12:42:37 +01:00
|
|
|
*
|
|
|
|
* @return N/A
|
|
|
|
*/
|
2019-03-14 16:20:46 +01:00
|
|
|
SECTION_FUNC(TEXT, z_user_thread_entry_wrapper)
|
2019-06-13 11:21:52 +02:00
|
|
|
seti _ARC_V2_INIT_IRQ_LOCK_KEY
|
2018-08-20 16:39:39 +02:00
|
|
|
pop_s r3
|
|
|
|
pop_s r2
|
|
|
|
pop_s r1
|
|
|
|
pop_s r0
|
|
|
|
/* the start of user sp is in r5 */
|
|
|
|
pop r5
|
|
|
|
/* start of privilege stack in blink */
|
2019-08-29 12:52:04 +02:00
|
|
|
mov_s blink, sp
|
2018-08-20 16:39:39 +02:00
|
|
|
|
|
|
|
st.aw r0, [r5, -4]
|
|
|
|
st.aw r1, [r5, -4]
|
|
|
|
st.aw r2, [r5, -4]
|
|
|
|
st.aw r3, [r5, -4]
|
2018-02-12 12:42:37 +01:00
|
|
|
|
|
|
|
/*
|
2018-05-23 19:22:26 +02:00
|
|
|
* when CONFIG_INIT_STACKS is enable, stack will be initialized
|
2019-03-14 16:20:46 +01:00
|
|
|
* in z_new_thread_init.
|
2018-02-12 12:42:37 +01:00
|
|
|
*/
|
|
|
|
j _arc_go_to_user_space
|
|
|
|
|
arch: arc: add user space support for arc
* add the implementation of syscall
* based on 'trap_s' intruction, id = 3
* add the privilege stack
* the privilege stack is allocted with thread stack
* for the kernel thread, the privilege stack is also a
part of thread stack, the start of stack can be configured
as stack guard
* for the user thread, no stack guard, when the user stack is
overflow, it will fall into kernel memory area which requires
kernel privilege, privilege violation will be raised
* modify the linker template and add MPU_ADDR_ALIGN
* add user space corresponding codes in mpu
* the user sp aux reg will be part of thread context
* When user thread is interruptted for the 1st time, the context is
saved in user stack (U bit of IRQ_CTLR is set to 1). When nest
interrupt comes, the context is saved in thread's privilege stack
* the arc_mpu_regions.c is moved to board folder, as it's board
specific
* the above codes have been tested through tests/kernel/mem_protect/
userspace for MPU version 2
Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
2018-01-23 10:13:09 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* User space entry function
|
|
|
|
*
|
|
|
|
* This function is the entry point to user mode from privileged execution.
|
|
|
|
* The conversion is one way, and threads which transition to user mode do
|
|
|
|
* not transition back later, unless they are doing system calls.
|
|
|
|
*
|
|
|
|
*/
|
2019-03-14 16:20:46 +01:00
|
|
|
SECTION_FUNC(TEXT, z_arc_userspace_enter)
|
arch: arc: add user space support for arc
* add the implementation of syscall
* based on 'trap_s' intruction, id = 3
* add the privilege stack
* the privilege stack is allocted with thread stack
* for the kernel thread, the privilege stack is also a
part of thread stack, the start of stack can be configured
as stack guard
* for the user thread, no stack guard, when the user stack is
overflow, it will fall into kernel memory area which requires
kernel privilege, privilege violation will be raised
* modify the linker template and add MPU_ADDR_ALIGN
* add user space corresponding codes in mpu
* the user sp aux reg will be part of thread context
* When user thread is interruptted for the 1st time, the context is
saved in user stack (U bit of IRQ_CTLR is set to 1). When nest
interrupt comes, the context is saved in thread's privilege stack
* the arc_mpu_regions.c is moved to board folder, as it's board
specific
* the above codes have been tested through tests/kernel/mem_protect/
userspace for MPU version 2
Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
2018-01-23 10:13:09 +01:00
|
|
|
/*
|
|
|
|
* In ARCv2, the U bit can only be set through exception return
|
|
|
|
*/
|
2018-07-19 10:59:21 +02:00
|
|
|
/* disable stack checking as the stack should be initialized */
|
2020-02-29 15:58:22 +01:00
|
|
|
_disable_stack_checking blink
|
|
|
|
|
arch: arc: add user space support for arc
* add the implementation of syscall
* based on 'trap_s' intruction, id = 3
* add the privilege stack
* the privilege stack is allocted with thread stack
* for the kernel thread, the privilege stack is also a
part of thread stack, the start of stack can be configured
as stack guard
* for the user thread, no stack guard, when the user stack is
overflow, it will fall into kernel memory area which requires
kernel privilege, privilege violation will be raised
* modify the linker template and add MPU_ADDR_ALIGN
* add user space corresponding codes in mpu
* the user sp aux reg will be part of thread context
* When user thread is interruptted for the 1st time, the context is
saved in user stack (U bit of IRQ_CTLR is set to 1). When nest
interrupt comes, the context is saved in thread's privilege stack
* the arc_mpu_regions.c is moved to board folder, as it's board
specific
* the above codes have been tested through tests/kernel/mem_protect/
userspace for MPU version 2
Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
2018-01-23 10:13:09 +01:00
|
|
|
/* the end of user stack in r5 */
|
|
|
|
add r5, r4, r5
|
2020-04-18 05:42:36 +02:00
|
|
|
/* get start of privilege stack, r6 points to current thread */
|
2020-04-02 16:53:06 +02:00
|
|
|
ld blink, [r6, _thread_offset_to_priv_stack_start]
|
|
|
|
add blink, blink, CONFIG_PRIVILEGED_STACK_SIZE
|
|
|
|
|
2019-08-29 12:52:04 +02:00
|
|
|
mov_s sp, r5
|
2018-02-12 12:42:37 +01:00
|
|
|
|
|
|
|
push_s r0
|
|
|
|
push_s r1
|
|
|
|
push_s r2
|
|
|
|
push_s r3
|
|
|
|
|
|
|
|
mov r5, sp /* skip r0, r1, r2, r3 */
|
arch: arc: add user space support for arc
* add the implementation of syscall
* based on 'trap_s' intruction, id = 3
* add the privilege stack
* the privilege stack is allocted with thread stack
* for the kernel thread, the privilege stack is also a
part of thread stack, the start of stack can be configured
as stack guard
* for the user thread, no stack guard, when the user stack is
overflow, it will fall into kernel memory area which requires
kernel privilege, privilege violation will be raised
* modify the linker template and add MPU_ADDR_ALIGN
* add user space corresponding codes in mpu
* the user sp aux reg will be part of thread context
* When user thread is interruptted for the 1st time, the context is
saved in user stack (U bit of IRQ_CTLR is set to 1). When nest
interrupt comes, the context is saved in thread's privilege stack
* the arc_mpu_regions.c is moved to board folder, as it's board
specific
* the above codes have been tested through tests/kernel/mem_protect/
userspace for MPU version 2
Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
2018-01-23 10:13:09 +01:00
|
|
|
|
2020-02-29 15:58:22 +01:00
|
|
|
/* to avoid the leakage of kernel info, the thread stack needs to be
|
|
|
|
* re-initialized
|
|
|
|
*/
|
arch: arc: add user space support for arc
* add the implementation of syscall
* based on 'trap_s' intruction, id = 3
* add the privilege stack
* the privilege stack is allocted with thread stack
* for the kernel thread, the privilege stack is also a
part of thread stack, the start of stack can be configured
as stack guard
* for the user thread, no stack guard, when the user stack is
overflow, it will fall into kernel memory area which requires
kernel privilege, privilege violation will be raised
* modify the linker template and add MPU_ADDR_ALIGN
* add user space corresponding codes in mpu
* the user sp aux reg will be part of thread context
* When user thread is interruptted for the 1st time, the context is
saved in user stack (U bit of IRQ_CTLR is set to 1). When nest
interrupt comes, the context is saved in thread's privilege stack
* the arc_mpu_regions.c is moved to board folder, as it's board
specific
* the above codes have been tested through tests/kernel/mem_protect/
userspace for MPU version 2
Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
2018-01-23 10:13:09 +01:00
|
|
|
#ifdef CONFIG_INIT_STACKS
|
2019-08-29 12:52:04 +02:00
|
|
|
mov_s r0, 0xaaaaaaaa
|
arch: arc: add user space support for arc
* add the implementation of syscall
* based on 'trap_s' intruction, id = 3
* add the privilege stack
* the privilege stack is allocted with thread stack
* for the kernel thread, the privilege stack is also a
part of thread stack, the start of stack can be configured
as stack guard
* for the user thread, no stack guard, when the user stack is
overflow, it will fall into kernel memory area which requires
kernel privilege, privilege violation will be raised
* modify the linker template and add MPU_ADDR_ALIGN
* add user space corresponding codes in mpu
* the user sp aux reg will be part of thread context
* When user thread is interruptted for the 1st time, the context is
saved in user stack (U bit of IRQ_CTLR is set to 1). When nest
interrupt comes, the context is saved in thread's privilege stack
* the arc_mpu_regions.c is moved to board folder, as it's board
specific
* the above codes have been tested through tests/kernel/mem_protect/
userspace for MPU version 2
Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
2018-01-23 10:13:09 +01:00
|
|
|
#else
|
2019-08-29 12:52:04 +02:00
|
|
|
mov_s r0, 0x0
|
arch: arc: add user space support for arc
* add the implementation of syscall
* based on 'trap_s' intruction, id = 3
* add the privilege stack
* the privilege stack is allocted with thread stack
* for the kernel thread, the privilege stack is also a
part of thread stack, the start of stack can be configured
as stack guard
* for the user thread, no stack guard, when the user stack is
overflow, it will fall into kernel memory area which requires
kernel privilege, privilege violation will be raised
* modify the linker template and add MPU_ADDR_ALIGN
* add user space corresponding codes in mpu
* the user sp aux reg will be part of thread context
* When user thread is interruptted for the 1st time, the context is
saved in user stack (U bit of IRQ_CTLR is set to 1). When nest
interrupt comes, the context is saved in thread's privilege stack
* the arc_mpu_regions.c is moved to board folder, as it's board
specific
* the above codes have been tested through tests/kernel/mem_protect/
userspace for MPU version 2
Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
2018-01-23 10:13:09 +01:00
|
|
|
#endif
|
|
|
|
_clear_user_stack:
|
|
|
|
st.ab r0, [r4, 4]
|
|
|
|
cmp r4, r5
|
|
|
|
jlt _clear_user_stack
|
|
|
|
|
2020-02-29 15:58:22 +01:00
|
|
|
/* reload the stack checking regs as the original kernel stack
|
2020-03-02 06:45:34 +01:00
|
|
|
* becomes user stack
|
2020-02-29 15:58:22 +01:00
|
|
|
*/
|
2018-06-01 08:00:22 +02:00
|
|
|
#ifdef CONFIG_ARC_STACK_CHECKING
|
2020-03-02 06:45:34 +01:00
|
|
|
/* current thread in r6, SMP case is also considered */
|
|
|
|
mov r2, r6
|
2018-06-01 08:00:22 +02:00
|
|
|
|
|
|
|
_load_stack_check_regs
|
|
|
|
|
2020-02-29 15:58:22 +01:00
|
|
|
_enable_stack_checking r0
|
2018-07-19 10:59:21 +02:00
|
|
|
#endif
|
2018-06-01 08:00:22 +02:00
|
|
|
|
2020-02-29 15:58:22 +01:00
|
|
|
/* the following codes are used to switch from kernel mode
|
|
|
|
* to user mode by fake exception, because U bit can only be set
|
|
|
|
* by exception
|
|
|
|
*/
|
2018-02-12 12:42:37 +01:00
|
|
|
_arc_go_to_user_space:
|
arch: arc: add user space support for arc
* add the implementation of syscall
* based on 'trap_s' intruction, id = 3
* add the privilege stack
* the privilege stack is allocted with thread stack
* for the kernel thread, the privilege stack is also a
part of thread stack, the start of stack can be configured
as stack guard
* for the user thread, no stack guard, when the user stack is
overflow, it will fall into kernel memory area which requires
kernel privilege, privilege violation will be raised
* modify the linker template and add MPU_ADDR_ALIGN
* add user space corresponding codes in mpu
* the user sp aux reg will be part of thread context
* When user thread is interruptted for the 1st time, the context is
saved in user stack (U bit of IRQ_CTLR is set to 1). When nest
interrupt comes, the context is saved in thread's privilege stack
* the arc_mpu_regions.c is moved to board folder, as it's board
specific
* the above codes have been tested through tests/kernel/mem_protect/
userspace for MPU version 2
Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
2018-01-23 10:13:09 +01:00
|
|
|
lr r0, [_ARC_V2_STATUS32]
|
|
|
|
bset r0, r0, _ARC_V2_STATUS32_U_BIT
|
|
|
|
|
2019-08-29 12:52:04 +02:00
|
|
|
mov_s r1, z_thread_entry_wrapper1
|
arch: arc: add user space support for arc
* add the implementation of syscall
* based on 'trap_s' intruction, id = 3
* add the privilege stack
* the privilege stack is allocted with thread stack
* for the kernel thread, the privilege stack is also a
part of thread stack, the start of stack can be configured
as stack guard
* for the user thread, no stack guard, when the user stack is
overflow, it will fall into kernel memory area which requires
kernel privilege, privilege violation will be raised
* modify the linker template and add MPU_ADDR_ALIGN
* add user space corresponding codes in mpu
* the user sp aux reg will be part of thread context
* When user thread is interruptted for the 1st time, the context is
saved in user stack (U bit of IRQ_CTLR is set to 1). When nest
interrupt comes, the context is saved in thread's privilege stack
* the arc_mpu_regions.c is moved to board folder, as it's board
specific
* the above codes have been tested through tests/kernel/mem_protect/
userspace for MPU version 2
Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
2018-01-23 10:13:09 +01:00
|
|
|
|
|
|
|
sr r0, [_ARC_V2_ERSTATUS]
|
|
|
|
sr r1, [_ARC_V2_ERET]
|
|
|
|
|
2019-07-17 00:20:11 +02:00
|
|
|
/* fake exception return */
|
|
|
|
lr r0, [_ARC_V2_STATUS32]
|
2020-03-02 06:56:36 +01:00
|
|
|
bset r0, r0, _ARC_V2_STATUS32_AE_BIT
|
2019-07-17 00:20:11 +02:00
|
|
|
kflag r0
|
|
|
|
|
2019-08-01 06:39:35 +02:00
|
|
|
/* when exception returns from kernel to user, sp and _ARC_V2_USER_SP
|
|
|
|
* /_ARC_V2_SECU_SP will be switched
|
|
|
|
*/
|
|
|
|
#if defined(CONFIG_ARC_HAS_SECURE) && defined(CONFIG_ARC_SECURE_FIRMWARE)
|
2018-02-01 09:34:47 +01:00
|
|
|
lr r0, [_ARC_V2_SEC_STAT]
|
|
|
|
/* the mode returns from exception return is secure mode */
|
|
|
|
bset r0, r0, 31
|
|
|
|
sr r0, [_ARC_V2_ERSEC_STAT]
|
|
|
|
sr r5, [_ARC_V2_SEC_U_SP]
|
|
|
|
#else
|
arch: arc: add user space support for arc
* add the implementation of syscall
* based on 'trap_s' intruction, id = 3
* add the privilege stack
* the privilege stack is allocted with thread stack
* for the kernel thread, the privilege stack is also a
part of thread stack, the start of stack can be configured
as stack guard
* for the user thread, no stack guard, when the user stack is
overflow, it will fall into kernel memory area which requires
kernel privilege, privilege violation will be raised
* modify the linker template and add MPU_ADDR_ALIGN
* add user space corresponding codes in mpu
* the user sp aux reg will be part of thread context
* When user thread is interruptted for the 1st time, the context is
saved in user stack (U bit of IRQ_CTLR is set to 1). When nest
interrupt comes, the context is saved in thread's privilege stack
* the arc_mpu_regions.c is moved to board folder, as it's board
specific
* the above codes have been tested through tests/kernel/mem_protect/
userspace for MPU version 2
Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
2018-01-23 10:13:09 +01:00
|
|
|
sr r5, [_ARC_V2_USER_SP]
|
2018-02-01 09:34:47 +01:00
|
|
|
#endif
|
2019-08-29 12:52:04 +02:00
|
|
|
mov_s sp, blink
|
2018-02-02 07:31:11 +01:00
|
|
|
|
2019-08-29 12:52:04 +02:00
|
|
|
mov_s r0, 0
|
2018-02-02 07:31:11 +01:00
|
|
|
|
|
|
|
clear_callee_regs
|
|
|
|
|
|
|
|
clear_scratch_regs
|
|
|
|
|
2019-08-29 12:52:04 +02:00
|
|
|
mov_s fp, 0
|
|
|
|
mov_s r29, 0
|
|
|
|
mov_s r30, 0
|
|
|
|
mov_s blink, 0
|
2018-05-24 08:29:37 +02:00
|
|
|
|
2018-06-27 10:40:30 +02:00
|
|
|
#ifdef CONFIG_EXECUTION_BENCHMARKING
|
2020-02-29 15:58:22 +01:00
|
|
|
bl read_timer_end_of_userspace_enter
|
|
|
|
#endif
|
2018-06-27 10:40:30 +02:00
|
|
|
|
arch: arc: add user space support for arc
* add the implementation of syscall
* based on 'trap_s' intruction, id = 3
* add the privilege stack
* the privilege stack is allocted with thread stack
* for the kernel thread, the privilege stack is also a
part of thread stack, the start of stack can be configured
as stack guard
* for the user thread, no stack guard, when the user stack is
overflow, it will fall into kernel memory area which requires
kernel privilege, privilege violation will be raised
* modify the linker template and add MPU_ADDR_ALIGN
* add user space corresponding codes in mpu
* the user sp aux reg will be part of thread context
* When user thread is interruptted for the 1st time, the context is
saved in user stack (U bit of IRQ_CTLR is set to 1). When nest
interrupt comes, the context is saved in thread's privilege stack
* the arc_mpu_regions.c is moved to board folder, as it's board
specific
* the above codes have been tested through tests/kernel/mem_protect/
userspace for MPU version 2
Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
2018-01-23 10:13:09 +01:00
|
|
|
rtie
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* Userspace system call function
|
|
|
|
*
|
|
|
|
* This function is used to do system calls from unprivileged code. This
|
|
|
|
* function is responsible for the following:
|
|
|
|
* 1) Dispatching the system call
|
|
|
|
* 2) Restoring stack and calling back to the caller of the system call
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
SECTION_FUNC(TEXT, _arc_do_syscall)
|
2019-09-26 15:13:42 +02:00
|
|
|
/*
|
|
|
|
* r0-r5: arg1-arg6, r6 is call id which is already checked in
|
|
|
|
* trap_s handler, r7 is the system call stack frame pointer
|
|
|
|
* need to recover r0, r1, r2 because they will be modified in
|
|
|
|
* _create_irq_stack_frame. If a specific syscall frame (different
|
|
|
|
* with irq stack frame) is defined, the cover of r0, r1, r2 can be
|
|
|
|
* optimized.
|
|
|
|
*/
|
|
|
|
ld_s r0, [sp, ___isf_t_r0_OFFSET]
|
|
|
|
ld_s r1, [sp, ___isf_t_r1_OFFSET]
|
|
|
|
ld_s r2, [sp, ___isf_t_r2_OFFSET]
|
|
|
|
|
|
|
|
mov r7, sp
|
arch: arc: add user space support for arc
* add the implementation of syscall
* based on 'trap_s' intruction, id = 3
* add the privilege stack
* the privilege stack is allocted with thread stack
* for the kernel thread, the privilege stack is also a
part of thread stack, the start of stack can be configured
as stack guard
* for the user thread, no stack guard, when the user stack is
overflow, it will fall into kernel memory area which requires
kernel privilege, privilege violation will be raised
* modify the linker template and add MPU_ADDR_ALIGN
* add user space corresponding codes in mpu
* the user sp aux reg will be part of thread context
* When user thread is interruptted for the 1st time, the context is
saved in user stack (U bit of IRQ_CTLR is set to 1). When nest
interrupt comes, the context is saved in thread's privilege stack
* the arc_mpu_regions.c is moved to board folder, as it's board
specific
* the above codes have been tested through tests/kernel/mem_protect/
userspace for MPU version 2
Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
2018-01-23 10:13:09 +01:00
|
|
|
|
2019-08-29 12:52:04 +02:00
|
|
|
mov_s blink, _k_syscall_table
|
2018-02-12 12:42:37 +01:00
|
|
|
ld.as r6, [blink, r6]
|
arch: arc: add user space support for arc
* add the implementation of syscall
* based on 'trap_s' intruction, id = 3
* add the privilege stack
* the privilege stack is allocted with thread stack
* for the kernel thread, the privilege stack is also a
part of thread stack, the start of stack can be configured
as stack guard
* for the user thread, no stack guard, when the user stack is
overflow, it will fall into kernel memory area which requires
kernel privilege, privilege violation will be raised
* modify the linker template and add MPU_ADDR_ALIGN
* add user space corresponding codes in mpu
* the user sp aux reg will be part of thread context
* When user thread is interruptted for the 1st time, the context is
saved in user stack (U bit of IRQ_CTLR is set to 1). When nest
interrupt comes, the context is saved in thread's privilege stack
* the arc_mpu_regions.c is moved to board folder, as it's board
specific
* the above codes have been tested through tests/kernel/mem_protect/
userspace for MPU version 2
Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
2018-01-23 10:13:09 +01:00
|
|
|
|
2018-02-12 12:42:37 +01:00
|
|
|
jl [r6]
|
arch: arc: add user space support for arc
* add the implementation of syscall
* based on 'trap_s' intruction, id = 3
* add the privilege stack
* the privilege stack is allocted with thread stack
* for the kernel thread, the privilege stack is also a
part of thread stack, the start of stack can be configured
as stack guard
* for the user thread, no stack guard, when the user stack is
overflow, it will fall into kernel memory area which requires
kernel privilege, privilege violation will be raised
* modify the linker template and add MPU_ADDR_ALIGN
* add user space corresponding codes in mpu
* the user sp aux reg will be part of thread context
* When user thread is interruptted for the 1st time, the context is
saved in user stack (U bit of IRQ_CTLR is set to 1). When nest
interrupt comes, the context is saved in thread's privilege stack
* the arc_mpu_regions.c is moved to board folder, as it's board
specific
* the above codes have been tested through tests/kernel/mem_protect/
userspace for MPU version 2
Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
2018-01-23 10:13:09 +01:00
|
|
|
|
2019-09-26 15:13:42 +02:00
|
|
|
/* save return value */
|
|
|
|
st_s r0, [sp, ___isf_t_r0_OFFSET]
|
2018-05-24 08:29:37 +02:00
|
|
|
|
2019-08-29 12:52:04 +02:00
|
|
|
mov_s r29, 0
|
|
|
|
mov_s r30, 0
|
2018-05-24 08:29:37 +02:00
|
|
|
|
arch: arc: add user space support for arc
* add the implementation of syscall
* based on 'trap_s' intruction, id = 3
* add the privilege stack
* the privilege stack is allocted with thread stack
* for the kernel thread, the privilege stack is also a
part of thread stack, the start of stack can be configured
as stack guard
* for the user thread, no stack guard, when the user stack is
overflow, it will fall into kernel memory area which requires
kernel privilege, privilege violation will be raised
* modify the linker template and add MPU_ADDR_ALIGN
* add user space corresponding codes in mpu
* the user sp aux reg will be part of thread context
* When user thread is interruptted for the 1st time, the context is
saved in user stack (U bit of IRQ_CTLR is set to 1). When nest
interrupt comes, the context is saved in thread's privilege stack
* the arc_mpu_regions.c is moved to board folder, as it's board
specific
* the above codes have been tested through tests/kernel/mem_protect/
userspace for MPU version 2
Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
2018-01-23 10:13:09 +01:00
|
|
|
/* through fake exception return, go back to the caller */
|
2019-09-26 15:13:42 +02:00
|
|
|
lr r0, [_ARC_V2_STATUS32]
|
|
|
|
bset r0, r0, _ARC_V2_STATUS32_AE_BIT
|
|
|
|
kflag r0
|
|
|
|
|
|
|
|
|
2019-08-01 06:39:35 +02:00
|
|
|
#ifdef CONFIG_ARC_SECURE_FIRMWARE
|
2019-09-26 15:13:42 +02:00
|
|
|
ld_s r0, [sp, ___isf_t_sec_stat_OFFSET]
|
|
|
|
sr r0,[_ARC_V2_ERSEC_STAT]
|
2018-05-24 08:29:37 +02:00
|
|
|
#endif
|
2019-09-26 15:13:42 +02:00
|
|
|
ld_s r0, [sp, ___isf_t_status32_OFFSET]
|
|
|
|
sr r0,[_ARC_V2_ERSTATUS]
|
2018-02-02 07:31:11 +01:00
|
|
|
|
2019-09-26 15:13:42 +02:00
|
|
|
ld_s r0, [sp, ___isf_t_pc_OFFSET] /* eret into pc */
|
|
|
|
sr r0,[_ARC_V2_ERET]
|
2018-02-02 07:31:11 +01:00
|
|
|
|
2019-09-26 15:13:42 +02:00
|
|
|
_pop_irq_stack_frame
|
2018-06-23 00:15:12 +02:00
|
|
|
|
2019-09-26 15:13:42 +02:00
|
|
|
rtie
|
2018-06-23 00:15:12 +02:00
|
|
|
|
|
|
|
/*
|
2019-11-07 21:43:29 +01:00
|
|
|
* size_t arch_user_string_nlen(const char *s, size_t maxsize, int *err_arg)
|
2018-06-23 00:15:12 +02:00
|
|
|
*/
|
2019-11-07 21:43:29 +01:00
|
|
|
SECTION_FUNC(TEXT, arch_user_string_nlen)
|
2018-06-23 00:15:12 +02:00
|
|
|
/* int err; */
|
|
|
|
sub_s sp,sp,0x4
|
|
|
|
|
|
|
|
/* Initial error value (-1 failure), store at [sp,0] */
|
|
|
|
mov_s r3, -1
|
|
|
|
st_s r3, [sp, 0]
|
|
|
|
|
|
|
|
/* Loop setup.
|
|
|
|
* r12 (position locator) = s - 1
|
|
|
|
* r0 (length counter return value)) = 0
|
|
|
|
* lp_count = maxsize + 1
|
|
|
|
* */
|
|
|
|
sub r12, r0, 0x1
|
|
|
|
mov_s r0, 0
|
|
|
|
add_s r1, r1, 1
|
|
|
|
mov lp_count, r1
|
|
|
|
|
|
|
|
strlen_loop:
|
2019-10-31 10:03:29 +01:00
|
|
|
z_arc_user_string_nlen_fault_start:
|
2018-06-23 00:15:12 +02:00
|
|
|
/* is the byte at ++r12 a NULL? if so, we're done. Might fault! */
|
|
|
|
ldb.aw r1, [r12, 1]
|
|
|
|
|
2019-10-31 10:03:29 +01:00
|
|
|
z_arc_user_string_nlen_fault_end:
|
2018-06-23 00:15:12 +02:00
|
|
|
brne_s r1, 0, not_null
|
|
|
|
|
|
|
|
strlen_done:
|
|
|
|
/* Success, set err to 0 */
|
|
|
|
mov_s r1, 0
|
|
|
|
st_s r1, [sp, 0]
|
|
|
|
|
2019-10-31 10:03:29 +01:00
|
|
|
z_arc_user_string_nlen_fixup:
|
2018-06-23 00:15:12 +02:00
|
|
|
/* *err_arg = err; Pop stack and return */
|
|
|
|
ld_s r1, [sp, 0]
|
|
|
|
add_s sp, sp, 4
|
|
|
|
j_s.d [blink]
|
|
|
|
st_s r1, [r2, 0]
|
|
|
|
|
|
|
|
not_null:
|
|
|
|
/* check if we've hit the maximum, if so we're done. */
|
|
|
|
brne.d.nt lp_count, 0x1, inc_len
|
|
|
|
sub lp_count, lp_count, 0x1
|
|
|
|
b_s strlen_done
|
|
|
|
|
|
|
|
inc_len:
|
|
|
|
/* increment length measurement, loop again */
|
|
|
|
add_s r0, r0, 1
|
|
|
|
b_s strlen_loop
|