18472SSean.Ye@Sun.COM /*
28472SSean.Ye@Sun.COM * CDDL HEADER START
38472SSean.Ye@Sun.COM *
48472SSean.Ye@Sun.COM * The contents of this file are subject to the terms of the
58472SSean.Ye@Sun.COM * Common Development and Distribution License (the "License").
68472SSean.Ye@Sun.COM * You may not use this file except in compliance with the License.
78472SSean.Ye@Sun.COM *
88472SSean.Ye@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
98472SSean.Ye@Sun.COM * or http://www.opensolaris.org/os/licensing.
108472SSean.Ye@Sun.COM * See the License for the specific language governing permissions
118472SSean.Ye@Sun.COM * and limitations under the License.
128472SSean.Ye@Sun.COM *
138472SSean.Ye@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
148472SSean.Ye@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
158472SSean.Ye@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
168472SSean.Ye@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
178472SSean.Ye@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
188472SSean.Ye@Sun.COM *
198472SSean.Ye@Sun.COM * CDDL HEADER END
208472SSean.Ye@Sun.COM */
218472SSean.Ye@Sun.COM
228472SSean.Ye@Sun.COM /*
238472SSean.Ye@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
248472SSean.Ye@Sun.COM * Use is subject to license terms.
258472SSean.Ye@Sun.COM */
268472SSean.Ye@Sun.COM
278472SSean.Ye@Sun.COM #include <sys/types.h>
288472SSean.Ye@Sun.COM #include <sys/cmn_err.h>
298472SSean.Ye@Sun.COM #include <sys/errno.h>
308472SSean.Ye@Sun.COM #include <sys/systm.h>
318472SSean.Ye@Sun.COM #include <sys/sunddi.h>
328472SSean.Ye@Sun.COM #include <sys/pci_cfgspace.h>
338472SSean.Ye@Sun.COM #include <sys/pci.h>
348472SSean.Ye@Sun.COM #include <sys/pcie.h>
358472SSean.Ye@Sun.COM #include <vm/seg_kmem.h>
368472SSean.Ye@Sun.COM #include <sys/mman.h>
378472SSean.Ye@Sun.COM #include <sys/cpu_module.h>
388472SSean.Ye@Sun.COM #include "intel_nhm.h"
398472SSean.Ye@Sun.COM
408472SSean.Ye@Sun.COM static ddi_acc_handle_t dev_pci_hdl[MAX_CPU_NODES][CPU_PCI_DEVS][CPU_PCI_FUNCS];
418472SSean.Ye@Sun.COM
428472SSean.Ye@Sun.COM void
nhm_pci_cfg_setup(dev_info_t * dip)438472SSean.Ye@Sun.COM nhm_pci_cfg_setup(dev_info_t *dip)
448472SSean.Ye@Sun.COM {
458472SSean.Ye@Sun.COM pci_regspec_t reg;
468472SSean.Ye@Sun.COM int i, j, k;
478472SSean.Ye@Sun.COM
488472SSean.Ye@Sun.COM reg.pci_phys_mid = 0;
498472SSean.Ye@Sun.COM reg.pci_phys_low = 0;
508472SSean.Ye@Sun.COM reg.pci_size_hi = 0;
518472SSean.Ye@Sun.COM reg.pci_size_low = PCIE_CONF_HDR_SIZE; /* overriden in pciex */
528472SSean.Ye@Sun.COM for (i = 0; i < MAX_CPU_NODES; i++) {
538472SSean.Ye@Sun.COM for (j = 0; j < CPU_PCI_DEVS; j++) {
548472SSean.Ye@Sun.COM for (k = 0; k < CPU_PCI_FUNCS; k++) {
558472SSean.Ye@Sun.COM reg.pci_phys_hi = ((SOCKET_BUS(i))
568472SSean.Ye@Sun.COM << PCI_REG_BUS_SHIFT) +
578472SSean.Ye@Sun.COM (j << PCI_REG_DEV_SHIFT) +
588472SSean.Ye@Sun.COM (k << PCI_REG_FUNC_SHIFT);
598472SSean.Ye@Sun.COM if (ddi_prop_update_int_array(
608472SSean.Ye@Sun.COM DDI_MAJOR_T_UNKNOWN, dip, "reg",
618472SSean.Ye@Sun.COM (int *)®, sizeof (reg)/sizeof (int)) !=
628472SSean.Ye@Sun.COM DDI_PROP_SUCCESS)
638472SSean.Ye@Sun.COM cmn_err(CE_WARN, "nhm_pci_cfg_setup: "
648472SSean.Ye@Sun.COM "cannot create reg property");
658472SSean.Ye@Sun.COM
668472SSean.Ye@Sun.COM if (pci_config_setup(dip,
678472SSean.Ye@Sun.COM &dev_pci_hdl[i][j][k]) != DDI_SUCCESS)
688472SSean.Ye@Sun.COM cmn_err(CE_WARN, "intel_nhm: "
698472SSean.Ye@Sun.COM "pci_config_setup failed");
708472SSean.Ye@Sun.COM }
718472SSean.Ye@Sun.COM }
728472SSean.Ye@Sun.COM }
73*9783SAdrian.Frost@Sun.COM ddi_prop_remove_all(dip);
748472SSean.Ye@Sun.COM }
758472SSean.Ye@Sun.COM
768472SSean.Ye@Sun.COM void
nhm_pci_cfg_free()778472SSean.Ye@Sun.COM nhm_pci_cfg_free()
788472SSean.Ye@Sun.COM {
798472SSean.Ye@Sun.COM int i, j, k;
808472SSean.Ye@Sun.COM
818472SSean.Ye@Sun.COM for (i = 0; i < MAX_CPU_NODES; i++) {
828472SSean.Ye@Sun.COM for (j = 0; j < CPU_PCI_DEVS; j++) {
838472SSean.Ye@Sun.COM for (k = 0; k < CPU_PCI_FUNCS; k++) {
848472SSean.Ye@Sun.COM pci_config_teardown(&dev_pci_hdl[i][j][k]);
858472SSean.Ye@Sun.COM }
868472SSean.Ye@Sun.COM }
878472SSean.Ye@Sun.COM }
888472SSean.Ye@Sun.COM }
898472SSean.Ye@Sun.COM
908472SSean.Ye@Sun.COM static ddi_acc_handle_t
nhm_get_hdl(int bus,int dev,int func)918472SSean.Ye@Sun.COM nhm_get_hdl(int bus, int dev, int func)
928472SSean.Ye@Sun.COM {
938472SSean.Ye@Sun.COM ddi_acc_handle_t hdl;
948472SSean.Ye@Sun.COM int slot;
958472SSean.Ye@Sun.COM
968472SSean.Ye@Sun.COM if (bus >= SOCKET_BUS(MAX_CPU_NODES) && bus <= SOCKET_BUS(0) &&
978472SSean.Ye@Sun.COM dev < CPU_PCI_DEVS && func < CPU_PCI_FUNCS) {
988472SSean.Ye@Sun.COM slot = SOCKET_BUS(0) - bus;
998472SSean.Ye@Sun.COM ASSERT(slot >= 0 && slot < MAX_CPU_NODES);
1008472SSean.Ye@Sun.COM hdl = dev_pci_hdl[slot][dev][func];
1018472SSean.Ye@Sun.COM } else {
1028472SSean.Ye@Sun.COM hdl = 0;
1038472SSean.Ye@Sun.COM }
1048472SSean.Ye@Sun.COM return (hdl);
1058472SSean.Ye@Sun.COM }
1068472SSean.Ye@Sun.COM
1078472SSean.Ye@Sun.COM uint8_t
nhm_pci_getb(int bus,int dev,int func,int reg,int * interpose)1088472SSean.Ye@Sun.COM nhm_pci_getb(int bus, int dev, int func, int reg, int *interpose)
1098472SSean.Ye@Sun.COM {
1108472SSean.Ye@Sun.COM ddi_acc_handle_t hdl;
1118472SSean.Ye@Sun.COM
1128472SSean.Ye@Sun.COM hdl = nhm_get_hdl(bus, dev, func);
1138472SSean.Ye@Sun.COM return (cmi_pci_getb(bus, dev, func, reg, interpose, hdl));
1148472SSean.Ye@Sun.COM }
1158472SSean.Ye@Sun.COM
1168472SSean.Ye@Sun.COM uint16_t
nhm_pci_getw(int bus,int dev,int func,int reg,int * interpose)1178472SSean.Ye@Sun.COM nhm_pci_getw(int bus, int dev, int func, int reg, int *interpose)
1188472SSean.Ye@Sun.COM {
1198472SSean.Ye@Sun.COM ddi_acc_handle_t hdl;
1208472SSean.Ye@Sun.COM
1218472SSean.Ye@Sun.COM hdl = nhm_get_hdl(bus, dev, func);
1228472SSean.Ye@Sun.COM return (cmi_pci_getw(bus, dev, func, reg, interpose, hdl));
1238472SSean.Ye@Sun.COM }
1248472SSean.Ye@Sun.COM
1258472SSean.Ye@Sun.COM uint32_t
nhm_pci_getl(int bus,int dev,int func,int reg,int * interpose)1268472SSean.Ye@Sun.COM nhm_pci_getl(int bus, int dev, int func, int reg, int *interpose)
1278472SSean.Ye@Sun.COM {
1288472SSean.Ye@Sun.COM ddi_acc_handle_t hdl;
1298472SSean.Ye@Sun.COM
1308472SSean.Ye@Sun.COM hdl = nhm_get_hdl(bus, dev, func);
1318472SSean.Ye@Sun.COM return (cmi_pci_getl(bus, dev, func, reg, interpose, hdl));
1328472SSean.Ye@Sun.COM }
1338472SSean.Ye@Sun.COM
1348472SSean.Ye@Sun.COM void
nhm_pci_putb(int bus,int dev,int func,int reg,uint8_t val)1358472SSean.Ye@Sun.COM nhm_pci_putb(int bus, int dev, int func, int reg, uint8_t val)
1368472SSean.Ye@Sun.COM {
1378472SSean.Ye@Sun.COM ddi_acc_handle_t hdl;
1388472SSean.Ye@Sun.COM
1398472SSean.Ye@Sun.COM hdl = nhm_get_hdl(bus, dev, func);
1408472SSean.Ye@Sun.COM cmi_pci_putb(bus, dev, func, reg, hdl, val);
1418472SSean.Ye@Sun.COM }
1428472SSean.Ye@Sun.COM
1438472SSean.Ye@Sun.COM void
nhm_pci_putw(int bus,int dev,int func,int reg,uint16_t val)1448472SSean.Ye@Sun.COM nhm_pci_putw(int bus, int dev, int func, int reg, uint16_t val)
1458472SSean.Ye@Sun.COM {
1468472SSean.Ye@Sun.COM ddi_acc_handle_t hdl;
1478472SSean.Ye@Sun.COM
1488472SSean.Ye@Sun.COM hdl = nhm_get_hdl(bus, dev, func);
1498472SSean.Ye@Sun.COM cmi_pci_putw(bus, dev, func, reg, hdl, val);
1508472SSean.Ye@Sun.COM }
1518472SSean.Ye@Sun.COM
1528472SSean.Ye@Sun.COM void
nhm_pci_putl(int bus,int dev,int func,int reg,uint32_t val)1538472SSean.Ye@Sun.COM nhm_pci_putl(int bus, int dev, int func, int reg, uint32_t val)
1548472SSean.Ye@Sun.COM {
1558472SSean.Ye@Sun.COM ddi_acc_handle_t hdl;
1568472SSean.Ye@Sun.COM
1578472SSean.Ye@Sun.COM hdl = nhm_get_hdl(bus, dev, func);
1588472SSean.Ye@Sun.COM cmi_pci_putl(bus, dev, func, reg, hdl, val);
1598472SSean.Ye@Sun.COM }
160