c88420b3bc75201aa71e3c807fd31e66073a089fdmick/*
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * CDDL HEADER START
c88420b3bc75201aa71e3c807fd31e66073a089fdmick *
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * The contents of this file are subject to the terms of the
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * Common Development and Distribution License (the "License").
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * You may not use this file except in compliance with the License.
c88420b3bc75201aa71e3c807fd31e66073a089fdmick *
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * or http://www.opensolaris.org/os/licensing.
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * See the License for the specific language governing permissions
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * and limitations under the License.
c88420b3bc75201aa71e3c807fd31e66073a089fdmick *
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * When distributing Covered Code, include this CDDL HEADER in each
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * If applicable, add the following below this CDDL HEADER, with the
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * fields enclosed by brackets "[]" replaced with your own identifying
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * information: Portions Copyright [yyyy] [name of copyright owner]
c88420b3bc75201aa71e3c807fd31e66073a089fdmick *
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * CDDL HEADER END
c88420b3bc75201aa71e3c807fd31e66073a089fdmick */
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmick/*
8d7fafffed373567f52062b634e61fd50858b8d9Zhi-Jun Robin Fu * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
c88420b3bc75201aa71e3c807fd31e66073a089fdmick */
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmick/*
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * PCI configuration space access routines
c88420b3bc75201aa71e3c807fd31e66073a089fdmick */
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmick#include <sys/systm.h>
c88420b3bc75201aa71e3c807fd31e66073a089fdmick#include <sys/psw.h>
c88420b3bc75201aa71e3c807fd31e66073a089fdmick#include <sys/bootconf.h>
c88420b3bc75201aa71e3c807fd31e66073a089fdmick#include <sys/reboot.h>
c88420b3bc75201aa71e3c807fd31e66073a089fdmick#include <sys/pci_impl.h>
c88420b3bc75201aa71e3c807fd31e66073a089fdmick#include <sys/pci_cfgspace.h>
c88420b3bc75201aa71e3c807fd31e66073a089fdmick#include <sys/pci_cfgspace_impl.h>
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu#include <sys/pci_cfgacc.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#if defined(__xpv)
843e19887f64dde75055cf8842fc4db2171eff45johnlev#include <sys/hypervisor.h>
843e19887f64dde75055cf8842fc4db2171eff45johnlev#endif
843e19887f64dde75055cf8842fc4db2171eff45johnlev
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu#if defined(__xpv)
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fuint pci_max_nbus = 0xFE;
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu#endif
c88420b3bc75201aa71e3c807fd31e66073a089fdmickint pci_bios_cfg_type = PCI_MECHANISM_UNKNOWN;
47310cedf870824837b096885cca62a0f10f5ff1Dana Myersint pci_bios_maxbus;
c88420b3bc75201aa71e3c807fd31e66073a089fdmickint pci_bios_mech;
c88420b3bc75201aa71e3c807fd31e66073a089fdmickint pci_bios_vers;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmick/*
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * These two variables can be used to force a configuration mechanism or
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * to force which function is used to probe for the presence of the PCI bus.
c88420b3bc75201aa71e3c807fd31e66073a089fdmick */
c88420b3bc75201aa71e3c807fd31e66073a089fdmickint PCI_CFG_TYPE = 0;
c88420b3bc75201aa71e3c807fd31e66073a089fdmickint PCI_PROBE_TYPE = 0;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu/*
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu * No valid mcfg_mem_base by default, and accessing pci config space
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu * in mem-mapped way is disabled.
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu */
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fuuint64_t mcfg_mem_base = 0;
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fuuint8_t mcfg_bus_start = 0;
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fuuint8_t mcfg_bus_end = 0xff;
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu
8d7fafffed373567f52062b634e61fd50858b8d9Zhi-Jun Robin Fu/*
8d7fafffed373567f52062b634e61fd50858b8d9Zhi-Jun Robin Fu * Maximum offset in config space when not using MMIO
8d7fafffed373567f52062b634e61fd50858b8d9Zhi-Jun Robin Fu */
8d7fafffed373567f52062b634e61fd50858b8d9Zhi-Jun Robin Fuuint_t pci_iocfg_max_offset = 0xff;
8d7fafffed373567f52062b634e61fd50858b8d9Zhi-Jun Robin Fu
c88420b3bc75201aa71e3c807fd31e66073a089fdmick/*
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * These function pointers lead to the actual implementation routines
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * for configuration space access. Normally they lead to either the
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * pci_mech1_* or pci_mech2_* routines, but they can also lead to
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * routines that work around chipset bugs.
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu * These functions are accessing pci config space via I/O way.
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu * Pci_cfgacc_get/put functions shoul be used as more common interfaces,
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu * which also provide accessing pci config space via mem-mapped way.
c88420b3bc75201aa71e3c807fd31e66073a089fdmick */
c88420b3bc75201aa71e3c807fd31e66073a089fdmickuint8_t (*pci_getb_func)(int bus, int dev, int func, int reg);
c88420b3bc75201aa71e3c807fd31e66073a089fdmickuint16_t (*pci_getw_func)(int bus, int dev, int func, int reg);
c88420b3bc75201aa71e3c807fd31e66073a089fdmickuint32_t (*pci_getl_func)(int bus, int dev, int func, int reg);
c88420b3bc75201aa71e3c807fd31e66073a089fdmickvoid (*pci_putb_func)(int bus, int dev, int func, int reg, uint8_t val);
c88420b3bc75201aa71e3c807fd31e66073a089fdmickvoid (*pci_putw_func)(int bus, int dev, int func, int reg, uint16_t val);
c88420b3bc75201aa71e3c807fd31e66073a089fdmickvoid (*pci_putl_func)(int bus, int dev, int func, int reg, uint32_t val);
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fuextern void (*pci_cfgacc_acc_p)(pci_cfgacc_req_t *req);
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu
c88420b3bc75201aa71e3c807fd31e66073a089fdmick/*
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * Internal routines
c88420b3bc75201aa71e3c807fd31e66073a089fdmick */
c88420b3bc75201aa71e3c807fd31e66073a089fdmickstatic int pci_check(void);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev#if !defined(__xpv)
c88420b3bc75201aa71e3c807fd31e66073a089fdmickstatic int pci_check_bios(void);
c88420b3bc75201aa71e3c807fd31e66073a089fdmickstatic int pci_get_cfg_type(void);
843e19887f64dde75055cf8842fc4db2171eff45johnlev#endif
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
137632774395dba0eb9b77257da1d8732bd5413dGuoli Shu/* for legacy io-based config space access */
c88420b3bc75201aa71e3c807fd31e66073a089fdmickkmutex_t pcicfg_mutex;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
137632774395dba0eb9b77257da1d8732bd5413dGuoli Shu/* for mmio-based config space access */
137632774395dba0eb9b77257da1d8732bd5413dGuoli Shukmutex_t pcicfg_mmio_mutex;
137632774395dba0eb9b77257da1d8732bd5413dGuoli Shu
c88420b3bc75201aa71e3c807fd31e66073a089fdmick/* ..except Orion and Neptune, which have to have their own */
c88420b3bc75201aa71e3c807fd31e66073a089fdmickkmutex_t pcicfg_chipset_mutex;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmickvoid
c88420b3bc75201aa71e3c807fd31e66073a089fdmickpci_cfgspace_init(void)
c88420b3bc75201aa71e3c807fd31e66073a089fdmick{
7f58d7249497f31d23e7d0c4222d27998c8b0d38dilpreet mutex_init(&pcicfg_mutex, NULL, MUTEX_SPIN,
7f58d7249497f31d23e7d0c4222d27998c8b0d38dilpreet (ddi_iblock_cookie_t)ipltospl(15));
137632774395dba0eb9b77257da1d8732bd5413dGuoli Shu mutex_init(&pcicfg_mmio_mutex, NULL, MUTEX_SPIN,
137632774395dba0eb9b77257da1d8732bd5413dGuoli Shu (ddi_iblock_cookie_t)ipltospl(DISP_LEVEL));
7f58d7249497f31d23e7d0c4222d27998c8b0d38dilpreet mutex_init(&pcicfg_chipset_mutex, NULL, MUTEX_SPIN,
7f58d7249497f31d23e7d0c4222d27998c8b0d38dilpreet (ddi_iblock_cookie_t)ipltospl(15));
c88420b3bc75201aa71e3c807fd31e66073a089fdmick if (!pci_check()) {
c88420b3bc75201aa71e3c807fd31e66073a089fdmick mutex_destroy(&pcicfg_mutex);
137632774395dba0eb9b77257da1d8732bd5413dGuoli Shu mutex_destroy(&pcicfg_mmio_mutex);
c88420b3bc75201aa71e3c807fd31e66073a089fdmick mutex_destroy(&pcicfg_chipset_mutex);
c88420b3bc75201aa71e3c807fd31e66073a089fdmick }
c88420b3bc75201aa71e3c807fd31e66073a089fdmick}
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmick/*
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu * This code determines if this system supports PCI/PCIE and which
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * type of configuration access method is used
c88420b3bc75201aa71e3c807fd31e66073a089fdmick */
c88420b3bc75201aa71e3c807fd31e66073a089fdmickstatic int
c88420b3bc75201aa71e3c807fd31e66073a089fdmickpci_check(void)
c88420b3bc75201aa71e3c807fd31e66073a089fdmick{
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu uint64_t ecfginfo[4];
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu
c88420b3bc75201aa71e3c807fd31e66073a089fdmick /*
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * Only do this once. NB: If this is not a PCI system, and we
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * get called twice, we can't detect it and will probably die
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * horribly when we try to ask the BIOS whether PCI is present.
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * This code is safe *ONLY* during system startup when the
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * BIOS is still available.
c88420b3bc75201aa71e3c807fd31e66073a089fdmick */
c88420b3bc75201aa71e3c807fd31e66073a089fdmick if (pci_bios_cfg_type != PCI_MECHANISM_UNKNOWN)
c88420b3bc75201aa71e3c807fd31e66073a089fdmick return (TRUE);
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
843e19887f64dde75055cf8842fc4db2171eff45johnlev#if defined(__xpv)
843e19887f64dde75055cf8842fc4db2171eff45johnlev /*
843e19887f64dde75055cf8842fc4db2171eff45johnlev * only support PCI config mechanism 1 in i86xpv. This should be fine
843e19887f64dde75055cf8842fc4db2171eff45johnlev * since the other ones are workarounds for old broken H/W which won't
843e19887f64dde75055cf8842fc4db2171eff45johnlev * be supported in i86xpv anyway.
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (DOMAIN_IS_INITDOMAIN(xen_info)) {
843e19887f64dde75055cf8842fc4db2171eff45johnlev pci_bios_cfg_type = PCI_MECHANISM_1;
843e19887f64dde75055cf8842fc4db2171eff45johnlev pci_getb_func = pci_mech1_getb;
843e19887f64dde75055cf8842fc4db2171eff45johnlev pci_getw_func = pci_mech1_getw;
843e19887f64dde75055cf8842fc4db2171eff45johnlev pci_getl_func = pci_mech1_getl;
843e19887f64dde75055cf8842fc4db2171eff45johnlev pci_putb_func = pci_mech1_putb;
843e19887f64dde75055cf8842fc4db2171eff45johnlev pci_putw_func = pci_mech1_putw;
843e19887f64dde75055cf8842fc4db2171eff45johnlev pci_putl_func = pci_mech1_putl;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev /*
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Since we can't get the BIOS info in i86xpv, we will do an
843e19887f64dde75055cf8842fc4db2171eff45johnlev * exhaustive search of all PCI buses. We have to do this until
843e19887f64dde75055cf8842fc4db2171eff45johnlev * we start using the PCI information in ACPI.
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
47310cedf870824837b096885cca62a0f10f5ff1Dana Myers pci_bios_maxbus = pci_max_nbus;
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev#else /* !__xpv */
843e19887f64dde75055cf8842fc4db2171eff45johnlev
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_bios_cfg_type = pci_check_bios();
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmick if (pci_bios_cfg_type == PCI_MECHANISM_NONE)
7b3700d1667b1178db936c8f0864fe50a502417eszhou pci_bios_cfg_type = PCI_MECHANISM_1; /* default to mech 1 */
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmick switch (pci_get_cfg_type()) {
c88420b3bc75201aa71e3c807fd31e66073a089fdmick case PCI_MECHANISM_1:
c88420b3bc75201aa71e3c807fd31e66073a089fdmick if (pci_is_broken_orion()) {
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_getb_func = pci_orion_getb;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_getw_func = pci_orion_getw;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_getl_func = pci_orion_getl;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_putb_func = pci_orion_putb;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_putw_func = pci_orion_putw;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_putl_func = pci_orion_putl;
8d7fafffed373567f52062b634e61fd50858b8d9Zhi-Jun Robin Fu } else if (pci_check_amd_ioecs()) {
8d7fafffed373567f52062b634e61fd50858b8d9Zhi-Jun Robin Fu pci_getb_func = pci_mech1_amd_getb;
8d7fafffed373567f52062b634e61fd50858b8d9Zhi-Jun Robin Fu pci_getw_func = pci_mech1_amd_getw;
8d7fafffed373567f52062b634e61fd50858b8d9Zhi-Jun Robin Fu pci_getl_func = pci_mech1_amd_getl;
8d7fafffed373567f52062b634e61fd50858b8d9Zhi-Jun Robin Fu pci_putb_func = pci_mech1_amd_putb;
8d7fafffed373567f52062b634e61fd50858b8d9Zhi-Jun Robin Fu pci_putw_func = pci_mech1_amd_putw;
8d7fafffed373567f52062b634e61fd50858b8d9Zhi-Jun Robin Fu pci_putl_func = pci_mech1_amd_putl;
8d7fafffed373567f52062b634e61fd50858b8d9Zhi-Jun Robin Fu pci_iocfg_max_offset = 0xfff;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick } else {
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_getb_func = pci_mech1_getb;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_getw_func = pci_mech1_getw;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_getl_func = pci_mech1_getl;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_putb_func = pci_mech1_putb;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_putw_func = pci_mech1_putw;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_putl_func = pci_mech1_putl;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick }
c88420b3bc75201aa71e3c807fd31e66073a089fdmick break;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmick case PCI_MECHANISM_2:
c88420b3bc75201aa71e3c807fd31e66073a089fdmick if (pci_check_neptune()) {
c88420b3bc75201aa71e3c807fd31e66073a089fdmick /*
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * The BIOS for some systems with the Intel
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * Neptune chipset seem to default to #2 even
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * though the chipset can do #1. Override
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * the BIOS so that MP systems will work
c88420b3bc75201aa71e3c807fd31e66073a089fdmick * correctly.
c88420b3bc75201aa71e3c807fd31e66073a089fdmick */
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_getb_func = pci_neptune_getb;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_getw_func = pci_neptune_getw;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_getl_func = pci_neptune_getl;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_putb_func = pci_neptune_putb;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_putw_func = pci_neptune_putw;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_putl_func = pci_neptune_putl;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick } else {
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_getb_func = pci_mech2_getb;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_getw_func = pci_mech2_getw;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_getl_func = pci_mech2_getl;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_putb_func = pci_mech2_putb;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_putw_func = pci_mech2_putw;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_putl_func = pci_mech2_putl;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick }
c88420b3bc75201aa71e3c807fd31e66073a089fdmick break;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmick default:
c88420b3bc75201aa71e3c807fd31e66073a089fdmick return (FALSE);
c88420b3bc75201aa71e3c807fd31e66073a089fdmick }
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu#endif /* __xpv */
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu /*
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu * Try to get a valid mcfg_mem_base in early boot
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu * If failed, leave mem-mapped pci config space accessing disabled
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu * until pci boot code (pci_autoconfig) makes sure this is a PCIE
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu * platform.
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu */
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu if (do_bsys_getprop(NULL, MCFG_PROPNAME, ecfginfo) != -1) {
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu mcfg_mem_base = ecfginfo[0];
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu mcfg_bus_start = ecfginfo[2];
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu mcfg_bus_end = ecfginfo[3];
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu }
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu /* See pci_cfgacc.c */
c0da627439dfb642fb41ab7d78406fc69d2c64b2Zhi-Jun Robin Fu pci_cfgacc_acc_p = pci_cfgacc_acc;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmick return (TRUE);
c88420b3bc75201aa71e3c807fd31e66073a089fdmick}
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
843e19887f64dde75055cf8842fc4db2171eff45johnlev#if !defined(__xpv)
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmickstatic int
c88420b3bc75201aa71e3c807fd31e66073a089fdmickpci_check_bios(void)
c88420b3bc75201aa71e3c807fd31e66073a089fdmick{
c88420b3bc75201aa71e3c807fd31e66073a089fdmick struct bop_regs regs;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick uint32_t carryflag;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick uint16_t ax, dx;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmick bzero(&regs, sizeof (regs));
c88420b3bc75201aa71e3c807fd31e66073a089fdmick regs.eax.word.ax = (PCI_FUNCTION_ID << 8) | PCI_BIOS_PRESENT;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmick BOP_DOINT(bootops, 0x1a, &regs);
c88420b3bc75201aa71e3c807fd31e66073a089fdmick carryflag = regs.eflags & PS_C;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick ax = regs.eax.word.ax;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick dx = regs.edx.word.dx;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmick /* the carry flag must not be set */
c88420b3bc75201aa71e3c807fd31e66073a089fdmick if (carryflag != 0)
c88420b3bc75201aa71e3c807fd31e66073a089fdmick return (PCI_MECHANISM_NONE);
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmick if (dx != ('P' | 'C'<<8))
c88420b3bc75201aa71e3c807fd31e66073a089fdmick return (PCI_MECHANISM_NONE);
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmick /* ah (the high byte of ax) must be zero */
c88420b3bc75201aa71e3c807fd31e66073a089fdmick if ((ax & 0xff00) != 0)
c88420b3bc75201aa71e3c807fd31e66073a089fdmick return (PCI_MECHANISM_NONE);
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_bios_mech = (ax & 0x3);
c88420b3bc75201aa71e3c807fd31e66073a089fdmick pci_bios_vers = regs.ebx.word.bx;
47310cedf870824837b096885cca62a0f10f5ff1Dana Myers pci_bios_maxbus = (regs.ecx.word.cx & 0xff);
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmick switch (pci_bios_mech) {
c88420b3bc75201aa71e3c807fd31e66073a089fdmick default: /* ?!? */
c88420b3bc75201aa71e3c807fd31e66073a089fdmick case 0: /* supports neither? */
c88420b3bc75201aa71e3c807fd31e66073a089fdmick return (PCI_MECHANISM_NONE);
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmick case 1:
c88420b3bc75201aa71e3c807fd31e66073a089fdmick case 3: /* supports both */
c88420b3bc75201aa71e3c807fd31e66073a089fdmick return (PCI_MECHANISM_1);
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmick case 2:
c88420b3bc75201aa71e3c807fd31e66073a089fdmick return (PCI_MECHANISM_2);
c88420b3bc75201aa71e3c807fd31e66073a089fdmick }
c88420b3bc75201aa71e3c807fd31e66073a089fdmick}
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmickstatic int
c88420b3bc75201aa71e3c807fd31e66073a089fdmickpci_get_cfg_type(void)
c88420b3bc75201aa71e3c807fd31e66073a089fdmick{
c88420b3bc75201aa71e3c807fd31e66073a089fdmick /* Check to see if the config mechanism has been set in /etc/system */
c88420b3bc75201aa71e3c807fd31e66073a089fdmick switch (PCI_CFG_TYPE) {
c88420b3bc75201aa71e3c807fd31e66073a089fdmick default:
c88420b3bc75201aa71e3c807fd31e66073a089fdmick case 0:
c88420b3bc75201aa71e3c807fd31e66073a089fdmick break;
c88420b3bc75201aa71e3c807fd31e66073a089fdmick case 1:
c88420b3bc75201aa71e3c807fd31e66073a089fdmick return (PCI_MECHANISM_1);
c88420b3bc75201aa71e3c807fd31e66073a089fdmick case 2:
c88420b3bc75201aa71e3c807fd31e66073a089fdmick return (PCI_MECHANISM_2);
c88420b3bc75201aa71e3c807fd31e66073a089fdmick case -1:
c88420b3bc75201aa71e3c807fd31e66073a089fdmick return (PCI_MECHANISM_NONE);
c88420b3bc75201aa71e3c807fd31e66073a089fdmick }
c88420b3bc75201aa71e3c807fd31e66073a089fdmick
c88420b3bc75201aa71e3c807fd31e66073a089fdmick /* call one of the PCI detection algorithms */
c88420b3bc75201aa71e3c807fd31e66073a089fdmick switch (PCI_PROBE_TYPE) {
c88420b3bc75201aa71e3c807fd31e66073a089fdmick default:
c88420b3bc75201aa71e3c807fd31e66073a089fdmick case 0:
c88420b3bc75201aa71e3c807fd31e66073a089fdmick /* From pci_check() and pci_check_bios() */
c88420b3bc75201aa71e3c807fd31e66073a089fdmick return (pci_bios_cfg_type);
c88420b3bc75201aa71e3c807fd31e66073a089fdmick case -1:
c88420b3bc75201aa71e3c807fd31e66073a089fdmick return (PCI_MECHANISM_NONE);
c88420b3bc75201aa71e3c807fd31e66073a089fdmick }
c88420b3bc75201aa71e3c807fd31e66073a089fdmick}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev#endif /* __xpv */