nrelease - fix/improve livecd
[dragonfly.git] / sys / dev / misc / ecc / e5_imc_var.h
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_ */