]> git.saurik.com Git - apple/xnu.git/blob - osfmk/kdp/ml/ppc/kdp_vm.c
dad44c78c7402441f203ae6158b810148c51ef3b
[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 * 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 #include <mach/mach_types.h>
23 #include <mach/vm_attributes.h>
24 #include <mach/vm_param.h>
25
26 #include <vm/pmap.h>
27
28 #include <ppc/proc_reg.h>
29 #include <ppc/machparam.h>
30 #include <ppc/mem.h>
31 #include <ppc/pmap.h>
32 #include <ppc/pmap_internals.h>
33 #include <ppc/mappings.h>
34
35 pmap_t kdp_pmap=0;
36 boolean_t kdp_trans_off=0;
37
38 unsigned kdp_xlate_off(void);
39 void kdp_xlate_restore(unsigned);
40 void kdp_flush_cache(vm_offset_t, unsigned);
41 vm_offset_t kdp_vtophys(pmap_t pmap, vm_offset_t vaddr);
42 void kdp_bcopy( unsigned char *, unsigned char *, unsigned);
43 void kdp_pmemcpy( vm_offset_t , vm_offset_t, unsigned);
44 unsigned kdp_vm_read( caddr_t, caddr_t, unsigned);
45 unsigned kdp_vm_write( caddr_t, caddr_t, unsigned);
46
47 extern vm_offset_t kvtophys(vm_offset_t);
48
49
50 /*
51 *
52 */
53 vm_offset_t kdp_vtophys(
54 pmap_t pmap,
55 vm_offset_t va)
56 {
57 register mapping *mp;
58 register vm_offset_t pa;
59
60 pa = LRA(pmap->space,(void *)va);
61
62 if (pa != 0)
63 return(pa);
64
65 mp = hw_lock_phys_vir(pmap->space, va);
66 if((unsigned int)mp&1) {
67 return 0;
68 }
69
70 if(!mp) { /* If it was not a normal page */
71 pa = hw_cvp_blk(pmap, va); /* Try to convert odd-sized page (returns 0 if not found) */
72 return pa; /* Return physical address */
73 }
74
75 mp = hw_cpv(mp);
76
77 if(!mp->physent) {
78 pa = (vm_offset_t)((mp->PTEr & -PAGE_SIZE) | ((unsigned int)va & (PAGE_SIZE-1)));
79 } else {
80 pa = (vm_offset_t)((mp->physent->pte1 & -PAGE_SIZE) | ((unsigned int)va & (PAGE_SIZE-1)));
81 hw_unlock_bit((unsigned int *)&mp->physent->phys_link, PHYS_LOCK);
82 }
83
84 return(pa);
85 }
86
87 /*
88 *
89 */
90 void kdp_bcopy(
91 unsigned char *src,
92 unsigned char *dst,
93 unsigned cnt)
94 {
95 while (cnt--)
96 *dst++ = *src++;
97 }
98
99 /*
100 *
101 */
102 unsigned kdp_vm_read(
103 caddr_t src,
104 caddr_t dst,
105 unsigned len)
106 {
107 vm_offset_t cur_virt_src, cur_virt_dst;
108 vm_offset_t cur_phys_src;
109 unsigned resid, cnt;
110 unsigned msr;
111
112 #ifdef KDP_VM_READ_DEBUG
113 kprintf("kdp_vm_read1: src %x dst %x len %x - %08X %08X\n", src, dst, len, ((unsigned long *)src)[0], ((unsigned long *)src)[1]);
114 #endif
115 if (kdp_trans_off) {
116 cur_virt_src = (vm_offset_t) ((int)src & 0x0fffffff);
117 cur_virt_dst = (vm_offset_t)dst;
118 resid = len;
119
120 while (resid != 0) {
121 cur_phys_src = cur_virt_src;
122 cnt = ((cur_virt_src + NBPG) & (-NBPG)) - cur_virt_src;
123 if (cnt > resid) cnt = resid;
124 msr = kdp_xlate_off();
125 kdp_bcopy((unsigned char *)cur_phys_src,
126 (unsigned char *)cur_virt_dst, cnt);
127 kdp_xlate_restore(msr);
128 cur_virt_src +=cnt;
129 cur_virt_dst +=cnt;
130 resid -= cnt;
131 }
132 } else {
133 cur_virt_src = (vm_offset_t)src;
134 cur_virt_dst = (vm_offset_t)dst;
135 resid = len;
136
137 while (resid != 0) {
138 if (kdp_pmap) {
139 if ((cur_phys_src =
140 kdp_vtophys(kdp_pmap,trunc_page(cur_virt_src))) == 0)
141 goto exit;
142 cur_phys_src += (cur_virt_src & PAGE_MASK);
143 } else {
144 if ((cur_phys_src = kdp_vtophys(kernel_pmap,cur_virt_src)) == 0)
145 goto exit;
146 }
147
148 cnt = ((cur_virt_src + NBPG) & (-NBPG)) - cur_virt_src;
149 if (cnt > resid) cnt = resid;
150 if (kdp_pmap) {
151 #ifdef KDP_VM_READ_DEBUG
152 kprintf("kdp_vm_read2: pmap %x, virt %x, phys %x\n",
153 kdp_pmap, cur_virt_src, cur_phys_src);
154 #endif
155 msr = kdp_xlate_off();
156 kdp_bcopy((unsigned char *)cur_phys_src,
157 (unsigned char *)cur_virt_dst, cnt);
158 kdp_xlate_restore(msr);
159 } else {
160 kdp_bcopy((unsigned char *)cur_virt_src,
161 (unsigned char *)cur_virt_dst, cnt);
162 }
163 cur_virt_src +=cnt;
164 cur_virt_dst +=cnt;
165 resid -= cnt;
166 }
167 }
168 exit:
169 #ifdef KDP_VM_READ_DEBUG
170 kprintf("kdp_vm_read: ret %08X\n", len-resid);
171 #endif
172 return (len-resid);
173 }
174
175 /*
176 *
177 */
178 unsigned kdp_vm_write(
179 caddr_t src,
180 caddr_t dst,
181 unsigned len)
182 {
183 vm_offset_t cur_virt_src, cur_virt_dst;
184 vm_offset_t cur_phys_src, cur_phys_dst;
185 unsigned resid, cnt, cnt_src, cnt_dst;
186 unsigned msr;
187
188 #ifdef KDP_VM_WRITE_DEBUG
189 printf("kdp_vm_write: src %x dst %x len %x - %08X %08X\n", src, dst, len, ((unsigned long *)src)[0], ((unsigned long *)src)[1]);
190 #endif
191
192 cur_virt_src = (vm_offset_t)src;
193 cur_virt_dst = (vm_offset_t)dst;
194 resid = len;
195
196 while (resid != 0) {
197 if ((cur_phys_dst = kdp_vtophys(kernel_pmap, cur_virt_dst)) == 0)
198 goto exit;
199 if ((cur_phys_src = kdp_vtophys(kernel_pmap, cur_virt_src)) == 0)
200 goto exit;
201
202 cnt_src = ((cur_phys_src + NBPG) & (-NBPG)) - cur_phys_src;
203 cnt_dst = ((cur_phys_dst + NBPG) & (-NBPG)) - cur_phys_dst;
204
205 if (cnt_src > cnt_dst)
206 cnt = cnt_dst;
207 else
208 cnt = cnt_src;
209 if (cnt > resid)
210 cnt = resid;
211
212 msr = kdp_xlate_off();
213 kdp_bcopy((unsigned char *)cur_virt_src, (unsigned char *)cur_phys_dst, cnt);
214 kdp_flush_cache(cur_phys_dst, cnt);
215 kdp_xlate_restore(msr);
216
217 cur_virt_src +=cnt;
218 cur_virt_dst +=cnt;
219 resid -= cnt;
220 }
221 exit:
222 return (len-resid);
223 }
224