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