diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-09-04 15:38:24 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-09-04 15:38:24 -0700 |
commit | 3f86ed6ec0b390c033eae7f9c487a3fea268e027 (patch) | |
tree | a0a1fa3e5c04e146bf9414833da9bc634df10b95 /arch/arc/kernel | |
parent | ea4f9c37f75271d8256a326c938c95733e1fec35 (diff) | |
parent | c40cad3b0aa47d6d0995637178fb6607ac3d45c1 (diff) | |
download | linux-3f86ed6ec0b390c033eae7f9c487a3fea268e027.tar.gz linux-3f86ed6ec0b390c033eae7f9c487a3fea268e027.tar.bz2 linux-3f86ed6ec0b390c033eae7f9c487a3fea268e027.zip |
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
...
Diffstat (limited to 'arch/arc/kernel')
-rw-r--r-- | arch/arc/kernel/Makefile | 9 | ||||
-rw-r--r-- | arch/arc/kernel/asm-offsets.c | 14 | ||||
-rw-r--r-- | arch/arc/kernel/ctx_sw.c | 112 | ||||
-rw-r--r-- | arch/arc/kernel/ctx_sw_asm.S | 76 | ||||
-rw-r--r-- | arch/arc/kernel/devtree.c | 1 | ||||
-rw-r--r-- | arch/arc/kernel/entry-arcv2.S | 15 | ||||
-rw-r--r-- | arch/arc/kernel/entry-compact.S | 19 | ||||
-rw-r--r-- | arch/arc/kernel/entry.S | 70 | ||||
-rw-r--r-- | arch/arc/kernel/intc-arcv2.c | 2 | ||||
-rw-r--r-- | arch/arc/kernel/kgdb.c | 2 | ||||
-rw-r--r-- | arch/arc/kernel/mcip.c | 2 | ||||
-rw-r--r-- | arch/arc/kernel/process.c | 17 | ||||
-rw-r--r-- | arch/arc/kernel/ptrace.c | 8 | ||||
-rw-r--r-- | arch/arc/kernel/setup.c | 563 | ||||
-rw-r--r-- | arch/arc/kernel/signal.c | 1 | ||||
-rw-r--r-- | arch/arc/kernel/smp.c | 7 | ||||
-rw-r--r-- | arch/arc/kernel/stacktrace.c | 1 | ||||
-rw-r--r-- | arch/arc/kernel/traps.c | 5 | ||||
-rw-r--r-- | arch/arc/kernel/troubleshoot.c | 13 |
19 files changed, 358 insertions, 579 deletions
diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile index 0723d888ac44..95fbf9364c67 100644 --- a/arch/arc/kernel/Makefile +++ b/arch/arc/kernel/Makefile @@ -5,6 +5,8 @@ obj-y := head.o arcksyms.o setup.o irq.o reset.o ptrace.o process.o devtree.o obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o +obj-y += ctx_sw_asm.o + obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o @@ -24,11 +26,4 @@ ifdef CONFIG_ISA_ARCOMPACT CFLAGS_fpu.o += -mdpfp endif -ifdef CONFIG_ARC_DW2_UNWIND -CFLAGS_ctx_sw.o += -fno-omit-frame-pointer -obj-y += ctx_sw.o -else -obj-y += ctx_sw_asm.o -endif - extra-y := vmlinux.lds diff --git a/arch/arc/kernel/asm-offsets.c b/arch/arc/kernel/asm-offsets.c index 0e884036ab74..f77deb799175 100644 --- a/arch/arc/kernel/asm-offsets.c +++ b/arch/arc/kernel/asm-offsets.c @@ -20,13 +20,13 @@ int main(void) BLANK(); - DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); DEFINE(THREAD_CALLEE_REG, offsetof(struct thread_struct, callee_reg)); DEFINE(THREAD_FAULT_ADDR, offsetof(struct thread_struct, fault_address)); BLANK(); + DEFINE(THREAD_INFO_KSP, offsetof(struct thread_info, ksp)); DEFINE(THREAD_INFO_FLAGS, offsetof(struct thread_info, flags)); DEFINE(THREAD_INFO_PREEMPT_COUNT, offsetof(struct thread_info, preempt_count)); @@ -46,7 +46,8 @@ int main(void) BLANK(); DEFINE(PT_status32, offsetof(struct pt_regs, status32)); - DEFINE(PT_event, offsetof(struct pt_regs, event)); + DEFINE(PT_event, offsetof(struct pt_regs, ecr)); + DEFINE(PT_bta, offsetof(struct pt_regs, bta)); DEFINE(PT_sp, offsetof(struct pt_regs, sp)); DEFINE(PT_r0, offsetof(struct pt_regs, r0)); DEFINE(PT_r1, offsetof(struct pt_regs, r1)); @@ -61,13 +62,9 @@ int main(void) DEFINE(PT_r26, offsetof(struct pt_regs, r26)); DEFINE(PT_ret, offsetof(struct pt_regs, ret)); DEFINE(PT_blink, offsetof(struct pt_regs, blink)); + OFFSET(PT_fp, pt_regs, fp); DEFINE(PT_lpe, offsetof(struct pt_regs, lp_end)); DEFINE(PT_lpc, offsetof(struct pt_regs, lp_count)); - DEFINE(PT_user_r25, offsetof(struct pt_regs, user_r25)); - - DEFINE(SZ_CALLEE_REGS, sizeof(struct callee_regs)); - DEFINE(SZ_PT_REGS, sizeof(struct pt_regs)); - #ifdef CONFIG_ISA_ARCV2 OFFSET(PT_r12, pt_regs, r12); OFFSET(PT_r30, pt_regs, r30); @@ -80,5 +77,8 @@ int main(void) OFFSET(PT_DSP_CTRL, pt_regs, DSP_CTRL); #endif + DEFINE(SZ_CALLEE_REGS, sizeof(struct callee_regs)); + DEFINE(SZ_PT_REGS, sizeof(struct pt_regs)); + return 0; } diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c deleted file mode 100644 index 1a76f2d6f694..000000000000 --- a/arch/arc/kernel/ctx_sw.c +++ /dev/null @@ -1,112 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) - * - * Vineetg: Aug 2009 - * -"C" version of lowest level context switch asm macro called by schedular - * gcc doesn't generate the dward CFI info for hand written asm, hence can't - * backtrace out of it (e.g. tasks sleeping in kernel). - * So we cheat a bit by writing almost similar code in inline-asm. - * -This is a hacky way of doing things, but there is no other simple way. - * I don't want/intend to extend unwinding code to understand raw asm - */ - -#include <asm/asm-offsets.h> -#include <linux/sched.h> -#include <linux/sched/debug.h> - -#define KSP_WORD_OFF ((TASK_THREAD + THREAD_KSP) / 4) - -struct task_struct *__sched -__switch_to(struct task_struct *prev_task, struct task_struct *next_task) -{ - unsigned int tmp; - unsigned int prev = (unsigned int)prev_task; - unsigned int next = (unsigned int)next_task; - - __asm__ __volatile__( - /* FP/BLINK save generated by gcc (standard function prologue */ - "st.a r13, [sp, -4] \n\t" - "st.a r14, [sp, -4] \n\t" - "st.a r15, [sp, -4] \n\t" - "st.a r16, [sp, -4] \n\t" - "st.a r17, [sp, -4] \n\t" - "st.a r18, [sp, -4] \n\t" - "st.a r19, [sp, -4] \n\t" - "st.a r20, [sp, -4] \n\t" - "st.a r21, [sp, -4] \n\t" - "st.a r22, [sp, -4] \n\t" - "st.a r23, [sp, -4] \n\t" - "st.a r24, [sp, -4] \n\t" -#ifndef CONFIG_ARC_CURR_IN_REG - "st.a r25, [sp, -4] \n\t" -#else - "sub sp, sp, 4 \n\t" /* usual r25 placeholder */ -#endif - - /* set ksp of outgoing task in tsk->thread.ksp */ -#if KSP_WORD_OFF <= 255 - "st.as sp, [%3, %1] \n\t" -#else - /* - * Workaround for NR_CPUS=4k - * %1 is bigger than 255 (S9 offset for st.as) - */ - "add2 r24, %3, %1 \n\t" - "st sp, [r24] \n\t" -#endif - - /* - * setup _current_task with incoming tsk. - * optionally, set r25 to that as well - * For SMP extra work to get to &_current_task[cpu] - * (open coded SET_CURR_TASK_ON_CPU) - */ -#ifndef CONFIG_SMP - "st %2, [@_current_task] \n\t" -#else - "lr r24, [identity] \n\t" - "lsr r24, r24, 8 \n\t" - "bmsk r24, r24, 7 \n\t" - "add2 r24, @_current_task, r24 \n\t" - "st %2, [r24] \n\t" -#endif -#ifdef CONFIG_ARC_CURR_IN_REG - "mov r25, %2 \n\t" -#endif - - /* get ksp of incoming task from tsk->thread.ksp */ - "ld.as sp, [%2, %1] \n\t" - - /* start loading it's CALLEE reg file */ - -#ifndef CONFIG_ARC_CURR_IN_REG - "ld.ab r25, [sp, 4] \n\t" -#else - "add sp, sp, 4 \n\t" -#endif - "ld.ab r24, [sp, 4] \n\t" - "ld.ab r23, [sp, 4] \n\t" - "ld.ab r22, [sp, 4] \n\t" - "ld.ab r21, [sp, 4] \n\t" - "ld.ab r20, [sp, 4] \n\t" - "ld.ab r19, [sp, 4] \n\t" - "ld.ab r18, [sp, 4] \n\t" - "ld.ab r17, [sp, 4] \n\t" - "ld.ab r16, [sp, 4] \n\t" - "ld.ab r15, [sp, 4] \n\t" - "ld.ab r14, [sp, 4] \n\t" - "ld.ab r13, [sp, 4] \n\t" - - /* last (ret value) = prev : although for ARC it mov r0, r0 */ - "mov %0, %3 \n\t" - - /* FP/BLINK restore generated by gcc (standard func epilogue */ - - : "=r"(tmp) - : "n"(KSP_WORD_OFF), "r"(next), "r"(prev) - : "blink" - ); - - return (struct task_struct *)tmp; -} diff --git a/arch/arc/kernel/ctx_sw_asm.S b/arch/arc/kernel/ctx_sw_asm.S index 02c461484761..48e1f21976ed 100644 --- a/arch/arc/kernel/ctx_sw_asm.S +++ b/arch/arc/kernel/ctx_sw_asm.S @@ -11,50 +11,54 @@ #include <asm/entry.h> /* For the SAVE_* macros */ #include <asm/asm-offsets.h> -#define KSP_WORD_OFF ((TASK_THREAD + THREAD_KSP) / 4) - -;################### Low Level Context Switch ########################## +; IN +; - r0: prev task (also current) +; - r1: next task +; OUT +; - r0: prev task (so r0 not touched) .section .sched.text,"ax",@progbits - .align 4 - .global __switch_to - .type __switch_to, @function -__switch_to: - CFI_STARTPROC - - /* Save regs on kernel mode stack of task */ - st.a blink, [sp, -4] - st.a fp, [sp, -4] - SAVE_CALLEE_SAVED_KERNEL +ENTRY_CFI(__switch_to) - /* Save the now KSP in task->thread.ksp */ -#if KSP_WORD_OFF <= 255 - st.as sp, [r0, KSP_WORD_OFF] -#else - /* Workaround for NR_CPUS=4k as ST.as can only take s9 offset */ - add2 r24, r0, KSP_WORD_OFF - st sp, [r24] -#endif - /* - * Return last task in r0 (return reg) - * On ARC, Return reg = First Arg reg = r0. - * Since we already have last task in r0, - * don't need to do anything special to return it - */ + /* save kernel stack frame regs of @prev task */ + push blink + CFI_DEF_CFA_OFFSET 4 + CFI_OFFSET r31, -4 + + push fp + CFI_DEF_CFA_OFFSET 8 + CFI_OFFSET r27, -8 + + mov fp, sp + CFI_DEF_CFA_REGISTER r27 + + /* kernel mode callee regs of @prev */ + SAVE_CALLEE_SAVED_KERNEL /* - * switch to new task, contained in r1 - * Temp reg r3 is required to get the ptr to store val + * save final SP to @prev->thread_info.ksp + * @prev is "current" so thread_info derived from SP */ - SET_CURR_TASK_ON_CPU r1, r3 + GET_CURR_THR_INFO_FROM_SP r10 + st sp, [r10, THREAD_INFO_KSP] + + /* update @next in _current_task[] and GP register caching it */ + SET_CURR_TASK_ON_CPU r1, r10 - /* reload SP with kernel mode stack pointer in task->thread.ksp */ - ld.as sp, [r1, (TASK_THREAD + THREAD_KSP)/4] + /* load SP from @next->thread_info.ksp */ + ld r10, [r1, TASK_THREAD_INFO] + ld sp, [r10, THREAD_INFO_KSP] - /* restore the registers */ + /* restore callee regs, stack frame regs of @next */ RESTORE_CALLEE_SAVED_KERNEL - ld.ab fp, [sp, 4] - ld.ab blink, [sp, 4] - j [blink] + pop fp + CFI_RESTORE r27 + CFI_DEF_CFA r28, 4 + + pop blink + CFI_RESTORE r31 + CFI_DEF_CFA_OFFSET 0 + + j [blink] END_CFI(__switch_to) diff --git a/arch/arc/kernel/devtree.c b/arch/arc/kernel/devtree.c index 721d465f1580..4c9e61457b2f 100644 --- a/arch/arc/kernel/devtree.c +++ b/arch/arc/kernel/devtree.c @@ -12,6 +12,7 @@ #include <linux/of.h> #include <linux/of_fdt.h> #include <asm/mach_desc.h> +#include <asm/serial.h> #ifdef CONFIG_SERIAL_EARLYCON diff --git a/arch/arc/kernel/entry-arcv2.S b/arch/arc/kernel/entry-arcv2.S index a7e6a2174187..2e49c81c8086 100644 --- a/arch/arc/kernel/entry-arcv2.S +++ b/arch/arc/kernel/entry-arcv2.S @@ -125,11 +125,6 @@ ENTRY(mem_service) EXCEPTION_PROLOGUE - lr r0, [efa] - mov r1, sp - - FAKE_RET_FROM_EXCPN - bl do_memory_error b ret_from_exception END(mem_service) @@ -138,11 +133,6 @@ ENTRY(EV_Misaligned) EXCEPTION_PROLOGUE - lr r0, [efa] ; Faulting Data address - mov r1, sp - - FAKE_RET_FROM_EXCPN - SAVE_CALLEE_SAVED_USER mov r2, sp ; callee_regs @@ -163,11 +153,6 @@ ENTRY(EV_TLBProtV) EXCEPTION_PROLOGUE - lr r0, [efa] ; Faulting Data address - mov r1, sp ; pt_regs - - FAKE_RET_FROM_EXCPN - mov blink, ret_from_exception b do_page_fault diff --git a/arch/arc/kernel/entry-compact.S b/arch/arc/kernel/entry-compact.S index 5cb0cd7e4eab..774c03cc1d1a 100644 --- a/arch/arc/kernel/entry-compact.S +++ b/arch/arc/kernel/entry-compact.S @@ -254,18 +254,7 @@ END(handle_interrupt_level1) ENTRY(EV_TLBProtV) - EXCEPTION_PROLOGUE - - mov r2, r10 ; ECR set into r10 already - lr r0, [efa] ; Faulting Data address (not part of pt_regs saved above) - - ; Exception auto-disables further Intr/exceptions. - ; Re-enable them by pretending to return from exception - ; (so rest of handler executes in pure K mode) - - FAKE_RET_FROM_EXCPN - - mov r1, sp ; Handle to pt_regs + EXCEPTION_PROLOGUE ; ECR returned in r10 ;------ (5) Type of Protection Violation? ---------- ; @@ -273,8 +262,7 @@ ENTRY(EV_TLBProtV) ; -Access Violation : 00_23_(00|01|02|03)_00 ; x r w r+w ; -Unaligned Access : 00_23_04_00 - ; - bbit1 r2, ECR_C_BIT_PROTV_MISALIG_DATA, 4f + bbit1 r10, ECR_C_BIT_PROTV_MISALIG_DATA, 4f ;========= (6a) Access Violation Processing ======== bl do_page_fault @@ -303,9 +291,6 @@ END(EV_TLBProtV) ENTRY(call_do_page_fault) EXCEPTION_PROLOGUE - lr r0, [efa] ; Faulting Data address - mov r1, sp - FAKE_RET_FROM_EXCPN mov blink, ret_from_exception b do_page_fault diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S index 54e91df678dd..089f6680518f 100644 --- a/arch/arc/kernel/entry.S +++ b/arch/arc/kernel/entry.S @@ -80,11 +80,6 @@ ENTRY(instr_service) EXCEPTION_PROLOGUE - lr r0, [efa] - mov r1, sp - - FAKE_RET_FROM_EXCPN - bl do_insterror_or_kprobe b ret_from_exception END(instr_service) @@ -95,16 +90,15 @@ END(instr_service) ENTRY(EV_MachineCheck) - EXCEPTION_PROLOGUE + EXCEPTION_PROLOGUE_KEEP_AE ; ECR returned in r10 - lr r2, [ecr] lr r0, [efa] mov r1, sp ; MC excpetions disable MMU ARC_MMU_REENABLE r3 - lsr r3, r2, 8 + lsr r3, r10, 8 bmsk r3, r3, 7 brne r3, ECR_C_MCHK_DUP_TLB, 1f @@ -129,11 +123,6 @@ ENTRY(EV_PrivilegeV) EXCEPTION_PROLOGUE - lr r0, [efa] - mov r1, sp - - FAKE_RET_FROM_EXCPN - bl do_privilege_fault b ret_from_exception END(EV_PrivilegeV) @@ -145,11 +134,6 @@ ENTRY(EV_Extension) EXCEPTION_PROLOGUE - lr r0, [efa] - mov r1, sp - - FAKE_RET_FROM_EXCPN - bl do_extension_fault b ret_from_exception END(EV_Extension) @@ -160,20 +144,19 @@ END(EV_Extension) ; syscall Tracing ; --------------------------------------------- tracesys: - ; save EFA in case tracer wants the PC of traced task - ; using ERET won't work since next-PC has already committed + ; safekeep EFA (r12) if syscall tracer wanted PC + ; for traps, ERET is pre-commit so points to next-PC GET_CURR_TASK_FIELD_PTR TASK_THREAD, r11 st r12, [r11, THREAD_FAULT_ADDR] ; thread.fault_address - ; PRE Sys Call Ptrace hook - mov r0, sp ; pt_regs needed - bl @syscall_trace_entry + ; PRE syscall trace hook + mov r0, sp ; pt_regs + bl @syscall_trace_enter ; Tracing code now returns the syscall num (orig or modif) mov r8, r0 ; Do the Sys Call as we normally would. - ; Validate the Sys Call number cmp r8, NR_syscalls - 1 mov.hi r0, -ENOSYS bhi tracesys_exit @@ -190,37 +173,36 @@ tracesys: ld r6, [sp, PT_r6] ld r7, [sp, PT_r7] ld.as r9, [sys_call_table, r8] - jl [r9] ; Entry into Sys Call Handler + jl [r9] tracesys_exit: - st r0, [sp, PT_r0] ; sys call return value in pt_regs + st r0, [sp, PT_r0] - ;POST Sys Call Ptrace Hook + ; POST syscall trace hook mov r0, sp ; pt_regs needed bl @syscall_trace_exit - b ret_from_exception ; NOT ret_from_system_call at is saves r0 which - ; we'd done before calling post hook above + + ; don't call ret_from_system_call as it saves r0, already done above + b ret_from_exception ; --------------------------------------------- ; Breakpoint TRAP ; --------------------------------------------- trap_with_param: mov r0, r12 ; EFA in case ptracer/gdb wants stop_pc - mov r1, sp + mov r1, sp ; pt_regs - ; Save callee regs in case gdb wants to have a look - ; SP will grow up by size of CALLEE Reg-File - ; NOTE: clobbers r12 + ; save callee regs in case tracer/gdb wants to peek SAVE_CALLEE_SAVED_USER - ; save location of saved Callee Regs @ thread_struct->pc + ; safekeep ref to callee regs GET_CURR_TASK_FIELD_PTR TASK_THREAD, r10 st sp, [r10, THREAD_CALLEE_REG] - ; Call the trap handler + ; call the non syscall trap handler bl do_non_swi_trap - ; unwind stack to discard Callee saved Regs + ; unwind stack to discard callee regs DISCARD_CALLEE_SAVED_USER b ret_from_exception @@ -232,37 +214,33 @@ trap_with_param: ENTRY(EV_Trap) - EXCEPTION_PROLOGUE + EXCEPTION_PROLOGUE_KEEP_AE lr r12, [efa] FAKE_RET_FROM_EXCPN - ;============ TRAP 1 :breakpoints - ; Check ECR for trap with arg (PROLOGUE ensures r10 has ECR) + ;============ TRAP N : breakpoints, kprobes etc bmsk.f 0, r10, 7 bnz trap_with_param - ;============ TRAP (no param): syscall top level + ;============ TRAP 0 (no param): syscall - ; If syscall tracing ongoing, invoke pre-post-hooks + ; syscall tracing ongoing, invoke pre-post-hooks around syscall GET_CURR_THR_INFO_FLAGS r10 and.f 0, r10, _TIF_SYSCALL_WORK bnz tracesys ; this never comes back ;============ Normal syscall case - ; syscall num shd not exceed the total system calls avail cmp r8, NR_syscalls - 1 mov.hi r0, -ENOSYS bhi .Lret_from_system_call - ; Offset into the syscall_table and call handler ld.as r9,[sys_call_table, r8] - jl [r9] ; Entry into Sys Call Handler + jl [r9] .Lret_from_system_call: - st r0, [sp, PT_r0] ; sys call return value in pt_regs ; fall through to ret_from_exception @@ -318,7 +296,7 @@ resume_user_mode_begin: ; tracer might call PEEKUSR(CALLEE reg) ; ; NOTE: SP will grow up by size of CALLEE Reg-File - SAVE_CALLEE_SAVED_USER ; clobbers r12 + SAVE_CALLEE_SAVED_USER ; save location of saved Callee Regs @ thread_struct->callee GET_CURR_TASK_FIELD_PTR TASK_THREAD, r10 diff --git a/arch/arc/kernel/intc-arcv2.c b/arch/arc/kernel/intc-arcv2.c index 5cda19d0aa91..678898757e47 100644 --- a/arch/arc/kernel/intc-arcv2.c +++ b/arch/arc/kernel/intc-arcv2.c @@ -108,7 +108,7 @@ static void arcv2_irq_unmask(struct irq_data *data) write_aux_reg(AUX_IRQ_ENABLE, 1); } -void arcv2_irq_enable(struct irq_data *data) +static void arcv2_irq_enable(struct irq_data *data) { /* set default priority */ write_aux_reg(AUX_IRQ_SELECT, data->hwirq); diff --git a/arch/arc/kernel/kgdb.c b/arch/arc/kernel/kgdb.c index 345a0000554c..4f2b5951454f 100644 --- a/arch/arc/kernel/kgdb.c +++ b/arch/arc/kernel/kgdb.c @@ -175,7 +175,7 @@ void kgdb_trap(struct pt_regs *regs) * with trap_s 4 (compiled) breakpoints, continuation needs to * start after the breakpoint. */ - if (regs->ecr_param == 3) + if (regs->ecr.param == 3) instruction_pointer(regs) -= BREAK_INSTR_SIZE; kgdb_handle_exception(1, SIGTRAP, 0, regs); diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c index f9fdb557c263..55373ca0d28b 100644 --- a/arch/arc/kernel/mcip.c +++ b/arch/arc/kernel/mcip.c @@ -165,8 +165,6 @@ static void mcip_probe_n_setup(void) IS_AVAIL1(mp.idu, "IDU "), IS_AVAIL1(mp.dbg, "DEBUG "), IS_AVAIL1(mp.gfrc, "GFRC")); - - cpuinfo_arc700[0].extn.gfrc = mp.gfrc; } struct plat_smp_ops plat_smp_ops = { diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c index 980b71da2f61..186ceab661eb 100644 --- a/arch/arc/kernel/process.c +++ b/arch/arc/kernel/process.c @@ -141,7 +141,7 @@ asmlinkage void ret_from_fork(void); * | unused | * | | * ------------------ - * | r25 | <==== top of Stack (thread.ksp) + * | r25 | <==== top of Stack (thread_info.ksp) * ~ ~ * | --to-- | (CALLEE Regs of kernel mode) * | r13 | @@ -162,7 +162,6 @@ asmlinkage void ret_from_fork(void); * | SP | * | orig_r0 | * | event/ECR | - * | user_r25 | * ------------------ <===== END of PAGE */ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) @@ -182,14 +181,14 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) c_callee = ((struct callee_regs *)childksp) - 1; /* - * __switch_to() uses thread.ksp to start unwinding stack + * __switch_to() uses thread_info.ksp to start unwinding stack * For kernel threads we don't need to create callee regs, the * stack layout nevertheless needs to remain the same. * Also, since __switch_to anyways unwinds callee regs, we use * this to populate kernel thread entry-pt/args into callee regs, * so that ret_from_kernel_thread() becomes simpler. */ - p->thread.ksp = (unsigned long)c_callee; /* THREAD_KSP */ + task_thread_info(p)->ksp = (unsigned long)c_callee; /* THREAD_INFO_KSP */ /* __switch_to expects FP(0), BLINK(return addr) at top */ childksp[0] = 0; /* fp */ @@ -243,16 +242,6 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) */ c_callee->r25 = task_thread_info(p)->thr_ptr; -#ifdef CONFIG_ARC_CURR_IN_REG - /* - * setup usermode thread pointer #2: - * however for this special use of r25 in kernel, __switch_to() sets - * r25 for kernel needs and only in the final return path is usermode - * r25 setup, from pt_regs->user_r25. So set that up as well - */ - c_regs->user_r25 = c_callee->r25; -#endif - return 0; } diff --git a/arch/arc/kernel/ptrace.c b/arch/arc/kernel/ptrace.c index 2abdcd9b09e8..e0c233c178b1 100644 --- a/arch/arc/kernel/ptrace.c +++ b/arch/arc/kernel/ptrace.c @@ -46,8 +46,7 @@ static const struct pt_regs_offset regoffset_table[] = { REG_OFFSET_NAME(r0), REG_OFFSET_NAME(sp), REG_OFFSET_NAME(orig_r0), - REG_OFFSET_NAME(event), - REG_OFFSET_NAME(user_r25), + REG_OFFSET_NAME(ecr), REG_OFFSET_END, }; @@ -55,9 +54,8 @@ static const struct pt_regs_offset regoffset_table[] = { static const struct pt_regs_offset regoffset_table[] = { REG_OFFSET_NAME(orig_r0), - REG_OFFSET_NAME(event), + REG_OFFSET_NAME(ecr), REG_OFFSET_NAME(bta), - REG_OFFSET_NAME(user_r25), REG_OFFSET_NAME(r26), REG_OFFSET_NAME(fp), REG_OFFSET_NAME(sp), @@ -341,7 +339,7 @@ long arch_ptrace(struct task_struct *child, long request, return ret; } -asmlinkage int syscall_trace_entry(struct pt_regs *regs) +asmlinkage int syscall_trace_enter(struct pt_regs *regs) { if (test_thread_flag(TIF_SYSCALL_TRACE)) if (ptrace_report_syscall_entry(regs)) diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index 41f07b3e594e..4dcf8589b708 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -29,6 +29,7 @@ #include <asm/mach_desc.h> #include <asm/smp.h> #include <asm/dsp-impl.h> +#include <soc/arc/mcip.h> #define FIX_PTR(x) __asm__ __volatile__(";" : "+r"(x)) @@ -43,19 +44,22 @@ const struct machine_desc *machine_desc; struct task_struct *_current_task[NR_CPUS]; /* For stack switching */ -struct cpuinfo_arc cpuinfo_arc700[NR_CPUS]; +struct cpuinfo_arc { + int arcver; + unsigned int t0:1, t1:1; + struct { + unsigned long base; + unsigned int sz; + } iccm, dccm; +}; + +#ifdef CONFIG_ISA_ARCV2 -static const struct id_to_str arc_legacy_rel[] = { +static const struct id_to_str arc_hs_rel[] = { /* ID.ARCVER, Release */ -#ifdef CONFIG_ISA_ARCOMPACT - { 0x34, "R4.10"}, - { 0x35, "R4.11"}, -#else { 0x51, "R2.0" }, { 0x52, "R2.1" }, { 0x53, "R3.0" }, -#endif - { 0x00, NULL } }; static const struct id_to_str arc_hs_ver54_rel[] = { @@ -66,323 +70,296 @@ static const struct id_to_str arc_hs_ver54_rel[] = { { 3, "R4.00a"}, { 0xFF, NULL } }; +#endif -static void read_decode_ccm_bcr(struct cpuinfo_arc *cpu) +static int +arcompact_mumbojumbo(int c, struct cpuinfo_arc *info, char *buf, int len) { - if (is_isa_arcompact()) { - struct bcr_iccm_arcompact iccm; - struct bcr_dccm_arcompact dccm; + int n = 0; +#ifdef CONFIG_ISA_ARCOMPACT + char *cpu_nm, *isa_nm = "ARCompact"; + struct bcr_fp_arcompact fpu_sp, fpu_dp; + int atomic = 0, be, present; + int bpu_full, bpu_cache, bpu_pred; + struct bcr_bpu_arcompact bpu; + struct bcr_iccm_arcompact iccm; + struct bcr_dccm_arcompact dccm; + struct bcr_generic isa; - READ_BCR(ARC_REG_ICCM_BUILD, iccm); - if (iccm.ver) { - cpu->iccm.sz = 4096 << iccm.sz; /* 8K to 512K */ - cpu->iccm.base_addr = iccm.base << 16; - } + READ_BCR(ARC_REG_ISA_CFG_BCR, isa); - READ_BCR(ARC_REG_DCCM_BUILD, dccm); - if (dccm.ver) { - unsigned long base; - cpu->dccm.sz = 2048 << dccm.sz; /* 2K to 256K */ + if (!isa.ver) /* ISA BCR absent, use Kconfig info */ + atomic = IS_ENABLED(CONFIG_ARC_HAS_LLSC); + else { + /* ARC700_BUILD only has 2 bits of isa info */ + atomic = isa.info & 1; + } - base = read_aux_reg(ARC_REG_DCCM_BASE_BUILD); - cpu->dccm.base_addr = base & ~0xF; - } - } else { - struct bcr_iccm_arcv2 iccm; - struct bcr_dccm_arcv2 dccm; - unsigned long region; - - READ_BCR(ARC_REG_ICCM_BUILD, iccm); - if (iccm.ver) { - cpu->iccm.sz = 256 << iccm.sz00; /* 512B to 16M */ - if (iccm.sz00 == 0xF && iccm.sz01 > 0) - cpu->iccm.sz <<= iccm.sz01; - - region = read_aux_reg(ARC_REG_AUX_ICCM); - cpu->iccm.base_addr = region & 0xF0000000; - } + be = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN); - READ_BCR(ARC_REG_DCCM_BUILD, dccm); - if (dccm.ver) { - cpu->dccm.sz = 256 << dccm.sz0; - if (dccm.sz0 == 0xF && dccm.sz1 > 0) - cpu->dccm.sz <<= dccm.sz1; + if (info->arcver < 0x34) + cpu_nm = "ARC750"; + else + cpu_nm = "ARC770"; - region = read_aux_reg(ARC_REG_AUX_DCCM); - cpu->dccm.base_addr = region & 0xF0000000; - } - } -} + n += scnprintf(buf + n, len - n, "processor [%d]\t: %s (%s ISA) %s%s%s\n", + c, cpu_nm, isa_nm, + IS_AVAIL2(atomic, "atomic ", CONFIG_ARC_HAS_LLSC), + IS_AVAIL1(be, "[Big-Endian]")); -static void decode_arc_core(struct cpuinfo_arc *cpu) -{ - struct bcr_uarch_build_arcv2 uarch; - const struct id_to_str *tbl; - - if (cpu->core.family < 0x54) { /* includes arc700 */ + READ_BCR(ARC_REG_FP_BCR, fpu_sp); + READ_BCR(ARC_REG_DPFP_BCR, fpu_dp); - for (tbl = &arc_legacy_rel[0]; tbl->id != 0; tbl++) { - if (cpu->core.family == tbl->id) { - cpu->release = tbl->str; - break; - } - } + if (fpu_sp.ver | fpu_dp.ver) + n += scnprintf(buf + n, len - n, "FPU\t\t: %s%s\n", + IS_AVAIL1(fpu_sp.ver, "SP "), + IS_AVAIL1(fpu_dp.ver, "DP ")); - if (is_isa_arcompact()) - cpu->name = "ARC700"; - else if (tbl->str) - cpu->name = "HS38"; - else - cpu->name = cpu->release = "Unknown"; + READ_BCR(ARC_REG_BPU_BCR, bpu); + bpu_full = bpu.fam ? 1 : 0; + bpu_cache = 256 << (bpu.ent - 1); + bpu_pred = 256 << (bpu.ent - 1); - return; + n += scnprintf(buf + n, len - n, + "BPU\t\t: %s%s match, cache:%d, Predict Table:%d\n", + IS_AVAIL1(bpu_full, "full"), + IS_AVAIL1(!bpu_full, "partial"), + bpu_cache, bpu_pred); + + READ_BCR(ARC_REG_ICCM_BUILD, iccm); + if (iccm.ver) { + info->iccm.sz = 4096 << iccm.sz; /* 8K to 512K */ + info->iccm.base = iccm.base << 16; } - /* - * Initial HS cores bumped AUX IDENTITY.ARCVER for each release until - * ARCVER 0x54 which introduced AUX MICRO_ARCH_BUILD and subsequent - * releases only update it. - */ - READ_BCR(ARC_REG_MICRO_ARCH_BCR, uarch); - - if (uarch.prod == 4) { - cpu->name = "HS48"; - cpu->extn.dual = 1; + READ_BCR(ARC_REG_DCCM_BUILD, dccm); + if (dccm.ver) { + unsigned long base; + info->dccm.sz = 2048 << dccm.sz; /* 2K to 256K */ - } else { - cpu->name = "HS38"; + base = read_aux_reg(ARC_REG_DCCM_BASE_BUILD); + info->dccm.base = base & ~0xF; } - for (tbl = &arc_hs_ver54_rel[0]; tbl->id != 0xFF; tbl++) { - if (uarch.maj == tbl->id) { - cpu->release = tbl->str; - break; - } - } + /* ARCompact ISA specific sanity checks */ + present = fpu_dp.ver; /* SP has no arch visible regs */ + CHK_OPT_STRICT(CONFIG_ARC_FPU_SAVE_RESTORE, present); +#endif + return n; + } -static void read_arc_build_cfg_regs(void) +static int arcv2_mumbojumbo(int c, struct cpuinfo_arc *info, char *buf, |