cpu_get_phys_page_debug/PAE
PATCH 1/1 cpu_get_phys_page_debug/PAE
Changelog:
2005-01-24 Filip Navara <[email protected]>
* Support resolving addresses in PAE mode in cpu_get_phys_page_debug.
Index: target-i386/helper2.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-i386/helper2.c,v retrieving revision 1.29
helper2.c +74 -18
@@ -745,30 +756,86 @@uint8_t *pde_ptr, *pte_ptr;uint32_t pde, pte, paddr, page_offset, page_size; -if (!(env->cr[0 ] &CR0_PG_MASK )) { - pte = addr; - page_size =4096 ; - }else { -/* page directory entry */ - pde_ptr = phys_ram_base + - (((env->cr[3 ] & ~0xfff ) + ((addr >>20 ) & ~3 )) & env->a20_mask); - pde =ldl_raw (pde_ptr); -if (!(pde &PG_PRESENT_MASK )) +if (env->cr[4 ] &CR4_PAE_MASK ) { +uint32_t pdpe_addr, pde_addr, pte_addr; +uint32_t pdpe; + +/* XXX: we only use 32 bit physical addresses */ +#ifdef TARGET_X86_64 +if (env->hflags &HF_LMA_MASK ) { +uint32_t pml4e_addr, pml4e; +int32_t sext; + +/* test virtual address sign extension */ + sext = (int64_t )addr >>47 ; +if (sext !=0 && sext !=-1 ) +return -1 ; + + pml4e_addr = ((env->cr[3 ] & ~0xfff ) + (((addr >>39 ) &0x1ff ) <<3 )) & + env->a20_mask; + pml4e =ldl_phys_aligned (pml4e_addr); +if (!(pml4e &PG_PRESENT_MASK )) +return -1 ; + + pdpe_addr = ((pml4e & ~0xfff ) + (((addr >>30 ) &0x1ff ) <<3 )) & + env->a20_mask; + pdpe =ldl_phys_aligned (pdpe_addr); +if (!(pdpe &PG_PRESENT_MASK )) +return -1 ; + } else +#endif + { + pdpe_addr = ((env->cr[3 ] & ~0x1f ) + ((addr >>30 ) <<3 )) & + env->a20_mask; + pdpe =ldl_phys_aligned (pdpe_addr); +if (!(pdpe &PG_PRESENT_MASK )) +return -1 ; + } + + pde_addr = ((pdpe & ~0xfff ) + (((addr >>21 ) &0x1ff ) <<3 )) & + env->a20_mask; + pde =ldl_phys_aligned (pde_addr); +if (!(pde &PG_PRESENT_MASK )) {return -1 ; -if ((pde &PG_PSE_MASK ) && (env->cr[4 ] &CR4_PSE_MASK )) { - pte = pde & ~0x003ff000 ;/* align to 4MB */ - page_size =4096 *1024 ; + } +if (pde &PG_PSE_MASK ) { +/* 2 MB page */ + page_size =2048 *1024 ; + pte = pde & ~( (page_size -1 ) & ~0xfff );/* align to page_size */ + }else { +/* 4 KB page */ + pte_addr = ((pde & ~0xfff ) + (((addr >>12 ) &0x1ff ) <<3 )) & + env->a20_mask; + page_size =4096 ; + pte =ldl_phys_aligned (pte_addr); + } + }else { +if (!(env->cr[0 ] &CR0_PG_MASK )) { + pte = addr; + page_size =4096 ; }else {/* page directory entry */ - pte_ptr = phys_ram_base + - (((pde & ~0xfff ) + ((addr >>10 ) &0xffc )) & env->a20_mask); - pte =ldl_raw (pte_ptr); -if (!(pte &PG_PRESENT_MASK )) + pde_ptr = phys_ram_base + + (((env->cr[3 ] & ~0xfff ) + ((addr >>20 ) & ~3 )) & env->a20_mask); + pde =ldl_raw (pde_ptr); +if (!(pde &PG_PRESENT_MASK ))return -1 ; - page_size =4096 ; +if ((pde &PG_PSE_MASK ) && (env->cr[4 ] &CR4_PSE_MASK )) { + pte = pde & ~0x003ff000 ;/* align to 4MB */ + page_size =4096 *1024 ; + }else { +/* page directory entry */ + pte_ptr = phys_ram_base + + (((pde & ~0xfff ) + ((addr >>10 ) &0xffc )) & env->a20_mask); + pte =ldl_raw (pte_ptr); +if (!(pte &PG_PRESENT_MASK )) +return -1 ; + page_size =4096 ; + } } + pte = pte & env->a20_mask; } - pte = pte & env->a20_mask; + page_offset = (addr &TARGET_PAGE_MASK ) & (page_size -1 ); paddr = (pte &TARGET_PAGE_MASK ) + page_offset;return paddr;