/* This gets called by via-pmu.c late during the sleep process. * The PMU was already send the sleep command and will shut us down * soon. We need to save all that is needed and setup the wakeup * vector that will be called by the ROM on wakeup
*/
_GLOBAL(low_sleep_handler)
#ifndef CONFIG_PPC_BOOK3S_32
blr
#else
mflr r0
lis r11,sleep_storage@ha
addi r11,r11,sleep_storage@l
stw r0,SL_LR(r11)
mfcr r0
stw r0,SL_CR(r11)
stw r1,SL_SP(r11)
stw r2,SL_R2(r11)
stmw r12,SL_R12(r11)
/* Backup various CPU config stuffs */
bl __save_cpu_setup
/* The ROM can wake us up via 2 different vectors: * - On wallstreet & lombard, we must write a magic * value 'Lars' at address 4 and a pointer to a * memory location containing the PC to resume from * at address 0. * - On Core99, we must store the wakeup vector at * address 0x80 and eventually its parameters * at address 0x84. I've have some trouble with those * parameters however and I no longer use them.
*/
lis r5,grackle_wake_up@ha
addi r5,r5,grackle_wake_up@l
tophys(r5,r5)
stw r5,SL_PC(r11)
lis r4,KERNELBASE@h
tophys(r5,r11)
addi r5,r5,SL_PC
lis r6,MAGIC@ha
addi r6,r6,MAGIC@l
stw r5,0(r4)
stw r6,4(r4) /* Setup stuffs at 0x80-0x84 for Core99 */
lis r3,core99_wake_up@ha
addi r3,r3,core99_wake_up@l
tophys(r3,r3)
stw r3,0x80(r4)
stw r5,0x84(r4)
/* Turn off data relocation. */
mfmsr r3 /* Save MSR in r7 */
rlwinm r3,r3,0,28,26 /* Turn off DR bit */
sync
mtmsr r3
isync
BEGIN_FTR_SECTION /* Flush any pending L2 data prefetches to work around HW bug */
sync
lis r3,0xfff0
lwz r0,0(r3) /* perform cache-inhibited load to ROM */
sync /* (caches are disabled at this point) */
END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
/* * Set the HID0 and MSR for sleep.
*/
mfspr r2,SPRN_HID0
rlwinm r2,r2,0,10,7 /* clear doze, nap */
oris r2,r2,HID0_SLEEP@h
sync
isync
mtspr SPRN_HID0,r2
sync
/* This loop puts us back to sleep in case we have a spurrious * wakeup so that the host bridge properly stays asleep. The * CPU will be turned off, either after a known time (about 1 * second) on wallstreet & lombard, or as soon as the CPU enters * SLEEP mode on core99
*/
mfmsr r2
oris r2,r2,MSR_POW@h
1: sync
mtmsr r2
isync
b 1b
_ASM_NOKPROBE_SYMBOL(low_cpu_offline_self) /* * Here is the resume code.
*/
/* * Core99 machines resume here * r4 has the physical address of SL_PC(sp) (unused)
*/
_GLOBAL(core99_wake_up) /* Make sure HID0 no longer contains any sleep bit and that data cache * is disabled
*/
mfspr r3,SPRN_HID0
rlwinm r3,r3,0,11,7 /* clear SLEEP, NAP, DOZE bits */
rlwinm 3,r3,0,18,15 /* clear DCE, ICE */
mtspr SPRN_HID0,r3
sync
isync
/* Pass thru to older resume code ... */
_ASM_NOKPROBE_SYMBOL(core99_wake_up) /* * Here is the resume code for older machines. * r1 has the physical address of SL_PC(sp).
*/
grackle_wake_up:
/* Restore the kernel's segment registers before * we do any r1 memory access as we are not sure they * are in a sane state above the first 256Mb region
*/
bl load_segment_registers
sync
isync
subi r1,r1,SL_PC
/* Restore various CPU config stuffs */
bl __restore_cpu_setup
/* Make sure all FPRs have been initialized */
bl reloc_offset
bl __init_fpu_registers
/* Invalidate & enable L1 cache, we don't care about * whatever the ROM may have tried to write to memory
*/
bl __inval_enable_L1
/* Restore the BATs, and SDR1. Then we can turn on the MMU. */
lwz r4,SL_SDR1(r1)
mtsdr1 r4
lwz r4,SL_SPRG0(r1)
mtsprg 0,r4
lwz r4,SL_SPRG0+4(r1)
mtsprg 1,r4
lwz r4,SL_SPRG0+8(r1)
mtsprg 2,r4
lwz r4,SL_SPRG0+12(r1)
mtsprg 3,r4
/* Restore the callee-saved registers and return */
lwz r0,SL_CR(r1)
mtcr r0
lwz r2,SL_R2(r1)
lmw r12,SL_R12(r1)
/* restore the MSR and SP and turn on the MMU and return */
lwz r3,SL_MSR(r1)
lwz r4,SL_LR(r1)
lwz r1,SL_SP(r1)
mtsrr0 r4
mtsrr1 r3
sync
isync
rfi
_ASM_NOKPROBE_SYMBOL(grackle_wake_up)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.