diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2013-05-13 09:00:41 -0400 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2015-06-22 04:36:55 -0400 |
commit | 1f6ccfff6314672743ad7252160654709e997a2a (patch) | |
tree | f2027c01b8d010b9d1aaa3685c7c4d0644271f53 | |
parent | 820970a5aa3c98be26e1df64da4b93294d20d4e7 (diff) |
ARCv2: Support for ARCv2 ISA and HS38x cores
The notable features are:
- SMP configurations of upto 4 cores with coherency
- Optional L2 Cache and IO-Coherency
- Revised Interrupt Architecture (multiple priorites, reg banks,
auto stack switch, auto regfile save/restore)
- MMUv4 (PIPT dcache, Huge Pages)
- Instructions for
* 64bit load/store: LDD, STD
* Hardware assisted divide/remainder: DIV, REM
* Function prologue/epilogue: ENTER_S, LEAVE_S
* IRQ enable/disable: CLRI, SETI
* pop count: FFS, FLS
* SETcc, BMSKN, XBFU...
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
-rw-r--r-- | arch/arc/Kconfig | 80 | ||||
-rw-r--r-- | arch/arc/Makefile | 8 | ||||
-rw-r--r-- | arch/arc/include/asm/arcregs.h | 53 | ||||
-rw-r--r-- | arch/arc/include/asm/bitops.h | 71 | ||||
-rw-r--r-- | arch/arc/include/asm/elf.h | 5 | ||||
-rw-r--r-- | arch/arc/include/asm/entry-arcv2.h | 190 | ||||
-rw-r--r-- | arch/arc/include/asm/entry.h | 4 | ||||
-rw-r--r-- | arch/arc/include/asm/irq.h | 5 | ||||
-rw-r--r-- | arch/arc/include/asm/irqflags-arcv2.h | 3 | ||||
-rw-r--r-- | arch/arc/include/asm/irqflags-compact.h | 2 | ||||
-rw-r--r-- | arch/arc/include/asm/irqflags.h | 4 | ||||
-rw-r--r-- | arch/arc/include/asm/ptrace.h | 43 | ||||
-rw-r--r-- | arch/arc/include/asm/thread_info.h | 1 | ||||
-rw-r--r-- | arch/arc/kernel/Makefile | 3 | ||||
-rw-r--r-- | arch/arc/kernel/entry-arcv2.S | 189 | ||||
-rw-r--r-- | arch/arc/kernel/head.S | 2 | ||||
-rw-r--r-- | arch/arc/kernel/process.c | 19 | ||||
-rw-r--r-- | arch/arc/kernel/ptrace.c | 2 | ||||
-rw-r--r-- | arch/arc/kernel/setup.c | 45 | ||||
-rw-r--r-- | arch/arc/kernel/signal.c | 6 | ||||
-rw-r--r-- | arch/arc/kernel/troubleshoot.c | 33 | ||||
-rw-r--r-- | arch/arc/mm/tlbex.S | 2 |
22 files changed, 737 insertions, 33 deletions
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 1eeefd9763d1..f72398847b5b 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig | |||
@@ -88,11 +88,31 @@ source "arch/arc/plat-axs10x/Kconfig" | |||
88 | 88 | ||
89 | endmenu | 89 | endmenu |
90 | 90 | ||
91 | choice | ||
92 | prompt "ARC Instruction Set" | ||
93 | default ISA_ARCOMPACT | ||
94 | |||
95 | config ISA_ARCOMPACT | ||
96 | bool "ARCompact ISA" | ||
97 | help | ||
98 | The original ARC ISA of ARC600/700 cores | ||
99 | |||
100 | ### For bisectability, disable ARCv2 support until we have all the bits in place | ||
101 | #config ISA_ARCV2 | ||
102 | # bool "ARC ISA v2" | ||
103 | # help | ||
104 | # ISA for the Next Generation ARC-HS cores | ||
105 | |||
106 | endchoice | ||
107 | |||
91 | menu "ARC CPU Configuration" | 108 | menu "ARC CPU Configuration" |
92 | 109 | ||
93 | choice | 110 | choice |
94 | prompt "ARC Core" | 111 | prompt "ARC Core" |
95 | default ARC_CPU_770 | 112 | default ARC_CPU_770 if ISA_ARCOMPACT |
113 | default ARC_CPU_HS if ISA_ARCV2 | ||
114 | |||
115 | if ISA_ARCOMPACT | ||
96 | 116 | ||
97 | config ARC_CPU_750D | 117 | config ARC_CPU_750D |
98 | bool "ARC750D" | 118 | bool "ARC750D" |
@@ -110,6 +130,27 @@ config ARC_CPU_770 | |||
110 | -Caches: New Prog Model, Region Flush | 130 | -Caches: New Prog Model, Region Flush |
111 | -Insns: endian swap, load-locked/store-conditional, time-stamp-ctr | 131 | -Insns: endian swap, load-locked/store-conditional, time-stamp-ctr |
112 | 132 | ||
133 | endif #ISA_ARCOMPACT | ||
134 | |||
135 | config ARC_CPU_HS | ||
136 | bool "ARC-HS" | ||
137 | depends on ISA_ARCV2 | ||
138 | help | ||
139 | Support for ARC HS38x Cores based on ARCv2 ISA | ||
140 | The notable features are: | ||
141 | - SMP configurations of upto 4 core with coherency | ||
142 | - Optional L2 Cache and IO-Coherency | ||
143 | - Revised Interrupt Architecture (multiple priorites, reg banks, | ||
144 | auto stack switch, auto regfile save/restore) | ||
145 | - MMUv4 (PIPT dcache, Huge Pages) | ||
146 | - Instructions for | ||
147 | * 64bit load/store: LDD, STD | ||
148 | * Hardware assisted divide/remainder: DIV, REM | ||
149 | * Function prologue/epilogue: ENTER_S, LEAVE_S | ||
150 | * IRQ enable/disable: CLRI, SETI | ||
151 | * pop count: FFS, FLS | ||
152 | * SETcc, BMSKN, XBFU... | ||
153 | |||
113 | endchoice | 154 | endchoice |
114 | 155 | ||
115 | config CPU_BIG_ENDIAN | 156 | config CPU_BIG_ENDIAN |
@@ -134,7 +175,7 @@ config ARC_HAS_COH_CACHES | |||
134 | config ARC_HAS_REENTRANT_IRQ_LV2 | 175 | config ARC_HAS_REENTRANT_IRQ_LV2 |
135 | def_bool n | 176 | def_bool n |
136 | 177 | ||
137 | endif | 178 | endif #SMP |
138 | 179 | ||
139 | config NR_CPUS | 180 | config NR_CPUS |
140 | int "Maximum number of CPUs (2-4096)" | 181 | int "Maximum number of CPUs (2-4096)" |
@@ -223,7 +264,7 @@ config ARC_HAS_HW_MPY | |||
223 | Multipler. Otherwise software multipy lib is used | 264 | Multipler. Otherwise software multipy lib is used |
224 | 265 | ||
225 | choice | 266 | choice |
226 | prompt "ARC700 MMU Version" | 267 | prompt "MMU Version" |
227 | default ARC_MMU_V3 if ARC_CPU_770 | 268 | default ARC_MMU_V3 if ARC_CPU_770 |
228 | default ARC_MMU_V2 if ARC_CPU_750D | 269 | default ARC_MMU_V2 if ARC_CPU_750D |
229 | 270 | ||
@@ -268,6 +309,8 @@ config ARC_PAGE_SIZE_4K | |||
268 | 309 | ||
269 | endchoice | 310 | endchoice |
270 | 311 | ||
312 | if ISA_ARCOMPACT | ||
313 | |||
271 | config ARC_COMPACT_IRQ_LEVELS | 314 | config ARC_COMPACT_IRQ_LEVELS |
272 | bool "ARCompact IRQ Priorities: High(2)/Low(1)" | 315 | bool "ARCompact IRQ Priorities: High(2)/Low(1)" |
273 | default n | 316 | default n |
@@ -287,7 +330,7 @@ config ARC_IRQ5_LV2 | |||
287 | config ARC_IRQ6_LV2 | 330 | config ARC_IRQ6_LV2 |
288 | bool | 331 | bool |
289 | 332 | ||
290 | endif | 333 | endif #ARC_COMPACT_IRQ_LEVELS |
291 | 334 | ||
292 | config ARC_FPU_SAVE_RESTORE | 335 | config ARC_FPU_SAVE_RESTORE |
293 | bool "Enable FPU state persistence across context switch" | 336 | bool "Enable FPU state persistence across context switch" |
@@ -300,18 +343,43 @@ config ARC_FPU_SAVE_RESTORE | |||
300 | based on actual usage of FPU by a task. Thus our implemn does | 343 | based on actual usage of FPU by a task. Thus our implemn does |
301 | this for all tasks in system. | 344 | this for all tasks in system. |
302 | 345 | ||
346 | endif #ISA_ARCOMPACT | ||
347 | |||
303 | config ARC_CANT_LLSC | 348 | config ARC_CANT_LLSC |
304 | def_bool n | 349 | def_bool n |
305 | 350 | ||
306 | config ARC_HAS_LLSC | 351 | config ARC_HAS_LLSC |
307 | bool "Insn: LLOCK/SCOND (efficient atomic ops)" | 352 | bool "Insn: LLOCK/SCOND (efficient atomic ops)" |
308 | default y | 353 | default y |
309 | depends on ARC_CPU_770 && !ARC_CANT_LLSC | 354 | depends on !ARC_CPU_750D && !ARC_CANT_LLSC |
310 | 355 | ||
311 | config ARC_HAS_SWAPE | 356 | config ARC_HAS_SWAPE |
312 | bool "Insn: SWAPE (endian-swap)" | 357 | bool "Insn: SWAPE (endian-swap)" |
313 | default y | 358 | default y |
314 | 359 | ||
360 | if ISA_ARCV2 | ||
361 | |||
362 | config ARC_HAS_LL64 | ||
363 | bool "Insn: 64bit LDD/STD" | ||
364 | help | ||
365 | Enable gcc to generate 64-bit load/store instructions | ||
366 | ISA mandates even/odd registers to allow encoding of two | ||
367 | dest operands with 2 possible source operands. | ||
368 | default y | ||
369 | |||
370 | config ARC_NUMBER_OF_INTERRUPTS | ||
371 | int "Number of interrupts" | ||
372 | range 8 240 | ||
373 | default 32 | ||
374 | help | ||
375 | This defines the number of interrupts on the ARCv2HS core. | ||
376 | It affects the size of vector table. | ||
377 | The initial 8 IRQs are fixed (Timer, ICI etc) and although configurable | ||
378 | in hardware, it keep things simple for Linux to assume they are always | ||
379 | present. | ||
380 | |||
381 | endif # ISA_ARCV2 | ||
382 | |||
315 | endmenu # "ARC CPU Configuration" | 383 | endmenu # "ARC CPU Configuration" |
316 | 384 | ||
317 | config LINUX_LINK_BASE | 385 | config LINUX_LINK_BASE |
@@ -337,8 +405,10 @@ config ARC_CURR_IN_REG | |||
337 | 405 | ||
338 | config ARC_EMUL_UNALIGNED | 406 | config ARC_EMUL_UNALIGNED |
339 | bool "Emulate unaligned memory access (userspace only)" | 407 | bool "Emulate unaligned memory access (userspace only)" |
408 | default N | ||
340 | select SYSCTL_ARCH_UNALIGN_NO_WARN | 409 | select SYSCTL_ARCH_UNALIGN_NO_WARN |
341 | select SYSCTL_ARCH_UNALIGN_ALLOW | 410 | select SYSCTL_ARCH_UNALIGN_ALLOW |
411 | depends on ISA_ARCOMPACT | ||
342 | help | 412 | help |
343 | This enables misaligned 16 & 32 bit memory access from user space. | 413 | This enables misaligned 16 & 32 bit memory access from user space. |
344 | Use ONLY-IF-ABS-NECESSARY as it will be very slow and also can hide | 414 | Use ONLY-IF-ABS-NECESSARY as it will be very slow and also can hide |
diff --git a/arch/arc/Makefile b/arch/arc/Makefile index 86c71b2089d2..bf68dc5a08be 100644 --- a/arch/arc/Makefile +++ b/arch/arc/Makefile | |||
@@ -14,7 +14,9 @@ endif | |||
14 | 14 | ||
15 | KBUILD_DEFCONFIG := nsim_700_defconfig | 15 | KBUILD_DEFCONFIG := nsim_700_defconfig |
16 | 16 | ||
17 | cflags-y += -mA7 -fno-common -pipe -fno-builtin -D__linux__ | 17 | cflags-y += -fno-common -pipe -fno-builtin -D__linux__ |
18 | cflags-${CONFIG_ISA_ARCOMPACT} += -mA7 | ||
19 | cflags-${CONFIG_ISA_ARCV2} += -mcpu=archs | ||
18 | 20 | ||
19 | ifdef CONFIG_ARC_CURR_IN_REG | 21 | ifdef CONFIG_ARC_CURR_IN_REG |
20 | # For a global register defintion, make sure it gets passed to every file | 22 | # For a global register defintion, make sure it gets passed to every file |
@@ -34,6 +36,10 @@ cflags-$(atleast_gcc44) += -fsection-anchors | |||
34 | cflags-$(CONFIG_ARC_HAS_LLSC) += -mlock | 36 | cflags-$(CONFIG_ARC_HAS_LLSC) += -mlock |
35 | cflags-$(CONFIG_ARC_HAS_SWAPE) += -mswape | 37 | cflags-$(CONFIG_ARC_HAS_SWAPE) += -mswape |
36 | 38 | ||
39 | ifndef CONFIG_ARC_HAS_LL64 | ||
40 | cflags-y += -mno-ll64 | ||
41 | endif | ||
42 | |||
37 | cflags-$(CONFIG_ARC_DW2_UNWIND) += -fasynchronous-unwind-tables | 43 | cflags-$(CONFIG_ARC_DW2_UNWIND) += -fasynchronous-unwind-tables |
38 | 44 | ||
39 | # By default gcc 4.8 generates dwarf4 which kernel unwinder can't grok | 45 | # By default gcc 4.8 generates dwarf4 which kernel unwinder can't grok |
diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h index 649646579986..373bb415e844 100644 --- a/arch/arc/include/asm/arcregs.h +++ b/arch/arc/include/asm/arcregs.h | |||
@@ -16,6 +16,7 @@ | |||
16 | #define ARC_REG_PERIBASE_BCR 0x69 | 16 | #define ARC_REG_PERIBASE_BCR 0x69 |
17 | #define ARC_REG_FP_BCR 0x6B /* ARCompact: Single-Precision FPU */ | 17 | #define ARC_REG_FP_BCR 0x6B /* ARCompact: Single-Precision FPU */ |
18 | #define ARC_REG_DPFP_BCR 0x6C /* ARCompact: Dbl Precision FPU */ | 18 | #define ARC_REG_DPFP_BCR 0x6C /* ARCompact: Dbl Precision FPU */ |
19 | #define ARC_REG_FP_V2_BCR 0xc8 /* ARCv2 FPU */ | ||
19 | #define ARC_REG_DCCM_BCR 0x74 /* DCCM Present + SZ */ | 20 | #define ARC_REG_DCCM_BCR 0x74 /* DCCM Present + SZ */ |
20 | #define ARC_REG_TIMERS_BCR 0x75 | 21 | #define ARC_REG_TIMERS_BCR 0x75 |
21 | #define ARC_REG_AP_BCR 0x76 | 22 | #define ARC_REG_AP_BCR 0x76 |
@@ -52,6 +53,7 @@ | |||
52 | * [15: 8] = Exception Cause Code | 53 | * [15: 8] = Exception Cause Code |
53 | * [ 7: 0] = Exception Parameters (for certain types only) | 54 | * [ 7: 0] = Exception Parameters (for certain types only) |
54 | */ | 55 | */ |
56 | #ifdef CONFIG_ISA_ARCOMPACT | ||
55 | #define ECR_V_MEM_ERR 0x01 | 57 | #define ECR_V_MEM_ERR 0x01 |
56 | #define ECR_V_INSN_ERR 0x02 | 58 | #define ECR_V_INSN_ERR 0x02 |
57 | #define ECR_V_MACH_CHK 0x20 | 59 | #define ECR_V_MACH_CHK 0x20 |
@@ -59,6 +61,15 @@ | |||
59 | #define ECR_V_DTLB_MISS 0x22 | 61 | #define ECR_V_DTLB_MISS 0x22 |
60 | #define ECR_V_PROTV 0x23 | 62 | #define ECR_V_PROTV 0x23 |
61 | #define ECR_V_TRAP 0x25 | 63 | #define ECR_V_TRAP 0x25 |
64 | #else | ||
65 | #define ECR_V_MEM_ERR 0x01 | ||
66 | #define ECR_V_INSN_ERR 0x02 | ||
67 | #define ECR_V_MACH_CHK 0x03 | ||
68 | #define ECR_V_ITLB_MISS 0x04 | ||
69 | #define ECR_V_DTLB_MISS 0x05 | ||
70 | #define ECR_V_PROTV 0x06 | ||
71 | #define ECR_V_TRAP 0x09 | ||
72 | #endif | ||
62 | 73 | ||
63 | /* DTLB Miss and Protection Violation Cause Codes */ | 74 | /* DTLB Miss and Protection Violation Cause Codes */ |
64 | 75 | ||
@@ -202,9 +213,11 @@ struct bcr_identity { | |||
202 | 213 | ||
203 | struct bcr_isa { | 214 | struct bcr_isa { |
204 | #ifdef CONFIG_CPU_BIG_ENDIAN | 215 | #ifdef CONFIG_CPU_BIG_ENDIAN |
205 | unsigned int pad1:23, atomic1:1, ver:8; | 216 | unsigned int div_rem:4, pad2:4, ldd:1, unalign:1, atomic:1, be:1, |
217 | pad1:11, atomic1:1, ver:8; | ||
206 | #else | 218 | #else |
207 | unsigned int ver:8, atomic1:1, pad1:23; | 219 | unsigned int ver:8, atomic1:1, pad1:11, be:1, atomic:1, unalign:1, |
220 | ldd:1, pad2:4, div_rem:4; | ||
208 | #endif | 221 | #endif |
209 | }; | 222 | }; |
210 | 223 | ||
@@ -267,11 +280,19 @@ struct bcr_fp_arcompact { | |||
267 | #endif | 280 | #endif |
268 | }; | 281 | }; |
269 | 282 | ||
283 | struct bcr_fp_arcv2 { | ||
284 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
285 | unsigned int pad2:15, dp:1, pad1:7, sp:1, ver:8; | ||
286 | #else | ||
287 | unsigned int ver:8, sp:1, pad1:7, dp:1, pad2:15; | ||
288 | #endif | ||
289 | }; | ||
290 | |||
270 | struct bcr_timer { | 291 | struct bcr_timer { |
271 | #ifdef CONFIG_CPU_BIG_ENDIAN | 292 | #ifdef CONFIG_CPU_BIG_ENDIAN |
272 | unsigned int pad2:15, rtsc:1, pad1:6, t1:1, t0:1, ver:8; | 293 | unsigned int pad2:15, rtsc:1, pad1:5, rtc:1, t1:1, t0:1, ver:8; |
273 | #else | 294 | #else |
274 | unsigned int ver:8, t0:1, t1:1, pad1:6, rtsc:1, pad2:15; | 295 | unsigned int ver:8, t0:1, t1:1, rtc:1, pad1:5, rtsc:1, pad2:15; |
275 | #endif | 296 | #endif |
276 | }; | 297 | }; |
277 | 298 | ||
@@ -283,6 +304,14 @@ struct bcr_bpu_arcompact { | |||
283 | #endif | 304 | #endif |
284 | }; | 305 | }; |
285 | 306 | ||
307 | struct bcr_bpu_arcv2 { | ||
308 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
309 | unsigned int pad:6, fbe:2, tqe:2, ts:4, ft:1, rse:2, pte:3, bce:3, ver:8; | ||
310 | #else | ||
311 | unsigned int ver:8, bce:3, pte:3, rse:2, ft:1, ts:4, tqe:2, fbe:2, pad:6; | ||
312 | #endif | ||
313 | }; | ||
314 | |||
286 | struct bcr_generic { | 315 | struct bcr_generic { |
287 | #ifdef CONFIG_CPU_BIG_ENDIAN | 316 | #ifdef CONFIG_CPU_BIG_ENDIAN |
288 | unsigned int pad:24, ver:8; | 317 | unsigned int pad:24, ver:8; |
@@ -334,6 +363,22 @@ struct cpuinfo_arc { | |||
334 | 363 | ||
335 | extern struct cpuinfo_arc cpuinfo_arc700[]; | 364 | extern struct cpuinfo_arc cpuinfo_arc700[]; |
336 | 365 | ||
366 | static inline int is_isa_arcv2(void) | ||
367 | { | ||
368 | return IS_ENABLED(CONFIG_ISA_ARCV2); | ||
369 | } | ||
370 | |||
371 | static inline int is_isa_arcompact(void) | ||
372 | { | ||
373 | return IS_ENABLED(CONFIG_ISA_ARCOMPACT); | ||
374 | } | ||
375 | |||
376 | #if defined(CONFIG_ISA_ARCOMPACT) && !defined(_CPU_DEFAULT_A7) | ||
377 | #error "Toolchain not configured for ARCompact builds" | ||
378 | #elif defined(CONFIG_ISA_ARCV2) && !defined(_CPU_DEFAULT_HS) | ||
379 | #error "Toolchain not configured for ARCv2 builds" | ||
380 | #endif | ||
381 | |||
337 | #endif /* __ASEMBLY__ */ | 382 | #endif /* __ASEMBLY__ */ |
338 | 383 | ||
339 | #endif /* _ASM_ARC_ARCREGS_H */ | 384 | #endif /* _ASM_ARC_ARCREGS_H */ |
diff --git a/arch/arc/include/asm/bitops.h b/arch/arc/include/asm/bitops.h index 4051e9525939..829a8a2e9704 100644 --- a/arch/arc/include/asm/bitops.h +++ b/arch/arc/include/asm/bitops.h | |||
@@ -402,6 +402,8 @@ test_bit(unsigned int nr, const volatile unsigned long *addr) | |||
402 | return ((mask & *addr) != 0); | 402 | return ((mask & *addr) != 0); |
403 | } | 403 | } |
404 | 404 | ||
405 | #ifdef CONFIG_ISA_ARCOMPACT | ||
406 | |||
405 | /* | 407 | /* |
406 | * Count the number of zeros, starting from MSB | 408 | * Count the number of zeros, starting from MSB |
407 | * Helper for fls( ) friends | 409 | * Helper for fls( ) friends |
@@ -494,6 +496,75 @@ static inline __attribute__ ((const)) int __ffs(unsigned long word) | |||
494 | return ffs(word) - 1; | 496 | return ffs(word) - 1; |
495 | } | 497 | } |
496 | 498 | ||
499 | #else /* CONFIG_ISA_ARCV2 */ | ||
500 | |||
501 | /* | ||
502 | * fls = Find Last Set in word | ||
503 | * @result: [1-32] | ||
504 | * fls(1) = 1, fls(0x80000000) = 32, fls(0) = 0 | ||
505 | */ | ||
506 | static inline __attribute__ ((const)) int fls(unsigned long x) | ||
507 | { | ||
508 | int n; | ||
509 | |||
510 | asm volatile( | ||
511 | " fls.f %0, %1 \n" /* 0:31; 0(Z) if src 0 */ | ||
512 | " add.nz %0, %0, 1 \n" /* 0:31 -> 1:32 */ | ||
513 | : "=r"(n) /* Early clobber not needed */ | ||
514 | : "r"(x) | ||
515 | : "cc"); | ||
516 | |||
517 | return n; | ||
518 | } | ||
519 | |||
520 | /* | ||
521 | * __fls: Similar to fls, but zero based (0-31). Also 0 if no bit set | ||
522 | */ | ||
523 | static inline __attribute__ ((const)) int __fls(unsigned long x) | ||
524 | { | ||
525 | /* FLS insn has exactly same semantics as the API */ | ||
526 | return __builtin_arc_fls(x); | ||
527 | } | ||
528 | |||
529 | /* | ||
530 | * ffs = Find First Set in word (LSB to MSB) | ||
531 | * @result: [1-32], 0 if all 0's | ||
532 | */ | ||
533 | static inline __attribute__ ((const)) int ffs(unsigned long x) | ||
534 | { | ||
535 | int n; | ||
536 | |||
537 | asm volatile( | ||
538 | " ffs.f %0, %1 \n" /* 0:31; 31(Z) if src 0 */ | ||
539 | " add.nz %0, %0, 1 \n" /* 0:31 -> 1:32 */ | ||
540 | " mov.z %0, 0 \n" /* 31(Z)-> 0 */ | ||
541 | : "=r"(n) /* Early clobber not needed */ | ||
542 | : "r"(x) | ||
543 | : "cc"); | ||
544 | |||
545 | return n; | ||
546 | } | ||
547 | |||
548 | /* | ||
549 | * __ffs: Similar to ffs, but zero based (0-31) | ||
550 | */ | ||
551 | static inline __attribute__ ((const)) int __ffs(unsigned long x) | ||
552 | { | ||
553 | int n; | ||
554 | |||
555 | asm volatile( | ||
556 | " ffs.f %0, %1 \n" /* 0:31; 31(Z) if src 0 */ | ||
557 | " mov.z %0, 0 \n" /* 31(Z)-> 0 */ | ||
558 | : "=r"(n) | ||
559 | : "r"(x) | ||
560 | : "cc"); | ||
561 | |||
562 | return n; | ||
563 | |||
564 | } | ||
565 | |||
566 | #endif /* CONFIG_ISA_ARCOMPACT */ | ||
567 | |||
497 | /* | 568 | /* |
498 | * ffz = Find First Zero in word. | 569 | * ffz = Find First Zero in word. |
499 | * @return:[0-31], 32 if all 1's | 570 | * @return:[0-31], 32 if all 1's |
diff --git a/arch/arc/include/asm/elf.h b/arch/arc/include/asm/elf.h index a26282857683..51a99e25fe33 100644 --- a/arch/arc/include/asm/elf.h +++ b/arch/arc/include/asm/elf.h | |||
@@ -15,6 +15,11 @@ | |||
15 | /* These ELF defines belong to uapi but libc elf.h already defines them */ | 15 | /* These ELF defines belong to uapi but libc elf.h already defines them */ |
16 | #define EM_ARCOMPACT 93 | 16 | #define EM_ARCOMPACT 93 |
17 | 17 | ||
18 | #define EM_ARCV2 195 /* ARCv2 Cores */ | ||
19 | |||
20 | #define EM_ARC_INUSE (IS_ENABLED(CONFIG_ISA_ARCOMPACT) ? \ | ||
21 | EM_ARCOMPACT : EM_ARCV2) | ||
22 | |||
18 | /* ARC Relocations (kernel Modules only) */ | 23 | /* ARC Relocations (kernel Modules only) */ |
19 | #define R_ARC_32 0x4 | 24 | #define R_ARC_32 0x4 |
20 | #define R_ARC_32_ME 0x1B | 25 | #define R_ARC_32_ME 0x1B |
diff --git a/arch/arc/include/asm/entry-arcv2.h b/arch/arc/include/asm/entry-arcv2.h new file mode 100644 index 000000000000..b5ff87e6f4b7 --- /dev/null +++ b/arch/arc/include/asm/entry-arcv2.h | |||
@@ -0,0 +1,190 @@ | |||
1 | |||
2 | #ifndef __ASM_ARC_ENTRY_ARCV2_H | ||
3 | #define __ASM_ARC_ENTRY_ARCV2_H | ||
4 | |||
5 | #include <asm/asm-offsets.h> | ||
6 | #include <asm/irqflags-arcv2.h> | ||
7 | #include <asm/thread_info.h> /* For THREAD_SIZE */ | ||
8 | |||
9 | /*------------------------------------------------------------------------*/ | ||
10 | .macro INTERRUPT_PROLOGUE called_from | ||
11 | |||
12 | ; Before jumping to Interrupt Vector, hardware micro-ops did following: | ||
13 | ; 1. SP auto-switched to kernel mode stack | ||
14 | ; 2. STATUS32.Z flag set to U mode at time of interrupt (U:1, K:0) | ||
15 | ; 3. Auto saved: r0-r11, blink, LPE,LPS,LPC, JLI,LDI,EI, PC, STAT32 | ||
16 | ; | ||
17 | ; Now manually save: r12, sp, fp, gp, r25 | ||
18 | |||
19 | PUSH r12 | ||
20 | |||
21 | ; Saving pt_regs->sp correctly requires some extra work due to the way | ||
22 | ; Auto stack switch works | ||
23 | ; - U mode: retrieve it from AUX_USER_SP | ||
24 | ; - K mode: add the offset from current SP where H/w starts auto push | ||
25 | ; | ||
26 | ; Utilize the fact that Z bit is set if Intr taken in U mode | ||
27 | mov.nz r9, sp | ||
28 | add.nz r9, r9, SZ_PT_REGS - PT_sp - 4 | ||
29 | bnz 1f | ||
30 | |||
31 | lr r9, [AUX_USER_SP] | ||
32 | 1: | ||
33 | PUSH r9 ; SP | ||
34 | |||
35 | PUSH fp | ||
36 | PUSH gp | ||
37 | |||
38 | #ifdef CONFIG_ARC_CURR_IN_REG | ||
39 | PUSH r25 ; user_r25 | ||
40 | GET_CURR_TASK_ON_CPU r25 | ||
41 | #else | ||
42 | sub sp, sp, 4 | ||
43 | #endif | ||
44 | |||
45 | .ifnc \called_from, exception | ||
46 | sub sp, sp, 12 ; BTA/ECR/orig_r0 placeholder per pt_regs | ||
47 | .endif | ||
48 | |||
49 | .endm | ||
50 | |||
51 | /*------------------------------------------------------------------------*/ | ||
52 | .macro INTERRUPT_EPILOGUE called_from | ||
53 | |||
54 | .ifnc \called_from, exception | ||
55 | add sp, sp, 12 ; skip BTA/ECR/orig_r0 placeholderss | ||
56 | .endif | ||
57 | |||
58 | #ifdef CONFIG_ARC_CURR_IN_REG | ||
59 | POP r25 | ||
60 | #else | ||
61 | add sp, sp, 4 | ||
62 | #endif | ||
63 | |||
64 | POP gp | ||
65 | POP fp | ||
66 | |||
67 | ; Don't touch AUX_USER_SP if returning to K mode (Z bit set) | ||
68 | ; (Z bit set on K mode is inverse of INTERRUPT_PROLOGUE) | ||
69 | add.z sp, sp, 4 | ||
70 | bz 1f | ||
71 | |||
72 | POPAX AUX_USER_SP | ||
73 | 1: | ||
74 | POP r12 | ||
75 | |||
76 | .endm | ||
77 | |||
78 | /*------------------------------------------------------------------------*/ | ||
79 | .macro EXCEPTION_PROLOGUE | ||
80 | |||
81 | ; Before jumping to Exception Vector, hardware micro-ops did following: | ||
82 | ; 1. SP auto-switched to kernel mode stack | ||
83 | ; 2. STATUS32.Z flag set to U mode at time of interrupt (U:1,K:0) | ||
84 | ; | ||
85 | ; Now manually save the complete reg file | ||
86 | |||
87 | PUSH r9 ; freeup a register: slot of erstatus | ||
88 | |||
89 | PUSHAX eret | ||
90 | sub sp, sp, 12 ; skip JLI, LDI, EI | ||
91 | PUSH lp_count | ||
92 | PUSHAX lp_start | ||
93 | PUSHAX lp_end | ||
94 | PUSH blink | ||
95 | |||
96 | PUSH r11 | ||
97 | PUSH r10 | ||
98 | |||
99 | ld.as r9, [sp, 10] ; load stashed r9 (status32 stack slot) | ||
100 | lr r10, [erstatus] | ||
101 | st.as r10, [sp, 10] ; save status32 at it's right stack slot | ||
102 | |||
103 | PUSH r9 | ||
104 | PUSH r8 | ||
105 | PUSH r7 | ||
106 | PUSH r6 | ||
107 | PUSH r5 | ||
108 | PUSH r4 | ||
109 | PUSH r3 | ||
110 | PUSH r2 | ||
111 | PUSH r1 | ||
112 | PUSH r0 | ||
113 | |||
114 | ; -- for interrupts, regs above are auto-saved by h/w in that order -- | ||
115 | ; Now do what ISR prologue does (manually save r12, sp, fp, gp, r25) | ||
116 | ; | ||
117 | ; Set Z flag if this was from U mode (expected by INTERRUPT_PROLOGUE) | ||
118 | ; Although H/w exception micro-ops do set Z flag for U mode (just like | ||
119 | ; for interrupts), it could get clobbered in case we soft land here from | ||
120 | ; a TLB Miss exception handler (tlbex.S) | ||
121 | |||
122 | and r10, r10, STATUS_U_MASK | ||
123 | xor.f 0, r10, STATUS_U_MASK | ||
124 | |||
125 | INTERRUPT_PROLOGUE exception | ||
126 | |||
127 | PUSHAX erbta | ||
128 | PUSHAX ecr ; r9 contains ECR, expected by EV_Trap | ||
129 | |||
130 | PUSH r0 ; orig_r0 | ||
131 | .endm | ||
132 | |||
133 | /*------------------------------------------------------------------------*/ | ||
134 | .macro EXCEPTION_EPILOGUE | ||
135 | |||
136 | ; Assumes r0 has PT_status32 | ||
137 | btst r0, STATUS_U_BIT ; Z flag set if K, used in INTERRUPT_EPILOGUE | ||
138 | |||
139 | add sp, sp, 8 ; orig_r0/ECR don't need restoring | ||
140 | POPAX erbta | ||
141 | |||
142 | INTERRUPT_EPILOGUE exception | ||
143 | |||
144 | POP r0 | ||
145 | POP r1 | ||
146 | POP r2 | ||
147 | POP r3 | ||
148 | POP r4 | ||
149 | POP r5 | ||
150 | POP r6 | ||
151 | POP r7 | ||
152 | POP r8 | ||
153 | POP r9 | ||
154 | POP r10 | ||
155 | POP r11 | ||
156 | |||
157 | POP blink | ||
158 | POPAX lp_end | ||
159 | POPAX lp_start | ||
160 | |||
161 | POP r9 | ||
162 | mov lp_count, r9 | ||
163 | |||
164 | add sp, sp, 12 ; skip JLI, LDI, EI | ||
165 | POPAX eret | ||
166 | POPAX erstatus | ||
167 | |||
168 | ld.as r9, [sp, -12] ; reload r9 which got clobbered | ||
169 | .endm | ||
170 | |||
171 | .macro FAKE_RET_FROM_EXCPN | ||
172 | lr r9, [status32] | ||
173 | bic r9, r9, (STATUS_U_MASK|STATUS_DE_MASK|STATUS_AE_MASK) | ||
174 | or r9, r9, (STATUS_L_MASK|STATUS_IE_MASK) | ||
175 | kflag r9 | ||
176 | .endm | ||
177 | |||
178 | /* Get thread_info of "current" tsk */ | ||
179 | .macro GET_CURR_THR_INFO_FROM_SP reg | ||
180 | bmskn \reg, sp, THREAD_SHIFT - 1 | ||
181 | .endm | ||
182 | |||
183 | /* Get CPU-ID of this core */ | ||
184 | .macro GET_CPU_ID reg | ||
185 | lr \reg, [identity] | ||
186 | xbfu \reg, \reg, 0xE8 /* 00111 01000 */ | ||
187 | /* M = 8-1 N = 8 */ | ||
188 | .endm | ||
189 | |||
190 | #endif | ||
diff --git a/arch/arc/include/asm/entry.h b/arch/arc/include/asm/entry.h index f61032c53d51..29d0ab6e10f5 100644 --- a/arch/arc/include/asm/entry.h +++ b/arch/arc/include/asm/entry.h | |||
@@ -16,7 +16,11 @@ | |||
16 | #include <asm/processor.h> /* For VMALLOC_START */ | 16 | #include <asm/processor.h> /* For VMALLOC_START */ |
17 | #include <asm/mmu.h> | 17 | #include <asm/mmu.h> |
18 | 18 | ||
19 | #ifdef CONFIG_ISA_ARCOMPACT | ||
19 | #include <asm/entry-compact.h> /* ISA specific bits */ | 20 | #include <asm/entry-compact.h> /* ISA specific bits */ |
21 | #else | ||
22 | #include <asm/entry-arcv2.h> | ||
23 | #endif | ||
20 | 24 | ||
21 | /* Note on the LD/ST addr modes with addr reg wback | 25 | /* Note on the LD/ST addr modes with addr reg wback |
22 | * | 26 | * |
diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h index f38652fb2ed7..49014f0ef36d 100644 --- a/arch/arc/include/asm/irq.h +++ b/arch/arc/include/asm/irq.h | |||
@@ -13,8 +13,13 @@ | |||
13 | #define NR_IRQS 128 /* allow some CPU external IRQ handling */ | 13 | #define NR_IRQS 128 /* allow some CPU external IRQ handling */ |
14 | 14 | ||
15 | /* Platform Independent IRQs */ | 15 | /* Platform Independent IRQs */ |
16 | #ifdef CONFIG_ISA_ARCOMPACT | ||
16 | #define TIMER0_IRQ 3 | 17 | #define TIMER0_IRQ 3 |
17 | #define TIMER1_IRQ 4 | 18 | #define TIMER1_IRQ 4 |
19 | #else | ||
20 | #define TIMER0_IRQ 16 | ||
21 | #define TIMER1_IRQ 17 | ||
22 | #endif | ||
18 | 23 | ||
19 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
20 | #include <asm-generic/irq.h> | 25 | #include <asm-generic/irq.h> |
diff --git a/arch/arc/include/asm/irqflags-arcv2.h b/arch/arc/include/asm/irqflags-arcv2.h index c946c56f141c..1eb41b00aac5 100644 --- a/arch/arc/include/asm/irqflags-arcv2.h +++ b/arch/arc/include/asm/irqflags-arcv2.h | |||
@@ -27,6 +27,9 @@ | |||
27 | #define AUX_IRQ_SELECT 0x40b | 27 | #define AUX_IRQ_SELECT 0x40b |
28 | #define AUX_IRQ_ENABLE 0x40c | 28 | #define AUX_IRQ_ENABLE 0x40c |
29 | 29 | ||
30 | /* Was Intr taken in User Mode */ | ||
31 | #define AUX_IRQ_ACT_BIT_U 31 | ||
32 | |||
30 | /* 0 is highest level, but taken by FIRQs, if present in design */ | 33 | /* 0 is highest level, but taken by FIRQs, if present in design */ |
31 | #define ARCV2_IRQ_DEF_PRIO 0 | 34 | #define ARCV2_IRQ_DEF_PRIO 0 |
32 | 35 | ||
diff --git a/arch/arc/include/asm/irqflags-compact.h b/arch/arc/include/asm/irqflags-compact.h index 18f3634ac347..aa805575c320 100644 --- a/arch/arc/include/asm/irqflags-compact.h +++ b/arch/arc/include/asm/irqflags-compact.h | |||
@@ -39,6 +39,8 @@ | |||
39 | #define AUX_ITRIGGER 0x40d | 39 | #define AUX_ITRIGGER 0x40d |
40 | #define AUX_IPULSE 0x415 | 40 | #define AUX_IPULSE 0x415 |
41 | 41 | ||
42 | #define ISA_INIT_STATUS_BITS STATUS_IE_MASK | ||
43 | |||
42 | #ifndef __ASSEMBLY__ | 44 | #ifndef __ASSEMBLY__ |
43 | 45 | ||
44 | /****************************************************************** | 46 | /****************************************************************** |
diff --git a/arch/arc/include/asm/irqflags.h b/arch/arc/include/asm/irqflags.h index 333972600680..59bc6a64f75d 100644 --- a/arch/arc/include/asm/irqflags.h +++ b/arch/arc/include/asm/irqflags.h | |||
@@ -10,6 +10,10 @@ | |||
10 | #ifndef __ASM_ARC_IRQFLAGS_H | 10 | #ifndef __ASM_ARC_IRQFLAGS_H |
11 | #define __ASM_ARC_IRQFLAGS_H | 11 | #define __ASM_ARC_IRQFLAGS_H |
12 | 12 | ||
13 | #ifdef CONFIG_ISA_ARCOMPACT | ||
13 | #include <asm/irqflags-compact.h> | 14 | #include <asm/irqflags-compact.h> |
15 | #else | ||
16 | #include <asm/irqflags-arcv2.h> | ||
17 | #endif | ||
14 | 18 | ||
15 | #endif | 19 | #endif |
diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h index 1bfeec2c0558..91755972b9a2 100644 --- a/arch/arc/include/asm/ptrace.h +++ b/arch/arc/include/asm/ptrace.h | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
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 | #ifdef CONFIG_ISA_ARCOMPACT | ||
19 | struct pt_regs { | 20 | struct pt_regs { |
20 | 21 | ||
21 | /* Real registers */ | 22 | /* Real registers */ |
@@ -56,6 +57,48 @@ struct pt_regs { | |||
56 | 57 | ||
57 | long user_r25; | 58 | long user_r25; |
58 | }; | 59 | }; |
60 | #else | ||
61 | |||
62 | struct pt_regs { | ||
63 | |||
64 | long orig_r0; | ||
65 | |||
66 | union { | ||
67 | struct { | ||
68 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
69 | unsigned long state:8, ecr_vec:8, | ||
70 | ecr_cause:8, ecr_param:8; | ||
71 | #else | ||
72 | unsigned long ecr_param:8, ecr_cause:8, | ||
73 | ecr_vec:8, state:8; | ||
74 | #endif | ||
75 | }; | ||
76 | unsigned long event; | ||
77 | }; | ||
78 | |||
79 | long bta; /* bta_l1, bta_l2, erbta */ | ||
80 | |||
81 | long user_r25; | ||
82 | |||
83 | long r26; /* gp */ | ||
84 | long fp; | ||
85 | long sp; /* user/kernel sp depending on where we came from */ | ||
86 | |||
87 | long r12; | ||
88 | |||
89 | /*------- Below list auto saved by h/w -----------*/ | ||
90 | long r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11; | ||
91 | |||
92 | long blink; | ||
93 | long lp_end, lp_start, lp_count; | ||
94 | |||
95 | long ei, ldi, jli; | ||
96 | |||
97 | long ret; | ||
98 | long status32; | ||
99 | }; | ||
100 | |||
101 | #endif | ||
59 | 102 | ||
60 | /* Callee saved registers - need to be saved only when you are scheduled out */ | 103 | /* Callee saved registers - need to be saved only when you are scheduled out */ |
61 | 104 | ||
diff --git a/arch/arc/include/asm/thread_info.h b/arch/arc/include/asm/thread_info.h index aca0d5a45c7b..3af67455659a 100644 --- a/arch/arc/include/asm/thread_info.h +++ b/arch/arc/include/asm/thread_info.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) | 27 | #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) |
28 | #define THREAD_SHIFT (PAGE_SHIFT << THREAD_SIZE_ORDER) | ||
28 | 29 | ||
29 | #ifndef __ASSEMBLY__ | 30 | #ifndef __ASSEMBLY__ |
30 | 31 | ||
diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile index cc929c0e2133..0be7ba087260 100644 --- a/arch/arc/kernel/Makefile +++ b/arch/arc/kernel/Makefile | |||
@@ -10,7 +10,8 @@ CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' | |||
10 | 10 | ||
11 | obj-y := arcksyms.o setup.o irq.o time.o reset.o ptrace.o process.o devtree.o | 11 | obj-y := arcksyms.o setup.o irq.o time.o reset.o ptrace.o process.o devtree.o |
12 | obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o clk.o | 12 | obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o clk.o |
13 | obj-y += entry-compact.o intc-compact.o | 13 | obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o |
14 | obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o | ||
14 | 15 | ||
15 | obj-$(CONFIG_MODULES) += arcksyms.o module.o | 16 | obj-$(CONFIG_MODULES) += arcksyms.o module.o |
16 | obj-$(CONFIG_SMP) += smp.o | 17 | obj-$(CONFIG_SMP) += smp.o |
diff --git a/arch/arc/kernel/entry-arcv2.S b/arch/arc/kernel/entry-arcv2.S new file mode 100644 index 000000000000..c59a396b7b98 --- /dev/null +++ b/arch/arc/kernel/entry-arcv2.S | |||
@@ -0,0 +1,189 @@ | |||
1 | /* | ||
2 | * ARCv2 ISA based core Low Level Intr/Traps/Exceptions(non-TLB) Handling | ||
3 | * | ||
4 | * Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/linkage.h> /* ARC_{EXTRY,EXIT} */ | ||
12 | #include <asm/entry.h> /* SAVE_ALL_{INT1,INT2,TRAP...} */ | ||
13 | #include <asm/errno.h> | ||
14 | #include <asm/arcregs.h> | ||
15 | #include <asm/irqflags.h> | ||
16 | |||
17 | .cpu HS | ||
18 | |||
19 | #define VECTOR .word | ||
20 | |||
21 | ;############################ Vector Table ################################# | ||
22 | |||
23 | .section .vector,"a",@progbits | ||
24 | .align 4 | ||
25 | |||
26 | # Initial 16 slots are Exception Vectors | ||
27 | VECTOR stext ; Restart Vector (jump to entry point) | ||
28 | VECTOR mem_service ; Mem exception | ||
29 | VECTOR instr_service ; Instrn Error | ||
30 | VECTOR EV_MachineCheck ; Fatal Machine check | ||
31 | VECTOR EV_TLBMissI ; Intruction TLB miss | ||
32 | VECTOR EV_TLBMissD ; Data TLB miss | ||
33 | VECTOR EV_TLBProtV ; Protection Violation | ||
34 | VECTOR EV_PrivilegeV ; Privilege Violation | ||
35 | VECTOR EV_SWI ; Software Breakpoint | ||
36 | VECTOR EV_Trap ; Trap exception | ||
37 | VECTOR EV_Extension ; Extn Instruction Exception | ||
38 | VECTOR EV_DivZero ; Divide by Zero | ||
39 | VECTOR EV_DCError ; Data Cache Error | ||
40 | VECTOR EV_Misaligned ; Misaligned Data Access | ||
41 | VECTOR reserved ; Reserved slots | ||
42 | VECTOR reserved ; Reserved slots | ||
43 | |||
44 | # Begin Interrupt Vectors | ||
45 | VECTOR handle_interrupt ; (16) Timer0 | ||
46 | VECTOR handle_interrupt ; unused (Timer1) | ||
47 | VECTOR handle_interrupt ; unused (WDT) | ||
48 | VECTOR handle_interrupt ; (19) ICI (inter core interrupt) | ||
49 | VECTOR handle_interrupt | ||
50 | VECTOR handle_interrupt | ||
51 | VECTOR handle_interrupt | ||
52 | VECTOR handle_interrupt ; (23) End of fixed IRQs | ||
53 | |||
54 | .rept CONFIG_ARC_NUMBER_OF_INTERRUPTS - 8 | ||
55 | VECTOR handle_interrupt | ||
56 | .endr | ||
57 | |||
58 | .section .text, "ax",@progbits | ||
59 | |||
60 | res_service: ; processor restart | ||
61 | flag 0x1 ; not implemented | ||
62 | nop | ||
63 | nop | ||
64 | |||
65 | reserved: ; processor restart | ||
66 | rtie ; jump to processor initializations | ||
67 | |||
68 | ;##################### Interrupt Handling ############################## | ||
69 | |||
70 | ENTRY(handle_interrupt) | ||
71 | |||
72 | INTERRUPT_PROLOGUE irq | ||
73 | |||
74 | clri ; To make status32.IE agree with CPU internal state | ||
75 | |||
76 | lr r0, [ICAUSE] | ||
77 | |||
78 | mov blink, ret_from_exception | ||
79 | |||
80 | b.d arch_do_IRQ | ||
81 | mov r1, sp | ||
82 | |||
83 | END(handle_interrupt) | ||
84 | |||
85 | ;################### Non TLB Exception Handling ############################# | ||
86 | |||
87 | ENTRY(EV_SWI) | ||
88 | flag 1 | ||
89 | END(EV_SWI) | ||
90 | |||
91 | ENTRY(EV_DivZero) | ||
92 | flag 1 | ||
93 | END(EV_DivZero) | ||
94 | |||
95 | ENTRY(EV_DCError) | ||
96 | flag 1 | ||
97 | END(EV_DCError) | ||
98 | |||
99 | ENTRY(EV_Misaligned) | ||
100 | |||
101 | EXCEPTION_PROLOGUE | ||
102 | |||
103 | lr r0, [efa] ; Faulting Data address | ||
104 | mov r1, sp | ||
105 | |||
106 | FAKE_RET_FROM_EXCPN | ||
107 | |||
108 | SAVE_CALLEE_SAVED_USER | ||
109 | mov r2, sp ; callee_regs | ||
110 | |||
111 | bl do_misaligned_access | ||
112 | |||
113 | ; TBD: optimize - do this only if a callee reg was involved | ||
114 | ; either a dst of emulated LD/ST or src with address-writeback | ||
115 | RESTORE_CALLEE_SAVED_USER | ||
116 | |||
117 | b ret_from_exception | ||
118 | END(EV_Misaligned) | ||
119 | |||
120 | ; --------------------------------------------- | ||
121 | ; Protection Violation Exception Handler | ||
122 | ; --------------------------------------------- | ||
123 | |||
124 | ENTRY(EV_TLBProtV) | ||
125 | |||
126 | EXCEPTION_PROLOGUE | ||
127 | |||
128 | lr r0, [efa] ; Faulting Data address | ||
129 | mov r1, sp ; pt_regs | ||
130 | |||
131 | FAKE_RET_FROM_EXCPN | ||
132 | |||
133 | mov blink, ret_from_exception | ||
134 | b do_page_fault | ||
135 | |||
136 | END(EV_TLBProtV) | ||
137 | |||
138 | ; From Linux standpoint Slow Path I/D TLB Miss is same a ProtV as they | ||
139 | ; need to call do_page_fault(). | ||
140 | ; ECR in pt_regs provides whether access was R/W/X | ||
141 | |||
142 | .global call_do_page_fault | ||
143 | .set call_do_page_fault, EV_TLBProtV | ||
144 | |||
145 | ;############# Common Handlers for ARCompact and ARCv2 ############## | ||
146 | |||
147 | #include "entry.S" | ||
148 | |||
149 | ;############# Return from Intr/Excp/Trap (ARCv2 ISA Specifics) ############## | ||
150 | ; | ||
151 | ; Restore the saved sys context (common exit-path for EXCPN/IRQ/Trap) | ||
152 | ; IRQ shd definitely not happen between now and rtie | ||
153 | ; All 2 entry points to here already disable interrupts | ||
154 | |||
155 | .Lrestore_regs: | ||
156 | |||
157 | ld r0, [sp, PT_status32] ; U/K mode at time of entry | ||
158 | lr r10, [AUX_IRQ_ACT] | ||
159 | |||
160 | bmsk r11, r10, 15 ; AUX_IRQ_ACT.ACTIVE | ||
161 | breq r11, 0, .Lexcept_ret ; No intr active, ret from Exception | ||
162 | |||
163 | ;####### Return from Intr ####### | ||
164 | |||
165 | debug_marker_l1: | ||
166 | ; Handle special case #1: (Entry via Exception, Return via IRQ) | ||
167 | ; | ||
168 | ; Exception in U mode, preempted in kernel, Intr taken (K mode), orig | ||
169 | ; task now returning to U mode (riding the Intr) | ||
170 | ; AUX_IRQ_ACTIVE won't have U bit set (since intr in K mode), hence SP | ||
171 | ; won't be switched to correct U mode value (from AUX_SP) | ||
172 | ; So force AUX_IRQ_ACT.U for such a case | ||
173 | |||
174 | btst r0, STATUS_U_BIT ; Z flag set if K (Z clear for U) | ||
175 | bset.nz r11, r11, AUX_IRQ_ACT_BIT_U ; NZ means U | ||
176 | sr r11, [AUX_IRQ_ACT] | ||
177 | |||
178 | INTERRUPT_EPILOGUE irq | ||
179 | rtie | ||
180 | |||
181 | ;####### Return from Exception / pure kernel mode ####### | ||
182 | |||
183 | .Lexcept_ret: ; Expects r0 has PT_status32 | ||
184 | |||
185 | debug_marker_syscall: | ||
186 | EXCEPTION_EPILOGUE | ||
187 | rtie | ||
188 | |||
189 | END(ret_from_exception) | ||
diff --git a/arch/arc/kernel/head.S b/arch/arc/kernel/head.S index 64a92e0b1e53..812f95e6ae69 100644 --- a/arch/arc/kernel/head.S +++ b/arch/arc/kernel/head.S | |||
@@ -49,8 +49,6 @@ | |||
49 | 1: | 49 | 1: |
50 | .endm | 50 | .endm |
51 | 51 | ||
52 | .cpu A7 | ||
53 | |||
54 | .section .init.text, "ax",@progbits | 52 | .section .init.text, "ax",@progbits |
55 | .type stext, @function | 53 | .type stext, @function |
56 | .globl stext | 54 | .globl stext |
diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c index b5426babd3c8..51560435a26b 100644 --- a/arch/arc/kernel/process.c +++ b/arch/arc/kernel/process.c | |||
@@ -44,7 +44,17 @@ SYSCALL_DEFINE0(arc_gettls) | |||
44 | void arch_cpu_idle(void) | 44 | void arch_cpu_idle(void) |
45 | { | 45 | { |
46 | /* sleep, but enable all interrupts before committing */ | 46 | /* sleep, but enable all interrupts before committing */ |
47 | __asm__("sleep 0x3"); | 47 | if (is_isa_arcompact()) { |
48 | __asm__("sleep 0x3"); | ||
49 | } else { | ||
50 | /* default irq priority (<=) which can interrupt the doze */ | ||
51 | const int arg = 0x10 | ARCV2_IRQ_DEF_PRIO; | ||
52 | |||
53 | __asm__ __volatile__( | ||
54 | "sleep %0 \n" | ||
55 | : | ||
56 | :"r"(arg)); | ||
57 | } | ||
48 | } | 58 | } |
49 | 59 | ||
50 | asmlinkage void ret_from_fork(void); | 60 | asmlinkage void ret_from_fork(void); |
@@ -166,7 +176,7 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long usp) | |||
166 | * [L] ZOL loop inhibited to begin with - cleared by a LP insn | 176 | * [L] ZOL loop inhibited to begin with - cleared by a LP insn |
167 | * Interrupts enabled | 177 | * Interrupts enabled |
168 | */ | 178 | */ |
169 | regs->status32 = STATUS_U_MASK | STATUS_L_MASK | STATUS_IE_MASK; | 179 | regs->status32 = STATUS_U_MASK | STATUS_L_MASK | ISA_INIT_STATUS_BITS; |
170 | 180 | ||
171 | /* bogus seed values for debugging */ | 181 | /* bogus seed values for debugging */ |
172 | regs->lp_start = 0x10; | 182 | regs->lp_start = 0x10; |
@@ -196,8 +206,11 @@ int elf_check_arch(const struct elf32_hdr *x) | |||
196 | { | 206 | { |
197 | unsigned int eflags; | 207 | unsigned int eflags; |
198 | 208 | ||
199 | if (x->e_machine != EM_ARCOMPACT) | 209 | if (x->e_machine != EM_ARC_INUSE) { |
210 | pr_err("ELF not built for %s ISA\n", | ||
211 | is_isa_arcompact() ? "ARCompact":"ARCv2"); | ||
200 | return 0; | 212 | return 0; |
213 | } | ||
201 | 214 | ||
202 | eflags = x->e_flags; | 215 | eflags = x->e_flags; |
203 | if ((eflags & EF_ARC_OSABI_MSK) < EF_ARC_OSABI_CURRENT) { | 216 | if ((eflags & EF_ARC_OSABI_MSK) < EF_ARC_OSABI_CURRENT) { |
diff --git a/arch/arc/kernel/ptrace.c b/arch/arc/kernel/ptrace.c index 4dd9e3a8c2da..4442204fe238 100644 --- a/arch/arc/kernel/ptrace.c +++ b/arch/arc/kernel/ptrace.c | |||
@@ -200,7 +200,7 @@ static const struct user_regset arc_regsets[] = { | |||
200 | 200 | ||
201 | static const struct user_regset_view user_arc_view = { | 201 | static const struct user_regset_view user_arc_view = { |
202 | .name = UTS_MACHINE, | 202 | .name = UTS_MACHINE, |
203 | .e_machine = EM_ARCOMPACT, | 203 | .e_machine = EM_ARC_INUSE, |
204 | .regsets = arc_regsets, | 204 | .regsets = arc_regsets, |
205 | .n = ARRAY_SIZE(arc_regsets) | 205 | .n = ARRAY_SIZE(arc_regsets) |
206 | }; | 206 | }; |
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index 96d44805ea56..d6fe80070bbf 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c | |||
@@ -96,7 +96,7 @@ static void read_arc_build_cfg_regs(void) | |||
96 | read_decode_mmu_bcr(); | 96 | read_decode_mmu_bcr(); |
97 | read_decode_cache_bcr(); | 97 | read_decode_cache_bcr(); |
98 | 98 | ||
99 | { | 99 | if (is_isa_arcompact()) { |
100 | struct bcr_fp_arcompact sp, dp; | 100 | struct bcr_fp_arcompact sp, dp; |
101 | struct bcr_bpu_arcompact bpu; | 101 | struct bcr_bpu_arcompact bpu; |
102 | 102 | ||
@@ -112,6 +112,19 @@ static void read_arc_build_cfg_regs(void) | |||
112 | cpu->bpu.num_cache = 256 << (bpu.ent - 1); | 112 | cpu->bpu.num_cache = 256 << (bpu.ent - 1); |
113 | cpu->bpu.num_pred = 256 << (bpu.ent - 1); | 113 | cpu->bpu.num_pred = 256 << (bpu.ent - 1); |
114 | } | 114 | } |
115 | } else { | ||
116 | struct bcr_fp_arcv2 spdp; | ||
117 | struct bcr_bpu_arcv2 bpu; | ||
118 | |||
119 | READ_BCR(ARC_REG_FP_V2_BCR, spdp); | ||
120 | cpu->extn.fpu_sp = spdp.sp ? 1 : 0; | ||
121 | cpu->extn.fpu_dp = spdp.dp ? 1 : 0; | ||
122 | |||
123 | READ_BCR(ARC_REG_BPU_BCR, bpu); | ||
124 | cpu->bpu.ver = bpu.ver; | ||
125 | cpu->bpu.full = bpu.ft; | ||
126 | cpu->bpu.num_cache = 256 << bpu.bce; | ||
127 | cpu->bpu.num_pred = 2048 << bpu.pte; | ||
115 | } | 128 | } |
116 | 129 | ||
117 | READ_BCR(ARC_REG_AP_BCR, bcr); | 130 | READ_BCR(ARC_REG_AP_BCR, bcr); |
@@ -131,6 +144,7 @@ static const struct cpuinfo_data arc_cpu_tbl[] = { | |||
131 | { {0x30, "ARC 700" }, 0x33}, | 144 | { {0x30, "ARC 700" }, 0x33}, |
132 | { {0x34, "ARC 700 R4.10"}, 0x34}, | 145 | { {0x34, "ARC 700 R4.10"}, 0x34}, |
133 | { {0x35, "ARC 700 R4.11"}, 0x35}, | 146 | { {0x35, "ARC 700 R4.11"}, 0x35}, |
147 | { {0x50, "ARC HS38" }, 0x51}, | ||
134 | { {0x00, NULL } } | 148 | { {0x00, NULL } } |
135 | }; | 149 | }; |
136 | 150 | ||
@@ -149,13 +163,17 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len) | |||
149 | 163 | ||
150 | FIX_PTR(cpu); | 164 | FIX_PTR(cpu); |
151 | 165 | ||
152 | { | 166 | if (is_isa_arcompact()) { |
153 | isa_nm = "ARCompact"; | 167 | isa_nm = "ARCompact"; |
154 | be = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN); | 168 | be = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN); |
155 | 169 | ||
156 | atomic = cpu->isa.atomic1; | 170 | atomic = cpu->isa.atomic1; |
157 | if (!cpu->isa.ver) /* ISA BCR absent, use Kconfig info */ | 171 | if (!cpu->isa.ver) /* ISA BCR absent, use Kconfig info */ |
158 | atomic = IS_ENABLED(CONFIG_ARC_HAS_LLSC); | 172 | atomic = IS_ENABLED(CONFIG_ARC_HAS_LLSC); |
173 | } else { | ||
174 | isa_nm = "ARCv2"; | ||
175 | be = cpu->isa.be; | ||
176 | atomic = cpu->isa.atomic; | ||
159 | } | 177 | } |
160 | 178 | ||
161 | n += scnprintf(buf + n, len - n, | 179 | n += scnprintf(buf + n, len - n, |
@@ -184,14 +202,31 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len) | |||
184 | IS_AVAIL1(cpu->timers.t0, "Timer0 "), | 202 | IS_AVAIL1(cpu->timers.t0, "Timer0 "), |
185 | IS_AVAIL1(cpu->timers.t1, "Timer1 ")); | 203 | IS_AVAIL1(cpu->timers.t1, "Timer1 ")); |
186 | 204 | ||
187 | n += i = scnprintf(buf + n, len - n, "%s%s", | 205 | n += i = scnprintf(buf + n, len - n, "%s%s%s%s%s", |
188 | IS_AVAIL2(atomic, "atomic ", CONFIG_ARC_HAS_LLSC)); | 206 | IS_AVAIL2(atomic, "atomic ", CONFIG_ARC_HAS_LLSC), |
207 | IS_AVAIL2(cpu->isa.ldd, "ll64 ", CONFIG_ARC_HAS_LL64), | ||
208 | IS_AVAIL1(cpu->isa.unalign, "unalign (not used)")); | ||
189 | 209 | ||
190 | if (i) | 210 | if (i) |
191 | n += scnprintf(buf + n, len - n, "\n\t\t: "); | 211 | n += scnprintf(buf + n, len - n, "\n\t\t: "); |
192 | 212 | ||
213 | if (cpu->extn_mpy.ver) { | ||
214 | if (cpu->extn_mpy.ver <= 0x2) { /* ARCompact */ | ||
215 | n += scnprintf(buf + n, len - n, "mpy "); | ||
216 | } else { | ||
217 | int opt = 2; /* stock MPY/MPYH */ | ||
218 | |||
219 | if (cpu->extn_mpy.dsp) /* OPT 7-9 */ | ||
220 | opt = cpu->extn_mpy.dsp + 6; | ||
221 | |||
222 | n += scnprintf(buf + n, len - n, "mpy[opt %d] ", opt); | ||
223 | } | ||
224 | n += scnprintf(buf + n, len - n, "%s", | ||
225 | IS_USED(CONFIG_ARC_HAS_HW_MPY)); | ||
226 | } | ||
227 | |||
193 | n += scnprintf(buf + n, len - n, "%s%s%s%s%s%s%s%s\n", | 228 | n += scnprintf(buf + n, len - n, "%s%s%s%s%s%s%s%s\n", |
194 | IS_AVAIL1(cpu->extn_mpy.ver, "mpy "), | 229 | IS_AVAIL1(cpu->isa.div_rem, "div_rem "), |
195 | IS_AVAIL1(cpu->extn.norm, "norm "), | 230 | IS_AVAIL1(cpu->extn.norm, "norm "), |
196 | IS_AVAIL1(cpu->extn.barrel, "barrel-shift "), | 231 | IS_AVAIL1(cpu->extn.barrel, "barrel-shift "), |
197 | IS_AVAIL1(cpu->extn.swap, "swap "), | 232 | IS_AVAIL1(cpu->extn.swap, "swap "), |
diff --git a/arch/arc/kernel/signal.c b/arch/arc/kernel/signal.c index b15d2fe9c461..004b7f0bc76c 100644 --- a/arch/arc/kernel/signal.c +++ b/arch/arc/kernel/signal.c | |||
@@ -336,7 +336,7 @@ static void arc_restart_syscall(struct k_sigaction *ka, struct pt_regs *regs) | |||
336 | * their orig user space value when we ret from kernel | 336 | * their orig user space value when we ret from kernel |
337 | */ | 337 | */ |
338 | regs->r0 = regs->orig_r0; | 338 | regs->r0 = regs->orig_r0; |
339 | regs->ret -= 4; | 339 | regs->ret -= is_isa_arcv2() ? 2 : 4; |
340 | break; | 340 | break; |
341 | } | 341 | } |
342 | } | 342 | } |
@@ -377,10 +377,10 @@ void do_signal(struct pt_regs *regs) | |||
377 | if (regs->r0 == -ERESTARTNOHAND || | 377 | if (regs->r0 == -ERESTARTNOHAND || |
378 | regs->r0 == -ERESTARTSYS || regs->r0 == -ERESTARTNOINTR) { | 378 | regs->r0 == -ERESTARTSYS || regs->r0 == -ERESTARTNOINTR) { |
379 | regs->r0 = regs->orig_r0; | 379 | regs->r0 = regs->orig_r0; |
380 | regs->ret -= 4; | 380 | regs->ret -= is_isa_arcv2() ? 2 : 4; |
381 | } else if (regs->r0 == -ERESTART_RESTARTBLOCK) { | 381 | } else if (regs->r0 == -ERESTART_RESTARTBLOCK) { |
382 | regs->r8 = __NR_restart_syscall; | 382 | regs->r8 = __NR_restart_syscall; |
383 | regs->ret -= 4; | 383 | regs->ret -= is_isa_arcv2() ? 2 : 4; |
384 | } | 384 | } |
385 | syscall_wont_restart(regs); /* No more restarts */ | 385 | syscall_wont_restart(regs); /* No more restarts */ |
386 | } | 386 | } |
diff --git a/arch/arc/kernel/troubleshoot.c b/arch/arc/kernel/troubleshoot.c index e00a01879025..e0cf99893212 100644 --- a/arch/arc/kernel/troubleshoot.c +++ b/arch/arc/kernel/troubleshoot.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/proc_fs.h> | 14 | #include <linux/proc_fs.h> |
15 | #include <linux/file.h> | 15 | #include <linux/file.h> |
16 | #include <asm/arcregs.h> | 16 | #include <asm/arcregs.h> |
17 | #include <asm/irqflags.h> | ||
17 | 18 | ||
18 | /* | 19 | /* |
19 | * Common routine to print scratch regs (r0-r12) or callee regs (r13-r25) | 20 | * Common routine to print scratch regs (r0-r12) or callee regs (r13-r25) |
@@ -34,7 +35,10 @@ static noinline void print_reg_file(long *reg_rev, int start_num) | |||
34 | n += scnprintf(buf + n, len - n, "\n"); | 35 | n += scnprintf(buf + n, len - n, "\n"); |
35 | 36 | ||
36 | /* because pt_regs has regs reversed: r12..r0, r25..r13 */ | 37 | /* because pt_regs has regs reversed: r12..r0, r25..r13 */ |
37 | reg_rev--; | 38 | if (is_isa_arcv2() && start_num == 0) |
39 | reg_rev++; | ||
40 | else | ||
41 | reg_rev--; | ||
38 | } | 42 | } |
39 | 43 | ||
40 | if (start_num != 0) | 44 | if (start_num != 0) |
@@ -152,6 +156,15 @@ static void show_ecr_verbose(struct pt_regs *regs) | |||
152 | ((cause_code == 0x02) ? "Write" : "EX")); | 156 | ((cause_code == 0x02) ? "Write" : "EX")); |
153 | } else if (vec == ECR_V_INSN_ERR) { | 157 | } else if (vec == ECR_V_INSN_ERR) { |
154 | pr_cont("Illegal Insn\n"); | 158 | pr_cont("Illegal Insn\n"); |
159 | #ifdef CONFIG_ISA_ARCV2 | ||
160 | } else if (vec == ECR_V_MEM_ERR) { | ||
161 | if (cause_code == 0x00) | ||
162 | pr_cont("Bus Error from Insn Mem\n"); | ||
163 | else if (cause_code == 0x10) | ||
164 | pr_cont("Bus Error from Data Mem\n"); | ||
165 | else | ||
166 | pr_cont("Bus Error, check PRM\n"); | ||
167 | #endif | ||
155 | } else { | 168 | } else { |
156 | pr_cont("Check Programmer's Manual\n"); | 169 | pr_cont("Check Programmer's Manual\n"); |
157 | } | 170 | } |
@@ -185,12 +198,20 @@ void show_regs(struct pt_regs *regs) | |||
185 | 198 | ||
186 | pr_info("[STAT32]: 0x%08lx", regs->status32); | 199 | pr_info("[STAT32]: 0x%08lx", regs->status32); |
187 | 200 | ||
188 | #define STS_BIT(r, bit) r->status32 & STATUS_##bit##_MASK ? #bit : "" | 201 | #define STS_BIT(r, bit) r->status32 & STATUS_##bit##_MASK ? #bit" " : "" |
189 | if (!user_mode(regs)) | ||
190 | pr_cont(" : %2s %2s %2s %2s %2s\n", | ||
191 | STS_BIT(regs, AE), STS_BIT(regs, A2), STS_BIT(regs, A1), | ||
192 | STS_BIT(regs, E2), STS_BIT(regs, E1)); | ||
193 | 202 | ||
203 | #ifdef CONFIG_ISA_ARCOMPACT | ||
204 | pr_cont(" : %2s%2s%2s%2s%2s%2s%2s\n", | ||
205 | (regs->status32 & STATUS_U_MASK) ? "U " : "K ", | ||
206 | STS_BIT(regs, DE), STS_BIT(regs, AE), | ||
207 | STS_BIT(regs, A2), STS_BIT(regs, A1), | ||
208 | STS_BIT(regs, E2), STS_BIT(regs, E1)); | ||
209 | #else | ||
210 | pr_cont(" : %2s%2s%2s%2s\n", | ||
211 | STS_BIT(regs, IE), | ||
212 | (regs->status32 & STATUS_U_MASK) ? "U " : "K ", | ||
213 | STS_BIT(regs, DE), STS_BIT(regs, AE)); | ||
214 | #endif | ||
194 | pr_info("BTA: 0x%08lx\t SP: 0x%08lx\t FP: 0x%08lx\n", | 215 | pr_info("BTA: 0x%08lx\t SP: 0x%08lx\t FP: 0x%08lx\n", |
195 | regs->bta, regs->sp, regs->fp); | 216 | regs->bta, regs->sp, regs->fp); |
196 | pr_info("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n", | 217 | pr_info("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n", |
diff --git a/arch/arc/mm/tlbex.S b/arch/arc/mm/tlbex.S index d224bf0feefc..00c8d7f772bc 100644 --- a/arch/arc/mm/tlbex.S +++ b/arch/arc/mm/tlbex.S | |||
@@ -35,8 +35,6 @@ | |||
35 | * Rahul Trivedi, Amit Bhor: Codito Technologies 2004 | 35 | * Rahul Trivedi, Amit Bhor: Codito Technologies 2004 |
36 | */ | 36 | */ |
37 | 37 | ||
38 | .cpu A7 | ||
39 | |||
40 | #include <linux/linkage.h> | 38 | #include <linux/linkage.h> |
41 | #include <asm/entry.h> | 39 | #include <asm/entry.h> |
42 | #include <asm/mmu.h> | 40 | #include <asm/mmu.h> |