- // Edge trigger, Fixed delivery
- uint32_t msi_data = vector;
-
- pci_write_cspace(
- device->cspace_base, PCI_MSI_ADDR(device->msi_loc), msi_addr);
-
- pci_reg_t reg1 = pci_read_cspace(device->cspace_base, device->msi_loc);
- pci_reg_t msg_ctl = reg1 >> 16;
-
- int offset = !!(msg_ctl & MSI_CAP_64BIT) * 4;
- pci_write_cspace(device->cspace_base,
- PCI_MSI_DATA(device->msi_loc, offset),
- msi_data & 0xffff);
-
- if ((msg_ctl & MSI_CAP_MASK)) {
- pci_write_cspace(
- device->cspace_base, PCI_MSI_MASK(device->msi_loc, offset), 0);
- }
-
- // manipulate the MSI_CTRL to allow device using MSI to request service.
- reg1 = (reg1 & 0xff8fffff) | 0x10000;
- pci_write_cspace(device->cspace_base, device->msi_loc, reg1);
-}
-
-struct pci_device*
-pci_get_device_by_id(uint16_t vendorId, uint16_t deviceId)
-{
- uint32_t dev_info = vendorId | (deviceId << 16);
- struct pci_device *pos, *n;
- llist_for_each(pos, n, &pci_devices, dev_chain)
- {
- if (pos->device_info == dev_info) {
- return pos;
- }
- }
-
- return NULL;
-}
-
-struct pci_device*
-pci_get_device_by_class(uint32_t class)
-{
- struct pci_device *pos, *n;
- llist_for_each(pos, n, &pci_devices, dev_chain)
- {
- if (PCI_DEV_CLASS(pos->class_info) == class) {
- return pos;
- }
- }
-
- return NULL;
-}
-
-void
-pci_add_driver(const char* name,
- u32_t class,
- u32_t vendor,
- u32_t devid,
- pci_drv_init init)
-{
- struct pci_driver* pci_drv = valloc(sizeof(*pci_drv));
- *pci_drv = (struct pci_driver){ .create_driver = init,
- .dev_info = (vendor << 16) | devid,
- .dev_class = class };
- if (name) {
- strncpy(pci_drv->name, name, PCI_DRV_NAME_LEN);
- }
-
- llist_append(&pci_drivers, &pci_drv->drivers);
-}
-
-int
-pci_bind_driver(struct pci_device* pci_dev)
-{
- struct pci_driver *pos, *n;
- llist_for_each(pos, n, &pci_drivers, drivers)
- {
- if (pos->dev_info) {
- if (pos->dev_info == pci_dev->device_info) {
- goto check_type;
- }
- continue;
- }
- check_type:
- if (pos->dev_class) {
- if (pos->dev_class == PCI_DEV_CLASS(pci_dev->class_info)) {
- pci_dev->driver.type = pos;
- pci_dev->driver.instance = pos->create_driver(pci_dev);
- return 1;
- }
- }
- }