Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 2486
b: refs/heads/master
c: 1492ec8
h: refs/heads/master
v: v3
  • Loading branch information
Kumar Gala authored and Linus Torvalds committed Jun 22, 2005
1 parent ec3d6f7 commit fb61295
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 172 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5be061eee931db2718feecaf10df17610386202b
refs/heads/master: 1492ec8069ea6f82bc32df27cabbec72e554e2b8
164 changes: 63 additions & 101 deletions trunk/arch/ppc/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -46,26 +46,23 @@

#ifdef CONFIG_BOOKE
#include "head_booke.h"
#define TRANSFER_TO_HANDLER_EXC_LEVEL(exc_level) \
mtspr exc_level##_SPRG,r8; \
BOOKE_LOAD_EXC_LEVEL_STACK(exc_level); \
lwz r0,GPR10-INT_FRAME_SIZE(r8); \
stw r0,GPR10(r11); \
lwz r0,GPR11-INT_FRAME_SIZE(r8); \
stw r0,GPR11(r11); \
mfspr r8,exc_level##_SPRG

.globl mcheck_transfer_to_handler
mcheck_transfer_to_handler:
mtspr MCHECK_SPRG,r8
BOOKE_LOAD_MCHECK_STACK
lwz r0,GPR10-INT_FRAME_SIZE(r8)
stw r0,GPR10(r11)
lwz r0,GPR11-INT_FRAME_SIZE(r8)
stw r0,GPR11(r11)
mfspr r8,MCHECK_SPRG
TRANSFER_TO_HANDLER_EXC_LEVEL(MCHECK)
b transfer_to_handler_full

.globl crit_transfer_to_handler
crit_transfer_to_handler:
mtspr CRIT_SPRG,r8
BOOKE_LOAD_CRIT_STACK
lwz r0,GPR10-INT_FRAME_SIZE(r8)
stw r0,GPR10(r11)
lwz r0,GPR11-INT_FRAME_SIZE(r8)
stw r0,GPR11(r11)
mfspr r8,CRIT_SPRG
TRANSFER_TO_HANDLER_EXC_LEVEL(CRIT)
/* fall through */
#endif

Expand Down Expand Up @@ -783,99 +780,64 @@ exc_exit_restart_end:
* time of the critical interrupt.
*
*/
.globl ret_from_crit_exc
ret_from_crit_exc:
REST_NVGPRS(r1)
lwz r3,_MSR(r1)
andi. r3,r3,MSR_PR
LOAD_MSR_KERNEL(r10,MSR_KERNEL)
bne user_exc_return

lwz r0,GPR0(r1)
lwz r2,GPR2(r1)
REST_4GPRS(3, r1)
REST_2GPRS(7, r1)

lwz r10,_XER(r1)
lwz r11,_CTR(r1)
mtspr SPRN_XER,r10
mtctr r11

PPC405_ERR77(0,r1)
stwcx. r0,0,r1 /* to clear the reservation */

lwz r11,_LINK(r1)
mtlr r11
lwz r10,_CCR(r1)
mtcrf 0xff,r10
#ifdef CONFIG_40x
/* avoid any possible TLB misses here by turning off MSR.DR, we
* assume the instructions here are mapped by a pinned TLB entry */
li r10,MSR_IR
mtmsr r10
isync
tophys(r1, r1)
#define PPC_40x_TURN_OFF_MSR_DR \
/* avoid any possible TLB misses here by turning off MSR.DR, we \
* assume the instructions here are mapped by a pinned TLB entry */ \
li r10,MSR_IR; \
mtmsr r10; \
isync; \
tophys(r1, r1);
#else
#define PPC_40x_TURN_OFF_MSR_DR
#endif
lwz r9,_DEAR(r1)
lwz r10,_ESR(r1)
mtspr SPRN_DEAR,r9
mtspr SPRN_ESR,r10
lwz r11,_NIP(r1)
lwz r12,_MSR(r1)
mtspr SPRN_CSRR0,r11
mtspr SPRN_CSRR1,r12
lwz r9,GPR9(r1)
lwz r12,GPR12(r1)
lwz r10,GPR10(r1)
lwz r11,GPR11(r1)
lwz r1,GPR1(r1)
PPC405_ERR77_SYNC
rfci
b . /* prevent prefetch past rfci */

