1/* 2 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29#include <ppc/asm.h> 30#include <ppc/proc_reg.h> 31#include <assym.s> 32 33/* 34This code is linked into the kernel but part of the "__HIB" section, which means 35its used by code running in the special context of restoring the kernel text and data 36from the hibernation image read by the booter. hibernate_kernel_entrypoint() and everything 37it calls or references (ie. hibernate_restore_phys_page()) 38needs to be careful to only touch memory also in the "__HIB" section. 39*/ 40 41/* 42void 43hibernate_restore_phys_page(uint64_t src, uint64_t dst, uint32_t len, uint32_t procFlags); 44*/ 45 46 .align 5 47 .globl EXT(hibernate_restore_phys_page) 48 .globl EXT(hibernate_machine_entrypoint) 49 50LEXT(hibernate_restore_phys_page) 51 52 andi. r0, r8, pf64Bit 53 bne hibernate_restore_phys_page64 54 55 srwi r10,r7,5 ; r10 <- 32-byte chunks to xfer 56 mtctr r10 57 cmpwi r4, 0 58 beq hibernate_restore_phys_pageFlush 59 60hibernate_restore_phys_pageCopy: 61 lwz r0,0(r4) 62 lwz r2,4(r4) 63 lwz r7,8(r4) 64 lwz r8,12(r4) 65 lwz r9,16(r4) 66 lwz r10,20(r4) 67 lwz r11,24(r4) 68 lwz r12,28(r4) 69 70 dcbz 0,r6 ; avoid prefetch of next cache line 71 stw r0,0(r6) 72 stw r2,4(r6) 73 stw r7,8(r6) 74 stw r8,12(r6) 75 stw r9,16(r6) 76 stw r10,20(r6) 77 stw r11,24(r6) 78 stw r12,28(r6) 79 80 dcbf 0, r6 81 sync 82 icbi 0, r6 83 isync 84 sync 85 86 addi r4,r4,32 87 addi r6,r6,32 88 89 bdnz hibernate_restore_phys_pageCopy ; loop if more chunks 90 blr 91 92hibernate_restore_phys_pageFlush: 93 dcbf 0, r6 94 sync 95 icbi 0, r6 96 isync 97 sync 98 99 addi r6,r6,32 100 bdnz hibernate_restore_phys_pageFlush ; loop if more chunks 101 blr 102 103 104hibernate_restore_phys_page64: 105 rlwinm r3,r3,0,1,0 ; Duplicate high half of long long paddr into top of reg 106 rlwimi r3,r4,0,0,31 ; Combine bottom of long long to full 64-bits 107 rlwinm r4,r5,0,1,0 ; Duplicate high half of long long paddr into top of reg 108 rlwimi r4,r6,0,0,31 ; Combine bottom of long long to full 64-bits 109 110 mfmsr r9 ; Get the MSR 111 li r0,1 ; Note - we use this in a couple places below 112 rldimi r9,r0,63,MSR_SF_BIT ; set SF on in MSR we will copy with 113 mtmsrd r9 ; turn 64-bit addressing on 114 isync ; wait for it to happen 115 116 srwi r10,r7,7 ; r10 <- 128-byte chunks to xfer 117 mtctr r10 118 cmpdi r3, 0 119 beq hibernate_restore_phys_page64Flush 120 121hibernate_restore_phys_page64Copy: 122 ld r0,0(r3) 123 ld r2,8(r3) 124 ld r7,16(r3) 125 ld r8,24(r3) 126 ld r9,32(r3) 127 ld r10,40(r3) 128 ld r11,48(r3) 129 ld r12,56(r3) 130 131 dcbz128 0,r4 ; avoid prefetch of next cache line 132 std r0,0(r4) 133 std r2,8(r4) 134 std r7,16(r4) 135 std r8,24(r4) 136 std r9,32(r4) 137 std r10,40(r4) 138 std r11,48(r4) 139 std r12,56(r4) 140 141 ld r0,64(r3) ; load 2nd half of chunk 142 ld r2,72(r3) 143 ld r7,80(r3) 144 ld r8,88(r3) 145 ld r9,96(r3) 146 ld r10,104(r3) 147 ld r11,112(r3) 148 ld r12,120(r3) 149 150 std r0,64(r4) 151 std r2,72(r4) 152 std r7,80(r4) 153 std r8,88(r4) 154 std r9,96(r4) 155 std r10,104(r4) 156 std r11,112(r4) 157 std r12,120(r4) 158 159 dcbf 0, r4 160 sync 161 icbi 0, r4 162 isync 163 sync 164 165 addi r3,r3,128 166 addi r4,r4,128 167 168 bdnz hibernate_restore_phys_page64Copy ; loop if more chunks 169 170 171hibernate_restore_phys_page64Done: 172 mfmsr r9 ; Get the MSR we used to copy 173 rldicl r9,r9,0,MSR_SF_BIT+1 ; clear SF 174 mtmsrd r9 ; turn 64-bit mode off 175 isync ; wait for it to happen 176 blr 177 178hibernate_restore_phys_page64Flush: 179 dcbf 0, r4 180 sync 181 icbi 0, r4 182 isync 183 sync 184 185 addi r4,r4,128 186 187 bdnz hibernate_restore_phys_page64Flush ; loop if more chunks 188 b hibernate_restore_phys_page64Done 189 190LEXT(hibernate_machine_entrypoint) 191 b EXT(hibernate_kernel_entrypoint) 192 193