]> git.saurik.com Git - apple/xnu.git/blob - osfmk/kdp/ml/ppc/kdp_vm.c
e7a5e1333f0f8f8071d578a71139a7d47aa24025
[apple/xnu.git] / osfmk / kdp / ml / ppc / kdp_vm.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 #include <mach/mach_types.h>
26 #include <mach/vm_attributes.h>
27 #include <mach/vm_param.h>
28
29 #include <vm/pmap.h>
30
31 #include <ppc/proc_reg.h>
32 #include <ppc/machparam.h>
33 #include <ppc/mem.h>
34 #include <ppc/pmap.h>
35 #include <ppc/pmap_internals.h>
36 #include <ppc/mappings.h>
37
38 pmap_t kdp_pmap=0;
39 boolean_t kdp_trans_off=0;
40
41 unsigned kdp_xlate_off(void);
42 void kdp_xlate_restore(unsigned);
43 void kdp_flush_cache(vm_offset_t, unsigned);
44 vm_offset_t kdp_vtophys(pmap_t pmap, vm_offset_t vaddr);
45 void kdp_bcopy( unsigned char *, unsigned char *, unsigned);
46 void kdp_pmemcpy( vm_offset_t , vm_offset_t, unsigned);
47 unsigned kdp_vm_read( caddr_t, caddr_t, unsigned);
48 unsigned kdp_vm_write( caddr_t, caddr_t, unsigned);
49
50 extern vm_offset_t kvtophys(vm_offset_t);
51 extern vm_offset_t mem_actual;
52
53 /*
54 *
55 */
56 vm_offset_t kdp_vtophys(
57 pmap_t pmap,
58 vm_offset_t va)
59 {
60 register mapping *mp;
61 register vm_offset_t pa;
62
63 pa = (vm_offset_t)LRA(pmap->space,(void *)va);
64
65 if (pa != 0)
66 return(pa);
67
68 mp = hw_lock_phys_vir(pmap->space, va);
69 if((unsigned int)mp&1) {
70 return 0;
71 }
72
73 if(!mp) { /* If it was not a normal page */
74 pa = hw_cvp_blk(pmap, va); /* Try to convert odd-sized page (returns 0 if not found) */
75 return pa; /* Return physical address */
76 }
77
78 mp = hw_cpv(mp);
79
80 if(!mp->physent) {
81 pa = (vm_offset_t)((mp->PTEr & -PAGE_SIZE) | ((unsigned int)va & (PAGE_SIZE-1)));
82 } else {
83 pa = (vm_offset_t)((mp->physent->pte1 & -PAGE_SIZE) | ((unsigned int)va & (PAGE_SIZE-1)));
84 hw_unlock_bit((unsigned int *)&mp->physent->phys_link, PHYS_LOCK);
85 }
86
87 return(pa);
88 }
89
90 /*
91 *
92 */
93 void kdp_bcopy(
94 unsigned char *src,
95 unsigned char *dst,
96 unsigned cnt)
97 {
98 while (cnt--)
99 *dst++ = *src++;
100 }
101
102 /*
103 *
104 */
105 unsigned kdp_vm_read(
106 caddr_t src,
107 caddr_t dst,
108 unsigned len)
109 {
110 vm_offset_t cur_virt_src, cur_virt_dst;
111 vm_offset_t cur_phys_src;
112 unsigned resid, cnt;
113 unsigned msr;
114
115 #ifdef KDP_VM_READ_DEBUG
116 kprintf("kdp_vm_read1: src %x dst %x len %x - %08X %08X\n", src, dst, len, ((unsigned long *)src)[0], ((unsigned long *)src)[1]);
117 #endif
118 if (kdp_trans_off) {
119 cur_virt_src = (vm_offset_t)src;
120 if((vm_offset_t)src >= mem_actual) return 0; /* Can't read where there's not any memory */
121 cur_virt_dst = (vm_offset_t)dst;
122 resid = (mem_actual - (vm_offset_t)src) > len ? len : (mem_actual - (vm_offset_t)src);
123
124 while (resid != 0) {
125 cur_phys_src = cur_virt_src;
126 cnt = ((cur_virt_src + NBPG) & (-NBPG)) - cur_virt_src;
127 if (cnt > resid) cnt = resid;
128 msr = kdp_xlate_off();
129 kdp_bcopy((unsigned char *)cur_phys_src,
130 (unsigned char *)cur_virt_dst, cnt);
131 kdp_xlate_restore(msr);
132 cur_virt_src +=cnt;
133 cur_virt_dst +=cnt;
134 resid -= cnt;
135 }
136 } else {
137 cur_virt_src = (vm_offset_t)src;
138 cur_virt_dst = (vm_offset_t)dst;
139 resid = len;
140
141 while (resid != 0) {
142 if (kdp_pmap) {
143 if ((cur_phys_src =
144 kdp_vtophys(kdp_pmap,trunc_page(cur_virt_src))) == 0)
145 goto exit;
146 cur_phys_src += (cur_virt_src & PAGE_MASK);
147 } else {
148 if ((cur_phys_src = kdp_vtophys(kernel_pmap,cur_virt_src)) == 0)
149 goto exit;
150 }
151
152 cnt = ((cur_virt_src + NBPG) & (-NBPG)) - cur_virt_src;
153 if (cnt > resid) cnt = resid;
154 if (kdp_pmap) {
155 #ifdef KDP_VM_READ_DEBUG
156 kprintf("kdp_vm_read2: pmap %x, virt %x, phys %x\n",
157 kdp_pmap, cur_virt_src, cur_phys_src);
158 #endif
159 msr = kdp_xlate_off();
160 kdp_bcopy((unsigned char *)cur_phys_src,
161 (unsigned char *)cur_virt_dst, cnt);
162 kdp_xlate_restore(msr);
163 } else {
164 kdp_bcopy((unsigned char *)cur_virt_src,
165 (unsigned char *)cur_virt_dst, cnt);
166 }
167 cur_virt_src +=cnt;
168 cur_virt_dst +=cnt;
169 resid -= cnt;
170 }
171 }
172 exit:
173 #ifdef KDP_VM_READ_DEBUG
174 kprintf("kdp_vm_read: ret %08X\n", len-resid);
175 #endif
176 return (len-resid);
177 }
178
179 /*
180 *
181 */
182 unsigned kdp_vm_write(
183 caddr_t src,
184 caddr_t dst,
185 unsigned len)
186 {
187 vm_offset_t cur_virt_src, cur_virt_dst;
188 vm_offset_t cur_phys_src, cur_phys_dst;
189 unsigned resid, cnt, cnt_src, cnt_dst;
190 unsigned msr;
191
192 #ifdef KDP_VM_WRITE_DEBUG
193 printf("kdp_vm_write: src %x dst %x len %x - %08X %08X\n", src, dst, len, ((unsigned long *)src)[0], ((unsigned long *)src)[1]);
194 #endif
195
196 cur_virt_src = (vm_offset_t)src;
197 cur_virt_dst = (vm_offset_t)dst;
198 resid = len;
199
200 while (resid != 0) {
201 if ((cur_phys_dst = kdp_vtophys(kernel_pmap, cur_virt_dst)) == 0)
202 goto exit;
203 if ((cur_phys_src = kdp_vtophys(kernel_pmap, cur_virt_src)) == 0)
204 goto exit;
205
206 cnt_src = ((cur_phys_src + NBPG) & (-NBPG)) - cur_phys_src;
207 cnt_dst = ((cur_phys_dst + NBPG) & (-NBPG)) - cur_phys_dst;
208
209 if (cnt_src > cnt_dst)
210 cnt = cnt_dst;
211 else
212 cnt = cnt_src;
213 if (cnt > resid)
214 cnt = resid;
215
216 msr = kdp_xlate_off();
217 kdp_bcopy((unsigned char *)cur_virt_src, (unsigned char *)cur_phys_dst, cnt);
218 kdp_flush_cache(cur_phys_dst, cnt);
219 kdp_xlate_restore(msr);
220
221 cur_virt_src +=cnt;
222 cur_virt_dst +=cnt;
223 resid -= cnt;
224 }
225 exit:
226 return (len-resid);
227 }
228