Changeset 57781 in vbox for trunk/src/VBox
- Timestamp:
- Sep 16, 2015 11:35:28 AM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 102718
- Location:
- trunk/src/VBox/Devices/Bus
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevPCI.cpp
r57393 r57781 289 289 mappings, we handle specific values as invalid 290 290 mappings. */ 291 /* Unconditionally exclude I/O-APIC/HPET/ROM. Pessimistic, but better than causing a mess. */ 291 292 if (last_addr <= new_addr || new_addr == 0 || 292 last_addr == ~0U) {293 (new_addr <= ~0U && last_addr >= 0xfec00000U)) { 293 294 new_addr = ~0U; 294 295 } … … 298 299 } 299 300 } 301 //LogRel(("PCI: config dev %u/%u BAR%i uOld=%#018llx uNew=%#018llx size=%llu\n", d->devfn >> 3, d->devfn & 7, i, r->addr, new_addr, r->size)); 300 302 /* now do the real mapping */ 301 303 if (new_addr != r->addr) { … … 877 879 static void pci_set_io_region_addr(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn, int region_num, uint32_t addr) 878 880 { 879 uint16_t cmd;880 881 uint32_t ofs; 881 882 … … 885 886 ofs = 0x10 + region_num * 4; 886 887 887 /* Read memory type first. */ 888 uint8_t uRessourceType = pci_config_readb(pGlobals, uBus, uDevFn, ofs); 889 890 /* Read command register. */ 891 cmd = pci_config_readw(pGlobals, uBus, uDevFn, PCI_COMMAND); 892 if ( region_num == PCI_ROM_SLOT ) 893 cmd |= 2; 894 else if ((uRessourceType & 0x01) == 1) /* Test if region is I/O space. */ 895 cmd |= 1; /* Enable I/O space access. */ 896 else /* The region is MMIO. */ 897 cmd |= 2; /* Enable MMIO access. */ 888 Log(("Set region address: %02x:%02x.%d region %d address=%lld\n", 889 uBus, uDevFn >> 3, uDevFn & 7, region_num, addr)); 898 890 899 891 /* Write address of the device. */ 900 892 pci_config_writel(pGlobals, uBus, uDevFn, ofs, addr); 901 902 /* enable memory mappings */903 pci_config_writew(pGlobals, uBus, uDevFn, PCI_COMMAND, cmd);904 893 } 905 894 … … 935 924 pci_set_io_region_addr(pGlobals, uBus, uDevFn, 2, 0x170); 936 925 pci_set_io_region_addr(pGlobals, uBus, uDevFn, 3, 0x374); 926 pci_config_writeb(pGlobals, uBus, uDevFn, PCI_COMMAND, 927 pci_config_readb(pGlobals, uBus, uDevFn, PCI_COMMAND) 928 | PCI_COMMAND_IOACCESS); 937 929 } 938 930 break; … … 945 937 * Legacy VGA I/O ports are implicitly decoded by a VGA class device. But 946 938 * only the framebuffer (i.e., a memory region) is explicitly registered via 947 * pci_set_io_region_addr, so I/O decoding must be enabled manually.939 * pci_set_io_region_addr, so don't forget to enable I/O decoding. 948 940 */ 949 941 pci_config_writeb(pGlobals, uBus, uDevFn, PCI_COMMAND, 950 942 pci_config_readb(pGlobals, uBus, uDevFn, PCI_COMMAND) 951 | 1 /* Enable I/O space access. */);943 | PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS); 952 944 break; 953 945 case 0x0800: … … 962 954 /* MPIC & MPIC2 */ 963 955 pci_set_io_region_addr(pGlobals, uBus, uDevFn, 0, 0x80800000 + 0x00040000); 956 pci_config_writeb(pGlobals, uBus, uDevFn, PCI_COMMAND, 957 pci_config_readb(pGlobals, uBus, uDevFn, PCI_COMMAND) 958 | PCI_COMMAND_MEMACCESS); 964 959 } 965 960 } … … 971 966 /* macio bridge */ 972 967 pci_set_io_region_addr(pGlobals, uBus, uDevFn, 0, 0x80800000); 968 pci_config_writeb(pGlobals, uBus, uDevFn, PCI_COMMAND, 969 pci_config_readb(pGlobals, uBus, uDevFn, PCI_COMMAND) 970 | PCI_COMMAND_MEMACCESS); 973 971 } 974 972 break; … … 1049 1047 { 1050 1048 /* default memory mappings */ 1049 bool fActiveMemRegion = false; 1050 bool fActiveIORegion = false; 1051 1051 /* 1052 1052 * PCI_NUM_REGIONS is 7 because of the rom region but there are only 6 base address register defined by the PCI spec. … … 1063 1063 pci_config_writel(pGlobals, uBus, uDevFn, u32Address, UINT32_C(0xffffffff)); 1064 1064 u32Size = pci_config_readl(pGlobals, uBus, uDevFn, u32Address); 1065 bool fIsPio = ((u8RessourceType & PCI_COMMAND_IOACCESS) == PCI_COMMAND_IOACCESS); 1065 1066 /* Clear resource information depending on resource type. */ 1066 if ( (u8RessourceType & 0x01) == 1) /* I/O */1067 if (fIsPio) /* I/O */ 1067 1068 u32Size &= ~(0x01); 1068 1069 else /* MMIO */ … … 1073 1074 * (From PCI implementation note) 1074 1075 */ 1075 if ( ((u8RessourceType & 0x01) == 1)&& (u32Size & UINT32_C(0xffff0000)) == 0)1076 if (fIsPio && (u32Size & UINT32_C(0xffff0000)) == 0) 1076 1077 u32Size = (~(u32Size | UINT32_C(0xffff0000))) + 1; 1077 1078 else 1078 1079 u32Size = (~u32Size) + 1; 1079 1080 1080 Log (("%s: Size of region %u for device %d on bus %d is %u\n", __FUNCTION__, i, uDevFn, uBus, u32Size));1081 Log2(("%s: Size of region %u for device %d on bus %d is %u\n", __FUNCTION__, i, uDevFn, uBus, u32Size)); 1081 1082 1082 1083 if (u32Size) 1083 1084 { 1084 if ( (u8RessourceType & 0x01) == 1)1085 if (fIsPio) 1085 1086 paddr = &pGlobals->pci_bios_io_addr; 1086 1087 else 1087 1088 paddr = &pGlobals->pci_bios_mem_addr; 1088 *paddr = (*paddr + u32Size - 1) & ~(u32Size - 1); 1089 Log(("%s: Start address of %s region %u is %#x\n", __FUNCTION__, ((u8RessourceType & 0x01) == 1 ? "I/O" : "MMIO"), i, *paddr)); 1090 pci_set_io_region_addr(pGlobals, uBus, uDevFn, i, *paddr); 1091 *paddr += u32Size; 1092 Log(("%s: New address is %#x\n", __FUNCTION__, *paddr)); 1089 uint32_t uNew = *paddr; 1090 uNew = (uNew + u32Size - 1) & ~(u32Size - 1); 1091 if (fIsPio) 1092 uNew &= UINT32_C(0xffff); 1093 /* Unconditionally exclude I/O-APIC/HPET/ROM. Pessimistic, but better than causing a mess. */ 1094 if (!uNew || (uNew <= UINT32_C(0xffffffff) && uNew + u32Size - 1 >= UINT32_C(0xfec00000))) 1095 { 1096 LogRel(("PCI: no space left for BAR%u of device %u/%u/%u (vendor=%#06x device=%#06x)\n", 1097 i, uBus, uDevFn >> 3, uDevFn & 7, vendor_id, device_id)); /** @todo make this a VM start failure later. */ 1098 /* Undo the mapping mess caused by the size probing. */ 1099 pci_config_writel(pGlobals, uBus, uDevFn, u32Address, UINT32_C(0)); 1100 } 1101 else 1102 { 1103 Log(("%s: Start address of %s region %u is %#x\n", __FUNCTION__, (fIsPio ? "I/O" : "MMIO"), i, uNew)); 1104 pci_set_io_region_addr(pGlobals, uBus, uDevFn, i, uNew); 1105 if (fIsPio) 1106 fActiveIORegion = true; 1107 else 1108 fActiveMemRegion = true; 1109 *paddr = uNew + u32Size; 1110 Log2(("%s: New address is %#x\n", __FUNCTION__, *paddr)); 1111 } 1093 1112 } 1094 1113 } 1114 1115 /* Update the command word appropriately. */ 1116 pci_config_writeb(pGlobals, uBus, uDevFn, PCI_COMMAND, 1117 pci_config_readb(pGlobals, uBus, uDevFn, PCI_COMMAND) 1118 | (fActiveMemRegion ? PCI_COMMAND_MEMACCESS : 0) 1119 | (fActiveIORegion ? PCI_COMMAND_IOACCESS : 0)); 1120 1095 1121 break; 1096 1122 } -
trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
r57393 r57781 894 894 { 895 895 uNew |= ((uint64_t)ich9pciGetDWord(pDev, uConfigReg+4)) << 32; 896 /** @todo r=klaus Is this really true? Needs to be fixed properly. */ 896 897 if (uNew > UINT64_C(0x0000010000000000)) 897 898 { 898 /* Workaround for REM being unhapping with mapping very l ange64-bit addresses */899 Log (("Ignoring too64-bit BAR: %llx\n", uNew));899 /* Workaround for REM being unhapping with mapping very long 64-bit addresses */ 900 LogRel(("Ignoring too long 64-bit BAR: %llx\n", uNew)); 900 901 uNew = INVALID_PCI_ADDRESS; 901 902 } … … 913 914 mappings, we handle specific values as invalid 914 915 mappings. */ 915 if (uLast <= uNew || uNew == 0 || uLast == INVALID_PCI_ADDRESS) 916 /* Unconditionally exclude I/O-APIC/HPET/ROM. Pessimistic, but better than causing a mess. */ 917 if (uLast <= uNew || uNew == 0 || (uNew <= UINT32_C(0xffffffff) && uLast >= UINT32_C(0xfec00000))) 916 918 uNew = INVALID_PCI_ADDRESS; 917 919 } … … 919 921 uNew = INVALID_PCI_ADDRESS; 920 922 } 923 //LogRel(("PCI: config dev %u/%u BAR%i uOld=%#018llx uNew=%#018llx size=%llu\n", pDev->devfn >> 3, pDev->devfn & 7, iRegion, pRegion->addr, uNew, pRegion->size)); 921 924 /* now do the real mapping */ 922 925 if (uNew != pRegion->addr) … … 936 939 } 937 940 } 941 942 if (f64Bit) 943 iRegion++; 938 944 } 939 945 } … … 1614 1620 /* Read memory type first. */ 1615 1621 uint8_t uResourceType = ich9pciConfigRead(pGlobals, uBus, uDevFn, uReg, 1); 1616 /* Read command register. */1617 uint16_t uCmd = ich9pciConfigRead(pGlobals, uBus, uDevFn, VBOX_PCI_COMMAND, 2);1618 1622 1619 1623 Log(("Set region address: %02x:%02x.%d region %d address=%lld\n", 1620 1624 uBus, uDevFn >> 3, uDevFn & 7, iRegion, addr)); 1621 1622 if ( iRegion == PCI_ROM_SLOT )1623 uCmd |= PCI_COMMAND_MEMACCESS;1624 else if ((uResourceType & PCI_ADDRESS_SPACE_IO) == PCI_ADDRESS_SPACE_IO)1625 uCmd |= PCI_COMMAND_IOACCESS; /* Enable I/O space access. */1626 else /* The region is MMIO. */1627 uCmd |= PCI_COMMAND_MEMACCESS; /* Enable MMIO access. */1628 1625 1629 1626 bool f64Bit = (uResourceType & PCI_ADDRESS_SPACE_BAR64) != 0; … … 1633 1630 if (f64Bit) 1634 1631 ich9pciConfigWrite(pGlobals, uBus, uDevFn, uReg + 4, (uint32_t)(addr >> 32), 4); 1635 1636 /* enable memory mappings */1637 ich9pciConfigWrite(pGlobals, uBus, uDevFn, VBOX_PCI_COMMAND, uCmd, 2);1638 1632 } 1639 1633 … … 1737 1731 * Legacy VGA I/O ports are implicitly decoded by a VGA class device. But 1738 1732 * only the framebuffer (i.e., a memory region) is explicitly registered via 1739 * ich9pciSetRegionAddress, so I/O decoding must be enabled manually.1733 * ich9pciSetRegionAddress, so don't forget to enable I/O decoding. 1740 1734 */ 1741 1735 uCmd = ich9pciConfigRead(pGlobals, uBus, uDevFn, VBOX_PCI_COMMAND, 1); 1742 1736 ich9pciConfigWrite(pGlobals, uBus, uDevFn, VBOX_PCI_COMMAND, 1743 /* Enable I/O space access. */ 1744 uCmd | PCI_COMMAND_IOACCESS, 1737 uCmd | PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS, 1745 1738 1); 1746 1739 break; 1747 case 0x0604:1740 case 0x0604: 1748 1741 /* PCI-to-PCI bridge. */ 1749 1742 AssertMsg(pGlobals->uBus < 255, ("Too many bridges on the bus\n")); … … 1754 1747 { 1755 1748 /* default memory mappings */ 1749 bool fActiveMemRegion = false; 1750 bool fActiveIORegion = false; 1756 1751 /* 1757 1752 * We ignore ROM region here. … … 1762 1757 1763 1758 /* Calculate size - we write all 1s into the BAR, and then evaluate which bits 1764 are cleared. .*/1759 are cleared. */ 1765 1760 uint8_t u8ResourceType = ich9pciConfigRead(pGlobals, uBus, uDevFn, u32Address, 1); 1766 1761 … … 1813 1808 if (cbRegSize64) 1814 1809 { 1810 /** @todo r=klaus make this code actually handle 64-bit BARs, especially MMIO which can't possibly fit into the memory hole. */ 1815 1811 uint32_t cbRegSize32 = (uint32_t)cbRegSize64; 1816 1812 uint32_t* paddr = fIsPio ? &pGlobals->uPciBiosIo : &pGlobals->uPciBiosMmio; 1817 *paddr = (*paddr + cbRegSize32 - 1) & ~(cbRegSize32 - 1); 1818 Log(("%s: Start address of %s region %u is %#x\n", __FUNCTION__, (fIsPio ? "I/O" : "MMIO"), iRegion, *paddr)); 1819 ich9pciSetRegionAddress(pGlobals, uBus, uDevFn, iRegion, *paddr); 1820 *paddr += cbRegSize32; 1821 Log2(("%s: New address is %#x\n", __FUNCTION__, *paddr)); 1813 uint32_t uNew = *paddr; 1814 uNew = (uNew + cbRegSize32 - 1) & ~(cbRegSize32 - 1); 1815 if (fIsPio) 1816 uNew &= UINT32_C(0xffff); 1817 /* Unconditionally exclude I/O-APIC/HPET/ROM. Pessimistic, but better than causing a mess. */ 1818 if (!uNew || (uNew <= UINT32_C(0xffffffff) && uNew + cbRegSize32 - 1 >= UINT32_C(0xfec00000))) 1819 { 1820 LogRel(("PCI: no space left for BAR%u of device %u/%u/%u (vendor=%#06x device=%#06x)\n", 1821 iRegion, uBus, uDevFn >> 3, uDevFn & 7, uVendor, uDevice)); /** @todo make this a VM start failure later. */ 1822 /* Undo the mapping mess caused by the size probing. */ 1823 ich9pciConfigWrite(pGlobals, uBus, uDevFn, u32Address, UINT32_C(0), 4); 1824 if (f64bit) 1825 ich9pciConfigWrite(pGlobals, uBus, uDevFn, u32Address+4, UINT32_C(0), 4); 1826 } 1827 else 1828 { 1829 Log(("%s: Start address of %s region %u is %#x\n", __FUNCTION__, (fIsPio ? "I/O" : "MMIO"), iRegion, uNew)); 1830 ich9pciSetRegionAddress(pGlobals, uBus, uDevFn, iRegion, uNew); 1831 if (fIsPio) 1832 fActiveIORegion = true; 1833 else 1834 fActiveMemRegion = true; 1835 *paddr = uNew + cbRegSize32; 1836 Log2(("%s: New address is %#x\n", __FUNCTION__, *paddr)); 1837 } 1822 1838 1823 1839 if (f64bit) … … 1825 1841 } 1826 1842 } 1843 1844 /* Update the command word appropriately. */ 1845 uCmd = ich9pciConfigRead(pGlobals, uBus, uDevFn, VBOX_PCI_COMMAND, 2); 1846 if (fActiveMemRegion) 1847 uCmd |= PCI_COMMAND_MEMACCESS; /* Enable MMIO access. */ 1848 if (fActiveIORegion) 1849 uCmd |= PCI_COMMAND_IOACCESS; /* Enable I/O space access. */ 1850 ich9pciConfigWrite(pGlobals, uBus, uDevFn, VBOX_PCI_COMMAND, uCmd, 2); 1827 1851 break; 1828 1852 }
Note:
See TracChangeset
for help on using the changeset viewer.