#define RET_FROM_EXC_LEVEL(exc_lvl_srr0, exc_lvl_srr1, exc_lvl_rfi) \
REST_NVGPRS(r1); \
lwz r3,_MSR(r1); \
andi. r3,r3,MSR_PR; \
LOAD_MSR_KERNEL(r10,MSR_KERNEL); \
bne user_exc_return; \
lwz r0,GPR0(r1); \
lwz r2,GPR2(r1); \
REST_4GPRS(3, r1); \
REST_2GPRS(7, r1); \
lwz r10,_XER(r1); \
lwz r11,_CTR(r1); \
mtspr SPRN_XER,r10; \
mtctr r11; \
PPC405_ERR77(0,r1); \
stwcx. r0,0,r1; /* to clear the reservation */ \
lwz r11,_LINK(r1); \
mtlr r11; \
lwz r10,_CCR(r1); \
mtcrf 0xff,r10; \
PPC_40x_TURN_OFF_MSR_DR; \
lwz r9,_DEAR(r1); \
lwz r10,_ESR(r1); \
mtspr SPRN_DEAR,r9; \
mtspr SPRN_ESR,r10; \
lwz r11,_NIP(r1); \
lwz r12,_MSR(r1); \
mtspr exc_lvl_srr0,r11; \
mtspr exc_lvl_srr1,r12; \
lwz r9,GPR9(r1); \
lwz r12,GPR12(r1); \
lwz r10,GPR10(r1); \
lwz r11,GPR11(r1); \
lwz r1,GPR1(r1); \
PPC405_ERR77_SYNC; \
exc_lvl_rfi; \
b .; /* prevent prefetch past exc_lvl_rfi */

.globl ret_from_crit_exc
ret_from_crit_exc:
RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI)

#ifdef CONFIG_BOOKE
/*
* Return from a machine check interrupt, similar to a critical
* interrupt.
*/
.globl ret_from_mcheck_exc
ret_from_mcheck_exc:
REST_NVGPRS(r1)
lwz r3,_MSR(r1)
andi. r3,r3,MSR_PR
LOAD_MSR_KERNEL(r10,MSR_KERNEL)
bne user_exc_return

lwz r0,GPR0(r1)
lwz r2,GPR2(r1)
REST_4GPRS(3, r1)
REST_2GPRS(7, r1)

lwz r10,_XER(r1)
lwz r11,_CTR(r1)
mtspr SPRN_XER,r10
mtctr r11

stwcx. r0,0,r1 /* to clear the reservation */

lwz r11,_LINK(r1)
mtlr r11
lwz r10,_CCR(r1)
mtcrf 0xff,r10
lwz r9,_DEAR(r1)
lwz r10,_ESR(r1)
mtspr SPRN_DEAR,r9
mtspr SPRN_ESR,r10
lwz r11,_NIP(r1)
lwz r12,_MSR(r1)
mtspr SPRN_MCSRR0,r11
mtspr SPRN_MCSRR1,r12
lwz r9,GPR9(r1)
lwz r12,GPR12(r1)
lwz r10,GPR10(r1)
lwz r11,GPR11(r1)
lwz r1,GPR1(r1)
RFMCI
RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, RFMCI)
#endif /* CONFIG_BOOKE */

/*
Expand Down
94 changes: 24 additions & 70 deletions trunk/arch/ppc/kernel/head_booke.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,46 +67,36 @@
#define CRIT_STACK_TOP (exception_stack_top)

#ifdef CONFIG_SMP
#define BOOKE_LOAD_CRIT_STACK \
#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
mfspr r8,SPRN_PIR; \
mulli r8,r8,BOOKE_EXCEPTION_STACK_SIZE; \
neg r8,r8; \
addis r8,r8,CRIT_STACK_TOP@ha; \
addi r8,r8,CRIT_STACK_TOP@l
#define BOOKE_LOAD_MCHECK_STACK \
mfspr r8,SPRN_PIR; \
mulli r8,r8,BOOKE_EXCEPTION_STACK_SIZE; \
neg r8,r8; \
addis r8,r8,MCHECK_STACK_TOP@ha; \
addi r8,r8,MCHECK_STACK_TOP@l
addis r8,r8,level##_STACK_TOP@ha; \
addi r8,r8,level##_STACK_TOP@l
#else
#define BOOKE_LOAD_CRIT_STACK \
lis r8,CRIT_STACK_TOP@h; \
ori r8,r8,CRIT_STACK_TOP@l
#define BOOKE_LOAD_MCHECK_STACK \
lis r8,MCHECK_STACK_TOP@h; \
ori r8,r8,MCHECK_STACK_TOP@l
#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
lis r8,level##_STACK_TOP@h; \
ori r8,r8,level##_STACK_TOP@l
#endif

/*
* Exception prolog for critical exceptions. This is a little different
* from the normal exception prolog above since a critical exception
* can potentially occur at any point during normal exception processing.
* Thus we cannot use the same SPRG registers as the normal prolog above.
* Instead we use a portion of the critical exception stack at low physical
* addresses.
* Exception prolog for critical/machine check exceptions. This is a
* little different from the normal exception prolog above since a
* critical/machine check exception can potentially occur at any point
* during normal exception processing. Thus we cannot use the same SPRG
* registers as the normal prolog above. Instead we use a portion of the
* critical/machine check exception stack at low physical addresses.
*/

