Commit 76d3f4c2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'arc-v3.11-rc1-part1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc

Pull first batch of ARC changes from Vineet Gupta:
 "There's a second bunch to follow next week - which depends on commits
  on other trees (irq/net).  I'd have preferred the accompanying ARC
  change via respective trees, but it didn't workout somehow.

  Highlights of changes:

   - Continuation of ARC MM changes from 3.10 including

       zero page optimization
       Setting pagecache pages dirty by default
       Non executable stack by default
       Reducing dcache flushes for aliasing VIPT config

   - Long overdue rework of pt_regs machinery - removing the unused word
     gutters and adding ECR register to baseline (helps cleanup lot of
     low level code)

   - Support for ARC gcc 4.8

   - Few other preventive fixes, cosmetics, usage of Kconfig helper..

  The diffstat is larger than normal primarily because of arcregs.h
  header split as well as beautification of macros in entry.h"

* tag 'arc-v3.11-rc1-part1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc: (32 commits)
  ARC: warn on improper stack unwind FDE entries
  arc: delete __cpuinit usage from all arc files
  ARC: [tlb-miss] Fix bug with CONFIG_ARC_DBG_TLB_MISS_COUNT
  ARC: [tlb-miss] Extraneous PTE bit testing/setting
  ARC: Adjustments for gcc 4.8
  ARC: Setup Vector Table Base in early boot
  ARC: Remove explicit passing around of ECR
  ARC: pt_regs update #5: Use real ECR for pt_regs->event vs. synth values
  ARC: stop using pt_regs->orig_r8
  ARC: pt_regs update #4: r25 saved/restored unconditionally
  ARC: K/U SP saved from one location in stack switching macro
  ARC: Entry Handler tweaks: Simplify branch for in-kernel preemption
  ARC: Entry Handler tweaks: Avoid hardcoded LIMMS for ECR values
  ARC: Increase readability of entry handlers
  ARC: pt_regs update #3: Remove unused gutter at start of callee_regs
  ARC: pt_regs update #2: Remove unused gutter at start of pt_regs
  ARC: pt_regs update #1: Align pt_regs end with end of kernel stack page
  ARC: pt_regs update #0: remove kernel stack canary
  ARC: [mm] Remove @write argument to do_page_fault()
  ARC: [mm] Make stack/heap Non-executable by default
  ...
