Changeset 1946 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Apr 5, 2007 10:57:11 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
r1828 r1946 718 718 { 719 719 unsigned iPage = off >> PAGE_SHIFT; 720 size_t cb; 720 721 721 722 /* Physical chunk in dynamically allocated range not present? */ 722 723 if (RT_UNLIKELY(!(pCur->aHCPhys[iPage] & X86_PTE_PAE_PG_MASK))) 723 724 { 724 int rc;725 #ifdef IN_RING3 726 if ( fGrabbedLock)725 /* Treat it as reserved; return zeros */ 726 cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK); 727 if (cb >= cbRead) 727 728 { 728 pgmUnlock(pVM); 729 rc = pgmr3PhysGrowRange(pVM, GCPhys); 730 if (rc == VINF_SUCCESS) 731 PGMPhysRead(pVM, GCPhys, pvBuf, cbRead); /* try again; can't assume pCur is still valid (paranoia) */ 732 return; 729 memset(pvBuf, 0, cbRead); 730 goto end; 733 731 } 734 rc = pgmr3PhysGrowRange(pVM, GCPhys); 735 #else 736 rc = CTXALLMID(VMM, CallHost)(pVM, VMMCALLHOST_PGM_RAM_GROW_RANGE, GCPhys); 737 #endif 738 if (rc != VINF_SUCCESS) 739 goto end; 740 } 741 742 size_t cb; 743 RTHCPHYS HCPhys = pCur->aHCPhys[iPage]; 744 switch (HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_VIRTUAL_ALL | MM_RAM_FLAGS_PHYSICAL_ALL | MM_RAM_FLAGS_ROM)) 745 { 746 /* 747 * Normal memory or ROM. 748 */ 749 case 0: 750 case MM_RAM_FLAGS_ROM: 751 case MM_RAM_FLAGS_ROM | MM_RAM_FLAGS_RESERVED: 752 case MM_RAM_FLAGS_PHYSICAL_WRITE: 753 case MM_RAM_FLAGS_MMIO2 | MM_RAM_FLAGS_PHYSICAL_WRITE: 754 case MM_RAM_FLAGS_VIRTUAL_WRITE: 732 memset(pvBuf, 0, cb); 733 } 734 else 735 { 736 RTHCPHYS HCPhys = pCur->aHCPhys[iPage]; 737 switch (HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_VIRTUAL_ALL | MM_RAM_FLAGS_PHYSICAL_ALL | MM_RAM_FLAGS_ROM)) 755 738 { 756 #ifdef IN_GC 757 void *pvSrc = NULL; 758 PGMGCDynMapHCPage(pVM, HCPhys & X86_PTE_PAE_PG_MASK, &pvSrc); 759 pvSrc = (char *)pvSrc + (off & PAGE_OFFSET_MASK); 760 #else 761 void *pvSrc = PGMRAMRANGE_GETHCPTR(pCur, off) 762 #endif 763 cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK); 764 if (cb >= cbRead) 765 { 766 #if defined(IN_RING3) && defined(PGM_PHYSMEMACCESS_CACHING) 767 if (cbRead <= 4) 768 pgmPhysCacheAdd(pVM, &pVM->pgm.s.pgmphysreadcache, GCPhys, (uint8_t*)pvSrc); 769 #endif /* IN_RING3 && PGM_PHYSMEMACCESS_CACHING */ 770 memcpy(pvBuf, pvSrc, cbRead); 771 goto end; 772 } 773 memcpy(pvBuf, pvSrc, cb); 774 break; 775 } 776 777 /* 778 * All reserved, nothing there. 779 */ 780 case MM_RAM_FLAGS_RESERVED: 781 cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK); 782 if (cb >= cbRead) 783 { 784 memset(pvBuf, 0, cbRead); 785 goto end; 786 } 787 memset(pvBuf, 0, cb); 788 break; 789 790 /* 791 * Physical handler. 792 */ 793 case MM_RAM_FLAGS_PHYSICAL_ALL: 794 case MM_RAM_FLAGS_MMIO2 | MM_RAM_FLAGS_PHYSICAL_ALL: /** r=bird: MMIO2 isn't in the mask! */ 795 { 796 int rc = VINF_PGM_HANDLER_DO_DEFAULT; 797 cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK); 798 #ifdef IN_RING3 /** @todo deal with this in GC and R0! */ 799 800 /* find and call the handler */ 801 PPGMPHYSHANDLER pNode = (PPGMPHYSHANDLER)RTAvlroGCPhysRangeGet(&pVM->pgm.s.pTreesHC->PhysHandlers, GCPhys); 802 if (pNode && pNode->pfnHandlerR3) 803 { 804 size_t cbRange = pNode->Core.KeyLast - GCPhys + 1; 805 if (cbRange < cb) 806 cb = cbRange; 807 if (cb > cbRead) 808 cb = cbRead; 809 810 void *pvSrc = PGMRAMRANGE_GETHCPTR(pCur, off) 811 812 /** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */ 813 rc = pNode->pfnHandlerR3(pVM, GCPhys, pvSrc, pvBuf, cb, PGMACCESSTYPE_READ, pNode->pvUserR3); 814 } 815 #endif /* IN_RING3 */ 816 if (rc == VINF_PGM_HANDLER_DO_DEFAULT) 739 /* 740 * Normal memory or ROM. 741 */ 742 case 0: 743 case MM_RAM_FLAGS_ROM: 744 case MM_RAM_FLAGS_ROM | MM_RAM_FLAGS_RESERVED: 745 case MM_RAM_FLAGS_PHYSICAL_WRITE: 746 case MM_RAM_FLAGS_MMIO2 | MM_RAM_FLAGS_PHYSICAL_WRITE: 747 case MM_RAM_FLAGS_VIRTUAL_WRITE: 817 748 { 818 749 #ifdef IN_GC … … 823 754 void *pvSrc = PGMRAMRANGE_GETHCPTR(pCur, off) 824 755 #endif 825 756 cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK); 826 757 if (cb >= cbRead) 827 758 { 759 #if defined(IN_RING3) && defined(PGM_PHYSMEMACCESS_CACHING) 760 if (cbRead <= 4) 761 pgmPhysCacheAdd(pVM, &pVM->pgm.s.pgmphysreadcache, GCPhys, (uint8_t*)pvSrc); 762 #endif /* IN_RING3 && PGM_PHYSMEMACCESS_CACHING */ 828 763 memcpy(pvBuf, pvSrc, cbRead); 829 764 goto end; 830 765 } 831 766 memcpy(pvBuf, pvSrc, cb); 767 break; 832 768 } 833 else if (cb >= cbRead) 834 goto end; 835 break; 836 } 837 838 case MM_RAM_FLAGS_VIRTUAL_ALL: 839 { 840 int rc = VINF_PGM_HANDLER_DO_DEFAULT; 841 cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK); 842 #ifdef IN_RING3 /** @todo deal with this in GC and R0! */ 843 /* Search the whole tree for matching physical addresses (rather expensive!) */ 844 PPGMVIRTHANDLER pNode; 845 unsigned iPage; 846 int rc2 = pgmHandlerVirtualFindByPhysAddr(pVM, GCPhys, &pNode, &iPage); 847 if (VBOX_SUCCESS(rc2) && pNode->pfnHandlerHC) 848 { 849 size_t cbRange = pNode->Core.KeyLast - GCPhys + 1; 850 if (cbRange < cb) 851 cb = cbRange; 852 if (cb > cbRead) 853 cb = cbRead; 854 RTGCUINTPTR GCPtr = ((RTGCUINTPTR)pNode->GCPtr & PAGE_BASE_GC_MASK) 855 + (iPage << PAGE_SHIFT) + (off & PAGE_OFFSET_MASK); 856 857 void *pvSrc = PGMRAMRANGE_GETHCPTR(pCur, off) 858 859 /** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */ 860 rc = pNode->pfnHandlerHC(pVM, (RTGCPTR)GCPtr, pvSrc, pvBuf, cb, PGMACCESSTYPE_READ, 0); 861 } 862 #endif /* IN_RING3 */ 863 if (rc == VINF_PGM_HANDLER_DO_DEFAULT) 864 { 865 #ifdef IN_GC 866 void *pvSrc = NULL; 867 PGMGCDynMapHCPage(pVM, HCPhys & X86_PTE_PAE_PG_MASK, &pvSrc); 868 pvSrc = (char *)pvSrc + (off & PAGE_OFFSET_MASK); 869 #else 870 void *pvSrc = PGMRAMRANGE_GETHCPTR(pCur, off) 871 #endif 769 770 /* 771 * All reserved, nothing there. 772 */ 773 case MM_RAM_FLAGS_RESERVED: 774 cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK); 872 775 if (cb >= cbRead) 873 776 { 874 mem cpy(pvBuf, pvSrc, cbRead);777 memset(pvBuf, 0, cbRead); 875 778 goto end; 876 779 } 877 memcpy(pvBuf, pvSrc, cb); 780 memset(pvBuf, 0, cb); 781 break; 782 783 /* 784 * Physical handler. 785 */ 786 case MM_RAM_FLAGS_PHYSICAL_ALL: 787 case MM_RAM_FLAGS_MMIO2 | MM_RAM_FLAGS_PHYSICAL_ALL: /** r=bird: MMIO2 isn't in the mask! */ 788 { 789 int rc = VINF_PGM_HANDLER_DO_DEFAULT; 790 cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK); 791 #ifdef IN_RING3 /** @todo deal with this in GC and R0! */ 792 793 /* find and call the handler */ 794 PPGMPHYSHANDLER pNode = (PPGMPHYSHANDLER)RTAvlroGCPhysRangeGet(&pVM->pgm.s.pTreesHC->PhysHandlers, GCPhys); 795 if (pNode && pNode->pfnHandlerR3) 796 { 797 size_t cbRange = pNode->Core.KeyLast - GCPhys + 1; 798 if (cbRange < cb) 799 cb = cbRange; 800 if (cb > cbRead) 801 cb = cbRead; 802 803 void *pvSrc = PGMRAMRANGE_GETHCPTR(pCur, off) 804 805 /** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */ 806 rc = pNode->pfnHandlerR3(pVM, GCPhys, pvSrc, pvBuf, cb, PGMACCESSTYPE_READ, pNode->pvUserR3); 807 } 808 #endif /* IN_RING3 */ 809 if (rc == VINF_PGM_HANDLER_DO_DEFAULT) 810 { 811 #ifdef IN_GC 812 void *pvSrc = NULL; 813 PGMGCDynMapHCPage(pVM, HCPhys & X86_PTE_PAE_PG_MASK, &pvSrc); 814 pvSrc = (char *)pvSrc + (off & PAGE_OFFSET_MASK); 815 #else 816 void *pvSrc = PGMRAMRANGE_GETHCPTR(pCur, off) 817 #endif 818 819 if (cb >= cbRead) 820 { 821 memcpy(pvBuf, pvSrc, cbRead); 822 goto end; 823 } 824 memcpy(pvBuf, pvSrc, cb); 825 } 826 else if (cb >= cbRead) 827 goto end; 828 break; 878 829 } 879 else if (cb >= cbRead) 880 goto end; 881 break; 830 831 case MM_RAM_FLAGS_VIRTUAL_ALL: 832 { 833 int rc = VINF_PGM_HANDLER_DO_DEFAULT; 834 cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK); 835 #ifdef IN_RING3 /** @todo deal with this in GC and R0! */ 836 /* Search the whole tree for matching physical addresses (rather expensive!) */ 837 PPGMVIRTHANDLER pNode; 838 unsigned iPage; 839 int rc2 = pgmHandlerVirtualFindByPhysAddr(pVM, GCPhys, &pNode, &iPage); 840 if (VBOX_SUCCESS(rc2) && pNode->pfnHandlerHC) 841 { 842 size_t cbRange = pNode->Core.KeyLast - GCPhys + 1; 843 if (cbRange < cb) 844 cb = cbRange; 845 if (cb > cbRead) 846 cb = cbRead; 847 RTGCUINTPTR GCPtr = ((RTGCUINTPTR)pNode->GCPtr & PAGE_BASE_GC_MASK) 848 + (iPage << PAGE_SHIFT) + (off & PAGE_OFFSET_MASK); 849 850 void *pvSrc = PGMRAMRANGE_GETHCPTR(pCur, off) 851 852 /** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */ 853 rc = pNode->pfnHandlerHC(pVM, (RTGCPTR)GCPtr, pvSrc, pvBuf, cb, PGMACCESSTYPE_READ, 0); 854 } 855 #endif /* IN_RING3 */ 856 if (rc == VINF_PGM_HANDLER_DO_DEFAULT) 857 { 858 #ifdef IN_GC 859 void *pvSrc = NULL; 860 PGMGCDynMapHCPage(pVM, HCPhys & X86_PTE_PAE_PG_MASK, &pvSrc); 861 pvSrc = (char *)pvSrc + (off & PAGE_OFFSET_MASK); 862 #else 863 void *pvSrc = PGMRAMRANGE_GETHCPTR(pCur, off) 864 #endif 865 if (cb >= cbRead) 866 { 867 memcpy(pvBuf, pvSrc, cbRead); 868 goto end; 869 } 870 memcpy(pvBuf, pvSrc, cb); 871 } 872 else if (cb >= cbRead) 873 goto end; 874 break; 875 } 876 877 /* 878 * The rest needs to be taken more carefully. 879 */ 880 default: 881 #if 1 /** @todo r=bird: Can you do this properly please. */ 882 /** @todo Try MMIO; quick hack */ 883 if (cbRead <= 4 && IOMMMIORead(pVM, GCPhys, (uint32_t *)pvBuf, cbRead) == VINF_SUCCESS) 884 goto end; 885 #endif 886 887 /** @todo fix me later. */ 888 AssertReleaseMsgFailed(("Unknown read at %VGp size %d implement the complex physical reading case %x\n", 889 GCPhys, cbRead, 890 HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_VIRTUAL_ALL | MM_RAM_FLAGS_PHYSICAL_ALL | MM_RAM_FLAGS_ROM))); 891 cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK); 892 break; 882 893 } 883 884 /* 885 * The rest needs to be taken more carefully. 886 */ 887 default: 888 #if 1 /** @todo r=bird: Can you do this properly please. */ 889 /** @todo Try MMIO; quick hack */ 890 if (cbRead <= 4 && IOMMMIORead(pVM, GCPhys, (uint32_t *)pvBuf, cbRead) == VINF_SUCCESS) 891 goto end; 892 #endif 893 894 /** @todo fix me later. */ 895 AssertReleaseMsgFailed(("Unknown read at %VGp size %d implement the complex physical reading case %x\n", 896 GCPhys, cbRead, 897 HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_VIRTUAL_ALL | MM_RAM_FLAGS_PHYSICAL_ALL | MM_RAM_FLAGS_ROM))); 898 cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK); 899 break; 900 } 901 894 } 902 895 cbRead -= cb; 903 896 off += cb;
Note:
See TracChangeset
for help on using the changeset viewer.