powerpc/32: Refactor EXCEPTION entry macros for head_8xx.S and head_32.S
EXCEPTION_PROLOG is similar in head_8xx.S and head_32.S This patch creates head_32.h and moves EXCEPTION_PROLOG macro into it. It also converts it from a GCC macro to a GAS macro in order to ease refactorisation with 40x later, since GAS macros allows the use of #ifdef/#else/#endif inside it. And it also has the advantage of not requiring the uggly "; \" at the end of each line. This patch also moves EXCEPTION() and EXC_XFER_XXXX() macros which are also similar while adding START_EXCEPTION() out of EXCEPTION(). Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
Родитель
e4dccf9092
Коммит
8a23fdec3d
|
@ -37,6 +37,8 @@
|
|||
#include <asm/export.h>
|
||||
#include <asm/feature-fixups.h>
|
||||
|
||||
#include "head_32.h"
|
||||
|
||||
/* 601 only have IBAT; cr0.eq is set on 601 when using this macro */
|
||||
#define LOAD_BAT(n, reg, RA, RB) \
|
||||
/* see the comment for clear_bats() -- Cort */ \
|
||||
|
@ -246,103 +248,6 @@ __secondary_hold_spinloop:
|
|||
__secondary_hold_acknowledge:
|
||||
.long -1
|
||||
|
||||
/*
|
||||
* Exception entry code. This code runs with address translation
|
||||
* turned off, i.e. using physical addresses.
|
||||
* We assume sprg3 has the physical address of the current
|
||||
* task's thread_struct.
|
||||
*/
|
||||
#define EXCEPTION_PROLOG \
|
||||
mtspr SPRN_SPRG_SCRATCH0,r10; \
|
||||
mtspr SPRN_SPRG_SCRATCH1,r11; \
|
||||
mfcr r10; \
|
||||
EXCEPTION_PROLOG_1; \
|
||||
EXCEPTION_PROLOG_2
|
||||
|
||||
#define EXCEPTION_PROLOG_1 \
|
||||
mfspr r11,SPRN_SRR1; /* check whether user or kernel */ \
|
||||
andi. r11,r11,MSR_PR; \
|
||||
tophys(r11,r1); /* use tophys(r1) if kernel */ \
|
||||
beq 1f; \
|
||||
mfspr r11,SPRN_SPRG_THREAD; \
|
||||
lwz r11,TASK_STACK-THREAD(r11); \
|
||||
addi r11,r11,THREAD_SIZE; \
|
||||
tophys(r11,r11); \
|
||||
1: subi r11,r11,INT_FRAME_SIZE /* alloc exc. frame */
|
||||
|
||||
|
||||
#define EXCEPTION_PROLOG_2 \
|
||||
stw r10,_CCR(r11); /* save registers */ \
|
||||
stw r12,GPR12(r11); \
|
||||
stw r9,GPR9(r11); \
|
||||
mfspr r10,SPRN_SPRG_SCRATCH0; \
|
||||
stw r10,GPR10(r11); \
|
||||
mfspr r12,SPRN_SPRG_SCRATCH1; \
|
||||
stw r12,GPR11(r11); \
|
||||
mflr r10; \
|
||||
stw r10,_LINK(r11); \
|
||||
mfspr r12,SPRN_SRR0; \
|
||||
mfspr r9,SPRN_SRR1; \
|
||||
stw r1,GPR1(r11); \
|
||||
stw r1,0(r11); \
|
||||
tovirt(r1,r11); /* set new kernel sp */ \
|
||||
li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR); /* can take exceptions */ \
|
||||
MTMSRD(r10); /* (except for mach check in rtas) */ \
|
||||
stw r0,GPR0(r11); \
|
||||
lis r10,STACK_FRAME_REGS_MARKER@ha; /* exception frame marker */ \
|
||||
addi r10,r10,STACK_FRAME_REGS_MARKER@l; \
|
||||
stw r10,8(r11); \
|
||||
SAVE_4GPRS(3, r11); \
|
||||
SAVE_2GPRS(7, r11)
|
||||
|
||||
/*
|
||||
* Note: code which follows this uses cr0.eq (set if from kernel),
|
||||
* r11, r12 (SRR0), and r9 (SRR1).
|
||||
*
|
||||
* Note2: once we have set r1 we are in a position to take exceptions
|
||||
* again, and we could thus set MSR:RI at that point.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Exception vectors.
|
||||
*/
|
||||
#define EXCEPTION(n, label, hdlr, xfer) \
|
||||
. = n; \
|
||||
DO_KVM n; \
|
||||
label: \
|
||||
EXCEPTION_PROLOG; \
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD; \
|
||||
xfer(n, hdlr)
|
||||
|
||||
#define EXC_XFER_TEMPLATE(n, hdlr, trap, copyee, tfer, ret) \
|
||||
li r10,trap; \
|
||||
stw r10,_TRAP(r11); \
|
||||
li r10,MSR_KERNEL; \
|
||||
copyee(r10, r9); \
|
||||
bl tfer; \
|
||||
i##n: \
|
||||
.long hdlr; \
|
||||
.long ret
|
||||
|
||||
#define COPY_EE(d, s) rlwimi d,s,0,16,16
|
||||
#define NOCOPY(d, s)
|
||||
|
||||
#define EXC_XFER_STD(n, hdlr) \
|
||||
EXC_XFER_TEMPLATE(n, hdlr, n, NOCOPY, transfer_to_handler_full, \
|
||||
ret_from_except_full)
|
||||
|
||||
#define EXC_XFER_LITE(n, hdlr) \
|
||||
EXC_XFER_TEMPLATE(n, hdlr, n+1, NOCOPY, transfer_to_handler, \
|
||||
ret_from_except)
|
||||
|
||||
#define EXC_XFER_EE(n, hdlr) \
|
||||
EXC_XFER_TEMPLATE(n, hdlr, n, COPY_EE, transfer_to_handler_full, \
|
||||
ret_from_except_full)
|
||||
|
||||
#define EXC_XFER_EE_LITE(n, hdlr) \
|
||||
EXC_XFER_TEMPLATE(n, hdlr, n+1, COPY_EE, transfer_to_handler, \
|
||||
ret_from_except)
|
||||
|
||||
/* System reset */
|
||||
/* core99 pmac starts the seconary here by changing the vector, and
|
||||
putting it back to what it was (unknown_exception) when done. */
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __HEAD_32_H__
|
||||
#define __HEAD_32_H__
|
||||
|
||||
#include <asm/ptrace.h> /* for STACK_FRAME_REGS_MARKER */
|
||||
|
||||
/*
|
||||
* Exception entry code. This code runs with address translation
|
||||
* turned off, i.e. using physical addresses.
|
||||
* We assume sprg3 has the physical address of the current
|
||||
* task's thread_struct.
|
||||
*/
|
||||
|
||||
.macro EXCEPTION_PROLOG
|
||||
mtspr SPRN_SPRG_SCRATCH0,r10
|
||||
mtspr SPRN_SPRG_SCRATCH1,r11
|
||||
mfcr r10
|
||||
EXCEPTION_PROLOG_1
|
||||
EXCEPTION_PROLOG_2
|
||||
.endm
|
||||
|
||||
.macro EXCEPTION_PROLOG_1
|
||||
mfspr r11,SPRN_SRR1 /* check whether user or kernel */
|
||||
andi. r11,r11,MSR_PR
|
||||
tophys(r11,r1) /* use tophys(r1) if kernel */
|
||||
beq 1f
|
||||
mfspr r11,SPRN_SPRG_THREAD
|
||||
lwz r11,TASK_STACK-THREAD(r11)
|
||||
addi r11,r11,THREAD_SIZE
|
||||
tophys(r11,r11)
|
||||
1: subi r11,r11,INT_FRAME_SIZE /* alloc exc. frame */
|
||||
.endm
|
||||
|
||||
.macro EXCEPTION_PROLOG_2
|
||||
stw r10,_CCR(r11) /* save registers */
|
||||
stw r12,GPR12(r11)
|
||||
stw r9,GPR9(r11)
|
||||
mfspr r10,SPRN_SPRG_SCRATCH0
|
||||
stw r10,GPR10(r11)
|
||||
mfspr r12,SPRN_SPRG_SCRATCH1
|
||||
stw r12,GPR11(r11)
|
||||
mflr r10
|
||||
stw r10,_LINK(r11)
|
||||
mfspr r12,SPRN_SRR0
|
||||
mfspr r9,SPRN_SRR1
|
||||
stw r1,GPR1(r11)
|
||||
stw r1,0(r11)
|
||||
tovirt(r1,r11) /* set new kernel sp */
|
||||
li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR) /* can take exceptions */
|
||||
MTMSRD(r10) /* (except for mach check in rtas) */
|
||||
stw r0,GPR0(r11)
|
||||
lis r10,STACK_FRAME_REGS_MARKER@ha /* exception frame marker */
|
||||
addi r10,r10,STACK_FRAME_REGS_MARKER@l
|
||||
stw r10,8(r11)
|
||||
SAVE_4GPRS(3, r11)
|
||||
SAVE_2GPRS(7, r11)
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Note: code which follows this uses cr0.eq (set if from kernel),
|
||||
* r11, r12 (SRR0), and r9 (SRR1).
|
||||
*
|
||||
* Note2: once we have set r1 we are in a position to take exceptions
|
||||
* again, and we could thus set MSR:RI at that point.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Exception vectors.
|
||||
*/
|
||||
#ifdef CONFIG_PPC_BOOK3S
|
||||
#define START_EXCEPTION(n, label) \
|
||||
. = n; \
|
||||
DO_KVM n; \
|
||||
label:
|
||||
|
||||
#else
|
||||
#define START_EXCEPTION(n, label) \
|
||||
. = n; \
|
||||
label:
|
||||
|
||||
#endif
|
||||
|
||||
#define EXCEPTION(n, label, hdlr, xfer) \
|
||||
START_EXCEPTION(n, label) \
|
||||
EXCEPTION_PROLOG; \
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD; \
|
||||
xfer(n, hdlr)
|
||||
|
||||
#define EXC_XFER_TEMPLATE(n, hdlr, trap, copyee, tfer, ret) \
|
||||
li r10,trap; \
|
||||
stw r10,_TRAP(r11); \
|
||||
li r10,MSR_KERNEL; \
|
||||
copyee(r10, r9); \
|
||||
bl tfer; \
|
||||
i##n: \
|
||||
.long hdlr; \
|
||||
.long ret
|
||||
|
||||
#define COPY_EE(d, s) rlwimi d,s,0,MSR_EE
|
||||
#define NOCOPY(d, s)
|
||||
|
||||
#define EXC_XFER_STD(n, hdlr) \
|
||||
EXC_XFER_TEMPLATE(n, hdlr, n, NOCOPY, transfer_to_handler_full, \
|
||||
ret_from_except_full)
|
||||
|
||||
#define EXC_XFER_LITE(n, hdlr) \
|
||||
EXC_XFER_TEMPLATE(n, hdlr, n+1, NOCOPY, transfer_to_handler, \
|
||||
ret_from_except)
|
||||
|
||||
#define EXC_XFER_EE(n, hdlr) \
|
||||
EXC_XFER_TEMPLATE(n, hdlr, n, COPY_EE, transfer_to_handler_full, \
|
||||
ret_from_except_full)
|
||||
|
||||
#define EXC_XFER_EE_LITE(n, hdlr) \
|
||||
EXC_XFER_TEMPLATE(n, hdlr, n+1, COPY_EE, transfer_to_handler, \
|
||||
ret_from_except)
|
||||
|
||||
#endif /* __HEAD_32_H__ */
|
|
@ -33,6 +33,8 @@
|
|||
#include <asm/export.h>
|
||||
#include <asm/code-patching-asm.h>
|
||||
|
||||
#include "head_32.h"
|
||||
|
||||
#if CONFIG_TASK_SIZE <= 0x80000000 && CONFIG_PAGE_OFFSET >= 0x80000000
|
||||
/* By simply checking Address >= 0x80000000, we know if its a kernel address */
|
||||
#define SIMPLE_KERNEL_ADDRESS 1
|
||||
|
@ -123,102 +125,6 @@ instruction_counter:
|
|||
.space 4
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Exception entry code. This code runs with address translation
|
||||
* turned off, i.e. using physical addresses.
|
||||
* We assume sprg3 has the physical address of the current
|
||||
* task's thread_struct.
|
||||
*/
|
||||
#define EXCEPTION_PROLOG \
|
||||
mtspr SPRN_SPRG_SCRATCH0, r10; \
|
||||
mtspr SPRN_SPRG_SCRATCH1, r11; \
|
||||
mfcr r10; \
|
||||
EXCEPTION_PROLOG_1; \
|
||||
EXCEPTION_PROLOG_2
|
||||
|
||||
#define EXCEPTION_PROLOG_1 \
|
||||
mfspr r11,SPRN_SRR1; /* check whether user or kernel */ \
|
||||
andi. r11,r11,MSR_PR; \
|
||||
tophys(r11,r1); /* use tophys(r1) if kernel */ \
|
||||
beq 1f; \
|
||||
mfspr r11,SPRN_SPRG_THREAD; \
|
||||
lwz r11,TASK_STACK-THREAD(r11); \
|
||||
addi r11,r11,THREAD_SIZE; \
|
||||
tophys(r11,r11); \
|
||||
1: subi r11,r11,INT_FRAME_SIZE /* alloc exc. frame */
|
||||
|
||||
|
||||
#define EXCEPTION_PROLOG_2 \
|
||||
stw r10,_CCR(r11); /* save registers */ \
|
||||
stw r12,GPR12(r11); \
|
||||
stw r9,GPR9(r11); \
|
||||
mfspr r10,SPRN_SPRG_SCRATCH0; \
|
||||
stw r10,GPR10(r11); \
|
||||
mfspr r12,SPRN_SPRG_SCRATCH1; \
|
||||
stw r12,GPR11(r11); \
|
||||
mflr r10; \
|
||||
stw r10,_LINK(r11); \
|
||||
mfspr r12,SPRN_SRR0; \
|
||||
mfspr r9,SPRN_SRR1; \
|
||||
stw r1,GPR1(r11); \
|
||||
stw r1,0(r11); \
|
||||
tovirt(r1,r11); /* set new kernel sp */ \
|
||||
li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR); /* can take exceptions */ \
|
||||
mtmsr r10; \
|
||||
stw r0,GPR0(r11); \
|
||||
lis r10, STACK_FRAME_REGS_MARKER@ha; /* exception frame marker */ \
|
||||
addi r10, r10, STACK_FRAME_REGS_MARKER@l; \
|
||||
stw r10, 8(r11); \
|
||||
SAVE_4GPRS(3, r11); \
|
||||
SAVE_2GPRS(7, r11)
|
||||
|
||||
/*
|
||||
* Note: code which follows this uses cr0.eq (set if from kernel),
|
||||
* r11, r12 (SRR0), and r9 (SRR1).
|
||||
*
|
||||
* Note2: once we have set r1 we are in a position to take exceptions
|
||||
* again, and we could thus set MSR:RI at that point.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Exception vectors.
|
||||
*/
|
||||
#define EXCEPTION(n, label, hdlr, xfer) \
|
||||
. = n; \
|
||||
label: \
|
||||
EXCEPTION_PROLOG; \
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD; \
|
||||
xfer(n, hdlr)
|
||||
|
||||
#define EXC_XFER_TEMPLATE(n, hdlr, trap, copyee, tfer, ret) \
|
||||
li r10,trap; \
|
||||
stw r10,_TRAP(r11); \
|
||||
li r10,MSR_KERNEL; \
|
||||
copyee(r10, r9); \
|
||||
bl tfer; \
|
||||
i##n: \
|
||||
.long hdlr; \
|
||||
.long ret
|
||||
|
||||
#define COPY_EE(d, s) rlwimi d,s,0,16,16
|
||||
#define NOCOPY(d, s)
|
||||
|
||||
#define EXC_XFER_STD(n, hdlr) \
|
||||
EXC_XFER_TEMPLATE(n, hdlr, n, NOCOPY, transfer_to_handler_full, \
|
||||
ret_from_except_full)
|
||||
|
||||
#define EXC_XFER_LITE(n, hdlr) \
|
||||
EXC_XFER_TEMPLATE(n, hdlr, n+1, NOCOPY, transfer_to_handler, \
|
||||
ret_from_except)
|
||||
|
||||
#define EXC_XFER_EE(n, hdlr) \
|
||||
EXC_XFER_TEMPLATE(n, hdlr, n, COPY_EE, transfer_to_handler_full, \
|
||||
ret_from_except_full)
|
||||
|
||||
#define EXC_XFER_EE_LITE(n, hdlr) \
|
||||
EXC_XFER_TEMPLATE(n, hdlr, n+1, COPY_EE, transfer_to_handler, \
|
||||
ret_from_except)
|
||||
|
||||
/* System reset */
|
||||
EXCEPTION(0x100, Reset, system_reset_exception, EXC_XFER_STD)
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче