aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arc')
-rw-r--r--arch/arc/Kconfig9
-rw-r--r--arch/arc/Kconfig.debug7
-rw-r--r--arch/arc/Makefile28
-rw-r--r--arch/arc/boot/dts/abilis_tb100_dvk.dts10
-rw-r--r--arch/arc/boot/dts/abilis_tb101_dvk.dts10
-rw-r--r--arch/arc/configs/fpga_defconfig2
-rw-r--r--arch/arc/configs/nsimosci_defconfig2
-rw-r--r--arch/arc/configs/tb10x_defconfig2
-rw-r--r--arch/arc/include/asm/arcregs.h127
-rw-r--r--arch/arc/include/asm/bug.h5
-rw-r--r--arch/arc/include/asm/cache.h26
-rw-r--r--arch/arc/include/asm/cacheflush.h13
-rw-r--r--arch/arc/include/asm/defines.h56
-rw-r--r--arch/arc/include/asm/entry.h521
-rw-r--r--arch/arc/include/asm/irq.h2
-rw-r--r--arch/arc/include/asm/irqflags.h20
-rw-r--r--arch/arc/include/asm/kgdb.h4
-rw-r--r--arch/arc/include/asm/kprobes.h6
-rw-r--r--arch/arc/include/asm/mmu.h44
-rw-r--r--arch/arc/include/asm/page.h7
-rw-r--r--arch/arc/include/asm/pgtable.h9
-rw-r--r--arch/arc/include/asm/processor.h17
-rw-r--r--arch/arc/include/asm/ptrace.h47
-rw-r--r--arch/arc/include/asm/syscall.h5
-rw-r--r--arch/arc/include/asm/tlb-mmu1.h4
-rw-r--r--arch/arc/include/asm/tlb.h26
-rw-r--r--arch/arc/include/asm/unaligned.h4
-rw-r--r--arch/arc/include/uapi/asm/ptrace.h15
-rw-r--r--arch/arc/kernel/asm-offsets.c7
-rw-r--r--arch/arc/kernel/ctx_sw.c14
-rw-r--r--arch/arc/kernel/entry.S103
-rw-r--r--arch/arc/kernel/head.S2
-rw-r--r--arch/arc/kernel/irq.c16
-rw-r--r--arch/arc/kernel/kgdb.c4
-rw-r--r--arch/arc/kernel/kprobes.c5
-rw-r--r--arch/arc/kernel/process.c9
-rw-r--r--arch/arc/kernel/ptrace.c14
-rw-r--r--arch/arc/kernel/setup.c18
-rw-r--r--arch/arc/kernel/smp.c4
-rw-r--r--arch/arc/kernel/stacktrace.c2
-rw-r--r--arch/arc/kernel/time.c17
-rw-r--r--arch/arc/kernel/traps.c52
-rw-r--r--arch/arc/kernel/troubleshoot.c33
-rw-r--r--arch/arc/kernel/unaligned.c2
-rw-r--r--arch/arc/kernel/unwind.c2
-rw-r--r--arch/arc/kernel/vmlinux.lds.S24
-rw-r--r--arch/arc/mm/cache_arc700.c126
-rw-r--r--arch/arc/mm/fault.c12
-rw-r--r--arch/arc/mm/init.c42
-rw-r--r--arch/arc/mm/tlb.c38
-rw-r--r--arch/arc/mm/tlbex.S35
-rw-r--r--arch/arc/plat-arcfpga/platform.c12
52 files changed, 688 insertions, 933 deletions
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 5917099470ea..68fcbb2d59e2 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -34,6 +34,7 @@ config ARC
34 select OF 34 select OF
35 select OF_EARLY_FLATTREE 35 select OF_EARLY_FLATTREE
36 select PERF_USE_VMALLOC 36 select PERF_USE_VMALLOC
37 select HAVE_DEBUG_STACKOVERFLOW
37 38
38config SCHED_OMIT_FRAME_POINTER 39config SCHED_OMIT_FRAME_POINTER
39 def_bool y 40 def_bool y
@@ -184,6 +185,7 @@ config ARC_CACHE_PAGES
184 185
185config ARC_CACHE_VIPT_ALIASING 186config ARC_CACHE_VIPT_ALIASING
186 bool "Support VIPT Aliasing D$" 187 bool "Support VIPT Aliasing D$"
188 depends on ARC_HAS_DCACHE
187 default n 189 default n
188 190
189endif #ARC_CACHE 191endif #ARC_CACHE
@@ -361,13 +363,6 @@ config ARC_MISALIGN_ACCESS
361 Use ONLY-IF-ABS-NECESSARY as it will be very slow and also can hide 363 Use ONLY-IF-ABS-NECESSARY as it will be very slow and also can hide
362 potential bugs in code 364 potential bugs in code
363 365
364config ARC_STACK_NONEXEC
365 bool "Make stack non-executable"
366 default n
367 help
368 To disable the execute permissions of stack/heap of processes
369 which are enabled by default.
370
371config HZ 366config HZ
372 int "Timer Frequency" 367 int "Timer Frequency"
373 default 100 368 default 100
diff --git a/arch/arc/Kconfig.debug b/arch/arc/Kconfig.debug
index 962c6099659e..a7fc0da25650 100644
--- a/arch/arc/Kconfig.debug
+++ b/arch/arc/Kconfig.debug
@@ -15,13 +15,6 @@ config EARLY_PRINTK
15 with klogd/syslogd or the X server. You should normally N here, 15 with klogd/syslogd or the X server. You should normally N here,
16 unless you want to debug such a crash. 16 unless you want to debug such a crash.
17 17
18config DEBUG_STACKOVERFLOW
19 bool "Check for stack overflows"
20 depends on DEBUG_KERNEL
21 help
22 This option will cause messages to be printed if free stack space
23 drops below a certain limit.
24
25config 16KSTACKS 18config 16KSTACKS
26 bool "Use 16Kb for kernel stacks instead of 8Kb" 19 bool "Use 16Kb for kernel stacks instead of 8Kb"
27 help 20 help
diff --git a/arch/arc/Makefile b/arch/arc/Makefile
index 183397fd289e..8c0b1aa56f7e 100644
--- a/arch/arc/Makefile
+++ b/arch/arc/Makefile
@@ -9,25 +9,27 @@
9UTS_MACHINE := arc 9UTS_MACHINE := arc
10 10
11ifeq ($(CROSS_COMPILE),) 11ifeq ($(CROSS_COMPILE),)
12CROSS_COMPILE := arc-elf32- 12CROSS_COMPILE := arc-linux-uclibc-
13endif 13endif
14 14
15KBUILD_DEFCONFIG := fpga_defconfig 15KBUILD_DEFCONFIG := fpga_defconfig
16 16
17cflags-y += -mA7 -fno-common -pipe -fno-builtin -D__linux__ 17cflags-y += -mA7 -fno-common -pipe -fno-builtin -D__linux__
18 18
19LINUXINCLUDE += -include ${src}/arch/arc/include/asm/defines.h
20
21ifdef CONFIG_ARC_CURR_IN_REG 19ifdef CONFIG_ARC_CURR_IN_REG
22# For a global register defintion, make sure it gets passed to every file 20# For a global register defintion, make sure it gets passed to every file
23# We had a customer reported bug where some code built in kernel was NOT using 21# We had a customer reported bug where some code built in kernel was NOT using
24# any kernel headers, and missing the r25 global register 22# any kernel headers, and missing the r25 global register
25# Can't do unconditionally (like above) because of recursive include issues 23# Can't do unconditionally because of recursive include issues
26# due to <linux/thread_info.h> 24# due to <linux/thread_info.h>
27LINUXINCLUDE += -include ${src}/arch/arc/include/asm/current.h 25LINUXINCLUDE += -include ${src}/arch/arc/include/asm/current.h
28endif 26endif
29 27
30atleast_gcc44 := $(call cc-ifversion, -gt, 0402, y) 28upto_gcc42 := $(call cc-ifversion, -le, 0402, y)
29upto_gcc44 := $(call cc-ifversion, -le, 0404, y)
30atleast_gcc44 := $(call cc-ifversion, -ge, 0404, y)
31atleast_gcc48 := $(call cc-ifversion, -ge, 0408, y)
32
31cflags-$(atleast_gcc44) += -fsection-anchors 33cflags-$(atleast_gcc44) += -fsection-anchors
32 34
33cflags-$(CONFIG_ARC_HAS_LLSC) += -mlock 35cflags-$(CONFIG_ARC_HAS_LLSC) += -mlock
@@ -35,6 +37,11 @@ cflags-$(CONFIG_ARC_HAS_SWAPE) += -mswape
35cflags-$(CONFIG_ARC_HAS_RTSC) += -mrtsc 37cflags-$(CONFIG_ARC_HAS_RTSC) += -mrtsc
36cflags-$(CONFIG_ARC_DW2_UNWIND) += -fasynchronous-unwind-tables 38cflags-$(CONFIG_ARC_DW2_UNWIND) += -fasynchronous-unwind-tables
37 39
40# By default gcc 4.8 generates dwarf4 which kernel unwinder can't grok
41ifeq ($(atleast_gcc48),y)
42cflags-$(CONFIG_ARC_DW2_UNWIND) += -gdwarf-2
43endif
44
38ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE 45ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE
39# Generic build system uses -O2, we want -O3 46# Generic build system uses -O2, we want -O3
40cflags-y += -O3 47cflags-y += -O3
@@ -48,11 +55,10 @@ cflags-$(disable_small_data) += -mno-sdata -fcall-used-gp
48cflags-$(CONFIG_CPU_BIG_ENDIAN) += -mbig-endian 55cflags-$(CONFIG_CPU_BIG_ENDIAN) += -mbig-endian
49ldflags-$(CONFIG_CPU_BIG_ENDIAN) += -EB 56ldflags-$(CONFIG_CPU_BIG_ENDIAN) += -EB
50 57
51# STAR 9000518362: 58# STAR 9000518362: (fixed with binutils shipping with gcc 4.8)
52# arc-linux-uclibc-ld (buildroot) or arceb-elf32-ld (EZChip) don't accept 59# arc-linux-uclibc-ld (buildroot) or arceb-elf32-ld (EZChip) don't accept
53# --build-id w/o "-marclinux". 60# --build-id w/o "-marclinux". Default arc-elf32-ld is OK
54# Default arc-elf32-ld is OK 61ldflags-$(upto_gcc44) += -marclinux
55ldflags-y += -marclinux
56 62
57ARC_LIBGCC := -mA7 63ARC_LIBGCC := -mA7
58cflags-$(CONFIG_ARC_HAS_HW_MPY) += -multcost=16 64cflags-$(CONFIG_ARC_HAS_HW_MPY) += -multcost=16
@@ -66,8 +72,8 @@ ifndef CONFIG_ARC_HAS_HW_MPY
66# With gcc 4.4.7, -mno-mpy is enough to make any other related adjustments, 72# With gcc 4.4.7, -mno-mpy is enough to make any other related adjustments,
67# e.g. increased cost of MPY. With gcc 4.2.1 this had to be explicitly hinted 73# e.g. increased cost of MPY. With gcc 4.2.1 this had to be explicitly hinted
68 74
69 ARC_LIBGCC := -marc600 75 ifeq ($(upto_gcc42),y)
70 ifneq ($(atleast_gcc44),y) 76 ARC_LIBGCC := -marc600
71 cflags-y += -multcost=30 77 cflags-y += -multcost=30
72 endif 78 endif
73endif 79endif
diff --git a/arch/arc/boot/dts/abilis_tb100_dvk.dts b/arch/arc/boot/dts/abilis_tb100_dvk.dts
index 0fa0d4abe795..ebc313a9f5b2 100644
--- a/arch/arc/boot/dts/abilis_tb100_dvk.dts
+++ b/arch/arc/boot/dts/abilis_tb100_dvk.dts
@@ -45,19 +45,19 @@
45 }; 45 };
46 46
47 i2c0: i2c@FF120000 { 47 i2c0: i2c@FF120000 {
48 sda-hold-time = <432>; 48 i2c-sda-hold-time-ns = <432>;
49 }; 49 };
50 i2c1: i2c@FF121000 { 50 i2c1: i2c@FF121000 {
51 sda-hold-time = <432>; 51 i2c-sda-hold-time-ns = <432>;
52 }; 52 };
53 i2c2: i2c@FF122000 { 53 i2c2: i2c@FF122000 {
54 sda-hold-time = <432>; 54 i2c-sda-hold-time-ns = <432>;
55 }; 55 };
56 i2c3: i2c@FF123000 { 56 i2c3: i2c@FF123000 {
57 sda-hold-time = <432>; 57 i2c-sda-hold-time-ns = <432>;
58 }; 58 };
59 i2c4: i2c@FF124000 { 59 i2c4: i2c@FF124000 {
60 sda-hold-time = <432>; 60 i2c-sda-hold-time-ns = <432>;
61 }; 61 };
62 62
63 leds { 63 leds {
diff --git a/arch/arc/boot/dts/abilis_tb101_dvk.dts b/arch/arc/boot/dts/abilis_tb101_dvk.dts
index a4d80ce283ae..b204657993aa 100644
--- a/arch/arc/boot/dts/abilis_tb101_dvk.dts
+++ b/arch/arc/boot/dts/abilis_tb101_dvk.dts
@@ -45,19 +45,19 @@
45 }; 45 };
46 46
47 i2c0: i2c@FF120000 { 47 i2c0: i2c@FF120000 {
48 sda-hold-time = <432>; 48 i2c-sda-hold-time-ns = <432>;
49 }; 49 };
50 i2c1: i2c@FF121000 { 50 i2c1: i2c@FF121000 {
51 sda-hold-time = <432>; 51 i2c-sda-hold-time-ns = <432>;
52 }; 52 };
53 i2c2: i2c@FF122000 { 53 i2c2: i2c@FF122000 {
54 sda-hold-time = <432>; 54 i2c-sda-hold-time-ns = <432>;
55 }; 55 };
56 i2c3: i2c@FF123000 { 56 i2c3: i2c@FF123000 {
57 sda-hold-time = <432>; 57 i2c-sda-hold-time-ns = <432>;
58 }; 58 };
59 i2c4: i2c@FF124000 { 59 i2c4: i2c@FF124000 {
60 sda-hold-time = <432>; 60 i2c-sda-hold-time-ns = <432>;
61 }; 61 };
62 62
63 leds { 63 leds {
diff --git a/arch/arc/configs/fpga_defconfig b/arch/arc/configs/fpga_defconfig
index 95350be6ef6f..c109af320274 100644
--- a/arch/arc/configs/fpga_defconfig
+++ b/arch/arc/configs/fpga_defconfig
@@ -1,4 +1,4 @@
1CONFIG_CROSS_COMPILE="arc-elf32-" 1CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
2# CONFIG_LOCALVERSION_AUTO is not set 2# CONFIG_LOCALVERSION_AUTO is not set
3CONFIG_DEFAULT_HOSTNAME="ARCLinux" 3CONFIG_DEFAULT_HOSTNAME="ARCLinux"
4# CONFIG_SWAP is not set 4# CONFIG_SWAP is not set
diff --git a/arch/arc/configs/nsimosci_defconfig b/arch/arc/configs/nsimosci_defconfig
index 446c96c24eff..451af30914f6 100644
--- a/arch/arc/configs/nsimosci_defconfig
+++ b/arch/arc/configs/nsimosci_defconfig
@@ -1,4 +1,4 @@
1CONFIG_CROSS_COMPILE="arc-elf32-" 1CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
2# CONFIG_LOCALVERSION_AUTO is not set 2# CONFIG_LOCALVERSION_AUTO is not set
3CONFIG_DEFAULT_HOSTNAME="ARCLinux" 3CONFIG_DEFAULT_HOSTNAME="ARCLinux"
4# CONFIG_SWAP is not set 4# CONFIG_SWAP is not set
diff --git a/arch/arc/configs/tb10x_defconfig b/arch/arc/configs/tb10x_defconfig
index 4fa5cd9f2202..6be6492442d6 100644
--- a/arch/arc/configs/tb10x_defconfig
+++ b/arch/arc/configs/tb10x_defconfig
@@ -1,4 +1,4 @@
1CONFIG_CROSS_COMPILE="arc-elf32-" 1CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
2# CONFIG_LOCALVERSION_AUTO is not set 2# CONFIG_LOCALVERSION_AUTO is not set
3CONFIG_DEFAULT_HOSTNAME="tb10x" 3CONFIG_DEFAULT_HOSTNAME="tb10x"
4CONFIG_SYSVIPC=y 4CONFIG_SYSVIPC=y
diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h
index 1b907c465666..355cb470c2a4 100644
--- a/arch/arc/include/asm/arcregs.h
+++ b/arch/arc/include/asm/arcregs.h
@@ -20,7 +20,6 @@
20#define ARC_REG_PERIBASE_BCR 0x69 20#define ARC_REG_PERIBASE_BCR 0x69
21#define ARC_REG_FP_BCR 0x6B /* Single-Precision FPU */ 21#define ARC_REG_FP_BCR 0x6B /* Single-Precision FPU */
22#define ARC_REG_DPFP_BCR 0x6C /* Dbl Precision FPU */ 22#define ARC_REG_DPFP_BCR 0x6C /* Dbl Precision FPU */
23#define ARC_REG_MMU_BCR 0x6f
24#define ARC_REG_DCCM_BCR 0x74 /* DCCM Present + SZ */ 23#define ARC_REG_DCCM_BCR 0x74 /* DCCM Present + SZ */
25#define ARC_REG_TIMERS_BCR 0x75 24#define ARC_REG_TIMERS_BCR 0x75
26#define ARC_REG_ICCM_BCR 0x78 25#define ARC_REG_ICCM_BCR 0x78
@@ -34,22 +33,12 @@
34#define ARC_REG_D_UNCACH_BCR 0x6A 33#define ARC_REG_D_UNCACH_BCR 0x6A
35 34
36/* status32 Bits Positions */ 35/* status32 Bits Positions */
37#define STATUS_H_BIT 0 /* CPU Halted */
38#define STATUS_E1_BIT 1 /* Int 1 enable */
39#define STATUS_E2_BIT 2 /* Int 2 enable */
40#define STATUS_A1_BIT 3 /* Int 1 active */
41#define STATUS_A2_BIT 4 /* Int 2 active */
42#define STATUS_AE_BIT 5 /* Exception active */ 36#define STATUS_AE_BIT 5 /* Exception active */
43#define STATUS_DE_BIT 6 /* PC is in delay slot */ 37#define STATUS_DE_BIT 6 /* PC is in delay slot */
44#define STATUS_U_BIT 7 /* User/Kernel mode */ 38#define STATUS_U_BIT 7 /* User/Kernel mode */
45#define STATUS_L_BIT 12 /* Loop inhibit */ 39#define STATUS_L_BIT 12 /* Loop inhibit */
46 40
47/* These masks correspond to the status word(STATUS_32) bits */ 41/* These masks correspond to the status word(STATUS_32) bits */
48#define STATUS_H_MASK (1<<STATUS_H_BIT)
49#define STATUS_E1_MASK (1<<STATUS_E1_BIT)
50#define STATUS_E2_MASK (1<<STATUS_E2_BIT)
51#define STATUS_A1_MASK (1<<STATUS_A1_BIT)
52#define STATUS_A2_MASK (1<<STATUS_A2_BIT)
53#define STATUS_AE_MASK (1<<STATUS_AE_BIT) 42#define STATUS_AE_MASK (1<<STATUS_AE_BIT)
54#define STATUS_DE_MASK (1<<STATUS_DE_BIT) 43#define STATUS_DE_MASK (1<<STATUS_DE_BIT)
55#define STATUS_U_MASK (1<<STATUS_U_BIT) 44#define STATUS_U_MASK (1<<STATUS_U_BIT)
@@ -71,6 +60,7 @@
71#define ECR_V_ITLB_MISS 0x21 60#define ECR_V_ITLB_MISS 0x21
72#define ECR_V_DTLB_MISS 0x22 61#define ECR_V_DTLB_MISS 0x22
73#define ECR_V_PROTV 0x23 62#define ECR_V_PROTV 0x23
63#define ECR_V_TRAP 0x25
74 64
75/* Protection Violation Exception Cause Code Values */ 65/* Protection Violation Exception Cause Code Values */
76#define ECR_C_PROTV_INST_FETCH 0x00 66#define ECR_C_PROTV_INST_FETCH 0x00
@@ -79,94 +69,23 @@
79#define ECR_C_PROTV_XCHG 0x03 69#define ECR_C_PROTV_XCHG 0x03
80#define ECR_C_PROTV_MISALIG_DATA 0x04 70#define ECR_C_PROTV_MISALIG_DATA 0x04
81 71
72#define ECR_C_BIT_PROTV_MISALIG_DATA 10
73
74/* Machine Check Cause Code Values */
75#define ECR_C_MCHK_DUP_TLB 0x01
76
82/* DTLB Miss Exception Cause Code Values */ 77/* DTLB Miss Exception Cause Code Values */
83#define ECR_C_BIT_DTLB_LD_MISS 8 78#define ECR_C_BIT_DTLB_LD_MISS 8
84#define ECR_C_BIT_DTLB_ST_MISS 9 79#define ECR_C_BIT_DTLB_ST_MISS 9
85 80
81/* Dummy ECR values for Interrupts */
82#define event_IRQ1 0x0031abcd
83#define event_IRQ2 0x0032abcd
86 84
87/* Auxiliary registers */ 85/* Auxiliary registers */
88#define AUX_IDENTITY 4 86#define AUX_IDENTITY 4
89#define AUX_INTR_VEC_BASE 0x25 87#define AUX_INTR_VEC_BASE 0x25
90#define AUX_IRQ_LEV 0x200 /* IRQ Priority: L1 or L2 */
91#define AUX_IRQ_HINT 0x201 /* For generating Soft Interrupts */
92#define AUX_IRQ_LV12 0x43 /* interrupt level register */
93
94#define AUX_IENABLE 0x40c
95#define AUX_ITRIGGER 0x40d
96#define AUX_IPULSE 0x415
97
98/* Timer related Aux registers */
99#define ARC_REG_TIMER0_LIMIT 0x23 /* timer 0 limit */
100#define ARC_REG_TIMER0_CTRL 0x22 /* timer 0 control */
101#define ARC_REG_TIMER0_CNT 0x21 /* timer 0 count */
102#define ARC_REG_TIMER1_LIMIT 0x102 /* timer 1 limit */
103#define ARC_REG_TIMER1_CTRL 0x101 /* timer 1 control */
104#define ARC_REG_TIMER1_CNT 0x100 /* timer 1 count */
105
106#define TIMER_CTRL_IE (1 << 0) /* Interupt when Count reachs limit */
107#define TIMER_CTRL_NH (1 << 1) /* Count only when CPU NOT halted */
108
109/* MMU Management regs */
110#define ARC_REG_TLBPD0 0x405
111#define ARC_REG_TLBPD1 0x406
112#define ARC_REG_TLBINDEX 0x407
113#define ARC_REG_TLBCOMMAND 0x408
114#define ARC_REG_PID 0x409
115#define ARC_REG_SCRATCH_DATA0 0x418
116
117/* Bits in MMU PID register */
118#define MMU_ENABLE (1 << 31) /* Enable MMU for process */
119
120/* Error code if probe fails */
121#define TLB_LKUP_ERR 0x80000000
122
123/* TLB Commands */
124#define TLBWrite 0x1
125#define TLBRead 0x2
126#define TLBGetIndex 0x3
127#define TLBProbe 0x4
128
129#if (CONFIG_ARC_MMU_VER >= 2)
130#define TLBWriteNI 0x5 /* write JTLB without inv uTLBs */
131#define TLBIVUTLB 0x6 /* explicitly inv uTLBs */
132#else
133#undef TLBWriteNI /* These cmds don't exist on older MMU */
134#undef TLBIVUTLB
135#endif
136 88
137/* Instruction cache related Auxiliary registers */
138#define ARC_REG_IC_BCR 0x77 /* Build Config reg */
139#define ARC_REG_IC_IVIC 0x10
140#define ARC_REG_IC_CTRL 0x11
141#define ARC_REG_IC_IVIL 0x19
142#if (CONFIG_ARC_MMU_VER > 2)
143#define ARC_REG_IC_PTAG 0x1E
144#endif
145
146/* Bit val in IC_CTRL */
147#define IC_CTRL_CACHE_DISABLE 0x1
148
149/* Data cache related Auxiliary registers */
150#define ARC_REG_DC_BCR 0x72
151#define ARC_REG_DC_IVDC 0x47
152#define ARC_REG_DC_CTRL 0x48
153#define ARC_REG_DC_IVDL 0x4A
154#define ARC_REG_DC_FLSH 0x4B
155#define ARC_REG_DC_FLDL 0x4C
156#if (CONFIG_ARC_MMU_VER > 2)
157#define ARC_REG_DC_PTAG 0x5C
158#endif
159
160/* Bit val in DC_CTRL */
161#define DC_CTRL_INV_MODE_FLUSH 0x40
162#define DC_CTRL_FLUSH_STATUS 0x100
163
164/* MMU Management regs */
165#define ARC_REG_PID 0x409
166#define ARC_REG_SCRATCH_DATA0 0x418
167
168/* Bits in MMU PID register */
169#define MMU_ENABLE (1 << 31) /* Enable MMU for process */
170 89
171/* 90/*
172 * Floating Pt Registers 91 * Floating Pt Registers
@@ -293,24 +212,6 @@ struct bcr_identity {
293#endif 212#endif
294}; 213};
295 214
296struct bcr_mmu_1_2 {
297#ifdef CONFIG_CPU_BIG_ENDIAN
298 unsigned int ver:8, ways:4, sets:4, u_itlb:8, u_dtlb:8;
299#else
300 unsigned int u_dtlb:8, u_itlb:8, sets:4, ways:4, ver:8;
301#endif
302};
303
304struct bcr_mmu_3 {
305#ifdef CONFIG_CPU_BIG_ENDIAN
306 unsigned int ver:8, ways:4, sets:4, osm:1, reserv:3, pg_sz:4,
307 u_itlb:4, u_dtlb:4;
308#else
309 unsigned int u_dtlb:4, u_itlb:4, pg_sz:4, reserv:3, osm:1, sets:4,
310 ways:4, ver:8;
311#endif
312};
313
314#define EXTN_SWAP_VALID 0x1 215#define EXTN_SWAP_VALID 0x1
315#define EXTN_NORM_VALID 0x2 216#define EXTN_NORM_VALID 0x2
316#define EXTN_MINMAX_VALID 0x2 217#define EXTN_MINMAX_VALID 0x2
@@ -343,14 +244,6 @@ struct bcr_extn_xymem {
343#endif 244#endif
344}; 245};
345 246
346struct bcr_cache {
347#ifdef CONFIG_CPU_BIG_ENDIAN
348 unsigned int pad:12, line_len:4, sz:4, config:4, ver:8;
349#else
350 unsigned int ver:8, config:4, sz:4, line_len:4, pad:12;
351#endif
352};
353
354struct bcr_perip { 247struct bcr_perip {
355#ifdef CONFIG_CPU_BIG_ENDIAN 248#ifdef CONFIG_CPU_BIG_ENDIAN
356 unsigned int start:8, pad2:8, sz:8, pad:8; 249 unsigned int start:8, pad2:8, sz:8, pad:8;
@@ -403,7 +296,7 @@ struct cpuinfo_arc_mmu {
403}; 296};
404 297
405struct cpuinfo_arc_cache { 298struct cpuinfo_arc_cache {
406 unsigned int has_aliasing, sz, line_len, assoc, ver; 299 unsigned int sz, line_len, assoc, ver;
407}; 300};
408 301
409struct cpuinfo_arc_ccm { 302struct cpuinfo_arc_ccm {
diff --git a/arch/arc/include/asm/bug.h b/arch/arc/include/asm/bug.h
index 2ad8f9b1c54b..5b18e94c6678 100644
--- a/arch/arc/include/asm/bug.h
+++ b/arch/arc/include/asm/bug.h
@@ -18,9 +18,8 @@ struct task_struct;
18void show_regs(struct pt_regs *regs); 18void show_regs(struct pt_regs *regs);
19void show_stacktrace(struct task_struct *tsk, struct pt_regs *regs); 19void show_stacktrace(struct task_struct *tsk, struct pt_regs *regs);
20void show_kernel_fault_diag(const char *str, struct pt_regs *regs, 20void show_kernel_fault_diag(const char *str, struct pt_regs *regs,
21 unsigned long address, unsigned long cause_reg); 21 unsigned long address);
22void die(const char *str, struct pt_regs *regs, unsigned long address, 22void die(const char *str, struct pt_regs *regs, unsigned long address);
23 unsigned long cause_reg);
24 23
25#define BUG() do { \ 24#define BUG() do { \
26 dump_stack(); \ 25 dump_stack(); \
diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h
index d5555fe4742a..5802849a6cae 100644
--- a/arch/arc/include/asm/cache.h
+++ b/arch/arc/include/asm/cache.h
@@ -18,21 +18,19 @@
18 18
19#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) 19#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
20 20
21#define ARC_ICACHE_WAYS 2 21/* For a rare case where customers have differently config I/D */
22#define ARC_DCACHE_WAYS 4
23
24/* Helpers */
25#define ARC_ICACHE_LINE_LEN L1_CACHE_BYTES 22#define ARC_ICACHE_LINE_LEN L1_CACHE_BYTES
26#define ARC_DCACHE_LINE_LEN L1_CACHE_BYTES 23#define ARC_DCACHE_LINE_LEN L1_CACHE_BYTES
27 24
28#define ICACHE_LINE_MASK (~(ARC_ICACHE_LINE_LEN - 1)) 25#define ICACHE_LINE_MASK (~(ARC_ICACHE_LINE_LEN - 1))
29#define DCACHE_LINE_MASK (~(ARC_DCACHE_LINE_LEN - 1)) 26#define DCACHE_LINE_MASK (~(ARC_DCACHE_LINE_LEN - 1))
30 27
31#if ARC_ICACHE_LINE_LEN != ARC_DCACHE_LINE_LEN 28/*
32#error "Need to fix some code as I/D cache lines not same" 29 * ARC700 doesn't cache any access in top 256M.
33#else 30 * Ideal for wiring memory mapped peripherals as we don't need to do
34#define is_not_cache_aligned(p) ((unsigned long)p & (~DCACHE_LINE_MASK)) 31 * explicit uncached accesses (LD.di/ST.di) hence more portable drivers
35#endif 32 */
33#define ARC_UNCACHED_ADDR_SPACE 0xc0000000
36 34
37#ifndef __ASSEMBLY__ 35#ifndef __ASSEMBLY__
38 36
@@ -57,16 +55,10 @@
57 55
58#define ARCH_DMA_MINALIGN L1_CACHE_BYTES 56#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
59 57
60/*
61 * ARC700 doesn't cache any access in top 256M.
62 * Ideal for wiring memory mapped peripherals as we don't need to do
63 * explicit uncached accesses (LD.di/ST.di) hence more portable drivers
64 */
65#define ARC_UNCACHED_ADDR_SPACE 0xc0000000
66
67extern void arc_cache_init(void); 58extern void arc_cache_init(void);
68extern char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len); 59extern char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len);
69extern void __init read_decode_cache_bcr(void); 60extern void __init read_decode_cache_bcr(void);
70#endif 61
62#endif /* !__ASSEMBLY__ */
71 63
72#endif /* _ASM_CACHE_H */ 64#endif /* _ASM_CACHE_H */
diff --git a/arch/arc/include/asm/cacheflush.h b/arch/arc/include/asm/cacheflush.h
index ef62682e8d95..6abc4972bc93 100644
--- a/arch/arc/include/asm/cacheflush.h
+++ b/arch/arc/include/asm/cacheflush.h
@@ -81,16 +81,19 @@ void flush_anon_page(struct vm_area_struct *vma,
81#endif /* CONFIG_ARC_CACHE_VIPT_ALIASING */ 81#endif /* CONFIG_ARC_CACHE_VIPT_ALIASING */
82 82
83/* 83/*
84 * A new pagecache page has PG_arch_1 clear - thus dcache dirty by default
85 * This works around some PIO based drivers which don't call flush_dcache_page
86 * to record that they dirtied the dcache
87 */
88#define PG_dc_clean PG_arch_1
89
90/*
84 * Simple wrapper over config option 91 * Simple wrapper over config option
85 * Bootup code ensures that hardware matches kernel configuration 92 * Bootup code ensures that hardware matches kernel configuration
86 */ 93 */
87static inline int cache_is_vipt_aliasing(void) 94static inline int cache_is_vipt_aliasing(void)
88{ 95{
89#ifdef CONFIG_ARC_CACHE_VIPT_ALIASING 96 return IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING);
90 return 1;
91#else
92 return 0;
93#endif
94} 97}
95 98
96#define CACHE_COLOR(addr) (((unsigned long)(addr) >> (PAGE_SHIFT)) & 1) 99#define CACHE_COLOR(addr) (((unsigned long)(addr) >> (PAGE_SHIFT)) & 1)
diff --git a/arch/arc/include/asm/defines.h b/arch/arc/include/asm/defines.h
deleted file mode 100644
index 6097bb439cc5..000000000000
--- a/arch/arc/include/asm/defines.h
+++ /dev/null
@@ -1,56 +0,0 @@
1/*
2 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef __ARC_ASM_DEFINES_H__
10#define __ARC_ASM_DEFINES_H__
11
12#if defined(CONFIG_ARC_MMU_V1)
13#define CONFIG_ARC_MMU_VER 1
14#elif defined(CONFIG_ARC_MMU_V2)
15#define CONFIG_ARC_MMU_VER 2
16#elif defined(CONFIG_ARC_MMU_V3)
17#define CONFIG_ARC_MMU_VER 3
18#endif
19
20#ifdef CONFIG_ARC_HAS_LLSC
21#define __CONFIG_ARC_HAS_LLSC_VAL 1
22#else
23#define __CONFIG_ARC_HAS_LLSC_VAL 0
24#endif
25
26#ifdef CONFIG_ARC_HAS_SWAPE
27#define __CONFIG_ARC_HAS_SWAPE_VAL 1
28#else
29#define __CONFIG_ARC_HAS_SWAPE_VAL 0
30#endif
31
32#ifdef CONFIG_ARC_HAS_RTSC
33#define __CONFIG_ARC_HAS_RTSC_VAL 1
34#else
35#define __CONFIG_ARC_HAS_RTSC_VAL 0
36#endif
37
38#ifdef CONFIG_ARC_MMU_SASID
39#define __CONFIG_ARC_MMU_SASID_VAL 1
40#else
41#define __CONFIG_ARC_MMU_SASID_VAL 0
42#endif
43
44#ifdef CONFIG_ARC_HAS_ICACHE
45#define __CONFIG_ARC_HAS_ICACHE 1
46#else
47#define __CONFIG_ARC_HAS_ICACHE 0
48#endif
49
50#ifdef CONFIG_ARC_HAS_DCACHE
51#define __CONFIG_ARC_HAS_DCACHE 1
52#else
53#define __CONFIG_ARC_HAS_DCACHE 0
54#endif
55
56#endif /* __ARC_ASM_DEFINES_H__ */
diff --git a/arch/arc/include/asm/entry.h b/arch/arc/include/asm/entry.h
index eb2ae53187d9..8943c028d4bb 100644
--- a/arch/arc/include/asm/entry.h
+++ b/arch/arc/include/asm/entry.h
@@ -50,194 +50,177 @@
50 * Eff Addr for load = [reg2] 50 * Eff Addr for load = [reg2]
51 */ 51 */
52 52
53.macro PUSH reg
54 st.a \reg, [sp, -4]
55.endm
56
57.macro PUSHAX aux
58 lr r9, [\aux]
59 PUSH r9
60.endm
61
62.macro POP reg
63 ld.ab \reg, [sp, 4]
64.endm
65
66.macro POPAX aux
67 POP r9
68 sr r9, [\aux]
69.endm
70
53/*-------------------------------------------------------------- 71/*--------------------------------------------------------------
54 * Save caller saved registers (scratch registers) ( r0 - r12 ) 72 * Helpers to save/restore Scratch Regs:
55 * Registers are pushed / popped in the order defined in struct ptregs 73 * used by Interrupt/Exception Prologue/Epilogue
56 * in asm/ptrace.h
57 *-------------------------------------------------------------*/ 74 *-------------------------------------------------------------*/
58.macro SAVE_CALLER_SAVED 75.macro SAVE_R0_TO_R12
59 st.a r0, [sp, -4] 76 PUSH r0
60 st.a r1, [sp, -4] 77 PUSH r1
61 st.a r2, [sp, -4] 78 PUSH r2
62 st.a r3, [sp, -4] 79 PUSH r3
63 st.a r4, [sp, -4] 80 PUSH r4
64 st.a r5, [sp, -4] 81 PUSH r5
65 st.a r6, [sp, -4] 82 PUSH r6
66 st.a r7, [sp, -4] 83 PUSH r7
67 st.a r8, [sp, -4] 84 PUSH r8
68 st.a r9, [sp, -4] 85 PUSH r9
69 st.a r10, [sp, -4] 86 PUSH r10
70 st.a r11, [sp, -4] 87 PUSH r11
71 st.a r12, [sp, -4] 88 PUSH r12
89.endm
90
91.macro RESTORE_R12_TO_R0
92 POP r12
93 POP r11
94 POP r10
95 POP r9
96 POP r8
97 POP r7
98 POP r6
99 POP r5
100 POP r4
101 POP r3
102 POP r2
103 POP r1
104 POP r0
105
106#ifdef CONFIG_ARC_CURR_IN_REG
107 ld r25, [sp, 12]
108#endif
72.endm 109.endm
73 110
74/*-------------------------------------------------------------- 111/*--------------------------------------------------------------
75 * Restore caller saved registers (scratch registers) 112 * Helpers to save/restore callee-saved regs:
113 * used by several macros below
76 *-------------------------------------------------------------*/ 114 *-------------------------------------------------------------*/
77.macro RESTORE_CALLER_SAVED 115.macro SAVE_R13_TO_R24
78 ld.ab r12, [sp, 4] 116 PUSH r13
79 ld.ab r11, [sp, 4] 117 PUSH r14
80 ld.ab r10, [sp, 4] 118 PUSH r15
81 ld.ab r9, [sp, 4] 119 PUSH r16
82 ld.ab r8, [sp, 4] 120 PUSH r17
83 ld.ab r7, [sp, 4] 121 PUSH r18
84 ld.ab r6, [sp, 4] 122 PUSH r19
85 ld.ab r5, [sp, 4] 123 PUSH r20
86 ld.ab r4, [sp, 4] 124 PUSH r21
87 ld.ab r3, [sp, 4] 125 PUSH r22
88 ld.ab r2, [sp, 4] 126 PUSH r23
89 ld.ab r1, [sp, 4] 127 PUSH r24
90 ld.ab r0, [sp, 4] 128.endm
129
130.macro RESTORE_R24_TO_R13
131 POP r24
132 POP r23
133 POP r22
134 POP r21
135 POP r20
136 POP r19
137 POP r18
138 POP r17
139 POP r16
140 POP r15
141 POP r14
142 POP r13
91.endm 143.endm
92 144
145#define OFF_USER_R25_FROM_R24 (SZ_CALLEE_REGS + SZ_PT_REGS - 8)/4
93 146
94/*-------------------------------------------------------------- 147/*--------------------------------------------------------------
95 * Save callee saved registers (non scratch registers) ( r13 - r25 ) 148 * Collect User Mode callee regs as struct callee_regs - needed by
96 * on kernel stack. 149 * fork/do_signal/unaligned-access-emulation.
97 * User mode callee regs need to be saved in case of 150 * (By default only scratch regs are saved on entry to kernel)
98 * -fork and friends for replicating from parent to child 151 *
99 * -before going into do_signal( ) for ptrace/core-dump 152 * Special handling for r25 if used for caching Task Pointer.
100 * Special case handling is required for r25 in case it is used by kernel 153 * It would have been saved in task->thread.user_r25 already, but to keep
101 * for caching task ptr. Low level exception/ISR save user mode r25 154 * the interface same it is copied into regular r25 placeholder in
102 * into task->thread.user_r25. So it needs to be retrieved from there and 155 * struct callee_regs.
103 * saved into kernel stack with rest of callee reg-file
104 *-------------------------------------------------------------*/ 156 *-------------------------------------------------------------*/
105.macro SAVE_CALLEE_SAVED_USER 157.macro SAVE_CALLEE_SAVED_USER
106 st.a r13, [sp, -4] 158
107 st.a r14, [sp, -4] 159 SAVE_R13_TO_R24
108 st.a r15, [sp, -4]
109 st.a r16, [sp, -4]
110 st.a r17, [sp, -4]
111 st.a r18, [sp, -4]
112 st.a r19, [sp, -4]
113 st.a r20, [sp, -4]
114 st.a r21, [sp, -4]
115 st.a r22, [sp, -4]
116 st.a r23, [sp, -4]
117 st.a r24, [sp, -4]
118 160
119#ifdef CONFIG_ARC_CURR_IN_REG 161#ifdef CONFIG_ARC_CURR_IN_REG
120 ; Retrieve orig r25 and save it on stack 162 ; Retrieve orig r25 and save it on stack
121 ld r12, [r25, TASK_THREAD + THREAD_USER_R25] 163 ld.as r12, [sp, OFF_USER_R25_FROM_R24]
122 st.a r12, [sp, -4] 164 st.a r12, [sp, -4]
123#else 165#else
124 st.a r25, [sp, -4] 166 PUSH r25
125#endif 167#endif
126 168
127 /* move up by 1 word to "create" callee_regs->"stack_place_holder" */
128 sub sp, sp, 4
129.endm 169.endm
130 170
131/*-------------------------------------------------------------- 171/*--------------------------------------------------------------
132 * Save callee saved registers (non scratch registers) ( r13 - r25 ) 172 * Save kernel Mode callee regs at the time of Contect Switch.
133 * kernel mode callee regs needed to be saved in case of context switch 173 *
134 * If r25 is used for caching task pointer then that need not be saved 174 * Special handling for r25 if used for caching Task Pointer.
135 * as it can be re-created from current task global 175 * Kernel simply skips saving it since it will be loaded with
176 * incoming task pointer anyways
136 *-------------------------------------------------------------*/ 177 *-------------------------------------------------------------*/
137.macro SAVE_CALLEE_SAVED_KERNEL 178.macro SAVE_CALLEE_SAVED_KERNEL
138 st.a r13, [sp, -4] 179
139 st.a r14, [sp, -4] 180 SAVE_R13_TO_R24
140 st.a r15, [sp, -4] 181
141 st.a r16, [sp, -4]
142 st.a r17, [sp, -4]
143 st.a r18, [sp, -4]
144 st.a r19, [sp, -4]
145 st.a r20, [sp, -4]
146 st.a r21, [sp, -4]
147 st.a r22, [sp, -4]
148 st.a r23, [sp, -4]
149 st.a r24, [sp, -4]
150#ifdef CONFIG_ARC_CURR_IN_REG 182#ifdef CONFIG_ARC_CURR_IN_REG
151 sub sp, sp, 8
152#else
153 st.a r25, [sp, -4]
154 sub sp, sp, 4 183 sub sp, sp, 4
184#else
185 PUSH r25
155#endif 186#endif
156.endm 187.endm
157 188
158/*-------------------------------------------------------------- 189/*--------------------------------------------------------------
159 * RESTORE_CALLEE_SAVED_KERNEL: 190 * Opposite of SAVE_CALLEE_SAVED_KERNEL
160 * Loads callee (non scratch) Reg File by popping from Kernel mode stack.
161 * This is reverse of SAVE_CALLEE_SAVED,
162 *
163 * NOTE:
164 * Ideally this shd only be called in switch_to for loading
165 * switched-IN task's CALLEE Reg File.
166 * For all other cases RESTORE_CALLEE_SAVED_FAST must be used
167 * which simply pops the stack w/o touching regs.
168 *-------------------------------------------------------------*/ 191 *-------------------------------------------------------------*/
169.macro RESTORE_CALLEE_SAVED_KERNEL 192.macro RESTORE_CALLEE_SAVED_KERNEL
170 193
171
172#ifdef CONFIG_ARC_CURR_IN_REG 194#ifdef CONFIG_ARC_CURR_IN_REG
173 add sp, sp, 8 /* skip callee_reg gutter and user r25 placeholder */ 195 add sp, sp, 4 /* skip usual r25 placeholder */
174#else 196#else
175 add sp, sp, 4 /* skip "callee_regs->stack_place_holder" */ 197 POP r25
176 ld.ab r25, [sp, 4]
177#endif 198#endif
178 199 RESTORE_R24_TO_R13
179 ld.ab r24, [sp, 4]
180 ld.ab r23, [sp, 4]
181 ld.ab r22, [sp, 4]
182 ld.ab r21, [sp, 4]
183 ld.ab r20, [sp, 4]
184 ld.ab r19, [sp, 4]
185 ld.ab r18, [sp, 4]
186 ld.ab r17, [sp, 4]
187 ld.ab r16, [sp, 4]
188 ld.ab r15, [sp, 4]
189 ld.ab r14, [sp, 4]
190 ld.ab r13, [sp, 4]
191
192.endm 200.endm
193 201
194/*-------------------------------------------------------------- 202/*--------------------------------------------------------------
195 * RESTORE_CALLEE_SAVED_USER: 203 * Opposite of SAVE_CALLEE_SAVED_USER
196 * This is called after do_signal where tracer might have changed callee regs 204 *
197 * thus we need to restore the reg file. 205 * ptrace tracer or unaligned-access fixup might have changed a user mode
198 * Special case handling is required for r25 in case it is used by kernel 206 * callee reg which is saved back to usual r25 storage location
199 * for caching task ptr. Ptrace would have modified on-kernel-stack value of
200 * r25, which needs to be shoved back into task->thread.user_r25 where from
201 * Low level exception/ISR return code will retrieve to populate with rest of
202 * callee reg-file.
203 *-------------------------------------------------------------*/ 207 *-------------------------------------------------------------*/
204.macro RESTORE_CALLEE_SAVED_USER 208.macro RESTORE_CALLEE_SAVED_USER
205 209
206 add sp, sp, 4 /* skip "callee_regs->stack_place_holder" */
207
208#ifdef CONFIG_ARC_CURR_IN_REG 210#ifdef CONFIG_ARC_CURR_IN_REG
209 ld.ab r12, [sp, 4] 211 ld.ab r12, [sp, 4]
210 st r12, [r25, TASK_THREAD + THREAD_USER_R25] 212 st.as r12, [sp, OFF_USER_R25_FROM_R24]
211#else 213#else
212 ld.ab r25, [sp, 4] 214 POP r25
213#endif 215#endif
214 216 RESTORE_R24_TO_R13
215 ld.ab r24, [sp, 4]
216 ld.ab r23, [sp, 4]
217 ld.ab r22, [sp, 4]
218 ld.ab r21, [sp, 4]
219 ld.ab r20, [sp, 4]
220 ld.ab r19, [sp, 4]
221 ld.ab r18, [sp, 4]
222 ld.ab r17, [sp, 4]
223 ld.ab r16, [sp, 4]
224 ld.ab r15, [sp, 4]
225 ld.ab r14, [sp, 4]
226 ld.ab r13, [sp, 4]
227.endm 217.endm
228 218
229/*-------------------------------------------------------------- 219/*--------------------------------------------------------------
230 * Super FAST Restore callee saved regs by simply re-adjusting SP 220 * Super FAST Restore callee saved regs by simply re-adjusting SP
231 *-------------------------------------------------------------*/ 221 *-------------------------------------------------------------*/
232.macro DISCARD_CALLEE_SAVED_USER 222.macro DISCARD_CALLEE_SAVED_USER
233 add sp, sp, 14 * 4 223 add sp, sp, SZ_CALLEE_REGS
234.endm
235
236/*--------------------------------------------------------------
237 * Restore User mode r25 saved in task_struct->thread.user_r25
238 *-------------------------------------------------------------*/
239.macro RESTORE_USER_R25
240 ld r25, [r25, TASK_THREAD + THREAD_USER_R25]
241.endm 224.endm
242 225
243/*------------------------------------------------------------- 226/*-------------------------------------------------------------
@@ -252,7 +235,7 @@
252 ld \out, [\tsk, TASK_THREAD_INFO] 235 ld \out, [\tsk, TASK_THREAD_INFO]
253 236
254 /* Go to end of page where stack begins (grows upwards) */ 237 /* Go to end of page where stack begins (grows upwards) */
255 add2 \out, \out, (THREAD_SIZE - 4)/4 /* one word GUTTER */ 238 add2 \out, \out, (THREAD_SIZE)/4
256 239
257.endm 240.endm
258 241
@@ -305,33 +288,28 @@
305 * safe-keeping not really needed, but it keeps the epilogue code 288 * safe-keeping not really needed, but it keeps the epilogue code
306 * (SP restore) simpler/uniform. 289 * (SP restore) simpler/uniform.
307 */ 290 */
308 b.d 77f 291 b.d 66f
309 292 mov r9, sp
310 st.a sp, [sp, -12] ; Make room for orig_r0 and orig_r8
311 293
31288: /*------Intr/Ecxp happened in user mode, "switch" stack ------ */ 29488: /*------Intr/Ecxp happened in user mode, "switch" stack ------ */
313 295
314 GET_CURR_TASK_ON_CPU r9 296 GET_CURR_TASK_ON_CPU r9
315 297
316#ifdef CONFIG_ARC_CURR_IN_REG
317
318 /* If current task pointer cached in r25, time to
319 * -safekeep USER r25 in task->thread_struct->user_r25
320 * -load r25 with current task ptr
321 */
322 st.as r25, [r9, (TASK_THREAD + THREAD_USER_R25)/4]
323 mov r25, r9
324#endif
325
326 /* With current tsk in r9, get it's kernel mode stack base */ 298 /* With current tsk in r9, get it's kernel mode stack base */
327 GET_TSK_STACK_BASE r9, r9 299 GET_TSK_STACK_BASE r9, r9
328 300
329#ifdef PT_REGS_CANARY 30166:
330 st 0xabcdabcd, [r9, 0] 302#ifdef CONFIG_ARC_CURR_IN_REG
303 /*
304 * Treat r25 as scratch reg, save it on stack first
305 * Load it with current task pointer
306 */
307 st r25, [r9, -4]
308 GET_CURR_TASK_ON_CPU r25
331#endif 309#endif
332 310
333 /* Save Pre Intr/Exception User SP on kernel stack */ 311 /* Save Pre Intr/Exception User SP on kernel stack */
334 st.a sp, [r9, -12] ; Make room for orig_r0 and orig_r8 312 st.a sp, [r9, -16] ; Make room for orig_r0, ECR, user_r25
335 313
336 /* CAUTION: 314 /* CAUTION:
337 * SP should be set at the very end when we are done with everything 315 * SP should be set at the very end when we are done with everything
@@ -342,7 +320,7 @@
342 /* set SP to point to kernel mode stack */ 320 /* set SP to point to kernel mode stack */
343 mov sp, r9 321 mov sp, r9
344 322
34577: /* ----- Stack Switched to kernel Mode, Now save REG FILE ----- */ 323 /* ----- Stack Switched to kernel Mode, Now save REG FILE ----- */
346 324
347.endm 325.endm
348 326
@@ -369,7 +347,7 @@
369 * @reg [OUT] &thread_info of "current" 347 * @reg [OUT] &thread_info of "current"
370 */ 348 */
371.macro GET_CURR_THR_INFO_FROM_SP reg 349.macro GET_CURR_THR_INFO_FROM_SP reg
372 and \reg, sp, ~(THREAD_SIZE - 1) 350 bic \reg, sp, (THREAD_SIZE - 1)
373.endm 351.endm
374 352
375/* 353/*
@@ -413,62 +391,25 @@
413 * Note that syscalls are implemented via TRAP which is also a exception 391 * Note that syscalls are implemented via TRAP which is also a exception
414 * from CPU's point of view 392 * from CPU's point of view
415 *-------------------------------------------------------------*/ 393 *-------------------------------------------------------------*/
416.macro SAVE_ALL_EXCEPTION marker 394.macro SAVE_ALL_SYS
417 395
418 st \marker, [sp, 8] /* orig_r8 */ 396 lr r9, [ecr]
397 st r9, [sp, 8] /* ECR */
419 st r0, [sp, 4] /* orig_r0, needed only for sys calls */ 398 st r0, [sp, 4] /* orig_r0, needed only for sys calls */
420 399
421 /* Restore r9 used to code the early prologue */ 400 /* Restore r9 used to code the early prologue */
422 EXCPN_PROLOG_RESTORE_REG r9 401 EXCPN_PROLOG_RESTORE_REG r9
423 402
424 SAVE_CALLER_SAVED 403 SAVE_R0_TO_R12
425 st.a r26, [sp, -4] /* gp */ 404 PUSH gp
426 st.a fp, [sp, -4] 405 PUSH fp
427 st.a blink, [sp, -4] 406 PUSH blink
428 lr r9, [eret] 407 PUSHAX eret
429 st.a r9, [sp, -4] 408 PUSHAX erstatus
430 lr r9, [erstatus] 409 PUSH lp_count
431 st.a r9, [sp, -4] 410 PUSHAX lp_end
432 st.a lp_count, [sp, -4] 411 PUSHAX lp_start
433 lr r9, [lp_end] 412 PUSHAX erbta
434 st.a r9, [sp, -4]
435 lr r9, [lp_start]
436 st.a r9, [sp, -4]
437 lr r9, [erbta]
438 st.a r9, [sp, -4]
439
440#ifdef PT_REGS_CANARY
441 mov r9, 0xdeadbeef
442 st r9, [sp, -4]
443#endif
444
445 /* move up by 1 word to "create" pt_regs->"stack_place_holder" */
446 sub sp, sp, 4
447.endm
448
449/*--------------------------------------------------------------
450 * Save scratch regs for exceptions
451 *-------------------------------------------------------------*/
452.macro SAVE_ALL_SYS
453 SAVE_ALL_EXCEPTION orig_r8_IS_EXCPN
454.endm
455
456/*--------------------------------------------------------------
457 * Save scratch regs for sys calls
458 *-------------------------------------------------------------*/
459.macro SAVE_ALL_TRAP
460 /*
461 * Setup pt_regs->orig_r8.
462 * Encode syscall number (r8) in upper short word of event type (r9)
463 * N.B. #1: This is already endian safe (see ptrace.h)
464 * #2: Only r9 can be used as scratch as it is already clobbered
465 * and it's contents are no longer needed by the latter part
466 * of exception prologue
467 */
468 lsl r9, r8, 16
469 or r9, r9, orig_r8_IS_SCALL
470
471 SAVE_ALL_EXCEPTION r9
472.endm 413.endm
473 414
474/*-------------------------------------------------------------- 415/*--------------------------------------------------------------
@@ -483,28 +424,22 @@
483 * by hardware and that is not good. 424 * by hardware and that is not good.
484 *-------------------------------------------------------------*/ 425 *-------------------------------------------------------------*/
485.macro RESTORE_ALL_SYS 426.macro RESTORE_ALL_SYS
427 POPAX erbta
428 POPAX lp_start
429 POPAX lp_end
430
431 POP r9
432 mov lp_count, r9 ;LD to lp_count is not allowed
486 433
487 add sp, sp, 4 /* hop over unused "pt_regs->stack_place_holder" */ 434 POPAX erstatus
488 435 POPAX eret
489 ld.ab r9, [sp, 4] 436 POP blink
490 sr r9, [erbta] 437 POP fp
491 ld.ab r9, [sp, 4] 438 POP gp
492 sr r9, [lp_start] 439 RESTORE_R12_TO_R0
493 ld.ab r9, [sp, 4]
494 sr r9, [lp_end]
495 ld.ab r9, [sp, 4]
496 mov lp_count, r9
497 ld.ab r9, [sp, 4]
498 sr r9, [erstatus]
499 ld.ab r9, [sp, 4]
500 sr r9, [eret]
501 ld.ab blink, [sp, 4]
502 ld.ab fp, [sp, 4]
503 ld.ab r26, [sp, 4] /* gp */
504 RESTORE_CALLER_SAVED
505 440
506 ld sp, [sp] /* restore original sp */ 441 ld sp, [sp] /* restore original sp */
507 /* orig_r0 and orig_r8 skipped automatically */ 442 /* orig_r0, ECR, user_r25 skipped automatically */
508.endm 443.endm
509 444
510 445
@@ -513,9 +448,7 @@
513 *-------------------------------------------------------------*/ 448 *-------------------------------------------------------------*/
514.macro SAVE_ALL_INT1 449.macro SAVE_ALL_INT1
515 450
516 /* restore original r9 , saved in int1_saved_reg 451 /* restore original r9 to be saved as part of reg-file */
517 * It will be saved on stack in macro: SAVE_CALLER_SAVED
518 */
519#ifdef CONFIG_SMP 452#ifdef CONFIG_SMP
520 lr r9, [ARC_REG_SCRATCH_DATA0] 453 lr r9, [ARC_REG_SCRATCH_DATA0]
521#else 454#else
@@ -523,29 +456,19 @@
523#endif 456#endif
524 457
525 /* now we are ready to save the remaining context :) */ 458 /* now we are ready to save the remaining context :) */
526 st orig_r8_IS_IRQ1, [sp, 8] /* Event Type */ 459 st event_IRQ1, [sp, 8] /* Dummy ECR */
527 st 0, [sp, 4] /* orig_r0 , N/A for IRQ */ 460 st 0, [sp, 4] /* orig_r0 , N/A for IRQ */
528 SAVE_CALLER_SAVED 461
529 st.a r26, [sp, -4] /* gp */ 462 SAVE_R0_TO_R12
530 st.a fp, [sp, -4] 463 PUSH gp
531 st.a blink, [sp, -4] 464 PUSH fp
532 st.a ilink1, [sp, -4] 465 PUSH blink
533 lr r9, [status32_l1] 466 PUSH ilink1
534 st.a r9, [sp, -4] 467 PUSHAX status32_l1
535 st.a lp_count, [sp, -4] 468 PUSH lp_count
536 lr r9, [lp_end] 469 PUSHAX lp_end
537 st.a r9, [sp, -4] 470 PUSHAX lp_start
538 lr r9, [lp_start] 471 PUSHAX bta_l1
539 st.a r9, [sp, -4]
540 lr r9, [bta_l1]
541 st.a r9, [sp, -4]
542
543#ifdef PT_REGS_CANARY
544 mov r9, 0xdeadbee1
545 st r9, [sp, -4]
546#endif
547 /* move up by 1 word to "create" pt_regs->"stack_place_holder" */
548 sub sp, sp, 4
549.endm 472.endm
550 473
551.macro SAVE_ALL_INT2 474.macro SAVE_ALL_INT2
@@ -558,30 +481,19 @@
558 ld r9, [@int2_saved_reg] 481 ld r9, [@int2_saved_reg]
559 482
560 /* now we are ready to save the remaining context :) */ 483 /* now we are ready to save the remaining context :) */
561 st orig_r8_IS_IRQ2, [sp, 8] /* Event Type */ 484 st event_IRQ2, [sp, 8] /* Dummy ECR */
562 st 0, [sp, 4] /* orig_r0 , N/A for IRQ */ 485 st 0, [sp, 4] /* orig_r0 , N/A for IRQ */
563 SAVE_CALLER_SAVED
564 st.a r26, [sp, -4] /* gp */
565 st.a fp, [sp, -4]
566 st.a blink, [sp, -4]
567 st.a ilink2, [sp, -4]
568 lr r9, [status32_l2]
569 st.a r9, [sp, -4]
570 st.a lp_count, [sp, -4]
571 lr r9, [lp_end]
572 st.a r9, [sp, -4]
573 lr r9, [lp_start]
574 st.a r9, [sp, -4]
575 lr r9, [bta_l2]
576 st.a r9, [sp, -4]
577
578#ifdef PT_REGS_CANARY
579 mov r9, 0xdeadbee2
580 st r9, [sp, -4]
581#endif
582 486
583 /* move up by 1 word to "create" pt_regs->"stack_place_holder" */ 487 SAVE_R0_TO_R12
584 sub sp, sp, 4 488 PUSH gp
489 PUSH fp
490 PUSH blink
491 PUSH ilink2
492 PUSHAX status32_l2
493 PUSH lp_count
494 PUSHAX lp_end
495 PUSHAX lp_start
496 PUSHAX bta_l2
585.endm 497.endm
586 498
587/*-------------------------------------------------------------- 499/*--------------------------------------------------------------
@@ -595,52 +507,41 @@
595 *-------------------------------------------------------------*/ 507 *-------------------------------------------------------------*/
596 508
597.macro RESTORE_ALL_INT1 509.macro RESTORE_ALL_INT1
598 add sp, sp, 4 /* hop over unused "pt_regs->stack_place_holder" */ 510 POPAX bta_l1
599 511 POPAX lp_start
600 ld.ab r9, [sp, 4] /* Actual reg file */ 512 POPAX lp_end
601 sr r9, [bta_l1] 513
602 ld.ab r9, [sp, 4] 514 POP r9
603 sr r9, [lp_start] 515 mov lp_count, r9 ;LD to lp_count is not allowed
604 ld.ab r9, [sp, 4] 516
605 sr r9, [lp_end] 517 POPAX status32_l1
606 ld.ab r9, [sp, 4] 518 POP ilink1
607 mov lp_count, r9 519 POP blink
608 ld.ab r9, [sp, 4] 520 POP fp
609 sr r9, [status32_l1] 521 POP gp
610 ld.ab r9, [sp, 4] 522 RESTORE_R12_TO_R0
611 mov ilink1, r9
612 ld.ab blink, [sp, 4]
613 ld.ab fp, [sp, 4]
614 ld.ab r26, [sp, 4] /* gp */
615 RESTORE_CALLER_SAVED
616 523
617 ld sp, [sp] /* restore original sp */ 524 ld sp, [sp] /* restore original sp */
618 /* orig_r0 and orig_r8 skipped automatically */ 525 /* orig_r0, ECR, user_r25 skipped automatically */
619.endm 526.endm
620 527
621.macro RESTORE_ALL_INT2 528.macro RESTORE_ALL_INT2
622 add sp, sp, 4 /* hop over unused "pt_regs->stack_place_holder" */ 529 POPAX bta_l2
623 530 POPAX lp_start
624 ld.ab r9, [sp, 4] 531 POPAX lp_end
625 sr r9, [bta_l2]
626 ld.ab r9, [sp, 4]
627 sr r9, [lp_start]
628 ld.ab r9, [sp, 4]
629 sr r9, [lp_end]
630 ld.ab r9, [sp, 4]
631 mov lp_count, r9
632 ld.ab r9, [sp, 4]
633 sr r9, [status32_l2]
634 ld.ab r9, [sp, 4]
635 mov ilink2, r9
636 ld.ab blink, [sp, 4]
637 ld.ab fp, [sp, 4]
638 ld.ab r26, [sp, 4] /* gp */
639 RESTORE_CALLER_SAVED
640 532
641 ld sp, [sp] /* restore original sp */ 533 POP r9
642 /* orig_r0 and orig_r8 skipped automatically */ 534 mov lp_count, r9 ;LD to lp_count is not allowed
643 535
536 POPAX status32_l2
537 POP ilink2
538 POP blink
539 POP fp
540 POP gp
541 RESTORE_R12_TO_R0
542
543 ld sp, [sp] /* restore original sp */
544 /* orig_r0, ECR, user_r25 skipped automatically */
644.endm 545.endm
645 546
646 547
diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h
index 57898a17eb82..c0a72105ee0b 100644
--- a/arch/arc/include/asm/irq.h
+++ b/arch/arc/include/asm/irq.h
@@ -21,6 +21,6 @@
21extern void __init arc_init_IRQ(void); 21extern void __init arc_init_IRQ(void);
22extern int __init get_hw_config_num_irq(void); 22extern int __init get_hw_config_num_irq(void);
23 23
24void __cpuinit arc_local_timer_setup(unsigned int cpu); 24void arc_local_timer_setup(unsigned int cpu);
25 25
26#endif 26#endif
diff --git a/arch/arc/include/asm/irqflags.h b/arch/arc/include/asm/irqflags.h
index eac071668201..d99f79bcf865 100644
--- a/arch/arc/include/asm/irqflags.h
+++ b/arch/arc/include/asm/irqflags.h
@@ -19,6 +19,26 @@
19 19
20#include <asm/arcregs.h> 20#include <asm/arcregs.h>
21 21
22/* status32 Reg bits related to Interrupt Handling */
23#define STATUS_E1_BIT 1 /* Int 1 enable */
24#define STATUS_E2_BIT 2 /* Int 2 enable */
25#define STATUS_A1_BIT 3 /* Int 1 active */
26#define STATUS_A2_BIT 4 /* Int 2 active */
27
28#define STATUS_E1_MASK (1<<STATUS_E1_BIT)
29#define STATUS_E2_MASK (1<<STATUS_E2_BIT)
30#define STATUS_A1_MASK (1<<STATUS_A1_BIT)
31#define STATUS_A2_MASK (1<<STATUS_A2_BIT)
32
33/* Other Interrupt Handling related Aux regs */
34#define AUX_IRQ_LEV 0x200 /* IRQ Priority: L1 or L2 */
35#define AUX_IRQ_HINT 0x201 /* For generating Soft Interrupts */
36#define AUX_IRQ_LV12 0x43 /* interrupt level register */
37
38#define AUX_IENABLE 0x40c
39#define AUX_ITRIGGER 0x40d
40#define AUX_IPULSE 0x415
41
22#ifndef __ASSEMBLY__ 42#ifndef __ASSEMBLY__
23 43
24/****************************************************************** 44/******************************************************************
diff --git a/arch/arc/include/asm/kgdb.h b/arch/arc/include/asm/kgdb.h
index 4930957ca3d3..b65fca7ffeb5 100644
--- a/arch/arc/include/asm/kgdb.h
+++ b/arch/arc/include/asm/kgdb.h
@@ -31,7 +31,7 @@ static inline void arch_kgdb_breakpoint(void)
31 __asm__ __volatile__ ("trap_s 0x4\n"); 31 __asm__ __volatile__ ("trap_s 0x4\n");
32} 32}
33 33
34extern void kgdb_trap(struct pt_regs *regs, int param); 34extern void kgdb_trap(struct pt_regs *regs);
35 35
36enum arc700_linux_regnums { 36enum arc700_linux_regnums {
37 _R0 = 0, 37 _R0 = 0,
@@ -53,7 +53,7 @@ enum arc700_linux_regnums {
53}; 53};
54 54
55#else 55#else
56#define kgdb_trap(regs, param) 56#define kgdb_trap(regs)
57#endif 57#endif
58 58
59#endif /* __ARC_KGDB_H__ */ 59#endif /* __ARC_KGDB_H__ */
diff --git a/arch/arc/include/asm/kprobes.h b/arch/arc/include/asm/kprobes.h
index 4d9c211fce70..944dbedb38b5 100644
--- a/arch/arc/include/asm/kprobes.h
+++ b/arch/arc/include/asm/kprobes.h
@@ -50,11 +50,9 @@ struct kprobe_ctlblk {
50 50
51int kprobe_fault_handler(struct pt_regs *regs, unsigned long cause); 51int kprobe_fault_handler(struct pt_regs *regs, unsigned long cause);
52void kretprobe_trampoline(void); 52void kretprobe_trampoline(void);
53void trap_is_kprobe(unsigned long cause, unsigned long address, 53void trap_is_kprobe(unsigned long address, struct pt_regs *regs);
54 struct pt_regs *regs);
55#else 54#else
56static void trap_is_kprobe(unsigned long cause, unsigned long address, 55static void trap_is_kprobe(unsigned long address, struct pt_regs *regs)
57 struct pt_regs *regs)
58{ 56{
59} 57}
60#endif 58#endif
diff --git a/arch/arc/include/asm/mmu.h b/arch/arc/include/asm/mmu.h
index 56b02320f1a9..7c03fe61759c 100644
--- a/arch/arc/include/asm/mmu.h
+++ b/arch/arc/include/asm/mmu.h
@@ -9,6 +9,40 @@
9#ifndef _ASM_ARC_MMU_H 9#ifndef _ASM_ARC_MMU_H
10#define _ASM_ARC_MMU_H 10#define _ASM_ARC_MMU_H
11 11
12#if defined(CONFIG_ARC_MMU_V1)
13#define CONFIG_ARC_MMU_VER 1
14#elif defined(CONFIG_ARC_MMU_V2)
15#define CONFIG_ARC_MMU_VER 2
16#elif defined(CONFIG_ARC_MMU_V3)
17#define CONFIG_ARC_MMU_VER 3
18#endif
19
20/* MMU Management regs */
21#define ARC_REG_MMU_BCR 0x06f
22#define ARC_REG_TLBPD0 0x405
23#define ARC_REG_TLBPD1 0x406
24#define ARC_REG_TLBINDEX 0x407
25#define ARC_REG_TLBCOMMAND 0x408
26#define ARC_REG_PID 0x409
27#define ARC_REG_SCRATCH_DATA0 0x418
28
29/* Bits in MMU PID register */
30#define MMU_ENABLE (1 << 31) /* Enable MMU for process */
31
32/* Error code if probe fails */
33#define TLB_LKUP_ERR 0x80000000
34
35/* TLB Commands */
36#define TLBWrite 0x1
37#define TLBRead 0x2
38#define TLBGetIndex 0x3
39#define TLBProbe 0x4
40
41#if (CONFIG_ARC_MMU_VER >= 2)
42#define TLBWriteNI 0x5 /* write JTLB without inv uTLBs */
43#define TLBIVUTLB 0x6 /* explicitly inv uTLBs */
44#endif
45
12#ifndef __ASSEMBLY__ 46#ifndef __ASSEMBLY__
13 47
14typedef struct { 48typedef struct {
@@ -18,6 +52,16 @@ typedef struct {
18#endif 52#endif
19} mm_context_t; 53} mm_context_t;
20 54
55#ifdef CONFIG_ARC_DBG_TLB_PARANOIA
56void tlb_paranoid_check(unsigned int pid_sw, unsigned long address);
57#else
58#define tlb_paranoid_check(a, b)
21#endif 59#endif
22 60
61void arc_mmu_init(void);
62extern char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len);
63void __init read_decode_mmu_bcr(void);
64
65#endif /* !__ASSEMBLY__ */
66
23#endif 67#endif
diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h
index ab84bf131fe1..9c8aa41e45c2 100644
--- a/arch/arc/include/asm/page.h
+++ b/arch/arc/include/asm/page.h
@@ -96,13 +96,8 @@ typedef unsigned long pgtable_t;
96 96
97#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) 97#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
98 98
99/* Default Permissions for page, used in mmap.c */ 99/* Default Permissions for stack/heaps pages (Non Executable) */
100#ifdef CONFIG_ARC_STACK_NONEXEC
101#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE) 100#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE)
102#else
103#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
104 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
105#endif
106 101
107#define WANT_PAGE_VIRTUAL 1 102#define WANT_PAGE_VIRTUAL 1
108 103
diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
index 95b1522212a7..4749a0eee1cf 100644
--- a/arch/arc/include/asm/pgtable.h
+++ b/arch/arc/include/asm/pgtable.h
@@ -135,6 +135,12 @@
135/* ioremap */ 135/* ioremap */
136#define PAGE_KERNEL_NO_CACHE __pgprot(_K_PAGE_PERMS) 136#define PAGE_KERNEL_NO_CACHE __pgprot(_K_PAGE_PERMS)
137 137
138/* Masks for actual TLB "PD"s */
139#define PTE_BITS_IN_PD0 (_PAGE_GLOBAL | _PAGE_PRESENT)
140#define PTE_BITS_IN_PD1 (PAGE_MASK | _PAGE_CACHEABLE | \
141 _PAGE_U_EXECUTE | _PAGE_U_WRITE | _PAGE_U_READ | \
142 _PAGE_K_EXECUTE | _PAGE_K_WRITE | _PAGE_K_READ)
143
138/************************************************************************** 144/**************************************************************************
139 * Mapping of vm_flags (Generic VM) to PTE flags (arch specific) 145 * Mapping of vm_flags (Generic VM) to PTE flags (arch specific)
140 * 146 *
@@ -394,9 +400,6 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
394 * remap a physical page `pfn' of size `size' with page protection `prot' 400 * remap a physical page `pfn' of size `size' with page protection `prot'
395 * into virtual address `from' 401 * into virtual address `from'
396 */ 402 */
397#define io_remap_pfn_range(vma, from, pfn, size, prot) \
398 remap_pfn_range(vma, from, pfn, size, prot)
399
400#include <asm-generic/pgtable.h> 403#include <asm-generic/pgtable.h>
401 404
402/* to cope with aliasing VIPT cache */ 405/* to cope with aliasing VIPT cache */
diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index 5f26b2c1cba0..15334ab66b56 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -19,6 +19,7 @@
19#ifndef __ASSEMBLY__ 19#ifndef __ASSEMBLY__
20 20
21#include <asm/arcregs.h> /* for STATUS_E1_MASK et all */ 21#include <asm/arcregs.h> /* for STATUS_E1_MASK et all */
22#include <asm/ptrace.h>
22 23
23/* Arch specific stuff which needs to be saved per task. 24/* Arch specific stuff which needs to be saved per task.
24 * However these items are not so important so as to earn a place in 25 * However these items are not so important so as to earn a place in
@@ -28,10 +29,6 @@ struct thread_struct {
28 unsigned long ksp; /* kernel mode stack pointer */ 29 unsigned long ksp; /* kernel mode stack pointer */
29 unsigned long callee_reg; /* pointer to callee regs */ 30 unsigned long callee_reg; /* pointer to callee regs */
30 unsigned long fault_address; /* dbls as brkpt holder as well */ 31 unsigned long fault_address; /* dbls as brkpt holder as well */
31 unsigned long cause_code; /* Exception Cause Code (ECR) */
32#ifdef CONFIG_ARC_CURR_IN_REG
33 unsigned long user_r25;
34#endif
35#ifdef CONFIG_ARC_FPU_SAVE_RESTORE 32#ifdef CONFIG_ARC_FPU_SAVE_RESTORE
36 struct arc_fpu fpu; 33 struct arc_fpu fpu;
37#endif 34#endif
@@ -50,7 +47,7 @@ struct task_struct;
50unsigned long thread_saved_pc(struct task_struct *t); 47unsigned long thread_saved_pc(struct task_struct *t);
51 48
52#define task_pt_regs(p) \ 49#define task_pt_regs(p) \
53 ((struct pt_regs *)(THREAD_SIZE - 4 + (void *)task_stack_page(p)) - 1) 50 ((struct pt_regs *)(THREAD_SIZE + (void *)task_stack_page(p)) - 1)
54 51
55/* Free all resources held by a thread. */ 52/* Free all resources held by a thread. */
56#define release_thread(thread) do { } while (0) 53#define release_thread(thread) do { } while (0)
@@ -75,11 +72,15 @@ unsigned long thread_saved_pc(struct task_struct *t);
75 72
76/* 73/*
77 * Where abouts of Task's sp, fp, blink when it was last seen in kernel mode. 74 * Where abouts of Task's sp, fp, blink when it was last seen in kernel mode.
78 * These can't be derived from pt_regs as that would give correp user-mode val 75 * Look in process.c for details of kernel stack layout
79 */ 76 */
80#define KSTK_ESP(tsk) (tsk->thread.ksp) 77#define KSTK_ESP(tsk) (tsk->thread.ksp)
81#define KSTK_BLINK(tsk) (*((unsigned int *)((KSTK_ESP(tsk)) + (13+1+1)*4))) 78
82#define KSTK_FP(tsk) (*((unsigned int *)((KSTK_ESP(tsk)) + (13+1)*4))) 79#define KSTK_REG(tsk, off) (*((unsigned int *)(KSTK_ESP(tsk) + \
80 sizeof(struct callee_regs) + off)))
81
82#define KSTK_BLINK(tsk) KSTK_REG(tsk, 4)
83#define KSTK_FP(tsk) KSTK_REG(tsk, 0)
83 84
84/* 85/*
85 * Do necessary setup to start up a newly executed thread. 86 * Do necessary setup to start up a newly executed thread.
diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h
index 6179de7e07c2..c9938e7a7dbd 100644
--- a/arch/arc/include/asm/ptrace.h
+++ b/arch/arc/include/asm/ptrace.h
@@ -17,12 +17,6 @@
17/* THE pt_regs: Defines how regs are saved during entry into kernel */ 17/* THE pt_regs: Defines how regs are saved during entry into kernel */
18 18
19struct pt_regs { 19struct pt_regs {
20 /*
21 * 1 word gutter after reg-file has been saved
22 * Technically not needed, Since SP always points to a "full" location
23 * (vs. "empty"). But pt_regs is shared with tools....
24 */
25 long res;
26 20
27 /* Real registers */ 21 /* Real registers */
28 long bta; /* bta_l1, bta_l2, erbta */ 22 long bta; /* bta_l1, bta_l2, erbta */
@@ -50,22 +44,32 @@ struct pt_regs {
50 long sp; /* user/kernel sp depending on where we came from */ 44 long sp; /* user/kernel sp depending on where we came from */
51 long orig_r0; 45 long orig_r0;
52 46
53 /*to distinguish bet excp, syscall, irq */ 47 /*
48 * To distinguish bet excp, syscall, irq
49 * For traps and exceptions, Exception Cause Register.
50 * ECR: <00> <VV> <CC> <PP>
51 * Last word used by Linux for extra state mgmt (syscall-restart)
52 * For interrupts, use artificial ECR values to note current prio-level
53 */
54 union { 54 union {
55 struct {
55#ifdef CONFIG_CPU_BIG_ENDIAN 56#ifdef CONFIG_CPU_BIG_ENDIAN
56 /* so that assembly code is same for LE/BE */ 57 unsigned long state:8, ecr_vec:8,
57 unsigned long orig_r8:16, event:16; 58 ecr_cause:8, ecr_param:8;
58#else 59#else
59 unsigned long event:16, orig_r8:16; 60 unsigned long ecr_param:8, ecr_cause:8,
61 ecr_vec:8, state:8;
60#endif 62#endif
61 long orig_r8_word; 63 };
64 unsigned long event;
62 }; 65 };
66
67 long user_r25;
63}; 68};
64 69
65/* Callee saved registers - need to be saved only when you are scheduled out */ 70/* Callee saved registers - need to be saved only when you are scheduled out */
66 71
67struct callee_regs { 72struct callee_regs {
68 long res; /* Again this is not needed */
69 long r25; 73 long r25;
70 long r24; 74 long r24;
71 long r23; 75 long r23;
@@ -99,18 +103,20 @@ struct callee_regs {
99/* return 1 if PC in delay slot */ 103/* return 1 if PC in delay slot */
100#define delay_mode(regs) ((regs->status32 & STATUS_DE_MASK) == STATUS_DE_MASK) 104#define delay_mode(regs) ((regs->status32 & STATUS_DE_MASK) == STATUS_DE_MASK)
101 105
102#define in_syscall(regs) (regs->event & orig_r8_IS_SCALL) 106#define in_syscall(regs) ((regs->ecr_vec == ECR_V_TRAP) && !regs->ecr_param)
103#define in_brkpt_trap(regs) (regs->event & orig_r8_IS_BRKPT) 107#define in_brkpt_trap(regs) ((regs->ecr_vec == ECR_V_TRAP) && regs->ecr_param)
108
109#define STATE_SCALL_RESTARTED 0x01
104 110
105#define syscall_wont_restart(regs) (regs->event |= orig_r8_IS_SCALL_RESTARTED) 111#define syscall_wont_restart(reg) (reg->state |= STATE_SCALL_RESTARTED)
106#define syscall_restartable(regs) !(regs->event & orig_r8_IS_SCALL_RESTARTED) 112#define syscall_restartable(reg) !(reg->state & STATE_SCALL_RESTARTED)
107 113
108#define current_pt_regs() \ 114#define current_pt_regs() \
109({ \ 115({ \
110 /* open-coded current_thread_info() */ \ 116 /* open-coded current_thread_info() */ \
111 register unsigned long sp asm ("sp"); \ 117 register unsigned long sp asm ("sp"); \
112 unsigned long pg_start = (sp & ~(THREAD_SIZE - 1)); \ 118 unsigned long pg_start = (sp & ~(THREAD_SIZE - 1)); \
113 (struct pt_regs *)(pg_start + THREAD_SIZE - 4) - 1; \ 119 (struct pt_regs *)(pg_start + THREAD_SIZE) - 1; \
114}) 120})
115 121
116static inline long regs_return_value(struct pt_regs *regs) 122static inline long regs_return_value(struct pt_regs *regs)
@@ -120,11 +126,4 @@ static inline long regs_return_value(struct pt_regs *regs)
120 126
121#endif /* !__ASSEMBLY__ */ 127#endif /* !__ASSEMBLY__ */
122 128
123#define orig_r8_IS_SCALL 0x0001
124#define orig_r8_IS_SCALL_RESTARTED 0x0002
125#define orig_r8_IS_BRKPT 0x0004
126#define orig_r8_IS_EXCPN 0x0008
127#define orig_r8_IS_IRQ1 0x0010
128#define orig_r8_IS_IRQ2 0x0020
129
130#endif /* __ASM_PTRACE_H */ 129#endif /* __ASM_PTRACE_H */
diff --git a/arch/arc/include/asm/syscall.h b/arch/arc/include/asm/syscall.h
index 33ab3048e9b2..29de09804306 100644
--- a/arch/arc/include/asm/syscall.h
+++ b/arch/arc/include/asm/syscall.h
@@ -18,7 +18,7 @@ static inline long
18syscall_get_nr(struct task_struct *task, struct pt_regs *regs) 18syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
19{ 19{
20 if (user_mode(regs) && in_syscall(regs)) 20 if (user_mode(regs) && in_syscall(regs))
21 return regs->orig_r8; 21 return regs->r8;
22 else 22 else
23 return -1; 23 return -1;
24} 24}
@@ -26,8 +26,7 @@ syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
26static inline void 26static inline void
27syscall_rollback(struct task_struct *task, struct pt_regs *regs) 27syscall_rollback(struct task_struct *task, struct pt_regs *regs)
28{ 28{
29 /* XXX: I can't fathom how pt_regs->r8 will be clobbered ? */ 29 regs->r0 = regs->orig_r0;
30 regs->r8 = regs->orig_r8;
31} 30}
32 31
33static inline long 32static inline long
diff --git a/arch/arc/include/asm/tlb-mmu1.h b/arch/arc/include/asm/tlb-mmu1.h
index a5ff961b1efc..8a1ec96012ae 100644
--- a/arch/arc/include/asm/tlb-mmu1.h
+++ b/arch/arc/include/asm/tlb-mmu1.h
@@ -9,9 +9,9 @@
9#ifndef __ASM_TLB_MMU_V1_H__ 9#ifndef __ASM_TLB_MMU_V1_H__
10#define __ASM_TLB_MMU_V1_H__ 10#define __ASM_TLB_MMU_V1_H__
11 11
12#if defined(__ASSEMBLY__) && defined(CONFIG_ARC_MMU_VER == 1) 12#include <asm/mmu.h>
13 13
14#include <asm/tlb.h> 14#if defined(__ASSEMBLY__) && (CONFIG_ARC_MMU_VER == 1)
15 15
16.macro TLB_WRITE_HEURISTICS 16.macro TLB_WRITE_HEURISTICS
17 17
diff --git a/arch/arc/include/asm/tlb.h b/arch/arc/include/asm/tlb.h
index cb0c708ca665..a9db5f62aaf3 100644
--- a/arch/arc/include/asm/tlb.h
+++ b/arch/arc/include/asm/tlb.h
@@ -9,18 +9,6 @@
9#ifndef _ASM_ARC_TLB_H 9#ifndef _ASM_ARC_TLB_H
10#define _ASM_ARC_TLB_H 10#define _ASM_ARC_TLB_H
11 11
12#ifdef __KERNEL__
13
14#include <asm/pgtable.h>
15
16/* Masks for actual TLB "PD"s */
17#define PTE_BITS_IN_PD0 (_PAGE_GLOBAL | _PAGE_PRESENT)
18#define PTE_BITS_IN_PD1 (PAGE_MASK | _PAGE_CACHEABLE | \
19 _PAGE_U_EXECUTE | _PAGE_U_WRITE | _PAGE_U_READ | \
20 _PAGE_K_EXECUTE | _PAGE_K_WRITE | _PAGE_K_READ)
21
22#ifndef __ASSEMBLY__
23
24#define tlb_flush(tlb) \ 12#define tlb_flush(tlb) \
25do { \ 13do { \
26 if (tlb->fullmm) \ 14 if (tlb->fullmm) \
@@ -56,18 +44,4 @@ do { \
56#include <linux/pagemap.h> 44#include <linux/pagemap.h>
57#include <asm-generic/tlb.h> 45#include <asm-generic/tlb.h>
58 46
59#ifdef CONFIG_ARC_DBG_TLB_PARANOIA
60void tlb_paranoid_check(unsigned int pid_sw, unsigned long address);
61#else
62#define tlb_paranoid_check(a, b)
63#endif
64
65void arc_mmu_init(void);
66extern char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len);
67void __init read_decode_mmu_bcr(void);
68
69#endif /* __ASSEMBLY__ */
70
71#endif /* __KERNEL__ */
72
73#endif /* _ASM_ARC_TLB_H */ 47#endif /* _ASM_ARC_TLB_H */
diff --git a/arch/arc/include/asm/unaligned.h b/arch/arc/include/asm/unaligned.h
index 5dbe63f17b66..60702f3751d2 100644
--- a/arch/arc/include/asm/unaligned.h
+++ b/arch/arc/include/asm/unaligned.h
@@ -16,11 +16,11 @@
16 16
17#ifdef CONFIG_ARC_MISALIGN_ACCESS 17#ifdef CONFIG_ARC_MISALIGN_ACCESS
18int misaligned_fixup(unsigned long address, struct pt_regs *regs, 18int misaligned_fixup(unsigned long address, struct pt_regs *regs,
19 unsigned long cause, struct callee_regs *cregs); 19 struct callee_regs *cregs);
20#else 20#else
21static inline int 21static inline int
22misaligned_fixup(unsigned long address, struct pt_regs *regs, 22misaligned_fixup(unsigned long address, struct pt_regs *regs,
23 unsigned long cause, struct callee_regs *cregs) 23 struct callee_regs *cregs)
24{ 24{
25 return 0; 25 return 0;
26} 26}
diff --git a/arch/arc/include/uapi/asm/ptrace.h b/arch/arc/include/uapi/asm/ptrace.h
index 30333cec0fef..2618cc13ba75 100644
--- a/arch/arc/include/uapi/asm/ptrace.h
+++ b/arch/arc/include/uapi/asm/ptrace.h
@@ -20,28 +20,31 @@
20 * 20 *
21 * This is to decouple pt_regs from user-space ABI, to be able to change it 21 * This is to decouple pt_regs from user-space ABI, to be able to change it
22 * w/o affecting the ABI. 22 * w/o affecting the ABI.
23 * Although the layout (initial padding) is similar to pt_regs to have some 23 *
24 * optimizations when copying pt_regs to/from user_regs_struct. 24 * The intermediate pad,pad2 are relics of initial layout based on pt_regs
25 * for optimizations when copying pt_regs to/from user_regs_struct.
26 * We no longer need them, but can't be changed as they are part of ABI now.
25 * 27 *
26 * Also, sigcontext only care about the scratch regs as that is what we really 28 * Also, sigcontext only care about the scratch regs as that is what we really
27 * save/restore for signal handling. 29 * save/restore for signal handling. However gdb also uses the same struct
30 * hence callee regs need to be in there too.
28*/ 31*/
29struct user_regs_struct { 32struct user_regs_struct {
30 33
34 long pad;
31 struct { 35 struct {
32 long pad;
33 long bta, lp_start, lp_end, lp_count; 36 long bta, lp_start, lp_end, lp_count;
34 long status32, ret, blink, fp, gp; 37 long status32, ret, blink, fp, gp;
35 long r12, r11, r10, r9, r8, r7, r6, r5, r4, r3, r2, r1, r0; 38 long r12, r11, r10, r9, r8, r7, r6, r5, r4, r3, r2, r1, r0;
36 long sp; 39 long sp;
37 } scratch; 40 } scratch;
41 long pad2;
38 struct { 42 struct {
39 long pad;
40 long r25, r24, r23, r22, r21, r20; 43 long r25, r24, r23, r22, r21, r20;
41 long r19, r18, r17, r16, r15, r14, r13; 44 long r19, r18, r17, r16, r15, r14, r13;
42 } callee; 45 } callee;
43 long efa; /* break pt addr, for break points in delay slots */ 46 long efa; /* break pt addr, for break points in delay slots */
44 long stop_pc; /* give dbg stop_pc directly after checking orig_r8 */ 47 long stop_pc; /* give dbg stop_pc after ensuring brkpt trap */
45}; 48};
46#endif /* !__ASSEMBLY__ */ 49#endif /* !__ASSEMBLY__ */
47 50
diff --git a/arch/arc/kernel/asm-offsets.c b/arch/arc/kernel/asm-offsets.c
index 7dcda7025241..6c3aa0edb9b5 100644
--- a/arch/arc/kernel/asm-offsets.c
+++ b/arch/arc/kernel/asm-offsets.c
@@ -24,9 +24,6 @@ int main(void)
24 24
25 DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); 25 DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
26 DEFINE(THREAD_CALLEE_REG, offsetof(struct thread_struct, callee_reg)); 26 DEFINE(THREAD_CALLEE_REG, offsetof(struct thread_struct, callee_reg));
27#ifdef CONFIG_ARC_CURR_IN_REG
28 DEFINE(THREAD_USER_R25, offsetof(struct thread_struct, user_r25));
29#endif
30 DEFINE(THREAD_FAULT_ADDR, 27 DEFINE(THREAD_FAULT_ADDR,
31 offsetof(struct thread_struct, fault_address)); 28 offsetof(struct thread_struct, fault_address));
32 29
@@ -49,7 +46,7 @@ int main(void)
49 BLANK(); 46 BLANK();
50 47
51 DEFINE(PT_status32, offsetof(struct pt_regs, status32)); 48 DEFINE(PT_status32, offsetof(struct pt_regs, status32));
52 DEFINE(PT_orig_r8, offsetof(struct pt_regs, orig_r8_word)); 49 DEFINE(PT_event, offsetof(struct pt_regs, event));
53 DEFINE(PT_sp, offsetof(struct pt_regs, sp)); 50 DEFINE(PT_sp, offsetof(struct pt_regs, sp));
54 DEFINE(PT_r0, offsetof(struct pt_regs, r0)); 51 DEFINE(PT_r0, offsetof(struct pt_regs, r0));
55 DEFINE(PT_r1, offsetof(struct pt_regs, r1)); 52 DEFINE(PT_r1, offsetof(struct pt_regs, r1));
@@ -60,5 +57,7 @@ int main(void)
60 DEFINE(PT_r6, offsetof(struct pt_regs, r6)); 57 DEFINE(PT_r6, offsetof(struct pt_regs, r6));
61 DEFINE(PT_r7, offsetof(struct pt_regs, r7)); 58 DEFINE(PT_r7, offsetof(struct pt_regs, r7));
62 59
60 DEFINE(SZ_CALLEE_REGS, sizeof(struct callee_regs));
61 DEFINE(SZ_PT_REGS, sizeof(struct pt_regs));
63 return 0; 62 return 0;
64} 63}
diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c
index 60844dac6132..34410eb1a308 100644
--- a/arch/arc/kernel/ctx_sw.c
+++ b/arch/arc/kernel/ctx_sw.c
@@ -23,10 +23,6 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
23 unsigned int tmp; 23 unsigned int tmp;
24 unsigned int prev = (unsigned int)prev_task; 24 unsigned int prev = (unsigned int)prev_task;
25 unsigned int next = (unsigned int)next_task; 25 unsigned int next = (unsigned int)next_task;
26 int num_words_to_skip = 1;
27#ifdef CONFIG_ARC_CURR_IN_REG
28 num_words_to_skip++;
29#endif
30 26
31 __asm__ __volatile__( 27 __asm__ __volatile__(
32 /* FP/BLINK save generated by gcc (standard function prologue */ 28 /* FP/BLINK save generated by gcc (standard function prologue */
@@ -44,8 +40,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
44 "st.a r24, [sp, -4] \n\t" 40 "st.a r24, [sp, -4] \n\t"
45#ifndef CONFIG_ARC_CURR_IN_REG 41#ifndef CONFIG_ARC_CURR_IN_REG
46 "st.a r25, [sp, -4] \n\t" 42 "st.a r25, [sp, -4] \n\t"
43#else
44 "sub sp, sp, 4 \n\t" /* usual r25 placeholder */
47#endif 45#endif
48 "sub sp, sp, %4 \n\t" /* create gutter at top */
49 46
50 /* set ksp of outgoing task in tsk->thread.ksp */ 47 /* set ksp of outgoing task in tsk->thread.ksp */
51 "st.as sp, [%3, %1] \n\t" 48 "st.as sp, [%3, %1] \n\t"
@@ -76,10 +73,10 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
76 73
77 /* start loading it's CALLEE reg file */ 74 /* start loading it's CALLEE reg file */
78 75
79 "add sp, sp, %4 \n\t" /* skip gutter at top */
80
81#ifndef CONFIG_ARC_CURR_IN_REG 76#ifndef CONFIG_ARC_CURR_IN_REG
82 "ld.ab r25, [sp, 4] \n\t" 77 "ld.ab r25, [sp, 4] \n\t"
78#else
79 "add sp, sp, 4 \n\t"
83#endif 80#endif
84 "ld.ab r24, [sp, 4] \n\t" 81 "ld.ab r24, [sp, 4] \n\t"
85 "ld.ab r23, [sp, 4] \n\t" 82 "ld.ab r23, [sp, 4] \n\t"
@@ -100,8 +97,7 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
100 /* FP/BLINK restore generated by gcc (standard func epilogue */ 97 /* FP/BLINK restore generated by gcc (standard func epilogue */
101 98
102 : "=r"(tmp) 99 : "=r"(tmp)
103 : "n"((TASK_THREAD + THREAD_KSP) / 4), "r"(next), "r"(prev), 100 : "n"((TASK_THREAD + THREAD_KSP) / 4), "r"(next), "r"(prev)
104 "n"(num_words_to_skip * 4)
105 : "blink" 101 : "blink"
106 ); 102 );
107 103
diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S
index 0c6d664d4a83..1d7165156e17 100644
--- a/arch/arc/kernel/entry.S
+++ b/arch/arc/kernel/entry.S
@@ -142,7 +142,7 @@ VECTOR reserved ; Reserved Exceptions
142.endr 142.endr
143 143
144#include <linux/linkage.h> /* ARC_{EXTRY,EXIT} */ 144#include <linux/linkage.h> /* ARC_{EXTRY,EXIT} */
145#include <asm/entry.h> /* SAVE_ALL_{INT1,INT2,TRAP...} */ 145#include <asm/entry.h> /* SAVE_ALL_{INT1,INT2,SYS...} */
146#include <asm/errno.h> 146#include <asm/errno.h>
147#include <asm/arcregs.h> 147#include <asm/arcregs.h>
148#include <asm/irqflags.h> 148#include <asm/irqflags.h>
@@ -274,10 +274,8 @@ ARC_ENTRY instr_service
274 SWITCH_TO_KERNEL_STK 274 SWITCH_TO_KERNEL_STK
275 SAVE_ALL_SYS 275 SAVE_ALL_SYS
276 276
277 lr r0, [ecr] 277 lr r0, [efa]
278 lr r1, [efa] 278 mov r1, sp
279
280 mov r2, sp
281 279
282 FAKE_RET_FROM_EXCPN r9 280 FAKE_RET_FROM_EXCPN r9
283 281
@@ -298,9 +296,8 @@ ARC_ENTRY mem_service
298 SWITCH_TO_KERNEL_STK 296 SWITCH_TO_KERNEL_STK
299 SAVE_ALL_SYS 297 SAVE_ALL_SYS
300 298
301 lr r0, [ecr] 299 lr r0, [efa]
302 lr r1, [efa] 300 mov r1, sp
303 mov r2, sp
304 bl do_memory_error 301 bl do_memory_error
305 b ret_from_exception 302 b ret_from_exception
306ARC_EXIT mem_service 303ARC_EXIT mem_service
@@ -317,11 +314,14 @@ ARC_ENTRY EV_MachineCheck
317 SWITCH_TO_KERNEL_STK 314 SWITCH_TO_KERNEL_STK
318 SAVE_ALL_SYS 315 SAVE_ALL_SYS
319 316
320 lr r0, [ecr] 317 lr r2, [ecr]
321 lr r1, [efa] 318 lr r0, [efa]
322 mov r2, sp 319 mov r1, sp
320
321 lsr r3, r2, 8
322 bmsk r3, r3, 7
323 brne r3, ECR_C_MCHK_DUP_TLB, 1f
323 324
324 brne r0, 0x200100, 1f
325 bl do_tlb_overlap_fault 325 bl do_tlb_overlap_fault
326 b ret_from_exception 326 b ret_from_exception
327 327
@@ -355,8 +355,8 @@ ARC_ENTRY EV_TLBProtV
355 ; ecr and efa were not saved in case an Intr sneaks in 355 ; ecr and efa were not saved in case an Intr sneaks in
356 ; after fake rtie 356 ; after fake rtie
357 ; 357 ;
358 lr r3, [ecr] 358 lr r2, [ecr]
359 lr r4, [efa] 359 lr r1, [efa] ; Faulting Data address
360 360
361 ; --------(4) Return from CPU Exception Mode --------- 361 ; --------(4) Return from CPU Exception Mode ---------
362 ; Fake a rtie, but rtie to next label 362 ; Fake a rtie, but rtie to next label
@@ -368,31 +368,25 @@ ARC_ENTRY EV_TLBProtV
368 ;------ (5) Type of Protection Violation? ---------- 368 ;------ (5) Type of Protection Violation? ----------
369 ; 369 ;
370 ; ProtV Hardware Exception is triggered for Access Faults of 2 types 370 ; ProtV Hardware Exception is triggered for Access Faults of 2 types
371 ; -Access Violaton (WRITE to READ ONLY Page) - for linux COW 371 ; -Access Violaton : 00_23_(00|01|02|03)_00
372 ; -Unaligned Access (READ/WRITE on odd boundary) 372 ; x r w r+w
373 ; -Unaligned Access : 00_23_04_00
373 ; 374 ;
374 cmp r3, 0x230400 ; Misaligned data access ? 375 bbit1 r2, ECR_C_BIT_PROTV_MISALIG_DATA, 4f
375 beq 4f
376 376
377 ;========= (6a) Access Violation Processing ======== 377 ;========= (6a) Access Violation Processing ========
378 cmp r3, 0x230100
379 mov r1, 0x0 ; if LD exception ? write = 0
380 mov.ne r1, 0x1 ; else write = 1
381
382 mov r2, r4 ; faulting address
383 mov r0, sp ; pt_regs 378 mov r0, sp ; pt_regs
384 bl do_page_fault 379 bl do_page_fault
385 b ret_from_exception 380 b ret_from_exception
386 381
387 ;========== (6b) Non aligned access ============ 382 ;========== (6b) Non aligned access ============
3884: 3834:
389 mov r0, r3 ; cause code 384 mov r0, r1
390 mov r1, r4 ; faulting address 385 mov r1, sp ; pt_regs
391 mov r2, sp ; pt_regs
392 386
393#ifdef CONFIG_ARC_MISALIGN_ACCESS 387#ifdef CONFIG_ARC_MISALIGN_ACCESS
394 SAVE_CALLEE_SAVED_USER 388 SAVE_CALLEE_SAVED_USER
395 mov r3, sp ; callee_regs 389 mov r2, sp ; callee_regs
396 390
397 bl do_misaligned_access 391 bl do_misaligned_access
398 392
@@ -419,9 +413,8 @@ ARC_ENTRY EV_PrivilegeV
419 SWITCH_TO_KERNEL_STK 413 SWITCH_TO_KERNEL_STK
420 SAVE_ALL_SYS 414 SAVE_ALL_SYS
421 415
422 lr r0, [ecr] 416 lr r0, [efa]
423 lr r1, [efa] 417 mov r1, sp
424 mov r2, sp
425 418
426 FAKE_RET_FROM_EXCPN r9 419 FAKE_RET_FROM_EXCPN r9
427 420
@@ -440,9 +433,8 @@ ARC_ENTRY EV_Extension
440 SWITCH_TO_KERNEL_STK 433 SWITCH_TO_KERNEL_STK
441 SAVE_ALL_SYS 434 SAVE_ALL_SYS
442 435
443 lr r0, [ecr] 436 lr r0, [efa]
444 lr r1, [efa] 437 mov r1, sp
445 mov r2, sp
446 bl do_extension_fault 438 bl do_extension_fault
447 b ret_from_exception 439 b ret_from_exception
448ARC_EXIT EV_Extension 440ARC_EXIT EV_Extension
@@ -498,11 +490,8 @@ tracesys_exit:
498trap_with_param: 490trap_with_param:
499 491
500 ; stop_pc info by gdb needs this info 492 ; stop_pc info by gdb needs this info
501 stw orig_r8_IS_BRKPT, [sp, PT_orig_r8] 493 lr r0, [efa]
502 494 mov r1, sp
503 mov r0, r12
504 lr r1, [efa]
505 mov r2, sp
506 495
507 ; Now that we have read EFA, its safe to do "fake" rtie 496 ; Now that we have read EFA, its safe to do "fake" rtie
508 ; and get out of CPU exception mode 497 ; and get out of CPU exception mode
@@ -544,11 +533,11 @@ ARC_ENTRY EV_Trap
544 lr r9, [erstatus] 533 lr r9, [erstatus]
545 534
546 SWITCH_TO_KERNEL_STK 535 SWITCH_TO_KERNEL_STK
547 SAVE_ALL_TRAP 536 SAVE_ALL_SYS
548 537
549 ;------- (4) What caused the Trap -------------- 538 ;------- (4) What caused the Trap --------------
550 lr r12, [ecr] 539 lr r12, [ecr]
551 and.f 0, r12, ECR_PARAM_MASK 540 bmsk.f 0, r12, 7
552 bnz trap_with_param 541 bnz trap_with_param
553 542
554 ; ======= (5a) Trap is due to System Call ======== 543 ; ======= (5a) Trap is due to System Call ========
@@ -589,11 +578,7 @@ ARC_ENTRY ret_from_exception
589 ; Pre-{IRQ,Trap,Exception} K/U mode from pt_regs->status32 578 ; Pre-{IRQ,Trap,Exception} K/U mode from pt_regs->status32
590 ld r8, [sp, PT_status32] ; returning to User/Kernel Mode 579 ld r8, [sp, PT_status32] ; returning to User/Kernel Mode
591 580
592#ifdef CONFIG_PREEMPT
593 bbit0 r8, STATUS_U_BIT, resume_kernel_mode 581 bbit0 r8, STATUS_U_BIT, resume_kernel_mode
594#else
595 bbit0 r8, STATUS_U_BIT, restore_regs
596#endif
597 582
598 ; Before returning to User mode check-for-and-complete any pending work 583 ; Before returning to User mode check-for-and-complete any pending work
599 ; such as rescheduling/signal-delivery etc. 584 ; such as rescheduling/signal-delivery etc.
@@ -653,10 +638,10 @@ resume_user_mode_begin:
653 b resume_user_mode_begin ; unconditionally back to U mode ret chks 638 b resume_user_mode_begin ; unconditionally back to U mode ret chks
654 ; for single exit point from this block 639 ; for single exit point from this block
655 640
656#ifdef CONFIG_PREEMPT
657
658resume_kernel_mode: 641resume_kernel_mode:
659 642
643#ifdef CONFIG_PREEMPT
644
660 ; Can't preempt if preemption disabled 645 ; Can't preempt if preemption disabled
661 GET_CURR_THR_INFO_FROM_SP r10 646 GET_CURR_THR_INFO_FROM_SP r10
662 ld r8, [r10, THREAD_INFO_PREEMPT_COUNT] 647 ld r8, [r10, THREAD_INFO_PREEMPT_COUNT]
@@ -687,17 +672,6 @@ restore_regs :
687 ; XXX can this be optimised out 672 ; XXX can this be optimised out
688 IRQ_DISABLE_SAVE r9, r10 ;@r10 has prisitine (pre-disable) copy 673 IRQ_DISABLE_SAVE r9, r10 ;@r10 has prisitine (pre-disable) copy
689 674
690#ifdef CONFIG_ARC_CURR_IN_REG
691 ; Restore User R25
692 ; Earlier this used to be only for returning to user mode
693 ; However with 2 levels of IRQ this can also happen even if
694 ; in kernel mode
695 ld r9, [sp, PT_sp]
696 brhs r9, VMALLOC_START, 8f
697 RESTORE_USER_R25
6988:
699#endif
700
701 ; Restore REG File. In case multiple Events outstanding, 675 ; Restore REG File. In case multiple Events outstanding,
702 ; use the same priorty as rtie: EXCPN, L2 IRQ, L1 IRQ, None 676 ; use the same priorty as rtie: EXCPN, L2 IRQ, L1 IRQ, None
703 ; Note that we use realtime STATUS32 (not pt_regs->status32) to 677 ; Note that we use realtime STATUS32 (not pt_regs->status32) to
@@ -714,28 +688,33 @@ not_exception:
714 688
715#ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS 689#ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS
716 690
691 ; Level 2 interrupt return Path - from hardware standpoint
717 bbit0 r10, STATUS_A2_BIT, not_level2_interrupt 692 bbit0 r10, STATUS_A2_BIT, not_level2_interrupt
718 693
719 ;------------------------------------------------------------------ 694 ;------------------------------------------------------------------
695 ; However the context returning might not have taken L2 intr itself
696 ; e.g. Task'A' user-code -> L2 intr -> schedule -> 'B' user-code ret
697 ; Special considerations needed for the context which took L2 intr
698
699 ld r9, [sp, PT_event] ; Ensure this is L2 intr context
700 brne r9, event_IRQ2, 149f
701
702 ;------------------------------------------------------------------
720 ; if L2 IRQ interrupted a L1 ISR, we'd disbaled preemption earlier 703 ; if L2 IRQ interrupted a L1 ISR, we'd disbaled preemption earlier
721 ; so that sched doesnt move to new task, causing L1 to be delayed 704 ; so that sched doesnt move to new task, causing L1 to be delayed
722 ; undeterministically. Now that we've achieved that, lets reset 705 ; undeterministically. Now that we've achieved that, lets reset
723 ; things to what they were, before returning from L2 context 706 ; things to what they were, before returning from L2 context
724 ;---------------------------------------------------------------- 707 ;----------------------------------------------------------------
725 708
726 ldw r9, [sp, PT_orig_r8] ; get orig_r8 to make sure it is
727 brne r9, orig_r8_IS_IRQ2, 149f ; infact a L2 ISR ret path
728
729 ld r9, [sp, PT_status32] ; get statu32_l2 (saved in pt_regs) 709 ld r9, [sp, PT_status32] ; get statu32_l2 (saved in pt_regs)
730 bbit0 r9, STATUS_A1_BIT, 149f ; L1 not active when L2 IRQ, so normal 710 bbit0 r9, STATUS_A1_BIT, 149f ; L1 not active when L2 IRQ, so normal
731 711
732 ; A1 is set in status32_l2
733 ; decrement thread_info->preempt_count (re-enable preemption) 712 ; decrement thread_info->preempt_count (re-enable preemption)
734 GET_CURR_THR_INFO_FROM_SP r10 713 GET_CURR_THR_INFO_FROM_SP r10
735 ld r9, [r10, THREAD_INFO_PREEMPT_COUNT] 714 ld r9, [r10, THREAD_INFO_PREEMPT_COUNT]
736 715
737 ; paranoid check, given A1 was active when A2 happened, preempt count 716 ; paranoid check, given A1 was active when A2 happened, preempt count
738 ; must not be 0 beccause we would have incremented it. 717 ; must not be 0 because we would have incremented it.
739 ; If this does happen we simply HALT as it means a BUG !!! 718 ; If this does happen we simply HALT as it means a BUG !!!
740 cmp r9, 0 719 cmp r9, 0
741 bnz 2f 720 bnz 2f
diff --git a/arch/arc/kernel/head.S b/arch/arc/kernel/head.S
index 006dec3fc353..2a913f85a747 100644
--- a/arch/arc/kernel/head.S
+++ b/arch/arc/kernel/head.S
@@ -27,6 +27,8 @@ stext:
27 ; Don't clobber r0-r4 yet. It might have bootloader provided info 27 ; Don't clobber r0-r4 yet. It might have bootloader provided info
28 ;------------------------------------------------------------------- 28 ;-------------------------------------------------------------------
29 29
30 sr @_int_vec_base_lds, [AUX_INTR_VEC_BASE]
31
30#ifdef CONFIG_SMP 32#ifdef CONFIG_SMP
31 ; Only Boot (Master) proceeds. Others wait in platform dependent way 33 ; Only Boot (Master) proceeds. Others wait in platform dependent way
32 ; IDENTITY Reg [ 3 2 1 0 ] 34 ; IDENTITY Reg [ 3 2 1 0 ]
diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c
index 8115fa531575..305b3f866aa7 100644
--- a/arch/arc/kernel/irq.c
+++ b/arch/arc/kernel/irq.c
@@ -28,25 +28,17 @@
28 * -Disable all IRQs (on CPU side) 28 * -Disable all IRQs (on CPU side)
29 * -Optionally, setup the High priority Interrupts as Level 2 IRQs 29 * -Optionally, setup the High priority Interrupts as Level 2 IRQs
30 */ 30 */
31void __cpuinit arc_init_IRQ(void) 31void arc_init_IRQ(void)
32{ 32{
33 int level_mask = 0; 33 int level_mask = 0;
34 34
35 write_aux_reg(AUX_INTR_VEC_BASE, _int_vec_base_lds);
36
37 /* Disable all IRQs: enable them as devices request */ 35 /* Disable all IRQs: enable them as devices request */
38 write_aux_reg(AUX_IENABLE, 0); 36 write_aux_reg(AUX_IENABLE, 0);
39 37
40 /* setup any high priority Interrupts (Level2 in ARCompact jargon) */ 38 /* setup any high priority Interrupts (Level2 in ARCompact jargon) */
41#ifdef CONFIG_ARC_IRQ3_LV2 39 level_mask |= IS_ENABLED(CONFIG_ARC_IRQ3_LV2) << 3;
42 level_mask |= (1 << 3); 40 level_mask |= IS_ENABLED(CONFIG_ARC_IRQ5_LV2) << 5;
43#endif 41 level_mask |= IS_ENABLED(CONFIG_ARC_IRQ6_LV2) << 6;
44#ifdef CONFIG_ARC_IRQ5_LV2
45 level_mask |= (1 << 5);
46#endif
47#ifdef CONFIG_ARC_IRQ6_LV2
48 level_mask |= (1 << 6);
49#endif
50 42
51 if (level_mask) { 43 if (level_mask) {
52 pr_info("Level-2 interrupts bitset %x\n", level_mask); 44 pr_info("Level-2 interrupts bitset %x\n", level_mask);
diff --git a/arch/arc/kernel/kgdb.c b/arch/arc/kernel/kgdb.c
index 52bdc83c1495..a7698fb14818 100644
--- a/arch/arc/kernel/kgdb.c
+++ b/arch/arc/kernel/kgdb.c
@@ -169,7 +169,7 @@ int kgdb_arch_init(void)
169 return 0; 169 return 0;
170} 170}
171 171
172void kgdb_trap(struct pt_regs *regs, int param) 172void kgdb_trap(struct pt_regs *regs)
173{ 173{
174 /* trap_s 3 is used for breakpoints that overwrite existing 174 /* trap_s 3 is used for breakpoints that overwrite existing
175 * instructions, while trap_s 4 is used for compiled breakpoints. 175 * instructions, while trap_s 4 is used for compiled breakpoints.
@@ -181,7 +181,7 @@ void kgdb_trap(struct pt_regs *regs, int param)
181 * with trap_s 4 (compiled) breakpoints, continuation needs to 181 * with trap_s 4 (compiled) breakpoints, continuation needs to
182 * start after the breakpoint. 182 * start after the breakpoint.
183 */ 183 */
184 if (param == 3) 184 if (regs->ecr_param == 3)
185 instruction_pointer(regs) -= BREAK_INSTR_SIZE; 185 instruction_pointer(regs) -= BREAK_INSTR_SIZE;
186 186
187 kgdb_handle_exception(1, SIGTRAP, 0, regs); 187 kgdb_handle_exception(1, SIGTRAP, 0, regs);
diff --git a/arch/arc/kernel/kprobes.c b/arch/arc/kernel/kprobes.c
index 5a7b80e2d883..72f97822784a 100644
--- a/arch/arc/kernel/kprobes.c
+++ b/arch/arc/kernel/kprobes.c
@@ -517,8 +517,7 @@ int __kprobes arch_trampoline_kprobe(struct kprobe *p)
517 return 0; 517 return 0;
518} 518}
519 519
520void trap_is_kprobe(unsigned long cause, unsigned long address, 520void trap_is_kprobe(unsigned long address, struct pt_regs *regs)
521 struct pt_regs *regs)
522{ 521{
523 notify_die(DIE_TRAP, "kprobe_trap", regs, address, cause, SIGTRAP); 522 notify_die(DIE_TRAP, "kprobe_trap", regs, address, 0, SIGTRAP);
524} 523}
diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c
index cad66851e0c4..07a3a968fe49 100644
--- a/arch/arc/kernel/process.c
+++ b/arch/arc/kernel/process.c
@@ -55,10 +55,8 @@ asmlinkage void ret_from_fork(void);
55 * | ... | 55 * | ... |
56 * | unused | 56 * | unused |
57 * | | 57 * | |
58 * ------------------ <==== top of Stack (thread.ksp)
59 * | UNUSED 1 word|
60 * ------------------ 58 * ------------------
61 * | r25 | 59 * | r25 | <==== top of Stack (thread.ksp)
62 * ~ ~ 60 * ~ ~
63 * | --to-- | (CALLEE Regs of user mode) 61 * | --to-- | (CALLEE Regs of user mode)
64 * | r13 | 62 * | r13 |
@@ -76,7 +74,10 @@ asmlinkage void ret_from_fork(void);
76 * | --to-- | (scratch Regs of user mode) 74 * | --to-- | (scratch Regs of user mode)
77 * | r0 | 75 * | r0 |
78 * ------------------ 76 * ------------------
79 * | UNUSED 1 word| 77 * | SP |
78 * | orig_r0 |
79 * | event/ECR |
80 * | user_r25 |
80 * ------------------ <===== END of PAGE 81 * ------------------ <===== END of PAGE
81 */ 82 */
82int copy_thread(unsigned long clone_flags, 83int copy_thread(unsigned long clone_flags,
diff --git a/arch/arc/kernel/ptrace.c b/arch/arc/kernel/ptrace.c
index c6a81c58d0f3..333238564b67 100644
--- a/arch/arc/kernel/ptrace.c
+++ b/arch/arc/kernel/ptrace.c
@@ -40,7 +40,15 @@ static int genregs_get(struct task_struct *target,
40 offsetof(struct user_regs_struct, LOC), \ 40 offsetof(struct user_regs_struct, LOC), \
41 offsetof(struct user_regs_struct, LOC) + 4); 41 offsetof(struct user_regs_struct, LOC) + 4);
42 42
43#define REG_O_ZERO(LOC) \
44 if (!ret) \
45 ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, \
46 offsetof(struct user_regs_struct, LOC), \
47 offsetof(struct user_regs_struct, LOC) + 4);
48
49 REG_O_ZERO(pad);
43 REG_O_CHUNK(scratch, callee, ptregs); 50 REG_O_CHUNK(scratch, callee, ptregs);
51 REG_O_ZERO(pad2);
44 REG_O_CHUNK(callee, efa, cregs); 52 REG_O_CHUNK(callee, efa, cregs);
45 REG_O_CHUNK(efa, stop_pc, &target->thread.fault_address); 53 REG_O_CHUNK(efa, stop_pc, &target->thread.fault_address);
46 54
@@ -88,8 +96,10 @@ static int genregs_set(struct task_struct *target,
88 offsetof(struct user_regs_struct, LOC), \ 96 offsetof(struct user_regs_struct, LOC), \
89 offsetof(struct user_regs_struct, LOC) + 4); 97 offsetof(struct user_regs_struct, LOC) + 4);
90 98
91 /* TBD: disallow updates to STATUS32, orig_r8 etc*/ 99 REG_IGNORE_ONE(pad);
92 REG_IN_CHUNK(scratch, callee, ptregs); /* pt_regs[bta..orig_r8] */ 100 /* TBD: disallow updates to STATUS32 etc*/
101 REG_IN_CHUNK(scratch, pad2, ptregs); /* pt_regs[bta..sp] */
102 REG_IGNORE_ONE(pad2);
93 REG_IN_CHUNK(callee, efa, cregs); /* callee_regs[r25..r13] */ 103 REG_IN_CHUNK(callee, efa, cregs); /* callee_regs[r25..r13] */
94 REG_IGNORE_ONE(efa); /* efa update invalid */ 104 REG_IGNORE_ONE(efa); /* efa update invalid */
95 REG_IN_ONE(stop_pc, &ptregs->ret); /* stop_pc: PC update */ 105 REG_IN_ONE(stop_pc, &ptregs->ret); /* stop_pc: PC update */
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index b2b3731dd1e9..6b083454d039 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -31,14 +31,14 @@
31int running_on_hw = 1; /* vs. on ISS */ 31int running_on_hw = 1; /* vs. on ISS */
32 32
33char __initdata command_line[COMMAND_LINE_SIZE]; 33char __initdata command_line[COMMAND_LINE_SIZE];
34struct machine_desc *machine_desc __cpuinitdata; 34struct machine_desc *machine_desc;
35 35
36struct task_struct *_current_task[NR_CPUS]; /* For stack switching */ 36struct task_struct *_current_task[NR_CPUS]; /* For stack switching */
37 37
38struct cpuinfo_arc cpuinfo_arc700[NR_CPUS]; 38struct cpuinfo_arc cpuinfo_arc700[NR_CPUS];
39 39
40 40
41void __cpuinit read_arc_build_cfg_regs(void) 41void read_arc_build_cfg_regs(void)
42{ 42{
43 struct bcr_perip uncached_space; 43 struct bcr_perip uncached_space;
44 struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; 44 struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
@@ -182,7 +182,7 @@ char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len)
182 FIX_PTR(cpu); 182 FIX_PTR(cpu);
183#define IS_AVAIL1(var, str) ((var) ? str : "") 183#define IS_AVAIL1(var, str) ((var) ? str : "")
184#define IS_AVAIL2(var, str) ((var == 0x2) ? str : "") 184#define IS_AVAIL2(var, str) ((var == 0x2) ? str : "")
185#define IS_USED(var) ((var) ? "(in-use)" : "(not used)") 185#define IS_USED(cfg) (IS_ENABLED(cfg) ? "(in-use)" : "(not used)")
186 186
187 n += scnprintf(buf + n, len - n, 187 n += scnprintf(buf + n, len - n,
188 "Extn [700-Base]\t: %s %s %s %s %s %s\n", 188 "Extn [700-Base]\t: %s %s %s %s %s %s\n",
@@ -202,9 +202,9 @@ char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len)
202 if (cpu->core.family == 0x34) { 202 if (cpu->core.family == 0x34) {
203 n += scnprintf(buf + n, len - n, 203 n += scnprintf(buf + n, len - n,
204 "Extn [700-4.10]\t: LLOCK/SCOND %s, SWAPE %s, RTSC %s\n", 204 "Extn [700-4.10]\t: LLOCK/SCOND %s, SWAPE %s, RTSC %s\n",
205 IS_USED(__CONFIG_ARC_HAS_LLSC_VAL), 205 IS_USED(CONFIG_ARC_HAS_LLSC),
206 IS_USED(__CONFIG_ARC_HAS_SWAPE_VAL), 206 IS_USED(CONFIG_ARC_HAS_SWAPE),
207 IS_USED(__CONFIG_ARC_HAS_RTSC_VAL)); 207 IS_USED(CONFIG_ARC_HAS_RTSC));
208 } 208 }
209 209
210 n += scnprintf(buf + n, len - n, "Extn [CCM]\t: %s", 210 n += scnprintf(buf + n, len - n, "Extn [CCM]\t: %s",
@@ -237,7 +237,7 @@ char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len)
237 return buf; 237 return buf;
238} 238}
239 239
240void __cpuinit arc_chk_ccms(void) 240void arc_chk_ccms(void)
241{ 241{
242#if defined(CONFIG_ARC_HAS_DCCM) || defined(CONFIG_ARC_HAS_ICCM) 242#if defined(CONFIG_ARC_HAS_DCCM) || defined(CONFIG_ARC_HAS_ICCM)
243 struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; 243 struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
@@ -272,7 +272,7 @@ void __cpuinit arc_chk_ccms(void)
272 * hardware has dedicated regs which need to be saved/restored on ctx-sw 272 * hardware has dedicated regs which need to be saved/restored on ctx-sw
273 * (Single Precision uses core regs), thus kernel is kind of oblivious to it 273 * (Single Precision uses core regs), thus kernel is kind of oblivious to it
274 */ 274 */
275void __cpuinit arc_chk_fpu(void) 275void arc_chk_fpu(void)
276{ 276{
277 struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; 277 struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
278 278
@@ -293,7 +293,7 @@ void __cpuinit arc_chk_fpu(void)
293 * such as only for boot CPU etc 293 * such as only for boot CPU etc
294 */ 294 */
295 295
296void __cpuinit setup_processor(void) 296void setup_processor(void)
297{ 297{
298 char str[512]; 298 char str[512];
299 int cpu_id = smp_processor_id(); 299 int cpu_id = smp_processor_id();
diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index 5c7fd603d216..bca3052c956d 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -117,7 +117,7 @@ const char *arc_platform_smp_cpuinfo(void)
117 * Called from asm stub in head.S 117 * Called from asm stub in head.S
118 * "current"/R25 already setup by low level boot code 118 * "current"/R25 already setup by low level boot code
119 */ 119 */
120void __cpuinit start_kernel_secondary(void) 120void start_kernel_secondary(void)
121{ 121{
122 struct mm_struct *mm = &init_mm; 122 struct mm_struct *mm = &init_mm;
123 unsigned int cpu = smp_processor_id(); 123 unsigned int cpu = smp_processor_id();
@@ -154,7 +154,7 @@ void __cpuinit start_kernel_secondary(void)
154 * 154 *
155 * Essential requirements being where to run from (PC) and stack (SP) 155 * Essential requirements being where to run from (PC) and stack (SP)
156*/ 156*/
157int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle) 157int __cpu_up(unsigned int cpu, struct task_struct *idle)
158{ 158{
159 unsigned long wait_till; 159 unsigned long wait_till;
160 160
diff --git a/arch/arc/kernel/stacktrace.c b/arch/arc/kernel/stacktrace.c
index ca0207b9d5b6..f8b7d880304d 100644
--- a/arch/arc/kernel/stacktrace.c
+++ b/arch/arc/kernel/stacktrace.c
@@ -79,7 +79,7 @@ static void seed_unwind_frame_info(struct task_struct *tsk,
79 * assembly code 79 * assembly code
80 */ 80 */
81 frame_info->regs.r27 = 0; 81 frame_info->regs.r27 = 0;
82 frame_info->regs.r28 += 64; 82 frame_info->regs.r28 += 60;
83 frame_info->call_frame = 0; 83 frame_info->call_frame = 0;
84 84
85 } else { 85 } else {
diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index 09f4309aa2c0..0e51e69cf30d 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -44,13 +44,24 @@
44#include <asm/clk.h> 44#include <asm/clk.h>
45#include <asm/mach_desc.h> 45#include <asm/mach_desc.h>
46 46
47/* Timer related Aux registers */
48#define ARC_REG_TIMER0_LIMIT 0x23 /* timer 0 limit */
49#define ARC_REG_TIMER0_CTRL 0x22 /* timer 0 control */
50#define ARC_REG_TIMER0_CNT 0x21 /* timer 0 count */
51#define ARC_REG_TIMER1_LIMIT 0x102 /* timer 1 limit */
52#define ARC_REG_TIMER1_CTRL 0x101 /* timer 1 control */
53#define ARC_REG_TIMER1_CNT 0x100 /* timer 1 count */
54
55#define TIMER_CTRL_IE (1 << 0) /* Interupt when Count reachs limit */
56#define TIMER_CTRL_NH (1 << 1) /* Count only when CPU NOT halted */
57
47#define ARC_TIMER_MAX 0xFFFFFFFF 58#define ARC_TIMER_MAX 0xFFFFFFFF
48 59
49/********** Clock Source Device *********/ 60/********** Clock Source Device *********/
50 61
51#ifdef CONFIG_ARC_HAS_RTSC 62#ifdef CONFIG_ARC_HAS_RTSC
52 63
53int __cpuinit arc_counter_setup(void) 64int arc_counter_setup(void)
54{ 65{
55 /* RTSC insn taps into cpu clk, needs no setup */ 66 /* RTSC insn taps into cpu clk, needs no setup */
56 67
@@ -105,7 +116,7 @@ static bool is_usable_as_clocksource(void)
105/* 116/*
106 * set 32bit TIMER1 to keep counting monotonically and wraparound 117 * set 32bit TIMER1 to keep counting monotonically and wraparound
107 */ 118 */
108int __cpuinit arc_counter_setup(void) 119int arc_counter_setup(void)
109{ 120{
110 write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMER_MAX); 121 write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMER_MAX);
111 write_aux_reg(ARC_REG_TIMER1_CNT, 0); 122 write_aux_reg(ARC_REG_TIMER1_CNT, 0);
@@ -212,7 +223,7 @@ static struct irqaction arc_timer_irq = {
212 * Setup the local event timer for @cpu 223 * Setup the local event timer for @cpu
213 * N.B. weak so that some exotic ARC SoCs can completely override it 224 * N.B. weak so that some exotic ARC SoCs can completely override it
214 */ 225 */
215void __attribute__((weak)) __cpuinit arc_local_timer_setup(unsigned int cpu) 226void __attribute__((weak)) arc_local_timer_setup(unsigned int cpu)
216{ 227{
217 struct clock_event_device *clk = &per_cpu(arc_clockevent_device, cpu); 228 struct clock_event_device *clk = &per_cpu(arc_clockevent_device, cpu);
218 229
diff --git a/arch/arc/kernel/traps.c b/arch/arc/kernel/traps.c
index 0471d9c9dd54..e21692d2fdab 100644
--- a/arch/arc/kernel/traps.c
+++ b/arch/arc/kernel/traps.c
@@ -28,10 +28,9 @@ void __init trap_init(void)
28 return; 28 return;
29} 29}
30 30
31void die(const char *str, struct pt_regs *regs, unsigned long address, 31void die(const char *str, struct pt_regs *regs, unsigned long address)
32 unsigned long cause_reg)
33{ 32{
34 show_kernel_fault_diag(str, regs, address, cause_reg); 33 show_kernel_fault_diag(str, regs, address);
35 34
36 /* DEAD END */ 35 /* DEAD END */
37 __asm__("flag 1"); 36 __asm__("flag 1");
@@ -42,14 +41,13 @@ void die(const char *str, struct pt_regs *regs, unsigned long address,
42 * -for user faults enqueues requested signal 41 * -for user faults enqueues requested signal
43 * -for kernel, chk if due to copy_(to|from)_user, otherwise die() 42 * -for kernel, chk if due to copy_(to|from)_user, otherwise die()
44 */ 43 */
45static noinline int handle_exception(unsigned long cause, char *str, 44static noinline int
46 struct pt_regs *regs, siginfo_t *info) 45handle_exception(const char *str, struct pt_regs *regs, siginfo_t *info)
47{ 46{
48 if (user_mode(regs)) { 47 if (user_mode(regs)) {
49 struct task_struct *tsk = current; 48 struct task_struct *tsk = current;
50 49
51 tsk->thread.fault_address = (__force unsigned int)info->si_addr; 50 tsk->thread.fault_address = (__force unsigned int)info->si_addr;
52 tsk->thread.cause_code = cause;
53 51
54 force_sig_info(info->si_signo, info, tsk); 52 force_sig_info(info->si_signo, info, tsk);
55 53
@@ -58,14 +56,14 @@ static noinline int handle_exception(unsigned long cause, char *str,
58 if (fixup_exception(regs)) 56 if (fixup_exception(regs))
59 return 0; 57 return 0;
60 58
61 die(str, regs, (unsigned long)info->si_addr, cause); 59 die(str, regs, (unsigned long)info->si_addr);
62 } 60 }
63 61
64 return 1; 62 return 1;
65} 63}
66 64
67#define DO_ERROR_INFO(signr, str, name, sicode) \ 65#define DO_ERROR_INFO(signr, str, name, sicode) \
68int name(unsigned long cause, unsigned long address, struct pt_regs *regs) \ 66int name(unsigned long address, struct pt_regs *regs) \
69{ \ 67{ \
70 siginfo_t info = { \ 68 siginfo_t info = { \
71 .si_signo = signr, \ 69 .si_signo = signr, \
@@ -73,7 +71,7 @@ int name(unsigned long cause, unsigned long address, struct pt_regs *regs) \
73 .si_code = sicode, \ 71 .si_code = sicode, \
74 .si_addr = (void __user *)address, \ 72 .si_addr = (void __user *)address, \
75 }; \ 73 }; \
76 return handle_exception(cause, str, regs, &info);\ 74 return handle_exception(str, regs, &info);\
77} 75}
78 76
79/* 77/*
@@ -90,11 +88,11 @@ DO_ERROR_INFO(SIGBUS, "Misaligned Access", do_misaligned_error, BUS_ADRALN)
90/* 88/*
91 * Entry Point for Misaligned Data access Exception, for emulating in software 89 * Entry Point for Misaligned Data access Exception, for emulating in software
92 */ 90 */
93int do_misaligned_access(unsigned long cause, unsigned long address, 91int do_misaligned_access(unsigned long address, struct pt_regs *regs,
94 struct pt_regs *regs, struct callee_regs *cregs) 92 struct callee_regs *cregs)
95{ 93{
96 if (misaligned_fixup(address, regs, cause, cregs) != 0) 94 if (misaligned_fixup(address, regs, cregs) != 0)
97 return do_misaligned_error(cause, address, regs); 95 return do_misaligned_error(address, regs);
98 96
99 return 0; 97 return 0;
100} 98}
@@ -104,10 +102,9 @@ int do_misaligned_access(unsigned long cause, unsigned long address,
104 * Entry point for miscll errors such as Nested Exceptions 102 * Entry point for miscll errors such as Nested Exceptions
105 * -Duplicate TLB entry is handled seperately though 103 * -Duplicate TLB entry is handled seperately though
106 */ 104 */
107void do_machine_check_fault(unsigned long cause, unsigned long address, 105void do_machine_check_fault(unsigned long address, struct pt_regs *regs)
108 struct pt_regs *regs)
109{ 106{
110 die("Machine Check Exception", regs, address, cause); 107 die("Machine Check Exception", regs, address);
111} 108}
112 109
113 110
@@ -120,23 +117,22 @@ void do_machine_check_fault(unsigned long cause, unsigned long address,
120 * -1 used for software breakpointing (gdb) 117 * -1 used for software breakpointing (gdb)
121 * -2 used by kprobes 118 * -2 used by kprobes
122 */ 119 */
123void do_non_swi_trap(unsigned long cause, unsigned long address, 120void do_non_swi_trap(unsigned long address, struct pt_regs *regs)
124 struct pt_regs *regs)
125{ 121{
126 unsigned int param = cause & 0xff; 122 unsigned int param = regs->ecr_param;
127 123
128 switch (param) { 124 switch (param) {
129 case 1: 125 case 1:
130 trap_is_brkpt(cause, address, regs); 126 trap_is_brkpt(address, regs);
131 break; 127 break;
132 128
133 case 2: 129 case 2:
134 trap_is_kprobe(param, address, regs); 130 trap_is_kprobe(address, regs);
135 break; 131 break;
136 132
137 case 3: 133 case 3:
138 case 4: 134 case 4:
139 kgdb_trap(regs, param); 135 kgdb_trap(regs);
140 break; 136 break;
141 137
142 default: 138 default:
@@ -149,14 +145,14 @@ void do_non_swi_trap(unsigned long cause, unsigned long address,
149 * -For a corner case, ARC kprobes implementation resorts to using 145 * -For a corner case, ARC kprobes implementation resorts to using
150 * this exception, hence the check 146 * this exception, hence the check
151 */ 147 */
152void do_insterror_or_kprobe(unsigned long cause, 148void do_insterror_or_kprobe(unsigned long address, struct pt_regs *regs)
153 unsigned long address,
154 struct pt_regs *regs)
155{ 149{
150 int rc;
151
156 /* Check if this exception is caused by kprobes */ 152 /* Check if this exception is caused by kprobes */
157 if (notify_die(DIE_IERR, "kprobe_ierr", regs, address, 153 rc = notify_die(DIE_IERR, "kprobe_ierr", regs, address, 0, SIGILL);
158 cause, SIGILL) == NOTIFY_STOP) 154 if (rc == NOTIFY_STOP)
159 return; 155 return;
160 156
161 insterror_is_error(cause, address, regs); 157 insterror_is_error(address, regs);
162} 158}
diff --git a/arch/arc/kernel/troubleshoot.c b/arch/arc/kernel/troubleshoot.c
index 11c301b81c92..73a7450ee622 100644
--- a/arch/arc/kernel/troubleshoot.c
+++ b/arch/arc/kernel/troubleshoot.c
@@ -101,7 +101,7 @@ static void show_faulting_vma(unsigned long address, char *buf)
101 if (file) { 101 if (file) {
102 struct path *path = &file->f_path; 102 struct path *path = &file->f_path;
103 nm = d_path(path, buf, PAGE_SIZE - 1); 103 nm = d_path(path, buf, PAGE_SIZE - 1);
104 inode = vma->vm_file->f_path.dentry->d_inode; 104 inode = file_inode(vma->vm_file);
105 dev = inode->i_sb->s_dev; 105 dev = inode->i_sb->s_dev;
106 ino = inode->i_ino; 106 ino = inode->i_ino;
107 } 107 }
@@ -117,23 +117,22 @@ static void show_faulting_vma(unsigned long address, char *buf)
117 117
118static void show_ecr_verbose(struct pt_regs *regs) 118static void show_ecr_verbose(struct pt_regs *regs)
119{ 119{
120 unsigned int vec, cause_code, cause_reg; 120 unsigned int vec, cause_code;
121 unsigned long address; 121 unsigned long address;
122 122
123 cause_reg = current->thread.cause_code; 123 pr_info("\n[ECR ]: 0x%08lx => ", regs->event);
124 pr_info("\n[ECR ]: 0x%08x => ", cause_reg);
125 124
126 /* For Data fault, this is data address not instruction addr */ 125 /* For Data fault, this is data address not instruction addr */
127 address = current->thread.fault_address; 126 address = current->thread.fault_address;
128 127
129 vec = cause_reg >> 16; 128 vec = regs->ecr_vec;
130 cause_code = (cause_reg >> 8) & 0xFF; 129 cause_code = regs->ecr_cause;
131 130
132 /* For DTLB Miss or ProtV, display the memory involved too */ 131 /* For DTLB Miss or ProtV, display the memory involved too */
133 if (vec == ECR_V_DTLB_MISS) { 132 if (vec == ECR_V_DTLB_MISS) {
134 pr_cont("Invalid %s 0x%08lx by insn @ 0x%08lx\n", 133 pr_cont("Invalid %s @ 0x%08lx by insn @ 0x%08lx\n",
135 (cause_code == 0x01) ? "Read From" : 134 (cause_code == 0x01) ? "Read" :
136 ((cause_code == 0x02) ? "Write to" : "EX"), 135 ((cause_code == 0x02) ? "Write" : "EX"),
137 address, regs->ret); 136 address, regs->ret);
138 } else if (vec == ECR_V_ITLB_MISS) { 137 } else if (vec == ECR_V_ITLB_MISS) {
139 pr_cont("Insn could not be fetched\n"); 138 pr_cont("Insn could not be fetched\n");
@@ -144,14 +143,12 @@ static void show_ecr_verbose(struct pt_regs *regs)
144 } else if (vec == ECR_V_PROTV) { 143 } else if (vec == ECR_V_PROTV) {
145 if (cause_code == ECR_C_PROTV_INST_FETCH) 144 if (cause_code == ECR_C_PROTV_INST_FETCH)
146 pr_cont("Execute from Non-exec Page\n"); 145 pr_cont("Execute from Non-exec Page\n");
147 else if (cause_code == ECR_C_PROTV_LOAD)
148 pr_cont("Read from Non-readable Page\n");
149 else if (cause_code == ECR_C_PROTV_STORE)
150 pr_cont("Write to Non-writable Page\n");
151 else if (cause_code == ECR_C_PROTV_XCHG)
152 pr_cont("Data exchange protection violation\n");
153 else if (cause_code == ECR_C_PROTV_MISALIG_DATA) 146 else if (cause_code == ECR_C_PROTV_MISALIG_DATA)
154 pr_cont("Misaligned r/w from 0x%08lx\n", address); 147 pr_cont("Misaligned r/w from 0x%08lx\n", address);
148 else
149 pr_cont("%s access not allowed on page\n",
150 (cause_code == 0x01) ? "Read" :
151 ((cause_code == 0x02) ? "Write" : "EX"));
155 } else if (vec == ECR_V_INSN_ERR) { 152 } else if (vec == ECR_V_INSN_ERR) {
156 pr_cont("Illegal Insn\n"); 153 pr_cont("Illegal Insn\n");
157 } else { 154 } else {
@@ -176,8 +173,7 @@ void show_regs(struct pt_regs *regs)
176 print_task_path_n_nm(tsk, buf); 173 print_task_path_n_nm(tsk, buf);
177 show_regs_print_info(KERN_INFO); 174 show_regs_print_info(KERN_INFO);
178 175
179 if (current->thread.cause_code) 176 show_ecr_verbose(regs);
180 show_ecr_verbose(regs);
181 177
182 pr_info("[EFA ]: 0x%08lx\n[BLINK ]: %pS\n[ERET ]: %pS\n", 178 pr_info("[EFA ]: 0x%08lx\n[BLINK ]: %pS\n[ERET ]: %pS\n",
183 current->thread.fault_address, 179 current->thread.fault_address,
@@ -213,10 +209,9 @@ void show_regs(struct pt_regs *regs)
213} 209}
214 210
215void show_kernel_fault_diag(const char *str, struct pt_regs *regs, 211void show_kernel_fault_diag(const char *str, struct pt_regs *regs,
216 unsigned long address, unsigned long cause_reg) 212 unsigned long address)
217{ 213{
218 current->thread.fault_address = address; 214 current->thread.fault_address = address;
219 current->thread.cause_code = cause_reg;
220 215
221 /* Caller and Callee regs */ 216 /* Caller and Callee regs */
222 show_regs(regs); 217 show_regs(regs);
diff --git a/arch/arc/kernel/unaligned.c b/arch/arc/kernel/unaligned.c
index 4cd81633febd..c0f832f595d3 100644
--- a/arch/arc/kernel/unaligned.c
+++ b/arch/arc/kernel/unaligned.c
@@ -187,7 +187,7 @@ fault: state->fault = 1;
187 * Returns 0 if successfully handled, 1 if some error happened 187 * Returns 0 if successfully handled, 1 if some error happened
188 */ 188 */
189int misaligned_fixup(unsigned long address, struct pt_regs *regs, 189int misaligned_fixup(unsigned long address, struct pt_regs *regs,
190 unsigned long cause, struct callee_regs *cregs) 190 struct callee_regs *cregs)
191{ 191{
192 struct disasm_state state; 192 struct disasm_state state;
193 char buf[TASK_COMM_LEN]; 193 char buf[TASK_COMM_LEN];
diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index a8d02223da44..e550b117ec4f 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -289,6 +289,8 @@ static void __init setup_unwind_table(struct unwind_table *table,
289 * instead of the initial loc addr 289 * instead of the initial loc addr
290 * return; 290 * return;
291 */ 291 */
292 WARN(1, "unwinder: FDE->initial_location NULL %p\n",
293 (const u8 *)(fde + 1) + *fde);
292 } 294 }
293 ++n; 295 ++n;
294 } 296 }
diff --git a/arch/arc/kernel/vmlinux.lds.S b/arch/arc/kernel/vmlinux.lds.S
index d3c92f52d444..2555f5886af6 100644
--- a/arch/arc/kernel/vmlinux.lds.S
+++ b/arch/arc/kernel/vmlinux.lds.S
@@ -125,6 +125,11 @@ SECTIONS
125 *(.debug_frame) 125 *(.debug_frame)
126 __end_unwind = .; 126 __end_unwind = .;
127 } 127 }
128 /*
129 * gcc 4.8 generates this for -fasynchonous-unwind-tables,
130 * while we still use the .debug_frame based unwinder
131 */
132 /DISCARD/ : { *(.eh_frame) }
128#else 133#else
129 /DISCARD/ : { *(.debug_frame) } 134 /DISCARD/ : { *(.debug_frame) }
130#endif 135#endif
@@ -142,15 +147,18 @@ SECTIONS
142 *(.arcextmap.*) 147 *(.arcextmap.*)
143 } 148 }
144 149
150#ifndef CONFIG_DEBUG_INFO
145 /* open-coded because we need .debug_frame seperately for unwinding */ 151 /* open-coded because we need .debug_frame seperately for unwinding */
146 .debug_aranges 0 : { *(.debug_aranges) } 152 /DISCARD/ : { *(.debug_aranges) }
147 .debug_pubnames 0 : { *(.debug_pubnames) } 153 /DISCARD/ : { *(.debug_pubnames) }
148 .debug_info 0 : { *(.debug_info) } 154 /DISCARD/ : { *(.debug_info) }
149 .debug_abbrev 0 : { *(.debug_abbrev) } 155 /DISCARD/ : { *(.debug_abbrev) }
150 .debug_line 0 : { *(.debug_line) } 156 /DISCARD/ : { *(.debug_line) }
151 .debug_str 0 : { *(.debug_str) } 157 /DISCARD/ : { *(.debug_str) }
152 .debug_loc 0 : { *(.debug_loc) } 158 /DISCARD/ : { *(.debug_loc) }
153 .debug_macinfo 0 : { *(.debug_macinfo) } 159 /DISCARD/ : { *(.debug_macinfo) }
160 /DISCARD/ : { *(.debug_ranges) }
161#endif
154 162
155#ifdef CONFIG_ARC_HAS_DCCM 163#ifdef CONFIG_ARC_HAS_DCCM
156 . = CONFIG_ARC_DCCM_BASE; 164 . = CONFIG_ARC_DCCM_BASE;
diff --git a/arch/arc/mm/cache_arc700.c b/arch/arc/mm/cache_arc700.c
index aedce1905441..f415d851b765 100644
--- a/arch/arc/mm/cache_arc700.c
+++ b/arch/arc/mm/cache_arc700.c
@@ -73,6 +73,33 @@
73#include <asm/cachectl.h> 73#include <asm/cachectl.h>
74#include <asm/setup.h> 74#include <asm/setup.h>
75 75
76/* Instruction cache related Auxiliary registers */
77#define ARC_REG_IC_BCR 0x77 /* Build Config reg */
78#define ARC_REG_IC_IVIC 0x10
79#define ARC_REG_IC_CTRL 0x11
80#define ARC_REG_IC_IVIL 0x19
81#if (CONFIG_ARC_MMU_VER > 2)
82#define ARC_REG_IC_PTAG 0x1E
83#endif
84
85/* Bit val in IC_CTRL */
86#define IC_CTRL_CACHE_DISABLE 0x1
87
88/* Data cache related Auxiliary registers */
89#define ARC_REG_DC_BCR 0x72 /* Build Config reg */
90#define ARC_REG_DC_IVDC 0x47
91#define ARC_REG_DC_CTRL 0x48
92#define ARC_REG_DC_IVDL 0x4A
93#define ARC_REG_DC_FLSH 0x4B
94#define ARC_REG_DC_FLDL 0x4C
95#if (CONFIG_ARC_MMU_VER > 2)
96#define ARC_REG_DC_PTAG 0x5C
97#endif
98
99/* Bit val in DC_CTRL */
100#define DC_CTRL_INV_MODE_FLUSH 0x40
101#define DC_CTRL_FLUSH_STATUS 0x100
102
76char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len) 103char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len)
77{ 104{
78 int n = 0; 105 int n = 0;
@@ -89,8 +116,10 @@ char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len)
89 enb ? "" : "DISABLED (kernel-build)"); \ 116 enb ? "" : "DISABLED (kernel-build)"); \
90} 117}
91 118
92 PR_CACHE(&cpuinfo_arc700[c].icache, __CONFIG_ARC_HAS_ICACHE, "I-Cache"); 119 PR_CACHE(&cpuinfo_arc700[c].icache, IS_ENABLED(CONFIG_ARC_HAS_ICACHE),
93 PR_CACHE(&cpuinfo_arc700[c].dcache, __CONFIG_ARC_HAS_DCACHE, "D-Cache"); 120 "I-Cache");
121 PR_CACHE(&cpuinfo_arc700[c].dcache, IS_ENABLED(CONFIG_ARC_HAS_DCACHE),
122 "D-Cache");
94 123
95 return buf; 124 return buf;
96} 125}
@@ -100,17 +129,23 @@ char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len)
100 * the cpuinfo structure for later use. 129 * the cpuinfo structure for later use.
101 * No Validation done here, simply read/convert the BCRs 130 * No Validation done here, simply read/convert the BCRs
102 */ 131 */
103void __cpuinit read_decode_cache_bcr(void) 132void read_decode_cache_bcr(void)
104{ 133{
105 struct bcr_cache ibcr, dbcr;
106 struct cpuinfo_arc_cache *p_ic, *p_dc; 134 struct cpuinfo_arc_cache *p_ic, *p_dc;
107 unsigned int cpu = smp_processor_id(); 135 unsigned int cpu = smp_processor_id();
136 struct bcr_cache {
137#ifdef CONFIG_CPU_BIG_ENDIAN
138 unsigned int pad:12, line_len:4, sz:4, config:4, ver:8;
139#else
140 unsigned int ver:8, config:4, sz:4, line_len:4, pad:12;
141#endif
142 } ibcr, dbcr;
108 143
109 p_ic = &cpuinfo_arc700[cpu].icache; 144 p_ic = &cpuinfo_arc700[cpu].icache;
110 READ_BCR(ARC_REG_IC_BCR, ibcr); 145 READ_BCR(ARC_REG_IC_BCR, ibcr);
111 146
112 if (ibcr.config == 0x3) 147 BUG_ON(ibcr.config != 3);
113 p_ic->assoc = 2; 148 p_ic->assoc = 2; /* Fixed to 2w set assoc */
114 p_ic->line_len = 8 << ibcr.line_len; 149 p_ic->line_len = 8 << ibcr.line_len;
115 p_ic->sz = 0x200 << ibcr.sz; 150 p_ic->sz = 0x200 << ibcr.sz;
116 p_ic->ver = ibcr.ver; 151 p_ic->ver = ibcr.ver;
@@ -118,8 +153,8 @@ void __cpuinit read_decode_cache_bcr(void)
118 p_dc = &cpuinfo_arc700[cpu].dcache; 153 p_dc = &cpuinfo_arc700[cpu].dcache;
119 READ_BCR(ARC_REG_DC_BCR, dbcr); 154 READ_BCR(ARC_REG_DC_BCR, dbcr);
120 155
121 if (dbcr.config == 0x2) 156 BUG_ON(dbcr.config != 2);
122 p_dc->assoc = 4; 157 p_dc->assoc = 4; /* Fixed to 4w set assoc */
123 p_dc->line_len = 16 << dbcr.line_len; 158 p_dc->line_len = 16 << dbcr.line_len;
124 p_dc->sz = 0x200 << dbcr.sz; 159 p_dc->sz = 0x200 << dbcr.sz;
125 p_dc->ver = dbcr.ver; 160 p_dc->ver = dbcr.ver;
@@ -132,14 +167,12 @@ void __cpuinit read_decode_cache_bcr(void)
132 * 3. Enable the Caches, setup default flush mode for D-Cache 167 * 3. Enable the Caches, setup default flush mode for D-Cache
133 * 3. Calculate the SHMLBA used by user space 168 * 3. Calculate the SHMLBA used by user space
134 */ 169 */
135void __cpuinit arc_cache_init(void) 170void arc_cache_init(void)
136{ 171{
137 unsigned int temp;
138 unsigned int cpu = smp_processor_id(); 172 unsigned int cpu = smp_processor_id();
139 struct cpuinfo_arc_cache *ic = &cpuinfo_arc700[cpu].icache; 173 struct cpuinfo_arc_cache *ic = &cpuinfo_arc700[cpu].icache;
140 struct cpuinfo_arc_cache *dc = &cpuinfo_arc700[cpu].dcache; 174 struct cpuinfo_arc_cache *dc = &cpuinfo_arc700[cpu].dcache;
141 int way_pg_ratio = way_pg_ratio; 175 unsigned int dcache_does_alias, temp;
142 int dcache_does_alias;
143 char str[256]; 176 char str[256];
144 177
145 printk(arc_cache_mumbojumbo(0, str, sizeof(str))); 178 printk(arc_cache_mumbojumbo(0, str, sizeof(str)));
@@ -149,20 +182,11 @@ void __cpuinit arc_cache_init(void)
149 182
150#ifdef CONFIG_ARC_HAS_ICACHE 183#ifdef CONFIG_ARC_HAS_ICACHE
151 /* 1. Confirm some of I-cache params which Linux assumes */ 184 /* 1. Confirm some of I-cache params which Linux assumes */
152 if ((ic->assoc != ARC_ICACHE_WAYS) || 185 if (ic->line_len != ARC_ICACHE_LINE_LEN)
153 (ic->line_len != ARC_ICACHE_LINE_LEN)) {
154 panic("Cache H/W doesn't match kernel Config"); 186 panic("Cache H/W doesn't match kernel Config");
155 }
156#if (CONFIG_ARC_MMU_VER > 2)
157 if (ic->ver != 3) {
158 if (running_on_hw)
159 panic("Cache ver doesn't match MMU ver\n");
160
161 /* For ISS - suggest the toggles to use */
162 pr_err("Use -prop=icache_version=3,-prop=dcache_version=3\n");
163 187
164 } 188 if (ic->ver != CONFIG_ARC_MMU_VER)
165#endif 189 panic("Cache ver doesn't match MMU ver\n");
166#endif 190#endif
167 191
168 /* Enable/disable I-Cache */ 192 /* Enable/disable I-Cache */
@@ -181,14 +205,12 @@ chk_dc:
181 return; 205 return;
182 206
183#ifdef CONFIG_ARC_HAS_DCACHE 207#ifdef CONFIG_ARC_HAS_DCACHE
184 if ((dc->assoc != ARC_DCACHE_WAYS) || 208 if (dc->line_len != ARC_DCACHE_LINE_LEN)
185 (dc->line_len != ARC_DCACHE_LINE_LEN)) {
186 panic("Cache H/W doesn't match kernel Config"); 209 panic("Cache H/W doesn't match kernel Config");
187 }
188
189 dcache_does_alias = (dc->sz / ARC_DCACHE_WAYS) > PAGE_SIZE;
190 210
191 /* check for D-Cache aliasing */ 211 /* check for D-Cache aliasing */
212 dcache_does_alias = (dc->sz / dc->assoc) > PAGE_SIZE;
213
192 if (dcache_does_alias && !cache_is_vipt_aliasing()) 214 if (dcache_does_alias && !cache_is_vipt_aliasing())
193 panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n"); 215 panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n");
194 else if (!dcache_does_alias && cache_is_vipt_aliasing()) 216 else if (!dcache_does_alias && cache_is_vipt_aliasing())
@@ -239,11 +261,9 @@ static inline void wait_for_flush(void)
239 */ 261 */
240static inline void __dc_entire_op(const int cacheop) 262static inline void __dc_entire_op(const int cacheop)
241{ 263{
242 unsigned long flags, tmp = tmp; 264 unsigned int tmp = tmp;
243 int aux; 265 int aux;
244 266
245 local_irq_save(flags);
246
247 if (cacheop == OP_FLUSH_N_INV) { 267 if (cacheop == OP_FLUSH_N_INV) {
248 /* Dcache provides 2 cmd: FLUSH or INV 268 /* Dcache provides 2 cmd: FLUSH or INV
249 * INV inturn has sub-modes: DISCARD or FLUSH-BEFORE 269 * INV inturn has sub-modes: DISCARD or FLUSH-BEFORE
@@ -267,8 +287,6 @@ static inline void __dc_entire_op(const int cacheop)
267 /* Switch back the DISCARD ONLY Invalidate mode */ 287 /* Switch back the DISCARD ONLY Invalidate mode */
268 if (cacheop == OP_FLUSH_N_INV) 288 if (cacheop == OP_FLUSH_N_INV)
269 write_aux_reg(ARC_REG_DC_CTRL, tmp & ~DC_CTRL_INV_MODE_FLUSH); 289 write_aux_reg(ARC_REG_DC_CTRL, tmp & ~DC_CTRL_INV_MODE_FLUSH);
270
271 local_irq_restore(flags);
272} 290}
273 291
274/* 292/*
@@ -459,8 +477,15 @@ static void __ic_line_inv_vaddr(unsigned long paddr, unsigned long vaddr,
459 local_irq_restore(flags); 477 local_irq_restore(flags);
460} 478}
461 479
480static inline void __ic_entire_inv(void)
481{
482 write_aux_reg(ARC_REG_IC_IVIC, 1);
483 read_aux_reg(ARC_REG_IC_CTRL); /* blocks */
484}
485
462#else 486#else
463 487
488#define __ic_entire_inv()
464#define __ic_line_inv_vaddr(pstart, vstart, sz) 489#define __ic_line_inv_vaddr(pstart, vstart, sz)
465 490
466#endif /* CONFIG_ARC_HAS_ICACHE */ 491#endif /* CONFIG_ARC_HAS_ICACHE */
@@ -487,7 +512,7 @@ void flush_dcache_page(struct page *page)
487 struct address_space *mapping; 512 struct address_space *mapping;
488 513
489 if (!cache_is_vipt_aliasing()) { 514 if (!cache_is_vipt_aliasing()) {
490 set_bit(PG_arch_1, &page->flags); 515 clear_bit(PG_dc_clean, &page->flags);
491 return; 516 return;
492 } 517 }
493 518
@@ -501,7 +526,7 @@ void flush_dcache_page(struct page *page)
501 * Make a note that K-mapping is dirty 526 * Make a note that K-mapping is dirty
502 */ 527 */
503 if (!mapping_mapped(mapping)) { 528 if (!mapping_mapped(mapping)) {
504 set_bit(PG_arch_1, &page->flags); 529 clear_bit(PG_dc_clean, &page->flags);
505 } else if (page_mapped(page)) { 530 } else if (page_mapped(page)) {
506 531
507 /* kernel reading from page with U-mapping */ 532 /* kernel reading from page with U-mapping */
@@ -629,26 +654,13 @@ void ___flush_dcache_page(unsigned long paddr, unsigned long vaddr)
629 __dc_line_op(paddr, vaddr & PAGE_MASK, PAGE_SIZE, OP_FLUSH_N_INV); 654 __dc_line_op(paddr, vaddr & PAGE_MASK, PAGE_SIZE, OP_FLUSH_N_INV);
630} 655}
631 656
632void flush_icache_all(void)
633{
634 unsigned long flags;
635
636 local_irq_save(flags);
637
638 write_aux_reg(ARC_REG_IC_IVIC, 1);
639
640 /* lr will not complete till the icache inv operation is not over */
641 read_aux_reg(ARC_REG_IC_CTRL);
642 local_irq_restore(flags);
643}
644
645noinline void flush_cache_all(void) 657noinline void flush_cache_all(void)
646{ 658{
647 unsigned long flags; 659 unsigned long flags;
648 660
649 local_irq_save(flags); 661 local_irq_save(flags);
650 662
651 flush_icache_all(); 663 __ic_entire_inv();
652 __dc_entire_op(OP_FLUSH_N_INV); 664 __dc_entire_op(OP_FLUSH_N_INV);
653 665
654 local_irq_restore(flags); 666 local_irq_restore(flags);
@@ -667,7 +679,12 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long u_vaddr,
667{ 679{
668 unsigned int paddr = pfn << PAGE_SHIFT; 680 unsigned int paddr = pfn << PAGE_SHIFT;
669 681
670 __sync_icache_dcache(paddr, u_vaddr, PAGE_SIZE); 682 u_vaddr &= PAGE_MASK;
683
684 ___flush_dcache_page(paddr, u_vaddr);
685
686 if (vma->vm_flags & VM_EXEC)
687 __inv_icache_page(paddr, u_vaddr);
671} 688}
672 689
673void flush_cache_range(struct vm_area_struct *vma, unsigned long start, 690void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
@@ -717,7 +734,7 @@ void copy_user_highpage(struct page *to, struct page *from,
717 * non copied user pages (e.g. read faults which wire in pagecache page 734 * non copied user pages (e.g. read faults which wire in pagecache page
718 * directly). 735 * directly).
719 */ 736 */
720 set_bit(PG_arch_1, &to->flags); 737 clear_bit(PG_dc_clean, &to->flags);
721 738
722 /* 739 /*
723 * if SRC was already usermapped and non-congruent to kernel mapping 740 * if SRC was already usermapped and non-congruent to kernel mapping
@@ -725,15 +742,16 @@ void copy_user_highpage(struct page *to, struct page *from,
725 */ 742 */
726 if (clean_src_k_mappings) { 743 if (clean_src_k_mappings) {
727 __flush_dcache_page(kfrom, kfrom); 744 __flush_dcache_page(kfrom, kfrom);
745 set_bit(PG_dc_clean, &from->flags);
728 } else { 746 } else {
729 set_bit(PG_arch_1, &from->flags); 747 clear_bit(PG_dc_clean, &from->flags);
730 } 748 }
731} 749}
732 750
733void clear_user_page(void *to, unsigned long u_vaddr, struct page *page) 751void clear_user_page(void *to, unsigned long u_vaddr, struct page *page)
734{ 752{
735 clear_page(to); 753 clear_page(to);
736 set_bit(PG_arch_1, &page->flags); 754 clear_bit(PG_dc_clean, &page->flags);
737} 755}
738 756
739 757
diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c
index 689ffd86d5e9..318164cabdfc 100644
--- a/arch/arc/mm/fault.c
+++ b/arch/arc/mm/fault.c
@@ -15,6 +15,7 @@
15#include <linux/uaccess.h> 15#include <linux/uaccess.h>
16#include <linux/kdebug.h> 16#include <linux/kdebug.h>
17#include <asm/pgalloc.h> 17#include <asm/pgalloc.h>
18#include <asm/mmu.h>
18 19
19static int handle_vmalloc_fault(struct mm_struct *mm, unsigned long address) 20static int handle_vmalloc_fault(struct mm_struct *mm, unsigned long address)
20{ 21{
@@ -51,14 +52,14 @@ bad_area:
51 return 1; 52 return 1;
52} 53}
53 54
54void do_page_fault(struct pt_regs *regs, int write, unsigned long address, 55void do_page_fault(struct pt_regs *regs, unsigned long address)
55 unsigned long cause_code)
56{ 56{
57 struct vm_area_struct *vma = NULL; 57 struct vm_area_struct *vma = NULL;
58 struct task_struct *tsk = current; 58 struct task_struct *tsk = current;
59 struct mm_struct *mm = tsk->mm; 59 struct mm_struct *mm = tsk->mm;
60 siginfo_t info; 60 siginfo_t info;
61 int fault, ret; 61 int fault, ret;
62 int write = regs->ecr_cause & ECR_C_PROTV_STORE; /* ST/EX */
62 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | 63 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
63 (write ? FAULT_FLAG_WRITE : 0); 64 (write ? FAULT_FLAG_WRITE : 0);
64 65
@@ -109,7 +110,8 @@ good_area:
109 110
110 /* Handle protection violation, execute on heap or stack */ 111 /* Handle protection violation, execute on heap or stack */
111 112
112 if (cause_code == ((ECR_V_PROTV << 16) | ECR_C_PROTV_INST_FETCH)) 113 if ((regs->ecr_vec == ECR_V_PROTV) &&
114 (regs->ecr_cause == ECR_C_PROTV_INST_FETCH))
113 goto bad_area; 115 goto bad_area;
114 116
115 if (write) { 117 if (write) {
@@ -176,7 +178,6 @@ bad_area_nosemaphore:
176 /* User mode accesses just cause a SIGSEGV */ 178 /* User mode accesses just cause a SIGSEGV */
177 if (user_mode(regs)) { 179 if (user_mode(regs)) {
178 tsk->thread.fault_address = address; 180 tsk->thread.fault_address = address;
179 tsk->thread.cause_code = cause_code;
180 info.si_signo = SIGSEGV; 181 info.si_signo = SIGSEGV;
181 info.si_errno = 0; 182 info.si_errno = 0;
182 /* info.si_code has been set above */ 183 /* info.si_code has been set above */
@@ -197,7 +198,7 @@ no_context:
197 if (fixup_exception(regs)) 198 if (fixup_exception(regs))
198 return; 199 return;
199 200
200 die("Oops", regs, address, cause_code); 201 die("Oops", regs, address);
201 202
202out_of_memory: 203out_of_memory:
203 if (is_global_init(tsk)) { 204 if (is_global_init(tsk)) {
@@ -218,7 +219,6 @@ do_sigbus:
218 goto no_context; 219 goto no_context;
219 220
220 tsk->thread.fault_address = address; 221 tsk->thread.fault_address = address;
221 tsk->thread.cause_code = cause_code;
222 info.si_signo = SIGBUS; 222 info.si_signo = SIGBUS;
223 info.si_errno = 0; 223 info.si_errno = 0;
224 info.si_code = BUS_ADRERR; 224 info.si_code = BUS_ADRERR;
diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c
index 4a177365b2c4..a08ce7185423 100644
--- a/arch/arc/mm/init.c
+++ b/arch/arc/mm/init.c
@@ -74,7 +74,7 @@ void __init setup_arch_memory(void)
74 /* Last usable page of low mem (no HIGHMEM yet for ARC port) */ 74 /* Last usable page of low mem (no HIGHMEM yet for ARC port) */
75 max_low_pfn = max_pfn = PFN_DOWN(end_mem); 75 max_low_pfn = max_pfn = PFN_DOWN(end_mem);
76 76
77 max_mapnr = num_physpages = max_low_pfn - min_low_pfn; 77 max_mapnr = max_low_pfn - min_low_pfn;
78 78
79 /*------------- reserve kernel image -----------------------*/ 79 /*------------- reserve kernel image -----------------------*/
80 memblock_reserve(CONFIG_LINUX_LINK_BASE, 80 memblock_reserve(CONFIG_LINUX_LINK_BASE,
@@ -84,7 +84,7 @@ void __init setup_arch_memory(void)
84 84
85 /*-------------- node setup --------------------------------*/ 85 /*-------------- node setup --------------------------------*/
86 memset(zones_size, 0, sizeof(zones_size)); 86 memset(zones_size, 0, sizeof(zones_size));
87 zones_size[ZONE_NORMAL] = num_physpages; 87 zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn;
88 88
89 /* 89 /*
90 * We can't use the helper free_area_init(zones[]) because it uses 90 * We can't use the helper free_area_init(zones[]) because it uses
@@ -106,39 +106,9 @@ void __init setup_arch_memory(void)
106 */ 106 */
107void __init mem_init(void) 107void __init mem_init(void)
108{ 108{
109 int codesize, datasize, initsize, reserved_pages, free_pages;
110 int tmp;
111
112 high_memory = (void *)(CONFIG_LINUX_LINK_BASE + arc_mem_sz); 109 high_memory = (void *)(CONFIG_LINUX_LINK_BASE + arc_mem_sz);
113 110 free_all_bootmem();
114 totalram_pages = free_all_bootmem(); 111 mem_init_print_info(NULL);
115
116 /* count all reserved pages [kernel code/data/mem_map..] */
117 reserved_pages = 0;
118 for (tmp = 0; tmp < max_mapnr; tmp++)
119 if (PageReserved(mem_map + tmp))
120 reserved_pages++;
121
122 /* XXX: nr_free_pages() is equivalent */
123 free_pages = max_mapnr - reserved_pages;
124
125 /*
126 * For the purpose of display below, split the "reserve mem"
127 * kernel code/data is already shown explicitly,
128 * Show any other reservations (mem_map[ ] et al)
129 */
130 reserved_pages -= (((unsigned int)_end - CONFIG_LINUX_LINK_BASE) >>
131 PAGE_SHIFT);
132
133 codesize = _etext - _text;
134 datasize = _end - _etext;
135 initsize = __init_end - __init_begin;
136
137 pr_info("Memory Available: %dM / %ldM (%dK code, %dK data, %dK init, %dK reserv)\n",
138 PAGES_TO_MB(free_pages),
139 TO_MB(arc_mem_sz),
140 TO_KB(codesize), TO_KB(datasize), TO_KB(initsize),
141 PAGES_TO_KB(reserved_pages));
142} 112}
143 113
144/* 114/*
@@ -146,13 +116,13 @@ void __init mem_init(void)
146 */ 116 */
147void __init_refok free_initmem(void) 117void __init_refok free_initmem(void)
148{ 118{
149 free_initmem_default(0); 119 free_initmem_default(-1);
150} 120}
151 121
152#ifdef CONFIG_BLK_DEV_INITRD 122#ifdef CONFIG_BLK_DEV_INITRD
153void __init free_initrd_mem(unsigned long start, unsigned long end) 123void __init free_initrd_mem(unsigned long start, unsigned long end)
154{ 124{
155 free_reserved_area(start, end, 0, "initrd"); 125 free_reserved_area((void *)start, (void *)end, -1, "initrd");
156} 126}
157#endif 127#endif
158 128
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index fe1c5a073afe..7957dc4e4d4a 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -55,7 +55,7 @@
55#include <asm/arcregs.h> 55#include <asm/arcregs.h>
56#include <asm/setup.h> 56#include <asm/setup.h>
57#include <asm/mmu_context.h> 57#include <asm/mmu_context.h>
58#include <asm/tlb.h> 58#include <asm/mmu.h>
59 59
60/* Need for ARC MMU v2 60/* Need for ARC MMU v2
61 * 61 *
@@ -97,6 +97,7 @@
97 * J-TLB entry got evicted/replaced. 97 * J-TLB entry got evicted/replaced.
98 */ 98 */
99 99
100
100/* A copy of the ASID from the PID reg is kept in asid_cache */ 101/* A copy of the ASID from the PID reg is kept in asid_cache */
101int asid_cache = FIRST_ASID; 102int asid_cache = FIRST_ASID;
102 103
@@ -432,9 +433,14 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr_unaligned,
432{ 433{
433 unsigned long vaddr = vaddr_unaligned & PAGE_MASK; 434 unsigned long vaddr = vaddr_unaligned & PAGE_MASK;
434 unsigned long paddr = pte_val(*ptep) & PAGE_MASK; 435 unsigned long paddr = pte_val(*ptep) & PAGE_MASK;
436 struct page *page = pfn_to_page(pte_pfn(*ptep));
435 437
436 create_tlb(vma, vaddr, ptep); 438 create_tlb(vma, vaddr, ptep);
437 439
440 if (page == ZERO_PAGE(0)) {
441 return;
442 }
443
438 /* 444 /*
439 * Exec page : Independent of aliasing/page-color considerations, 445 * Exec page : Independent of aliasing/page-color considerations,
440 * since icache doesn't snoop dcache on ARC, any dirty 446 * since icache doesn't snoop dcache on ARC, any dirty
@@ -446,9 +452,8 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr_unaligned,
446 */ 452 */
447 if ((vma->vm_flags & VM_EXEC) || 453 if ((vma->vm_flags & VM_EXEC) ||
448 addr_not_cache_congruent(paddr, vaddr)) { 454 addr_not_cache_congruent(paddr, vaddr)) {
449 struct page *page = pfn_to_page(pte_pfn(*ptep));
450 455
451 int dirty = test_and_clear_bit(PG_arch_1, &page->flags); 456 int dirty = !test_and_set_bit(PG_dc_clean, &page->flags);
452 if (dirty) { 457 if (dirty) {
453 /* wback + inv dcache lines */ 458 /* wback + inv dcache lines */
454 __flush_dcache_page(paddr, paddr); 459 __flush_dcache_page(paddr, paddr);
@@ -464,12 +469,27 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr_unaligned,
464 * the cpuinfo structure for later use. 469 * the cpuinfo structure for later use.
465 * No Validation is done here, simply read/convert the BCRs 470 * No Validation is done here, simply read/convert the BCRs
466 */ 471 */
467void __cpuinit read_decode_mmu_bcr(void) 472void read_decode_mmu_bcr(void)
468{ 473{
469 unsigned int tmp;
470 struct bcr_mmu_1_2 *mmu2; /* encoded MMU2 attr */
471 struct bcr_mmu_3 *mmu3; /* encoded MMU3 attr */
472 struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu; 474 struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu;
475 unsigned int tmp;
476 struct bcr_mmu_1_2 {
477#ifdef CONFIG_CPU_BIG_ENDIAN
478 unsigned int ver:8, ways:4, sets:4, u_itlb:8, u_dtlb:8;
479#else
480 unsigned int u_dtlb:8, u_itlb:8, sets:4, ways:4, ver:8;
481#endif
482 } *mmu2;
483
484 struct bcr_mmu_3 {
485#ifdef CONFIG_CPU_BIG_ENDIAN
486 unsigned int ver:8, ways:4, sets:4, osm:1, reserv:3, pg_sz:4,
487 u_itlb:4, u_dtlb:4;
488#else
489 unsigned int u_dtlb:4, u_itlb:4, pg_sz:4, reserv:3, osm:1, sets:4,
490 ways:4, ver:8;
491#endif
492 } *mmu3;
473 493
474 tmp = read_aux_reg(ARC_REG_MMU_BCR); 494 tmp = read_aux_reg(ARC_REG_MMU_BCR);
475 mmu->ver = (tmp >> 24); 495 mmu->ver = (tmp >> 24);
@@ -505,12 +525,12 @@ char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len)
505 "J-TLB %d (%dx%d), uDTLB %d, uITLB %d, %s\n", 525 "J-TLB %d (%dx%d), uDTLB %d, uITLB %d, %s\n",
506 p_mmu->num_tlb, p_mmu->sets, p_mmu->ways, 526 p_mmu->num_tlb, p_mmu->sets, p_mmu->ways,
507 p_mmu->u_dtlb, p_mmu->u_itlb, 527 p_mmu->u_dtlb, p_mmu->u_itlb,
508 __CONFIG_ARC_MMU_SASID_VAL ? "SASID" : ""); 528 IS_ENABLED(CONFIG_ARC_MMU_SASID) ? "SASID" : "");
509 529
510 return buf; 530 return buf;
511} 531}
512 532
513void __cpuinit arc_mmu_init(void) 533void arc_mmu_init(void)
514{ 534{
515 char str[256]; 535 char str[256];
516 struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu; 536 struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu;
diff --git a/arch/arc/mm/tlbex.S b/arch/arc/mm/tlbex.S
index 3357d26ffe54..5c5bb23001b0 100644
--- a/arch/arc/mm/tlbex.S
+++ b/arch/arc/mm/tlbex.S
@@ -39,7 +39,7 @@
39 39
40#include <linux/linkage.h> 40#include <linux/linkage.h>
41#include <asm/entry.h> 41#include <asm/entry.h>
42#include <asm/tlb.h> 42#include <asm/mmu.h>
43#include <asm/pgtable.h> 43#include <asm/pgtable.h>
44#include <asm/arcregs.h> 44#include <asm/arcregs.h>
45#include <asm/cache.h> 45#include <asm/cache.h>
@@ -147,9 +147,9 @@ ex_saved_reg1:
147#ifdef CONFIG_ARC_DBG_TLB_MISS_COUNT 147#ifdef CONFIG_ARC_DBG_TLB_MISS_COUNT
148 and.f 0, r0, _PAGE_PRESENT 148 and.f 0, r0, _PAGE_PRESENT
149 bz 1f 149 bz 1f
150 ld r2, [num_pte_not_present] 150 ld r3, [num_pte_not_present]
151 add r2, r2, 1 151 add r3, r3, 1
152 st r2, [num_pte_not_present] 152 st r3, [num_pte_not_present]
1531: 1531:
154#endif 154#endif
155 155
@@ -271,22 +271,22 @@ ARC_ENTRY EV_TLBMissI
271#endif 271#endif
272 272
273 ;---------------------------------------------------------------- 273 ;----------------------------------------------------------------
274 ; Get the PTE corresponding to V-addr accessed 274 ; Get the PTE corresponding to V-addr accessed, r2 is setup with EFA
275 LOAD_FAULT_PTE 275 LOAD_FAULT_PTE
276 276
277 ;---------------------------------------------------------------- 277 ;----------------------------------------------------------------
278 ; VERIFY_PTE: Check if PTE permissions approp for executing code 278 ; VERIFY_PTE: Check if PTE permissions approp for executing code
279 cmp_s r2, VMALLOC_START 279 cmp_s r2, VMALLOC_START
280 mov.lo r2, (_PAGE_PRESENT | _PAGE_U_READ | _PAGE_U_EXECUTE) 280 mov.lo r2, (_PAGE_PRESENT | _PAGE_U_EXECUTE)
281 mov.hs r2, (_PAGE_PRESENT | _PAGE_K_READ | _PAGE_K_EXECUTE) 281 mov.hs r2, (_PAGE_PRESENT | _PAGE_K_EXECUTE)
282 282
283 and r3, r0, r2 ; Mask out NON Flag bits from PTE 283 and r3, r0, r2 ; Mask out NON Flag bits from PTE
284 xor.f r3, r3, r2 ; check ( ( pte & flags_test ) == flags_test ) 284 xor.f r3, r3, r2 ; check ( ( pte & flags_test ) == flags_test )
285 bnz do_slow_path_pf 285 bnz do_slow_path_pf
286 286
287 ; Let Linux VM know that the page was accessed 287 ; Let Linux VM know that the page was accessed
288 or r0, r0, (_PAGE_PRESENT | _PAGE_ACCESSED) ; set Accessed Bit 288 or r0, r0, _PAGE_ACCESSED ; set Accessed Bit
289 st_s r0, [r1] ; Write back PTE 289 st_s r0, [r1] ; Write back PTE
290 290
291 CONV_PTE_TO_TLB 291 CONV_PTE_TO_TLB
292 COMMIT_ENTRY_TO_MMU 292 COMMIT_ENTRY_TO_MMU
@@ -311,7 +311,7 @@ ARC_ENTRY EV_TLBMissD
311 311
312 ;---------------------------------------------------------------- 312 ;----------------------------------------------------------------
313 ; Get the PTE corresponding to V-addr accessed 313 ; Get the PTE corresponding to V-addr accessed
314 ; If PTE exists, it will setup, r0 = PTE, r1 = Ptr to PTE 314 ; If PTE exists, it will setup, r0 = PTE, r1 = Ptr to PTE, r2 = EFA
315 LOAD_FAULT_PTE 315 LOAD_FAULT_PTE
316 316
317 ;---------------------------------------------------------------- 317 ;----------------------------------------------------------------
@@ -345,7 +345,7 @@ ARC_ENTRY EV_TLBMissD
345 ;---------------------------------------------------------------- 345 ;----------------------------------------------------------------
346 ; UPDATE_PTE: Let Linux VM know that page was accessed/dirty 346 ; UPDATE_PTE: Let Linux VM know that page was accessed/dirty
347 lr r3, [ecr] 347 lr r3, [ecr]
348 or r0, r0, (_PAGE_PRESENT | _PAGE_ACCESSED) ; Accessed bit always 348 or r0, r0, _PAGE_ACCESSED ; Accessed bit always
349 btst_s r3, ECR_C_BIT_DTLB_ST_MISS ; See if it was a Write Access ? 349 btst_s r3, ECR_C_BIT_DTLB_ST_MISS ; See if it was a Write Access ?
350 or.nz r0, r0, _PAGE_MODIFIED ; if Write, set Dirty bit as well 350 or.nz r0, r0, _PAGE_MODIFIED ; if Write, set Dirty bit as well
351 st_s r0, [r1] ; Write back PTE 351 st_s r0, [r1] ; Write back PTE
@@ -381,18 +381,7 @@ do_slow_path_pf:
381 381
382 ; ------- setup args for Linux Page fault Hanlder --------- 382 ; ------- setup args for Linux Page fault Hanlder ---------
383 mov_s r0, sp 383 mov_s r0, sp
384 lr r2, [efa] 384 lr r1, [efa]
385 lr r3, [ecr]
386
387 ; Both st and ex imply WRITE access of some sort, hence do_page_fault( )
388 ; invoked with write=1 for DTLB-st/ex Miss and write=0 for ITLB miss or
389 ; DTLB-ld Miss
390 ; DTLB Miss Cause code is ld = 0x01 , st = 0x02, ex = 0x03
391 ; Following code uses that fact that st/ex have one bit in common
392
393 btst_s r3, ECR_C_BIT_DTLB_ST_MISS
394 mov.z r1, 0
395 mov.nz r1, 1
396 385
397 ; We don't want exceptions to be disabled while the fault is handled. 386 ; We don't want exceptions to be disabled while the fault is handled.
398 ; Now that we have saved the context we return from exception hence 387 ; Now that we have saved the context we return from exception hence
diff --git a/arch/arc/plat-arcfpga/platform.c b/arch/arc/plat-arcfpga/platform.c
index b3700c064c06..d71f3c3bcf24 100644
--- a/arch/arc/plat-arcfpga/platform.c
+++ b/arch/arc/plat-arcfpga/platform.c
@@ -77,6 +77,7 @@ static void __init setup_bvci_lat_unit(void)
77 77
78/*----------------------- Platform Devices -----------------------------*/ 78/*----------------------- Platform Devices -----------------------------*/
79 79
80#if IS_ENABLED(CONFIG_SERIAL_ARC)
80static unsigned long arc_uart_info[] = { 81static unsigned long arc_uart_info[] = {
81 0, /* uart->is_emulated (runtime @running_on_hw) */ 82 0, /* uart->is_emulated (runtime @running_on_hw) */
82 0, /* uart->port.uartclk */ 83 0, /* uart->port.uartclk */
@@ -115,7 +116,7 @@ static struct platform_device arc_uart0_dev = {
115static struct platform_device *fpga_early_devs[] __initdata = { 116static struct platform_device *fpga_early_devs[] __initdata = {
116 &arc_uart0_dev, 117 &arc_uart0_dev,
117}; 118};
118#endif 119#endif /* CONFIG_SERIAL_ARC_CONSOLE */
119 120
120static void arc_fpga_serial_init(void) 121static void arc_fpga_serial_init(void)
121{ 122{
@@ -152,8 +153,13 @@ static void arc_fpga_serial_init(void)
152 * otherwise the early console never gets a chance to run. 153 * otherwise the early console never gets a chance to run.
153 */ 154 */
154 add_preferred_console("ttyARC", 0, "115200"); 155 add_preferred_console("ttyARC", 0, "115200");
155#endif 156#endif /* CONFIG_SERIAL_ARC_CONSOLE */
157}
158#else /* !IS_ENABLED(CONFIG_SERIAL_ARC) */
159static void arc_fpga_serial_init(void)
160{
156} 161}
162#endif
157 163
158static void __init plat_fpga_early_init(void) 164static void __init plat_fpga_early_init(void)
159{ 165{
@@ -169,7 +175,7 @@ static void __init plat_fpga_early_init(void)
169} 175}
170 176
171static struct of_dev_auxdata plat_auxdata_lookup[] __initdata = { 177static struct of_dev_auxdata plat_auxdata_lookup[] __initdata = {
172#if defined(CONFIG_SERIAL_ARC) || defined(CONFIG_SERIAL_ARC_MODULE) 178#if IS_ENABLED(CONFIG_SERIAL_ARC)
173 OF_DEV_AUXDATA("snps,arc-uart", UART0_BASE, "arc-uart", arc_uart_info), 179 OF_DEV_AUXDATA("snps,arc-uart", UART0_BASE, "arc-uart", arc_uart_info),
174#endif 180#endif
175 {} 181 {}