VirtualBox

Changeset 33722 in vbox


Ignore:
Timestamp:
Nov 3, 2010 12:56:43 PM (14 years ago)
Author:
vboxsync
Message:

Main, PCI: uniform PCI slots management, please watch/report regressions

Location:
trunk/src/VBox
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Bus/DevPciIch9.cpp

    r33687 r33722  
    19641964    int32_t     iFunction;
    19651965} PciSlotAssignments[] = {
    1966     /* Due to somewhat inflexible PCI bus configuration, ConsoleImpl hardcodes 0:5:0 as HDA address, so we shalln't put elsewhere */
    1967 #if 0
    1968     {
    1969         "lan",      25, 0 /* LAN controller */
    1970     },
    1971     {
    1972         "hda",      27, 0 /* High Definition Audio */
    1973     },
    1974 #endif
     1966    /* The only override that have to be here, as host controller is added in the way invisible to bus slot assignment management,
     1967       maybe to be changed in the future. */
    19751968    {
    19761969        "i82801",   30, 0 /* Host Controller */
    1977     },
    1978     /**
    1979      *  Please note, that for devices being functions, like we do here, device 0
    1980      *  must be multifunction, i.e. have header type 0x80. Our LPC device is.
    1981      *  Alternative approach is to assign separate slot to each device.
    1982      */
    1983     {
    1984         "lpc",      31, 0 /* Low Pin Count bus */
    1985     },
    1986     {
    1987         "piix3ide", 31, 1 /* IDE controller */
    1988     },
    1989     /* Disable, if we may wish to have multiple AHCI controllers */
    1990     {
    1991         "ahci",     31, 2 /* SATA controller */
    1992     },
    1993     {
    1994         "smbus",    31, 3 /* System Management Bus */
    1995     },
    1996     {
    1997         "usb-ohci", 31, 4 /* OHCI USB controller */
    1998     },
    1999     {
    2000         "usb-ehci", 31, 5 /* EHCI USB controller */
    2001     },
    2002     {
    2003         "thermal",  31, 6 /* Thermal controller */
    20041970    },
    20051971};
  • trunk/src/VBox/Main/BusAssignmentManager.cpp

    r33690 r33722  
    2525#include <map>
    2626#include <vector>
     27#include <algorithm>
     28
     29struct DeviceAssignmentRule
     30{
     31    const char* pszName;
     32    int         iBus;
     33    int         iDevice;
     34    int         iFn;
     35    int         iPriority;
     36};
     37
     38struct DeviceAliasRule
     39{
     40    const char* pszDevName;
     41    const char* pszDevAlias;
     42};
     43
     44/* Those rules define PCI slots assignment */
     45
     46/* Generic rules */
     47static const DeviceAssignmentRule aGenericRules[] =
     48{
     49    /* VGA controller */
     50    {"vga",           0,  2, 0,  0},
     51
     52    /* VMM device */
     53    {"VMMDev",        0,  4, 0,  0},
     54
     55    /* Audio controllers */
     56    {"ichac97",       0,  5, 0,  0},
     57    {"hda",           0,  5, 0,  0},
     58
     59    /* Storage controllers */
     60    {"ahci",          0, 13, 0,  0},
     61    {"lsilogic",      0, 20, 0,  0},
     62    {"buslogic",      0, 21, 0,  0},
     63    {"lsilogicsas",   0, 22, 0,  0},
     64
     65    /* USB controllers */
     66    {"usb-ohci",      0,  6,  0, 0},
     67    {"usb-ehci",      0, 11,  0, 0},
     68
     69    /* ACPI controller */
     70    {"acpi",          0,  7,  0, 0},
     71
     72
     73    /* Network controllers */
     74    /* the first network card gets the PCI ID 3, the next 3 gets 8..10,
     75     * next 4 get 16..19. */
     76    {"nic",           0,  3,  0, 0},
     77    {"nic",           0,  8,  0, 0},
     78    {"nic",           0,  9,  0, 0},
     79    {"nic",           0, 10,  0, 0},
     80    {"nic",           0, 16,  0, 0},
     81    {"nic",           0, 17,  0, 0},
     82    {"nic",           0, 18,  0, 0},
     83    {"nic",           0, 19,  0, 0},
     84    /* VMWare assigns first NIC to slot 11 */
     85    {"nic-vmware",    0, 11,  0, 0},
     86
     87    /* ISA/LPC controller */
     88    {"lpc",           0, 31,  0, 0},
     89
     90    { NULL,          -1, -1, -1,  0}
     91};
     92
     93/* PIIX3 chipset rules */
     94static const DeviceAssignmentRule aPiix3Rules[] =
     95{
     96    {"piix3ide",      0,  1,  1, 0},
     97    {"pcibridge",     0, 24,  0, 0},
     98    {"pcibridge",     0, 25,  0, 0},
     99    { NULL,          -1, -1, -1, 0}
     100};
     101
     102
     103/* ICH9 chipset rules */
     104static const DeviceAssignmentRule aIch9Rules[] =
     105{
     106    /* Host Controller */
     107    {"i82801",        0, 30, 0,  0},
     108
     109    /* Those are functions of LPC at 00:1e:00 */
     110    /**
     111     *  Please note, that for devices being functions, like we do here, device 0
     112     *  must be multifunction, i.e. have header type 0x80. Our LPC device is.
     113     *  Alternative approach is to assign separate slot to each device.
     114     */
     115    {"piix3ide",      0, 31, 1,  1},
     116    {"ahci",          0, 31, 2,  1},
     117    {"smbus",         0, 31, 3,  1},
     118    {"usb-ohci",      0, 31, 4,  1},
     119    {"usb-ehci",      0, 31, 5,  1},
     120    {"thermal",       0, 31, 6,  1},
     121
     122    /* ths rule has lower priority than generic one */
     123    {"lsilogic",      1, 20, 0,  -1},
     124    {"lsilogic",      1, 20, 0,  -1},
     125
     126    /* to make sure rule never used before rules assigning devices on it */
     127    {"ich9pcibridge", 0, 24, 0,  10},
     128    {"ich9pcibridge", 0, 25, 0,  10},
     129    {"ich9pcibridge", 1, 24, 0,   5},
     130    {"ich9pcibridge", 1, 25, 0,   5},
     131    { NULL,          -1, -1, -1,  0}
     132};
     133
     134/* Aliasing rules */
     135static const DeviceAliasRule aDeviceAliases[] =
     136{
     137    {"e1000",      "nic"},
     138    {"pcnet",      "nic"},
     139    {"virtio-net", "nic"}
     140};
    27141
    28142struct BusAssignmentManager::State
     
    50164    typedef std::map <PciBusAddress,PciDeviceRecord > PciMap;
    51165    typedef std::vector<PciBusAddress>                PciAddrList;
     166    typedef std::vector<const DeviceAssignmentRule*>  PciRulesList;
     167
    52168    typedef std::map <PciDeviceRecord,PciAddrList >   ReversePciMap;
    53169
     
    69185    bool    checkAvailable(PciBusAddress& Address);
    70186    bool    findPciAddress(const char* pszDevName, int iInstance, PciBusAddress& Address);
     187
     188    const char* findAlias(const char* pszName);
     189    void addMatchingRules(const char* pszName, PciRulesList& aList);
    71190};
    72191
     
    76195    return S_OK;
    77196}
    78 
    79197
    80198HRESULT BusAssignmentManager::State::record(const char* pszName, PciBusAddress& Address)
     
    113231}
    114232
     233void BusAssignmentManager::State::addMatchingRules(const char* pszName, PciRulesList& aList)
     234{
     235    size_t iRuleset, iRule;
     236    const DeviceAssignmentRule* aArrays[2] = {aGenericRules, NULL};
     237
     238    switch (mChipsetType)
     239    {
     240        case ChipsetType_PIIX3:
     241            aArrays[1] = aPiix3Rules;
     242            break;
     243        case ChipsetType_ICH9:
     244            aArrays[1] = aIch9Rules;
     245            break;
     246        default:
     247            Assert(false);
     248            break;
     249    }
     250
     251    for (iRuleset = 0; iRuleset < RT_ELEMENTS(aArrays); iRuleset++)
     252    {
     253        if (aArrays[iRuleset] == NULL)
     254            continue;
     255
     256        for (iRule = 0; aArrays[iRuleset][iRule].pszName != NULL; iRule++)
     257        {
     258            if (strcmp(pszName, aArrays[iRuleset][iRule].pszName) == 0)
     259                aList.push_back(&aArrays[iRuleset][iRule]);
     260        }
     261    }
     262}
     263
     264const char* BusAssignmentManager::State::findAlias(const char* pszDev)
     265{
     266    for (size_t iAlias = 0; iAlias < RT_ELEMENTS(aDeviceAliases); iAlias++)
     267    {
     268        if (strcmp(pszDev, aDeviceAliases[iAlias].pszDevName) == 0)
     269            return aDeviceAliases[iAlias].pszDevAlias;
     270    }
     271    return NULL;
     272}
     273
     274static bool  RuleComparator(const DeviceAssignmentRule* r1, const DeviceAssignmentRule* r2)
     275{
     276    return (r1->iPriority > r2->iPriority);
     277}
     278
    115279HRESULT BusAssignmentManager::State::autoAssign(const char* pszName, PciBusAddress& Address)
    116280{
    117     // unimplemented yet
    118     Assert(false);
    119     return S_OK;
     281    PciRulesList matchingRules;
     282
     283    addMatchingRules(pszName,  matchingRules);
     284    const char* pszAlias = findAlias(pszName);
     285    if (pszAlias)
     286        addMatchingRules(pszAlias, matchingRules);
     287
     288    AssertMsg(matchingRules.size() > 0, ("No rule for %s(%s)\n", pszName, pszAlias));
     289
     290    sort(matchingRules.begin(), matchingRules.end(), RuleComparator);
     291
     292    for (size_t iRule = 0; iRule < matchingRules.size(); iRule++)
     293    {
     294        const DeviceAssignmentRule* rule = matchingRules[iRule];
     295
     296        Address.iBus = rule->iBus;
     297        Address.iDevice = rule->iDevice;
     298        Address.iFn = rule->iFn;
     299
     300        if (checkAvailable(Address))
     301            return S_OK;
     302    }
     303    AssertMsg(false, ("All possible candidate positions for %s exhausted\n", pszName));
     304
     305    return E_INVALIDARG;
    120306}
    121307
     
    202388        return rc;
    203389
    204     Assert(Address.valid());
     390    Assert(Address.valid() && pState->checkAvailable(Address));
    205391
    206392    rc = pState->record(pszDevName, Address);
  • trunk/src/VBox/Main/ConsoleImpl2.cpp

    r33718 r33722  
    882882            InsertConfigNode(pDev,     "0", &pInst);
    883883            InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
    884             PciAddr = PciBusAddress(0, 24, 0);
    885             hrc = BusMgr->assignPciDevice("ich9pcibridge", pInst, PciAddr);                               H();
     884            hrc = BusMgr->assignPciDevice("ich9pcibridge", pInst);                               H();
    886885
    887886            InsertConfigNode(pDev,     "1", &pInst);
    888887            InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
    889             PciAddr = PciBusAddress(0, 25, 0);
    890             hrc = BusMgr->assignPciDevice("ich9pcibridge", pInst, PciAddr);                               H();
     888            hrc = BusMgr->assignPciDevice("ich9pcibridge", pInst);                               H();
    891889        }
    892890
     
    966964            InsertConfigNode(pDevices, "lpc", &pDev);
    967965            InsertConfigNode(pDev,     "0", &pInst);
    968 #if 0
    969             PciAddr = PciBusAddress(0, 31, 0);
    970966            hrc = BusMgr->assignPciDevice("lpc", pInst);                               H();
    971 #endif
    972967            InsertConfigInteger(pInst, "Trusted",   1); /* boolean */
    973968        }
     
    10611056        InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
    10621057
    1063         PciAddr = PciBusAddress(0, 2, 0);
    1064         hrc = BusMgr->assignPciDevice("vga", pInst, PciAddr);                               H();
     1058        hrc = BusMgr->assignPciDevice("vga", pInst);                               H();
    10651059        InsertConfigNode(pInst,    "Config", &pCfg);
    10661060        ULONG cVRamMBs;
     
    13291323                case StorageControllerType_LsiLogic:
    13301324                {
    1331                     PciAddr = PciBusAddress(1, 20, 0);
    1332                     hrc = BusMgr->assignPciDevice("lsilogic", pCtlInst, PciAddr);                               H();
     1325                    hrc = BusMgr->assignPciDevice("lsilogic", pCtlInst);                               H();
    13331326
    13341327
     
    13471340                case StorageControllerType_BusLogic:
    13481341                {
    1349                     PciAddr = PciBusAddress(0, 21, 0);
    1350                     hrc = BusMgr->assignPciDevice("buslogic", pCtlInst, PciAddr);                               H();
     1342                    hrc = BusMgr->assignPciDevice("buslogic", pCtlInst);                               H();
    13511343
    13521344                    /* Attach the status driver */
     
    13641356                case StorageControllerType_IntelAhci:
    13651357                {
    1366                     PciAddr = PciBusAddress(0, 13, 0);
    1367                     hrc = BusMgr->assignPciDevice("ahci", pCtlInst, PciAddr);                               H();
     1358                    hrc = BusMgr->assignPciDevice("ahci", pCtlInst);                               H();
    13681359
    13691360                    ULONG cPorts = 0;
     
    14101401                     * IDE (update this when the main interface changes)
    14111402                     */
    1412                     PciAddr = PciBusAddress(0, 1, 1);
    1413                     hrc = BusMgr->assignPciDevice("ide", pCtlInst, PciAddr);                               H();
     1403                    hrc = BusMgr->assignPciDevice("piix3ide", pCtlInst);                               H();
    14141404                    InsertConfigString(pCfg,   "Type", controllerString(enmCtrlType));
    14151405
     
    14561446                case StorageControllerType_LsiLogicSas:
    14571447                {
    1458                     PciAddr = PciBusAddress(0, 22, 0);
    1459                     hrc = BusMgr->assignPciDevice("lsilogicsas", pCtlInst, PciAddr);                               H();
     1448                    hrc = BusMgr->assignPciDevice("lsilogicsas", pCtlInst);                               H();
    14601449
    14611450                    InsertConfigString(pCfg,  "ControllerType", "SAS1068");
     
    18181807        InsertConfigNode(pInst,    "Config", &pCfg);
    18191808        InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
    1820         PciAddr = PciBusAddress(0, 4, 0);
    1821         hrc = BusMgr->assignPciDevice("VMMDev", pInst, PciAddr);                               H();
     1809        hrc = BusMgr->assignPciDevice("VMMDev", pInst);                               H();
    18221810
    18231811        Bstr hwVersion;
     
    18811869                    InsertConfigNode(pDev,     "0", &pInst);
    18821870                    InsertConfigInteger(pInst, "Trusted",          1); /* boolean */
    1883                     PciAddr = PciBusAddress(0, 5, 0);
    1884                     hrc = BusMgr->assignPciDevice("ichac97", pInst, PciAddr);                               H();
     1871                    hrc = BusMgr->assignPciDevice("ichac97", pInst);                               H();
    18851872                    InsertConfigNode(pInst,    "Config", &pCfg);
    18861873                    break;
     
    19061893                    InsertConfigNode(pDev,     "0", &pInst);
    19071894                    InsertConfigInteger(pInst, "Trusted",          1); /* boolean */
    1908                     PciAddr = PciBusAddress(0, 5, 0);
    1909                     hrc = BusMgr->assignPciDevice("hda", pInst, PciAddr);                               H();
     1895                    hrc = BusMgr->assignPciDevice("hda", pInst);                               H();
    19101896                    InsertConfigNode(pInst,    "Config", &pCfg);
    19111897                }
     
    20061992                InsertConfigNode(pInst,    "Config", &pCfg);
    20071993                InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
    2008                 PciAddr = PciBusAddress(0, 6, 0);
    2009                 hrc = BusMgr->assignPciDevice("usb-ohci", pInst, PciAddr);                               H();
     1994                hrc = BusMgr->assignPciDevice("usb-ohci", pInst);                           H();
    20101995                InsertConfigNode(pInst,    "LUN#0", &pLunL0);
    20111996                InsertConfigString(pLunL0, "Driver",               "VUSBRootHub");
     
    20312016                    InsertConfigNode(pInst,    "Config", &pCfg);
    20322017                    InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
    2033                     PciAddr = PciBusAddress(0, 11, 0);
    2034                     hrc = BusMgr->assignPciDevice("usb-ohci", pInst, PciAddr);                               H();
     2018                    hrc = BusMgr->assignPciDevice("usb-ehci", pInst);                               H();
    20352019
    20362020                    InsertConfigNode(pInst,    "LUN#0", &pLunL0);
     
    22912275            InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
    22922276            InsertConfigNode(pInst,    "Config", &pCfg);
    2293             PciAddr = PciBusAddress(0, 7, 0);
    2294             hrc = BusMgr->assignPciDevice("acpi", pInst, PciAddr);                               H();
     2277            hrc = BusMgr->assignPciDevice("acpi", pInst);                               H();
    22952278
    22962279            InsertConfigInteger(pCfg,  "RamSize",          cbRam);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette