mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-07 23:11:27 +00:00
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:
parent
e4dccf9092
commit
8a23fdec3d
3 changed files with 122 additions and 193 deletions
|
@ -37,6 +37,8 @@
|
||||||
#include <asm/export.h>
|
#include <asm/export.h>
|
||||||
#include <asm/feature-fixups.h>
|
#include <asm/feature-fixups.h>
|
||||||
|
|
||||||
|
#include "head_32.h"
|
||||||
|
|
||||||
/* 601 only have IBAT; cr0.eq is set on 601 when using this macro */
|
/* 601 only have IBAT; cr0.eq is set on 601 when using this macro */
|
||||||
#define LOAD_BAT(n, reg, RA, RB) \
|
#define LOAD_BAT(n, reg, RA, RB) \
|
||||||
/* see the comment for clear_bats() -- Cort */ \
|
/* see the comment for clear_bats() -- Cort */ \
|
||||||
|
@ -246,103 +248,6 @@ __secondary_hold_spinloop:
|
||||||
__secondary_hold_acknowledge:
|
__secondary_hold_acknowledge:
|
||||||
.long -1
|
.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 */
|
/* System reset */
|
||||||
/* core99 pmac starts the seconary here by changing the vector, and
|
/* core99 pmac starts the seconary here by changing the vector, and
|
||||||
putting it back to what it was (unknown_exception) when done. */
|
putting it back to what it was (unknown_exception) when done. */
|
||||||
|
|
118
arch/powerpc/kernel/head_32.h
Normal file
118
arch/powerpc/kernel/head_32.h
Normal file
|
@ -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/export.h>
|
||||||
#include <asm/code-patching-asm.h>
|
#include <asm/code-patching-asm.h>
|
||||||
|
|
||||||
|
#include "head_32.h"
|
||||||
|
|
||||||
#if CONFIG_TASK_SIZE <= 0x80000000 && CONFIG_PAGE_OFFSET >= 0x80000000
|
#if CONFIG_TASK_SIZE <= 0x80000000 && CONFIG_PAGE_OFFSET >= 0x80000000
|
||||||
/* By simply checking Address >= 0x80000000, we know if its a kernel address */
|
/* By simply checking Address >= 0x80000000, we know if its a kernel address */
|
||||||
#define SIMPLE_KERNEL_ADDRESS 1
|
#define SIMPLE_KERNEL_ADDRESS 1
|
||||||
|
@ -123,102 +125,6 @@ instruction_counter:
|
||||||
.space 4
|
.space 4
|
||||||
#endif
|
#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 */
|
/* System reset */
|
||||||
EXCEPTION(0x100, Reset, system_reset_exception, EXC_XFER_STD)
|
EXCEPTION(0x100, Reset, system_reset_exception, EXC_XFER_STD)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue