~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/msr_rdcl.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/msr_rdcl.c,v 1.1 2002/12/10 15:12:27 alanh Exp $ */
 
2
/*
 
3
 * $Workfile: msr_rdcl.c $
 
4
 *
 
5
 * This file contains MSR access routines for Redcloud.
 
6
 *
 
7
 * NSC_LIC_ALTERNATIVE_PREAMBLE
 
8
 *
 
9
 * Revision 1.0
 
10
 *
 
11
 * National Semiconductor Alternative GPL-BSD License
 
12
 *
 
13
 * National Semiconductor Corporation licenses this software 
 
14
 * ("Software"):
 
15
 *
 
16
 *      Durango
 
17
 *
 
18
 * under one of the two following licenses, depending on how the 
 
19
 * Software is received by the Licensee.
 
20
 * 
 
21
 * If this Software is received as part of the Linux Framebuffer or
 
22
 * other GPL licensed software, then the GPL license designated 
 
23
 * NSC_LIC_GPL applies to this Software; in all other circumstances 
 
24
 * then the BSD-style license designated NSC_LIC_BSD shall apply.
 
25
 *
 
26
 * END_NSC_LIC_ALTERNATIVE_PREAMBLE */
 
27
 
 
28
/* NSC_LIC_BSD
 
29
 *
 
30
 * National Semiconductor Corporation Open Source License for Durango
 
31
 *
 
32
 * (BSD License with Export Notice)
 
33
 *
 
34
 * Copyright (c) 1999-2001
 
35
 * National Semiconductor Corporation.
 
36
 * All rights reserved.
 
37
 *
 
38
 * Redistribution and use in source and binary forms, with or without 
 
39
 * modification, are permitted provided that the following conditions 
 
40
 * are met: 
 
41
 *
 
42
 *   * Redistributions of source code must retain the above copyright 
 
43
 *     notice, this list of conditions and the following disclaimer. 
 
44
 *
 
45
 *   * Redistributions in binary form must reproduce the above 
 
46
 *     copyright notice, this list of conditions and the following 
 
47
 *     disclaimer in the documentation and/or other materials provided 
 
48
 *     with the distribution. 
 
49
 *
 
50
 *   * Neither the name of the National Semiconductor Corporation nor 
 
51
 *     the names of its contributors may be used to endorse or promote 
 
52
 *     products derived from this software without specific prior 
 
53
 *     written permission. 
 
54
 * 
 
55
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 
56
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 
57
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 
58
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 
59
 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY 
 
60
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
 
61
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
 
62
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 
63
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 
 
64
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE,
 
65
 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY 
 
66
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
 
67
 * OF SUCH DAMAGE.
 
68
 *
 
69
 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF 
 
70
 * YOUR JURISDICTION. It is licensee's responsibility to comply with 
 
71
 * any export regulations applicable in licensee's jurisdiction. Under 
 
72
 * CURRENT (2001) U.S. export regulations this software 
 
73
 * is eligible for export from the U.S. and can be downloaded by or 
 
74
 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed 
 
75
 * destinations which include Cuba, Iraq, Libya, North Korea, Iran, 
 
76
 * Syria, Sudan, Afghanistan and any other country to which the U.S. 
 
77
 * has embargoed goods and services. 
 
78
 *
 
79
 * END_NSC_LIC_BSD */
 
80
 
 
81
/* NSC_LIC_GPL
 
82
 *
 
83
 * National Semiconductor Corporation Gnu General Public License for Durango
 
84
 *
 
85
 * (GPL License with Export Notice)
 
86
 *
 
87
 * Copyright (c) 1999-2001
 
88
 * National Semiconductor Corporation.
 
89
 * All rights reserved.
 
90
 *
 
91
 * Redistribution and use in source and binary forms, with or without 
 
92
 * modification, are permitted under the terms of the GNU General 
 
93
 * Public License as published by the Free Software Foundation; either 
 
94
 * version 2 of the License, or (at your option) any later version  
 
95
 *
 
96
 * In addition to the terms of the GNU General Public License, neither 
 
97
 * the name of the National Semiconductor Corporation nor the names of 
 
98
 * its contributors may be used to endorse or promote products derived 
 
99
 * from this software without specific prior written permission. 
 
100
 *
 
101
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 
102
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 
103
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 
104
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 
105
 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY 
 
106
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
 
107
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
 
108
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 
109
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 
 
110
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, 
 
111
 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY 
 
112
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
 
113
 * OF SUCH DAMAGE. See the GNU General Public License for more details. 
 
114
 *
 
115
 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF 
 
116
 * YOUR JURISDICTION. It is licensee's responsibility to comply with 
 
117
 * any export regulations applicable in licensee's jurisdiction. Under 
 
118
 * CURRENT (2001) U.S. export regulations this software 
 
119
 * is eligible for export from the U.S. and can be downloaded by or 
 
120
 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed 
 
121
 * destinations which include Cuba, Iraq, Libya, North Korea, Iran, 
 
122
 * Syria, Sudan, Afghanistan and any other country to which the U.S. 
 
123
 * has embargoed goods and services. 
 
124
 *
 
125
 * You should have received a copy of the GNU General Public License 
 
126
 * along with this file; if not, write to the Free Software Foundation, 
 
127
 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
 
128
 *
 
129
 * END_NSC_LIC_GPL */
 
