1 #ifndef _E5_IMC_VAR_H_ 2 #define _E5_IMC_VAR_H_ 3 4 #define E5_IMC_CHAN_VER2 2 /* E5 v2 */ 5 #define E5_IMC_CHAN_VER3 3 /* E5 v3 */ 6 7 struct e5_imc_chan { 8 uint16_t did; 9 int slot; 10 int func; 11 const char *desc; 12 13 int chan_ext; /* external channel */ 14 int chan; 15 int ver; 16 17 int ubox_slot; 18 int ubox_func; 19 uint16_t ubox_did; 20 21 int cpgc_slot; 22 int cpgc_func; 23 uint16_t cpgc_did; 24 uint32_t cpgc_chandis; 25 26 int ctad_slot; 27 int ctad_func; 28 uint16_t ctad_did; 29 }; 30 31 #define E5_IMC_CHAN_END \ 32 { 0, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 33 34 #define E5_IMC_CHAN_FIELDS(v, imc, c, c_ext) \ 35 .chan_ext = c_ext, \ 36 .chan = c, \ 37 .ver = E5_IMC_CHAN_VER##v, \ 38 \ 39 .ubox_slot = PCISLOT_E5V##v##_UBOX0, \ 40 .ubox_func = PCIFUNC_E5V##v##_UBOX0, \ 41 .ubox_did = PCI_E5V##v##_UBOX0_DID_ID, \ 42 \ 43 .cpgc_slot = PCISLOT_E5V##v##_IMC##imc##_CPGC, \ 44 .cpgc_func = PCIFUNC_E5V##v##_IMC##imc##_CPGC, \ 45 .cpgc_did = PCI_E5V##v##_IMC##imc##_CPGC_DID_ID, \ 46 .cpgc_chandis = PCI_E5V##v##_IMC_CPGC_MCMTR_CHN_DISABLE(c), \ 47 \ 48 .ctad_slot = PCISLOT_E5V##v##_IMC##imc##_CTAD, \ 49 .ctad_func = PCIFUNC_E5V##v##_IMC##imc##_CTAD(c), \ 50 .ctad_did = PCI_E5V##v##_IMC##imc##_CTAD_DID_ID(c) \ 51 52 #define UBOX_READ(dev, c, ofs, w) \ 53 pcib_read_config((dev), pci_get_bus((dev)), \ 54 (c)->ubox_slot, (c)->ubox_func, (ofs), (w)) 55 #define UBOX_READ_2(dev, c, ofs) UBOX_READ((dev), (c), (ofs), 2) 56 #define UBOX_READ_4(dev, c, ofs) UBOX_READ((dev), (c), (ofs), 4) 57 58 #define IMC_CPGC_READ(dev, c, ofs, w) \ 59 pcib_read_config((dev), pci_get_bus((dev)), \ 60 (c)->cpgc_slot, (c)->cpgc_func, (ofs), (w)) 61 #define IMC_CPGC_READ_2(dev, c, ofs) IMC_CPGC_READ((dev), (c), (ofs), 2) 62 #define IMC_CPGC_READ_4(dev, c, ofs) IMC_CPGC_READ((dev), (c), (ofs), 4) 63 64 #define IMC_CTAD_READ(dev, c, ofs, w) \ 65 pcib_read_config((dev), pci_get_bus((dev)), \ 66 (c)->ctad_slot, (c)->ctad_func, (ofs), (w)) 67 #define IMC_CTAD_READ_2(dev, c, ofs) IMC_CTAD_READ((dev), (c), (ofs), 2) 68 #define IMC_CTAD_READ_4(dev, c, ofs) IMC_CTAD_READ((dev), (c), (ofs), 4) 69 70 static __inline int 71 e5_imc_node_probe(device_t dev, const struct e5_imc_chan *c) 72 { 73 int node, dimm; 74 uint32_t val; 75 76 /* Check CPGC vid/did */ 77 if (IMC_CPGC_READ_2(dev, c, PCIR_VENDOR) != PCI_E5_IMC_VID_ID || 78 IMC_CPGC_READ_2(dev, c, PCIR_DEVICE) != c->cpgc_did) 79 return -1; 80 81 /* Is this channel disabled */ 82 val = IMC_CPGC_READ_4(dev, c, PCI_E5_IMC_CPGC_MCMTR); 83 if (val & c->cpgc_chandis) 84 return -1; 85 86 /* Check CTAD vid/did */ 87 if (IMC_CTAD_READ_2(dev, c, PCIR_VENDOR) != PCI_E5_IMC_VID_ID || 88 IMC_CTAD_READ_2(dev, c, PCIR_DEVICE) != c->ctad_did) 89 return -1; 90 91 /* Are there any DIMMs populated? */ 92 for (dimm = 0; dimm < PCI_E5_IMC_CHN_DIMM_MAX; ++dimm) { 93 val = IMC_CTAD_READ_4(dev, c, PCI_E5_IMC_CTAD_DIMMMTR(dimm)); 94 if (val & PCI_E5_IMC_CTAD_DIMMMTR_DIMM_POP) 95 break; 96 } 97 if (dimm == PCI_E5_IMC_CHN_DIMM_MAX) 98 return -1; 99 100 /* Check UBOX vid/did */ 101 if (UBOX_READ_2(dev, c, PCIR_VENDOR) != PCI_E5_IMC_VID_ID || 102 UBOX_READ_2(dev, c, PCIR_DEVICE) != c->ubox_did) 103 return -1; 104 105 val = UBOX_READ_4(dev, c, PCI_E5_UBOX0_CPUNODEID); 106 node = __SHIFTOUT(val, PCI_E5_UBOX0_CPUNODEID_LCLNODEID); 107 108 return node; 109 } 110 111 #endif /* !_E5_IMC_VAR_H_ */ 112