mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
298 lines
6.5 KiB
298 lines
6.5 KiB
/* SPDX-License-Identifier: GPL-2.0-only */ |
|
/* |
|
* Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com) |
|
* Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) |
|
*/ |
|
|
|
#ifndef __ASM_ARC_ENTRY_H |
|
#define __ASM_ARC_ENTRY_H |
|
|
|
#include <asm/unistd.h> /* For NR_syscalls defination */ |
|
#include <asm/arcregs.h> |
|
#include <asm/ptrace.h> |
|
#include <asm/processor.h> /* For VMALLOC_START */ |
|
#include <asm/mmu.h> |
|
|
|
#ifdef CONFIG_ISA_ARCOMPACT |
|
#include <asm/entry-compact.h> /* ISA specific bits */ |
|
#else |
|
#include <asm/entry-arcv2.h> |
|
#endif |
|
|
|
/* Note on the LD/ST addr modes with addr reg wback |
|
* |
|
* LD.a same as LD.aw |
|
* |
|
* LD.a reg1, [reg2, x] => Pre Incr |
|
* Eff Addr for load = [reg2 + x] |
|
* |
|
* LD.ab reg1, [reg2, x] => Post Incr |
|
* Eff Addr for load = [reg2] |
|
*/ |
|
|
|
.macro PUSH reg |
|
st.a \reg, [sp, -4] |
|
.endm |
|
|
|
.macro PUSHAX aux |
|
lr r9, [\aux] |
|
PUSH r9 |
|
.endm |
|
|
|
.macro POP reg |
|
ld.ab \reg, [sp, 4] |
|
.endm |
|
|
|
.macro POPAX aux |
|
POP r9 |
|
sr r9, [\aux] |
|
.endm |
|
|
|
/*-------------------------------------------------------------- |
|
* Helpers to save/restore Scratch Regs: |
|
* used by Interrupt/Exception Prologue/Epilogue |
|
*-------------------------------------------------------------*/ |
|
.macro SAVE_R0_TO_R12 |
|
PUSH r0 |
|
PUSH r1 |
|
PUSH r2 |
|
PUSH r3 |
|
PUSH r4 |
|
PUSH r5 |
|
PUSH r6 |
|
PUSH r7 |
|
PUSH r8 |
|
PUSH r9 |
|
PUSH r10 |
|
PUSH r11 |
|
PUSH r12 |
|
.endm |
|
|
|
.macro RESTORE_R12_TO_R0 |
|
POP r12 |
|
POP r11 |
|
POP r10 |
|
POP r9 |
|
POP r8 |
|
POP r7 |
|
POP r6 |
|
POP r5 |
|
POP r4 |
|
POP r3 |
|
POP r2 |
|
POP r1 |
|
POP r0 |
|
|
|
.endm |
|
|
|
/*-------------------------------------------------------------- |
|
* Helpers to save/restore callee-saved regs: |
|
* used by several macros below |
|
*-------------------------------------------------------------*/ |
|
.macro SAVE_R13_TO_R24 |
|
PUSH r13 |
|
PUSH r14 |
|
PUSH r15 |
|
PUSH r16 |
|
PUSH r17 |
|
PUSH r18 |
|
PUSH r19 |
|
PUSH r20 |
|
PUSH r21 |
|
PUSH r22 |
|
PUSH r23 |
|
PUSH r24 |
|
.endm |
|
|
|
.macro RESTORE_R24_TO_R13 |
|
POP r24 |
|
POP r23 |
|
POP r22 |
|
POP r21 |
|
POP r20 |
|
POP r19 |
|
POP r18 |
|
POP r17 |
|
POP r16 |
|
POP r15 |
|
POP r14 |
|
POP r13 |
|
.endm |
|
|
|
/*-------------------------------------------------------------- |
|
* Collect User Mode callee regs as struct callee_regs - needed by |
|
* fork/do_signal/unaligned-access-emulation. |
|
* (By default only scratch regs are saved on entry to kernel) |
|
* |
|
* Special handling for r25 if used for caching Task Pointer. |
|
* It would have been saved in task->thread.user_r25 already, but to keep |
|
* the interface same it is copied into regular r25 placeholder in |
|
* struct callee_regs. |
|
*-------------------------------------------------------------*/ |
|
.macro SAVE_CALLEE_SAVED_USER |
|
|
|
mov r12, sp ; save SP as ref to pt_regs |
|
SAVE_R13_TO_R24 |
|
|
|
#ifdef CONFIG_ARC_CURR_IN_REG |
|
; Retrieve orig r25 and save it with rest of callee_regs |
|
ld r12, [r12, PT_user_r25] |
|
PUSH r12 |
|
#else |
|
PUSH r25 |
|
#endif |
|
|
|
.endm |
|
|
|
/*-------------------------------------------------------------- |
|
* Save kernel Mode callee regs at the time of Contect Switch. |
|
* |
|
* Special handling for r25 if used for caching Task Pointer. |
|
* Kernel simply skips saving it since it will be loaded with |
|
* incoming task pointer anyways |
|
*-------------------------------------------------------------*/ |
|
.macro SAVE_CALLEE_SAVED_KERNEL |
|
|
|
SAVE_R13_TO_R24 |
|
|
|
#ifdef CONFIG_ARC_CURR_IN_REG |
|
sub sp, sp, 4 |
|
#else |
|
PUSH r25 |
|
#endif |
|
.endm |
|
|
|
/*-------------------------------------------------------------- |
|
* Opposite of SAVE_CALLEE_SAVED_KERNEL |
|
*-------------------------------------------------------------*/ |
|
.macro RESTORE_CALLEE_SAVED_KERNEL |
|
|
|
#ifdef CONFIG_ARC_CURR_IN_REG |
|
add sp, sp, 4 /* skip usual r25 placeholder */ |
|
#else |
|
POP r25 |
|
#endif |
|
RESTORE_R24_TO_R13 |
|
.endm |
|
|
|
/*-------------------------------------------------------------- |
|
* Opposite of SAVE_CALLEE_SAVED_USER |
|
* |
|
* ptrace tracer or unaligned-access fixup might have changed a user mode |
|
* callee reg which is saved back to usual r25 storage location |
|
*-------------------------------------------------------------*/ |
|
.macro RESTORE_CALLEE_SAVED_USER |
|
|
|
#ifdef CONFIG_ARC_CURR_IN_REG |
|
POP r12 |
|
#else |
|
POP r25 |
|
#endif |
|
RESTORE_R24_TO_R13 |
|
|
|
; SP is back to start of pt_regs |
|
#ifdef CONFIG_ARC_CURR_IN_REG |
|
st r12, [sp, PT_user_r25] |
|
#endif |
|
.endm |
|
|
|
/*-------------------------------------------------------------- |
|
* Super FAST Restore callee saved regs by simply re-adjusting SP |
|
*-------------------------------------------------------------*/ |
|
.macro DISCARD_CALLEE_SAVED_USER |
|
add sp, sp, SZ_CALLEE_REGS |
|
.endm |
|
|
|
/*------------------------------------------------------------- |
|
* given a tsk struct, get to the base of it's kernel mode stack |
|
* tsk->thread_info is really a PAGE, whose bottom hoists stack |
|
* which grows upwards towards thread_info |
|
*------------------------------------------------------------*/ |
|
|
|
.macro GET_TSK_STACK_BASE tsk, out |
|
|
|
/* Get task->thread_info (this is essentially start of a PAGE) */ |
|
ld \out, [\tsk, TASK_THREAD_INFO] |
|
|
|
/* Go to end of page where stack begins (grows upwards) */ |
|
add2 \out, \out, (THREAD_SIZE)/4 |
|
|
|
.endm |
|
|
|
/* |
|
* @reg [OUT] thread_info->flags of "current" |
|
*/ |
|
.macro GET_CURR_THR_INFO_FLAGS reg |
|
GET_CURR_THR_INFO_FROM_SP \reg |
|
ld \reg, [\reg, THREAD_INFO_FLAGS] |
|
.endm |
|
|
|
#ifdef CONFIG_SMP |
|
|
|
/*------------------------------------------------- |
|
* Retrieve the current running task on this CPU |
|
* 1. Determine curr CPU id. |
|
* 2. Use it to index into _current_task[ ] |
|
*/ |
|
.macro GET_CURR_TASK_ON_CPU reg |
|
GET_CPU_ID \reg |
|
ld.as \reg, [@_current_task, \reg] |
|
.endm |
|
|
|
/*------------------------------------------------- |
|
* Save a new task as the "current" task on this CPU |
|
* 1. Determine curr CPU id. |
|
* 2. Use it to index into _current_task[ ] |
|
* |
|
* Coded differently than GET_CURR_TASK_ON_CPU (which uses LD.AS) |
|
* because ST r0, [r1, offset] can ONLY have s9 @offset |
|
* while LD can take s9 (4 byte insn) or LIMM (8 byte insn) |
|
*/ |
|
|
|
.macro SET_CURR_TASK_ON_CPU tsk, tmp |
|
GET_CPU_ID \tmp |
|
add2 \tmp, @_current_task, \tmp |
|
st \tsk, [\tmp] |
|
#ifdef CONFIG_ARC_CURR_IN_REG |
|
mov r25, \tsk |
|
#endif |
|
|
|
.endm |
|
|
|
|
|
#else /* Uniprocessor implementation of macros */ |
|
|
|
.macro GET_CURR_TASK_ON_CPU reg |
|
ld \reg, [@_current_task] |
|
.endm |
|
|
|
.macro SET_CURR_TASK_ON_CPU tsk, tmp |
|
st \tsk, [@_current_task] |
|
#ifdef CONFIG_ARC_CURR_IN_REG |
|
mov r25, \tsk |
|
#endif |
|
.endm |
|
|
|
#endif /* SMP / UNI */ |
|
|
|
/* ------------------------------------------------------------------ |
|
* Get the ptr to some field of Current Task at @off in task struct |
|
* -Uses r25 for Current task ptr if that is enabled |
|
*/ |
|
|
|
#ifdef CONFIG_ARC_CURR_IN_REG |
|
|
|
.macro GET_CURR_TASK_FIELD_PTR off, reg |
|
add \reg, r25, \off |
|
.endm |
|
|
|
#else |
|
|
|
.macro GET_CURR_TASK_FIELD_PTR off, reg |
|
GET_CURR_TASK_ON_CPU \reg |
|
add \reg, \reg, \off |
|
.endm |
|
|
|
#endif /* CONFIG_ARC_CURR_IN_REG */ |
|
|
|
#endif /* __ASM_ARC_ENTRY_H */
|
|
|