cim_msr.c revision f29dbc25
1f29dbc25Smrg/*
2f29dbc25Smrg * Copyright (c) 2006 Advanced Micro Devices, Inc.
3f29dbc25Smrg *
4f29dbc25Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5f29dbc25Smrg * copy of this software and associated documentation files (the "Software"),
6f29dbc25Smrg * to deal in the Software without restriction, including without limitation
7f29dbc25Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8f29dbc25Smrg * and/or sell copies of the Software, and to permit persons to whom the
9f29dbc25Smrg * Software is furnished to do so, subject to the following conditions:
10f29dbc25Smrg *
11f29dbc25Smrg * The above copyright notice and this permission notice shall be included in
12f29dbc25Smrg * all copies or substantial portions of the Software.
13f29dbc25Smrg *
14f29dbc25Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15f29dbc25Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16f29dbc25Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17f29dbc25Smrg * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18f29dbc25Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19f29dbc25Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20f29dbc25Smrg * DEALINGS IN THE SOFTWARE.
21f29dbc25Smrg *
22f29dbc25Smrg * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
23f29dbc25Smrg * contributors may be used to endorse or promote products derived from this
24f29dbc25Smrg * software without specific prior written permission.
25f29dbc25Smrg */
26f29dbc25Smrg
27f29dbc25Smrg /*
28f29dbc25Smrg  * Cimarron MSR access routines.  These routines allow the user to query the
29f29dbc25Smrg  * state of the GeodeLink Bus and read and write model-specfic registers.
30f29dbc25Smrg  */
31f29dbc25Smrg
32f29dbc25Smrg/*--------------------------------------------------------------*/
33f29dbc25Smrg/* MSR GLOBALS                                                  */
34f29dbc25Smrg/* These variables hold a local copy of the GeodeLink mapping   */
35f29dbc25Smrg/* as well as a lookup table for easy device addressing.        */
36f29dbc25Smrg/*--------------------------------------------------------------*/
37f29dbc25Smrg
38f29dbc25SmrgGEODELINK_NODE gliu_nodes[24];
39f29dbc25SmrgGEODELINK_NODE msr_dev_lookup[MSR_DEVICE_EMPTY];
40f29dbc25Smrg
41f29dbc25Smrg#define GET_DEVICE_ID(macrohigh, macrolow) ((macrolow >> 12) & 0xFF)
42f29dbc25Smrg
43f29dbc25Smrg/*---------------------------------------------------------------------------
44f29dbc25Smrg * msr_init_table
45f29dbc25Smrg *
46f29dbc25Smrg * This routine intializes the internal MSR table in Cimarron.  This table is
47f29dbc25Smrg * used for any MSR device accesses.
48f29dbc25Smrg *--------------------------------------------------------------------------*/
49f29dbc25Smrg
50f29dbc25Smrgint
51f29dbc25Smrgmsr_init_table(void)
52f29dbc25Smrg{
53f29dbc25Smrg    Q_WORD msr_value = {0, 0};
54f29dbc25Smrg    unsigned int i, j;
55f29dbc25Smrg    int return_value = CIM_STATUS_OK;
56f29dbc25Smrg
57f29dbc25Smrg    /* CHECK FOR VALID GEODELINK CONFIGURATION
58f29dbc25Smrg     * The CPU and the three GLIUs are assumed to be at known static
59f29dbc25Smrg     * addresses, so we will check the device IDs at these addresses as proof
60f29dbc25Smrg     * of a valid GeodeLink configuration
61f29dbc25Smrg     */
62f29dbc25Smrg
63f29dbc25Smrg    MSR_READ(MSR_GEODELINK_CAP, MSR_ADDRESS_VAIL, &msr_value);
64f29dbc25Smrg    if (GET_DEVICE_ID(msr_value.high, msr_value.low) != MSR_CLASS_CODE_VAIL)
65f29dbc25Smrg        return_value = CIM_STATUS_ERROR;
66f29dbc25Smrg
67f29dbc25Smrg    MSR_READ(MSR_GEODELINK_CAP, MSR_ADDRESS_GLIU0, &msr_value);
68f29dbc25Smrg    if (GET_DEVICE_ID(msr_value.high, msr_value.low) != MSR_CLASS_CODE_GLIU)
69f29dbc25Smrg        return_value = CIM_STATUS_ERROR;
70f29dbc25Smrg
71f29dbc25Smrg    MSR_READ(MSR_GEODELINK_CAP, MSR_ADDRESS_GLIU1, &msr_value);
72f29dbc25Smrg    if (GET_DEVICE_ID(msr_value.high, msr_value.low) != MSR_CLASS_CODE_GLIU)
73f29dbc25Smrg        return_value = CIM_STATUS_ERROR;
74f29dbc25Smrg
75f29dbc25Smrg    MSR_READ(MSR_GEODELINK_CAP, MSR_ADDRESS_GLIU2, &msr_value);
76f29dbc25Smrg    if (GET_DEVICE_ID(msr_value.high, msr_value.low) != MSR_CLASS_CODE_GLIU)
77f29dbc25Smrg        return_value = CIM_STATUS_ERROR;
78f29dbc25Smrg
79f29dbc25Smrg    if (return_value == CIM_STATUS_OK) {
80f29dbc25Smrg        /* BUILD LOCAL COPY OF THE GEODELINK BUS */
81f29dbc25Smrg
82f29dbc25Smrg        msr_create_geodelink_table(gliu_nodes);
83f29dbc25Smrg
84f29dbc25Smrg        /* CLEAR TABLE STATUS */
85f29dbc25Smrg
86f29dbc25Smrg        for (i = 0; i < MSR_DEVICE_EMPTY; i++)
87f29dbc25Smrg            msr_dev_lookup[i].device_id = MSR_DEVICE_NOTFOUND;
88f29dbc25Smrg
89f29dbc25Smrg        /* CREATE EASY LOOKUP TABLE FOR FUTURE HARDWARE ACCESS    */
90f29dbc25Smrg        /* Note that MSR_DEVICE_EMPTY is the index after the last */
91f29dbc25Smrg        /* available device.  Also note that we fill in known     */
92f29dbc25Smrg        /* devices before filling in the rest of the table.       */
93f29dbc25Smrg
94f29dbc25Smrg        msr_dev_lookup[MSR_DEVICE_GEODELX_GLIU0].address_from_cpu =
95f29dbc25Smrg            MSR_ADDRESS_GLIU0;
96f29dbc25Smrg        msr_dev_lookup[MSR_DEVICE_GEODELX_GLIU0].device_id =
97f29dbc25Smrg            MSR_DEVICE_PRESENT;
98f29dbc25Smrg        msr_dev_lookup[MSR_DEVICE_GEODELX_GLIU1].address_from_cpu =
99f29dbc25Smrg            MSR_ADDRESS_GLIU1;
100f29dbc25Smrg        msr_dev_lookup[MSR_DEVICE_GEODELX_GLIU1].device_id =
101f29dbc25Smrg            MSR_DEVICE_PRESENT;
102f29dbc25Smrg        msr_dev_lookup[MSR_DEVICE_5535_GLIU].address_from_cpu =
103f29dbc25Smrg            MSR_ADDRESS_GLIU2;
104f29dbc25Smrg        msr_dev_lookup[MSR_DEVICE_5535_GLIU].device_id = MSR_DEVICE_PRESENT;
105f29dbc25Smrg        msr_dev_lookup[MSR_DEVICE_GEODELX_VAIL].address_from_cpu =
106f29dbc25Smrg            MSR_ADDRESS_VAIL;
107f29dbc25Smrg        msr_dev_lookup[MSR_DEVICE_GEODELX_VAIL].device_id =
108f29dbc25Smrg            MSR_DEVICE_PRESENT;
109f29dbc25Smrg
110f29dbc25Smrg        for (i = 0; i < MSR_DEVICE_EMPTY; i++) {
111f29dbc25Smrg            if (msr_dev_lookup[i].device_id == MSR_DEVICE_NOTFOUND) {
112f29dbc25Smrg                for (j = 0; j < 24; j++) {
113f29dbc25Smrg                    if (gliu_nodes[j].device_id == i)
114f29dbc25Smrg                        break;
115f29dbc25Smrg                }
116f29dbc25Smrg
117f29dbc25Smrg                if (j == 24)
118f29dbc25Smrg                    msr_dev_lookup[i].device_id = MSR_DEVICE_NOTFOUND;
119f29dbc25Smrg                else {
120f29dbc25Smrg                    msr_dev_lookup[i].device_id = MSR_DEVICE_PRESENT;
121f29dbc25Smrg                    msr_dev_lookup[i].address_from_cpu =
122f29dbc25Smrg                        gliu_nodes[j].address_from_cpu;
123f29dbc25Smrg                }
124f29dbc25Smrg            }
125f29dbc25Smrg        }
126f29dbc25Smrg    } else {
127f29dbc25Smrg        /* ERROR OUT THE GEODELINK TABLES */
128f29dbc25Smrg
129f29dbc25Smrg        for (i = 0; i < 24; i++) {
130f29dbc25Smrg            gliu_nodes[i].address_from_cpu = 0xFFFFFFFF;
131f29dbc25Smrg            gliu_nodes[i].device_id = MSR_DEVICE_EMPTY;
132f29dbc25Smrg        }
133f29dbc25Smrg
134f29dbc25Smrg        for (i = 0; i < MSR_DEVICE_EMPTY; i++) {
135f29dbc25Smrg            msr_dev_lookup[i].address_from_cpu = 0xFFFFFFFF;
136f29dbc25Smrg            msr_dev_lookup[i].device_id = MSR_DEVICE_NOTFOUND;
137f29dbc25Smrg        }
138f29dbc25Smrg    }
139f29dbc25Smrg    return return_value;
140f29dbc25Smrg}
141f29dbc25Smrg
142f29dbc25Smrg/*---------------------------------------------------------------------------
143f29dbc25Smrg * msr_create_geodelink_table
144f29dbc25Smrg *
145f29dbc25Smrg * This routine dumps the contents of the GeodeLink bus into an array of
146f29dbc25Smrg * 24 GEODELINK_NODE structures.  Indexes 0-7 represent ports 0-7 of GLIU0,
147f29dbc25Smrg * indexes 8-15 represent ports 0-7 of GLIU1 and indexes 16-23 represent
148f29dbc25Smrg * ports 0-7 of GLIU2 (5535).
149f29dbc25Smrg *--------------------------------------------------------------------------*/
150f29dbc25Smrg
151f29dbc25Smrgint
152f29dbc25Smrgmsr_create_geodelink_table(GEODELINK_NODE * gliu_nodes)
153f29dbc25Smrg{
154f29dbc25Smrg    unsigned long mbiu_port_count, reflective;
155f29dbc25Smrg    unsigned long port, index;
156f29dbc25Smrg    unsigned long gliu_count = 0;
157f29dbc25Smrg    int glcp_count = 0;
158f29dbc25Smrg    int usb_count = 0;
159f29dbc25Smrg    int mpci_count = 0;
160f29dbc25Smrg    Q_WORD msr_value = {0, 0};
161f29dbc25Smrg
162f29dbc25Smrg    /* ALL THREE GLIUS ARE IN ONE ARRAY                               */
163f29dbc25Smrg    /* Entries 0-7 contain the port information for GLIU0, entries    */
164f29dbc25Smrg    /* 8-15 contain GLIU1 and 15-23 contain GLIU2.  We perform the    */
165f29dbc25Smrg    /* enumeration in two passes.  The first simply fills in the      */
166f29dbc25Smrg    /* addresses and class codes at each node.  The second pass       */
167f29dbc25Smrg    /* translates the class codes into indexes into Cimarron's device */
168f29dbc25Smrg    /* lookup table.                                                  */
169f29dbc25Smrg
170f29dbc25Smrg    /* COUNT GLIU0 PORTS */
171f29dbc25Smrg
172f29dbc25Smrg    MSR_READ(MSR_GLIU_CAP, MSR_ADDRESS_GLIU0, &msr_value);
173f29dbc25Smrg    mbiu_port_count = (msr_value.high >> NUM_PORTS_SHIFT) & 7;
174f29dbc25Smrg
175f29dbc25Smrg    /* FIND REFLECTIVE PORT */
176f29dbc25Smrg    /* Query the GLIU for the port through which we are communicating. */
177f29dbc25Smrg    /* We will avoid accesses to this port to avoid a self-reference.  */
178f29dbc25Smrg
179f29dbc25Smrg    MSR_READ(MSR_GLIU_WHOAMI, MSR_ADDRESS_GLIU0, &msr_value);
180f29dbc25Smrg    reflective = msr_value.low & WHOAMI_MASK;
181f29dbc25Smrg
182f29dbc25Smrg    /* SPECIAL CASE FOR PORT 0 */
183f29dbc25Smrg    /* GLIU0 port 0 is a special case, as it points back to GLIU0.  GLIU0 */
184f29dbc25Smrg    /* responds at address 0x10000xxx, which does not equal 0 << 29.      */
185f29dbc25Smrg
186f29dbc25Smrg    gliu_nodes[0].address_from_cpu = MSR_ADDRESS_GLIU0;
187f29dbc25Smrg    gliu_nodes[0].device_id = MSR_CLASS_CODE_GLIU;
188f29dbc25Smrg
189f29dbc25Smrg    /* ENUMERATE ALL PORTS */
190f29dbc25Smrg
191f29dbc25Smrg    for (port = 1; port < 8; port++) {
192f29dbc25Smrg        /* FILL IN ADDRESS */
193f29dbc25Smrg
194f29dbc25Smrg        gliu_nodes[port].address_from_cpu = port << 29;
195f29dbc25Smrg
196f29dbc25Smrg        if (port == reflective)
197f29dbc25Smrg            gliu_nodes[port].device_id = MSR_CLASS_CODE_REFLECTIVE;
198f29dbc25Smrg        else if (port > mbiu_port_count)
199f29dbc25Smrg            gliu_nodes[port].device_id = MSR_CLASS_CODE_UNPOPULATED;
200f29dbc25Smrg        else {
201f29dbc25Smrg            MSR_READ(MSR_GEODELINK_CAP, gliu_nodes[port].address_from_cpu,
202f29dbc25Smrg                &msr_value);
203f29dbc25Smrg            gliu_nodes[port].device_id =
204f29dbc25Smrg                GET_DEVICE_ID(msr_value.high, msr_value.low);
205f29dbc25Smrg        }
206f29dbc25Smrg    }
207f29dbc25Smrg
208f29dbc25Smrg    /* COUNT GLIU1 PORTS */
209f29dbc25Smrg
210f29dbc25Smrg    MSR_READ(MSR_GLIU_CAP, MSR_ADDRESS_GLIU1, &msr_value);
211f29dbc25Smrg    mbiu_port_count = (msr_value.high >> NUM_PORTS_SHIFT) & 7;
212f29dbc25Smrg
213f29dbc25Smrg    /* FIND REFLECTIVE PORT */
214f29dbc25Smrg
215f29dbc25Smrg    MSR_READ(MSR_GLIU_WHOAMI, MSR_ADDRESS_GLIU1, &msr_value);
216f29dbc25Smrg    reflective = msr_value.low & WHOAMI_MASK;
217f29dbc25Smrg
218f29dbc25Smrg    /* ENUMERATE ALL PORTS */
219f29dbc25Smrg
220f29dbc25Smrg    for (port = 0; port < 8; port++) {
221f29dbc25Smrg        index = port + 8;
222f29dbc25Smrg
223f29dbc25Smrg        /* FILL IN ADDRESS */
224f29dbc25Smrg
225f29dbc25Smrg        gliu_nodes[index].address_from_cpu = (0x02l << 29) + (port << 26);
226f29dbc25Smrg
227f29dbc25Smrg        if (port == reflective)
228f29dbc25Smrg            gliu_nodes[index].device_id = MSR_CLASS_CODE_REFLECTIVE;
229f29dbc25Smrg        else if (port > mbiu_port_count)
230f29dbc25Smrg            gliu_nodes[index].device_id = MSR_CLASS_CODE_UNPOPULATED;
231f29dbc25Smrg        else {
232f29dbc25Smrg            MSR_READ(MSR_GEODELINK_CAP, gliu_nodes[index].address_from_cpu,
233f29dbc25Smrg                &msr_value);
234f29dbc25Smrg            gliu_nodes[index].device_id =
235f29dbc25Smrg                GET_DEVICE_ID(msr_value.high, msr_value.low);
236f29dbc25Smrg        }
237f29dbc25Smrg    }
238f29dbc25Smrg
239f29dbc25Smrg    /* COUNT GLIU2 PORTS */
240f29dbc25Smrg
241f29dbc25Smrg    MSR_READ(MSR_GLIU_CAP, MSR_ADDRESS_GLIU2, &msr_value);
242f29dbc25Smrg    mbiu_port_count = (msr_value.high >> NUM_PORTS_SHIFT) & 7;
243f29dbc25Smrg
244f29dbc25Smrg    /* FIND REFLECTIVE PORT */
245f29dbc25Smrg
246f29dbc25Smrg    MSR_READ(MSR_GLIU_WHOAMI, MSR_ADDRESS_GLIU2, &msr_value);
247f29dbc25Smrg    reflective = msr_value.low & WHOAMI_MASK;
248f29dbc25Smrg
249f29dbc25Smrg    /* FILL IN PORT 0 AND 1 */
250f29dbc25Smrg    /* Port 0 on 5535 is MBIU2.  Port 1 is MPCI, but it is referenced at */
251f29dbc25Smrg    /* a special address.                                                */
252f29dbc25Smrg
253f29dbc25Smrg    gliu_nodes[16].address_from_cpu = MSR_ADDRESS_GLIU2;
254f29dbc25Smrg    gliu_nodes[16].device_id = MSR_CLASS_CODE_GLIU;
255f29dbc25Smrg
256f29dbc25Smrg    gliu_nodes[17].address_from_cpu = MSR_ADDRESS_5535MPCI;
257f29dbc25Smrg    gliu_nodes[17].device_id = MSR_CLASS_CODE_MPCI;
258f29dbc25Smrg
259f29dbc25Smrg    /* ENUMERATE ALL PORTS */
260f29dbc25Smrg
261f29dbc25Smrg    for (port = 2; port < 8; port++) {
262f29dbc25Smrg        index = port + 16;
263f29dbc25Smrg
264f29dbc25Smrg        /* FILL IN ADDRESS */
265f29dbc25Smrg
266f29dbc25Smrg        gliu_nodes[index].address_from_cpu =
267f29dbc25Smrg            (0x02l << 29) + (0x04l << 26) + (0x02l << 23) + (port << 20);
268f29dbc25Smrg
269f29dbc25Smrg        if (port == reflective)
270f29dbc25Smrg            gliu_nodes[index].device_id = MSR_CLASS_CODE_REFLECTIVE;
271f29dbc25Smrg        else if (port > mbiu_port_count)
272f29dbc25Smrg            gliu_nodes[index].device_id = MSR_CLASS_CODE_UNPOPULATED;
273f29dbc25Smrg        else {
274f29dbc25Smrg            MSR_READ(MSR_GEODELINK_CAP, gliu_nodes[index].address_from_cpu,
275f29dbc25Smrg                &msr_value);
276f29dbc25Smrg            gliu_nodes[index].device_id =
277f29dbc25Smrg                GET_DEVICE_ID(msr_value.high, msr_value.low);
278f29dbc25Smrg        }
279f29dbc25Smrg    }
280f29dbc25Smrg
281f29dbc25Smrg    /* SECOND PASS - TRANSLATION */
282f29dbc25Smrg    /* Now that the class codes for each device are stored in the  */
283f29dbc25Smrg    /* array, we walk through the array and translate the class    */
284f29dbc25Smrg    /* codes to table indexes.  For class codes that have multiple */
285f29dbc25Smrg    /* instances, the table indexes are sequential.                */
286f29dbc25Smrg
287f29dbc25Smrg    for (port = 0; port < 24; port++) {
288f29dbc25Smrg        /* SPECIAL CASE FOR GLIU UNITS */
289f29dbc25Smrg        /* A GLIU can be both on another port and on its own port.  These  */
290f29dbc25Smrg        /* end up as the same address, but are shown as duplicate nodes in */
291f29dbc25Smrg        /* the GeodeLink table.                                            */
292f29dbc25Smrg
293f29dbc25Smrg        if ((port & 7) == 0)
294f29dbc25Smrg            gliu_count = port >> 3;
295f29dbc25Smrg
296f29dbc25Smrg        switch (gliu_nodes[port].device_id) {
297f29dbc25Smrg            /* UNPOPULATED OR REFLECTIVE NODES */
298f29dbc25Smrg
299f29dbc25Smrg        case MSR_CLASS_CODE_UNPOPULATED:
300f29dbc25Smrg            index = MSR_DEVICE_EMPTY;
301f29dbc25Smrg            break;
302f29dbc25Smrg        case MSR_CLASS_CODE_REFLECTIVE:
303f29dbc25Smrg            index = MSR_DEVICE_REFLECTIVE;
304f29dbc25Smrg            break;
305f29dbc25Smrg
306f29dbc25Smrg            /* KNOWN CLASS CODES */
307f29dbc25Smrg
308f29dbc25Smrg        case MSR_CLASS_CODE_GLIU:
309f29dbc25Smrg            index = MSR_DEVICE_GEODELX_GLIU0 + gliu_count++;
310f29dbc25Smrg            break;
311f29dbc25Smrg        case MSR_CLASS_CODE_GLCP:
312f29dbc25Smrg            index = MSR_DEVICE_GEODELX_GLCP + glcp_count++;
313f29dbc25Smrg            break;
314f29dbc25Smrg        case MSR_CLASS_CODE_MPCI:
315f29dbc25Smrg            index = MSR_DEVICE_GEODELX_MPCI + mpci_count++;
316f29dbc25Smrg            break;
317f29dbc25Smrg        case MSR_CLASS_CODE_USB:
318f29dbc25Smrg            index = MSR_DEVICE_5535_USB2 + usb_count++;
319f29dbc25Smrg            break;
320f29dbc25Smrg        case MSR_CLASS_CODE_USB2:
321f29dbc25Smrg            index = MSR_DEVICE_5536_USB_2_0;
322f29dbc25Smrg            break;
323f29dbc25Smrg        case MSR_CLASS_CODE_ATAC:
324f29dbc25Smrg            index = MSR_DEVICE_5535_ATAC;
325f29dbc25Smrg            break;
326f29dbc25Smrg        case MSR_CLASS_CODE_MDD:
327f29dbc25Smrg            index = MSR_DEVICE_5535_MDD;
328f29dbc25Smrg            break;
329f29dbc25Smrg        case MSR_CLASS_CODE_ACC:
330f29dbc25Smrg            index = MSR_DEVICE_5535_ACC;
331f29dbc25Smrg            break;
332f29dbc25Smrg        case MSR_CLASS_CODE_MC:
333f29dbc25Smrg            index = MSR_DEVICE_GEODELX_MC;
334f29dbc25Smrg            break;
335f29dbc25Smrg        case MSR_CLASS_CODE_GP:
336f29dbc25Smrg            index = MSR_DEVICE_GEODELX_GP;
337f29dbc25Smrg            break;
338f29dbc25Smrg        case MSR_CLASS_CODE_VG:
339f29dbc25Smrg            index = MSR_DEVICE_GEODELX_VG;
340f29dbc25Smrg            break;
341f29dbc25Smrg        case MSR_CLASS_CODE_DF:
342f29dbc25Smrg            index = MSR_DEVICE_GEODELX_DF;
343f29dbc25Smrg            break;
344f29dbc25Smrg        case MSR_CLASS_CODE_FG:
345f29dbc25Smrg            index = MSR_DEVICE_GEODELX_FG;
346f29dbc25Smrg            break;
347f29dbc25Smrg        case MSR_CLASS_CODE_VIP:
348f29dbc25Smrg            index = MSR_DEVICE_GEODELX_VIP;
349f29dbc25Smrg            break;
350f29dbc25Smrg        case MSR_CLASS_CODE_AES:
351f29dbc25Smrg            index = MSR_DEVICE_GEODELX_AES;
352f29dbc25Smrg            break;
353f29dbc25Smrg        case MSR_CLASS_CODE_VAIL:
354f29dbc25Smrg            index = MSR_DEVICE_GEODELX_VAIL;
355f29dbc25Smrg            break;
356f29dbc25Smrg        default:
357f29dbc25Smrg            index = MSR_DEVICE_EMPTY;
358f29dbc25Smrg            break;
359f29dbc25Smrg        }
360f29dbc25Smrg
361f29dbc25Smrg        gliu_nodes[port].device_id = index;
362f29dbc25Smrg    }
363f29dbc25Smrg
364f29dbc25Smrg    return CIM_STATUS_OK;
365f29dbc25Smrg}
366f29dbc25Smrg
367f29dbc25Smrg/*---------------------------------------------------------------------------
368f29dbc25Smrg * msr_create_device_list
369f29dbc25Smrg *
370f29dbc25Smrg * This routine dumps a list of all known GeodeLX/5535 devices as well as their
371f29dbc25Smrg * respective status and address.
372f29dbc25Smrg *--------------------------------------------------------------------------*/
373f29dbc25Smrg
374f29dbc25Smrgint
375f29dbc25Smrgmsr_create_device_list(GEODELINK_NODE * gliu_nodes, int max_devices)
376f29dbc25Smrg{
377f29dbc25Smrg    int i, count;
378f29dbc25Smrg
379f29dbc25Smrg    if (max_devices < MSR_DEVICE_EMPTY)
380f29dbc25Smrg        count = max_devices;
381f29dbc25Smrg    else
382f29dbc25Smrg        count = MSR_DEVICE_EMPTY;
383f29dbc25Smrg
384f29dbc25Smrg    for (i = 0; i < count; i++) {
385f29dbc25Smrg        gliu_nodes[i].address_from_cpu = msr_dev_lookup[i].address_from_cpu;
386f29dbc25Smrg        gliu_nodes[i].device_id = msr_dev_lookup[i].device_id;
387f29dbc25Smrg    }
388f29dbc25Smrg
389f29dbc25Smrg    return CIM_STATUS_OK;
390f29dbc25Smrg}
391f29dbc25Smrg
392f29dbc25Smrg/*--------------------------------------------------------------------
393f29dbc25Smrg * msr_read64
394f29dbc25Smrg *
395f29dbc25Smrg * Performs a 64-bit read from 'msr_register' in device 'device'.  'device' is
396f29dbc25Smrg * an index into Cimarron's table of known GeodeLink devices.
397f29dbc25Smrg *-------------------------------------------------------------------*/
398f29dbc25Smrg
399f29dbc25Smrgint
400f29dbc25Smrgmsr_read64(unsigned long device, unsigned long msr_register,
401f29dbc25Smrg    Q_WORD * msr_value)
402f29dbc25Smrg{
403f29dbc25Smrg    if (device < MSR_DEVICE_EMPTY) {
404f29dbc25Smrg        if (msr_dev_lookup[device].device_id == MSR_DEVICE_PRESENT) {
405f29dbc25Smrg            MSR_READ(msr_register, msr_dev_lookup[device].address_from_cpu,
406f29dbc25Smrg                msr_value);
407f29dbc25Smrg            return CIM_STATUS_OK;
408f29dbc25Smrg        }
409f29dbc25Smrg    }
410f29dbc25Smrg
411f29dbc25Smrg    msr_value->low = msr_value->high = 0;
412f29dbc25Smrg    return CIM_STATUS_DEVNOTFOUND;
413f29dbc25Smrg}
414f29dbc25Smrg
415f29dbc25Smrg/*--------------------------------------------------------------------
416f29dbc25Smrg * msr_write64
417f29dbc25Smrg *
418f29dbc25Smrg * Performs a 64-bit write to 'msr_register' in device 'device'.  'device' is
419f29dbc25Smrg * an index into Cimarron's table of known GeodeLink devices.
420f29dbc25Smrg *-------------------------------------------------------------------*/
421f29dbc25Smrg
422f29dbc25Smrgint
423f29dbc25Smrgmsr_write64(unsigned long device, unsigned long msr_register,
424f29dbc25Smrg    Q_WORD * msr_value)
425f29dbc25Smrg{
426f29dbc25Smrg    if (device < MSR_DEVICE_EMPTY) {
427f29dbc25Smrg        if (msr_dev_lookup[device].device_id == MSR_DEVICE_PRESENT) {
428f29dbc25Smrg            MSR_WRITE(msr_register, msr_dev_lookup[device].address_from_cpu,
429f29dbc25Smrg                msr_value);
430f29dbc25Smrg            return CIM_STATUS_OK;
431f29dbc25Smrg        }
432f29dbc25Smrg    }
433f29dbc25Smrg    return CIM_STATUS_DEVNOTFOUND;
434f29dbc25Smrg}
435