/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <sys/machlock.h>
#include <sys/smp_impldefs.h>
#include <sys/psm_common.h>
#include <sys/archsystm.h>
#include <sys/mach_intr.h>
#include <sys/sysmacros.h>
#include <sys/pci_intr_lib.h>
/* Multiple vector support for MSI */
/* Multiple vector support for MSI-X */
/*
* check whether the system supports MSI
*
* If PCI-E capability is found, then this must be a PCI-E system.
* Since MSI is required for PCI-E system, it returns PSM_SUCCESS
* to indicate this system supports MSI.
*/
int
{
int dev_len;
/*
* check whether the first level children of root_node have
* PCI-E capability
*/
" driver: %s, binding: %s, nodename: %s\n", (void *)cdip,
ddi_node_name(cdip)));
!= DDI_PROP_SUCCESS)
continue;
return (PSM_SUCCESS);
}
/* MSI is not supported on this system */
"device_type found\n"));
return (PSM_FAILURE);
}
/*
* It finds the apic_irq_t associates with the dip, ispec and type.
*/
{
int i;
for (i = apic_min_device_irq; i <= apic_max_device_irq; i++) {
if (type == DDI_INTR_TYPE_MSI) {
if (irqp->airq_mps_intr_index ==
return (irqp);
} else if (type == DDI_INTR_TYPE_MSIX) {
if (irqp->airq_mps_intr_index ==
return (irqp);
} else
return (irqp);
}
}
}
return (NULL);
}
int
{
int i;
/*
* Convert the vecirq arg to an irq using vector_to_irq table
* if the arg is a vector. Pass thru if already an irq.
*/
else
return (PSM_FAILURE);
}
/* Get the (temp) cpu from apic_irq table, indexed by irq. */
/* Return user bound info for intrd. */
}
}
if (intr_params_p->avgi_req_flags &
/* Get number of devices from apic_irq table shared field. */
/* Some devices have NULL dip. Don't count these. */
if (intr_params_p->avgi_num_devs > 0) {
i++;
}
/* There are no viable dips to return. */
if (intr_params_p->avgi_num_devs == 0)
else { /* Return list of dips */
/* Allocate space in array for that number of devs. */
sizeof (dev_info_t *),
KM_SLEEP);
/*
* Loop through the device list of the autovec table
* filling in the dip array.
*
* Note that the autovect table may have some special
* entries which contain NULL dips. These will be
* ignored.
*/
intr_params_p->avgi_dip_list[i++] =
}
}
return (PSM_SUCCESS);
}
/*
* apic_pci_msi_enable_vector:
* XXX: MSI-X support
*/
/* ARGSUSED */
void
int count, int target_apic_id)
{
"\tdriver = %s, inum=0x%x vector=0x%x apicid=0x%x\n", (void *)dip,
/* MSI Address */
msi_addr = (MSI_ADDR_HDR |
/* MSI Data: MSI is edge triggered according to spec */
if (type == DDI_INTR_TYPE_MSI) {
/* Set the bits to inform how many MSIs are enabled */
}
}
/*
* apic_pci_msi_disable_mode:
*/
void
{
if (type == DDI_INTR_TYPE_MSI) {
if (!(msi_ctrl & PCI_MSI_ENABLE_BIT))
return;
} else if (type == DDI_INTR_TYPE_MSIX) {
if (msi_ctrl & PCI_MSIX_ENABLE_BIT) {
msi_ctrl);
}
}
}
/*
* apic_pci_msi_enable_mode:
*/
void
{
if (type == DDI_INTR_TYPE_MSI) {
if ((msi_ctrl & PCI_MSI_ENABLE_BIT))
return;
} else if (type == DDI_INTR_TYPE_MSIX) {
/* Offset into "inum"th entry in the MSI-X table & clear mask */
if (!(msi_ctrl & PCI_MSIX_ENABLE_BIT)) {
msi_ctrl);
}
}
}
/*
* We let the hypervisor deal with msi configutation
* so just stub this out.
*/
/* ARGSUSED */
void
{
}