Message ID | 1358356884-14216-1-git-send-email-stuart.yoder@freescale.com (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
On 01/16/2013 11:21:24 AM, Stuart Yoder wrote: > From: Stuart Yoder <stuart.yoder@freescale.com> > > loop was derived from book3e_idle() > > Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com> > --- > arch/powerpc/kernel/epapr_hcalls.S | 63 > ++++++++++++++++++++++++++++++++++++ > 1 file changed, 63 insertions(+) > > diff --git a/arch/powerpc/kernel/epapr_hcalls.S > b/arch/powerpc/kernel/epapr_hcalls.S > index 62c0dc2..6a46bfb 100644 > --- a/arch/powerpc/kernel/epapr_hcalls.S > +++ b/arch/powerpc/kernel/epapr_hcalls.S > @@ -17,6 +17,68 @@ > #include <asm/asm-compat.h> > #include <asm/asm-offsets.h> > > +#ifdef CONFIG_PPC64 > +/* epapr_ev_idle() was derived from book3e_idle() */ > +_GLOBAL(epapr_ev_idle) > + /* Save LR for later */ > + mflr r0 > + std r0,16(r1) > + > + /* Hard disable interrupts */ > + wrteei 0 > + > + /* Now check if an interrupt came in while we were soft disabled > + * since we may otherwise lose it (doorbells etc...). > + */ > + lbz r3,PACAIRQHAPPENED(r13) > + cmpwi cr0,r3,0 > + bnelr > + > + /* Now we are going to mark ourselves as soft and hard enabled > in > + * order to be able to take interrupts while asleep. We inform > lockdep > + * of that. We don't actually turn interrupts on just yet tho. > + */ > +#ifdef CONFIG_TRACE_IRQFLAGS > + stdu r1,-128(r1) > + bl .trace_hardirqs_on > + addi r1,r1,128 > +#endif > + li r0,1 > + stb r0,PACASOFTIRQEN(r13) > + > + /* Interrupts will make use return to LR, so get something we > want > + * in there > + */ > + bl 1f > + > + /* And return (interrupts are on) */ > + ld r0,16(r1) > + mtlr r0 > + blr > + > +1: /* Let's set the _TLF_NAPPING flag so interrupts make us return > + * to the right spot > + */ > + CURRENT_THREAD_INFO(r11, r1) > + ld r10,TI_LOCAL_FLAGS(r11) > + ori r10,r10,_TLF_NAPPING > + std r10,TI_LOCAL_FLAGS(r11) > + > + /* We can now re-enable hard interrupts and go to sleep */ > + wrteei 1 > +idle_loop: > + LOAD_REG_IMMEDIATE(r11, EV_HCALL_TOKEN(EV_IDLE)) > + > +.global epapr_ev_idle_start > +epapr_ev_idle_start: > + li r3, -1 > + nop > + nop > + nop > + b idle_loop > + We should probably do this as an assembler macro, so we can have one instance of it that gets instantiated for both "wait" and "ev_idle". -Scott
diff --git a/arch/powerpc/kernel/epapr_hcalls.S b/arch/powerpc/kernel/epapr_hcalls.S index 62c0dc2..6a46bfb 100644 --- a/arch/powerpc/kernel/epapr_hcalls.S +++ b/arch/powerpc/kernel/epapr_hcalls.S @@ -17,6 +17,68 @@ #include <asm/asm-compat.h> #include <asm/asm-offsets.h> +#ifdef CONFIG_PPC64 +/* epapr_ev_idle() was derived from book3e_idle() */ +_GLOBAL(epapr_ev_idle) + /* Save LR for later */ + mflr r0 + std r0,16(r1) + + /* Hard disable interrupts */ + wrteei 0 + + /* Now check if an interrupt came in while we were soft disabled + * since we may otherwise lose it (doorbells etc...). + */ + lbz r3,PACAIRQHAPPENED(r13) + cmpwi cr0,r3,0 + bnelr + + /* Now we are going to mark ourselves as soft and hard enabled in + * order to be able to take interrupts while asleep. We inform lockdep + * of that. We don't actually turn interrupts on just yet tho. + */ +#ifdef CONFIG_TRACE_IRQFLAGS + stdu r1,-128(r1) + bl .trace_hardirqs_on + addi r1,r1,128 +#endif + li r0,1 + stb r0,PACASOFTIRQEN(r13) + + /* Interrupts will make use return to LR, so get something we want + * in there + */ + bl 1f + + /* And return (interrupts are on) */ + ld r0,16(r1) + mtlr r0 + blr + +1: /* Let's set the _TLF_NAPPING flag so interrupts make us return + * to the right spot + */ + CURRENT_THREAD_INFO(r11, r1) + ld r10,TI_LOCAL_FLAGS(r11) + ori r10,r10,_TLF_NAPPING + std r10,TI_LOCAL_FLAGS(r11) + + /* We can now re-enable hard interrupts and go to sleep */ + wrteei 1 +idle_loop: + LOAD_REG_IMMEDIATE(r11, EV_HCALL_TOKEN(EV_IDLE)) + +.global epapr_ev_idle_start +epapr_ev_idle_start: + li r3, -1 + nop + nop + nop + b idle_loop + +#else /* CONFIG_PPC64 */ + /* epapr_ev_idle() was derived from e500_idle() */ _GLOBAL(epapr_ev_idle) CURRENT_THREAD_INFO(r3, r1) @@ -42,6 +104,7 @@ epapr_ev_idle_start: * _TLF_NAPPING. */ b idle_loop +#endif /* Hypercall entry point. Will be patched with device tree instructions. */ .global epapr_hypercall_start