Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull ARC updates from Vineet Gupta:

- fixes for -Wmissing-prototype warnings

- missing compiler barrier in relaxed atomics

- some uaccess simplification, declutter

- removal of massive glocal struct cpuinfo_arc from bootlog code

- __switch_to consolidation (removal of inline asm variant)

- use GP to cache task pointer (vs. r25)

- misc rework of entry code

* tag 'arc-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc: (24 commits)
ARC: boot log: fix warning
arc: Explicitly include correct DT includes
ARC: pt_regs: create seperate type for ecr
ARCv2: entry: rearrange pt_regs slightly
ARC: entry: replace 8 byte ADD.ne with 4 byte ADD2.ne
ARC: entry: replace 8 byte OR with 4 byte BSET
ARC: entry: Add more common chores to EXCEPTION_PROLOGUE
ARC: entry: EV_MachineCheck dont re-read ECR
ARC: entry: ARcompact EV_ProtV to use r10 directly
ARC: entry: rework (non-functional)
ARC: __switch_to: move ksp to thread_info from thread_struct
ARC: __switch_to: asm with dwarf ops (vs. inline asm)
ARC: kernel stack: INIT_THREAD need not setup @init_stack in @ksp
ARC: entry: use gp to cache task pointer (vs. r25)
ARC: boot log: eliminate struct cpuinfo_arc #4: boot log per ISA
ARC: boot log: eliminate struct cpuinfo_arc #3: don't export
ARC: boot log: eliminate struct cpuinfo_arc #2: cache
ARC: boot log: eliminate struct cpuinfo_arc #1: mm
ARCv2: memset: don't prefetch for len == 0 which happens a alot
ARC: uaccess: elide unaliged handling if hardware supports
...

