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

« back to all changes in this revision

Viewing changes to unix/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_priv.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/tdfx/tdfx_priv.c,v 1.16 2001/05/21 21:43:55 dawes Exp $ */
 
2
 
 
3
 
 
4
#include "xf86.h"
 
5
#include "xf86_OSproc.h"
 
6
#include "xf86_ansic.h"
 
7
#include "xf86fbman.h"
 
8
#include "compiler.h"
 
9
#include "tdfx.h"
 
10
 
 
11
/*
 
12
  Memory layout of card is as follows:
 
13
 
 
14
  000000-00ffff: VGA memory
 
15
  010000-013fff: Cursor 
 
16
  011000-xxxxxx: Fifo (Min of CMDFIFO pages)
 
17
  xxxxxx- A-1  : Front Buffer (framebuffer)
 
18
   A    - B-1  : Pixmap Cache (framebuffer)
 
19
   B    - C-1  : Texture Memory
 
20
   C    - D-1  : Back Buffer
 
21
   D    - E-1  : Depth Buffer
 
22
 
 
23
  NB: pixmap cache usually butts right up against texture memory. when
 
24
  3d is disabled (via Transition2D) then the pixmap cache is increased
 
25
  to overlap the texture memory. maximum pixmap cache of 4095 lines on
 
26
  voodoo5 and 2048 on voodoo3/4 applies.
 
27
*/
 
28
 
 
29
#if X_BYTE_ORDER == X_BIG_ENDIAN
 
30
void TDFXWriteFifo_24(TDFXPtr pTDFX, int val) {
 
31
  *pTDFX->fifoPtr++ = val;
 
32
}
 
33
 
 
34
void TDFXWriteFifo_16(TDFXPtr pTDFX, int val) {
 
35
  *pTDFX->fifoPtr++ = BE_WSWAP32(val);
 
36
}
 
37
 
 
38
void TDFXWriteFifo_8(TDFXPtr pTDFX, int val) {
 
39
  *pTDFX->fifoPtr++ = BE_BSWAP32(val);
 
40
}
 
41
#endif
 
42
 
 
43
 
 
44
static void TDFXSendNOPFifo3D(ScrnInfoPtr pScrn)
 
45
{
 
46
  TDFXPtr pTDFX;
 
47
 
 
48
  pTDFX=TDFXPTR(pScrn);
 
49
  TDFXAllocateSlots(pTDFX, 2);
 
50
  SET_3DPK4_HEADER(1, 0x48<<3);
 
51
  WRITE_FIFO(pTDFX, 0, 0);
 
52
}
 
53
 
 
54
void TDFXSendNOPFifo2D(ScrnInfoPtr pScrn)
 
55
{
 
56
  TDFXPtr pTDFX;
 
57
 
 
58
  pTDFX=TDFXPTR(pScrn);
 
59
  if (!pTDFX->syncDone) {
 
60
    TDFXFirstSync(pScrn);
 
61
    return;
 
62
  }
 
63
  TDFXAllocateSlots(pTDFX, 2);
 
64
  SET_PKT2_HEADER(SSTCP_COMMAND);
 
65
  WRITE_FIFO(pTDFX, SST_2D_COMMAND, SST_2D_NOP|SST_2D_GO);
 
66
}  
 
67
 
 
68
void TDFXSendNOPFifo(ScrnInfoPtr pScrn)
 
69
{
 
70
  TDFXSendNOPFifo2D(pScrn);
 
71
  TDFXSendNOPFifo3D(pScrn);
 
72
}
 
73
 
 
74
static void InstallFifo(ScrnInfoPtr pScrn)
 
75
{
 
76
  TDFXPtr pTDFX;
 
77
 
 
78
  pTDFX=TDFXPTR(pScrn);
 
79
  /* Install the fifo */
 
80
  TDFXWriteLongMMIO(pTDFX, SST_FIFO_BASEADDR0, pTDFX->fifoOffset>>12);
 
81
  TDFXWriteLongMMIO(pTDFX, SST_FIFO_BUMP0, 0);
 
82
  TDFXWriteLongMMIO(pTDFX, SST_FIFO_RDPTRL0, pTDFX->fifoOffset);
 
83
  TDFXWriteLongMMIO(pTDFX, SST_FIFO_RDPTRH0, 0);
 
84
  TDFXWriteLongMMIO(pTDFX, SST_FIFO_AMIN0, pTDFX->fifoOffset-4);
 
85
  TDFXWriteLongMMIO(pTDFX, SST_FIFO_AMAX0, pTDFX->fifoOffset-4);
 
86
  TDFXWriteLongMMIO(pTDFX, SST_FIFO_DEPTH0, 0);
 
87
  TDFXWriteLongMMIO(pTDFX, SST_FIFO_HOLECNT0, 0);
 
88
  if (pTDFX->ChipType == PCI_CHIP_BANSHEE) 
 
89
    TDFXWriteLongMMIO(pTDFX, SST_FIFO_FIFOTHRESH, (0x9<<5) | 0x2);
 
90
  else 
 
91
    TDFXWriteLongMMIO(pTDFX, SST_FIFO_FIFOTHRESH, (0xf<<5) | 0x8);
 
92
  TDFXWriteLongMMIO(pTDFX, SST_FIFO_BASESIZE0, ((pTDFX->fifoSize>>12)-1) | 
 
93
                    SST_EN_CMDFIFO);
 
94
  /* Set the internal state */
 
95
  pTDFX->fifoRead = pTDFX->fifoBase;
 
96
  pTDFX->fifoPtr = pTDFX->fifoBase;
 
97
  pTDFX->fifoSlots = (pTDFX->fifoSize>>2) - 1;
 
98
  pTDFX->fifoEnd = pTDFX->fifoBase+pTDFX->fifoSlots;
 
99
  TDFXSendNOPFifo(pScrn);
 
100
}
 
101
 
 
102
static void TDFXResetFifo(ScrnInfoPtr pScrn)
 
103
{
 
104
  TDFXPtr pTDFX;
 
105
  int oldValue;
 
106
  long start_sec, end_sec, dummy;
 
107
 
 
108
  pTDFX=TDFXPTR(pScrn);
 
109
  ErrorF("Resetting FIFO\n");
 
110
  /* Shut down the fifo */
 
111
  TDFXWriteLongMMIO(pTDFX, SST_FIFO_BASESIZE0, 0);
 
112
  /* Toggle the reset bits */
 
113
  oldValue=TDFXReadLongMMIO(pTDFX, MISCINIT0);
 
114
  TDFXWriteLongMMIO(pTDFX, MISCINIT0, oldValue|0x23);
 
115
  getsecs(&start_sec, &dummy);
 
116
  do {
 
117
    getsecs(&end_sec, &dummy);
 
118
  } while (end_sec-start_sec<2);
 
119
  TDFXWriteLongMMIO(pTDFX, MISCINIT0, oldValue);
 
120
  oldValue=TDFXReadLongMMIO(pTDFX, MISCINIT1);
 
121
  TDFXWriteLongMMIO(pTDFX, MISCINIT1, oldValue|BIT(19));
 
122
  getsecs(&start_sec, &dummy);
 
123
  do {
 
124
    getsecs(&end_sec, &dummy);
 
125
  } while (end_sec-start_sec<2);
 
126
  TDFXWriteLongMMIO(pTDFX, MISCINIT1, oldValue);
 
127
  InstallFifo(pScrn);
 
128
}
 
129
 
 
130
/*
 
131
  There are two steps to fully syncing the board:
 
132
  
 
133
  1) Send a NOP, which waits for any commands in progress
 
134
  2) Read the status register for 3 consecutive non-busy
 
135
 
 
136
  !!! We should use expedential backoff in our reads !!!
 
137
*/
 
