/* $Id$ */
/** @file
*
* VirtualBox bus slots assignment manager
*/
/*
* Copyright (C) 2010-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#include "BusAssignmentManager.h"
#include "PCIDeviceAttachmentImpl.h"
#include <map>
#include <vector>
#include <algorithm>
struct DeviceAssignmentRule
{
const char* pszName;
int iBus;
int iDevice;
int iFn;
int iPriority;
};
struct DeviceAliasRule
{
const char* pszDevName;
const char* pszDevAlias;
};
/* Those rules define PCI slots assignment */
/* Device Bus Device Function Priority */
/* Generic rules */
{
/* VGA controller */
{"vga", 0, 2, 0, 0},
/* VMM device */
{"VMMDev", 0, 4, 0, 0},
/* Audio controllers */
{"ichac97", 0, 5, 0, 0},
{"hda", 0, 5, 0, 0},
/* Storage controllers */
{"lsilogic", 0, 20, 0, 1},
{"buslogic", 0, 21, 0, 1},
{"lsilogicsas", 0, 22, 0, 1},
/* USB controllers */
{"usb-ohci", 0, 6, 0, 0},
{"usb-ehci", 0, 11, 0, 0},
{"usb-xhci", 0, 12, 0, 0},
/* ACPI controller */
{"acpi", 0, 7, 0, 0},
/* Network controllers */
/* the first network card gets the PCI ID 3, the next 3 gets 8..10,
* next 4 get 16..19. In "VMWare compatibility" mode the IDs 3 and 17
* swap places, i.e. the first card goes to ID 17=0x11. */
{"nic", 0, 3, 0, 1},
{"nic", 0, 8, 0, 1},
{"nic", 0, 9, 0, 1},
{"nic", 0, 10, 0, 1},
{"nic", 0, 16, 0, 1},
{"nic", 0, 17, 0, 1},
{"nic", 0, 18, 0, 1},
{"nic", 0, 19, 0, 1},
{"lpc", 0, 31, 0, 0},
};
/* PIIX3 chipset rules */
{
{"piix3ide", 0, 1, 1, 0},
{"ahci", 0, 13, 0, 1},
{"pcibridge", 0, 24, 0, 0},
{"pcibridge", 0, 25, 0, 0},
};
/* ICH9 chipset rules */
{
/* Host Controller */
{"i82801", 0, 30, 0, 0},
/* Those are functions of LPC at 00:1e:00 */
/**
* Please note, that for devices being functions, like we do here, device 0
* must be multifunction, i.e. have header type 0x80. Our LPC device is.
* Alternative approach is to assign separate slot to each device.
*/
{"piix3ide", 0, 31, 1, 2},
{"ahci", 0, 31, 2, 2},
{"smbus", 0, 31, 3, 2},
{"usb-ohci", 0, 31, 4, 2},
{"usb-ehci", 0, 31, 5, 2},
{"thermal", 0, 31, 6, 2},
/* to make sure rule never used before rules assigning devices on it */
{"ich9pcibridge", 0, 24, 0, 10},
{"ich9pcibridge", 0, 25, 0, 10},
{"ich9pcibridge", 1, 24, 0, 9},
{"ich9pcibridge", 1, 25, 0, 9},
{"ich9pcibridge", 2, 24, 0, 8},
{"ich9pcibridge", 2, 25, 0, 8},
{"ich9pcibridge", 3, 24, 0, 7},
{"ich9pcibridge", 3, 25, 0, 7},
{"ich9pcibridge", 4, 24, 0, 6},
{"ich9pcibridge", 4, 25, 0, 6},
{"ich9pcibridge", 5, 24, 0, 5},
{"ich9pcibridge", 5, 25, 0, 5},
/* Storage controllers */
{"ahci", 1, 0, 0, 0},
{"ahci", 1, 1, 0, 0},
{"ahci", 1, 2, 0, 0},
{"ahci", 1, 3, 0, 0},
{"ahci", 1, 4, 0, 0},
{"ahci", 1, 5, 0, 0},
{"ahci", 1, 6, 0, 0},
{"lsilogic", 1, 7, 0, 0},
{"lsilogic", 1, 8, 0, 0},
{"lsilogic", 1, 9, 0, 0},
{"lsilogic", 1, 10, 0, 0},
{"lsilogic", 1, 11, 0, 0},
{"lsilogic", 1, 12, 0, 0},
{"lsilogic", 1, 13, 0, 0},
{"buslogic", 1, 14, 0, 0},
{"buslogic", 1, 15, 0, 0},
{"buslogic", 1, 16, 0, 0},
{"buslogic", 1, 17, 0, 0},
{"buslogic", 1, 18, 0, 0},
{"buslogic", 1, 19, 0, 0},
{"buslogic", 1, 20, 0, 0},
{"lsilogicsas", 1, 21, 0, 0},
{"lsilogicsas", 1, 26, 0, 0},
{"lsilogicsas", 1, 27, 0, 0},
{"lsilogicsas", 1, 28, 0, 0},
{"lsilogicsas", 1, 29, 0, 0},
{"lsilogicsas", 1, 30, 0, 0},
{"lsilogicsas", 1, 31, 0, 0},
/* NICs */
{"nic", 2, 0, 0, 0},
{"nic", 2, 1, 0, 0},
{"nic", 2, 2, 0, 0},
{"nic", 2, 3, 0, 0},
{"nic", 2, 4, 0, 0},
{"nic", 2, 5, 0, 0},
{"nic", 2, 6, 0, 0},
{"nic", 2, 7, 0, 0},
{"nic", 2, 8, 0, 0},
{"nic", 2, 9, 0, 0},
{"nic", 2, 10, 0, 0},
{"nic", 2, 11, 0, 0},
{"nic", 2, 12, 0, 0},
{"nic", 2, 13, 0, 0},
{"nic", 2, 14, 0, 0},
{"nic", 2, 15, 0, 0},
{"nic", 2, 16, 0, 0},
{"nic", 2, 17, 0, 0},
{"nic", 2, 18, 0, 0},
{"nic", 2, 19, 0, 0},
{"nic", 2, 20, 0, 0},
{"nic", 2, 21, 0, 0},
{"nic", 2, 26, 0, 0},
{"nic", 2, 27, 0, 0},
{"nic", 2, 28, 0, 0},
{"nic", 2, 29, 0, 0},
{"nic", 2, 30, 0, 0},
{"nic", 2, 31, 0, 0},
};
/* Aliasing rules */
{
{"e1000", "nic"},
{"pcnet", "nic"},
{"virtio-net", "nic"},
{"ahci", "storage"},
{"lsilogic", "storage"},
{"buslogic", "storage"},
{"lsilogicsas", "storage"}
};
{
struct PCIDeviceRecord
{
{
this->HostAddress = aHostAddress;
}
{
}
bool operator<(const PCIDeviceRecord &a) const
{
}
bool operator==(const PCIDeviceRecord &a) const
{
}
};
State()
{}
~State()
{}
};
{
return S_OK;
}
HRESULT BusAssignmentManager::State::record(const char* pszName, PCIBusAddress& Address, PCIBusAddress HostAddress)
{
/* Remember address -> device mapping */
{
}
/* Remember device name -> addresses mapping */
return S_OK;
}
bool BusAssignmentManager::State::findPCIAddress(const char* pszDevName, int iInstance, PCIBusAddress& Address)
{
return false;
return false;
return true;
}
{
switch (mChipsetType)
{
case ChipsetType_PIIX3:
break;
case ChipsetType_ICH9:
break;
default:
Assert(false);
break;
}
{
continue;
{
}
}
}
{
{
}
return NULL;
}
{
}
{
if (pszAlias)
{
if (checkAvailable(Address))
return S_OK;
}
return E_INVALIDARG;
}
{
}
void BusAssignmentManager::State::listAttachedPCIDevices(std::vector<ComPtr<IPCIDeviceAttachment> > &aAttached)
{
size_t i = 0;
{
dev.createObject();
}
}
{
}
{
if (pState)
{
delete pState;
}
}
{
return pInstance;
}
{
}
{
delete this;
}
{
if (RT_FAILURE(vrc))
return E_INVALIDARG;
return S_OK;
}
bool fGuestAddressRequired)
{
if (!GuestAddress.valid())
else
{
if (!fAvailable)
{
rc = E_ACCESSDENIED;
else
}
}
return rc;
return rc;
return rc;
return rc;
return rc;
return S_OK;
}
bool BusAssignmentManager::findPCIAddress(const char* pszDevName, int iInstance, PCIBusAddress& Address)
{
}
void BusAssignmentManager::listAttachedPCIDevices(std::vector<ComPtr<IPCIDeviceAttachment> > &aAttached)
{
}