130
 
 
131
int redcloud_msr_init(void);
 
132
DEV_STATUS redcloud_id_msr_device(MSR * pDev, unsigned long address);
 
133
DEV_STATUS redcloud_get_msr_dev_address(unsigned int device,
 
134
                                        unsigned long *address);
 
135
DEV_STATUS redcloud_get_glink_id_at_address(unsigned int *device,
 
136
                                            unsigned long address);
 
137
DEV_STATUS redcloud_msr_read(unsigned int device, unsigned int msrRegister,
 
138
                             Q_WORD * msrValue);
 
139
DEV_STATUS redcloud_msr_write(unsigned int device, unsigned int msrRegister,
 
140
                              Q_WORD * msrValue);
 
141
 
 
142
void redcloud_build_mbus_tree(void);    /* private routine definition */
 
143
int redcloud_init_msr_devices(MSR aDev[], unsigned int array_size);     /* private routine definition */
 
144
DEV_STATUS redcloud_find_msr_device(MSR * pDev);        /* private routine definition */
 
145
 
 
146
/* REDCLOUD MSR BITMASKS */
 
147
 
 
148
#define MBD_MSR_CAP                     0x2000
 
149
#define MSR_CAP_ID_MASK         0xFF000
 
150
#define MSR_CAP_ID_SHIFT        12
 
151
#define MSR_CAP_REV_MASK    0x0F
 
152
#define MBIU_CAP                        0x86
 
153
#define NUM_PORTS_MASK          0x00380000
 
154
#define NUM_PORTS_SHIFT         19
 
155
#define MBIU_WHOAMI                     0x8B
 
156
#define WHOAMI_MASK                     0x07
 
157
 
 
158
/* REDCLOUD and CS5535 MSR DEVICES */
 
159
 
 
160
MSR msrDev[] = {
 
161
   {FOUND, RC_CC_MBIU, RC_MB0_MBIU0},
 
162
   {FOUND, RC_CC_MBIU, RC_MB0_MBIU1},
 
163
   {NOT_KNOWN, RC_CC_MCP, FAKE_ADDRESS},
 
164
   {NOT_KNOWN, RC_CC_MPCI, FAKE_ADDRESS},
 
165
   {NOT_KNOWN, RC_CC_MC, FAKE_ADDRESS},
 
166
   {NOT_KNOWN, RC_CC_GP, FAKE_ADDRESS},
 
167
   {NOT_KNOWN, RC_CC_VG, FAKE_ADDRESS},
 
168
   {NOT_KNOWN, RC_CC_DF, FAKE_ADDRESS},
 
169
   {NOT_KNOWN, RC_CC_FG, FAKE_ADDRESS},
 
170
   {FOUND, RC_CC_VA, RC_MB0_CPU},
 
171
   {FOUND, CP_CC_MBIU, CP_MB0_MBIU0},
 
172
   {NOT_KNOWN, CP_CC_MPCI, FAKE_ADDRESS},
 
173
   {NOT_KNOWN, CP_CC_USB2, FAKE_ADDRESS},
 
174
   {NOT_KNOWN, CP_CC_ATAC, FAKE_ADDRESS},
 
175
   {NOT_KNOWN, CP_CC_MDD, FAKE_ADDRESS},
 
176
   {NOT_KNOWN, CP_CC_ACC, FAKE_ADDRESS},
 
177
   {NOT_KNOWN, CP_CC_USB1, FAKE_ADDRESS},
 
178
   {NOT_KNOWN, CP_CC_MCP, FAKE_ADDRESS},
 
179
};
 
180
 
 
181
#define NUM_DEVS sizeof(msrDev) / sizeof(struct msr)
 
182
 
 
183
/* CAPISTRANO DEVICE INDEX LIMITS */
 
184
/* These defines represent the start and stop indexes into the device array  */
 
185
/* for all Capistrano devices.  These should be updated whenever a device is */
 
186
/* added or removed to the Capistrano list.                                  */
 
187
 
 
188
#define CP_INDEX_START CP_ID_MBIU
 
189
#define CP_INDEX_STOP  CP_ID_MCP
 
190
 
 
191
/* GLOBAL MBUS CACHE STRUCTURES */
 
192
/* These structures contain a "cached" copy of the MBUS topology */
 
193
/* for easy future lookup.                                       */
 
194
 
 
195
MBUS_NODE MBIU0[8], MBIU1[8], MBIU2[8];
 
196
 
 
197
/* REGISTER MACROS */
 
198
 
 
199
#define GET_DEVICE_ID( CAPABILITIES_HIGH, CAPABILITIES_LOW ) \
 
200
                                         ((unsigned int)(( (CAPABILITIES_LOW) & MSR_CAP_ID_MASK ) >> MSR_CAP_ID_SHIFT ))
 
201
 
 
202
#define GET_NUM_PORTS( MBIU_CAP_HIGH, MBIU_CAP_LOW ) (((MBIU_CAP_HIGH) & NUM_PORTS_MASK ) >> NUM_PORTS_SHIFT)
 
203
 
 
204
/*-----------------------------------------------------------------------------
 
205
 * gfx_msr_init
 
206
 * 
 
207
 * This routine initializes the base addresses of all known MBUS devices.  
 
208
 *-----------------------------------------------------------------------------
 
209
 */
 
210
#if GFX_MSR_DYNAMIC
 
211
int
 
212
redcloud_msr_init(void)
 
213
#else
 
214
int
 
215
gfx_msr_init(void)
 
216
#endif
 
217
{
 
218
   Q_WORD msrValue;
 
219
   int return_value = 1;
 
220
 
 
221
   /* CHECK FOR VALID MBUS CONFIGURATION */
 
222
   /* The CPU and the two MBIUs are assumed to be at known static addresses, so */
 
223
   /* we will check the device IDs at these addresses as proof of a valid mbus  */
 
224
   /* configuration.                                                            */
 
225
 
 
226
   MSR_READ(MBD_MSR_CAP, RC_MB0_CPU, &(msrValue.high), &(msrValue.low));
 
227
   if (GET_DEVICE_ID(msrValue.high, msrValue.low) != RC_CC_VA)
 
228
      return_value = 0;
 
229
 
 
230
   MSR_READ(MBD_MSR_CAP, RC_MB0_MBIU0, &(msrValue.high), &(msrValue.low));
 
231
   if (GET_DEVICE_ID(msrValue.high, msrValue.low) != RC_CC_MBIU)
 
232
      return_value = 0;
 
233
 
 
234
   MSR_READ(MBD_MSR_CAP, RC_MB0_MBIU1, &(msrValue.high), &(msrValue.low));
 
235
   if (GET_DEVICE_ID(msrValue.high, msrValue.low) != RC_CC_MBIU)
 
236
      return_value = 0;
 
237
 
 
238
   /* ENUMERATE VALID BUS */
 
239
   /* If all static devices were identified, continue with the enumeration */
 
240
 
 
241
   if (return_value) {
 
242
      /* OPTIMIZATION */
 
243
      /* Build a local copy of the MBUS topology.  This allows us to  */
 
244
      /* quickly search the entire MBUS for a given device ID without */
 
245
      /* repeated MSR accesses.                                       */
 
246
 
 
247
      redcloud_build_mbus_tree();
 
248
 
 
249
      /* INITIALIZE MSR DEVICES */
 
250
 
 
251
      return_value = redcloud_init_msr_devices(msrDev, NUM_DEVS);
 
252
 
 
253
   }
 
254
 
 
255
   return return_value;
 
256
 
 
257
}
 
258
 
 
259
/*--------------------------------------------------------------------------
 
260
 * void redcloud_build_mbus_tree() (PRIVATE ROUTINE - NOT PART OF DURANGO API)
 
261
 *
 
262
 * This routine walks through the MBUS and records the address value and 
 
263
 * device ID found at each node.  If a node (aka port) is not populated, 
 
264
 * that node returns '0'.  The deviceID for that node is set to '0' 
 
265
 * (NOT_POPULATED) to reflect this. If the node being queried points back to 
 
266
 * Vail or MBIU0, the deviceID for that node is set to 'REFLECTIVE'.  Reflective 
 
267
 * nodes are nodes that forward the given MBUS address BACK to the initiator.
 
268
 *-----------------------------------------------------------------------------
 
269
 */
 
270
void
 
271
redcloud_build_mbus_tree(void)
 
272
{
 
273
   unsigned long mbiu_port_count, reflective;
 
274
   unsigned long port;
 
275
   Q_WORD msrValue;
 
276
 
 
277
   /*                  */
 
278
   /* ENUMERATE MBIU0  */
 
279
   /*                  */
 
280
 
 
281
   /* COUNT MBIU PORTS */
 
282
 
 
283
   MSR_READ(MBIU_CAP, RC_MB0_MBIU0, &(msrValue.high), &(msrValue.low));
 
284
   mbiu_port_count = GET_NUM_PORTS(msrValue.high, msrValue.low);
 
285
 
 
286
   /* FIND REFLECTIVE PORT */
 
287
   /* Query the MBIU for the port through which we are communicating. */
 
288
   /* We will avoid accesses to this port to avoid a self-reference.  */
 
289
 
 
290
   MSR_READ(MBIU_WHOAMI, RC_MB0_MBIU0, &(msrValue.high), &(msrValue.low));
 
291
   reflective = msrValue.low & WHOAMI_MASK;
 
292
 
 
293
   /* ENUMERATE ALL PORTS */
 
294
   /* For every possible port, set the MBIU.deviceId to something. */
 
295
 
 
296
   for (port = 0; port < 8; port++) {
 
297
      /* FILL IN CLAIMED FIELD */
 
298
      /* All MBIU ports can only be assigned to one device from the */
 
299
      /* Durango table                                              */
 
300
 
 
301
      MBIU0[port].claimed = 0;
 
302
 
 
303
      /* MBIU0 PORT NUMBERS ARE IN ADDRESS BITS 31:29 */
 
304
 
 
305
      MBIU0[port].address = port << 29;
 
306
 
 
307
      /* SPECIAL CASE FOR MBIU0 */
 
308
      /* MBIU0 port 0 is a special case, as it points back to MBIU0.  MBIU0 */
 
309
      /* responds at address 0x40000xxx, which does not equal 0 << 29.      */
 
310
 
 
311
      if (port == 0)
 
312
         MBIU0[port].deviceId = RC_CC_MBIU;
 
313
      else if (port == reflective)
 
314
         MBIU0[port].deviceId = REFLECTIVE;
 
315
      else if (port > mbiu_port_count)
 
316
         MBIU0[port].deviceId = NOT_POPULATED;
 
317
      else {
 
318
         MSR_READ(MBD_MSR_CAP, MBIU0[port].address, &(msrValue.high),
 
319
                  &(msrValue.low));
 
320
         MBIU0[port].deviceId = GET_DEVICE_ID(msrValue.high, msrValue.low);
 
321
      }
 
322
   }
 
323
 
 
324
   /*                  */
 
325
   /* ENUMERATE MBIU1  */
 
326
   /*                  */
 
327
 
 
328
   /* COUNT MBIU PORTS */
 
329
 
 
330
   MSR_READ(MBIU_CAP, RC_MB0_MBIU1, &(msrValue.high), &(msrValue.low));
 
331
   mbiu_port_count = GET_NUM_PORTS(msrValue.high, msrValue.low);
 
332
 
 
333
   /* FIND REFLECTIVE PORT */
 
334
   /* Query the MBIU for the port through which we are communicating. */
 
335
   /* We will avoid accesses to this port to avoid a self-reference.  */
 
336
 
 
337
   MSR_READ(MBIU_WHOAMI, RC_MB0_MBIU1, &(msrValue.high), &(msrValue.low));
 
338
   reflective = msrValue.low & WHOAMI_MASK;
 
339
 
 
340
   /* ENUMERATE ALL PORTS */
 
341
   /* For every possible port, set the MBIU.deviceId to something. */
 
342
 
 
343
   for (port = 0; port < 8; port++) {
 
344
      /* FILL IN CLAIMED FIELD */
 
345
      /* All MBIU ports can only be assigned to one device from the */
 
346
      /* Durango table                                              */
 
347
 
 
348
      MBIU1[port].claimed = 0;
 
349
 
 
350
      /* MBIU1 PORT NUMBERS ARE IN 28:26 AND 31:29 = 010B */
 
351
 
 
352
      MBIU1[port].address = (0x02l << 29) + (port << 26);
 
353
 
 
354
      if (port == reflective)
 
355
         MBIU1[port].deviceId = REFLECTIVE;
 
356
      else if (port > mbiu_port_count)
 
357
         MBIU1[port].deviceId = NOT_POPULATED;
 
358
      else {
 
359
         MSR_READ(MBD_MSR_CAP, MBIU1[port].address, &(msrValue.high),
 
360
                  &(msrValue.low));
 
361
         MBIU1[port].deviceId = GET_DEVICE_ID(msrValue.high, msrValue.low);
 
362
      }
 
363
   }
 
364
 
 
365
   /*                          */
 
366
   /* ENUMERATE MBIU2 (CS5535) */
 
367
   /*  (if present)            */
 
368
 
 
369
   MSR_READ(MBD_MSR_CAP, CP_MB0_MBIU0, &(msrValue.high), &(msrValue.low));
 
370
   if (GET_DEVICE_ID(msrValue.high, msrValue.low) == CP_CC_MBIU) {
 
371
      /* COUNT MBIU PORTS */
 
372
 
 
373
      MSR_READ(MBIU_CAP, CP_MB0_MBIU0, &(msrValue.high), &(msrValue.low));
 
374
      mbiu_port_count = GET_NUM_PORTS(msrValue.high, msrValue.low);
 
375
 
 
376
      /* FIND REFLECTIVE PORT */
 
377
      /* Query the MBIU for the port through which we are communicating. */
 
378
      /* We will avoid accesses to this port to avoid a self-reference.  */
 
379
 
 
380
      MSR_READ(MBIU_WHOAMI, CP_MB0_MBIU0, &(msrValue.high), &(msrValue.low));
 
381
      reflective = msrValue.low & WHOAMI_MASK;
 
382
 
 
383
      /* ENUMERATE ALL PORTS */
 
384
      /* For every possible port, set the MBIU.deviceId to something. */
 
385
 
 
386
      for (port = 0; port < 8; port++) {
 
387
         /* FILL IN CLAIMED FIELD */
 
388
         /* All MBIU ports can only be assigned to one device from the */
 
389
         /* Durango table                                              */
 
390
 
 
391
         MBIU2[port].claimed = 0;
 
392
 
 
393
         /* MBIU2 PORT NUMBERS ARE IN 22:20 AND 31:23 = 010100010B */
 
394
 
 
395
         MBIU2[port].address =
 
396
               (0x02l << 29) + (0x04l << 26) + (0x02l << 23) + (port << 20);
 
397
 
 
398
         if (port == reflective)
 
399
            MBIU2[port].deviceId = REFLECTIVE;
 
400
         else if (port > mbiu_port_count)
 
401
            MBIU2[port].deviceId = NOT_POPULATED;
 
402
         else {
 
403
            MSR_READ(MBD_MSR_CAP, MBIU2[port].address, &(msrValue.high),
 
404
                     &(msrValue.low));
 
405
            MBIU2[port].deviceId = GET_DEVICE_ID(msrValue.high, msrValue.low);
 
406
         }
 
407
      }
 
408
   } else {
 
409
      /* NO 5535                                                  */
 
410
      /* If the CS5535 is not installed, fill in the cached table */
 
411
      /* with the 'NOT_INSTALLED' flag.  Also, fill in the device */
 
412
      /* status from NOT_KNOWN to REQ_NOT_INSTALLED.              */
 
413
 
 
414
      for (port = 0; port < 8; port++) {
 
415
         MBIU2[port].claimed = 0;
 
416
         MBIU2[port].deviceId = NOT_INSTALLED;
 
417
         MBIU2[port].address =
 
418
               (0x02l << 29) + (0x04l << 26) + (0x02l << 23) + (port << 20);
 
419
      }
 
420
      for (port = CP_INDEX_START; port <= CP_INDEX_STOP; port++) {
 
421
         msrDev[port].Present = REQ_NOT_INSTALLED;
 
422
      }
 
423
   }
 
424
}
 
425
 
 
426
/*------------------------------------------------------------------
 
427
 * redcloud_init_msr_devices (PRIVATE ROUTINE - NOT PART OF DURANGO API)
 
428
 
 
429
 * Handles the details of finding each possible device on the MBUS.
 
430
 * If a given device is not found, its structure is left uninitialized.
 
431
 * If a given device is found, its structure is updated.
 
432
 *
 
433
 * This init routine only checks for devices in aDev[].
 
434
 *
 
435
 *  Passed:
 
436
 *              aDev - is a pointer to the array of MBUS devices.
 
437
 *              arraySize - number of elements in aDev.
 
438
 *
 
439
 *      Returns:
 
440
 *              1 - If, for every device, its address was found.
 
441
 *              0 - If, for any device, an error was encountered.
 
442
 *------------------------------------------------------------------
 
443
 */
 
444
int
 
445
redcloud_init_msr_devices(MSR aDev[], unsigned int array_size)
 
446
{
 
447
   unsigned int i, issues = 0;
 
448
 
 
449
   /* TRY TO FIND EACH ITEM IN THE ARRAY */
 
450
 
 
451
   for (i = 0; i < array_size; i++) {
 
452
      /* IGNORE DEVICES THAT ARE ALREADY FOUND                */
 
453
      /* The addresses for "found" devices are already known. */
 
454
 
 
455
      if (aDev[i].Present == FOUND || aDev[i].Present == REQ_NOT_INSTALLED)
 
456
         continue;
 
457
 
 
458
      /* TRY TO FIND THE DEVICE ON THE MBUS */
 
459
 
 
460
      aDev[i].Present = redcloud_find_msr_device(&aDev[i]);
 
461
 
 
462
      /* INCREMENT ERROR COUNT IF DEVICE NOT FOUND */
 
463
 
 
464
      if (aDev[i].Present != FOUND)
 
465
         issues++;
 
466
   }
 
467
 
 
468
   return (issues == 0);
 
469
}
 
470
 
 
471
/*------------------------------------------------------------------
 
472
 *  redcloud_find_msr_device (PRIVATE ROUTINE - NOT PART OF DURANGO API)
 
473
 *
 
474
 *  Passed:
 
475
 *          pDev - is a pointer to one element in the array of MBUS devices
 
476
 *
 
477
 *  Returns:
 
478
 *          FOUND - Device was found and pDev->Address has been updated.
 
479
 *
 
480
 *              REQ_NOT_FOUND - Device was not found and pDev->Address has not
 
481
 *                                              been updated.
 
482
 *
 
483
 *------------------------------------------------------------------
 
484
*/
 
485
DEV_STATUS
 
486
redcloud_find_msr_device(MSR * pDev)
 
487
{
 
488
   unsigned int i;
 
489
 
 
490
   /* SEARCH DURANGO'S CACHED MBUS TOPOLOGY */
 
491
   /* This gets a little tricky.  As the only identifier we have for each   */
 
492
   /* device is the device ID and we have multiple devices of the same type */
 
493
   /* MCP, MPCI, USB, etc. we need to make some assumptions based on table  */
 
494
   /* order.  These are as follows:                                         */
 
495
   /* 1. All Redcloud nodes are searched first, as we assume that they      */
 
496
   /*    are first in the table.                                            */
 
497
   /* 2. If two devices have the same device ID and are found on the same   */
 
498
   /*    device (GX2, CS5535, etc.) we assume that they are listed such     */
 
499
   /*    that the first device in the table with this device ID has a lower */
 
500
   /*    port address.                                                      */
 
501
   /* 3. After a device ID has been matched, the port is marked as          */
 
502
   /*    'claimed', such that future enumerations continue searching the    */
 
503
   /*    GeodeLink topology.                                                */
 
504
 
 
505
   /* SEARCH MBIU0 */
 
506
 
 
507
   for (i = 0; i < 8; i++) {
 
508
      if (MBIU0[i].deviceId == pDev->Id && !(MBIU0[i].claimed)) {
 
509
         MBIU0[i].claimed = 1;
 
510
         pDev->Address = MBIU0[i].address;
 
511
         return FOUND;
 
512
      }
 
513
   }
 
514
 
 
515
   /* SEARCH MBIU1 */
 
516
 
 
517
   for (i = 0; i < 8; i++) {
 
518
      if (MBIU1[i].deviceId == pDev->Id && !(MBIU1[i].claimed)) {
 
519
         MBIU1[i].claimed = 1;
 
520
         pDev->Address = MBIU1[i].address;
 
521
         return FOUND;
 
522
      }
 
523
   }
 
524
 
 
525
   /* SEARCH MBIU2 */
 
526
 
 
527
   for (i = 0; i < 8; i++) {
 
528
      if (MBIU2[i].deviceId == pDev->Id && !(MBIU2[i].claimed)) {
 
529
         MBIU2[i].claimed = 1;
 
530
         pDev->Address = MBIU2[i].address;
 
531
         return FOUND;
 
532
      }
 
533
   }
 
534
 
 
535
   return REQ_NOT_FOUND;
 
536
}
 
537
 
 
538
/*--------------------------------------------------------------------
 
539
 * gfx_id_msr_device 
 
540
 *
 
541
 *      This routine handles reading the capabilities MSR register (typically 0x2000)
 
542
 *      and checking if the 'id' field matchs  pDev.Id.  This routine is
 
543
 *  used by applications/drivers that need to extend the list of known
 
544
 *  MBUS devices beyond those known by Durango.
 
545
 *
 
546
 *              Passed:
 
547
 *                      pDev - Pointer to MSR structure containing the device's ID.
 
548
 *                  address - device address.
 
549
 *
 
550
 *              Returns:
 
551
 *                      FOUND - The IDs do match.
 
552
 *                      REQ_NOT_FOUND - There was not a match.
 
553
 *
 
554
 *--------------------------------------------------------------------
 
555
 */
 
556
#if GFX_MSR_DYNAMIC
 
557
DEV_STATUS
 
558
redcloud_id_msr_device(MSR * pDev, unsigned long address)
 
559
#else
 
560
DEV_STATUS
 
561
gfx_id_msr_device(MSR * pDev, unsigned long address)
 
562
#endif
 
563
{
 
564
   Q_WORD msrValue;
 
565
 
 
566
   MSR_READ(MBD_MSR_CAP, address, &(msrValue.high), &(msrValue.low));
 
567
 
 
568
   if (GET_DEVICE_ID(msrValue.high, msrValue.low) == pDev->Id)
 
569
      return FOUND;
 
570
   else
 
571
      return REQ_NOT_FOUND;
 
572
}
 
573
 
 
574
/*--------------------------------------------------------------------
 
575
 * gfx_get_msr_dev_address
 
576
 * 
 
577
 * This function returns the 32-bit address of the requested device.
 
578
 * The device must be a known MBUS device.  (It must be in Durango's 
 
579
 * device table.)  DEV_STATUS should be checked to verify that the address 
 
580
 * was updated.
 
581
 *
 
582
 *
 
583
 * Passed:
 
584
 *     device - device index of the device in question.
 
585
 *         *address - ptr to location where address should be stored.
 
586
 *         
 
587
 * Returns:
 
588
 *         DEV_STATUS of device in question.  (NOT_KNOWN if device is out of range.)
 
589
 *     *address - updated if 'device' is within range
 
590
 *   
 
591
 *      Notes:
 
592
 *     This function should only be called after gfx_msr_init
 
593
 *
 
594
 *--------------------------------------------------------------------
 
595
 */
 
596
#if GFX_MSR_DYNAMIC
 
597
DEV_STATUS
 
598
redcloud_get_msr_dev_address(unsigned int device, unsigned long *address)
 
599
#else
 
600
DEV_STATUS
 
601
gfx_get_msr_dev_address(unsigned int device, unsigned long *address)
 
602
#endif
 
603
{
 
604
   if (device < NUM_DEVS) {
 
605
      if (msrDev[device].Present == FOUND)
 
606
         *address = msrDev[device].Address;
 
607
 
 
608
      return msrDev[device].Present;
 
609
   }
 
610
   return NOT_KNOWN;
 
611
 
 
612
}
 
613
 
 
614
/*--------------------------------------------------------------------
 
615
 *  gfx_get_glink_id_at_address
 
616
 *   
 
617
 *      This function returns the 16-bit deviceId at the requested address.
 
618
 *  DEV_STATUS should be checked to make sure that device was updated.
 
619
 *
 
620
 *      Passed:
 
621
 *          device - ptr to location where device ID should be stored.
 
622
 *              address - address of desired device ID.
 
623
 *         
 
624
 *  Returns:
 
625
 *          FOUND if address is a valid address, NOT_KNOWN if address cannot be found 
 
626
 *      on the mbus.
 
627
 *      *device - updated with device Id info.
 
628
 *
 
629
 *      Notes:
 
630
 *      This function should be called after gfx_msr_init 
 
631
 *
 
632
 *--------------------------------------------------------------------
 
633
 */
 