138
static void TDFXSyncFifo(ScrnInfoPtr pScrn)
 
139
{
 
140
  TDFXPtr pTDFX;
 
141
  int i, cnt, resets=0;
 
142
  int stat;
 
143
  long start_sec, end_sec, dummy, readptr;
 
144
 
 
145
  TDFXTRACEACCEL("TDFXSyncFifo start\n");
 
146
  pTDFX=TDFXPTR(pScrn);
 
147
  TDFXSendNOPFifo(pScrn);
 
148
  i=0;
 
149
  cnt=0;
 
150
  start_sec=0;
 
151
  readptr=TDFXReadLongMMIO(pTDFX, SST_FIFO_RDPTRL0);
 
152
  do {
 
153
    readptr=TDFXReadLongMMIO(pTDFX, SST_FIFO_RDPTRL0);
 
154
    stat=TDFXReadLongMMIO(pTDFX, 0);
 
155
    if (stat&SST_BUSY) i=0; else i++;
 
156
    cnt++;
 
157
    if (cnt==1000) {
 
158
      if (!start_sec) {
 
159
        getsecs(&start_sec, &dummy);
 
160
      } else {
 
161
        getsecs(&end_sec, &dummy);
 
162
        if (end_sec-start_sec>3) {
 
163
          dummy=TDFXReadLongMMIO(pTDFX, SST_FIFO_RDPTRL0);
 
164
          if (dummy==readptr) {
 
165
            TDFXResetFifo(pScrn);
 
166
            readptr=dummy;
 
167
            resets++;
 
168
            if (resets==3) {
 
169
              xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 
170
                         "Board is not responding.\n");
 
171
              return;
 
172
            }
 
173
          }
 
174
          start_sec=0;
 
175
        }
 
176
      }
 
177
      cnt=0;
 
178
    }
 
179
  } while (i<3);
 
180
  pTDFX->PciCnt=stat&0x1F;
 
181
  pTDFX->prevBlitDest.x1=pTDFX->prevBlitDest.y1=0;
 
182
  pTDFX->prevBlitDest.x2=pTDFX->prevBlitDest.y2=0;
 
183
}
 
184
 
 
185
Bool TDFXInitFifo(ScreenPtr pScreen)
 
186
{
 
187
  ScrnInfoPtr pScrn;
 
188
  TDFXPtr pTDFX;
 
189
 
 
190
  pScrn = xf86Screens[pScreen->myNum];
 
191
  pTDFX=TDFXPTR(pScrn);
 
192
#ifdef DEBUG_FIFO
 
193
  pTDFX->fifoMirrorBase=0;
 
194
#endif
 
195
  pTDFX->fifoBase = (uint32*)(pTDFX->FbBase+pTDFX->fifoOffset);
 
196
#ifdef DEBUG_FIFO
 
197
  pTDFX->fifoMirrorBase = xalloc(pTDFX->fifoSize);
 
198
  pTDFX->fifoMirrorPtr = pTDFX->fifoMirrorBase;
 
199
#endif
 
200
  pTDFX->sync=TDFXSyncFifo;
 
201
  InstallFifo(pScrn);
 
202
  return TRUE;
 
203
}
 
204
 
 
205
void TDFXShutdownFifo(ScreenPtr pScreen)
 
206
{
 
207
  ScrnInfoPtr pScrn;
 
208
  TDFXPtr pTDFX;
 
209
 
 
210
  pScrn = xf86Screens[pScreen->myNum];
 
211
  pTDFX=TDFXPTR(pScrn);
 
212
  TDFXWriteLongMMIO(pTDFX, SST_FIFO_BASESIZE0, 0);
 
213
  pTDFX->sync=TDFXSync;
 
214
#ifdef DEBUG_FIFO
 
215
  if (pTDFX->fifoMirrorBase) xfree(pTDFX->fifoMirrorBase);
 
216
  pTDFX->fifoMirrorBase=0;
 
217
#endif
 
218
}
 
