1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <sys/types.h> 28 #include <sys/cmn_err.h> 29 #include <sys/errno.h> 30 #include <sys/systm.h> 31 #include <sys/sunddi.h> 32 #include <sys/pci_cfgspace.h> 33 #include <sys/pci.h> 34 #include <sys/pcie.h> 35 #include <vm/seg_kmem.h> 36 #include <sys/mman.h> 37 #include <sys/cpu_module.h> 38 #include "nb5000.h" 39 40 static ddi_acc_handle_t dev_16_hdl[NB_PCI_NFUNC]; 41 static ddi_acc_handle_t dev_17_hdl[NB_PCI_NFUNC]; 42 static ddi_acc_handle_t dev_pci_hdl[NB_PCI_DEV]; 43 44 void 45 nb_pci_cfg_setup(dev_info_t *dip) 46 { 47 pci_regspec_t reg; 48 int i; 49 50 reg.pci_phys_hi = 16 << PCI_REG_DEV_SHIFT; /* Bus=0, Dev=16, Func=0 */ 51 reg.pci_phys_mid = 0; 52 reg.pci_phys_low = 0; 53 reg.pci_size_hi = 0; 54 reg.pci_size_low = PCIE_CONF_HDR_SIZE; /* overriden in pciex */ 55 56 for (i = 0; i < NB_PCI_NFUNC; i++) { 57 if (ddi_prop_update_int_array(DDI_MAJOR_T_UNKNOWN, dip, "reg", 58 (int *)®, sizeof (reg)/sizeof (int)) != DDI_PROP_SUCCESS) 59 cmn_err(CE_WARN, 60 "nb_pci_cfg_setup: cannot create reg property"); 61 62 if (pci_config_setup(dip, &dev_16_hdl[i]) != DDI_SUCCESS) 63 cmn_err(CE_WARN, 64 "intel_nb5000: pci_config_setup failed"); 65 reg.pci_phys_hi += 1 << PCI_REG_FUNC_SHIFT; 66 } 67 reg.pci_phys_hi = 17 << PCI_REG_DEV_SHIFT; /* Bus=0, Dev=17, Func=0 */ 68 for (i = 0; i < NB_PCI_NFUNC; i++) { 69 if (ddi_prop_update_int_array(DDI_MAJOR_T_UNKNOWN, dip, "reg", 70 (int *)®, sizeof (reg)/sizeof (int)) != DDI_PROP_SUCCESS) 71 cmn_err(CE_WARN, 72 "nb_pci_cfg_setup: cannot create reg property"); 73 74 if (pci_config_setup(dip, &dev_17_hdl[i]) != DDI_SUCCESS) 75 cmn_err(CE_WARN, 76 "intel_nb5000: pci_config_setup failed"); 77 reg.pci_phys_hi += 1 << PCI_REG_FUNC_SHIFT; 78 } 79 reg.pci_phys_hi = 0; /* Bus=0, Dev=0, Func=0 */ 80 for (i = 0; i < NB_PCI_DEV; i++) { 81 if (ddi_prop_update_int_array(DDI_MAJOR_T_UNKNOWN, dip, "reg", 82 (int *)®, sizeof (reg)/sizeof (int)) != DDI_PROP_SUCCESS) 83 cmn_err(CE_WARN, 84 "nb_pci_cfg_setup: cannot create reg property"); 85 86 if (pci_config_setup(dip, &dev_pci_hdl[i]) != DDI_SUCCESS) 87 cmn_err(CE_WARN, 88 "intel_nb5000: pci_config_setup failed"); 89 reg.pci_phys_hi += 1 << PCI_REG_DEV_SHIFT; 90 } 91 } 92 93 void 94 nb_pci_cfg_free() 95 { 96 int i; 97 98 for (i = 0; i < NB_PCI_NFUNC; i++) { 99 pci_config_teardown(&dev_16_hdl[i]); 100 } 101 for (i = 0; i < NB_PCI_NFUNC; i++) { 102 pci_config_teardown(&dev_17_hdl[i]); 103 } 104 for (i = 0; i < NB_PCI_DEV; i++) 105 pci_config_teardown(&dev_pci_hdl[i]); 106 } 107 108 static ddi_acc_handle_t 109 nb_get_hdl(int bus, int dev, int func) 110 { 111 ddi_acc_handle_t hdl; 112 113 if (bus == 0 && dev == 16 && func < NB_PCI_NFUNC) { 114 hdl = dev_16_hdl[func]; 115 } else if (bus == 0 && dev == 17 && func < NB_PCI_NFUNC) { 116 hdl = dev_17_hdl[func]; 117 } else if (bus == 0 && dev < NB_PCI_DEV && func == 0) { 118 hdl = dev_pci_hdl[dev]; 119 } else { 120 hdl = 0; 121 } 122 return (hdl); 123 } 124 125 uint8_t 126 nb_pci_getb(int bus, int dev, int func, int reg, int *interpose) 127 { 128 ddi_acc_handle_t hdl; 129 130 hdl = nb_get_hdl(bus, dev, func); 131 return (cmi_pci_getb(bus, dev, func, reg, interpose, hdl)); 132 } 133 134 uint16_t 135 nb_pci_getw(int bus, int dev, int func, int reg, int *interpose) 136 { 137 ddi_acc_handle_t hdl; 138 139 hdl = nb_get_hdl(bus, dev, func); 140 return (cmi_pci_getw(bus, dev, func, reg, interpose, hdl)); 141 } 142 143 uint32_t 144 nb_pci_getl(int bus, int dev, int func, int reg, int *interpose) 145 { 146 ddi_acc_handle_t hdl; 147 148 hdl = nb_get_hdl(bus, dev, func); 149 return (cmi_pci_getl(bus, dev, func, reg, interpose, hdl)); 150 } 151 152 void 153 nb_pci_putb(int bus, int dev, int func, int reg, uint8_t val) 154 { 155 ddi_acc_handle_t hdl; 156 157 hdl = nb_get_hdl(bus, dev, func); 158 cmi_pci_putb(bus, dev, func, reg, hdl, val); 159 } 160 161 void 162 nb_pci_putw(int bus, int dev, int func, int reg, uint16_t val) 163 { 164 ddi_acc_handle_t hdl; 165 166 hdl = nb_get_hdl(bus, dev, func); 167 cmi_pci_putw(bus, dev, func, reg, hdl, val); 168 } 169 170 void 171 nb_pci_putl(int bus, int dev, int func, int reg, uint32_t val) 172 { 173 ddi_acc_handle_t hdl; 174 175 hdl = nb_get_hdl(bus, dev, func); 176 cmi_pci_putl(bus, dev, func, reg, hdl, val); 177 } 178