px_tools_4v.c revision f0a73f0415a4150b270534bc7ed2cbb77d87c5a2
/*
* 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
*/
/*
* Copyright 2006 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/machsystm.h>
#include <sys/ddi_implfuncs.h>
#include <sys/hypervisor_api.h>
#include <px_obj.h>
#include <sys/pci_tools.h>
#include <px_tools_var.h>
#include "px_lib4v.h"
#include <px_tools_ext.h>
/*
* Delay needed to have a safe environment envelop any error which could
* surface. The larger the number of bridges and switches, the larger the
* number needed here.
*
* Note: this is a workaround until a better solution is found. While this
* number is high, given enough bridges and switches in the device path, this
* workaround can break. Also, other PIL 15 interrupts besides the ones we are
* enveloping could delay processing of the interrupt we are trying to protect.
*/
int pxtool_cfg_delay_usec = 2500;
int pxtool_iomem_delay_usec = 25000;
/* Currently there is no way of getting this info from hypervisor. */
#define INTERRUPT_MAPPING_ENTRIES 64
/* Number of inos per root complex. */
/* Verify hypervisor version for DIAG functions ra2pa and hpriv. */
#define PXTOOL_HYP_VER_UNINIT 0
#define PXTOOL_HYP_VER_BAD 1
#define PXTOOL_HYP_VER_OK 2
static int pxtool_hyp_version = PXTOOL_HYP_VER_UNINIT;
/* Swap endianness. */
static uint64_t
{
typedef union {
} data_split_t;
int i;
returned_data.data64 = 0;
for (i = 0; i < size; i++) {
}
return (returned_data.data64);
}
static void
{
int ret;
if (*diag_svc_status_p == PXTOOL_HYP_VER_UNINIT) {
/*
* Verify that hypervisor DIAG API has been
* negotiated (by unix).
*/
&pxtool_diag_maj_ver, &pxtool_diag_min_ver)) != 0) {
"diag hypervisor svc not negotiated: "
} else if (pxtool_diag_maj_ver == 1) {
/*
* Major version 1 is OK.
*
* Code maintainers: if the version changes, check for
* API changes in hv_ra2pa() and hv_hpriv() before
* accepting the new version.
*/
} else {
"diag hypervisor svc: bad major number: "
"grp:0x%lx, maj:0x%lx, min:0x%lx\n",
}
}
}
static int
{
int rval;
if (pxtool_hyp_version != PXTOOL_HYP_VER_OK) {
if (pxtool_hyp_version != PXTOOL_HYP_VER_OK) {
return (EPERM);
}
}
return (EIO);
}
return (EIO);
}
return (EIO);
}
return (EIO);
}
if (is_write) {
if (is_big_endian)
local_data = *data_p;
else
} else {
}
switch (rval) {
case H_ENOACCESS: /* Returned by non-debug hypervisor. */
break;
case H_EOK:
break;
default:
break;
}
if (is_big_endian)
*data_p = local_data;
else
*data_p =
}
return (rval);
}
/*
* This function is for PCI config space access.
* It assumes that offset, bdf, acc_attr are valid in prg_p.
* This function modifies prg_p status and data.
*
* prg_p->phys_addr isn't used.
*/
/*ARGSUSED*/
int
{
int rval = 0;
/* Alignment checking. */
return (EINVAL);
}
if (is_write) {
else
switch (size) {
case sizeof (uint8_t):
break;
case sizeof (uint16_t):
break;
case sizeof (uint32_t):
break;
case sizeof (uint64_t):
break;
}
} else
} else {
} else
switch (size) {
case sizeof (uint8_t):
break;
case sizeof (uint16_t):
break;
case sizeof (uint32_t):
break;
case sizeof (uint64_t):
break;
default:
break;
}
}
/*
* Workaround: delay taking down safe access env.
* For more info, see comments where pxtool_cfg_delay_usec is declared.
*/
if (pxtool_cfg_delay_usec > 0)
no_trap();
} else
return (rval);
}
/*
* This function is for PCI IO space and memory space access.
* It assumes that offset, bdf, acc_attr are current in prg_p.
* It assumes that prg_p->phys_addr is the final phys addr (including offset).
* This function modifies prg_p status and data.
*/
int
{
int rval = 0;
/* Alignment checking. */
return (EINVAL);
}
if (is_write) {
} else
} else {
*data_p = 0;
} else
}
/*
* Workaround: delay taking down safe access env.
* For more info, see comment where pxtool_iomem_delay_usec is declared.
*/
if (pxtool_iomem_delay_usec > 0)
no_trap();
} else
return (rval);
}
/*ARGSUSED*/
int
{
return (SUCCESS);
}
/*
* Perform register accesses on the nexus device itself.
*/
int
{
if (cmd == PCITOOL_NEXUS_SET_REG)
/* Read data from userland. */
mode) != DDI_SUCCESS) {
return (EFAULT);
}
/*
* If bank num == ff, base phys addr passed in from userland.
*
* Normal bank specification is invalid, as there is no OBP property to
* back it up.
*/
goto done;
}
/* Allow only size of 8-bytes. */
goto done;
}
/* Alignment checking. */
goto done;
}
/*
* Only the hypervisor can access nexus registers. As a result, there
* can be no error recovery in the OS. If there is an error, the
* system will go down, but with a trap type 7f. The OS cannot
* intervene with this kind of trap.
*/
/* Access device. prg.status is modified. */
done:
mode) != DDI_SUCCESS) {
return (EFAULT);
}
return (rval);
}