30 #define CR0_PG 0x80000000
32 #define EFER_LMA 0x400
34 #define PTE_PSE (1 << 7)
35 #define PTE_DIRTY (1 << 5)
36 #define PTE_NOCACHE (1 << 4)
37 #define PTE_WRITETHROUGH (1 << 3)
38 #define PTE_USER (1 << 2)
39 #define PTE_WRITE (1 << 1)
40 #define PTE_PRESENT (1 << 0)
62 if (!(cpuid_edx & (1 << 3)))
64 if (!(cpuid_edx & (1 << 17))) {
95 unsigned int size = 8;
96 unsigned int wordsizealignbits;
135 vmask = 0x01ffull << downshift;
139 else if (ptlevels == 3) {
142 vmask = 0x01ffll << downshift;
146 else if (ptlevels == 2) {
148 vmask = 0x03ffll << downshift;
153 wordsizealignbits = 3;
154 entryaddrmask = 0x00ffffffffff000ull;
157 wordsizealignbits = 2;
158 entryaddrmask = 0xfffff000ull;
162 "lookup: pgd=0x%"PRIxADDR",ptlevels=%d,size=%u,"
163 "downshift=%d,shiftinc=%d,vmask=0x%"PRIxADDR","
165 pgd,ptlevels,size,downshift,shiftinc,vmask,entryaddrmask);
167 if (ptlevels == 4 || ptlevels == 3) {
169 for (curlevel = ptlevels; curlevel > 0; --curlevel) {
170 if (ptlevels == 3 && ptlevels == curlevel) {
173 paddr = pbase + (((0x03ull << 30) & virt) >> (30 - wordsizealignbits));
176 paddr = pbase + ((vmask & virt) >> downshift);
179 downshift -= shiftinc;
184 verror(
"could not read L%d entry (pbase 0x%"PRIxADDR
","
185 " paddr 0x%"PRIxADDR
")!\n",curlevel,pbase,paddr);
192 "nonpresent L%d entry 0x%"PRIxADDR
" (pbase 0x%"PRIxADDR
193 ", paddr 0x%"PRIxADDR
"\n",curlevel,entry,pbase,paddr);
194 errno = EADDRNOTAVAIL;
197 else if (curlevel == 3 && entry &
PTE_PSE) {
200 ((entry & (0x0full << 12)) << 20)
201 | ((entry & (0x0full << 16)) << 16)
202 | ((entry & (0x03ffull << 21)));
205 ((entry & (0x0full << 12)) << 20)
206 | (entry & (0x03ffull << 21));
209 (entry & ((0x03ffull << 21)));
211 verror(
"PSE set in PTE, but PSE support disabled in CPU!!\n");
217 retval = nentry | (virt & 0x3fffffff);
220 "lookup L%d: entry 0x%"PRIxADDR
221 " -> 1GB phys addr 0x%"PRIxADDR
"\n",
222 curlevel,entry,retval);
226 else if (curlevel == 2 && entry & PTE_PSE) {
229 ((entry & (0x0full << 12)) << 20)
230 | ((entry & (0x0full << 16)) << 16)
231 | ((entry & (0x03ffull << 21)));
234 ((entry & (0x0full << 12)) << 16)
235 | ((entry & (0x03ffull << 21)));
238 (entry & ((0x03ffull << 21)));
240 verror(
"PSE set in PTE, but PSE support disabled in CPU!!\n");
246 retval = nentry | (virt & 0x0001fffff);
249 "lookup L%d: entry 0x%"PRIxADDR
250 " -> 2MB phys addr 0x%"PRIxADDR
"\n",
251 curlevel,nentry,retval);
256 pbase = (entryaddrmask & entry);
259 "lookup L%d: entry 0x%"PRIxADDR
" -> table 0x%"PRIxADDR
"\n",
260 curlevel,entry,pbase);
269 retval = pbase | (virt & 0x0fffull);
273 for (curlevel = ptlevels; curlevel > 0; --curlevel) {
274 paddr = pbase + ((vmask & virt) >> downshift);
276 downshift -= shiftinc;
280 verror(
"could not read L%d entry (pbase 0x%"PRIxADDR
","
281 " paddr 0x%"PRIxADDR
")!\n",curlevel,pbase,paddr);
288 "nonpresent L%d entry 0x%"PRIxADDR
" (pbase 0x%"PRIxADDR
289 ", paddr 0x%"PRIxADDR
"\n",curlevel,entry,pbase,paddr);
290 errno = EADDRNOTAVAIL;
293 else if (curlevel == 2 && entry &
PTE_PSE) {
296 (entry & ((0x0full << 13) << 19))
297 | (entry & ((0x0full << 17) << 15))
298 | (entry & ((0x03ffull << 22)));
301 (entry & ((0x0full << 13) << 19))
302 | (entry & ((0x03ffull << 22)));
305 (entry & ((0x03ffull << 22)));
307 verror(
"PSE set in PTE, but PSE support disabled in CPU!!\n");
313 retval |= (virt & 0x0001fffff);
316 "lookup L%d: entry 0x%"PRIxADDR
317 " -> 2MB phys addr 0x%"PRIxADDR
"\n",
318 curlevel,entry,retval);
323 pbase = (entryaddrmask & entry);
326 "lookup L%d: entry 0x%"PRIxADDR
" -> table 0x%"PRIxADDR
"\n",
327 curlevel,entry,pbase);
336 retval = entry | (virt & 0x0fffull);
353 unsigned int remaining =
bufsiz;
356 strncpy(buf + (bufsiz - remaining),
"NOTPAGING,",remaining);
357 if (strlen(
"NOTPAGING,") > remaining) {
358 buf[bufsiz-1] =
'\0';
362 remaining -= strlen(
"NOTPAGING,");
365 strncpy(buf + (bufsiz - remaining),
"PAE,",remaining);
366 if (strlen(
"PAE,") > remaining) {
367 buf[bufsiz-1] =
'\0';
371 remaining -= strlen(
"PAE,");
374 strncpy(buf + (bufsiz - remaining),
"NOPSE,",remaining);
375 if (strlen(
"NOPSE,") > remaining) {
376 buf[bufsiz-1] =
'\0';
380 remaining -= strlen(
"NOPSE,");
383 strncpy(buf + (bufsiz - remaining),
"NOPSE36,",remaining);
384 if (strlen(
"NOPSE36,") > remaining) {
385 buf[bufsiz-1] =
'\0';
389 remaining -= strlen(
"NOPSE36,");
392 strncpy(buf + (bufsiz - remaining),
"NOPSE40,",remaining);
393 if (strlen(
"NOPSE40,") > remaining) {
394 buf[bufsiz-1] =
'\0';
398 remaining -= strlen(
"NOPSE40,");
401 strncpy(buf + (bufsiz - remaining),
"LMA,",remaining);
402 if (strlen(
"LMA,") > remaining) {
403 buf[bufsiz-1] =
'\0';
407 remaining -= strlen(
"LMA,");
410 strncpy(buf + (bufsiz - remaining),
"PV,",remaining);
411 if (strlen(
"PV,") > remaining) {
412 buf[bufsiz-1] =
'\0';
416 remaining -= strlen(
"PV,");
419 if (remaining >= bufsiz)
420 buf[bufsiz - 1] =
'\0';
422 buf[bufsiz - remaining] =
'\0';
424 return bufsiz - remaining;
int target_arch_x86_v2p(struct target *target, ADDR pgd, ADDR virt, arch_x86_v2p_flags_t flags, ADDR *phys)
#define vwarnopt(level, area, flags, format,...)
int target_arch_x86_v2p_flags_snprintf(struct target *target, arch_x86_v2p_flags_t flags, char *buf, unsigned int bufsiz)
#define verror(format,...)
unsigned char * target_read_physaddr(struct target *target, ADDR paddr, unsigned long length, unsigned char *buf)
int target_arch_x86_v2p_get_flags(struct target *target, REGVAL cr0, REGVAL cr4, REGVAL msr_efer, REGVAL cpuid_edx, arch_x86_v2p_flags_t *flags)
#define vdebug(devel, areas, flags, format,...)