Revision f51589da
b/target-i386/helper2.c | ||
---|---|---|
742 | 742 |
#else |
743 | 743 |
target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr) |
744 | 744 |
{ |
745 |
uint8_t *pde_ptr, *pte_ptr;
|
|
745 |
uint32_t pde_addr, pte_addr;
|
|
746 | 746 |
uint32_t pde, pte, paddr, page_offset, page_size; |
747 | 747 |
|
748 |
if (!(env->cr[0] & CR0_PG_MASK)) { |
|
749 |
pte = addr; |
|
750 |
page_size = 4096; |
|
751 |
} else { |
|
752 |
/* page directory entry */ |
|
753 |
pde_ptr = phys_ram_base + |
|
754 |
(((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3)) & env->a20_mask); |
|
755 |
pde = ldl_raw(pde_ptr); |
|
756 |
if (!(pde & PG_PRESENT_MASK)) |
|
748 |
if (env->cr[4] & CR4_PAE_MASK) { |
|
749 |
uint32_t pdpe_addr, pde_addr, pte_addr; |
|
750 |
uint32_t pdpe; |
|
751 |
|
|
752 |
/* XXX: we only use 32 bit physical addresses */ |
|
753 |
#ifdef TARGET_X86_64 |
|
754 |
if (env->hflags & HF_LMA_MASK) { |
|
755 |
uint32_t pml4e_addr, pml4e; |
|
756 |
int32_t sext; |
|
757 |
|
|
758 |
/* test virtual address sign extension */ |
|
759 |
sext = (int64_t)addr >> 47; |
|
760 |
if (sext != 0 && sext != -1) |
|
761 |
return -1; |
|
762 |
|
|
763 |
pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) & |
|
764 |
env->a20_mask; |
|
765 |
pml4e = ldl_phys_aligned(pml4e_addr); |
|
766 |
if (!(pml4e & PG_PRESENT_MASK)) |
|
767 |
return -1; |
|
768 |
|
|
769 |
pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) & |
|
770 |
env->a20_mask; |
|
771 |
pdpe = ldl_phys_aligned(pdpe_addr); |
|
772 |
if (!(pdpe & PG_PRESENT_MASK)) |
|
773 |
return -1; |
|
774 |
} else |
|
775 |
#endif |
|
776 |
{ |
|
777 |
pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 30) << 3)) & |
|
778 |
env->a20_mask; |
|
779 |
pdpe = ldl_phys_aligned(pdpe_addr); |
|
780 |
if (!(pdpe & PG_PRESENT_MASK)) |
|
781 |
return -1; |
|
782 |
} |
|
783 |
|
|
784 |
pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) & |
|
785 |
env->a20_mask; |
|
786 |
pde = ldl_phys_aligned(pde_addr); |
|
787 |
if (!(pde & PG_PRESENT_MASK)) { |
|
757 | 788 |
return -1; |
758 |
if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) { |
|
759 |
pte = pde & ~0x003ff000; /* align to 4MB */ |
|
760 |
page_size = 4096 * 1024; |
|
789 |
} |
|
790 |
if (pde & PG_PSE_MASK) { |
|
791 |
/* 2 MB page */ |
|
792 |
page_size = 2048 * 1024; |
|
793 |
pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */ |
|
794 |
} else { |
|
795 |
/* 4 KB page */ |
|
796 |
pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) & |
|
797 |
env->a20_mask; |
|
798 |
page_size = 4096; |
|
799 |
pte = ldl_phys_aligned(pte_addr); |
|
800 |
} |
|
801 |
} else { |
|
802 |
if (!(env->cr[0] & CR0_PG_MASK)) { |
|
803 |
pte = addr; |
|
804 |
page_size = 4096; |
|
761 | 805 |
} else { |
762 | 806 |
/* page directory entry */ |
763 |
pte_ptr = phys_ram_base + |
|
764 |
(((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask); |
|
765 |
pte = ldl_raw(pte_ptr); |
|
766 |
if (!(pte & PG_PRESENT_MASK)) |
|
807 |
pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3)) & env->a20_mask; |
|
808 |
pde = ldl_phys_aligned(pde_addr); |
|
809 |
if (!(pde & PG_PRESENT_MASK)) |
|
767 | 810 |
return -1; |
768 |
page_size = 4096; |
|
811 |
if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) { |
|
812 |
pte = pde & ~0x003ff000; /* align to 4MB */ |
|
813 |
page_size = 4096 * 1024; |
|
814 |
} else { |
|
815 |
/* page directory entry */ |
|
816 |
pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask; |
|
817 |
pte = ldl_phys_aligned(pte_addr); |
|
818 |
if (!(pte & PG_PRESENT_MASK)) |
|
819 |
return -1; |
|
820 |
page_size = 4096; |
|
821 |
} |
|
769 | 822 |
} |
823 |
pte = pte & env->a20_mask; |
|
770 | 824 |
} |
771 |
pte = pte & env->a20_mask; |
|
825 |
|
|
772 | 826 |
page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1); |
773 | 827 |
paddr = (pte & TARGET_PAGE_MASK) + page_offset; |
774 | 828 |
return paddr; |
Also available in: Unified diff