/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (c) 2011, 2017 embedded brains GmbH. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <bspopts.h>
#include <rtems/score/percpu.h>
#include <bsp/vectors.h>
#define SCRATCH_REGISTER_0 r3
#define SCRATCH_REGISTER_1 r4
.global ppc_exc_fatal_normal
.global ppc_exc_fatal_critical
.global ppc_exc_fatal_machine_check
.global ppc_exc_fatal_debug
ppc_exc_fatal_critical:
PPC_REG_STORE SCRATCH_REGISTER_1, GPR4_OFFSET(r1)
mfcsrr0 SCRATCH_REGISTER_1
PPC_REG_STORE SCRATCH_REGISTER_1, SRR0_FRAME_OFFSET(r1)
mfcsrr1 SCRATCH_REGISTER_1
PPC_REG_STORE SCRATCH_REGISTER_1, SRR1_FRAME_OFFSET(r1)
b .Lppc_exc_fatal
ppc_exc_fatal_machine_check:
PPC_REG_STORE SCRATCH_REGISTER_1, GPR4_OFFSET(r1)
mfmcsrr0 SCRATCH_REGISTER_1
PPC_REG_STORE SCRATCH_REGISTER_1, SRR0_FRAME_OFFSET(r1)
mfmcsrr1 SCRATCH_REGISTER_1
PPC_REG_STORE SCRATCH_REGISTER_1, SRR1_FRAME_OFFSET(r1)
b .Lppc_exc_fatal
ppc_exc_fatal_debug:
PPC_REG_STORE SCRATCH_REGISTER_1, GPR4_OFFSET(r1)
mfspr SCRATCH_REGISTER_1, BOOKE_DSRR0
PPC_REG_STORE SCRATCH_REGISTER_1, SRR0_FRAME_OFFSET(r1)
mfspr SCRATCH_REGISTER_1, BOOKE_DSRR1
PPC_REG_STORE SCRATCH_REGISTER_1, SRR1_FRAME_OFFSET(r1)
b .Lppc_exc_fatal
ppc_exc_fatal_normal:
PPC_REG_STORE SCRATCH_REGISTER_1, GPR4_OFFSET(r1)
mfsrr0 SCRATCH_REGISTER_1
PPC_REG_STORE SCRATCH_REGISTER_1, SRR0_FRAME_OFFSET(r1)
mfsrr1 SCRATCH_REGISTER_1
PPC_REG_STORE SCRATCH_REGISTER_1, SRR1_FRAME_OFFSET(r1)
.Lppc_exc_fatal:
stw r3, EXCEPTION_NUMBER_OFFSET(r1)
mfcr SCRATCH_REGISTER_1
stw SCRATCH_REGISTER_1, EXC_CR_OFFSET(r1)
mfxer SCRATCH_REGISTER_1
stw SCRATCH_REGISTER_1, EXC_XER_OFFSET(r1)
mfctr SCRATCH_REGISTER_1
PPC_REG_STORE SCRATCH_REGISTER_1, EXC_CTR_OFFSET(r1)
mflr SCRATCH_REGISTER_1
PPC_REG_STORE SCRATCH_REGISTER_1, EXC_LR_OFFSET(r1)
PPC_REG_STORE r0, GPR0_OFFSET(r1)
PPC_REG_STORE r1, GPR1_OFFSET(r1)
PPC_REG_STORE r2, GPR2_OFFSET(r1)
PPC_REG_STORE r5, GPR5_OFFSET(r1)
PPC_REG_STORE r6, GPR6_OFFSET(r1)
PPC_REG_STORE r7, GPR7_OFFSET(r1)
PPC_REG_STORE r8, GPR8_OFFSET(r1)
PPC_REG_STORE r9, GPR9_OFFSET(r1)
PPC_REG_STORE r10, GPR10_OFFSET(r1)
PPC_REG_STORE r11, GPR11_OFFSET(r1)
PPC_REG_STORE r12, GPR12_OFFSET(r1)
PPC_REG_STORE r13, GPR13_OFFSET(r1)
PPC_REG_STORE r14, GPR14_OFFSET(r1)
PPC_REG_STORE r15, GPR15_OFFSET(r1)
PPC_REG_STORE r16, GPR16_OFFSET(r1)
PPC_REG_STORE r17, GPR17_OFFSET(r1)
PPC_REG_STORE r18, GPR18_OFFSET(r1)
PPC_REG_STORE r19, GPR19_OFFSET(r1)
PPC_REG_STORE r20, GPR20_OFFSET(r1)
PPC_REG_STORE r21, GPR21_OFFSET(r1)
PPC_REG_STORE r22, GPR22_OFFSET(r1)
PPC_REG_STORE r23, GPR23_OFFSET(r1)
PPC_REG_STORE r24, GPR24_OFFSET(r1)
PPC_REG_STORE r25, GPR25_OFFSET(r1)
PPC_REG_STORE r26, GPR26_OFFSET(r1)
PPC_REG_STORE r27, GPR27_OFFSET(r1)
PPC_REG_STORE r28, GPR28_OFFSET(r1)
PPC_REG_STORE r29, GPR29_OFFSET(r1)
PPC_REG_STORE r30, GPR30_OFFSET(r1)
PPC_REG_STORE r31, GPR31_OFFSET(r1)
/* Enable FPU and/or AltiVec */
#if defined(PPC_MULTILIB_FPU) || defined(PPC_MULTILIB_ALTIVEC)
mfmsr SCRATCH_REGISTER_1
#ifdef PPC_MULTILIB_FPU
ori SCRATCH_REGISTER_1, SCRATCH_REGISTER_1, MSR_FP
#endif
#ifdef PPC_MULTILIB_ALTIVEC
oris SCRATCH_REGISTER_1, SCRATCH_REGISTER_1, MSR_VE >> 16
#endif
mtmsr SCRATCH_REGISTER_1
isync
#endif
#ifdef PPC_MULTILIB_ALTIVEC
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(0)
stvx v0, r1, SCRATCH_REGISTER_1
mfvscr v0
li SCRATCH_REGISTER_1, PPC_EXC_VSCR_OFFSET
stvewx v0, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(1)
stvx v1, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(2)
stvx v2, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(3)
stvx v3, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(4)
stvx v4, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(5)
stvx v5, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(6)
stvx v6, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(7)
stvx v7, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(8)
stvx v8, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(9)
stvx v9, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(10)
stvx v10, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(11)
stvx v11, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(12)
stvx v12, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(13)
stvx v13, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(14)
stvx v14, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(15)
stvx v15, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(16)
stvx v16, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(17)
stvx v17, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(18)
stvx v18, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(19)
stvx v19, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(20)
stvx v20, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(21)
stvx v21, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(22)
stvx v22, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(23)
stvx v23, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(24)
stvx v24, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(25)
stvx v25, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(26)
stvx v26, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(27)
stvx v27, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(28)
stvx v28, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(29)
stvx v29, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(30)
stvx v30, r1, SCRATCH_REGISTER_1
li SCRATCH_REGISTER_1, PPC_EXC_VR_OFFSET(31)
stvx v31, r1, SCRATCH_REGISTER_1
mfvrsave SCRATCH_REGISTER_1
stw SCRATCH_REGISTER_1, PPC_EXC_VRSAVE_OFFSET(r1)
#endif
#ifdef PPC_MULTILIB_FPU
stfd f0, PPC_EXC_FR_OFFSET(0)(r1)
mffs f0
stfd f0, PPC_EXC_FPSCR_OFFSET(r1)
stfd f1, PPC_EXC_FR_OFFSET(1)(r1)
stfd f2, PPC_EXC_FR_OFFSET(2)(r1)
stfd f3, PPC_EXC_FR_OFFSET(3)(r1)
stfd f4, PPC_EXC_FR_OFFSET(4)(r1)
stfd f5, PPC_EXC_FR_OFFSET(5)(r1)
stfd f6, PPC_EXC_FR_OFFSET(6)(r1)
stfd f7, PPC_EXC_FR_OFFSET(7)(r1)
stfd f8, PPC_EXC_FR_OFFSET(8)(r1)
stfd f9, PPC_EXC_FR_OFFSET(9)(r1)
stfd f10, PPC_EXC_FR_OFFSET(10)(r1)
stfd f11, PPC_EXC_FR_OFFSET(11)(r1)
stfd f12, PPC_EXC_FR_OFFSET(12)(r1)
stfd f13, PPC_EXC_FR_OFFSET(13)(r1)
stfd f14, PPC_EXC_FR_OFFSET(14)(r1)
stfd f15, PPC_EXC_FR_OFFSET(15)(r1)
stfd f16, PPC_EXC_FR_OFFSET(16)(r1)
stfd f17, PPC_EXC_FR_OFFSET(17)(r1)
stfd f18, PPC_EXC_FR_OFFSET(18)(r1)
stfd f19, PPC_EXC_FR_OFFSET(19)(r1)
stfd f20, PPC_EXC_FR_OFFSET(20)(r1)
stfd f21, PPC_EXC_FR_OFFSET(21)(r1)
stfd f22, PPC_EXC_FR_OFFSET(22)(r1)
stfd f23, PPC_EXC_FR_OFFSET(23)(r1)
stfd f24, PPC_EXC_FR_OFFSET(24)(r1)
stfd f25, PPC_EXC_FR_OFFSET(25)(r1)
stfd f26, PPC_EXC_FR_OFFSET(26)(r1)
stfd f27, PPC_EXC_FR_OFFSET(27)(r1)
stfd f28, PPC_EXC_FR_OFFSET(28)(r1)
stfd f29, PPC_EXC_FR_OFFSET(29)(r1)
stfd f30, PPC_EXC_FR_OFFSET(30)(r1)
stfd f31, PPC_EXC_FR_OFFSET(31)(r1)
#endif
li r3, 9
addi r4, r1, FRAME_LINK_SPACE
b _Terminate
PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE