linux/arch/arc/include/asm/entry.h
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com)
   3 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License version 2 as
   7 * published by the Free Software Foundation.
   8 */
   9
  10#ifndef __ASM_ARC_ENTRY_H
  11#define __ASM_ARC_ENTRY_H
  12
  13#include <asm/unistd.h>         /* For NR_syscalls defination */
  14#include <asm/arcregs.h>
  15#include <asm/ptrace.h>
  16#include <asm/processor.h>      /* For VMALLOC_START */
  17#include <asm/mmu.h>
  18
  19#ifdef CONFIG_ISA_ARCOMPACT
  20#include <asm/entry-compact.h>  /* ISA specific bits */
  21#else
  22#include <asm/entry-arcv2.h>
  23#endif
  24
  25/* Note on the LD/ST addr modes with addr reg wback
  26 *
  27 * LD.a same as LD.aw
  28 *
  29 * LD.a    reg1, [reg2, x]  => Pre Incr
  30 *      Eff Addr for load = [reg2 + x]
  31 *
  32 * LD.ab   reg1, [reg2, x]  => Post Incr
  33 *      Eff Addr for load = [reg2]
  34 */
  35
  36.macro PUSH reg
  37        st.a    \reg, [sp, -4]
  38.endm
  39
  40.macro PUSHAX aux
  41        lr      r9, [\aux]
  42        PUSH    r9
  43.endm
  44
  45.macro POP reg
  46        ld.ab   \reg, [sp, 4]
  47.endm
  48
  49.macro POPAX aux
  50        POP     r9
  51        sr      r9, [\aux]
  52.endm
  53
  54/*--------------------------------------------------------------
  55 * Helpers to save/restore Scratch Regs:
  56 * used by Interrupt/Exception Prologue/Epilogue
  57 *-------------------------------------------------------------*/
  58.macro  SAVE_R0_TO_R12
  59        PUSH    r0
  60        PUSH    r1
  61        PUSH    r2
  62        PUSH    r3
  63        PUSH    r4
  64        PUSH    r5
  65        PUSH    r6
  66        PUSH    r7
  67        PUSH    r8
  68        PUSH    r9
  69        PUSH    r10
  70        PUSH    r11
  71        PUSH    r12
  72.endm
  73
  74.macro RESTORE_R12_TO_R0
  75        POP     r12
  76        POP     r11
  77        POP     r10
  78        POP     r9
  79        POP     r8
  80        POP     r7
  81        POP     r6
  82        POP     r5
  83        POP     r4
  84        POP     r3
  85        POP     r2
  86        POP     r1
  87        POP     r0
  88
  89#ifdef CONFIG_ARC_CURR_IN_REG
  90        ld      r25, [sp, 12]
  91#endif
  92.endm
  93
  94/*--------------------------------------------------------------
  95 * Helpers to save/restore callee-saved regs:
  96 * used by several macros below
  97 *-------------------------------------------------------------*/
  98.macro SAVE_R13_TO_R24
  99        PUSH    r13
 100        PUSH    r14
 101        PUSH    r15
 102        PUSH    r16
 103        PUSH    r17
 104        PUSH    r18
 105        PUSH    r19
 106        PUSH    r20
 107        PUSH    r21
 108        PUSH    r22
 109        PUSH    r23
 110        PUSH    r24
 111.endm
 112
 113.macro RESTORE_R24_TO_R13
 114        POP     r24
 115        POP     r23
 116        POP     r22
 117        POP     r21
 118        POP     r20
 119        POP     r19
 120        POP     r18
 121        POP     r17
 122        POP     r16
 123        POP     r15
 124        POP     r14
 125        POP     r13
 126.endm
 127
 128/*--------------------------------------------------------------
 129 * Collect User Mode callee regs as struct callee_regs - needed by
 130 * fork/do_signal/unaligned-access-emulation.
 131 * (By default only scratch regs are saved on entry to kernel)
 132 *
 133 * Special handling for r25 if used for caching Task Pointer.
 134 * It would have been saved in task->thread.user_r25 already, but to keep
 135 * the interface same it is copied into regular r25 placeholder in
 136 * struct callee_regs.
 137 *-------------------------------------------------------------*/
 138.macro SAVE_CALLEE_SAVED_USER
 139
 140        mov     r12, sp         ; save SP as ref to pt_regs
 141        SAVE_R13_TO_R24
 142
 143#ifdef CONFIG_ARC_CURR_IN_REG
 144        ; Retrieve orig r25 and save it with rest of callee_regs
 145        ld      r12, [r12, PT_user_r25]
 146        PUSH    r12
 147#else
 148        PUSH    r25
 149#endif
 150
 151.endm
 152
 153/*--------------------------------------------------------------
 154 * Save kernel Mode callee regs at the time of Contect Switch.
 155 *
 156 * Special handling for r25 if used for caching Task Pointer.
 157 * Kernel simply skips saving it since it will be loaded with
 158 * incoming task pointer anyways
 159 *-------------------------------------------------------------*/
 160.macro SAVE_CALLEE_SAVED_KERNEL
 161
 162        SAVE_R13_TO_R24
 163
 164#ifdef CONFIG_ARC_CURR_IN_REG
 165        sub     sp, sp, 4
 166#else
 167        PUSH    r25
 168#endif
 169.endm
 170
 171/*--------------------------------------------------------------
 172 * Opposite of SAVE_CALLEE_SAVED_KERNEL
 173 *-------------------------------------------------------------*/
 174.macro RESTORE_CALLEE_SAVED_KERNEL
 175
 176#ifdef CONFIG_ARC_CURR_IN_REG
 177        add     sp, sp, 4  /* skip usual r25 placeholder */
 178#else
 179        POP     r25
 180#endif
 181        RESTORE_R24_TO_R13
 182.endm
 183
 184/*--------------------------------------------------------------
 185 * Opposite of SAVE_CALLEE_SAVED_USER
 186 *
 187 * ptrace tracer or unaligned-access fixup might have changed a user mode
 188 * callee reg which is saved back to usual r25 storage location
 189 *-------------------------------------------------------------*/
 190.macro RESTORE_CALLEE_SAVED_USER
 191
 192#ifdef CONFIG_ARC_CURR_IN_REG
 193        POP     r12
 194#else
 195        POP     r25
 196#endif
 197        RESTORE_R24_TO_R13
 198
 199        ; SP is back to start of pt_regs
 200#ifdef CONFIG_ARC_CURR_IN_REG
 201        st      r12, [sp, PT_user_r25]
 202#endif
 203.endm
 204
 205/*--------------------------------------------------------------
 206 * Super FAST Restore callee saved regs by simply re-adjusting SP
 207 *-------------------------------------------------------------*/
 208.macro DISCARD_CALLEE_SAVED_USER
 209        add     sp, sp, SZ_CALLEE_REGS
 210.endm
 211
 212/*-------------------------------------------------------------
 213 * given a tsk struct, get to the base of it's kernel mode stack
 214 * tsk->thread_info is really a PAGE, whose bottom hoists stack
 215 * which grows upwards towards thread_info
 216 *------------------------------------------------------------*/
 217
 218.macro GET_TSK_STACK_BASE tsk, out
 219
 220        /* Get task->thread_info (this is essentially start of a PAGE) */
 221        ld  \out, [\tsk, TASK_THREAD_INFO]
 222
 223        /* Go to end of page where stack begins (grows upwards) */
 224        add2 \out, \out, (THREAD_SIZE)/4
 225
 226.endm
 227
 228/*
 229 * @reg [OUT] thread_info->flags of "current"
 230 */
 231.macro GET_CURR_THR_INFO_FLAGS  reg
 232        GET_CURR_THR_INFO_FROM_SP  \reg
 233        ld  \reg, [\reg, THREAD_INFO_FLAGS]
 234.endm
 235
 236#ifdef CONFIG_SMP
 237
 238/*-------------------------------------------------
 239 * Retrieve the current running task on this CPU
 240 * 1. Determine curr CPU id.
 241 * 2. Use it to index into _current_task[ ]
 242 */
 243.macro  GET_CURR_TASK_ON_CPU   reg
 244        GET_CPU_ID  \reg
 245        ld.as  \reg, [@_current_task, \reg]
 246.endm
 247
 248/*-------------------------------------------------
 249 * Save a new task as the "current" task on this CPU
 250 * 1. Determine curr CPU id.
 251 * 2. Use it to index into _current_task[ ]
 252 *
 253 * Coded differently than GET_CURR_TASK_ON_CPU (which uses LD.AS)
 254 * because ST r0, [r1, offset] can ONLY have s9 @offset
 255 * while   LD can take s9 (4 byte insn) or LIMM (8 byte insn)
 256 */
 257
 258.macro  SET_CURR_TASK_ON_CPU    tsk, tmp
 259        GET_CPU_ID  \tmp
 260        add2 \tmp, @_current_task, \tmp
 261        st   \tsk, [\tmp]
 262#ifdef CONFIG_ARC_CURR_IN_REG
 263        mov r25, \tsk
 264#endif
 265
 266.endm
 267
 268
 269#else   /* Uniprocessor implementation of macros */
 270
 271.macro  GET_CURR_TASK_ON_CPU    reg
 272        ld  \reg, [@_current_task]
 273.endm
 274
 275.macro  SET_CURR_TASK_ON_CPU    tsk, tmp
 276        st  \tsk, [@_current_task]
 277#ifdef CONFIG_ARC_CURR_IN_REG
 278        mov r25, \tsk
 279#endif
 280.endm
 281
 282#endif /* SMP / UNI */
 283
 284/* ------------------------------------------------------------------
 285 * Get the ptr to some field of Current Task at @off in task struct
 286 *  -Uses r25 for Current task ptr if that is enabled
 287 */
 288
 289#ifdef CONFIG_ARC_CURR_IN_REG
 290
 291.macro GET_CURR_TASK_FIELD_PTR  off,  reg
 292        add \reg, r25, \off
 293.endm
 294
 295#else
 296
 297.macro GET_CURR_TASK_FIELD_PTR  off,  reg
 298        GET_CURR_TASK_ON_CPU  \reg
 299        add \reg, \reg, \off
 300.endm
 301
 302#endif  /* CONFIG_ARC_CURR_IN_REG */
 303
 304#endif  /* __ASM_ARC_ENTRY_H */
 305