px_lib4v.c revision 817a6df8b3316f1bd1c398f765f71964d8966da4
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/sysmacros.h>
#include <sys/hypervisor_api.h>
#include <px_obj.h>
#include <sys/machsystm.h>
#include "px_lib4v.h"
#include "px_err.h"
/* mask for the ranges property in calculating the real PFN range */
int
{
int ret;
if (ret != DDI_PROP_SUCCESS) {
return (DDI_FAILURE);
}
/*
* Initilize device handle. The device handle uniquely identifies
* a SUN4V device. It consists of the lower 28-bits of the hi-cell
* of the first entry of the SUN4V device's "reg" property as
* defined by the SUN4V Bus Binding to Open Firmware.
*/
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
"hvio_intr_devino_to_sysino failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
*sysino);
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
(int *)intr_valid_state)) != H_EOK) {
ret);
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
ret);
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
ret);
return (DDI_FAILURE);
}
*intr_state);
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
ret);
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
"hvio_intr_gettarget failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
"hvio_intr_settarget failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
int flag)
{
int i, err = DDI_SUCCESS;
"pages 0x%x atrr 0x%x addr 0x%p pfn_index 0x%llx, flag 0x%x\n",
KM_NOSLEEP)) == NULL) {
return (DDI_FAILURE);
}
if (flag == MMU_MAP_MP) {
}
} else {
for (i = 0; i < pages; i++, a += MMU_PAGE_SIZE) {
}
}
pgs_mapped = 0;
while (pgs) {
"hvio_iommu_map failed, ret 0x%lx\n", ret);
err = DDI_FAILURE;
break;
}
pgs_mapped += pgs_cnt;
pgs_cnt = 0;
}
return (err);
}
/*ARGSUSED*/
int
{
while (pages) {
"hvio_iommu_demap failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
pgs_cnt = 0;
}
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
"hvio_iommu_getmap failed, ret 0x%lx\n", ret);
}
*attributes_p, *r_addr_p);
return (DDI_SUCCESS);
}
/*
* Checks dma attributes against system bypass ranges
* A sun4v device must be capable of generating the entire 64-bit
* address in order to perform bypass DMA.
*/
/*ARGSUSED*/
int
{
return (DDI_DMA_BADATTR);
}
*hi_p = UINT64_MAX;
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
"hvio_iommu_getbypass failed, ret 0x%lx\n", ret);
}
*io_addr_p);
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
"handle 0x%llx off 0x%x len 0x%x flags 0x%x\n",
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
if (!len)
return (DDI_FAILURE);
}
else
}
}
/*
* MSIQ Functions:
*/
/*ARGSUSED*/
int
{
int i, err = DDI_SUCCESS;
for (i = 0; i < msiq_state_p->msiq_cnt; i++) {
(i + msiq_state_p->msiq_1st_msiq_id),
"hvio_msiq_conf failed, ret 0x%lx\n", ret);
err = DDI_FAILURE;
break;
}
(i + msiq_state_p->msiq_1st_msiq_id),
"px_lib_msiq_info failed, ret 0x%x\n", err);
err = DDI_FAILURE;
break;
}
}
return (err);
}
/*ARGSUSED*/
int
{
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
"hvio_msiq_info failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
ra_p, *msiq_rec_cnt_p);
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
"hvio_msiq_getvalid failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
"hvio_msiq_setvalid failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
"hvio_msiq_getstate failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
*msiq_state);
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
"hvio_msiq_setstate failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
"hvio_msiq_gethead failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
*msiq_head_p);
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
"hvio_msiq_sethead failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
"hvio_msiq_gettail failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
*msiq_tail_p);
return (DDI_SUCCESS);
}
/*ARGSUSED*/
void
{
if (!curr_msiq_rec_p->msiq_rec_type)
return;
/* Zero out msiq_rec_type field */
curr_msiq_rec_p->msiq_rec_type = 0;
}
/*
* MSI Functions:
*/
/*ARGSUSED*/
int
{
/* Noop */
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
"hvio_msi_getmsiq failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
*msiq_id);
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
"hvio_msi_setmsiq failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
"hvio_msi_getvalid failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
"hvio_msi_setvalid failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
"hvio_msi_getstate failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
*msi_state);
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
"hvio_msi_setstate failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
/*
* MSG Functions:
*/
/*ARGSUSED*/
int
{
"hvio_msg_getmsiq failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
*msiq_id);
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
"hvio_msg_setmsiq failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
msg_valid_state)) != H_EOK) {
"hvio_msg_getvalid failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
/*ARGSUSED*/
int
{
msg_valid_state)) != H_EOK) {
"hvio_msg_setvalid failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
/*
* Currently unsupported by hypervisor and all functions are noops.
*/
/*ARGSUSED*/
int
{
/* Not supported */
return (DDI_FAILURE);
}
/*ARGSUSED*/
void
{
/* Noop */
}
/*
* PCI tool Functions:
* Currently unsupported by hypervisor and all functions are noops.
*/
/*ARGSUSED*/
int
{
return (DDI_FAILURE);
}
/*ARGSUSED*/
int
{
return (DDI_FAILURE);
}
/*ARGSUSED*/
int
{
return (DDI_FAILURE);
}
/*
* Misc Functions:
* Currently unsupported by hypervisor and all functions are noops.
*/
/*ARGSUSED*/
{
return (DDI_SUCCESS);
}
/*ARGSUSED*/
void
{
/* Noop */
}
/*ARGSUSED*/
static int
{
"hvio_config_get failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
/*ARGSUSED*/
static int
{
"hvio_config_put failed, ret 0x%lx\n", ret);
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
static uint32_t
{
/* XXX update error kstats */
return (0xffffffff);
return (rdata);
}
static void
{
/*EMPTY*/
/* XXX update error kstats */
}
}
static uint8_t
{
}
static uint16_t
{
}
static uint32_t
{
}
static uint64_t
{
}
static void
{
pci_cfg_data_t wdata = { 0 };
}
static void
{
pci_cfg_data_t wdata = { 0 };
}
static void
{
pci_cfg_data_t wdata = { 0 };
}
static void
{
pci_cfg_data_t wdata = { 0 };
}
static void
{
if (flags == DDI_DEV_AUTOINCR)
else
}
/*
* Function to rep read 16 bit data off the PCI configuration space behind
* the 21554's host interface.
*/
static void
{
if (flags == DDI_DEV_AUTOINCR)
else
}
/*
* Function to rep read 32 bit data off the PCI configuration space behind
* the 21554's host interface.
*/
static void
{
if (flags == DDI_DEV_AUTOINCR)
else
}
/*
* Function to rep read 64 bit data off the PCI configuration space behind
* the 21554's host interface.
*/
static void
{
if (flags == DDI_DEV_AUTOINCR)
else
}
/*
* Function to rep write 8 bit data into the PCI configuration space behind
* the 21554's host interface.
*/
static void
{
if (flags == DDI_DEV_AUTOINCR)
else
}
/*
* Function to rep write 16 bit data into the PCI configuration space behind
* the 21554's host interface.
*/
static void
{
if (flags == DDI_DEV_AUTOINCR)
else
}
/*
* Function to rep write 32 bit data into the PCI configuration space behind
* the 21554's host interface.
*/
static void
{
if (flags == DDI_DEV_AUTOINCR)
else
}
/*
* Function to rep write 64 bit data into the PCI configuration space behind
* the 21554's host interface.
*/
static void
{
if (flags == DDI_DEV_AUTOINCR)
else
}
/*
* Provide a private access handle to route config access calls to Hypervisor.
* Beware: Do all error checking for config space accesses before calling
* this function. ie. do error checking from the calling function.
* Due to a lack of meaningful error code in DDI, the gauranteed return of
* the generic code.
*/
/*ARGSUSED*/
int
{
/* Check for mapping teardown operation */
/* free up memory allocated for the private access handle. */
return (DDI_SUCCESS);
}
/* allocate memory for our private handle */
px_pvt = (px_config_acc_pvt_t *)
/* set up private data for use during IO routines */
/* addr needed by the HV APIs */
/*
* Address that specifies the actual offset into the 256MB
* memory mapped configuration space, 4K per device.
* First 12bits form the offset into 4K config space.
* This address is only used during the IO routines to calculate
* the offset at which the transaction must be performed.
* Drivers bypassing DDI functions to access PCI config space will
* panic the system since the following is a bogus virtual address.
*/
return (DDI_SUCCESS);
}
/*
* px_lib_log_safeacc_err:
* This will initiate something similar to px_fm_callback.
*/
static void
{
if (hp)
}
#ifdef DEBUG
int px_peekfault_cnt = 0;
int px_pokefault_cnt = 0;
#endif /* DEBUG */
static int
{
/* Start with an array of 8 reg spaces for now to cover most devices. */
int buflen = sizeof (regspec_array);
int status;
/* If need more space, fallback to kmem_alloc. */
if (status == DDI_PROP_BUF_TOO_SMALL) {
}
/* Get phys_hi from first element. All have same bdf. */
if (status == DDI_PROP_SUCCESS)
if (kmalloced)
}
/*
* Do a safe write to a device.
*
* When this function is given a handle (cautious access), all errors are
* suppressed.
*
* When this function is not given a handle (poke), only Unsupported Request
* and Completer Abort errors are suppressed.
*
* In all cases, all errors are returned in the function return status.
*/
int
{
int err = DDI_SUCCESS;
/*
* However there is no way to guarantee that the fabric error
* handler will occur in the window where otd is set.
*/
"poke: px_lib_bdf_from_dip failed\n");
err = DDI_FAILURE;
goto done;
}
switch (size) {
case sizeof (uint8_t):
break;
case sizeof (uint16_t):
break;
case sizeof (uint32_t):
break;
case sizeof (uint64_t):
break;
default:
"poke: invalid size %d passed\n", size);
err = DDI_FAILURE;
goto done;
}
/*
* Grab pokefault mutex since hypervisor does not guarantee
* poke serialization.
*/
if (hp) {
} else {
}
err = DDI_FAILURE;
err = DDI_FAILURE;
#ifdef DEBUG
#endif
/*
* For CAUTIOUS and POKE access, notify FMA to
*/
(hp ? DDI_FM_ERR_EXPECTED :
if (hp) {
} else {
}
goto done;
}
if (hp) {
} else {
}
}
}
done:
return (err);
}
/*ARGSUSED*/
int
{
int err = DDI_SUCCESS;
/*
* However there is no way to guarantee that the fabric error
* handler will occur in the window where otd is set.
*/
/* Lock pokefault mutex so read doesn't mask a poke fault. */
if (hp) {
} else {
}
err = DDI_FAILURE;
/*
* For CAUTIOUS and PEEK access, notify FMA to
*/
(hp ? DDI_FM_ERR_EXPECTED :
/* Stuff FFs in host addr if peek. */
int i;
*ff_addr++ = 0xff;
}
#ifdef DEBUG
#endif
if (hp) {
} else {
}
goto done;
}
if (hp) {
} else {
}
case sizeof (uint8_t):
break;
case sizeof (uint16_t):
break;
case sizeof (uint32_t):
break;
case sizeof (uint64_t):
break;
default:
"peek: invalid size %d passed\n",
err = DDI_FAILURE;
goto done;
}
}
}
done:
return (err);
}
/* add interrupt vector */
int
{
int ret;
"px_err_add_intr: calling add_ivintr");
if (ret != DDI_SUCCESS) {
return (ret);
}
"px_err_add_intr: ib_intr_enable ");
return (ret);
}
/* remove interrupt vector */
void
{
}
#ifdef FMA
void
{
/* initialise all the structure members */
rc_status->status_valid = 0;
/* PCI Status Register */
}
/* PCIe Status Register */
}
}
}
}
/* ue_fst_err_ptr - not available for sun4v?? */
}
}
}
#endif
/*ARGSUSED*/
int
{
return (DDI_FAILURE);
}
/*ARGSUSED*/
{
return (DDI_INTR_CLAIMED);
}
/*ARGSUSED*/
{
return (DDI_INTR_CLAIMED);
}
/*
* Only used for temporary PCI-E Fabric Error Handling.
*/
(pci_cfg_data_t *)&data);
return (data);
}
void
pci_cfg_data_t wdata = { 0 };
}
/* Dummy cpr add callback */
/*ARGSUSED*/
void
{
}
/* Dummy cpr rem callback */
/*ARGSUSED*/
void
{
}