#define CRITICAL_EXCEPTION_PROLOG \
mtspr CRIT_SPRG,r8; \
BOOKE_LOAD_CRIT_STACK; /* r8 points to the crit stack */ \
#define EXC_LEVEL_EXCEPTION_PROLOG(exc_level, exc_level_srr0, exc_level_srr1) \
mtspr exc_level##_SPRG,r8; \
BOOKE_LOAD_EXC_LEVEL_STACK(exc_level);/* r8 points to the exc_level stack*/ \
stw r10,GPR10-INT_FRAME_SIZE(r8); \
stw r11,GPR11-INT_FRAME_SIZE(r8); \
mfcr r10; /* save CR in r10 for now */\
mfspr r11,SPRN_CSRR1; /* check whether user or kernel */\
mfspr r11,exc_level_srr1; /* check whether user or kernel */\
andi. r11,r11,MSR_PR; \
mr r11,r8; \
mfspr r8,CRIT_SPRG; \
mfspr r8,exc_level##_SPRG; \
beq 1f; \
/* COMING FROM USER MODE */ \
mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\
Expand All @@ -122,55 +112,20 @@
stw r12,_DEAR(r11); /* since they may have had stuff */\
mfspr r9,SPRN_ESR; /* in them at the point where the */\
stw r9,_ESR(r11); /* exception was taken */\
mfspr r12,SPRN_CSRR0; \
mfspr r12,exc_level_srr0; \
stw r1,GPR1(r11); \
mfspr r9,SPRN_CSRR1; \
mfspr r9,exc_level_srr1; \
stw r1,0(r11); \
mr r1,r11; \
rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
stw r0,GPR0(r11); \
SAVE_4GPRS(3, r11); \
SAVE_2GPRS(7, r11)

/*
* Exception prolog for machine check exceptions. This is similar to
* the critical exception prolog, except that machine check exceptions
* have their stack.
*/
#define MCHECK_EXCEPTION_PROLOG \
mtspr MCHECK_SPRG,r8; \
BOOKE_LOAD_MCHECK_STACK; /* r8 points to the mcheck stack */\
stw r10,GPR10-INT_FRAME_SIZE(r8); \
stw r11,GPR11-INT_FRAME_SIZE(r8); \
mfcr r10; /* save CR in r10 for now */\
mfspr r11,SPRN_MCSRR1; /* check whether user or kernel */\
andi. r11,r11,MSR_PR; \
mr r11,r8; \
mfspr r8,MCHECK_SPRG; \
beq 1f; \
/* COMING FROM USER MODE */ \
mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\
lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
addi r11,r11,THREAD_SIZE; \
1: subi r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame */\
stw r10,_CCR(r11); /* save various registers */\
stw r12,GPR12(r11); \
stw r9,GPR9(r11); \
mflr r10; \
stw r10,_LINK(r11); \
mfspr r12,SPRN_DEAR; /* save DEAR and ESR in the frame */\
stw r12,_DEAR(r11); /* since they may have had stuff */\
mfspr r9,SPRN_ESR; /* in them at the point where the */\
stw r9,_ESR(r11); /* exception was taken */\
mfspr r12,SPRN_MCSRR0; \
stw r1,GPR1(r11); \
mfspr r9,SPRN_MCSRR1; \
stw r1,0(r11); \
mr r1,r11; \
rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
stw r0,GPR0(r11); \
SAVE_4GPRS(3, r11); \
SAVE_2GPRS(7, r11)
#define CRITICAL_EXCEPTION_PROLOG \
EXC_LEVEL_EXCEPTION_PROLOG(CRIT, SPRN_CSRR0, SPRN_CSRR1)
#define MCHECK_EXCEPTION_PROLOG \
EXC_LEVEL_EXCEPTION_PROLOG(MCHECK, SPRN_MCSRR0, SPRN_MCSRR1)

/*
* Exception vectors.
Expand Down Expand Up @@ -237,7 +192,6 @@
EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, COPY_EE, transfer_to_handler, \
ret_from_except)


/* Check for a single step debug exception while in an exception
* handler before state has been saved. This is to catch the case
* where an instruction that we are trying to single step causes
Expand Down Expand Up @@ -291,7 +245,7 @@
lwz r9,GPR9(r11); \
lwz r12,GPR12(r11); \
mtspr CRIT_SPRG,r8; \
BOOKE_LOAD_CRIT_STACK; /* r8 points to the crit stack */ \
BOOKE_LOAD_EXC_LEVEL_STACK(CRIT); /* r8 points to the debug stack */ \
lwz r10,GPR10-INT_FRAME_SIZE(r8); \
lwz r11,GPR11-INT_FRAME_SIZE(r8); \
mfspr r8,CRIT_SPRG; \
Expand Down

0 comments on commit fb61295

Please sign in to comment.