|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * @OSF_COPYRIGHT@
24: */
25:
26: #include <cpus.h>
27:
28: #include <ppc/asm.h>
29: #include <ppc/proc_reg.h>
30: #include <cpus.h>
31: #include <assym.s>
32: #include <mach_debug.h>
33: #include <mach/ppc/vm_param.h>
34:
35: /*
36: * extern void sync_cache(vm_offset_t pa, unsigned count);
37: *
38: * sync_cache takes a physical address and count to sync, thus
39: * must not be called for multiple virtual pages.
40: *
41: * it writes out the data cache and invalidates the instruction
42: * cache for the address range in question
43: */
44:
45: ENTRY(sync_cache, TAG_NO_FRAME_USED)
46:
47: /* Switch off data translations */
48: mfmsr r6
49: rlwinm r7, r6, 0, MSR_DR_BIT+1, MSR_DR_BIT-1
50: mtmsr r7
51: isync
52:
53: /* Check to see if the address is aligned. */
54: add r8, r3,r4
55: andi. r8,r8,(CACHE_LINE_SIZE-1)
56: beq- .L_sync_check
57: addi r4,r4,CACHE_LINE_SIZE
58: li r7,(CACHE_LINE_SIZE-1) /* Align buffer & count - avoid overflow problems */
59: andc r4,r4,r7
60: andc r3,r3,r7
61:
62: .L_sync_check:
63: cmpwi r4, CACHE_LINE_SIZE
64: ble .L_sync_one_line
65:
66: /* Make ctr hold count of how many times we should loop */
67: addi r8, r4, (CACHE_LINE_SIZE-1)
68: srwi r8, r8, CACHE_LINE_POW2
69: mtctr r8
70:
71: /* loop to flush the data cache */
72: .L_sync_data_loop:
73: subic r4, r4, CACHE_LINE_SIZE
74: dcbst r3, r4
75: bdnz .L_sync_data_loop
76:
77: sync
78: mtctr r8
79:
80: /* loop to invalidate the instruction cache */
81: .L_sync_inval_loop:
82: icbi r3, r4
83: addic r4, r4, CACHE_LINE_SIZE
84: bdnz .L_sync_inval_loop
85:
86: .L_sync_cache_done:
87: sync /* Finish physical writes */
88: mtmsr r6 /* Restore original translations */
89: isync /* Ensure data translations are on */
90: blr
91:
92: .L_sync_one_line:
93: dcbst 0,r3
94: sync
95: icbi 0,r3
96: b .L_sync_cache_done
97:
98: /*
99: * extern void flush_dcache(vm_offset_t addr, unsigned count, boolean phys);
100: *
101: * flush_dcache takes a virtual or physical address and count to flush
102: * and (can be called for multiple virtual pages).
103: *
104: * it flushes the data cache
105: * cache for the address range in question
106: *
107: * if 'phys' is non-zero then physical addresses will be used
108: */
109:
110: ENTRY(flush_dcache, TAG_NO_FRAME_USED)
111:
112: /* optionally switch off data translations */
113:
114: cmpwi r5, 0
115: mfmsr r6
116: beq+ 0f
117: rlwinm r7, r6, 0, MSR_DR_BIT+1, MSR_DR_BIT-1
118: mtmsr r7
119: isync
120: 0:
121:
122: /* Check to see if the address is aligned. */
123: add r8, r3,r4
124: andi. r8,r8,(CACHE_LINE_SIZE-1)
125: beq- .L_flush_dcache_check
126: addi r4,r4,CACHE_LINE_SIZE
127: li r7,(CACHE_LINE_SIZE-1) /* Align buffer & count - avoid overflow problems */
128: andc r4,r4,r7
129: andc r3,r3,r7
130:
131: .L_flush_dcache_check:
132: cmpwi r4, CACHE_LINE_SIZE
133: ble .L_flush_dcache_one_line
134:
135: /* Make ctr hold count of how many times we should loop */
136: addi r8, r4, (CACHE_LINE_SIZE-1)
137: srwi r8, r8, CACHE_LINE_POW2
138: mtctr r8
139:
140: .L_flush_dcache_flush_loop:
141: subic r4, r4, CACHE_LINE_SIZE
142: dcbf r3, r4
143: bdnz .L_flush_dcache_flush_loop
144:
145: .L_flush_dcache_done:
146: /* Sync restore msr if it was modified */
147: cmpwi r5, 0
148: sync /* make sure invalidates have completed */
149: beq+ 0f
150: mtmsr r6 /* Restore original translations */
151: isync /* Ensure data translations are on */
152: 0:
153: blr
154:
155: .L_flush_dcache_one_line:
156: xor r4,r4,r4
157: dcbf 0,r3
158: b .L_flush_dcache_done
159:
160:
161: /*
162: * extern void invalidate_dcache(vm_offset_t va, unsigned count, boolean phys);
163: *
164: * invalidate_dcache takes a virtual or physical address and count to
165: * invalidate and (can be called for multiple virtual pages).
166: *
167: * it invalidates the data cache for the address range in question
168: */
169:
170: ENTRY(invalidate_dcache, TAG_NO_FRAME_USED)
171:
172: /* optionally switch off data translations */
173:
174: cmpwi r5, 0
175: mfmsr r6
176: beq+ 0f
177: rlwinm r7, r6, 0, MSR_DR_BIT+1, MSR_DR_BIT-1
178: mtmsr r7
179: isync
180: 0:
181:
182: /* Check to see if the address is aligned. */
183: add r8, r3,r4
184: andi. r8,r8,(CACHE_LINE_SIZE-1)
185: beq- .L_invalidate_dcache_check
186: addi r4,r4,CACHE_LINE_SIZE
187: li r7,(CACHE_LINE_SIZE-1) /* Align buffer & count - avoid overflow problems */
188: andc r4,r4,r7
189: andc r3,r3,r7
190:
191: .L_invalidate_dcache_check:
192: cmpwi r4, CACHE_LINE_SIZE
193: ble .L_invalidate_dcache_one_line
194:
195: /* Make ctr hold count of how many times we should loop */
196: addi r8, r4, (CACHE_LINE_SIZE-1)
197: srwi r8, r8, CACHE_LINE_POW2
198: mtctr r8
199:
200: .L_invalidate_dcache_invalidate_loop:
201: subic r4, r4, CACHE_LINE_SIZE
202: dcbi r3, r4
203: dcbi r3, r4
204: bdnz .L_invalidate_dcache_invalidate_loop
205:
206: .L_invalidate_dcache_done:
207: /* Sync restore msr if it was modified */
208: cmpwi r5, 0
209: sync /* make sure invalidates have completed */
210: beq+ 0f
211: mtmsr r6 /* Restore original translations */
212: isync /* Ensure data translations are on */
213: 0:
214: blr
215:
216: .L_invalidate_dcache_one_line:
217: xor r4,r4,r4
218: dcbi 0,r3
219: dcbi 0,r3
220: b .L_invalidate_dcache_done
221:
222: /*
223: * extern void invalidate_icache(vm_offset_t addr, unsigned cnt, boolean phys);
224: *
225: * invalidate_icache takes a virtual or physical address and
226: * count to invalidate, (can be called for multiple virtual pages).
227: *
228: * it invalidates the instruction cache for the address range in question.
229: */
230:
231: ENTRY(invalidate_icache, TAG_NO_FRAME_USED)
232:
233: /* optionally switch off data translations */
234: cmpwi r5, 0
235: mfmsr r6
236: beq+ 0f
237: rlwinm r7, r6, 0, MSR_DR_BIT+1, MSR_DR_BIT-1
238: mtmsr r7
239: isync
240: 0:
241:
242: /* Check to see if the address is aligned. */
243: add r8, r3,r4
244: andi. r8,r8,(CACHE_LINE_SIZE-1)
245: beq- .L_invalidate_icache_check
246: addi r4,r4,CACHE_LINE_SIZE
247: li r7,(CACHE_LINE_SIZE-1) /* Align buffer & count - avoid overflow problems */
248: andc r4,r4,r7
249: andc r3,r3,r7
250:
251: .L_invalidate_icache_check:
252: cmpwi r4, CACHE_LINE_SIZE
253: ble .L_invalidate_icache_one_line
254:
255: /* Make ctr hold count of how many times we should loop */
256: addi r8, r4, (CACHE_LINE_SIZE-1)
257: srwi r8, r8, CACHE_LINE_POW2
258: mtctr r8
259:
260: .L_invalidate_icache_invalidate_loop:
261: subic r4, r4, CACHE_LINE_SIZE
262: icbi r3, r4
263: icbi r3, r4
264: bdnz .L_invalidate_icache_invalidate_loop
265:
266: .L_invalidate_icache_done:
267: /* Sync restore msr if it was modified */
268: cmpwi r5, 0
269: sync /* make sure invalidates have completed */
270: beq+ 0f
271: mtmsr r6 /* Restore original translations */
272: isync /* Ensure data translations are on */
273: 0:
274: blr
275:
276: .L_invalidate_icache_one_line:
277: xor r4,r4,r4
278: icbi 0,r3
279: icbi 0,r3
280: b .L_invalidate_icache_done
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.