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 2009 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 ddi_prop_remove_all(dip); 92 } 93 94 void 95 nb_pci_cfg_free() 96 { 97 int i; 98 99 for (i = 0; i < NB_PCI_NFUNC; i++) { 100 pci_config_teardown(&dev_16_hdl[i]); 101 } 102 for (i = 0; i < NB_PCI_NFUNC; i++) { 103 pci_config_teardown(&dev_17_hdl[i]); 104 } 105 for (i = 0; i < NB_PCI_DEV; i++) 106 pci_config_teardown(&dev_pci_hdl[i]); 107 } 108 109 static ddi_acc_handle_t 110 nb_get_hdl(int bus, int dev, int func) 111 { 112 ddi_acc_handle_t hdl; 113 114 if (bus == 0 && dev == 16 && func < NB_PCI_NFUNC) { 115 hdl = dev_16_hdl[func]; 116 } else if (bus == 0 && dev == 17 && func < NB_PCI_NFUNC) { 117 hdl = dev_17_hdl[func]; 118 } else if (bus == 0 && dev < NB_PCI_DEV && func == 0) { 119 hdl = dev_pci_hdl[dev]; 120 } else { 121 hdl = 0; 122 } 123 return (hdl); 124 } 125 126 uint8_t 127 nb_pci_getb(int bus, int dev, int func, int reg, int *interpose) 128 { 129 ddi_acc_handle_t hdl; 130 131 hdl = nb_get_hdl(bus, dev, func); 132 return (cmi_pci_getb(bus, dev, func, reg, interpose, hdl)); 133 } 134 135 uint16_t 136 nb_pci_getw(int bus, int dev, int func, int reg, int *interpose) 137 { 138 ddi_acc_handle_t hdl; 139 140 hdl = nb_get_hdl(bus, dev, func); 141 return (cmi_pci_getw(bus, dev, func, reg, interpose, hdl)); 142 } 143 144 uint32_t 145 nb_pci_getl(int bus, int dev, int func, int reg, int *interpose) 146 { 147 ddi_acc_handle_t hdl; 148 149 hdl = nb_get_hdl(bus, dev, func); 150 return (cmi_pci_getl(bus, dev, func, reg, interpose, hdl)); 151 } 152 153 void 154 nb_pci_putb(int bus, int dev, int func, int reg, uint8_t val) 155 { 156 ddi_acc_handle_t hdl; 157 158 hdl = nb_get_hdl(bus, dev, func); 159 cmi_pci_putb(bus, dev, func, reg, hdl, val); 160 } 161 162 void 163 nb_pci_putw(int bus, int dev, int func, int reg, uint16_t val) 164 { 165 ddi_acc_handle_t hdl; 166 167 hdl = nb_get_hdl(bus, dev, func); 168 cmi_pci_putw(bus, dev, func, reg, hdl, val); 169 } 170 171 void 172 nb_pci_putl(int bus, int dev, int func, int reg, uint32_t val) 173 { 174 ddi_acc_handle_t hdl; 175 176 hdl = nb_get_hdl(bus, dev, func); 177 cmi_pci_putl(bus, dev, func, reg, hdl, val); 178 } 179