634
#if GFX_MSR_DYNAMIC
 
635
DEV_STATUS
 
636
redcloud_get_glink_id_at_address(unsigned int *device, unsigned long address)
 
637
#else
 
638
DEV_STATUS
 
639
gfx_get_glink_id_at_address(unsigned int *device, unsigned long address)
 
640
#endif
 
641
{
 
642
   int port;
 
643
 
 
644
   for (port = 0; port < 8; port++) {
 
645
      if (MBIU0[port].address == address) {
 
646
         *device = MBIU0[port].deviceId;
 
647
         return FOUND;
 
648
      } else if (MBIU1[port].address == address) {
 
649
         *device = MBIU1[port].deviceId;
 
650
         return FOUND;
 
651
      } else if (MBIU2[port].address == address) {
 
652
         *device = MBIU2[port].deviceId;
 
653
         return FOUND;
 
654
      }
 
655
   }
 
656
 
 
657
   return NOT_KNOWN;
 
658
 
 
659
}
 
660
 
 
661
/*--------------------------------------------------------------------
 
662
 * gfx_msr_read
 
663
 *
 
664
 * Performs a 64-bit read from 'msrRegister' in device 'device'.  'device' is 
 
665
 * an index into Durango's table of known MBUS devices.
 
666
 *
 
667
 * Returns:
 
668
 *     FOUND - if no errors were detected and msrValue has been updated.
 
669
 *         NOT_KNOWN    - an error was detected.  msrValue is not updated.
 
670
 *         REQ_NOT_FOUND - 'msrAddress' for 'devID' is unknown.  Caller
 
671
 *                                              should call msrInit() first.  msrValue is not updated.
 
672
 *         Notes:
 
673
 *         This function should be called after gfx_msr_init
 
674
 *--------------------------------------------------------------------
 
675
 */
 
676
#if GFX_MSR_DYNAMIC
 
677
DEV_STATUS
 
678
redcloud_msr_read(unsigned int device, unsigned int msrRegister,
 
679
                  Q_WORD * msrValue)
 
680
#else
 
681
DEV_STATUS
 
682
gfx_msr_read(unsigned int device, unsigned int msrRegister, Q_WORD * msrValue)
 
683
#endif
 
684
{
 
685
   if (device < NUM_DEVS) {
 
686
      if (msrDev[device].Present == FOUND)
 
687
         MSR_READ(msrRegister, msrDev[device].Address, &(msrValue->high),
 
688
                  &(msrValue->low));
 
689
 
 
690
      return msrDev[device].Present;
 
691
   }
 
692
   return NOT_KNOWN;
 
693
}
 
694
 
 
695
/*--------------------------------------------------------------------
 
696
 * gfx_msr_write
 
697
 *
 
698
 *              Performs a 64-bit write to 'msrRegister' in device 'devID'.
 
699
 *
 
700
 *              Returns:
 
701
 *                      FOUND - if no errors were detected and msrValue has been updated.
 
702
 *                      NOT_KNOWN       - an error was detected.  msrValue is not updated.
 
703
 *                      REQ_NOT_FOUND - 'msrAddress' for 'devID' is unknown.  Caller
 
704
 *                                              should call msrInit() first.  msrValue is not updated.
 
705
 *
 
706
 *              Notes:
 
707
 *              This function is valid to call after initMSR_API() 
 
708
 *
 
709
 *--------------------------------------------------------------------
 
710
 */
 
711
#if GFX_MSR_DYNAMIC
 
712
DEV_STATUS
 
713
redcloud_msr_write(unsigned int device, unsigned int msrRegister,
 
714
                   Q_WORD * msrValue)
 
715
#else
 
716
DEV_STATUS
 
717
gfx_msr_write(unsigned int device, unsigned int msrRegister,
 
718
              Q_WORD * msrValue)
 
719
#endif
 
720
{
 
721
   if (device < NUM_DEVS) {
 
722
      if (msrDev[device].Present == FOUND)
 
723
         MSR_WRITE(msrRegister, msrDev[device].Address, &(msrValue->high),
 
724
                   &(msrValue->low));
 
725
 
 
726
      return msrDev[device].Present;
 
727
   }
 
728
   return NOT_KNOWN;
 
729
}