parents c1101cbc baadb8fd
......@@ -184,6 +184,7 @@ config ARC_CACHE_PAGES
config ARC_CACHE_VIPT_ALIASING
bool "Support VIPT Aliasing D$"
depends on ARC_HAS_DCACHE
default n
endif #ARC_CACHE
......@@ -361,13 +362,6 @@ config ARC_MISALIGN_ACCESS
Use ONLY-IF-ABS-NECESSARY as it will be very slow and also can hide
potential bugs in code
config ARC_STACK_NONEXEC
bool "Make stack non-executable"
default n
help
To disable the execute permissions of stack/heap of processes
which are enabled by default.
config HZ
int "Timer Frequency"
default 100
......
......@@ -9,25 +9,27 @@
UTS_MACHINE := arc
ifeq ($(CROSS_COMPILE),)
CROSS_COMPILE := arc-elf32-
CROSS_COMPILE := arc-linux-uclibc-
endif
KBUILD_DEFCONFIG := fpga_defconfig
cflags-y += -mA7 -fno-common -pipe -fno-builtin -D__linux__
LINUXINCLUDE += -include ${src}/arch/arc/include/asm/defines.h
ifdef CONFIG_ARC_CURR_IN_REG
# For a global register defintion, make sure it gets passed to every file
# We had a customer reported bug where some code built in kernel was NOT using
# any kernel headers, and missing the r25 global register
# Can't do unconditionally (like above) because of recursive include issues
# Can't do unconditionally because of recursive include issues
# due to <linux/thread_info.h>
LINUXINCLUDE += -include ${src}/arch/arc/include/asm/current.h
endif
atleast_gcc44 := $(call cc-ifversion, -gt, 0402, y)
upto_gcc42 := $(call cc-ifversion, -le, 0402, y)
upto_gcc44 := $(call cc-ifversion, -le, 0404, y)
atleast_gcc44 := $(call cc-ifversion, -ge, 0404, y)
atleast_gcc48 := $(call cc-ifversion, -ge, 0408, y)
cflags-$(atleast_gcc44) += -fsection-anchors
cflags-$(CONFIG_ARC_HAS_LLSC) += -mlock
......@@ -35,6 +37,11 @@ cflags-$(CONFIG_ARC_HAS_SWAPE) += -mswape
cflags-$(CONFIG_ARC_HAS_RTSC) += -mrtsc
cflags-$(CONFIG_ARC_DW2_UNWIND) += -fasynchronous-unwind-tables
# By default gcc 4.8 generates dwarf4 which kernel unwinder can't grok
ifeq ($(atleast_gcc48),y)
cflags-$(CONFIG_ARC_DW2_UNWIND) += -gdwarf-2
endif
ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE
# Generic build system uses -O2, we want -O3
cflags-y += -O3
......@@ -48,11 +55,10 @@ cflags-$(disable_small_data) += -mno-sdata -fcall-used-gp
cflags-$(CONFIG_CPU_BIG_ENDIAN) += -mbig-endian
ldflags-$(CONFIG_CPU_BIG_ENDIAN) += -EB
# STAR 9000518362:
# STAR 9000518362: (fixed with binutils shipping with gcc 4.8)
# arc-linux-uclibc-ld (buildroot) or arceb-elf32-ld (EZChip) don't accept
# --build-id w/o "-marclinux".
# Default arc-elf32-ld is OK
ldflags-y += -marclinux
# --build-id w/o "-marclinux". Default arc-elf32-ld is OK
ldflags-$(upto_gcc44) += -marclinux
ARC_LIBGCC := -mA7
cflags-$(CONFIG_ARC_HAS_HW_MPY) += -multcost=16
......@@ -66,8 +72,8 @@ ifndef CONFIG_ARC_HAS_HW_MPY
# With gcc 4.4.7, -mno-mpy is enough to make any other related adjustments,
# e.g. increased cost of MPY. With gcc 4.2.1 this had to be explicitly hinted
ARC_LIBGCC := -marc600
ifneq ($(atleast_gcc44),y)
ifeq ($(upto_gcc42),y)
ARC_LIBGCC := -marc600
cflags-y += -multcost=30
endif
endif
......
CONFIG_CROSS_COMPILE="arc-elf32-"
CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_DEFAULT_HOSTNAME="ARCLinux"
# CONFIG_SWAP is not set
......
CONFIG_CROSS_COMPILE="arc-elf32-"
CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_DEFAULT_HOSTNAME="ARCLinux"
# CONFIG_SWAP is not set
......
CONFIG_CROSS_COMPILE="arc-elf32-"
CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_DEFAULT_HOSTNAME="tb10x"
CONFIG_SYSVIPC=y
......
......@@ -20,7 +20,6 @@
#define ARC_REG_PERIBASE_BCR 0x69
#define ARC_REG_FP_BCR 0x6B /* Single-Precision FPU */
#define ARC_REG_DPFP_BCR 0x6C /* Dbl Precision FPU */
#define ARC_REG_MMU_BCR 0x6f
#define ARC_REG_DCCM_BCR 0x74 /* DCCM Present + SZ */
#define ARC_REG_TIMERS_BCR 0x75
#define ARC_REG_ICCM_BCR 0x78
......@@ -34,22 +33,12 @@
#define ARC_REG_D_UNCACH_BCR 0x6A
/* status32 Bits Positions */
#define STATUS_H_BIT 0 /* CPU Halted */
#define STATUS_E1_BIT 1 /* Int 1 enable */
#define STATUS_E2_BIT 2 /* Int 2 enable */
#define STATUS_A1_BIT 3 /* Int 1 active */
#define STATUS_A2_BIT 4 /* Int 2 active */
#define STATUS_AE_BIT 5 /* Exception active */
#define STATUS_DE_BIT 6 /* PC is in delay slot */
#define STATUS_U_BIT 7 /* User/Kernel mode */
#define STATUS_L_BIT 12 /* Loop inhibit */
/* These masks correspond to the status word(STATUS_32) bits */
#define STATUS_H_MASK (1<<STATUS_H_BIT)
#define STATUS_E1_MASK (1<<STATUS_E1_BIT)
#define STATUS_E2_MASK (1<<STATUS_E2_BIT)
#define STATUS_A1_MASK (1<<STATUS_A1_BIT)
#define STATUS_A2_MASK (1<<STATUS_A2_BIT)
#define STATUS_AE_MASK (1<<STATUS_AE_BIT)
#define STATUS_DE_MASK (1<<STATUS_DE_BIT)
#define STATUS_U_MASK (1<<STATUS_U_BIT)
......@@ -71,6 +60,7 @@
#define ECR_V_ITLB_MISS 0x21
#define ECR_V_DTLB_MISS 0x22
#define ECR_V_PROTV 0x23
#define ECR_V_TRAP 0x25
/* Protection Violation Exception Cause Code Values */
#define ECR_C_PROTV_INST_FETCH 0x00
......@@ -79,94 +69,23 @@
#define ECR_C_PROTV_XCHG 0x03
#define ECR_C_PROTV_MISALIG_DATA 0x04
#define ECR_C_BIT_PROTV_MISALIG_DATA 10
/* Machine Check Cause Code Values */
#define ECR_C_MCHK_DUP_TLB 0x01
/* DTLB Miss Exception Cause Code Values */
#define ECR_C_BIT_DTLB_LD_MISS 8
#define ECR_C_BIT_DTLB_ST_MISS 9
/* Dummy ECR values for Interrupts */
#define event_IRQ1 0x0031abcd
#define event_IRQ2 0x0032abcd
/* Auxiliary registers */
#define AUX_IDENTITY 4
#define AUX_INTR_VEC_BASE 0x25
#define AUX_IRQ_LEV 0x200 /* IRQ Priority: L1 or L2 */
#define AUX_IRQ_HINT 0x201 /* For generating Soft Interrupts */
#define AUX_IRQ_LV12 0x43 /* interrupt level register */
#define AUX_IENABLE 0x40c
#define AUX_ITRIGGER 0x40d
#define AUX_IPULSE 0x415
/* Timer related Aux registers */
#define ARC_REG_TIMER0_LIMIT 0x23 /* timer 0 limit */
#define ARC_REG_TIMER0_CTRL 0x22 /* timer 0 control */
#define ARC_REG_TIMER0_CNT 0x21 /* timer 0 count */
#define ARC_REG_TIMER1_LIMIT 0x102 /* timer 1 limit */
#define ARC_REG_TIMER1_CTRL 0x101 /* timer 1 control */
#define ARC_REG_TIMER1_CNT 0x100 /* timer 1 count */
#define TIMER_CTRL_IE (1 << 0) /* Interupt when Count reachs limit */
#define TIMER_CTRL_NH (1 << 1) /* Count only when CPU NOT halted */
/* MMU Management regs */
#define ARC_REG_TLBPD0 0x405
#define ARC_REG_TLBPD1 0x406
#define ARC_REG_TLBINDEX 0x407
#define ARC_REG_TLBCOMMAND 0x408
#define ARC_REG_PID 0x409
#define ARC_REG_SCRATCH_DATA0 0x418
/* Bits in MMU PID register */
#define MMU_ENABLE (1 << 31) /* Enable MMU for process */
/* Error code if probe fails */
#define TLB_LKUP_ERR 0x80000000
/* TLB Commands */
#define TLBWrite 0x1
#define TLBRead 0x2
#define TLBGetIndex 0x3
#define TLBProbe 0x4
#if (CONFIG_ARC_MMU_VER >= 2)
#define TLBWriteNI 0x5 /* write JTLB without inv uTLBs */
#define TLBIVUTLB 0x6 /* explicitly inv uTLBs */
#else
#undef TLBWriteNI /* These cmds don't exist on older MMU */
#undef TLBIVUTLB
#endif
/* Instruction cache related Auxiliary registers */
#define ARC_REG_IC_BCR 0x77 /* Build Config reg */
#define ARC_REG_IC_IVIC 0x10
#define ARC_REG_IC_CTRL 0x11
#define ARC_REG_IC_IVIL 0x19
#if (CONFIG_ARC_MMU_VER > 2)
#define ARC_REG_IC_PTAG 0x1E
#endif
/* Bit val in IC_CTRL */
#define IC_CTRL_CACHE_DISABLE 0x1
/* Data cache related Auxiliary registers */
#define ARC_REG_DC_BCR 0x72
#define ARC_REG_DC_IVDC 0x47
#define ARC_REG_DC_CTRL 0x48
#define ARC_REG_DC_IVDL 0x4A
#define ARC_REG_DC_FLSH 0x4B
#define ARC_REG_DC_FLDL 0x4C
#if (CONFIG_ARC_MMU_VER > 2)
#define ARC_REG_DC_PTAG 0x5C
#endif
/* Bit val in DC_CTRL */
#define DC_CTRL_INV_MODE_FLUSH 0x40
#define DC_CTRL_FLUSH_STATUS 0x100
/* MMU Management regs */
#define ARC_REG_PID 0x409
#define ARC_REG_SCRATCH_DATA0 0x418
/* Bits in MMU PID register */
#define MMU_ENABLE (1 << 31) /* Enable MMU for process */
/*
* Floating Pt Registers
......@@ -293,24 +212,6 @@ struct bcr_identity {
#endif
};
struct bcr_mmu_1_2 {
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int ver:8, ways:4, sets:4, u_itlb:8, u_dtlb:8;
#else
unsigned int u_dtlb:8, u_itlb:8, sets:4, ways:4, ver:8;
#endif
};
struct bcr_mmu_3 {
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int ver:8, ways:4, sets:4, osm:1, reserv:3, pg_sz:4,
u_itlb:4, u_dtlb:4;
#else
unsigned int u_dtlb:4, u_itlb:4, pg_sz:4, reserv:3, osm:1, sets:4,
ways:4, ver:8;
#endif
};
#define EXTN_SWAP_VALID 0x1
#define EXTN_NORM_VALID 0x2
#define EXTN_MINMAX_VALID 0x2
......@@ -343,14 +244,6 @@ struct bcr_extn_xymem {
#endif
};
struct bcr_cache {
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int pad:12, line_len:4, sz:4, config:4, ver:8;
#else
unsigned int ver:8, config:4, sz:4, line_len:4, pad:12;
#endif
};
struct bcr_perip {
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int start:8, pad2:8, sz:8, pad:8;
......@@ -403,7 +296,7 @@ struct cpuinfo_arc_mmu {
};
struct cpuinfo_arc_cache {
unsigned int has_aliasing, sz, line_len, assoc, ver;
unsigned int sz, line_len, assoc, ver;
};
struct cpuinfo_arc_ccm {
......
......@@ -18,9 +18,8 @@ struct task_struct;
void show_regs(struct pt_regs *regs);
void show_stacktrace(struct task_struct *tsk, struct pt_regs *regs);
void show_kernel_fault_diag(const char *str, struct pt_regs *regs,
unsigned long address, unsigned long cause_reg);
void die(const char *str, struct pt_regs *regs, unsigned long address,
unsigned long cause_reg);
unsigned long address);
void die(const char *str, struct pt_regs *regs, unsigned long address);
#define BUG() do { \
dump_stack(); \
......
......@@ -18,21 +18,19 @@
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
#define ARC_ICACHE_WAYS 2
#define ARC_DCACHE_WAYS 4
/* Helpers */
/* For a rare case where customers have differently config I/D */
#define ARC_ICACHE_LINE_LEN L1_CACHE_BYTES
#define ARC_DCACHE_LINE_LEN L1_CACHE_BYTES
#define ICACHE_LINE_MASK (~(ARC_ICACHE_LINE_LEN - 1))
#define DCACHE_LINE_MASK (~(ARC_DCACHE_LINE_LEN - 1))
#if ARC_ICACHE_LINE_LEN != ARC_DCACHE_LINE_LEN
#error "Need to fix some code as I/D cache lines not same"
#else
#define is_not_cache_aligned(p) ((unsigned long)p & (~DCACHE_LINE_MASK))
#endif
/*
* ARC700 doesn't cache any access in top 256M.
* Ideal for wiring memory mapped peripherals as we don't need to do
* explicit uncached accesses (LD.di/ST.di) hence more portable drivers
*/
#define ARC_UNCACHED_ADDR_SPACE 0xc0000000
#ifndef __ASSEMBLY__
......@@ -57,16 +55,10 @@
#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
/*
* ARC700 doesn't cache any access in top 256M.
* Ideal for wiring memory mapped peripherals as we don't need to do
* explicit uncached accesses (LD.di/ST.di) hence more portable drivers
*/
#define ARC_UNCACHED_ADDR_SPACE 0xc0000000
extern void arc_cache_init(void);
extern char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len);
extern void __init read_decode_cache_bcr(void);
#endif
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_CACHE_H */
......@@ -80,17 +80,20 @@ void flush_anon_page(struct vm_area_struct *vma,
#endif /* CONFIG_ARC_CACHE_VIPT_ALIASING */
/*
* A new pagecache page has PG_arch_1 clear - thus dcache dirty by default
* This works around some PIO based drivers which don't call flush_dcache_page
* to record that they dirtied the dcache
*/
#define PG_dc_clean PG_arch_1
/*
* Simple wrapper over config option
* Bootup code ensures that hardware matches kernel configuration
*/
static inline int cache_is_vipt_aliasing(void)
{
#ifdef CONFIG_ARC_CACHE_VIPT_ALIASING
return 1;
#else
return 0;
#endif
return IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING);
}
#define CACHE_COLOR(addr) (((unsigned long)(addr) >> (PAGE_SHIFT)) & 1)
......
/*
* Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __ARC_ASM_DEFINES_H__
#define __ARC_ASM_DEFINES_H__
#if defined(CONFIG_ARC_MMU_V1)
#define CONFIG_ARC_MMU_VER 1
#elif defined(CONFIG_ARC_MMU_V2)
#define CONFIG_ARC_MMU_VER 2
#elif defined(CONFIG_ARC_MMU_V3)
#define CONFIG_ARC_MMU_VER 3
#endif
#ifdef CONFIG_ARC_HAS_LLSC
#define __CONFIG_ARC_HAS_LLSC_VAL 1
#else
#define __CONFIG_ARC_HAS_LLSC_VAL 0
#endif
#ifdef CONFIG_ARC_HAS_SWAPE
#define __CONFIG_ARC_HAS_SWAPE_VAL 1
#else
#define __CONFIG_ARC_HAS_SWAPE_VAL 0
#endif
#ifdef CONFIG_ARC_HAS_RTSC
#define __CONFIG_ARC_HAS_RTSC_VAL 1
#else
#define __CONFIG_ARC_HAS_RTSC_VAL 0
#endif
#ifdef CONFIG_ARC_MMU_SASID
#define __CONFIG_ARC_MMU_SASID_VAL 1
#else
#define __CONFIG_ARC_MMU_SASID_VAL 0
#endif
#ifdef CONFIG_ARC_HAS_ICACHE
#define __CONFIG_ARC_HAS_ICACHE 1
#else
#define __CONFIG_ARC_HAS_ICACHE 0
#endif
#ifdef CONFIG_ARC_HAS_DCACHE
#define __CONFIG_ARC_HAS_DCACHE 1
#else
#define __CONFIG_ARC_HAS_DCACHE 0
#endif
#endif /* __ARC_ASM_DEFINES_H__ */
......@@ -50,194 +50,177 @@
* 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
/*--------------------------------------------------------------
* Save caller saved registers (scratch registers) ( r0 - r12 )
* Registers are pushed / popped in the order defined in struct ptregs
* in asm/ptrace.h
* Helpers to save/restore Scratch Regs:
* used by Interrupt/Exception Prologue/Epilogue
*-------------------------------------------------------------*/
.macro SAVE_CALLER_SAVED
st.a r0, [sp, -4]
st.a r1, [sp, -4]
st.a r2, [sp, -4]
st.a r3, [sp, -4]
st.a r4, [sp, -4]
st.a r5, [sp, -4]
st.a r6, [sp, -4]
st.a r7, [sp, -4]
st.a r8, [sp, -4]
st.a r9, [sp, -4]
st.a r10, [sp, -4]
st.a r11, [sp, -4]
st.a r12, [sp, -4]
.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
#ifdef CONFIG_ARC_CURR_IN_REG
ld r25, [sp, 12]
#endif
.endm
/*--------------------------------------------------------------
* Restore caller saved registers (scratch registers)
* Helpers to save/restore callee-saved regs:
* used by several macros below
*-------------------------------------------------------------*/
.macro RESTORE_CALLER_SAVED
ld.ab r12, [sp, 4]
ld.ab r11, [sp, 4]
ld.ab r10, [sp, 4]
ld.ab r9, [sp, 4]
ld.ab r8, [sp, 4]
ld.ab r7, [sp, 4]
ld.ab r6, [sp, 4]
ld.ab r5, [sp, 4]
ld.ab r4, [sp, 4]
ld.ab r3, [sp, 4]
ld.ab r2, [sp, 4]
ld.ab r1, [sp, 4]
ld.ab r0, [sp, 4]
.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
#define OFF_USER_R25_FROM_R24 (SZ_CALLEE_REGS + SZ_PT_REGS - 8)/4
/*--------------------------------------------------------------
* Save callee saved registers (non scratch registers) ( r13 - r25 )
* on kernel stack.
* User mode callee regs need to be saved in case of
* -fork and friends for replicating from parent to child
* -before going into do_signal( ) for ptrace/core-dump
* Special case handling is required for r25 in case it is used by kernel
* for caching task ptr. Low level exception/ISR save user mode r25
* into task->thread.user_r25. So it needs to be retrieved from there and
* saved into kernel stack with rest of callee reg-file
* 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
st.a r13, [sp, -4]
st.a r14, [sp, -4]
st.a r15, [sp, -4]
st.a r16, [sp, -4]
st.a r17, [sp, -4]
st.a r18, [sp, -4]
st.a r19, [sp, -4]
st.a r20, [sp, -4]
st.a r21, [sp, -4]
st.a r22, [sp, -4]
st.a r23, [sp, -4]
st.a r24, [sp, -4]
SAVE_R13_TO_R24
#ifdef CONFIG_ARC_CURR_IN_REG
; Retrieve orig r25 and save it on stack
ld r12, [r25, TASK_THREAD + THREAD_USER_R25]
ld.as r12, [sp, OFF_USER_R25_FROM_R24]
st.a r12, [sp, -4]
#else
st.a r25, [sp, -4]
PUSH r25
#endif
/* move up by 1 word to "create" callee_regs->"stack_place_holder" */
sub sp, sp, 4
.endm
/*--------------------------------------------------------------
* Save callee saved registers (non scratch registers) ( r13 - r25 )
* kernel mode callee regs needed to be saved in case of context switch
* If r25 is used for caching task pointer then that need not be saved
* as it can be re-created from current task global
* 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
st.a r13, [sp, -4]