219
 
 
220
static uint32 
 
221
GetReadPtr(TDFXPtr pTDFX)
 
222
{
 
223
  uint32 read_ptr, dummy;
 
224
 
 
225
  do {
 
226
    dummy = TDFXReadLongMMIO(pTDFX, SST_FIFO_RDPTRL0);
 
227
    read_ptr = TDFXReadLongMMIO(pTDFX, SST_FIFO_RDPTRL0);
 
228
  } while (read_ptr != dummy);
 
229
  return read_ptr;
 
230
}
 
231
 
 
232
#ifdef XF86DRI
 
233
void TDFXSwapContextFifo(ScreenPtr pScreen)
 
234
{
 
235
  ScrnInfoPtr pScrn;
 
236
  TDFXPtr pTDFX;
 
237
  int dummy, readPos;
 
238
  TDFXSAREAPriv *sPriv;
 
239
 
 
240
  pScrn = xf86Screens[pScreen->myNum];
 
241
  pTDFX=TDFXPTR(pScrn);
 
242
  sPriv=(TDFXSAREAPriv*)DRIGetSAREAPrivate(pScreen);
 
243
  /* if (sPriv)
 
244
     ErrorF("In FifoPtr=%d FifoRead=%d\n", sPriv->fifoPtr, sPriv->fifoRead); */
 
245
#if 1
 
246
  do {
 
247
    dummy=TDFXReadLongMMIO(pTDFX, SST_FIFO_DEPTH0);
 
248
    readPos=TDFXReadLongMMIO(pTDFX, SST_FIFO_DEPTH0);
 
249
  } while (dummy || readPos);
 
250
  readPos=(GetReadPtr(pTDFX)-pTDFX->fifoOffset)>>2;
 
251
  pTDFX->fifoPtr = pTDFX->fifoBase+readPos;
 
252
  pTDFX->fifoRead = pTDFX->fifoPtr;
 
253
#else
 
254
  sPriv=(TDFXSAREAPriv*)DRIGetSAREAPrivate(pScreen);
 
255
  if (!sPriv) return;
 
256
  if ((sPriv->fifoPtr<pTDFX->fifoOffset) || 
 
257
      (sPriv->fifoPtr>(int)pTDFX->fifoOffset+pTDFX->fifoSize) ||
 
258
      (sPriv->fifoRead<pTDFX->fifoOffset) ||
 
259
      (sPriv->fifoRead>(int)pTDFX->fifoOffset+pTDFX->fifoSize)) {
 
260
    ErrorF("Invalid offsets passed between client and X server\n");
 
261
    ResetFifo(pScrn);
 
262
  } else {
 
263
    pTDFX->fifoPtr = (unsigned int *)(pTDFX->FbBase+sPriv->fifoPtr);
 
264
    pTDFX->fifoRead = (unsigned int *)(pTDFX->FbBase+sPriv->fifoRead);
 
265
  }
 
266
#endif
 
267
  if (pTDFX->fifoRead>pTDFX->fifoPtr)
 
268
    pTDFX->fifoSlots = pTDFX->fifoRead-pTDFX->fifoPtr-1-8;
 
269
  else 
 
270
    pTDFX->fifoSlots = pTDFX->fifoEnd-pTDFX->fifoPtr-8;
 
271
}    
 
272
 
 
273
#endif
 
274
 
 
275
static void 
 
276
TDFXMakeSpace(TDFXPtr pTDFX, uint32 slots)
 
