/* SPDX-License-Identifier: GPL-2.0+ */ | |
/* | |
* Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved. | |
*/ | |
#include <linux/linkage.h> | |
/* | |
* Note on the LD/ST addressing modes with address register write-back | |
* | |
* LD.a same as LD.aw | |
* | |
* LD.a reg1, [reg2, x] => Pre Incr | |
* Eff Addr for load = [reg2 + x] | |
* | |
* LD.ab reg1, [reg2, x] => Post Incr | |
* Eff Addr for load = [reg2] | |
*/ | |
.macro PUSH reg | |
st.a \reg, [%sp, -4] | |
.endm | |
.macro PUSHAX aux | |
lr %r9, [\aux] | |
PUSH %r9 | |
.endm | |
.macro SAVE_R1_TO_R24 | |
PUSH %r1 | |
PUSH %r2 | |
PUSH %r3 | |
PUSH %r4 | |
PUSH %r5 | |
PUSH %r6 | |
PUSH %r7 | |
PUSH %r8 | |
PUSH %r9 | |
PUSH %r10 | |
PUSH %r11 | |
PUSH %r12 | |
PUSH %r13 | |
PUSH %r14 | |
PUSH %r15 | |
PUSH %r16 | |
PUSH %r17 | |
PUSH %r18 | |
PUSH %r19 | |
PUSH %r20 | |
PUSH %r21 | |
PUSH %r22 | |
PUSH %r23 | |
PUSH %r24 | |
.endm | |
.macro SAVE_ALL_SYS | |
/* saving %r0 to reg->r0 in advance since we read %ecr into it */ | |
st %r0, [%sp, -8] | |
lr %r0, [%ecr] /* all stack addressing is manual so far */ | |
st %r0, [%sp] | |
st %sp, [%sp, -4] | |
/* now move %sp to reg->r0 position so we can do "push" automatically */ | |
sub %sp, %sp, 8 | |
SAVE_R1_TO_R24 | |
PUSH %r25 | |
PUSH %gp | |
PUSH %fp | |
PUSH %blink | |
PUSHAX %eret | |
PUSHAX %erstatus | |
PUSH %lp_count | |
PUSHAX %lp_end | |
PUSHAX %lp_start | |
PUSHAX %erbta | |
.endm | |
.macro SAVE_EXCEPTION_SOURCE | |
#ifdef CONFIG_MMU | |
/* If MMU exists exception faulting address is loaded in EFA reg */ | |
lr %r0, [%efa] | |
#else | |
/* Otherwise in ERET (exception return) reg */ | |
lr %r0, [%eret] | |
#endif | |
.endm | |
ENTRY(memory_error) | |
SAVE_ALL_SYS | |
SAVE_EXCEPTION_SOURCE | |
mov %r1, %sp | |
j do_memory_error | |
ENDPROC(memory_error) | |
ENTRY(instruction_error) | |
SAVE_ALL_SYS | |
SAVE_EXCEPTION_SOURCE | |
mov %r1, %sp | |
j do_instruction_error | |
ENDPROC(instruction_error) | |
ENTRY(interrupt_handler) | |
/* Todo - save and restore CPU context when interrupts will be in use */ | |
bl do_interrupt_handler | |
rtie | |
ENDPROC(interrupt_handler) | |
ENTRY(EV_MachineCheck) | |
SAVE_ALL_SYS | |
SAVE_EXCEPTION_SOURCE | |
mov %r1, %sp | |
j do_machine_check_fault | |
ENDPROC(EV_MachineCheck) | |
ENTRY(EV_TLBMissI) | |
SAVE_ALL_SYS | |
mov %r0, %sp | |
j do_itlb_miss | |
ENDPROC(EV_TLBMissI) | |
ENTRY(EV_TLBMissD) | |
SAVE_ALL_SYS | |
mov %r0, %sp | |
j do_dtlb_miss | |
ENDPROC(EV_TLBMissD) | |
ENTRY(EV_TLBProtV) | |
SAVE_ALL_SYS | |
SAVE_EXCEPTION_SOURCE | |
mov %r1, %sp | |
j do_tlb_prot_violation | |
ENDPROC(EV_TLBProtV) | |
ENTRY(EV_PrivilegeV) | |
SAVE_ALL_SYS | |
mov %r0, %sp | |
j do_privilege_violation | |
ENDPROC(EV_PrivilegeV) | |
ENTRY(EV_Trap) | |
SAVE_ALL_SYS | |
mov %r0, %sp | |
j do_trap | |
ENDPROC(EV_Trap) | |
ENTRY(EV_Extension) | |
SAVE_ALL_SYS | |
mov %r0, %sp | |
j do_extension | |
ENDPROC(EV_Extension) | |
#ifdef CONFIG_ISA_ARCV2 | |
ENTRY(EV_SWI) | |
SAVE_ALL_SYS | |
mov %r0, %sp | |
j do_swi | |
ENDPROC(EV_SWI) | |
ENTRY(EV_DivZero) | |
SAVE_ALL_SYS | |
SAVE_EXCEPTION_SOURCE | |
mov %r1, %sp | |
j do_divzero | |
ENDPROC(EV_DivZero) | |
ENTRY(EV_DCError) | |
SAVE_ALL_SYS | |
mov %r0, %sp | |
j do_dcerror | |
ENDPROC(EV_DCError) | |
ENTRY(EV_Maligned) | |
SAVE_ALL_SYS | |
SAVE_EXCEPTION_SOURCE | |
mov %r1, %sp | |
j do_maligned | |
ENDPROC(EV_Maligned) | |
#endif |