+744 -1053
+5 -3
arch/arc/Kconfig
··· 27 27 select GENERIC_SCHED_CLOCK 28 28 select GENERIC_SMP_IDLE_THREAD 29 29 select GENERIC_IOREMAP 30 + select GENERIC_STRNCPY_FROM_USER if MMU 31 + select GENERIC_STRNLEN_USER if MMU 30 32 select HAVE_ARCH_KGDB 31 33 select HAVE_ARCH_TRACEHOOK 32 34 select HAVE_ARCH_TRANSPARENT_HUGEPAGE if ARC_MMU_V4 ··· 493 491 kernel-user gutter) 494 492 495 493 config ARC_CURR_IN_REG 496 - bool "Dedicate Register r25 for current_task pointer" 494 + bool "cache current task pointer in gp" 497 495 default y 498 496 help 499 - This reserved Register R25 to point to Current Task in 500 - kernel mode. This saves memory access for each such access 497 + This reserves gp register to point to Current Task in 498 + kernel mode eliding memory access for each access 501 499 502 500 503 501 config ARC_EMUL_UNALIGNED
+3 -3
arch/arc/Makefile
··· 28 28 endif 29 29 endif 30 30 31 - 32 31 ifdef CONFIG_ARC_CURR_IN_REG 33 32 # For a global register definition, make sure it gets passed to every file 34 33 # We had a customer reported bug where some code built in kernel was NOT using 35 - # any kernel headers, and missing the r25 global register 34 + # any kernel headers, and missing the global register 36 35 # Can't do unconditionally because of recursive include issues 37 36 # due to <linux/thread_info.h> 38 37 LINUXINCLUDE += -include $(srctree)/arch/arc/include/asm/current.h 38 + cflags-y += -ffixed-gp 39 39 endif 40 40 41 41 cflags-y += -fsection-anchors ··· 67 67 # small data is default for elf32 tool-chain. If not usable, disable it 68 68 # This also allows repurposing GP as scratch reg to gcc reg allocator 69 69 disable_small_data := y 70 - cflags-$(disable_small_data) += -mno-sdata -fcall-used-gp 70 + cflags-$(disable_small_data) += -mno-sdata 71 71 72 72 cflags-$(CONFIG_CPU_BIG_ENDIAN) += -mbig-endian 73 73 ldflags-$(CONFIG_CPU_BIG_ENDIAN) += -EB
+55 -44
arch/arc/include/asm/arcregs.h
··· 23 23 #define ARC_REG_ICCM_BUILD 0x78 /* ICCM size (common) */ 24 24 #define ARC_REG_XY_MEM_BCR 0x79 25 25 #define ARC_REG_MAC_BCR 0x7a 26 - #define ARC_REG_MUL_BCR 0x7b 26 + #define ARC_REG_MPY_BCR 0x7b 27 27 #define ARC_REG_SWAP_BCR 0x7c 28 28 #define ARC_REG_NORM_BCR 0x7d 29 29 #define ARC_REG_MIXMAX_BCR 0x7e ··· 177 177 #endif 178 178 }; 179 179 180 - struct bcr_uarch_build_arcv2 { 180 + struct bcr_uarch_build { 181 181 #ifdef CONFIG_CPU_BIG_ENDIAN 182 182 unsigned int pad:8, prod:8, maj:8, min:8; 183 183 #else 184 184 unsigned int min:8, maj:8, prod:8, pad:8; 185 + #endif 186 + }; 187 + 188 + struct bcr_mmu_3 { 189 + #ifdef CONFIG_CPU_BIG_ENDIAN 190 + unsigned int ver:8, ways:4, sets:4, res:3, sasid:1, pg_sz:4, 191 + u_itlb:4, u_dtlb:4; 192 + #else 193 + unsigned int u_dtlb:4, u_itlb:4, pg_sz:4, sasid:1, res:3, sets:4, 194 + ways:4, ver:8; 195 + #endif 196 + }; 197 + 198 + struct bcr_mmu_4 { 199 + #ifdef CONFIG_CPU_BIG_ENDIAN 200 + unsigned int ver:8, sasid:1, sz1:4, sz0:4, res:2, pae:1, 201 + n_ways:2, n_entry:2, n_super:2, u_itlb:3, u_dtlb:3; 202 + #else 203 + /* DTLB ITLB JES JE JA */ 204 + unsigned int u_dtlb:3, u_itlb:3, n_super:2, n_entry:2, n_ways:2, 205 + pae:1, res:2, sz0:4, sz1:4, sasid:1, ver:8; 206 + #endif 207 + }; 208 + 209 + struct bcr_cache { 210 + #ifdef CONFIG_CPU_BIG_ENDIAN 211 + unsigned int pad:12, line_len:4, sz:4, config:4, ver:8; 212 + #else 213 + unsigned int ver:8, config:4, sz:4, line_len:4, pad:12; 214 + #endif 215 + }; 216 + 217 + struct bcr_slc_cfg { 218 + #ifdef CONFIG_CPU_BIG_ENDIAN 219 + unsigned int pad:24, way:2, lsz:2, sz:4; 220 + #else 221 + unsigned int sz:4, lsz:2, way:2, pad:24; 222 + #endif 223 + }; 224 + 225 + struct bcr_clust_cfg { 226 + #ifdef CONFIG_CPU_BIG_ENDIAN 227 + unsigned int pad:7, c:1, num_entries:8, num_cores:8, ver:8; 228 + #else 229 + unsigned int ver:8, num_cores:8, num_entries:8, c:1, pad:7; 230 + #endif 231 + }; 232 + 233 + struct bcr_volatile { 234 + #ifdef CONFIG_CPU_BIG_ENDIAN 235 + unsigned int start:4, limit:4, pad:22, order:1, disable:1; 236 + #else 237 + unsigned int disable:1, order:1, pad:22, limit:4, start:4; 185 238 #endif 186 239 }; 187 240 ··· 354 301 unsigned int ver:8, info:24; 355 302 #endif 356 303 }; 357 - 358 - /* 359 - ******************************************************************* 360 - * Generic structures to hold build configuration used at runtime 361 - */ 362 - 363 - struct cpuinfo_arc_mmu { 364 - unsigned int ver:4, pg_sz_k:8, s_pg_sz_m:8, pad:10, sasid:1, pae:1; 365 - unsigned int sets:12, ways:4, u_dtlb:8, u_itlb:8; 366 - }; 367 - 368 - struct cpuinfo_arc_cache { 369 - unsigned int sz_k:14, line_len:8, assoc:4, alias:1, vipt:1, pad:4; 370 - }; 371 - 372 - struct cpuinfo_arc_bpu { 373 - unsigned int ver, full, num_cache, num_pred, ret_stk; 374 - }; 375 - 376 - struct cpuinfo_arc_ccm { 377 - unsigned int base_addr, sz; 378 - }; 379 - 380 - struct cpuinfo_arc { 381 - struct cpuinfo_arc_cache icache, dcache, slc; 382 - struct cpuinfo_arc_mmu mmu; 383 - struct cpuinfo_arc_bpu bpu; 384 - struct bcr_identity core; 385 - struct bcr_isa_arcv2 isa; 386 - const char *release, *name; 387 - unsigned int vec_base; 388 - struct cpuinfo_arc_ccm iccm, dccm; 389 - struct { 390 - unsigned int swap:1, norm:1, minmax:1, barrel:1, crc:1, swape:1, pad1:2, 391 - fpu_sp:1, fpu_dp:1, dual:1, dual_enb:1, pad2:4, 392 - ap_num:4, ap_full:1, smart:1, rtt:1, pad3:1, 393 - timer0:1, timer1:1, rtc:1, gfrc:1, pad4:4; 394 - } extn; 395 - struct bcr_mpy extn_mpy; 396 - }; 397 - 398 - extern struct cpuinfo_arc cpuinfo_arc700[]; 399 304 400 305 static inline int is_isa_arcv2(void) 401 306 {
+3 -3
arch/arc/include/asm/atomic-llsc.h
··· 18 18 : [val] "=&r" (val) /* Early clobber to prevent reg reuse */ \ 19 19 : [ctr] "r" (&v->counter), /* Not "m": llock only supports reg direct addr mode */ \ 20 20 [i] "ir" (i) \ 21 - : "cc"); \ 21 + : "cc", "memory"); \ 22 22 } \ 23 23 24 24 #define ATOMIC_OP_RETURN(op, asm_op) \ ··· 34 34 : [val] "=&r" (val) \ 35 35 : [ctr] "r" (&v->counter), \ 36 36 [i] "ir" (i) \ 37 - : "cc"); \ 37 + : "cc", "memory"); \ 38 38 \ 39 39 return val; \ 40 40 } ··· 56 56 [orig] "=&r" (orig) \ 57 57 : [ctr] "r" (&v->counter), \ 58 58 [i] "ir" (i) \ 59 - : "cc"); \ 59 + : "cc", "memory"); \ 60 60 \ 61 61 return orig; \ 62 62 }
+3 -3
arch/arc/include/asm/atomic64-arcv2.h
··· 60 60 " bnz 1b \n" \ 61 61 : "=&r"(val) \ 62 62 : "r"(&v->counter), "ir"(a) \ 63 - : "cc"); \ 63 + : "cc", "memory"); \ 64 64 } \ 65 65 66 66 #define ATOMIC64_OP_RETURN(op, op1, op2) \ ··· 77 77 " bnz 1b \n" \ 78 78 : [val] "=&r"(val) \ 79 79 : "r"(&v->counter), "ir"(a) \ 80 - : "cc"); /* memory clobber comes from smp_mb() */ \ 80 + : "cc", "memory"); \ 81 81 \ 82 82 return val; \ 83 83 } ··· 99 99 " bnz 1b \n" \ 100 100 : "=&r"(orig), "=&r"(val) \ 101 101 : "r"(&v->counter), "ir"(a) \ 102 - : "cc"); /* memory clobber comes from smp_mb() */ \ 102 + : "cc", "memory"); \ 103 103 \ 104 104 return orig; \ 105 105 }
+1 -1
arch/arc/include/asm/current.h
··· 13 13 14 14 #ifdef CONFIG_ARC_CURR_IN_REG 15 15 16 - register struct task_struct *curr_arc asm("r25"); 16 + register struct task_struct *curr_arc asm("gp"); 17 17 #define current (curr_arc) 18 18 19 19 #else
+20 -12
arch/arc/include/asm/dwarf.h
··· 10 10 11 11 #ifdef ARC_DW2_UNWIND_AS_CFI 12 12 13 - #define CFI_STARTPROC .cfi_startproc 14 - #define CFI_ENDPROC .cfi_endproc 15 - #define CFI_DEF_CFA .cfi_def_cfa 16 - #define CFI_REGISTER .cfi_register 17 - #define CFI_REL_OFFSET .cfi_rel_offset 18 - #define CFI_UNDEFINED .cfi_undefined 13 + #define CFI_STARTPROC .cfi_startproc 14 + #define CFI_ENDPROC .cfi_endproc 15 + #define CFI_DEF_CFA .cfi_def_cfa 16 + #define CFI_DEF_CFA_OFFSET .cfi_def_cfa_offset 17 + #define CFI_DEF_CFA_REGISTER .cfi_def_cfa_register 18 + #define CFI_OFFSET .cfi_offset 19 + #define CFI_REL_OFFSET .cfi_rel_offset 20 + #define CFI_REGISTER .cfi_register 21 + #define CFI_RESTORE .cfi_restore 22 + #define CFI_UNDEFINED .cfi_undefined 19 23 20 24 #else 21 25 22 26 #define CFI_IGNORE # 23 27 24 - #define CFI_STARTPROC CFI_IGNORE 25 - #define CFI_ENDPROC CFI_IGNORE 26 - #define CFI_DEF_CFA CFI_IGNORE 27 - #define CFI_REGISTER CFI_IGNORE 28 - #define CFI_REL_OFFSET CFI_IGNORE 29 - #define CFI_UNDEFINED CFI_IGNORE 28 + #define CFI_STARTPROC CFI_IGNORE 29 + #define CFI_ENDPROC CFI_IGNORE 30 + #define CFI_DEF_CFA CFI_IGNORE 31 + #define CFI_DEF_CFA_OFFSET CFI_IGNORE 32 + #define CFI_DEF_CFA_REGISTER CFI_IGNORE 33 + #define CFI_OFFSET CFI_IGNORE 34 + #define CFI_REL_OFFSET CFI_IGNORE 35 + #define CFI_REGISTER CFI_IGNORE 36 + #define CFI_RESTORE CFI_IGNORE 37 + #define CFI_UNDEFINED CFI_IGNORE 30 38 31 39 #endif /* !ARC_DW2_UNWIND_AS_CFI */ 32 40
+38 -28
arch/arc/include/asm/entry-arcv2.h
··· 18 18 * | orig_r0 | 19 19 * | event/ECR | 20 20 * | bta | 21 - * | user_r25 | 22 21 * | gp | 23 22 * | fp | 24 23 * | sp | ··· 48 49 /*------------------------------------------------------------------------*/ 49 50 .macro INTERRUPT_PROLOGUE 50 51 51 - ; (A) Before jumping to Interrupt Vector, hardware micro-ops did following: 52 + ; Before jumping to Interrupt Vector, hardware micro-ops did following: 52 53 ; 1. SP auto-switched to kernel mode stack 53 54 ; 2. STATUS32.Z flag set if in U mode at time of interrupt (U:1,K:0) 54 55 ; 3. Auto save: (mandatory) Push PC and STAT32 on stack 55 56 ; hardware does even if CONFIG_ARC_IRQ_NO_AUTOSAVE 56 - ; 4. Auto save: (optional) r0-r11, blink, LPE,LPS,LPC, JLI,LDI,EI 57 + ; 4a. Auto save: (optional) r0-r11, blink, LPE,LPS,LPC, JLI,LDI,EI 57 58 ; 58 - ; (B) Manually saved some regs: r12,r25,r30, sp,fp,gp, ACCL pair 59 + ; Now 60 + ; 4b. If Auto-save (optional) not enabled in hw, manually save them 61 + ; 5. Manually save: r12,r30, sp,fp,gp, ACCL pair 62 + ; 63 + ; At the end, SP points to pt_regs 59 64 60 65 #ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE 61 66 ; carve pt_regs on stack (case #3), PC/STAT32 already on stack ··· 75 72 .endm 76 73 77 74 /*------------------------------------------------------------------------*/ 78 - .macro EXCEPTION_PROLOGUE 75 + .macro EXCEPTION_PROLOGUE_KEEP_AE 79 76 80 - ; (A) Before jumping to Exception Vector, hardware micro-ops did following: 77 + ; Before jumping to Exception Vector, hardware micro-ops did following: 81 78 ; 1. SP auto-switched to kernel mode stack 82 79 ; 2. STATUS32.Z flag set if in U mode at time of exception (U:1,K:0) 83 80 ; 84 - ; (B) Manually save the complete reg file below 81 + ; Now manually save rest of reg file 82 + ; At the end, SP points to pt_regs 85 83 86 - sub sp, sp, SZ_PT_REGS ; carve pt_regs 84 + sub sp, sp, SZ_PT_REGS ; carve space for pt_regs 87 85 88 86 ; _HARD saves r10 clobbered by _SOFT as scratch hence comes first 89 87 ··· 102 98 ST2 r10, r11, PT_event 103 99 104 100 ; OUTPUT: r10 has ECR expected by EV_Trap 101 + .endm 102 + 103 + .macro EXCEPTION_PROLOGUE 104 + 105 + EXCEPTION_PROLOGUE_KEEP_AE ; return ECR in r10 106 + 107 + lr r0, [efa] 108 + mov r1, sp 109 + 110 + FAKE_RET_FROM_EXCPN ; clobbers r9 105 111 .endm 106 112 107 113 /*------------------------------------------------------------------------ ··· 149 135 */ 150 136 .macro __SAVE_REGFILE_SOFT 151 137 152 - ST2 gp, fp, PT_r26 ; gp (r26), fp (r27) 153 - 154 - st r12, [sp, PT_sp + 4] 155 - st r30, [sp, PT_sp + 8] 138 + st fp, [sp, PT_fp] ; r27 139 + st r30, [sp, PT_r30] 140 + st r12, [sp, PT_r12] 141 + st r26, [sp, PT_r26] ; gp 156 142 157 143 ; Saving pt_regs->sp correctly requires some extra work due to the way 158 144 ; Auto stack switch works ··· 167 153 168 154 ; ISA requires ADD.nz to have same dest and src reg operands 169 155 mov.nz r10, sp 170 - add.nz r10, r10, SZ_PT_REGS ; K mode SP 156 + add2.nz r10, r10, SZ_PT_REGS/4 ; K mode SP 171 157 172 158 st r10, [sp, PT_sp] ; SP (pt_regs->sp) 173 - 174 - #ifdef CONFIG_ARC_CURR_IN_REG 175 - st r25, [sp, PT_user_r25] 176 - GET_CURR_TASK_ON_CPU r25 177 - #endif 178 159 179 160 #ifdef CONFIG_ARC_HAS_ACCL_REGS 180 161 ST2 r58, r59, PT_r58 ··· 177 168 178 169 /* clobbers r10, r11 registers pair */ 179 170 DSP_SAVE_REGFILE_IRQ 171 + 172 + #ifdef CONFIG_ARC_CURR_IN_REG 173 + GET_CURR_TASK_ON_CPU gp 174 + #endif 175 + 180 176 .endm 181 177 182 178 /*------------------------------------------------------------------------*/ 183 179 .macro __RESTORE_REGFILE_SOFT 184 180 185 - LD2 gp, fp, PT_r26 ; gp (r26), fp (r27) 186 - 187 - ld r12, [sp, PT_r12] 181 + ld fp, [sp, PT_fp] 188 182 ld r30, [sp, PT_r30] 183 + ld r12, [sp, PT_r12] 184 + ld r26, [sp, PT_r26] 189 185 190 186 ; Restore SP (into AUX_USER_SP) only if returning to U mode 191 187 ; - for K mode, it will be implicitly restored as stack is unwound ··· 201 187 ld r10, [sp, PT_sp] ; SP (pt_regs->sp) 202 188 sr r10, [AUX_USER_SP] 203 189 1: 204 - 205 - #ifdef CONFIG_ARC_CURR_IN_REG 206 - ld r25, [sp, PT_user_r25] 207 - #endif 208 190 209 191 /* clobbers r10, r11 registers pair */ 210 192 DSP_RESTORE_REGFILE_IRQ ··· 259 249 260 250 btst r0, STATUS_U_BIT ; Z flag set if K, used in restoring SP 261 251 262 - ld r10, [sp, PT_event + 4] 252 + ld r10, [sp, PT_bta] 263 253 sr r10, [erbta] 264 254 265 255 LD2 r10, r11, PT_ret ··· 274 264 275 265 .macro FAKE_RET_FROM_EXCPN 276 266 lr r9, [status32] 277 - bic r9, r9, STATUS_AE_MASK 278 - or r9, r9, STATUS_IE_MASK 267 + bclr r9, r9, STATUS_AE_BIT 268 + bset r9, r9, STATUS_IE_BIT 279 269 kflag r9 280 270 .endm 281 271
+24 -26
arch/arc/include/asm/entry-compact.h
··· 140 140 * 141 141 * After this it is safe to call the "C" handlers 142 142 *-------------------------------------------------------------*/ 143 - .macro EXCEPTION_PROLOGUE 143 + .macro EXCEPTION_PROLOGUE_KEEP_AE 144 144 145 145 /* Need at least 1 reg to code the early exception prologue */ 146 146 PROLOG_FREEUP_REG r9, @ex_saved_reg1 ··· 150 150 151 151 /* ARC700 doesn't provide auto-stack switching */ 152 152 SWITCH_TO_KERNEL_STK 153 - 154 - #ifdef CONFIG_ARC_CURR_IN_REG 155 - /* Treat r25 as scratch reg (save on stack) and load with "current" */ 156 - PUSH r25 157 - GET_CURR_TASK_ON_CPU r25 158 - #else 159 - sub sp, sp, 4 160 - #endif 161 153 162 154 st.a r0, [sp, -8] /* orig_r0 needed for syscall (skip ECR slot) */ 163 155 sub sp, sp, 4 /* skip pt_regs->sp, already saved above */ ··· 170 178 PUSHAX erbta 171 179 172 180 lr r10, [ecr] 173 - st r10, [sp, PT_event] /* EV_Trap expects r10 to have ECR */ 181 + st r10, [sp, PT_event] 182 + 183 + #ifdef CONFIG_ARC_CURR_IN_REG 184 + /* gp already saved on stack: now load with "current" */ 185 + GET_CURR_TASK_ON_CPU gp 186 + #endif 187 + ; OUTPUT: r10 has ECR expected by EV_Trap 188 + .endm 189 + 190 + .macro EXCEPTION_PROLOGUE 191 + 192 + EXCEPTION_PROLOGUE_KEEP_AE ; return ECR in r10 193 + 194 + lr r0, [efa] 195 + mov r1, sp 196 + 197 + FAKE_RET_FROM_EXCPN ; clobbers r9 174 198 .endm 175 199 176 200 /*-------------------------------------------------------------- ··· 216 208 POP gp 217 209 RESTORE_R12_TO_R0 218 210 219 - #ifdef CONFIG_ARC_CURR_IN_REG 220 - ld r25, [sp, 12] 221 - #endif 222 211 ld sp, [sp] /* restore original sp */ 223 - /* orig_r0, ECR, user_r25 skipped automatically */ 212 + /* orig_r0, ECR skipped automatically */ 224 213 .endm 225 214 226 215 /* Dummy ECR values for Interrupts */ ··· 234 229 235 230 SWITCH_TO_KERNEL_STK 236 231 237 - #ifdef CONFIG_ARC_CURR_IN_REG 238 - /* Treat r25 as scratch reg (save on stack) and load with "current" */ 239 - PUSH r25 240 - GET_CURR_TASK_ON_CPU r25 241 - #else 242 - sub sp, sp, 4 243 - #endif 244 232 245 233 PUSH 0x003\LVL\()abcd /* Dummy ECR */ 246 234 sub sp, sp, 8 /* skip orig_r0 (not needed) ··· 253 255 PUSHAX lp_start 254 256 PUSHAX bta_l\LVL\() 255 257 258 + #ifdef CONFIG_ARC_CURR_IN_REG 259 + /* gp already saved on stack: now load with "current" */ 260 + GET_CURR_TASK_ON_CPU gp 261 + #endif 256 262 .endm 257 263 258 264 /*-------------------------------------------------------------- ··· 284 282 POP gp 285 283 RESTORE_R12_TO_R0 286 284 287 - #ifdef CONFIG_ARC_CURR_IN_REG 288 - ld r25, [sp, 12] 289 - #endif 290 - ld sp, [sp] /* restore original sp */ 291 - /* orig_r0, ECR, user_r25 skipped automatically */ 285 + ld sp, [sp] /* restore original sp; orig_r0, ECR skipped implicitly */ 292 286 .endm 293 287 294 288 /* Get thread_info of "current" tsk */
+52 -80
arch/arc/include/asm/entry.h
··· 13 13 #include <asm/processor.h> /* For VMALLOC_START */ 14 14 #include <asm/mmu.h> 15 15 16 + #ifdef __ASSEMBLY__ 17 + 16 18 #ifdef CONFIG_ISA_ARCOMPACT 17 19 #include <asm/entry-compact.h> /* ISA specific bits */ 18 20 #else ··· 91 89 * Helpers to save/restore callee-saved regs: 92 90 * used by several macros below 93 91 *-------------------------------------------------------------*/ 94 - .macro SAVE_R13_TO_R24 92 + .macro SAVE_R13_TO_R25 95 93 PUSH r13 96 94 PUSH r14 97 95 PUSH r15 ··· 104 102 PUSH r22 105 103 PUSH r23 106 104 PUSH r24 105 + PUSH r25 107 106 .endm 108 107 109 - .macro RESTORE_R24_TO_R13 108 + .macro RESTORE_R25_TO_R13 109 + POP r25 110 110 POP r24 111 111 POP r23 112 112 POP r22 ··· 123 119 POP r13 124 120 .endm 125 121 126 - /*-------------------------------------------------------------- 127 - * Collect User Mode callee regs as struct callee_regs - needed by 128 - * fork/do_signal/unaligned-access-emulation. 129 - * (By default only scratch regs are saved on entry to kernel) 130 - * 131 - * Special handling for r25 if used for caching Task Pointer. 132 - * It would have been saved in task->thread.user_r25 already, but to keep 133 - * the interface same it is copied into regular r25 placeholder in 134 - * struct callee_regs. 135 - *-------------------------------------------------------------*/ 122 + /* 123 + * save user mode callee regs as struct callee_regs 124 + * - needed by fork/do_signal/unaligned-access-emulation. 125 + */ 136 126 .macro SAVE_CALLEE_SAVED_USER 137 - 138 - mov r12, sp ; save SP as ref to pt_regs 139 - SAVE_R13_TO_R24 140 - 141 - #ifdef CONFIG_ARC_CURR_IN_REG 142 - ; Retrieve orig r25 and save it with rest of callee_regs 143 - ld r12, [r12, PT_user_r25] 144 - PUSH r12 145 - #else 146 - PUSH r25 147 - #endif 148 - 127 + SAVE_R13_TO_R25 149 128 .endm 150 129 151 - /*-------------------------------------------------------------- 152 - * Save kernel Mode callee regs at the time of Contect Switch. 153 - * 154 - * Special handling for r25 if used for caching Task Pointer. 155 - * Kernel simply skips saving it since it will be loaded with 156 - * incoming task pointer anyways 157 - *-------------------------------------------------------------*/ 158 - .macro SAVE_CALLEE_SAVED_KERNEL 159 - 160 - SAVE_R13_TO_R24 161 - 162 - #ifdef CONFIG_ARC_CURR_IN_REG 163 - sub sp, sp, 4 164 - #else 165 - PUSH r25 166 - #endif 167 - .endm 168 - 169 - /*-------------------------------------------------------------- 170 - * Opposite of SAVE_CALLEE_SAVED_KERNEL 171 - *-------------------------------------------------------------*/ 172 - .macro RESTORE_CALLEE_SAVED_KERNEL 173 - 174 - #ifdef CONFIG_ARC_CURR_IN_REG 175 - add sp, sp, 4 /* skip usual r25 placeholder */ 176 - #else 177 - POP r25 178 - #endif 179 - RESTORE_R24_TO_R13 180 - .endm 181 - 182 - /*-------------------------------------------------------------- 183 - * Opposite of SAVE_CALLEE_SAVED_USER 184 - * 185 - * ptrace tracer or unaligned-access fixup might have changed a user mode 186 - * callee reg which is saved back to usual r25 storage location 187 - *-------------------------------------------------------------*/ 130 + /* 131 + * restore user mode callee regs as struct callee_regs 132 + * - could have been changed by ptrace tracer or unaligned-access fixup 133 + */ 188 134 .macro RESTORE_CALLEE_SAVED_USER 135 + RESTORE_R25_TO_R13 136 + .endm 189 137 190 - #ifdef CONFIG_ARC_CURR_IN_REG 191 - POP r12 192 - #else 193 - POP r25 194 - #endif 195 - RESTORE_R24_TO_R13 138 + /* 139 + * save/restore kernel mode callee regs at the time of context switch 140 + */ 141 + .macro SAVE_CALLEE_SAVED_KERNEL 142 + SAVE_R13_TO_R25 143 + .endm 196 144 197 - ; SP is back to start of pt_regs 198 - #ifdef CONFIG_ARC_CURR_IN_REG 199 - st r12, [sp, PT_user_r25] 200 - #endif 145 + .macro RESTORE_CALLEE_SAVED_KERNEL 146 + RESTORE_R25_TO_R13 201 147 .endm 202 148 203 149 /*-------------------------------------------------------------- ··· 183 229 184 230 #ifdef CONFIG_SMP 185 231 186 - /*------------------------------------------------- 232 + /* 187 233 * Retrieve the current running task on this CPU 188 - * 1. Determine curr CPU id. 189 - * 2. Use it to index into _current_task[ ] 234 + * - loads it from backing _current_task[] (and can't use the 235 + * caching reg for current task 190 236 */ 191 237 .macro GET_CURR_TASK_ON_CPU reg 192 238 GET_CPU_ID \reg ··· 208 254 add2 \tmp, @_current_task, \tmp 209 255 st \tsk, [\tmp] 210 256 #ifdef CONFIG_ARC_CURR_IN_REG 211 - mov r25, \tsk 257 + mov gp, \tsk 212 258 #endif 213 259 214 260 .endm ··· 223 269 .macro SET_CURR_TASK_ON_CPU tsk, tmp 224 270 st \tsk, [@_current_task] 225 271 #ifdef CONFIG_ARC_CURR_IN_REG 226 - mov r25, \tsk 272 + mov gp, \tsk 227 273 #endif 228 274 .endm 229 275 230 276 #endif /* SMP / UNI */ 231 277 232 - /* ------------------------------------------------------------------ 278 + /* 233 279 * Get the ptr to some field of Current Task at @off in task struct 234 - * -Uses r25 for Current task ptr if that is enabled 280 + * - Uses current task cached in reg if enabled 235 281 */ 236 - 237 282 #ifdef CONFIG_ARC_CURR_IN_REG 238 283 239 284 .macro GET_CURR_TASK_FIELD_PTR off, reg 240 - add \reg, r25, \off 285 + add \reg, gp, \off 241 286 .endm 242 287 243 288 #else ··· 247 294 .endm 248 295 249 296 #endif /* CONFIG_ARC_CURR_IN_REG */ 297 + 298 + #else /* !__ASSEMBLY__ */ 299 + 300 + extern void do_signal(struct pt_regs *); 301 + extern void do_notify_resume(struct pt_regs *); 302 + extern int do_privilege_fault(unsigned long, struct pt_regs *); 303 + extern int do_extension_fault(unsigned long, struct pt_regs *); 304 + extern int insterror_is_error(unsigned long, struct pt_regs *); 305 + extern int do_memory_error(unsigned long, struct pt_regs *); 306 + extern int trap_is_brkpt(unsigned long, struct pt_regs *); 307 + extern int do_misaligned_error(unsigned long, struct pt_regs *); 308 + extern int do_trap5_error(unsigned long, struct pt_regs *); 309 + extern int do_misaligned_access(unsigned long, struct pt_regs *, struct callee_regs *); 310 + extern void do_machine_check_fault(unsigned long, struct pt_regs *); 311 + extern void do_non_swi_trap(unsigned long, struct pt_regs *); 312 + extern void do_insterror_or_kprobe(unsigned long, struct pt_regs *); 313 + extern void do_page_fault(unsigned long, struct pt_regs *); 314 + 315 + #endif 250 316 251 317 #endif /* __ASM_ARC_ENTRY_H */
+1
arch/arc/include/asm/irq.h
··· 25 25 #include <asm-generic/irq.h> 26 26 27 27 extern void arc_init_IRQ(void); 28 + extern void arch_do_IRQ(unsigned int, struct pt_regs *); 28 29 29 30 #endif
+2
arch/arc/include/asm/mmu.h
··· 14 14 unsigned long asid[NR_CPUS]; /* 8 bit MMU PID + Generation cycle */ 15 15 } mm_context_t; 16 16 17 + extern void do_tlb_overlap_fault(unsigned long, unsigned long, struct pt_regs *); 18 + 17 19 #endif 18 20 19 21 #include <asm/mmu-arcv2.h>
+2 -5
arch/arc/include/asm/processor.h
··· 22 22 * struct thread_info 23 23 */ 24 24 struct thread_struct { 25 - unsigned long ksp; /* kernel mode stack pointer */ 26 25 unsigned long callee_reg; /* pointer to callee regs */ 27 26 unsigned long fault_address; /* dbls as brkpt holder as well */ 28 27 #ifdef CONFIG_ARC_DSP_SAVE_RESTORE_REGS ··· 32 33 #endif 33 34 }; 34 35 35 - #define INIT_THREAD { \ 36 - .ksp = sizeof(init_stack) + (unsigned long) init_stack, \ 37 - } 36 + #define INIT_THREAD { } 38 37 39 38 /* Forward declaration, a strange C thing */ 40 39 struct task_struct; ··· 53 56 * Where about of Task's sp, fp, blink when it was last seen in kernel mode. 54 57 * Look in process.c for details of kernel stack layout 55 58 */ 56 - #define TSK_K_ESP(tsk) (tsk->thread.ksp) 59 + #define TSK_K_ESP(tsk) (task_thread_info(tsk)->ksp) 57 60 58 61 #define TSK_K_REG(tsk, off) (*((unsigned long *)(TSK_K_ESP(tsk) + \ 59 62 sizeof(struct callee_regs) + off)))
+27 -38
arch/arc/include/asm/ptrace.h
··· 12 12 13 13 #ifndef __ASSEMBLY__ 14 14 15 + typedef union { 16 + struct { 17 + #ifdef CONFIG_CPU_BIG_ENDIAN 18 + unsigned long state:8, vec:8, cause:8, param:8; 19 + #else 20 + unsigned long param:8, cause:8, vec:8, state:8; 21 + #endif 22 + }; 23 + unsigned long full; 24 + } ecr_reg; 25 + 15 26 /* THE pt_regs: Defines how regs are saved during entry into kernel */ 16 27 17 28 #ifdef CONFIG_ISA_ARCOMPACT ··· 51 40 * Last word used by Linux for extra state mgmt (syscall-restart) 52 41 * For interrupts, use artificial ECR values to note current prio-level 53 42 */ 54 - union { 55 - struct { 56 - #ifdef CONFIG_CPU_BIG_ENDIAN 57 - unsigned long state:8, ecr_vec:8, 58 - ecr_cause:8, ecr_param:8; 59 - #else 60 - unsigned long ecr_param:8, ecr_cause:8, 61 - ecr_vec:8, state:8; 62 - #endif 63 - }; 64 - unsigned long event; 65 - }; 66 - 67 - unsigned long user_r25; 43 + ecr_reg ecr; 68 44 }; 69 45 70 - #define MAX_REG_OFFSET offsetof(struct pt_regs, user_r25) 46 + #define MAX_REG_OFFSET offsetof(struct pt_regs, ecr) 71 47 72 48 #else 73 49 ··· 62 64 63 65 unsigned long orig_r0; 64 66 65 - union { 66 - struct { 67 - #ifdef CONFIG_CPU_BIG_ENDIAN 68 - unsigned long state:8, ecr_vec:8, 69 - ecr_cause:8, ecr_param:8; 70 - #else 71 - unsigned long ecr_param:8, ecr_cause:8, 72 - ecr_vec:8, state:8; 73 - #endif 74 - }; 75 - unsigned long event; 76 - }; 67 + ecr_reg ecr; /* Exception Cause Reg */ 77 68 78 - unsigned long bta; /* bta_l1, bta_l2, erbta */ 69 + unsigned long bta; /* erbta */ 79 70 80 - unsigned long user_r25; 81 - 82 - unsigned long r26; /* gp */ 83 71 unsigned long fp; 84 - unsigned long sp; /* user/kernel sp depending on where we came from */ 85 - 86 - unsigned long r12, r30; 72 + unsigned long r30; 73 + unsigned long r12; 74 + unsigned long r26; /* gp */ 87 75 88 76 #ifdef CONFIG_ARC_HAS_ACCL_REGS 89 77 unsigned long r58, r59; /* ACCL/ACCH used by FPU / DSP MPY */ ··· 77 93 #ifdef CONFIG_ARC_DSP_SAVE_RESTORE_REGS 78 94 unsigned long DSP_CTRL; 79 95 #endif 96 + 97 + unsigned long sp; /* user/kernel sp depending on entry */ 80 98 81 99 /*------- Below list auto saved by h/w -----------*/ 82 100 unsigned long r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11; ··· 120 134 /* return 1 if PC in delay slot */ 121 135 #define delay_mode(regs) ((regs->status32 & STATUS_DE_MASK) == STATUS_DE_MASK) 122 136 123 - #define in_syscall(regs) ((regs->ecr_vec == ECR_V_TRAP) && !regs->ecr_param) 124 - #define in_brkpt_trap(regs) ((regs->ecr_vec == ECR_V_TRAP) && regs->ecr_param) 137 + #define in_syscall(regs) ((regs->ecr.vec == ECR_V_TRAP) && !regs->ecr.param) 138 + #define in_brkpt_trap(regs) ((regs->ecr.vec == ECR_V_TRAP) && regs->ecr.param) 125 139 126 140 #define STATE_SCALL_RESTARTED 0x01 127 141 128 - #define syscall_wont_restart(reg) (reg->state |= STATE_SCALL_RESTARTED) 129 - #define syscall_restartable(reg) !(reg->state & STATE_SCALL_RESTARTED) 142 + #define syscall_wont_restart(regs) (regs->ecr.state |= STATE_SCALL_RESTARTED) 143 + #define syscall_restartable(regs) !(regs->ecr.state & STATE_SCALL_RESTARTED) 130 144 131 145 #define current_pt_regs() \ 132 146 ({ \ ··· 166 180 167 181 return *(unsigned long *)((unsigned long)regs + offset); 168 182 } 183 + 184 + extern int syscall_trace_entry(struct pt_regs *); 185 + extern void syscall_trace_exit(struct pt_regs *); 169 186 170 187 #endif /* !__ASSEMBLY__ */ 171 188
+4 -4
arch/arc/include/asm/setup.h
··· 35 35 #define IS_AVAIL3(v, v2, s) IS_AVAIL1(v, s), IS_AVAIL1(v, IS_DISABLED_RUN(v2)) 36 36 37 37 extern void arc_mmu_init(void); 38 - extern char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len); 39 - extern void read_decode_mmu_bcr(void); 38 + extern int arc_mmu_mumbojumbo(int cpu_id, char *buf, int len); 40 39 41 40 extern void arc_cache_init(void); 42 - extern char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len); 43 - extern void read_decode_cache_bcr(void); 41 + extern int arc_cache_mumbojumbo(int cpu_id, char *buf, int len); 42 + 43 + extern void __init handle_uboot_args(void); 44 44 45 45 #endif /* __ASMARC_SETUP_H */
+2
arch/arc/include/asm/smp.h
··· 29 29 extern void __init smp_init_cpus(void); 30 30 extern void first_lines_of_secondary(void); 31 31 extern const char *arc_platform_smp_cpuinfo(void); 32 + extern void arc_platform_smp_wait_to_boot(int); 33 + extern void start_kernel_secondary(void); 32 34 33 35 /* 34 36 * API expected BY platform smp code (FROM arch smp code)
+5 -5
arch/arc/include/asm/thread_info.h
··· 37 37 */ 38 38 struct thread_info { 39 39 unsigned long flags; /* low level flags */ 40 + unsigned long ksp; /* kernel mode stack top in __switch_to */ 40 41 int preempt_count; /* 0 => preemptable, <0 => BUG */ 41 - struct task_struct *task; /* main task structure */ 42 - __u32 cpu; /* current CPU */ 42 + int cpu; /* current CPU */ 43 43 unsigned long thr_ptr; /* TLS ptr */ 44 + struct task_struct *task; /* main task structure */ 44 45 }; 45 46 46 47 /* 47 - * macros/functions for gaining access to the thread information structure 48 - * 49 - * preempt_count needs to be 1 initially, until the scheduler is functional. 48 + * initilaize thread_info for any @tsk 49 + * - this is not related to init_task per se 50 50 */ 51 51 #define INIT_THREAD_INFO(tsk) \ 52 52 { \
+8 -13
arch/arc/include/asm/uaccess.h
··· 146 146 if (n == 0) 147 147 return 0; 148 148 149 - /* unaligned */ 150 - if (((unsigned long)to & 0x3) || ((unsigned long)from & 0x3)) { 149 + /* fallback for unaligned access when hardware doesn't support */ 150 + if (!IS_ENABLED(CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS) && 151 + (((unsigned long)to & 0x3) || ((unsigned long)from & 0x3))) { 151 152 152 153 unsigned char tmp; 153 154 ··· 374 373 if (n == 0) 375 374 return 0; 376 375 377 - /* unaligned */ 378 - if (((unsigned long)to & 0x3) || ((unsigned long)from & 0x3)) { 376 + /* fallback for unaligned access when hardware doesn't support */ 377 + if (!IS_ENABLED(CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS) && 378 + (((unsigned long)to & 0x3) || ((unsigned long)from & 0x3))) { 379 379 380 380 unsigned char tmp; 381 381 ··· 586 584 return res; 587 585 } 588 586 589 - static inline unsigned long __arc_clear_user(void __user *to, unsigned long n) 587 + static inline unsigned long __clear_user(void __user *to, unsigned long n) 590 588 { 591 589 long res = n; 592 590 unsigned char *d_char = to; ··· 628 626 return res; 629 627 } 630 628 631 - #ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE 632 - 633 629 #define INLINE_COPY_TO_USER 634 630 #define INLINE_COPY_FROM_USER 635 631 636 - #define __clear_user(d, n) __arc_clear_user(d, n) 637 - #else 638 - extern unsigned long arc_clear_user_noinline(void __user *to, 639 - unsigned long n); 640 - #define __clear_user(d, n) arc_clear_user_noinline(d, n) 641 - #endif 632 + #define __clear_user __clear_user 642 633 643 634 #include <asm-generic/uaccess.h> 644 635
+2 -7
arch/arc/kernel/Makefile
··· 5 5 6 6 obj-y := head.o arcksyms.o setup.o irq.o reset.o ptrace.o process.o devtree.o 7 7 obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o 8 + obj-y += ctx_sw_asm.o 9 + 8 10 obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o 9 11 obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o 10 12 ··· 24 22 obj-$(CONFIG_ARC_FPU_SAVE_RESTORE) += fpu.o 25 23 ifdef CONFIG_ISA_ARCOMPACT 26 24 CFLAGS_fpu.o += -mdpfp 27 - endif 28 - 29 - ifdef CONFIG_ARC_DW2_UNWIND 30 - CFLAGS_ctx_sw.o += -fno-omit-frame-pointer 31 - obj-y += ctx_sw.o 32 - else 33 - obj-y += ctx_sw_asm.o 34 25 endif 35 26 36 27 extra-y := vmlinux.lds
+7 -7
arch/arc/kernel/asm-offsets.c
··· 20 20 21 21 BLANK(); 22 22 23 - DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); 24 23 DEFINE(THREAD_CALLEE_REG, offsetof(struct thread_struct, callee_reg)); 25 24 DEFINE(THREAD_FAULT_ADDR, 26 25 offsetof(struct thread_struct, fault_address)); 27 26 28 27 BLANK(); 29 28 29 + DEFINE(THREAD_INFO_KSP, offsetof(struct thread_info, ksp)); 30 30 DEFINE(THREAD_INFO_FLAGS, offsetof(struct thread_info, flags)); 31 31 DEFINE(THREAD_INFO_PREEMPT_COUNT, 32 32 offsetof(struct thread_info, preempt_count)); ··· 46 46 BLANK(); 47 47 48 48 DEFINE(PT_status32, offsetof(struct pt_regs, status32)); 49 - DEFINE(PT_event, offsetof(struct pt_regs, event)); 49 + DEFINE(PT_event, offsetof(struct pt_regs, ecr)); 50 + DEFINE(PT_bta, offsetof(struct pt_regs, bta)); 50 51 DEFINE(PT_sp, offsetof(struct pt_regs, sp)); 51 52 DEFINE(PT_r0, offsetof(struct pt_regs, r0)); 52 53 DEFINE(PT_r1, offsetof(struct pt_regs, r1)); ··· 62 61 DEFINE(PT_r26, offsetof(struct pt_regs, r26)); 63 62 DEFINE(PT_ret, offsetof(struct pt_regs, ret)); 64 63 DEFINE(PT_blink, offsetof(struct pt_regs, blink)); 64 + OFFSET(PT_fp, pt_regs, fp); 65 65 DEFINE(PT_lpe, offsetof(struct pt_regs, lp_end)); 66 66 DEFINE(PT_lpc, offsetof(struct pt_regs, lp_count)); 67 - DEFINE(PT_user_r25, offsetof(struct pt_regs, user_r25)); 68 - 69 - DEFINE(SZ_CALLEE_REGS, sizeof(struct callee_regs)); 70 - DEFINE(SZ_PT_REGS, sizeof(struct pt_regs)); 71 - 72 67 #ifdef CONFIG_ISA_ARCV2 73 68 OFFSET(PT_r12, pt_regs, r12); 74 69 OFFSET(PT_r30, pt_regs, r30); ··· 76 79 #ifdef CONFIG_ARC_DSP_SAVE_RESTORE_REGS 77 80 OFFSET(PT_DSP_CTRL, pt_regs, DSP_CTRL); 78 81 #endif 82 + 83 + DEFINE(SZ_CALLEE_REGS, sizeof(struct callee_regs)); 84 + DEFINE(SZ_PT_REGS, sizeof(struct pt_regs)); 79 85 80 86 return 0; 81 87 }
-112
arch/arc/kernel/ctx_sw.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) 4 - * 5 - * Vineetg: Aug 2009 6 - * -"C" version of lowest level context switch asm macro called by schedular 7 - * gcc doesn't generate the dward CFI info for hand written asm, hence can't 8 - * backtrace out of it (e.g. tasks sleeping in kernel). 9 - * So we cheat a bit by writing almost similar code in inline-asm. 10 - * -This is a hacky way of doing things, but there is no other simple way. 11 - * I don't want/intend to extend unwinding code to understand raw asm 12 - */ 13 - 14 - #include <asm/asm-offsets.h> 15 - #include <linux/sched.h> 16 - #include <linux/sched/debug.h> 17 - 18 - #define KSP_WORD_OFF ((TASK_THREAD + THREAD_KSP) / 4) 19 - 20 - struct task_struct *__sched 21 - __switch_to(struct task_struct *prev_task, struct task_struct *next_task) 22 - { 23 - unsigned int tmp; 24 - unsigned int prev = (unsigned int)prev_task; 25 - unsigned int next = (unsigned int)next_task; 26 - 27 - __asm__ __volatile__( 28 - /* FP/BLINK save generated by gcc (standard function prologue */ 29 - "st.a r13, [sp, -4] \n\t" 30 - "st.a r14, [sp, -4] \n\t" 31 - "st.a r15, [sp, -4] \n\t" 32 - "st.a r16, [sp, -4] \n\t" 33 - "st.a r17, [sp, -4] \n\t" 34 - "st.a r18, [sp, -4] \n\t" 35 - "st.a r19, [sp, -4] \n\t" 36 - "st.a r20, [sp, -4] \n\t" 37 - "st.a r21, [sp, -4] \n\t" 38 - "st.a r22, [sp, -4] \n\t" 39 - "st.a r23, [sp, -4] \n\t" 40 - "st.a r24, [sp, -4] \n\t" 41 - #ifndef CONFIG_ARC_CURR_IN_REG 42 - "st.a r25, [sp, -4] \n\t" 43 - #else 44 - "sub sp, sp, 4 \n\t" /* usual r25 placeholder */ 45 - #endif 46 - 47 - /* set ksp of outgoing task in tsk->thread.ksp */ 48 - #if KSP_WORD_OFF <= 255 49 - "st.as sp, [%3, %1] \n\t" 50 - #else 51 - /* 52 - * Workaround for NR_CPUS=4k 53 - * %1 is bigger than 255 (S9 offset for st.as) 54 - */ 55 - "add2 r24, %3, %1 \n\t" 56 - "st sp, [r24] \n\t" 57 - #endif 58 - 59 - /* 60 - * setup _current_task with incoming tsk. 61 - * optionally, set r25 to that as well 62 - * For SMP extra work to get to &_current_task[cpu] 63 - * (open coded SET_CURR_TASK_ON_CPU) 64 - */ 65 - #ifndef CONFIG_SMP 66 - "st %2, [@_current_task] \n\t" 67 - #else 68 - "lr r24, [identity] \n\t" 69 - "lsr r24, r24, 8 \n\t" 70 - "bmsk r24, r24, 7 \n\t" 71 - "add2 r24, @_current_task, r24 \n\t" 72 - "st %2, [r24] \n\t" 73 - #endif 74 - #ifdef CONFIG_ARC_CURR_IN_REG 75 - "mov r25, %2 \n\t" 76 - #endif 77 - 78 - /* get ksp of incoming task from tsk->thread.ksp */ 79 - "ld.as sp, [%2, %1] \n\t" 80 - 81 - /* start loading it's CALLEE reg file */ 82 - 83 - #ifndef CONFIG_ARC_CURR_IN_REG 84 - "ld.ab r25, [sp, 4] \n\t" 85 - #else 86 - "add sp, sp, 4 \n\t" 87 - #endif 88 - "ld.ab r24, [sp, 4] \n\t" 89 - "ld.ab r23, [sp, 4] \n\t" 90 - "ld.ab r22, [sp, 4] \n\t" 91 - "ld.ab r21, [sp, 4] \n\t" 92 - "ld.ab r20, [sp, 4] \n\t" 93 - "ld.ab r19, [sp, 4] \n\t" 94 - "ld.ab r18, [sp, 4] \n\t" 95 - "ld.ab r17, [sp, 4] \n\t" 96 - "ld.ab r16, [sp, 4] \n\t" 97 - "ld.ab r15, [sp, 4] \n\t" 98 - "ld.ab r14, [sp, 4] \n\t" 99 - "ld.ab r13, [sp, 4] \n\t" 100 - 101 - /* last (ret value) = prev : although for ARC it mov r0, r0 */ 102 - "mov %0, %3 \n\t" 103 - 104 - /* FP/BLINK restore generated by gcc (standard func epilogue */ 105 - 106 - : "=r"(tmp) 107 - : "n"(KSP_WORD_OFF), "r"(next), "r"(prev) 108 - : "blink" 109 - ); 110 - 111 - return (struct task_struct *)tmp; 112 - }
+39 -35
arch/arc/kernel/ctx_sw_asm.S
··· 11 11 #include <asm/entry.h> /* For the SAVE_* macros */ 12 12 #include <asm/asm-offsets.h> 13 13 14 - #define KSP_WORD_OFF ((TASK_THREAD + THREAD_KSP) / 4) 15 - 16 - ;################### Low Level Context Switch ########################## 14 + ; IN 15 + ; - r0: prev task (also current) 16 + ; - r1: next task 17 + ; OUT 18 + ; - r0: prev task (so r0 not touched) 17 19 18 20 .section .sched.text,"ax",@progbits 19 - .align 4 20 - .global __switch_to 21 - .type __switch_to, @function 22 - __switch_to: 23 - CFI_STARTPROC 21 + ENTRY_CFI(__switch_to) 24 22 25 - /* Save regs on kernel mode stack of task */ 26 - st.a blink, [sp, -4] 27 - st.a fp, [sp, -4] 23 + /* save kernel stack frame regs of @prev task */ 24 + push blink 25 + CFI_DEF_CFA_OFFSET 4 26 + CFI_OFFSET r31, -4 27 + 28 + push fp 29 + CFI_DEF_CFA_OFFSET 8 30 + CFI_OFFSET r27, -8 31 + 32 + mov fp, sp 33 + CFI_DEF_CFA_REGISTER r27 34 + 35 + /* kernel mode callee regs of @prev */ 28 36 SAVE_CALLEE_SAVED_KERNEL 29 37 30 - /* Save the now KSP in task->thread.ksp */ 31 - #if KSP_WORD_OFF <= 255 32 - st.as sp, [r0, KSP_WORD_OFF] 33 - #else 34 - /* Workaround for NR_CPUS=4k as ST.as can only take s9 offset */ 35 - add2 r24, r0, KSP_WORD_OFF 36 - st sp, [r24] 37 - #endif 38 38 /* 39 - * Return last task in r0 (return reg) 40 - * On ARC, Return reg = First Arg reg = r0. 41 - * Since we already have last task in r0, 42 - * don't need to do anything special to return it 43 - */ 44 - 45 - /* 46 - * switch to new task, contained in r1 47 - * Temp reg r3 is required to get the ptr to store val 39 + * save final SP to @prev->thread_info.ksp 40 + * @prev is "current" so thread_info derived from SP 48 41 */ 49 - SET_CURR_TASK_ON_CPU r1, r3 42 + GET_CURR_THR_INFO_FROM_SP r10 43 + st sp, [r10, THREAD_INFO_KSP] 50 44 51 - /* reload SP with kernel mode stack pointer in task->thread.ksp */ 52 - ld.as sp, [r1, (TASK_THREAD + THREAD_KSP)/4] 45 + /* update @next in _current_task[] and GP register caching it */ 46 + SET_CURR_TASK_ON_CPU r1, r10 53 47 54 - /* restore the registers */ 48 + /* load SP from @next->thread_info.ksp */ 49 + ld r10, [r1, TASK_THREAD_INFO] 50 + ld sp, [r10, THREAD_INFO_KSP] 51 + 52 + /* restore callee regs, stack frame regs of @next */ 55 53 RESTORE_CALLEE_SAVED_KERNEL 56 - ld.ab fp, [sp, 4] 57 - ld.ab blink, [sp, 4] 58 - j [blink] 59 54 55 + pop fp 56 + CFI_RESTORE r27 57 + CFI_DEF_CFA r28, 4 58 + 59 + pop blink 60 + CFI_RESTORE r31 61 + CFI_DEF_CFA_OFFSET 0 62 + 63 + j [blink] 60 64 END_CFI(__switch_to)
+1
arch/arc/kernel/devtree.c
··· 12 12 #include <linux/of.h> 13 13 #include <linux/of_fdt.h> 14 14 #include <asm/mach_desc.h> 15 + #include <asm/serial.h> 15 16 16 17 #ifdef CONFIG_SERIAL_EARLYCON 17 18
-15
arch/arc/kernel/entry-arcv2.S
··· 125 125 126 126 EXCEPTION_PROLOGUE 127 127 128 - lr r0, [efa] 129 - mov r1, sp 130 - 131 - FAKE_RET_FROM_EXCPN 132 - 133 128 bl do_memory_error 134 129 b ret_from_exception 135 130 END(mem_service) ··· 132 137 ENTRY(EV_Misaligned) 133 138 134 139 EXCEPTION_PROLOGUE 135 - 136 - lr r0, [efa] ; Faulting Data address 137 - mov r1, sp 138 - 139 - FAKE_RET_FROM_EXCPN 140 140 141 141 SAVE_CALLEE_SAVED_USER 142 142 mov r2, sp ; callee_regs ··· 152 162 ENTRY(EV_TLBProtV) 153 163 154 164 EXCEPTION_PROLOGUE 155 - 156 - lr r0, [efa] ; Faulting Data address 157 - mov r1, sp ; pt_regs 158 - 159 - FAKE_RET_FROM_EXCPN 160 165 161 166 mov blink, ret_from_exception 162 167 b do_page_fault
+2 -17
arch/arc/kernel/entry-compact.S
··· 254 254 255 255 ENTRY(EV_TLBProtV) 256 256 257 - EXCEPTION_PROLOGUE 258 - 259 - mov r2, r10 ; ECR set into r10 already 260 - lr r0, [efa] ; Faulting Data address (not part of pt_regs saved above) 261 - 262 - ; Exception auto-disables further Intr/exceptions. 263 - ; Re-enable them by pretending to return from exception 264 - ; (so rest of handler executes in pure K mode) 265 - 266 - FAKE_RET_FROM_EXCPN 267 - 268 - mov r1, sp ; Handle to pt_regs 257 + EXCEPTION_PROLOGUE ; ECR returned in r10 269 258 270 259 ;------ (5) Type of Protection Violation? ---------- 271 260 ; ··· 262 273 ; -Access Violation : 00_23_(00|01|02|03)_00 263 274 ; x r w r+w 264 275 ; -Unaligned Access : 00_23_04_00 265 - ; 266 - bbit1 r2, ECR_C_BIT_PROTV_MISALIG_DATA, 4f 276 + bbit1 r10, ECR_C_BIT_PROTV_MISALIG_DATA, 4f 267 277 268 278 ;========= (6a) Access Violation Processing ======== 269 279 bl do_page_fault ··· 291 303 ENTRY(call_do_page_fault) 292 304 293 305 EXCEPTION_PROLOGUE 294 - lr r0, [efa] ; Faulting Data address 295 - mov r1, sp 296 - FAKE_RET_FROM_EXCPN 297 306 298 307 mov blink, ret_from_exception 299 308 b do_page_fault
+24 -46
arch/arc/kernel/entry.S
··· 80 80 81 81 EXCEPTION_PROLOGUE 82 82 83 - lr r0, [efa] 84 - mov r1, sp 85 - 86 - FAKE_RET_FROM_EXCPN 87 - 88 83 bl do_insterror_or_kprobe 89 84 b ret_from_exception 90 85 END(instr_service) ··· 90 95 91 96 ENTRY(EV_MachineCheck) 92 97 93 - EXCEPTION_PROLOGUE 98 + EXCEPTION_PROLOGUE_KEEP_AE ; ECR returned in r10 94 99 95 - lr r2, [ecr] 96 100 lr r0, [efa] 97 101 mov r1, sp 98 102 99 103 ; MC excpetions disable MMU 100 104 ARC_MMU_REENABLE r3 101 105 102 - lsr r3, r2, 8 106 + lsr r3, r10, 8 103 107 bmsk r3, r3, 7 104 108 brne r3, ECR_C_MCHK_DUP_TLB, 1f 105 109 ··· 123 129 124 130 EXCEPTION_PROLOGUE 125 131 126 - lr r0, [efa] 127 - mov r1, sp 128 - 129 - FAKE_RET_FROM_EXCPN 130 - 131 132 bl do_privilege_fault 132 133 b ret_from_exception 133 134 END(EV_PrivilegeV) ··· 134 145 135 146 EXCEPTION_PROLOGUE 136 147 137 - lr r0, [efa] 138 - mov r1, sp 139 - 140 - FAKE_RET_FROM_EXCPN 141 - 142 148 bl do_extension_fault 143 149 b ret_from_exception 144 150 END(EV_Extension) ··· 144 160 ; syscall Tracing 145 161 ; --------------------------------------------- 146 162 tracesys: 147 - ; save EFA in case tracer wants the PC of traced task 148 - ; using ERET won't work since next-PC has already committed 163 + ; safekeep EFA (r12) if syscall tracer wanted PC 164 + ; for traps, ERET is pre-commit so points to next-PC 149 165 GET_CURR_TASK_FIELD_PTR TASK_THREAD, r11 150 166 st r12, [r11, THREAD_FAULT_ADDR] ; thread.fault_address 151 167 152 - ; PRE Sys Call Ptrace hook 153 - mov r0, sp ; pt_regs needed 154 - bl @syscall_trace_entry 168 + ; PRE syscall trace hook 169 + mov r0, sp ; pt_regs 170 + bl @syscall_trace_enter 155 171 156 172 ; Tracing code now returns the syscall num (orig or modif) 157 173 mov r8, r0 158 174 159 175 ; Do the Sys Call as we normally would. 160 - ; Validate the Sys Call number 161 176 cmp r8, NR_syscalls - 1 162 177 mov.hi r0, -ENOSYS 163 178 bhi tracesys_exit ··· 173 190 ld r6, [sp, PT_r6] 174 191 ld r7, [sp, PT_r7] 175 192 ld.as r9, [sys_call_table, r8] 176 - jl [r9] ; Entry into Sys Call Handler 193 + jl [r9] 177 194 178 195 tracesys_exit: 179 - st r0, [sp, PT_r0] ; sys call return value in pt_regs 196 + st r0, [sp, PT_r0] 180 197 181 - ;POST Sys Call Ptrace Hook 198 + ; POST syscall trace hook 182 199 mov r0, sp ; pt_regs needed 183 200 bl @syscall_trace_exit 184 - b ret_from_exception ; NOT ret_from_system_call at is saves r0 which 185 - ; we'd done before calling post hook above 201 + 202 + ; don't call ret_from_system_call as it saves r0, already done above 203 + b ret_from_exception 186 204 187 205 ; --------------------------------------------- 188 206 ; Breakpoint TRAP 189 207 ; --------------------------------------------- 190 208 trap_with_param: 191 209 mov r0, r12 ; EFA in case ptracer/gdb wants stop_pc 192 - mov r1, sp 210 + mov r1, sp ; pt_regs 193 211 194 - ; Save callee regs in case gdb wants to have a look 195 - ; SP will grow up by size of CALLEE Reg-File 196 - ; NOTE: clobbers r12 212 + ; save callee regs in case tracer/gdb wants to peek 197 213 SAVE_CALLEE_SAVED_USER 198 214 199 - ; save location of saved Callee Regs @ thread_struct->pc 215 + ; safekeep ref to callee regs 200 216 GET_CURR_TASK_FIELD_PTR TASK_THREAD, r10 201 217 st sp, [r10, THREAD_CALLEE_REG] 202 218 203 - ; Call the trap handler 219 + ; call the non syscall trap handler 204 220 bl do_non_swi_trap 205 221 206 - ; unwind stack to discard Callee saved Regs 222 + ; unwind stack to discard callee regs 207 223 DISCARD_CALLEE_SAVED_USER 208 224 209 225 b ret_from_exception ··· 214 232 215 233 ENTRY(EV_Trap) 216 234 217 - EXCEPTION_PROLOGUE 235 + EXCEPTION_PROLOGUE_KEEP_AE 218 236 219 237 lr r12, [efa] 220 238 221 239 FAKE_RET_FROM_EXCPN 222 240 223 - ;============ TRAP 1 :breakpoints 224 - ; Check ECR for trap with arg (PROLOGUE ensures r10 has ECR) 241 + ;============ TRAP N : breakpoints, kprobes etc 225 242 bmsk.f 0, r10, 7 226 243 bnz trap_with_param 227 244 228 - ;============ TRAP (no param): syscall top level 245 + ;============ TRAP 0 (no param): syscall 229 246 230 - ; If syscall tracing ongoing, invoke pre-post-hooks 247 + ; syscall tracing ongoing, invoke pre-post-hooks around syscall 231 248 GET_CURR_THR_INFO_FLAGS r10 232 249 and.f 0, r10, _TIF_SYSCALL_WORK 233 250 bnz tracesys ; this never comes back 234 251 235 252 ;============ Normal syscall case 236 253 237 - ; syscall num shd not exceed the total system calls avail 238 254 cmp r8, NR_syscalls - 1 239 255 mov.hi r0, -ENOSYS 240 256 bhi .Lret_from_system_call 241 257 242 - ; Offset into the syscall_table and call handler 243 258 ld.as r9,[sys_call_table, r8] 244 - jl [r9] ; Entry into Sys Call Handler 259 + jl [r9] 245 260 246 261 .Lret_from_system_call: 247 - 248 262 st r0, [sp, PT_r0] ; sys call return value in pt_regs 249 263 250 264 ; fall through to ret_from_exception ··· 296 318 ; tracer might call PEEKUSR(CALLEE reg) 297 319 ; 298 320 ; NOTE: SP will grow up by size of CALLEE Reg-File 299 - SAVE_CALLEE_SAVED_USER ; clobbers r12 321 + SAVE_CALLEE_SAVED_USER 300 322 301 323 ; save location of saved Callee Regs @ thread_struct->callee 302 324 GET_CURR_TASK_FIELD_PTR TASK_THREAD, r10
+1 -1
arch/arc/kernel/intc-arcv2.c
··· 108 108 write_aux_reg(AUX_IRQ_ENABLE, 1); 109 109 } 110 110 111 - void arcv2_irq_enable(struct irq_data *data) 111 + static void arcv2_irq_enable(struct irq_data *data) 112 112 { 113 113 /* set default priority */ 114 114 write_aux_reg(AUX_IRQ_SELECT, data->hwirq);
+1 -1
arch/arc/kernel/kgdb.c
··· 175 175 * with trap_s 4 (compiled) breakpoints, continuation needs to 176 176 * start after the breakpoint. 177 177 */ 178 - if (regs->ecr_param == 3) 178 + if (regs->ecr.param == 3) 179 179 instruction_pointer(regs) -= BREAK_INSTR_SIZE; 180 180 181 181 kgdb_handle_exception(1, SIGTRAP, 0, regs);
-2
arch/arc/kernel/mcip.c
··· 165 165 IS_AVAIL1(mp.idu, "IDU "), 166 166 IS_AVAIL1(mp.dbg, "DEBUG "), 167 167 IS_AVAIL1(mp.gfrc, "GFRC")); 168 - 169 - cpuinfo_arc700[0].extn.gfrc = mp.gfrc; 170 168 } 171 169 172 170 struct plat_smp_ops plat_smp_ops = {
+3 -14
arch/arc/kernel/process.c
··· 141 141 * | unused | 142 142 * | | 143 143 * ------------------ 144 - * | r25 | <==== top of Stack (thread.ksp) 144 + * | r25 | <==== top of Stack (thread_info.ksp) 145 145 * ~ ~ 146 146 * | --to-- | (CALLEE Regs of kernel mode) 147 147 * | r13 | ··· 162 162 * | SP | 163 163 * | orig_r0 | 164 164 * | event/ECR | 165 - * | user_r25 | 166 165 * ------------------ <===== END of PAGE 167 166 */ 168 167 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) ··· 181 182 c_callee = ((struct callee_regs *)childksp) - 1; 182 183 183 184 /* 184 - * __switch_to() uses thread.ksp to start unwinding stack 185 + * __switch_to() uses thread_info.ksp to start unwinding stack 185 186 * For kernel threads we don't need to create callee regs, the 186 187 * stack layout nevertheless needs to remain the same. 187 188 * Also, since __switch_to anyways unwinds callee regs, we use 188 189 * this to populate kernel thread entry-pt/args into callee regs, 189 190 * so that ret_from_kernel_thread() becomes simpler. 190 191 */ 191 - p->thread.ksp = (unsigned long)c_callee; /* THREAD_KSP */ 192 + task_thread_info(p)->ksp = (unsigned long)c_callee; /* THREAD_INFO_KSP */ 192 193 193 194 /* __switch_to expects FP(0), BLINK(return addr) at top */ 194 195 childksp[0] = 0; /* fp */ ··· 241 242 * ensures those regs are not clobbered all the way to RTIE to usermode 242 243 */ 243 244 c_callee->r25 = task_thread_info(p)->thr_ptr; 244 - 245 - #ifdef CONFIG_ARC_CURR_IN_REG 246 - /* 247 - * setup usermode thread pointer #2: 248 - * however for this special use of r25 in kernel, __switch_to() sets 249 - * r25 for kernel needs and only in the final return path is usermode 250 - * r25 setup, from pt_regs->user_r25. So set that up as well 251 - */ 252 - c_regs->user_r25 = c_callee->r25; 253 - #endif 254 245 255 246 return 0; 256 247 }
+3 -5
arch/arc/kernel/ptrace.c
··· 46 46 REG_OFFSET_NAME(r0), 47 47 REG_OFFSET_NAME(sp), 48 48 REG_OFFSET_NAME(orig_r0), 49 - REG_OFFSET_NAME(event), 50 - REG_OFFSET_NAME(user_r25), 49 + REG_OFFSET_NAME(ecr), 51 50 REG_OFFSET_END, 52 51 }; 53 52 ··· 54 55 55 56 static const struct pt_regs_offset regoffset_table[] = { 56 57 REG_OFFSET_NAME(orig_r0), 57 - REG_OFFSET_NAME(event), 58 + REG_OFFSET_NAME(ecr), 58 59 REG_OFFSET_NAME(bta), 59 - REG_OFFSET_NAME(user_r25), 60 60 REG_OFFSET_NAME(r26), 61 61 REG_OFFSET_NAME(fp), 62 62 REG_OFFSET_NAME(sp), ··· 339 341 return ret; 340 342 } 341 343 342 - asmlinkage int syscall_trace_entry(struct pt_regs *regs) 344 + asmlinkage int syscall_trace_enter(struct pt_regs *regs) 343 345 { 344 346 if (test_thread_flag(TIF_SYSCALL_TRACE)) 345 347 if (ptrace_report_syscall_entry(regs))
+279 -324
arch/arc/kernel/setup.c
··· 29 29 #include <asm/mach_desc.h> 30 30 #include <asm/smp.h> 31 31 #include <asm/dsp-impl.h> 32 + #include <soc/arc/mcip.h> 32 33 33 34 #define FIX_PTR(x) __asm__ __volatile__(";" : "+r"(x)) 34 35 ··· 44 43 45 44 struct task_struct *_current_task[NR_CPUS]; /* For stack switching */ 46 45 47 - struct cpuinfo_arc cpuinfo_arc700[NR_CPUS]; 46 + struct cpuinfo_arc { 47 + int arcver; 48 + unsigned int t0:1, t1:1; 49 + struct { 50 + unsigned long base; 51 + unsigned int sz; 52 + } iccm, dccm; 53 + }; 48 54 49 - static const struct id_to_str arc_legacy_rel[] = { 55 + #ifdef CONFIG_ISA_ARCV2 56 + 57 + static const struct id_to_str arc_hs_rel[] = { 50 58 /* ID.ARCVER, Release */ 51 - #ifdef CONFIG_ISA_ARCOMPACT 52 - { 0x34, "R4.10"}, 53 - { 0x35, "R4.11"}, 54 - #else 55 59 { 0x51, "R2.0" }, 56 60 { 0x52, "R2.1" }, 57 61 { 0x53, "R3.0" }, 58 - #endif 59 - { 0x00, NULL } 60 62 }; 61 63 62 64 static const struct id_to_str arc_hs_ver54_rel[] = { ··· 70 66 { 3, "R4.00a"}, 71 67 { 0xFF, NULL } 72 68 }; 69 + #endif 73 70 74 - static void read_decode_ccm_bcr(struct cpuinfo_arc *cpu) 71 + static int 72 + arcompact_mumbojumbo(int c, struct cpuinfo_arc *info, char *buf, int len) 75 73 { 76 - if (is_isa_arcompact()) { 77 - struct bcr_iccm_arcompact iccm; 78 - struct bcr_dccm_arcompact dccm; 74 + int n = 0; 75 + #ifdef CONFIG_ISA_ARCOMPACT 76 + char *cpu_nm, *isa_nm = "ARCompact"; 77 + struct bcr_fp_arcompact fpu_sp, fpu_dp; 78 + int atomic = 0, be, present; 79 + int bpu_full, bpu_cache, bpu_pred; 80 + struct bcr_bpu_arcompact bpu; 81 + struct bcr_iccm_arcompact iccm; 82 + struct bcr_dccm_arcompact dccm; 83 + struct bcr_generic isa; 79 84 80 - READ_BCR(ARC_REG_ICCM_BUILD, iccm); 81 - if (iccm.ver) { 82 - cpu->iccm.sz = 4096 << iccm.sz; /* 8K to 512K */ 83 - cpu->iccm.base_addr = iccm.base << 16; 84 - } 85 + READ_BCR(ARC_REG_ISA_CFG_BCR, isa); 85 86 86 - READ_BCR(ARC_REG_DCCM_BUILD, dccm); 87 - if (dccm.ver) { 88 - unsigned long base; 89 - cpu->dccm.sz = 2048 << dccm.sz; /* 2K to 256K */ 90 - 91 - base = read_aux_reg(ARC_REG_DCCM_BASE_BUILD); 92 - cpu->dccm.base_addr = base & ~0xF; 93 - } 94 - } else { 95 - struct bcr_iccm_arcv2 iccm; 96 - struct bcr_dccm_arcv2 dccm; 97 - unsigned long region; 98 - 99 - READ_BCR(ARC_REG_ICCM_BUILD, iccm); 100 - if (iccm.ver) { 101 - cpu->iccm.sz = 256 << iccm.sz00; /* 512B to 16M */ 102 - if (iccm.sz00 == 0xF && iccm.sz01 > 0) 103 - cpu->iccm.sz <<= iccm.sz01; 104 - 105 - region = read_aux_reg(ARC_REG_AUX_ICCM); 106 - cpu->iccm.base_addr = region & 0xF0000000; 107 - } 108 - 109 - READ_BCR(ARC_REG_DCCM_BUILD, dccm); 110 - if (dccm.ver) { 111 - cpu->dccm.sz = 256 << dccm.sz0; 112 - if (dccm.sz0 == 0xF && dccm.sz1 > 0) 113 - cpu->dccm.sz <<= dccm.sz1; 114 - 115 - region = read_aux_reg(ARC_REG_AUX_DCCM); 116 - cpu->dccm.base_addr = region & 0xF0000000; 117 - } 87 + if (!isa.ver) /* ISA BCR absent, use Kconfig info */ 88 + atomic = IS_ENABLED(CONFIG_ARC_HAS_LLSC); 89 + else { 90 + /* ARC700_BUILD only has 2 bits of isa info */ 91 + atomic = isa.info & 1; 118 92 } 93 + 94 + be = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN); 95 + 96 + if (info->arcver < 0x34) 97 + cpu_nm = "ARC750"; 98 + else 99 + cpu_nm = "ARC770"; 100 + 101 + n += scnprintf(buf + n, len - n, "processor [%d]\t: %s (%s ISA) %s%s%s\n", 102 + c, cpu_nm, isa_nm, 103 + IS_AVAIL2(atomic, "atomic ", CONFIG_ARC_HAS_LLSC), 104 + IS_AVAIL1(be, "[Big-Endian]")); 105 + 106 + READ_BCR(ARC_REG_FP_BCR, fpu_sp); 107 + READ_BCR(ARC_REG_DPFP_BCR, fpu_dp); 108 + 109 + if (fpu_sp.ver | fpu_dp.ver) 110 + n += scnprintf(buf + n, len - n, "FPU\t\t: %s%s\n", 111 + IS_AVAIL1(fpu_sp.ver, "SP "), 112 + IS_AVAIL1(fpu_dp.ver, "DP ")); 113 + 114 + READ_BCR(ARC_REG_BPU_BCR, bpu); 115 + bpu_full = bpu.fam ? 1 : 0; 116 + bpu_cache = 256 << (bpu.ent - 1); 117 + bpu_pred = 256 << (bpu.ent - 1); 118 + 119 + n += scnprintf(buf + n, len - n, 120 + "BPU\t\t: %s%s match, cache:%d, Predict Table:%d\n", 121 + IS_AVAIL1(bpu_full, "full"), 122 + IS_AVAIL1(!bpu_full, "partial"), 123 + bpu_cache, bpu_pred); 124 + 125 + READ_BCR(ARC_REG_ICCM_BUILD, iccm); 126 + if (iccm.ver) { 127 + info->iccm.sz = 4096 << iccm.sz; /* 8K to 512K */ 128 + info->iccm.base = iccm.base << 16; 129 + } 130 + 131 + READ_BCR(ARC_REG_DCCM_BUILD, dccm); 132 + if (dccm.ver) { 133 + unsigned long base; 134 + info->dccm.sz = 2048 << dccm.sz; /* 2K to 256K */ 135 + 136 + base = read_aux_reg(ARC_REG_DCCM_BASE_BUILD); 137 + info->dccm.base = base & ~0xF; 138 + } 139 + 140 + /* ARCompact ISA specific sanity checks */ 141 + present = fpu_dp.ver; /* SP has no arch visible regs */ 142 + CHK_OPT_STRICT(CONFIG_ARC_FPU_SAVE_RESTORE, present); 143 + #endif 144 + return n; 145 + 119 146 } 120 147 121 - static void decode_arc_core(struct cpuinfo_arc *cpu) 148 + static int arcv2_mumbojumbo(int c, struct cpuinfo_arc *info, char *buf, int len) 122 149 { 123 - struct bcr_uarch_build_arcv2 uarch; 124 - const struct id_to_str *tbl; 125 - 126 - if (cpu->core.family < 0x54) { /* includes arc700 */ 127 - 128 - for (tbl = &arc_legacy_rel[0]; tbl->id != 0; tbl++) { 129 - if (cpu->core.family == tbl->id) { 130 - cpu->release = tbl->str; 131 - break; 132 - } 133 - } 134 - 135 - if (is_isa_arcompact()) 136 - cpu->name = "ARC700"; 137 - else if (tbl->str) 138 - cpu->name = "HS38"; 139 - else 140 - cpu->name = cpu->release = "Unknown"; 141 - 142 - return; 143 - } 150 + int n = 0; 151 + #ifdef CONFIG_ISA_ARCV2 152 + const char *release, *cpu_nm, *isa_nm = "ARCv2"; 153 + int dual_issue = 0, dual_enb = 0, mpy_opt, present; 154 + int bpu_full, bpu_cache, bpu_pred, bpu_ret_stk; 155 + char mpy_nm[16], lpb_nm[32]; 156 + struct bcr_isa_arcv2 isa; 157 + struct bcr_mpy mpy; 158 + struct bcr_fp_arcv2 fpu; 159 + struct bcr_bpu_arcv2 bpu; 160 + struct bcr_lpb lpb; 161 + struct bcr_iccm_arcv2 iccm; 162 + struct bcr_dccm_arcv2 dccm; 163 + struct bcr_erp erp; 144 164 145 165 /* 146 166 * Initial HS cores bumped AUX IDENTITY.ARCVER for each release until 147 167 * ARCVER 0x54 which introduced AUX MICRO_ARCH_BUILD and subsequent 148 168 * releases only update it. 149 169 */ 150 - READ_BCR(ARC_REG_MICRO_ARCH_BCR, uarch); 151 170 152 - if (uarch.prod == 4) { 153 - cpu->name = "HS48"; 154 - cpu->extn.dual = 1; 171 + cpu_nm = "HS38"; 155 172 173 + if (info->arcver > 0x50 && info->arcver <= 0x53) { 174 + release = arc_hs_rel[info->arcver - 0x51].str; 156 175 } else { 157 - cpu->name = "HS38"; 158 - } 176 + const struct id_to_str *tbl; 177 + struct bcr_uarch_build uarch; 159 178 160 - for (tbl = &arc_hs_ver54_rel[0]; tbl->id != 0xFF; tbl++) { 161 - if (uarch.maj == tbl->id) { 162 - cpu->release = tbl->str; 163 - break; 179 + READ_BCR(ARC_REG_MICRO_ARCH_BCR, uarch); 180 + 181 + for (tbl = &arc_hs_ver54_rel[0]; tbl->id != 0xFF; tbl++) { 182 + if (uarch.maj == tbl->id) { 183 + release = tbl->str; 184 + break; 185 + } 164 186 } 165 - } 166 - } 167 - 168 - static void read_arc_build_cfg_regs(void) 169 - { 170 - struct bcr_timer timer; 171 - struct bcr_generic bcr; 172 - struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; 173 - struct bcr_isa_arcv2 isa; 174 - struct bcr_actionpoint ap; 175 - 176 - FIX_PTR(cpu); 177 - 178 - READ_BCR(AUX_IDENTITY, cpu->core); 179 - decode_arc_core(cpu); 180 - 181 - READ_BCR(ARC_REG_TIMERS_BCR, timer); 182 - cpu->extn.timer0 = timer.t0; 183 - cpu->extn.timer1 = timer.t1; 184 - cpu->extn.rtc = timer.rtc; 185 - 186 - cpu->vec_base = read_aux_reg(AUX_INTR_VEC_BASE); 187 - 188 - READ_BCR(ARC_REG_MUL_BCR, cpu->extn_mpy); 189 - 190 - /* Read CCM BCRs for boot reporting even if not enabled in Kconfig */ 191 - read_decode_ccm_bcr(cpu); 192 - 193 - read_decode_mmu_bcr(); 194 - read_decode_cache_bcr(); 195 - 196 - if (is_isa_arcompact()) { 197 - struct bcr_fp_arcompact sp, dp; 198 - struct bcr_bpu_arcompact bpu; 199 - 200 - READ_BCR(ARC_REG_FP_BCR, sp); 201 - READ_BCR(ARC_REG_DPFP_BCR, dp); 202 - cpu->extn.fpu_sp = sp.ver ? 1 : 0; 203 - cpu->extn.fpu_dp = dp.ver ? 1 : 0; 204 - 205 - READ_BCR(ARC_REG_BPU_BCR, bpu); 206 - cpu->bpu.ver = bpu.ver; 207 - cpu->bpu.full = bpu.fam ? 1 : 0; 208 - if (bpu.ent) { 209 - cpu->bpu.num_cache = 256 << (bpu.ent - 1); 210 - cpu->bpu.num_pred = 256 << (bpu.ent - 1); 211 - } 212 - } else { 213 - struct bcr_fp_arcv2 spdp; 214 - struct bcr_bpu_arcv2 bpu; 215 - 216 - READ_BCR(ARC_REG_FP_V2_BCR, spdp); 217 - cpu->extn.fpu_sp = spdp.sp ? 1 : 0; 218 - cpu->extn.fpu_dp = spdp.dp ? 1 : 0; 219 - 220 - READ_BCR(ARC_REG_BPU_BCR, bpu); 221 - cpu->bpu.ver = bpu.ver; 222 - cpu->bpu.full = bpu.ft; 223 - cpu->bpu.num_cache = 256 << bpu.bce; 224 - cpu->bpu.num_pred = 2048 << bpu.pte; 225 - cpu->bpu.ret_stk = 4 << bpu.rse; 226 - 227 - /* if dual issue hardware, is it enabled ? */ 228 - if (cpu->extn.dual) { 187 + if (uarch.prod == 4) { 229 188 unsigned int exec_ctrl; 230 189 190 + cpu_nm = "HS48"; 191 + dual_issue = 1; 192 + /* if dual issue hardware, is it enabled ? */ 231 193 READ_BCR(AUX_EXEC_CTRL, exec_ctrl); 232 - cpu->extn.dual_enb = !(exec_ctrl & 1); 194 + dual_enb = !(exec_ctrl & 1); 233 195 } 234 196 } 235 - 236 - READ_BCR(ARC_REG_AP_BCR, ap); 237 - if (ap.ver) { 238 - cpu->extn.ap_num = 2 << ap.num; 239 - cpu->extn.ap_full = !ap.min; 240 - } 241 - 242 - READ_BCR(ARC_REG_SMART_BCR, bcr); 243 - cpu->extn.smart = bcr.ver ? 1 : 0; 244 - 245 - READ_BCR(ARC_REG_RTT_BCR, bcr); 246 - cpu->extn.rtt = bcr.ver ? 1 : 0; 247 197 248 198 READ_BCR(ARC_REG_ISA_CFG_BCR, isa); 249 199 250 - /* some hacks for lack of feature BCR info in old ARC700 cores */ 251 - if (is_isa_arcompact()) { 252 - if (!isa.ver) /* ISA BCR absent, use Kconfig info */ 253 - cpu->isa.atomic = IS_ENABLED(CONFIG_ARC_HAS_LLSC); 254 - else { 255 - /* ARC700_BUILD only has 2 bits of isa info */ 256 - struct bcr_generic bcr = *(struct bcr_generic *)&isa; 257 - cpu->isa.atomic = bcr.info & 1; 258 - } 200 + n += scnprintf(buf + n, len - n, "processor [%d]\t: %s %s (%s ISA) %s%s%s\n", 201 + c, cpu_nm, release, isa_nm, 202 + IS_AVAIL1(isa.be, "[Big-Endian]"), 203 + IS_AVAIL3(dual_issue, dual_enb, " Dual-Issue ")); 259 204 260 - cpu->isa.be = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN); 205 + READ_BCR(ARC_REG_MPY_BCR, mpy); 206 + mpy_opt = 2; /* stock MPY/MPYH */ 207 + if (mpy.dsp) /* OPT 7-9 */ 208 + mpy_opt = mpy.dsp + 6; 261 209 262 - /* there's no direct way to distinguish 750 vs. 770 */ 263 - if (unlikely(cpu->core.family < 0x34 || cpu->mmu.ver < 3)) 264 - cpu->name = "ARC750"; 265 - } else { 266 - cpu->isa = isa; 210 + scnprintf(mpy_nm, 16, "mpy[opt %d] ", mpy_opt); 211 + 212 + READ_BCR(ARC_REG_FP_V2_BCR, fpu); 213 + 214 + n += scnprintf(buf + n, len - n, "ISA Extn\t: %s%s%s%s%s%s%s%s%s%s%s\n", 215 + IS_AVAIL2(isa.atomic, "atomic ", CONFIG_ARC_HAS_LLSC), 216 + IS_AVAIL2(isa.ldd, "ll64 ", CONFIG_ARC_HAS_LL64), 217 + IS_AVAIL2(isa.unalign, "unalign ", CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS), 218 + IS_AVAIL1(mpy.ver, mpy_nm), 219 + IS_AVAIL1(isa.div_rem, "div_rem "), 220 + IS_AVAIL1((fpu.sp | fpu.dp), " FPU:"), 221 + IS_AVAIL1(fpu.sp, " sp"), 222 + IS_AVAIL1(fpu.dp, " dp")); 223 + 224 + READ_BCR(ARC_REG_BPU_BCR, bpu); 225 + bpu_full = bpu.ft; 226 + bpu_cache = 256 << bpu.bce; 227 + bpu_pred = 2048 << bpu.pte; 228 + bpu_ret_stk = 4 << bpu.rse; 229 + 230 + READ_BCR(ARC_REG_LPB_BUILD, lpb); 231 + if (lpb.ver) { 232 + unsigned int ctl; 233 + ctl = read_aux_reg(ARC_REG_LPB_CTRL); 234 + 235 + scnprintf(lpb_nm, sizeof(lpb_nm), " Loop Buffer:%d %s", 236 + lpb.entries, IS_DISABLED_RUN(!ctl)); 267 237 } 268 - } 269 - 270 - static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len) 271 - { 272 - struct cpuinfo_arc *cpu = &cpuinfo_arc700[cpu_id]; 273 - struct bcr_identity *core = &cpu->core; 274 - char mpy_opt[16]; 275 - int n = 0; 276 - 277 - FIX_PTR(cpu); 278 238 279 239 n += scnprintf(buf + n, len - n, 280 - "\nIDENTITY\t: ARCVER [%#02x] ARCNUM [%#02x] CHIPID [%#4x]\n", 281 - core->family, core->cpu_id, core->chip_id); 240 + "BPU\t\t: %s%s match, cache:%d, Predict Table:%d Return stk: %d%s\n", 241 + IS_AVAIL1(bpu_full, "full"), 242 + IS_AVAIL1(!bpu_full, "partial"), 243 + bpu_cache, bpu_pred, bpu_ret_stk, 244 + lpb_nm); 282 245 283 - n += scnprintf(buf + n, len - n, "processor [%d]\t: %s %s (%s ISA) %s%s%s\n", 284 - cpu_id, cpu->name, cpu->release, 285 - is_isa_arcompact() ? "ARCompact" : "ARCv2", 286 - IS_AVAIL1(cpu->isa.be, "[Big-Endian]"), 287 - IS_AVAIL3(cpu->extn.dual, cpu->extn.dual_enb, " Dual-Issue ")); 288 - 289 - n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s%s%s\nISA Extn\t: ", 290 - IS_AVAIL1(cpu->extn.timer0, "Timer0 "), 291 - IS_AVAIL1(cpu->extn.timer1, "Timer1 "), 292 - IS_AVAIL2(cpu->extn.rtc, "RTC [UP 64-bit] ", CONFIG_ARC_TIMERS_64BIT), 293 - IS_AVAIL2(cpu->extn.gfrc, "GFRC [SMP 64-bit] ", CONFIG_ARC_TIMERS_64BIT)); 294 - 295 - if (cpu->extn_mpy.ver) { 296 - if (is_isa_arcompact()) { 297 - scnprintf(mpy_opt, 16, "mpy"); 298 - } else { 299 - 300 - int opt = 2; /* stock MPY/MPYH */ 301 - 302 - if (cpu->extn_mpy.dsp) /* OPT 7-9 */ 303 - opt = cpu->extn_mpy.dsp + 6; 304 - 305 - scnprintf(mpy_opt, 16, "mpy[opt %d] ", opt); 306 - } 246 + READ_BCR(ARC_REG_ICCM_BUILD, iccm); 247 + if (iccm.ver) { 248 + unsigned long base; 249 + info->iccm.sz = 256 << iccm.sz00; /* 512B to 16M */ 250 + if (iccm.sz00 == 0xF && iccm.sz01 > 0) 251 + info->iccm.sz <<= iccm.sz01; 252 + base = read_aux_reg(ARC_REG_AUX_ICCM); 253 + info->iccm.base = base & 0xF0000000; 307 254 } 308 255 309 - n += scnprintf(buf + n, len - n, "%s%s%s%s%s%s%s%s\n", 310 - IS_AVAIL2(cpu->isa.atomic, "atomic ", CONFIG_ARC_HAS_LLSC), 311 - IS_AVAIL2(cpu->isa.ldd, "ll64 ", CONFIG_ARC_HAS_LL64), 312 - IS_AVAIL2(cpu->isa.unalign, "unalign ", CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS), 313 - IS_AVAIL1(cpu->extn_mpy.ver, mpy_opt), 314 - IS_AVAIL1(cpu->isa.div_rem, "div_rem ")); 315 - 316 - if (cpu->bpu.ver) { 317 - n += scnprintf(buf + n, len - n, 318 - "BPU\t\t: %s%s match, cache:%d, Predict Table:%d Return stk: %d", 319 - IS_AVAIL1(cpu->bpu.full, "full"), 320 - IS_AVAIL1(!cpu->bpu.full, "partial"), 321 - cpu->bpu.num_cache, cpu->bpu.num_pred, cpu->bpu.ret_stk); 322 - 323 - if (is_isa_arcv2()) { 324 - struct bcr_lpb lpb; 325 - 326 - READ_BCR(ARC_REG_LPB_BUILD, lpb); 327 - if (lpb.ver) { 328 - unsigned int ctl; 329 - ctl = read_aux_reg(ARC_REG_LPB_CTRL); 330 - 331 - n += scnprintf(buf + n, len - n, " Loop Buffer:%d %s", 332 - lpb.entries, 333 - IS_DISABLED_RUN(!ctl)); 334 - } 335 - } 336 - n += scnprintf(buf + n, len - n, "\n"); 256 + READ_BCR(ARC_REG_DCCM_BUILD, dccm); 257 + if (dccm.ver) { 258 + unsigned long base; 259 + info->dccm.sz = 256 << dccm.sz0; 260 + if (dccm.sz0 == 0xF && dccm.sz1 > 0) 261 + info->dccm.sz <<= dccm.sz1; 262 + base = read_aux_reg(ARC_REG_AUX_DCCM); 263 + info->dccm.base = base & 0xF0000000; 337 264 } 338 265 339 - return buf; 340 - } 341 - 342 - static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len) 343 - { 344 - int n = 0; 345 - struct cpuinfo_arc *cpu = &cpuinfo_arc700[cpu_id]; 346 - 347 - FIX_PTR(cpu); 348 - 349 - n += scnprintf(buf + n, len - n, "Vector Table\t: %#x\n", cpu->vec_base); 350 - 351 - if (cpu->extn.fpu_sp || cpu->extn.fpu_dp) 352 - n += scnprintf(buf + n, len - n, "FPU\t\t: %s%s\n", 353 - IS_AVAIL1(cpu->extn.fpu_sp, "SP "), 354 - IS_AVAIL1(cpu->extn.fpu_dp, "DP ")); 355 - 356 - if (cpu->extn.ap_num | cpu->extn.smart | cpu->extn.rtt) { 357 - n += scnprintf(buf + n, len - n, "DEBUG\t\t: %s%s", 358 - IS_AVAIL1(cpu->extn.smart, "smaRT "), 359 - IS_AVAIL1(cpu->extn.rtt, "RTT ")); 360 - if (cpu->extn.ap_num) { 361 - n += scnprintf(buf + n, len - n, "ActionPoint %d/%s", 362 - cpu->extn.ap_num, 363 - cpu->extn.ap_full ? "full":"min"); 364 - } 365 - n += scnprintf(buf + n, len - n, "\n"); 366 - } 367 - 368 - if (cpu->dccm.sz || cpu->iccm.sz) 369 - n += scnprintf(buf + n, len - n, "Extn [CCM]\t: DCCM @ %x, %d KB / ICCM: @ %x, %d KB\n", 370 - cpu->dccm.base_addr, TO_KB(cpu->dccm.sz), 371 - cpu->iccm.base_addr, TO_KB(cpu->iccm.sz)); 372 - 373 - if (is_isa_arcv2()) { 374 - 375 - /* Error Protection: ECC/Parity */ 376 - struct bcr_erp erp; 377 - READ_BCR(ARC_REG_ERP_BUILD, erp); 378 - 379 - if (erp.ver) { 380 - struct ctl_erp ctl; 381 - READ_BCR(ARC_REG_ERP_CTRL, ctl); 382 - 383 - /* inverted bits: 0 means enabled */ 384 - n += scnprintf(buf + n, len - n, "Extn [ECC]\t: %s%s%s%s%s%s\n", 266 + /* Error Protection: ECC/Parity */ 267 + READ_BCR(ARC_REG_ERP_BUILD, erp); 268 + if (erp.ver) { 269 + struct ctl_erp ctl; 270 + READ_BCR(ARC_REG_ERP_CTRL, ctl); 271 + /* inverted bits: 0 means enabled */ 272 + n += scnprintf(buf + n, len - n, "Extn [ECC]\t: %s%s%s%s%s%s\n", 385 273 IS_AVAIL3(erp.ic, !ctl.dpi, "IC "), 386 274 IS_AVAIL3(erp.dc, !ctl.dpd, "DC "), 387 275 IS_AVAIL3(erp.mmu, !ctl.mpd, "MMU ")); 388 - } 389 276 } 277 + 278 + /* ARCv2 ISA specific sanity checks */ 279 + present = fpu.sp | fpu.dp | mpy.dsp; /* DSP and/or FPU */ 280 + CHK_OPT_STRICT(CONFIG_ARC_HAS_ACCL_REGS, present); 281 + 282 + dsp_config_check(); 283 + #endif 284 + return n; 285 + } 286 + 287 + static char *arc_cpu_mumbojumbo(int c, struct cpuinfo_arc *info, char *buf, int len) 288 + { 289 + struct bcr_identity ident; 290 + struct bcr_timer timer; 291 + struct bcr_generic bcr; 292 + struct mcip_bcr mp; 293 + struct bcr_actionpoint ap; 294 + unsigned long vec_base; 295 + int ap_num, ap_full, smart, rtt, n; 296 + 297 + memset(info, 0, sizeof(struct cpuinfo_arc)); 298 + 299 + READ_BCR(AUX_IDENTITY, ident); 300 + info->arcver = ident.family; 301 + 302 + n = scnprintf(buf, len, 303 + "\nIDENTITY\t: ARCVER [%#02x] ARCNUM [%#02x] CHIPID [%#4x]\n", 304 + ident.family, ident.cpu_id, ident.chip_id); 305 + 306 + if (is_isa_arcompact()) { 307 + n += arcompact_mumbojumbo(c, info, buf + n, len - n); 308 + } else if (is_isa_arcv2()){ 309 + n += arcv2_mumbojumbo(c, info, buf + n, len - n); 310 + } 311 + 312 + n += arc_mmu_mumbojumbo(c, buf + n, len - n); 313 + n += arc_cache_mumbojumbo(c, buf + n, len - n); 314 + 315 + READ_BCR(ARC_REG_TIMERS_BCR, timer); 316 + info->t0 = timer.t0; 317 + info->t1 = timer.t1; 318 + 319 + READ_BCR(ARC_REG_MCIP_BCR, mp); 320 + vec_base = read_aux_reg(AUX_INTR_VEC_BASE); 321 + 322 + n += scnprintf(buf + n, len - n, 323 + "Timers\t\t: %s%s%s%s%s%s\nVector Table\t: %#lx\n", 324 + IS_AVAIL1(timer.t0, "Timer0 "), 325 + IS_AVAIL1(timer.t1, "Timer1 "), 326 + IS_AVAIL2(timer.rtc, "RTC [UP 64-bit] ", CONFIG_ARC_TIMERS_64BIT), 327 + IS_AVAIL2(mp.gfrc, "GFRC [SMP 64-bit] ", CONFIG_ARC_TIMERS_64BIT), 328 + vec_base); 329 + 330 + READ_BCR(ARC_REG_AP_BCR, ap); 331 + if (ap.ver) { 332 + ap_num = 2 << ap.num; 333 + ap_full = !ap.min; 334 + } 335 + 336 + READ_BCR(ARC_REG_SMART_BCR, bcr); 337 + smart = bcr.ver ? 1 : 0; 338 + 339 + READ_BCR(ARC_REG_RTT_BCR, bcr); 340 + rtt = bcr.ver ? 1 : 0; 341 + 342 + if (ap.ver | smart | rtt) { 343 + n += scnprintf(buf + n, len - n, "DEBUG\t\t: %s%s", 344 + IS_AVAIL1(smart, "smaRT "), 345 + IS_AVAIL1(rtt, "RTT ")); 346 + if (ap.ver) { 347 + n += scnprintf(buf + n, len - n, "ActionPoint %d/%s", 348 + ap_num, 349 + ap_full ? "full":"min"); 350 + } 351 + n += scnprintf(buf + n, len - n, "\n"); 352 + } 353 + 354 + if (info->dccm.sz || info->iccm.sz) 355 + n += scnprintf(buf + n, len - n, 356 + "Extn [CCM]\t: DCCM @ %lx, %d KB / ICCM: @ %lx, %d KB\n", 357 + info->dccm.base, TO_KB(info->dccm.sz), 358 + info->iccm.base, TO_KB(info->iccm.sz)); 390 359 391 360 return buf; 392 361 } ··· 378 401 panic("Disable %s, hardware NOT present\n", opt_name); 379 402 } 380 403 381 - static void arc_chk_core_config(void) 404 + /* 405 + * ISA agnostic sanity checks 406 + */ 407 + static void arc_chk_core_config(struct cpuinfo_arc *info) 382 408 { 383 - struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; 384 - int present = 0; 385 - 386 - if (!cpu->extn.timer0) 409 + if (!info->t0) 387 410 panic("Timer0 is not present!\n"); 388 411 389 - if (!cpu->extn.timer1) 412 + if (!info->t1) 390 413 panic("Timer1 is not present!\n"); 391 414 392 415 #ifdef CONFIG_ARC_HAS_DCCM ··· 394 417 * DCCM can be arbit placed in hardware. 395 418 * Make sure it's placement/sz matches what Linux is built with 396 419 */ 397 - if ((unsigned int)__arc_dccm_base != cpu->dccm.base_addr) 420 + if ((unsigned int)__arc_dccm_base != info->dccm.base) 398 421 panic("Linux built with incorrect DCCM Base address\n"); 399 422 400 - if (CONFIG_ARC_DCCM_SZ * SZ_1K != cpu->dccm.sz) 423 + if (CONFIG_ARC_DCCM_SZ * SZ_1K != info->dccm.sz) 401 424 panic("Linux built with incorrect DCCM Size\n"); 402 425 #endif 403 426 404 427 #ifdef CONFIG_ARC_HAS_ICCM 405 - if (CONFIG_ARC_ICCM_SZ * SZ_1K != cpu->iccm.sz) 428 + if (CONFIG_ARC_ICCM_SZ * SZ_1K != info->iccm.sz) 406 429 panic("Linux built with incorrect ICCM Size\n"); 407 430 #endif 408 - 409 - /* 410 - * FP hardware/software config sanity 411 - * -If hardware present, kernel needs to save/restore FPU state 412 - * -If not, it will crash trying to save/restore the non-existant regs 413 - */ 414 - 415 - if (is_isa_arcompact()) { 416 - /* only DPDP checked since SP has no arch visible regs */ 417 - present = cpu->extn.fpu_dp; 418 - CHK_OPT_STRICT(CONFIG_ARC_FPU_SAVE_RESTORE, present); 419 - } else { 420 - /* Accumulator Low:High pair (r58:59) present if DSP MPY or FPU */ 421 - present = cpu->extn_mpy.dsp | cpu->extn.fpu_sp | cpu->extn.fpu_dp; 422 - CHK_OPT_STRICT(CONFIG_ARC_HAS_ACCL_REGS, present); 423 - 424 - dsp_config_check(); 425 - } 426 431 } 427 432 428 433 /* ··· 415 456 416 457 void setup_processor(void) 417 458 { 459 + struct cpuinfo_arc info; 460 + int c = smp_processor_id(); 418 461 char str[512]; 419 - int cpu_id = smp_processor_id(); 420 462 421 - read_arc_build_cfg_regs(); 463 + pr_info("%s", arc_cpu_mumbojumbo(c, &info, str, sizeof(str))); 464 + pr_info("%s", arc_platform_smp_cpuinfo()); 465 + 466 + arc_chk_core_config(&info); 467 + 422 468 arc_init_IRQ(); 423 - 424 - pr_info("%s", arc_cpu_mumbojumbo(cpu_id, str, sizeof(str))); 425 - 426 469 arc_mmu_init(); 427 470 arc_cache_init(); 428 471 429 - pr_info("%s", arc_extn_mumbojumbo(cpu_id, str, sizeof(str))); 430 - pr_info("%s", arc_platform_smp_cpuinfo()); 431 - 432 - arc_chk_core_config(); 433 472 } 434 473 435 474 static inline bool uboot_arg_invalid(unsigned long addr) ··· 574 617 char *str; 575 618 int cpu_id = ptr_to_cpu(v); 576 619 struct device *cpu_dev = get_cpu_device(cpu_id); 620 + struct cpuinfo_arc info; 577 621 struct clk *cpu_clk; 578 622 unsigned long freq = 0; 579 623 ··· 587 629 if (!str) 588 630 goto done; 589 631 590 - seq_printf(m, arc_cpu_mumbojumbo(cpu_id, str, PAGE_SIZE)); 632 + seq_printf(m, arc_cpu_mumbojumbo(cpu_id, &info, str, PAGE_SIZE)); 591 633 592 634 cpu_clk = clk_get(cpu_dev, NULL); 593 635 if (IS_ERR(cpu_clk)) { ··· 604 646 loops_per_jiffy / (500000 / HZ), 605 647 (loops_per_jiffy / (5000 / HZ)) % 100); 606 648 607 - seq_printf(m, arc_mmu_mumbojumbo(cpu_id, str, PAGE_SIZE)); 608 - seq_printf(m, arc_cache_mumbojumbo(cpu_id, str, PAGE_SIZE)); 609 - seq_printf(m, arc_extn_mumbojumbo(cpu_id, str, PAGE_SIZE)); 610 649 seq_printf(m, arc_platform_smp_cpuinfo()); 611 650 612 651 free_page((unsigned long)str);
+1
arch/arc/kernel/signal.c
··· 53 53 #include <linux/sched/task_stack.h> 54 54 55 55 #include <asm/ucontext.h> 56 + #include <asm/entry.h> 56 57 57 58 struct rt_sigframe { 58 59 struct siginfo info;
+4 -3
arch/arc/kernel/smp.c
··· 23 23 #include <linux/export.h> 24 24 #include <linux/of_fdt.h> 25 25 26 - #include <asm/processor.h> 27 - #include <asm/setup.h> 28 26 #include <asm/mach_desc.h> 27 + #include <asm/setup.h> 28 + #include <asm/smp.h> 29 + #include <asm/processor.h> 29 30 30 31 #ifndef CONFIG_ARC_HAS_LLSC 31 32 arch_spinlock_t smp_atomic_ops_lock = __ARCH_SPIN_LOCK_UNLOCKED; ··· 352 351 * arch-common ISR to handle for inter-processor interrupts 353 352 * Has hooks for platform specific IPI 354 353 */ 355 - irqreturn_t do_IPI(int irq, void *dev_id) 354 + static irqreturn_t do_IPI(int irq, void *dev_id) 356 355 { 357 356 unsigned long pending; 358 357 unsigned long __maybe_unused copy;
+1
arch/arc/kernel/stacktrace.c
··· 29 29 30 30 #include <asm/arcregs.h> 31 31 #include <asm/unwind.h> 32 + #include <asm/stacktrace.h> 32 33 #include <asm/switch_to.h> 33 34 34 35 /*-------------------------------------------------------------------------
+2 -3
arch/arc/kernel/traps.c
··· 16 16 #include <linux/ptrace.h> 17 17 #include <linux/kprobes.h> 18 18 #include <linux/kgdb.h> 19 + #include <asm/entry.h> 19 20 #include <asm/setup.h> 20 21 #include <asm/unaligned.h> 21 22 #include <asm/kprobes.h> ··· 110 109 */ 111 110 void do_non_swi_trap(unsigned long address, struct pt_regs *regs) 112 111 { 113 - unsigned int param = regs->ecr_param; 114 - 115 - switch (param) { 112 + switch (regs->ecr.param) { 116 113 case 1: 117 114 trap_is_brkpt(address, regs); 118 115 break;
+7 -6
arch/arc/kernel/troubleshoot.c
··· 115 115 /* For Data fault, this is data address not instruction addr */ 116 116 address = current->thread.fault_address; 117 117 118 - vec = regs->ecr_vec; 119 - cause_code = regs->ecr_cause; 118 + vec = regs->ecr.vec; 119 + cause_code = regs->ecr.cause; 120 120 121 121 /* For DTLB Miss or ProtV, display the memory involved too */ 122 122 if (vec == ECR_V_DTLB_MISS) { ··· 154 154 pr_cont("Misaligned r/w from 0x%08lx\n", address); 155 155 #endif 156 156 } else if (vec == ECR_V_TRAP) { 157 - if (regs->ecr_param == 5) 157 + if (regs->ecr.param == 5) 158 158 pr_cont("gcc generated __builtin_trap\n"); 159 159 } else { 160 160 pr_cont("Check Programmer's Manual\n"); ··· 184 184 if (user_mode(regs)) 185 185 show_faulting_vma(regs->ret); /* faulting code, not data */ 186 186 187 - pr_info("ECR: 0x%08lx EFA: 0x%08lx ERET: 0x%08lx\nSTAT: 0x%08lx", 188 - regs->event, current->thread.fault_address, regs->ret, 189 - regs->status32); 187 + pr_info("ECR: 0x%08lx EFA: 0x%08lx ERET: 0x%08lx\n", 188 + regs->ecr.full, current->thread.fault_address, regs->ret); 189 + 190 + pr_info("STAT32: 0x%08lx", regs->status32); 190 191 191 192 #define STS_BIT(r, bit) r->status32 & STATUS_##bit##_MASK ? #bit" " : "" 192 193
+2 -1
arch/arc/lib/memset-archs.S
··· 36 36 #endif 37 37 38 38 ENTRY_CFI(memset) 39 - PREFETCHW_INSTR r0, 0 ; Prefetch the first write location 40 39 mov.f 0, r2 41 40 ;;; if size is zero 42 41 jz.d [blink] 43 42 mov r3, r0 ; don't clobber ret val 43 + 44 + PREFETCHW_INSTR r0, 0 ; Prefetch the first write location 44 45 45 46 ;;; if length < 8 46 47 brls.d.nt r2, 8, .Lsmallchunk
+68 -111
arch/arc/mm/cache.c
··· 28 28 unsigned long perip_base = ARC_UNCACHED_ADDR_SPACE; /* legacy value for boot */ 29 29 unsigned long perip_end = 0xFFFFFFFF; /* legacy value */ 30 30 31 + static struct cpuinfo_arc_cache { 32 + unsigned int sz_k, line_len, colors; 33 + } ic_info, dc_info, slc_info; 34 + 31 35 void (*_cache_line_loop_ic_fn)(phys_addr_t paddr, unsigned long vaddr, 32 36 unsigned long sz, const int op, const int full_page); 33 37 ··· 39 35 void (*__dma_cache_inv)(phys_addr_t start, unsigned long sz); 40 36 void (*__dma_cache_wback)(phys_addr_t start, unsigned long sz); 41 37 42 - char *arc_cache_mumbojumbo(int c, char *buf, int len) 38 + static int read_decode_cache_bcr_arcv2(int c, char *buf, int len) 43 39 { 44 - int n = 0; 45 - struct cpuinfo_arc_cache *p; 46 - 47 - #define PR_CACHE(p, cfg, str) \ 48 - if (!(p)->line_len) \ 49 - n += scnprintf(buf + n, len - n, str"\t\t: N/A\n"); \ 50 - else \ 51 - n += scnprintf(buf + n, len - n, \ 52 - str"\t\t: %uK, %dway/set, %uB Line, %s%s%s\n", \ 53 - (p)->sz_k, (p)->assoc, (p)->line_len, \ 54 - (p)->vipt ? "VIPT" : "PIPT", \ 55 - (p)->alias ? " aliasing" : "", \ 56 - IS_USED_CFG(cfg)); 57 - 58 - PR_CACHE(&cpuinfo_arc700[c].icache, CONFIG_ARC_HAS_ICACHE, "I-Cache"); 59 - PR_CACHE(&cpuinfo_arc700[c].dcache, CONFIG_ARC_HAS_DCACHE, "D-Cache"); 60 - 61 - p = &cpuinfo_arc700[c].slc; 62 - if (p->line_len) 63 - n += scnprintf(buf + n, len - n, 64 - "SLC\t\t: %uK, %uB Line%s\n", 65 - p->sz_k, p->line_len, IS_USED_RUN(slc_enable)); 66 - 67 - n += scnprintf(buf + n, len - n, "Peripherals\t: %#lx%s%s\n", 68 - perip_base, 69 - IS_AVAIL3(ioc_exists, ioc_enable, ", IO-Coherency (per-device) ")); 70 - 71 - return buf; 72 - } 73 - 74 - /* 75 - * Read the Cache Build Confuration Registers, Decode them and save into 76 - * the cpuinfo structure for later use. 77 - * No Validation done here, simply read/convert the BCRs 78 - */ 79 - static void read_decode_cache_bcr_arcv2(int cpu) 80 - { 81 - struct cpuinfo_arc_cache *p_slc = &cpuinfo_arc700[cpu].slc; 40 + struct cpuinfo_arc_cache *p_slc = &slc_info; 41 + struct bcr_identity ident; 82 42 struct bcr_generic sbcr; 83 - 84 - struct bcr_slc_cfg { 85 - #ifdef CONFIG_CPU_BIG_ENDIAN 86 - unsigned int pad:24, way:2, lsz:2, sz:4; 87 - #else 88 - unsigned int sz:4, lsz:2, way:2, pad:24; 89 - #endif 90 - } slc_cfg; 91 - 92 - struct bcr_clust_cfg { 93 - #ifdef CONFIG_CPU_BIG_ENDIAN 94 - unsigned int pad:7, c:1, num_entries:8, num_cores:8, ver:8; 95 - #else 96 - unsigned int ver:8, num_cores:8, num_entries:8, c:1, pad:7; 97 - #endif 98 - } cbcr; 99 - 100 - struct bcr_volatile { 101 - #ifdef CONFIG_CPU_BIG_ENDIAN 102 - unsigned int start:4, limit:4, pad:22, order:1, disable:1; 103 - #else 104 - unsigned int disable:1, order:1, pad:22, limit:4, start:4; 105 - #endif 106 - } vol; 107 - 43 + struct bcr_clust_cfg cbcr; 44 + struct bcr_volatile vol; 45 + int n = 0; 108 46 109 47 READ_BCR(ARC_REG_SLC_BCR, sbcr); 110 48 if (sbcr.ver) { 49 + struct bcr_slc_cfg slc_cfg; 111 50 READ_BCR(ARC_REG_SLC_CFG, slc_cfg); 112 51 p_slc->sz_k = 128 << slc_cfg.sz; 113 52 l2_line_sz = p_slc->line_len = (slc_cfg.lsz == 0) ? 128 : 64; 53 + n += scnprintf(buf + n, len - n, 54 + "SLC\t\t: %uK, %uB Line%s\n", 55 + p_slc->sz_k, p_slc->line_len, IS_USED_RUN(slc_enable)); 114 56 } 115 57 116 58 READ_BCR(ARC_REG_CLUSTER_BCR, cbcr); ··· 79 129 ioc_enable = 0; 80 130 } 81 131 132 + READ_BCR(AUX_IDENTITY, ident); 133 + 82 134 /* HS 2.0 didn't have AUX_VOL */ 83 - if (cpuinfo_arc700[cpu].core.family > 0x51) { 135 + if (ident.family > 0x51) { 84 136 READ_BCR(AUX_VOL, vol); 85 137 perip_base = vol.start << 28; 86 138 /* HS 3.0 has limit and strict-ordering fields */ 87 - if (cpuinfo_arc700[cpu].core.family > 0x52) 139 + if (ident.family > 0x52) 88 140 perip_end = (vol.limit << 28) - 1; 89 141 } 142 + 143 + n += scnprintf(buf + n, len - n, "Peripherals\t: %#lx%s%s\n", 144 + perip_base, 145 + IS_AVAIL3(ioc_exists, ioc_enable, ", IO-Coherency (per-device) ")); 146 + 147 + return n; 90 148 } 91 149 92 - void read_decode_cache_bcr(void) 150 + int arc_cache_mumbojumbo(int c, char *buf, int len) 93 151 { 94 - struct cpuinfo_arc_cache *p_ic, *p_dc; 95 - unsigned int cpu = smp_processor_id(); 96 - struct bcr_cache { 97 - #ifdef CONFIG_CPU_BIG_ENDIAN 98 - unsigned int pad:12, line_len:4, sz:4, config:4, ver:8; 99 - #else 100 - unsigned int ver:8, config:4, sz:4, line_len:4, pad:12; 101 - #endif 102 - } ibcr, dbcr; 152 + struct cpuinfo_arc_cache *p_ic = &ic_info, *p_dc = &dc_info; 153 + struct bcr_cache ibcr, dbcr; 154 + int vipt, assoc; 155 + int n = 0; 103 156 104 - p_ic = &cpuinfo_arc700[cpu].icache; 105 157 READ_BCR(ARC_REG_IC_BCR, ibcr); 106 - 107 158 if (!ibcr.ver) 108 159 goto dc_chk; 109 160 110 - if (ibcr.ver <= 3) { 161 + if (is_isa_arcompact() && (ibcr.ver <= 3)) { 111 162 BUG_ON(ibcr.config != 3); 112 - p_ic->assoc = 2; /* Fixed to 2w set assoc */ 113 - } else if (ibcr.ver >= 4) { 114 - p_ic->assoc = 1 << ibcr.config; /* 1,2,4,8 */ 163 + assoc = 2; /* Fixed to 2w set assoc */ 164 + } else if (is_isa_arcv2() && (ibcr.ver >= 4)) { 165 + assoc = 1 << ibcr.config; /* 1,2,4,8 */ 115 166 } 116 167 117 168 p_ic->line_len = 8 << ibcr.line_len; 118 169 p_ic->sz_k = 1 << (ibcr.sz - 1); 119 - p_ic->vipt = 1; 120 - p_ic->alias = p_ic->sz_k/p_ic->assoc/TO_KB(PAGE_SIZE) > 1; 170 + p_ic->colors = p_ic->sz_k/assoc/TO_KB(PAGE_SIZE); 171 + 172 + n += scnprintf(buf + n, len - n, 173 + "I-Cache\t\t: %uK, %dway/set, %uB Line, VIPT%s%s\n", 174 + p_ic->sz_k, assoc, p_ic->line_len, 175 + p_ic->colors > 1 ? " aliasing" : "", 176 + IS_USED_CFG(CONFIG_ARC_HAS_ICACHE)); 121 177 122 178 dc_chk: 123 - p_dc = &cpuinfo_arc700[cpu].dcache; 124 179 READ_BCR(ARC_REG_DC_BCR, dbcr); 125 - 126 180 if (!dbcr.ver) 127 181 goto slc_chk; 128 182 129 - if (dbcr.ver <= 3) { 183 + if (is_isa_arcompact() && (dbcr.ver <= 3)) { 130 184 BUG_ON(dbcr.config != 2); 131 - p_dc->assoc = 4; /* Fixed to 4w set assoc */ 132 - p_dc->vipt = 1; 133 - p_dc->alias = p_dc->sz_k/p_dc->assoc/TO_KB(PAGE_SIZE) > 1; 134 - } else if (dbcr.ver >= 4) { 135 - p_dc->assoc = 1 << dbcr.config; /* 1,2,4,8 */ 136 - p_dc->vipt = 0; 137 - p_dc->alias = 0; /* PIPT so can't VIPT alias */ 185 + vipt = 1; 186 + assoc = 4; /* Fixed to 4w set assoc */ 187 + p_dc->colors = p_dc->sz_k/assoc/TO_KB(PAGE_SIZE); 188 + } else if (is_isa_arcv2() && (dbcr.ver >= 4)) { 189 + vipt = 0; 190 + assoc = 1 << dbcr.config; /* 1,2,4,8 */ 191 + p_dc->colors = 1; /* PIPT so can't VIPT alias */ 138 192 } 139 193 140 194 p_dc->line_len = 16 << dbcr.line_len; 141 195 p_dc->sz_k = 1 << (dbcr.sz - 1); 142 196 197 + n += scnprintf(buf + n, len - n, 198 + "D-Cache\t\t: %uK, %dway/set, %uB Line, %s%s%s\n", 199 + p_dc->sz_k, assoc, p_dc->line_len, 200 + vipt ? "VIPT" : "PIPT", 201 + p_dc->colors > 1 ? " aliasing" : "", 202 + IS_USED_CFG(CONFIG_ARC_HAS_DCACHE)); 203 + 143 204 slc_chk: 144 205 if (is_isa_arcv2()) 145 - read_decode_cache_bcr_arcv2(cpu); 206 + n += read_decode_cache_bcr_arcv2(c, buf + n, len - n); 207 + 208 + return n; 146 209 } 147 210 148 211 /* ··· 544 581 545 582 #endif /* CONFIG_ARC_HAS_ICACHE */ 546 583 547 - noinline void slc_op_rgn(phys_addr_t paddr, unsigned long sz, const int op) 584 + static noinline void slc_op_rgn(phys_addr_t paddr, unsigned long sz, const int op) 548 585 { 549 586 #ifdef CONFIG_ISA_ARCV2 550 587 /* ··· 607 644 #endif 608 645 } 609 646 610 - noinline void slc_op_line(phys_addr_t paddr, unsigned long sz, const int op) 647 + static __maybe_unused noinline void slc_op_line(phys_addr_t paddr, unsigned long sz, const int op) 611 648 { 612 649 #ifdef CONFIG_ISA_ARCV2 613 650 /* ··· 1045 1082 * 3. All Caches need to be disabled when setting up IOC to elide any in-flight 1046 1083 * Coherency transactions 1047 1084 */ 1048 - noinline void __init arc_ioc_setup(void) 1085 + static noinline void __init arc_ioc_setup(void) 1049 1086 { 1050 1087 unsigned int ioc_base, mem_sz; 1051 1088 ··· 1107 1144 * one core suffices for all 1108 1145 * - IOC setup / dma callbacks only need to be done once 1109 1146 */ 1110 - void __init arc_cache_init_master(void) 1147 + static noinline void __init arc_cache_init_master(void) 1111 1148 { 1112 - unsigned int __maybe_unused cpu = smp_processor_id(); 1113 - 1114 1149 if (IS_ENABLED(CONFIG_ARC_HAS_ICACHE)) { 1115 - struct cpuinfo_arc_cache *ic = &cpuinfo_arc700[cpu].icache; 1150 + struct cpuinfo_arc_cache *ic = &ic_info; 1116 1151 1117 1152 if (!ic->line_len) 1118 1153 panic("cache support enabled but non-existent cache\n"); ··· 1123 1162 * In MMU v4 (HS38x) the aliasing icache config uses IVIL/PTAG 1124 1163 * pair to provide vaddr/paddr respectively, just as in MMU v3 1125 1164 */ 1126 - if (is_isa_arcv2() && ic->alias) 1165 + if (is_isa_arcv2() && ic->colors > 1) 1127 1166 _cache_line_loop_ic_fn = __cache_line_loop_v3; 1128 1167 else 1129 1168 _cache_line_loop_ic_fn = __cache_line_loop; 1130 1169 } 1131 1170 1132 1171 if (IS_ENABLED(CONFIG_ARC_HAS_DCACHE)) { 1133 - struct cpuinfo_arc_cache *dc = &cpuinfo_arc700[cpu].dcache; 1172 + struct cpuinfo_arc_cache *dc = &dc_info; 1134 1173 1135 1174 if (!dc->line_len) 1136 1175 panic("cache support enabled but non-existent cache\n"); ··· 1142 1181 /* check for D-Cache aliasing on ARCompact: ARCv2 has PIPT */ 1143 1182 if (is_isa_arcompact()) { 1144 1183 int handled = IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING); 1145 - int num_colors = dc->sz_k/dc->assoc/TO_KB(PAGE_SIZE); 1146 1184 1147 - if (dc->alias) { 1185 + if (dc->colors > 1) { 1148 1186 if (!handled) 1149 1187 panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n"); 1150 - if (CACHE_COLORS_NUM != num_colors) 1188 + if (CACHE_COLORS_NUM != dc->colors) 1151 1189 panic("CACHE_COLORS_NUM not optimized for config\n"); 1152 - } else if (!dc->alias && handled) { 1190 + } else if (handled && dc->colors == 1) { 1153 1191 panic("Disable CONFIG_ARC_CACHE_VIPT_ALIASING\n"); 1154 1192 } 1155 1193 } ··· 1191 1231 void __ref arc_cache_init(void) 1192 1232 { 1193 1233 unsigned int __maybe_unused cpu = smp_processor_id(); 1194 - char str[256]; 1195 - 1196 - pr_info("%s", arc_cache_mumbojumbo(0, str, sizeof(str))); 1197 1234 1198 1235 if (!cpu) 1199 1236 arc_cache_init_master();
-11
arch/arc/mm/extable.c
··· 22 22 23 23 return 0; 24 24 } 25 - 26 - #ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE 27 - 28 - unsigned long arc_clear_user_noinline(void __user *to, 29 - unsigned long n) 30 - { 31 - return __arc_clear_user(to, n); 32 - } 33 - EXPORT_SYMBOL(arc_clear_user_noinline); 34 - 35 - #endif
+4 -3
arch/arc/mm/fault.c
··· 13 13 #include <linux/kdebug.h> 14 14 #include <linux/perf_event.h> 15 15 #include <linux/mm_types.h> 16 + #include <asm/entry.h> 16 17 #include <asm/mmu.h> 17 18 18 19 /* ··· 100 99 if (faulthandler_disabled() || !mm) 101 100 goto no_context; 102 101 103 - if (regs->ecr_cause & ECR_C_PROTV_STORE) /* ST/EX */ 102 + if (regs->ecr.cause & ECR_C_PROTV_STORE) /* ST/EX */ 104 103 write = 1; 105 - else if ((regs->ecr_vec == ECR_V_PROTV) && 106 - (regs->ecr_cause == ECR_C_PROTV_INST_FETCH)) 104 + else if ((regs->ecr.vec == ECR_V_PROTV) && 105 + (regs->ecr.cause == ECR_C_PROTV_INST_FETCH)) 107 106 exec = 1; 108 107 109 108 flags = FAULT_FLAG_DEFAULT;
+1
arch/arc/mm/init.c
··· 15 15 #include <linux/highmem.h> 16 16 #include <asm/page.h> 17 17 #include <asm/sections.h> 18 + #include <asm/setup.h> 18 19 #include <asm/arcregs.h> 19 20 20 21 pgd_t swapper_pg_dir[PTRS_PER_PGD] __aligned(PAGE_SIZE);
+37 -60
arch/arc/mm/tlb.c
··· 18 18 /* A copy of the ASID from the PID reg is kept in asid_cache */ 19 19 DEFINE_PER_CPU(unsigned int, asid_cache) = MM_CTXT_FIRST_CYCLE; 20 20 21 - static int __read_mostly pae_exists; 21 + static struct cpuinfo_arc_mmu { 22 + unsigned int ver, pg_sz_k, s_pg_sz_m, pae, sets, ways; 23 + } mmuinfo; 22 24 23 25 /* 24 26 * Utility Routine to erase a J-TLB entry ··· 133 131 134 132 noinline void local_flush_tlb_all(void) 135 133 { 136 - struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu; 134 + struct cpuinfo_arc_mmu *mmu = &mmuinfo; 137 135 unsigned long flags; 138 136 unsigned int entry; 139 137 int num_tlb = mmu->sets * mmu->ways; ··· 391 389 /* 392 390 * Routine to create a TLB entry 393 391 */ 394 - void create_tlb(struct vm_area_struct *vma, unsigned long vaddr, pte_t *ptep) 392 + static void create_tlb(struct vm_area_struct *vma, unsigned long vaddr, pte_t *ptep) 395 393 { 396 394 unsigned long flags; 397 395 unsigned int asid_or_sasid, rwx; ··· 566 564 * the cpuinfo structure for later use. 567 565 * No Validation is done here, simply read/convert the BCRs 568 566 */ 569 - void read_decode_mmu_bcr(void) 567 + int arc_mmu_mumbojumbo(int c, char *buf, int len) 570 568 { 571 - struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu; 572 - unsigned int tmp; 573 - struct bcr_mmu_3 { 574 - #ifdef CONFIG_CPU_BIG_ENDIAN 575 - unsigned int ver:8, ways:4, sets:4, res:3, sasid:1, pg_sz:4, 576 - u_itlb:4, u_dtlb:4; 577 - #else 578 - unsigned int u_dtlb:4, u_itlb:4, pg_sz:4, sasid:1, res:3, sets:4, 579 - ways:4, ver:8; 580 - #endif 581 - } *mmu3; 569 + struct cpuinfo_arc_mmu *mmu = &mmuinfo; 570 + unsigned int bcr, u_dtlb, u_itlb, sasid; 571 + struct bcr_mmu_3 *mmu3; 572 + struct bcr_mmu_4 *mmu4; 573 + char super_pg[64] = ""; 574 + int n = 0; 582 575 583 - struct bcr_mmu_4 { 584 - #ifdef CONFIG_CPU_BIG_ENDIAN 585 - unsigned int ver:8, sasid:1, sz1:4, sz0:4, res:2, pae:1, 586 - n_ways:2, n_entry:2, n_super:2, u_itlb:3, u_dtlb:3; 587 - #else 588 - /* DTLB ITLB JES JE JA */ 589 - unsigned int u_dtlb:3, u_itlb:3, n_super:2, n_entry:2, n_ways:2, 590 - pae:1, res:2, sz0:4, sz1:4, sasid:1, ver:8; 591 - #endif 592 - } *mmu4; 593 - 594 - tmp = read_aux_reg(ARC_REG_MMU_BCR); 595 - mmu->ver = (tmp >> 24); 576 + bcr = read_aux_reg(ARC_REG_MMU_BCR); 577 + mmu->ver = (bcr >> 24); 596 578 597 579 if (is_isa_arcompact() && mmu->ver == 3) { 598 - mmu3 = (struct bcr_mmu_3 *)&tmp; 580 + mmu3 = (struct bcr_mmu_3 *)&bcr; 599 581 mmu->pg_sz_k = 1 << (mmu3->pg_sz - 1); 600 582 mmu->sets = 1 << mmu3->sets; 601 583 mmu->ways = 1 << mmu3->ways; 602 - mmu->u_dtlb = mmu3->u_dtlb; 603 - mmu->u_itlb = mmu3->u_itlb; 604 - mmu->sasid = mmu3->sasid; 584 + u_dtlb = mmu3->u_dtlb; 585 + u_itlb = mmu3->u_itlb; 586 + sasid = mmu3->sasid; 605 587 } else { 606 - mmu4 = (struct bcr_mmu_4 *)&tmp; 588 + mmu4 = (struct bcr_mmu_4 *)&bcr; 607 589 mmu->pg_sz_k = 1 << (mmu4->sz0 - 1); 608 590 mmu->s_pg_sz_m = 1 << (mmu4->sz1 - 11); 609 591 mmu->sets = 64 << mmu4->n_entry; 610 592 mmu->ways = mmu4->n_ways * 2; 611 - mmu->u_dtlb = mmu4->u_dtlb * 4; 612 - mmu->u_itlb = mmu4->u_itlb * 4; 613 - mmu->sasid = mmu4->sasid; 614 - pae_exists = mmu->pae = mmu4->pae; 593 + u_dtlb = mmu4->u_dtlb * 4; 594 + u_itlb = mmu4->u_itlb * 4; 595 + sasid = mmu4->sasid; 596 + mmu->pae = mmu4->pae; 615 597 } 616 - } 617 598 618 - char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len) 619 - { 620 - int n = 0; 621 - struct cpuinfo_arc_mmu *p_mmu = &cpuinfo_arc700[cpu_id].mmu; 622 - char super_pg[64] = ""; 623 - 624 - if (p_mmu->s_pg_sz_m) 625 - scnprintf(super_pg, 64, "%dM Super Page %s", 626 - p_mmu->s_pg_sz_m, 627 - IS_USED_CFG(CONFIG_TRANSPARENT_HUGEPAGE)); 599 + if (mmu->s_pg_sz_m) 600 + scnprintf(super_pg, 64, "/%dM%s", 601 + mmu->s_pg_sz_m, 602 + IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) ? " (THP enabled)":""); 628 603 629 604 n += scnprintf(buf + n, len - n, 630 - "MMU [v%x]\t: %dk PAGE, %s, swalk %d lvl, JTLB %d (%dx%d), uDTLB %d, uITLB %d%s%s\n", 631 - p_mmu->ver, p_mmu->pg_sz_k, super_pg, CONFIG_PGTABLE_LEVELS, 632 - p_mmu->sets * p_mmu->ways, p_mmu->sets, p_mmu->ways, 633 - p_mmu->u_dtlb, p_mmu->u_itlb, 634 - IS_AVAIL2(p_mmu->pae, ", PAE40 ", CONFIG_ARC_HAS_PAE40)); 605 + "MMU [v%x]\t: %dk%s, swalk %d lvl, JTLB %dx%d, uDTLB %d, uITLB %d%s%s%s\n", 606 + mmu->ver, mmu->pg_sz_k, super_pg, CONFIG_PGTABLE_LEVELS, 607 + mmu->sets, mmu->ways, 608 + u_dtlb, u_itlb, 609 + IS_AVAIL1(sasid, ", SASID"), 610 + IS_AVAIL2(mmu->pae, ", PAE40 ", CONFIG_ARC_HAS_PAE40)); 635 611 636 - return buf; 612 + return n; 637 613 } 638 614 639 615 int pae40_exist_but_not_enab(void) 640 616 { 641 - return pae_exists && !is_pae40_enabled(); 617 + return mmuinfo.pae && !is_pae40_enabled(); 642 618 } 643 619 644 620 void arc_mmu_init(void) 645 621 { 646 - struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu; 647 - char str[256]; 622 + struct cpuinfo_arc_mmu *mmu = &mmuinfo; 648 623 int compat = 0; 649 - 650 - pr_info("%s", arc_mmu_mumbojumbo(0, str, sizeof(str))); 651 624 652 625 /* 653 626 * Can't be done in processor.h due to header include dependencies ··· 700 723 void do_tlb_overlap_fault(unsigned long cause, unsigned long address, 701 724 struct pt_regs *regs) 702 725 { 703 - struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu; 726 + struct cpuinfo_arc_mmu *mmu = &mmuinfo; 704 727 unsigned long flags; 705 728 int set, n_ways = mmu->ways; 706 729
-1
arch/arc/plat-axs10x/axs10x.c
··· 6 6 */ 7 7 8 8 #include <linux/of_fdt.h> 9 - #include <linux/of_platform.h> 10 9 #include <linux/libfdt.h> 11 10 12 11 #include <asm/asm-offsets.h>