162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com) 462306a36Sopenharmony_ci * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#ifndef __ASM_ARC_ENTRY_H 862306a36Sopenharmony_ci#define __ASM_ARC_ENTRY_H 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <asm/unistd.h> /* For NR_syscalls defination */ 1162306a36Sopenharmony_ci#include <asm/arcregs.h> 1262306a36Sopenharmony_ci#include <asm/ptrace.h> 1362306a36Sopenharmony_ci#include <asm/processor.h> /* For VMALLOC_START */ 1462306a36Sopenharmony_ci#include <asm/mmu.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#ifdef __ASSEMBLY__ 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#ifdef CONFIG_ISA_ARCOMPACT 1962306a36Sopenharmony_ci#include <asm/entry-compact.h> /* ISA specific bits */ 2062306a36Sopenharmony_ci#else 2162306a36Sopenharmony_ci#include <asm/entry-arcv2.h> 2262306a36Sopenharmony_ci#endif 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci/* Note on the LD/ST addr modes with addr reg wback 2562306a36Sopenharmony_ci * 2662306a36Sopenharmony_ci * LD.a same as LD.aw 2762306a36Sopenharmony_ci * 2862306a36Sopenharmony_ci * LD.a reg1, [reg2, x] => Pre Incr 2962306a36Sopenharmony_ci * Eff Addr for load = [reg2 + x] 3062306a36Sopenharmony_ci * 3162306a36Sopenharmony_ci * LD.ab reg1, [reg2, x] => Post Incr 3262306a36Sopenharmony_ci * Eff Addr for load = [reg2] 3362306a36Sopenharmony_ci */ 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci.macro PUSH reg 3662306a36Sopenharmony_ci st.a \reg, [sp, -4] 3762306a36Sopenharmony_ci.endm 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci.macro PUSHAX aux 4062306a36Sopenharmony_ci lr r9, [\aux] 4162306a36Sopenharmony_ci PUSH r9 4262306a36Sopenharmony_ci.endm 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci.macro POP reg 4562306a36Sopenharmony_ci ld.ab \reg, [sp, 4] 4662306a36Sopenharmony_ci.endm 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci.macro POPAX aux 4962306a36Sopenharmony_ci POP r9 5062306a36Sopenharmony_ci sr r9, [\aux] 5162306a36Sopenharmony_ci.endm 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci/*-------------------------------------------------------------- 5462306a36Sopenharmony_ci * Helpers to save/restore Scratch Regs: 5562306a36Sopenharmony_ci * used by Interrupt/Exception Prologue/Epilogue 5662306a36Sopenharmony_ci *-------------------------------------------------------------*/ 5762306a36Sopenharmony_ci.macro SAVE_R0_TO_R12 5862306a36Sopenharmony_ci PUSH r0 5962306a36Sopenharmony_ci PUSH r1 6062306a36Sopenharmony_ci PUSH r2 6162306a36Sopenharmony_ci PUSH r3 6262306a36Sopenharmony_ci PUSH r4 6362306a36Sopenharmony_ci PUSH r5 6462306a36Sopenharmony_ci PUSH r6 6562306a36Sopenharmony_ci PUSH r7 6662306a36Sopenharmony_ci PUSH r8 6762306a36Sopenharmony_ci PUSH r9 6862306a36Sopenharmony_ci PUSH r10 6962306a36Sopenharmony_ci PUSH r11 7062306a36Sopenharmony_ci PUSH r12 7162306a36Sopenharmony_ci.endm 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci.macro RESTORE_R12_TO_R0 7462306a36Sopenharmony_ci POP r12 7562306a36Sopenharmony_ci POP r11 7662306a36Sopenharmony_ci POP r10 7762306a36Sopenharmony_ci POP r9 7862306a36Sopenharmony_ci POP r8 7962306a36Sopenharmony_ci POP r7 8062306a36Sopenharmony_ci POP r6 8162306a36Sopenharmony_ci POP r5 8262306a36Sopenharmony_ci POP r4 8362306a36Sopenharmony_ci POP r3 8462306a36Sopenharmony_ci POP r2 8562306a36Sopenharmony_ci POP r1 8662306a36Sopenharmony_ci POP r0 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci.endm 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci/*-------------------------------------------------------------- 9162306a36Sopenharmony_ci * Helpers to save/restore callee-saved regs: 9262306a36Sopenharmony_ci * used by several macros below 9362306a36Sopenharmony_ci *-------------------------------------------------------------*/ 9462306a36Sopenharmony_ci.macro SAVE_R13_TO_R25 9562306a36Sopenharmony_ci PUSH r13 9662306a36Sopenharmony_ci PUSH r14 9762306a36Sopenharmony_ci PUSH r15 9862306a36Sopenharmony_ci PUSH r16 9962306a36Sopenharmony_ci PUSH r17 10062306a36Sopenharmony_ci PUSH r18 10162306a36Sopenharmony_ci PUSH r19 10262306a36Sopenharmony_ci PUSH r20 10362306a36Sopenharmony_ci PUSH r21 10462306a36Sopenharmony_ci PUSH r22 10562306a36Sopenharmony_ci PUSH r23 10662306a36Sopenharmony_ci PUSH r24 10762306a36Sopenharmony_ci PUSH r25 10862306a36Sopenharmony_ci.endm 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci.macro RESTORE_R25_TO_R13 11162306a36Sopenharmony_ci POP r25 11262306a36Sopenharmony_ci POP r24 11362306a36Sopenharmony_ci POP r23 11462306a36Sopenharmony_ci POP r22 11562306a36Sopenharmony_ci POP r21 11662306a36Sopenharmony_ci POP r20 11762306a36Sopenharmony_ci POP r19 11862306a36Sopenharmony_ci POP r18 11962306a36Sopenharmony_ci POP r17 12062306a36Sopenharmony_ci POP r16 12162306a36Sopenharmony_ci POP r15 12262306a36Sopenharmony_ci POP r14 12362306a36Sopenharmony_ci POP r13 12462306a36Sopenharmony_ci.endm 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci/* 12762306a36Sopenharmony_ci * save user mode callee regs as struct callee_regs 12862306a36Sopenharmony_ci * - needed by fork/do_signal/unaligned-access-emulation. 12962306a36Sopenharmony_ci */ 13062306a36Sopenharmony_ci.macro SAVE_CALLEE_SAVED_USER 13162306a36Sopenharmony_ci SAVE_R13_TO_R25 13262306a36Sopenharmony_ci.endm 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci/* 13562306a36Sopenharmony_ci * restore user mode callee regs as struct callee_regs 13662306a36Sopenharmony_ci * - could have been changed by ptrace tracer or unaligned-access fixup 13762306a36Sopenharmony_ci */ 13862306a36Sopenharmony_ci.macro RESTORE_CALLEE_SAVED_USER 13962306a36Sopenharmony_ci RESTORE_R25_TO_R13 14062306a36Sopenharmony_ci.endm 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci/* 14362306a36Sopenharmony_ci * save/restore kernel mode callee regs at the time of context switch 14462306a36Sopenharmony_ci */ 14562306a36Sopenharmony_ci.macro SAVE_CALLEE_SAVED_KERNEL 14662306a36Sopenharmony_ci SAVE_R13_TO_R25 14762306a36Sopenharmony_ci.endm 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci.macro RESTORE_CALLEE_SAVED_KERNEL 15062306a36Sopenharmony_ci RESTORE_R25_TO_R13 15162306a36Sopenharmony_ci.endm 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci/*-------------------------------------------------------------- 15462306a36Sopenharmony_ci * Super FAST Restore callee saved regs by simply re-adjusting SP 15562306a36Sopenharmony_ci *-------------------------------------------------------------*/ 15662306a36Sopenharmony_ci.macro DISCARD_CALLEE_SAVED_USER 15762306a36Sopenharmony_ci add sp, sp, SZ_CALLEE_REGS 15862306a36Sopenharmony_ci.endm 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci/*------------------------------------------------------------- 16162306a36Sopenharmony_ci * given a tsk struct, get to the base of it's kernel mode stack 16262306a36Sopenharmony_ci * tsk->thread_info is really a PAGE, whose bottom hoists stack 16362306a36Sopenharmony_ci * which grows upwards towards thread_info 16462306a36Sopenharmony_ci *------------------------------------------------------------*/ 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci.macro GET_TSK_STACK_BASE tsk, out 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci /* Get task->thread_info (this is essentially start of a PAGE) */ 16962306a36Sopenharmony_ci ld \out, [\tsk, TASK_THREAD_INFO] 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci /* Go to end of page where stack begins (grows upwards) */ 17262306a36Sopenharmony_ci add2 \out, \out, (THREAD_SIZE)/4 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci.endm 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci/* 17762306a36Sopenharmony_ci * @reg [OUT] thread_info->flags of "current" 17862306a36Sopenharmony_ci */ 17962306a36Sopenharmony_ci.macro GET_CURR_THR_INFO_FLAGS reg 18062306a36Sopenharmony_ci GET_CURR_THR_INFO_FROM_SP \reg 18162306a36Sopenharmony_ci ld \reg, [\reg, THREAD_INFO_FLAGS] 18262306a36Sopenharmony_ci.endm 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci#ifdef CONFIG_SMP 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci/* 18762306a36Sopenharmony_ci * Retrieve the current running task on this CPU 18862306a36Sopenharmony_ci * - loads it from backing _current_task[] (and can't use the 18962306a36Sopenharmony_ci * caching reg for current task 19062306a36Sopenharmony_ci */ 19162306a36Sopenharmony_ci.macro GET_CURR_TASK_ON_CPU reg 19262306a36Sopenharmony_ci GET_CPU_ID \reg 19362306a36Sopenharmony_ci ld.as \reg, [@_current_task, \reg] 19462306a36Sopenharmony_ci.endm 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci/*------------------------------------------------- 19762306a36Sopenharmony_ci * Save a new task as the "current" task on this CPU 19862306a36Sopenharmony_ci * 1. Determine curr CPU id. 19962306a36Sopenharmony_ci * 2. Use it to index into _current_task[ ] 20062306a36Sopenharmony_ci * 20162306a36Sopenharmony_ci * Coded differently than GET_CURR_TASK_ON_CPU (which uses LD.AS) 20262306a36Sopenharmony_ci * because ST r0, [r1, offset] can ONLY have s9 @offset 20362306a36Sopenharmony_ci * while LD can take s9 (4 byte insn) or LIMM (8 byte insn) 20462306a36Sopenharmony_ci */ 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci.macro SET_CURR_TASK_ON_CPU tsk, tmp 20762306a36Sopenharmony_ci GET_CPU_ID \tmp 20862306a36Sopenharmony_ci add2 \tmp, @_current_task, \tmp 20962306a36Sopenharmony_ci st \tsk, [\tmp] 21062306a36Sopenharmony_ci#ifdef CONFIG_ARC_CURR_IN_REG 21162306a36Sopenharmony_ci mov gp, \tsk 21262306a36Sopenharmony_ci#endif 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci.endm 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci#else /* Uniprocessor implementation of macros */ 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci.macro GET_CURR_TASK_ON_CPU reg 22062306a36Sopenharmony_ci ld \reg, [@_current_task] 22162306a36Sopenharmony_ci.endm 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci.macro SET_CURR_TASK_ON_CPU tsk, tmp 22462306a36Sopenharmony_ci st \tsk, [@_current_task] 22562306a36Sopenharmony_ci#ifdef CONFIG_ARC_CURR_IN_REG 22662306a36Sopenharmony_ci mov gp, \tsk 22762306a36Sopenharmony_ci#endif 22862306a36Sopenharmony_ci.endm 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci#endif /* SMP / UNI */ 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci/* 23362306a36Sopenharmony_ci * Get the ptr to some field of Current Task at @off in task struct 23462306a36Sopenharmony_ci * - Uses current task cached in reg if enabled 23562306a36Sopenharmony_ci */ 23662306a36Sopenharmony_ci#ifdef CONFIG_ARC_CURR_IN_REG 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci.macro GET_CURR_TASK_FIELD_PTR off, reg 23962306a36Sopenharmony_ci add \reg, gp, \off 24062306a36Sopenharmony_ci.endm 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci#else 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci.macro GET_CURR_TASK_FIELD_PTR off, reg 24562306a36Sopenharmony_ci GET_CURR_TASK_ON_CPU \reg 24662306a36Sopenharmony_ci add \reg, \reg, \off 24762306a36Sopenharmony_ci.endm 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci#endif /* CONFIG_ARC_CURR_IN_REG */ 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci#else /* !__ASSEMBLY__ */ 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ciextern void do_signal(struct pt_regs *); 25462306a36Sopenharmony_ciextern void do_notify_resume(struct pt_regs *); 25562306a36Sopenharmony_ciextern int do_privilege_fault(unsigned long, struct pt_regs *); 25662306a36Sopenharmony_ciextern int do_extension_fault(unsigned long, struct pt_regs *); 25762306a36Sopenharmony_ciextern int insterror_is_error(unsigned long, struct pt_regs *); 25862306a36Sopenharmony_ciextern int do_memory_error(unsigned long, struct pt_regs *); 25962306a36Sopenharmony_ciextern int trap_is_brkpt(unsigned long, struct pt_regs *); 26062306a36Sopenharmony_ciextern int do_misaligned_error(unsigned long, struct pt_regs *); 26162306a36Sopenharmony_ciextern int do_trap5_error(unsigned long, struct pt_regs *); 26262306a36Sopenharmony_ciextern int do_misaligned_access(unsigned long, struct pt_regs *, struct callee_regs *); 26362306a36Sopenharmony_ciextern void do_machine_check_fault(unsigned long, struct pt_regs *); 26462306a36Sopenharmony_ciextern void do_non_swi_trap(unsigned long, struct pt_regs *); 26562306a36Sopenharmony_ciextern void do_insterror_or_kprobe(unsigned long, struct pt_regs *); 26662306a36Sopenharmony_ciextern void do_page_fault(unsigned long, struct pt_regs *); 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci#endif 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci#endif /* __ASM_ARC_ENTRY_H */ 271