277
{
 
278
  uint32 slots_available;
 
279
 
 
280
  /*
 
281
  ** Check to see if we have to wrap to get enough space.
 
282
  */
 
283
  if (slots > pTDFX->fifoEnd-pTDFX->fifoPtr) {
 
284
    /*
 
285
    ** Make sure that the read pointer is not ahead of us in the
 
286
    ** the command fifo before wrapping.
 
287
    ** This insures two things:
 
288
    **   1) There is room at fifo_ptr for the JMP packet.
 
289
    **   2) There are slots available at the beginning of the fifo up to the read_ptr.
 
290
    **
 
291
    ** Since we are wrapping, insure that the read pointer is not at the
 
292
    ** beginning of the fifo to prevent the ambiguous situation described
 
293
    ** below.
 
294
    */
 
295
    do {
 
296
      pTDFX->fifoRead = (uint32*)(pTDFX->FbBase + GetReadPtr(pTDFX));
 
297
    }
 
298
    while (pTDFX->fifoRead>pTDFX->fifoPtr || 
 
299
           pTDFX->fifoRead == pTDFX->fifoBase);
 
300
    /*
 
301
    ** Put a jump command in command fifo to wrap to the beginning.
 
302
    */
 
303
#if X_BYTE_ORDER == X_BIG_ENDIAN
 
304
    WRITE_FIFO(pTDFX, 0, (pTDFX->fifoOffset >> 2) << SSTCP_PKT0_ADDR_SHIFT |
 
305
      SSTCP_PKT0_JMP_LOCAL);
 
306
#else
 
307
    *pTDFX->fifoPtr = (pTDFX->fifoOffset >> 2) << SSTCP_PKT0_ADDR_SHIFT |
 
308
      SSTCP_PKT0_JMP_LOCAL;
 
309
#endif
 
310
    FLUSH_WCB();
 
311
 
 
312
    /*
 
313
    ** Reset the fifo_ptr to the beginning of the command fifo.
 
314
    */
 
315
    pTDFX->fifoPtr = pTDFX->fifoBase;
 
316
#ifdef DEBUG_FIFO
 
317
    pTDFX->fifoMirrorPtr = pTDFX->fifoMirrorBase;
 
318
#endif
 
319
  }
 
320
 
 
321
  /*
 
322
  ** Wait for enough slots to satisfy the request.
 
323
  */
 
324
  do {
 
325
    pTDFX->fifoRead = (uint32*)(pTDFX->FbBase + GetReadPtr(pTDFX));
 
326
 
 
327
    /*
 
328
    ** If the HW read_ptr is ahead the SW fifo_ptr, we don't allocate the
 
329
    ** fifo slot immediately behind the HW read_ptr.  This is to prevent
 
330
    ** the following ambiguous situation...
 
331
    **
 
332
    ** If (HW read_ptr == SW fifo_ptr) is it because the HW read_ptr has
 
333
    ** caught up to the SW fifo_ptr and the fifo is completely empty
 
334
    ** OR is it because the SW fifo_ptr has caught up to the HW read_ptr
 
335
    ** and the fifo is completely full?
 
336
    */
 
337
    if ((uint32*)pTDFX->fifoRead > pTDFX->fifoPtr)
 
338
      slots_available = pTDFX->fifoRead - pTDFX->fifoPtr - 1;
 
339
    else
 
340
      slots_available = pTDFX->fifoEnd - pTDFX->fifoPtr;
 
341
  } while (slots > slots_available);
 
342
 
 
343
  pTDFX->fifoSlots = slots_available-slots;
 
344
}
 
345
 
 
346
void 
 
347
TDFXAllocateSlots(TDFXPtr pTDFX, int slots)
 
348
{
 
349
#ifdef TDFX_DEBUG_FIFO
 
350
  if (pTDFX->fifoEnd-pTDFX->fifoPtr<pTDFX->fifoSlots)
 
351
    ErrorF("FIFO overrun\n");
 
352
  if (!pTDFX->syncDone) {
 
353
    ErrorF("Writing to FIFO without sync\n");
 
354
  }
 
355
#endif
 
356
  pTDFX->fifoSlots-=slots;
 
357
  if (pTDFX->fifoSlots<0) TDFXMakeSpace(pTDFX, slots);
 
358
}