]>
Commit | Line | Data |
---|---|---|
1c79356b A |
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); | |
0b4e3aa0 | 48 | extern vm_offset_t mem_actual; |
1c79356b A |
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 | ||
0b4e3aa0 | 60 | pa = (vm_offset_t)LRA(pmap->space,(void *)va); |
1c79356b A |
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) { | |
0b4e3aa0 A |
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); | |
1c79356b A |
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 |