diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-03 14:09:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-03 14:09:27 -0400 |
commit | 76d3f4c27d3c2c85e5cfe731537b6929145bf652 (patch) | |
tree | 80d6dd04ad832122f69edaad710252d771e39c1b /arch/arc | |
parent | c1101cbc7db316dcdc94d344727fd372622d0ce7 (diff) | |
parent | baadb8fd0c62540f2ffb2d0f12b8a47c7975562b (diff) |
Merge tag 'arc-v3.11-rc1-part1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc
Pull first batch of ARC changes from Vineet Gupta:
"There's a second bunch to follow next week - which depends on commits
on other trees (irq/net). I'd have preferred the accompanying ARC
change via respective trees, but it didn't workout somehow.
Highlights of changes:
- Continuation of ARC MM changes from 3.10 including
zero page optimization
Setting pagecache pages dirty by default
Non executable stack by default
Reducing dcache flushes for aliasing VIPT config
- Long overdue rework of pt_regs machinery - removing the unused word
gutters and adding ECR register to baseline (helps cleanup lot of
low level code)
- Support for ARC gcc 4.8
- Few other preventive fixes, cosmetics, usage of Kconfig helper..
The diffstat is larger than normal primarily because of arcregs.h
header split as well as beautification of macros in entry.h"
* tag 'arc-v3.11-rc1-part1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc: (32 commits)
ARC: warn on improper stack unwind FDE entries
arc: delete __cpuinit usage from all arc files
ARC: [tlb-miss] Fix bug with CONFIG_ARC_DBG_TLB_MISS_COUNT
ARC: [tlb-miss] Extraneous PTE bit testing/setting
ARC: Adjustments for gcc 4.8
ARC: Setup Vector Table Base in early boot
ARC: Remove explicit passing around of ECR
ARC: pt_regs update #5: Use real ECR for pt_regs->event vs. synth values
ARC: stop using pt_regs->orig_r8
ARC: pt_regs update #4: r25 saved/restored unconditionally
ARC: K/U SP saved from one location in stack switching macro
ARC: Entry Handler tweaks: Simplify branch for in-kernel preemption
ARC: Entry Handler tweaks: Avoid hardcoded LIMMS for ECR values
ARC: Increase readability of entry handlers
ARC: pt_regs update #3: Remove unused gutter at start of callee_regs
ARC: pt_regs update #2: Remove unused gutter at start of pt_regs
ARC: pt_regs update #1: Align pt_regs end with end of kernel stack page
ARC: pt_regs update #0: remove kernel stack canary
ARC: [mm] Remove @write argument to do_page_fault()
ARC: [mm] Make stack/heap Non-executable by default
...
Diffstat (limited to 'arch/arc')
48 files changed, 670 insertions, 876 deletions
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 5917099470ea..4a0e54fc01b2 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig | |||
@@ -184,6 +184,7 @@ config ARC_CACHE_PAGES | |||
184 | 184 | ||
185 | config ARC_CACHE_VIPT_ALIASING | 185 | config ARC_CACHE_VIPT_ALIASING |
186 | bool "Support VIPT Aliasing D$" | 186 | bool "Support VIPT Aliasing D$" |
187 | depends on ARC_HAS_DCACHE | ||
187 | default n | 188 | default n |
188 | 189 | ||
189 | endif #ARC_CACHE | 190 | endif #ARC_CACHE |
@@ -361,13 +362,6 @@ config ARC_MISALIGN_ACCESS | |||
361 | Use ONLY-IF-ABS-NECESSARY as it will be very slow and also can hide | 362 | Use ONLY-IF-ABS-NECESSARY as it will be very slow and also can hide |
362 | potential bugs in code | 363 | potential bugs in code |
363 | 364 | ||
364 | config 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 | |||
371 | config HZ | 365 | config HZ |
372 | int "Timer Frequency" | 366 | int "Timer Frequency" |
373 | default 100 | 367 | default 100 |
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 @@ | |||
9 | UTS_MACHINE := arc | 9 | UTS_MACHINE := arc |
10 | 10 | ||
11 | ifeq ($(CROSS_COMPILE),) | 11 | ifeq ($(CROSS_COMPILE),) |
12 | CROSS_COMPILE := arc-elf32- | 12 | CROSS_COMPILE := arc-linux-uclibc- |
13 | endif | 13 | endif |
14 | 14 | ||
15 | KBUILD_DEFCONFIG := fpga_defconfig | 15 | KBUILD_DEFCONFIG := fpga_defconfig |
16 | 16 | ||
17 | cflags-y += -mA7 -fno-common -pipe -fno-builtin -D__linux__ | 17 | cflags-y += -mA7 -fno-common -pipe -fno-builtin -D__linux__ |
18 | 18 | ||
19 | LINUXINCLUDE += -include ${src}/arch/arc/include/asm/defines.h | ||
20 | |||
21 | ifdef CONFIG_ARC_CURR_IN_REG | 19 | ifdef 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> |
27 | LINUXINCLUDE += -include ${src}/arch/arc/include/asm/current.h | 25 | LINUXINCLUDE += -include ${src}/arch/arc/include/asm/current.h |
28 | endif | 26 | endif |
29 | 27 | ||
30 | atleast_gcc44 := $(call cc-ifversion, -gt, 0402, y) | 28 | upto_gcc42 := $(call cc-ifversion, -le, 0402, y) |
29 | upto_gcc44 := $(call cc-ifversion, -le, 0404, y) | ||
30 | atleast_gcc44 := $(call cc-ifversion, -ge, 0404, y) | ||
31 | atleast_gcc48 := $(call cc-ifversion, -ge, 0408, y) | ||
32 | |||
31 | cflags-$(atleast_gcc44) += -fsection-anchors | 33 | cflags-$(atleast_gcc44) += -fsection-anchors |
32 | 34 | ||
33 | cflags-$(CONFIG_ARC_HAS_LLSC) += -mlock | 35 | cflags-$(CONFIG_ARC_HAS_LLSC) += -mlock |
@@ -35,6 +37,11 @@ cflags-$(CONFIG_ARC_HAS_SWAPE) += -mswape | |||
35 | cflags-$(CONFIG_ARC_HAS_RTSC) += -mrtsc | 37 | cflags-$(CONFIG_ARC_HAS_RTSC) += -mrtsc |
36 | cflags-$(CONFIG_ARC_DW2_UNWIND) += -fasynchronous-unwind-tables | 38 | cflags-$(CONFIG_ARC_DW2_UNWIND) += -fasynchronous-unwind-tables |
37 | 39 | ||
40 | # By default gcc 4.8 generates dwarf4 which kernel unwinder can't grok | ||
41 | ifeq ($(atleast_gcc48),y) | ||
42 | cflags-$(CONFIG_ARC_DW2_UNWIND) += -gdwarf-2 | ||
43 | endif | ||
44 | |||
38 | ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE | 45 | ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE |
39 | # Generic build system uses -O2, we want -O3 | 46 | # Generic build system uses -O2, we want -O3 |
40 | cflags-y += -O3 | 47 | cflags-y += -O3 |
@@ -48,11 +55,10 @@ cflags-$(disable_small_data) += -mno-sdata -fcall-used-gp | |||
48 | cflags-$(CONFIG_CPU_BIG_ENDIAN) += -mbig-endian | 55 | cflags-$(CONFIG_CPU_BIG_ENDIAN) += -mbig-endian |
49 | ldflags-$(CONFIG_CPU_BIG_ENDIAN) += -EB | 56 | ldflags-$(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 | 61 | ldflags-$(upto_gcc44) += -marclinux |
55 | ldflags-y += -marclinux | ||
56 | 62 | ||
57 | ARC_LIBGCC := -mA7 | 63 | ARC_LIBGCC := -mA7 |
58 | cflags-$(CONFIG_ARC_HAS_HW_MPY) += -multcost=16 | 64 | cflags-$(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 |
73 | endif | 79 | endif |
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 @@ | |||
1 | CONFIG_CROSS_COMPILE="arc-elf32-" | 1 | CONFIG_CROSS_COMPILE="arc-linux-uclibc-" |
2 | # CONFIG_LOCALVERSION_AUTO is not set | 2 | # CONFIG_LOCALVERSION_AUTO is not set |
3 | CONFIG_DEFAULT_HOSTNAME="ARCLinux" | 3 | CONFIG_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 @@ | |||
1 | CONFIG_CROSS_COMPILE="arc-elf32-" | 1 | CONFIG_CROSS_COMPILE="arc-linux-uclibc-" |
2 | # CONFIG_LOCALVERSION_AUTO is not set | 2 | # CONFIG_LOCALVERSION_AUTO is not set |
3 | CONFIG_DEFAULT_HOSTNAME="ARCLinux" | 3 | CONFIG_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 @@ | |||
1 | CONFIG_CROSS_COMPILE="arc-elf32-" | 1 | CONFIG_CROSS_COMPILE="arc-linux-uclibc-" |
2 | # CONFIG_LOCALVERSION_AUTO is not set | 2 | # CONFIG_LOCALVERSION_AUTO is not set |
3 | CONFIG_DEFAULT_HOSTNAME="tb10x" | 3 | CONFIG_DEFAULT_HOSTNAME="tb10x" |
4 | CONFIG_SYSVIPC=y | 4 | CONFIG_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 | ||
296 | struct 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 | |||
304 | struct 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 | ||
346 | struct 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 | |||
354 | struct bcr_perip { | 247 | struct 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 | ||
405 | struct cpuinfo_arc_cache { | 298 | struct 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 | ||
409 | struct cpuinfo_arc_ccm { | 302 | struct 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; | |||
18 | void show_regs(struct pt_regs *regs); | 18 | void show_regs(struct pt_regs *regs); |
19 | void show_stacktrace(struct task_struct *tsk, struct pt_regs *regs); | 19 | void show_stacktrace(struct task_struct *tsk, struct pt_regs *regs); |
20 | void show_kernel_fault_diag(const char *str, struct pt_regs *regs, | 20 | void show_kernel_fault_diag(const char *str, struct pt_regs *regs, |
21 | unsigned long address, unsigned long cause_reg); | 21 | unsigned long address); |
22 | void die(const char *str, struct pt_regs *regs, unsigned long address, | 22 | void 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 | |||
67 | extern void arc_cache_init(void); | 58 | extern void arc_cache_init(void); |
68 | extern char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len); | 59 | extern char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len); |
69 | extern void __init read_decode_cache_bcr(void); | 60 | extern 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 | */ |
87 | static inline int cache_is_vipt_aliasing(void) | 94 | static 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 | ||
312 | 88: /*------Intr/Ecxp happened in user mode, "switch" stack ------ */ | 294 | 88: /*------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 | 301 | 66: |
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 | ||
345 | 77: /* ----- 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 @@ | |||
21 | extern void __init arc_init_IRQ(void); | 21 | extern void __init arc_init_IRQ(void); |
22 | extern int __init get_hw_config_num_irq(void); | 22 | extern int __init get_hw_config_num_irq(void); |
23 | 23 | ||
24 | void __cpuinit arc_local_timer_setup(unsigned int cpu); | 24 | void 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 | ||
34 | extern void kgdb_trap(struct pt_regs *regs, int param); | 34 | extern void kgdb_trap(struct pt_regs *regs); |
35 | 35 | ||
36 | enum arc700_linux_regnums { | 36 | enum 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 | ||
51 | int kprobe_fault_handler(struct pt_regs *regs, unsigned long cause); | 51 | int kprobe_fault_handler(struct pt_regs *regs, unsigned long cause); |
52 | void kretprobe_trampoline(void); | 52 | void kretprobe_trampoline(void); |
53 | void trap_is_kprobe(unsigned long cause, unsigned long address, | 53 | void trap_is_kprobe(unsigned long address, struct pt_regs *regs); |
54 | struct pt_regs *regs); | ||
55 | #else | 54 | #else |
56 | static void trap_is_kprobe(unsigned long cause, unsigned long address, | 55 | static 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 | ||
14 | typedef struct { | 48 | typedef 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 | ||
56 | void 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 | ||
61 | void arc_mmu_init(void); | ||
62 | extern char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len); | ||
63 | void __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 c110ac87d22b..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 | * |
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; | |||
50 | unsigned long thread_saved_pc(struct task_struct *t); | 47 | unsigned 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 | ||
19 | struct pt_regs { | 19 | struct 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 | ||
67 | struct callee_regs { | 72 | struct 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 | ||
116 | static inline long regs_return_value(struct pt_regs *regs) | 122 | static 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 | |||
18 | syscall_get_nr(struct task_struct *task, struct pt_regs *regs) | 18 | syscall_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) | |||
26 | static inline void | 26 | static inline void |
27 | syscall_rollback(struct task_struct *task, struct pt_regs *regs) | 27 | syscall_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 | ||
33 | static inline long | 32 | static 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) \ |
25 | do { \ | 13 | do { \ |
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 | ||
60 | void tlb_paranoid_check(unsigned int pid_sw, unsigned long address); | ||
61 | #else | ||
62 | #define tlb_paranoid_check(a, b) | ||
63 | #endif | ||
64 | |||
65 | void arc_mmu_init(void); | ||
66 | extern char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len); | ||
67 | void __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 |
18 | int misaligned_fixup(unsigned long address, struct pt_regs *regs, | 18 | int 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 |
21 | static inline int | 21 | static inline int |
22 | misaligned_fixup(unsigned long address, struct pt_regs *regs, | 22 | misaligned_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 | */ |
29 | struct user_regs_struct { | 32 | struct 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 |
306 | ARC_EXIT mem_service | 303 | ARC_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 ============ |
388 | 4: | 383 | 4: |
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 |
448 | ARC_EXIT EV_Extension | 440 | ARC_EXIT EV_Extension |
@@ -498,11 +490,8 @@ tracesys_exit: | |||
498 | trap_with_param: | 490 | trap_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 | |||
658 | resume_kernel_mode: | 641 | resume_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 | ||
698 | 8: | ||
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 | */ |
31 | void __cpuinit arc_init_IRQ(void) | 31 | void 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 | ||
172 | void kgdb_trap(struct pt_regs *regs, int param) | 172 | void 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 | ||
520 | void trap_is_kprobe(unsigned long cause, unsigned long address, | 520 | void 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 | */ |
82 | int copy_thread(unsigned long clone_flags, | 83 | int 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 @@ | |||
31 | int running_on_hw = 1; /* vs. on ISS */ | 31 | int running_on_hw = 1; /* vs. on ISS */ |
32 | 32 | ||
33 | char __initdata command_line[COMMAND_LINE_SIZE]; | 33 | char __initdata command_line[COMMAND_LINE_SIZE]; |
34 | struct machine_desc *machine_desc __cpuinitdata; | 34 | struct machine_desc *machine_desc; |
35 | 35 | ||
36 | struct task_struct *_current_task[NR_CPUS]; /* For stack switching */ | 36 | struct task_struct *_current_task[NR_CPUS]; /* For stack switching */ |
37 | 37 | ||
38 | struct cpuinfo_arc cpuinfo_arc700[NR_CPUS]; | 38 | struct cpuinfo_arc cpuinfo_arc700[NR_CPUS]; |
39 | 39 | ||
40 | 40 | ||
41 | void __cpuinit read_arc_build_cfg_regs(void) | 41 | void 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 | ||
240 | void __cpuinit arc_chk_ccms(void) | 240 | void 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 | */ |
275 | void __cpuinit arc_chk_fpu(void) | 275 | void 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 | ||
296 | void __cpuinit setup_processor(void) | 296 | void 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 | */ |
120 | void __cpuinit start_kernel_secondary(void) | 120 | void 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 | */ |
157 | int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle) | 157 | int __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 | ||
53 | int __cpuinit arc_counter_setup(void) | 64 | int 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 | */ |
108 | int __cpuinit arc_counter_setup(void) | 119 | int 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 | */ |
215 | void __attribute__((weak)) __cpuinit arc_local_timer_setup(unsigned int cpu) | 226 | void __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 | ||
31 | void die(const char *str, struct pt_regs *regs, unsigned long address, | 31 | void 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 | */ |
45 | static noinline int handle_exception(unsigned long cause, char *str, | 44 | static noinline int |
46 | struct pt_regs *regs, siginfo_t *info) | 45 | handle_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) \ |
68 | int name(unsigned long cause, unsigned long address, struct pt_regs *regs) \ | 66 | int 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 | */ |
93 | int do_misaligned_access(unsigned long cause, unsigned long address, | 91 | int 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 | */ |
107 | void do_machine_check_fault(unsigned long cause, unsigned long address, | 105 | void 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 | */ |
123 | void do_non_swi_trap(unsigned long cause, unsigned long address, | 120 | void 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 | */ |
152 | void do_insterror_or_kprobe(unsigned long cause, | 148 | void 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 a03528ecd276..73a7450ee622 100644 --- a/arch/arc/kernel/troubleshoot.c +++ b/arch/arc/kernel/troubleshoot.c | |||
@@ -117,23 +117,22 @@ static void show_faulting_vma(unsigned long address, char *buf) | |||
117 | 117 | ||
118 | static void show_ecr_verbose(struct pt_regs *regs) | 118 | static 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 | ||
215 | void show_kernel_fault_diag(const char *str, struct pt_regs *regs, | 211 | void 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 | */ |
189 | int misaligned_fixup(unsigned long address, struct pt_regs *regs, | 189 | int 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 | |||
76 | char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len) | 103 | char *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 | */ |
103 | void __cpuinit read_decode_cache_bcr(void) | 132 | void 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 | */ |
135 | void __cpuinit arc_cache_init(void) | 170 | void 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 | */ |
240 | static inline void __dc_entire_op(const int cacheop) | 262 | static 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 | ||
480 | static 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 | ||
632 | void 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 | |||
645 | noinline void flush_cache_all(void) | 657 | noinline 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 | ||
673 | void flush_cache_range(struct vm_area_struct *vma, unsigned long start, | 690 | void 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 | ||
733 | void clear_user_page(void *to, unsigned long u_vaddr, struct page *page) | 751 | void 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 | ||
19 | static int handle_vmalloc_fault(struct mm_struct *mm, unsigned long address) | 20 | static 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 | ||
54 | void do_page_fault(struct pt_regs *regs, int write, unsigned long address, | 55 | void 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 | ||
202 | out_of_memory: | 203 | out_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/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 */ |
101 | int asid_cache = FIRST_ASID; | 102 | int 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 | */ |
467 | void __cpuinit read_decode_mmu_bcr(void) | 472 | void 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 | ||
513 | void __cpuinit arc_mmu_init(void) | 533 | void 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] |
153 | 1: | 153 | 1: |
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) | ||
80 | static unsigned long arc_uart_info[] = { | 81 | static 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 = { | |||
115 | static struct platform_device *fpga_early_devs[] __initdata = { | 116 | static 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 | ||
120 | static void arc_fpga_serial_init(void) | 121 | static 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) */ | ||
159 | static void arc_fpga_serial_init(void) | ||
160 | { | ||
156 | } | 161 | } |
162 | #endif | ||
157 | 163 | ||
158 | static void __init plat_fpga_early_init(void) | 164 | static 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 | ||
171 | static struct of_dev_auxdata plat_auxdata_lookup[] __initdata = { | 177 | static 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 | {} |