]> git.saurik.com Git - apple/xnu.git/blob - osfmk/kdp/ml/ppc/kdp_vm.c
xnu-201.42.3.tar.gz
[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 extern vm_offset_t mem_actual;
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 = (vm_offset_t)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)src;
117 if((vm_offset_t)src >= mem_actual) return 0; /* Can't read where there's not any memory */
118 cur_virt_dst = (vm_offset_t)dst;
119 resid = (mem_actual - (vm_offset_t)src) > len ? len : (mem_actual - (vm_offset_t)src);
120
121 while (resid != 0) {
122 cur_phys_src = cur_virt_src;
123 cnt = ((cur_virt_src + NBPG) & (-NBPG)) - cur_virt_src;
124 if (cnt > resid) cnt = resid;
125 msr = kdp_xlate_off();
126 kdp_bcopy((unsigned char *)cur_phys_src,
127 (unsigned char *)cur_virt_dst, cnt);
128 kdp_xlate_restore(msr);
129 cur_virt_src +=cnt;
130 cur_virt_dst +=cnt;
131 resid -= cnt;
132 }
133 } else {
134 cur_virt_src = (vm_offset_t)src;
135 cur_virt_dst = (vm_offset_t)dst;
136 resid = len;
137
138 while (resid != 0) {
139 if (kdp_pmap) {
140 if ((cur_phys_src =
141 kdp_vtophys(kdp_pmap,trunc_page(cur_virt_src))) == 0)
142 goto exit;
143 cur_phys_src += (cur_virt_src & PAGE_MASK);
144 } else {
145 if ((cur_phys_src = kdp_vtophys(kernel_pmap,cur_virt_src)) == 0)
146 goto exit;
147 }
148
149 cnt = ((cur_virt_src + NBPG) & (-NBPG)) - cur_virt_src;
150 if (cnt > resid) cnt = resid;
151 if (kdp_pmap) {
152 #ifdef KDP_VM_READ_DEBUG
153 kprintf("kdp_vm_read2: pmap %x, virt %x, phys %x\n",
154 kdp_pmap, cur_virt_src, cur_phys_src);
155 #endif
156 msr = kdp_xlate_off();
157 kdp_bcopy((unsigned char *)cur_phys_src,
158 (unsigned char *)cur_virt_dst, cnt);
159 kdp_xlate_restore(msr);
160 } else {
161 kdp_bcopy((unsigned char *)cur_virt_src,
162 (unsigned char *)cur_virt_dst, cnt);
163 }
164 cur_virt_src +=cnt;
165 cur_virt_dst +=cnt;
166 resid -= cnt;
167 }
168 }
169 exit:
170 #ifdef KDP_VM_READ_DEBUG
171 kprintf("kdp_vm_read: ret %08X\n", len-resid);
172 #endif
173 return (len-resid);
174 }
175
176 /*
177 *
178 */
179 unsigned kdp_vm_write(
180 caddr_t src,
181 caddr_t dst,
182 unsigned len)
183 {
184 vm_offset_t cur_virt_src, cur_virt_dst;
185 vm_offset_t cur_phys_src, cur_phys_dst;
186 unsigned resid, cnt, cnt_src, cnt_dst;
187 unsigned msr;
188
189 #ifdef KDP_VM_WRITE_DEBUG
190 printf("kdp_vm_write: src %x dst %x len %x - %08X %08X\n", src, dst, len, ((unsigned long *)src)[0], ((unsigned long *)src)[1]);
191 #endif
192
193 cur_virt_src = (vm_offset_t)src;
194 cur_virt_dst = (vm_offset_t)dst;
195 resid = len;
196
197 while (resid != 0) {
198 if ((cur_phys_dst = kdp_vtophys(kernel_pmap, cur_virt_dst)) == 0)
199 goto exit;
200 if ((cur_phys_src = kdp_vtophys(kernel_pmap, cur_virt_src)) == 0)
201 goto exit;
202
203 cnt_src = ((cur_phys_src + NBPG) & (-NBPG)) - cur_phys_src;
204 cnt_dst = ((cur_phys_dst + NBPG) & (-NBPG)) - cur_phys_dst;
205
206 if (cnt_src > cnt_dst)
207 cnt = cnt_dst;
208 else
209 cnt = cnt_src;
210 if (cnt > resid)
211 cnt = resid;
212
213 msr = kdp_xlate_off();
214 kdp_bcopy((unsigned char *)cur_virt_src, (unsigned char *)cur_phys_dst, cnt);
215 kdp_flush_cache(cur_phys_dst, cnt);
216 kdp_xlate_restore(msr);
217
218 cur_virt_src +=cnt;
219 cur_virt_dst +=cnt;
220 resid -= cnt;
221 }
222 exit:
223 return (len-resid);
224 }
225