gpu: pvr: move debugfs infrastructure to its own files
[sgx.git] / pvr / tools / dbgdriv.c
1 /**********************************************************************
2  *
3  * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful but, except
10  * as otherwise stated in writing, without any warranty; without even the
11  * implied warranty of merchantability or fitness for a particular purpose.
12  * See the GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  * The full GNU General Public License is included in this distribution in
19  * the file called "COPYING".
20  *
21  * Contact Information:
22  * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23  * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24  *
25  ******************************************************************************/
26
27 #include <linux/string.h>
28
29 #include "img_types.h"
30 #include "pvr_debug.h"
31 #include "dbgdrvif.h"
32 #include "dbgdriv.h"
33 #include "hotkey.h"
34 #include "hostfunc.h"
35
36 #define LAST_FRAME_BUF_SIZE     1024
37
38 struct DBG_LASTFRAME_BUFFER {
39         struct DBG_STREAM *psStream;
40         u8 ui8Buffer[LAST_FRAME_BUF_SIZE];
41         u32 ui32BufLen;
42         struct DBG_LASTFRAME_BUFFER *psNext;
43 };
44
45 static struct DBG_STREAM *g_psStreamList;
46 static struct DBG_LASTFRAME_BUFFER *g_psLFBufferList;
47
48 static u32 g_ui32LOff;
49 static u32 g_ui32Line;
50 static u32 g_ui32MonoLines = 25;
51
52 static IMG_BOOL g_bHotkeyMiddump = IMG_FALSE;
53 static u32 g_ui32HotkeyMiddumpStart = 0xffffffff;
54 static u32 g_ui32HotkeyMiddumpEnd = 0xffffffff;
55
56 void *g_pvAPIMutex;
57
58 IMG_BOOL gbDumpThisFrame = IMG_FALSE;
59
60 static u32 SpaceInStream(struct DBG_STREAM *psStream);
61 static IMG_BOOL ExpandStreamBuffer(struct DBG_STREAM *psStream,
62                                    u32 ui32NewSize);
63 struct DBG_LASTFRAME_BUFFER *FindLFBuf(struct DBG_STREAM *psStream);
64
65 struct DBGKM_SERVICE_TABLE g_sDBGKMServices = {
66         sizeof(struct DBGKM_SERVICE_TABLE),
67         ExtDBGDrivCreateStream,
68         ExtDBGDrivDestroyStream,
69         ExtDBGDrivFindStream,
70         ExtDBGDrivWriteString,
71         ExtDBGDrivReadString,
72         ExtDBGDrivWrite,
73         ExtDBGDrivRead,
74         ExtDBGDrivSetCaptureMode,
75         ExtDBGDrivSetOutputMode,
76         ExtDBGDrivSetDebugLevel,
77         ExtDBGDrivSetFrame,
78         ExtDBGDrivGetFrame,
79         ExtDBGDrivOverrideMode,
80         ExtDBGDrivDefaultMode,
81         ExtDBGDrivWrite2,
82         ExtDBGDrivWriteStringCM,
83         ExtDBGDrivWriteCM,
84         ExtDBGDrivSetMarker,
85         ExtDBGDrivGetMarker,
86         ExtDBGDrivStartInitPhase,
87         ExtDBGDrivStopInitPhase,
88         ExtDBGDrivIsCaptureFrame,
89         ExtDBGDrivWriteLF,
90         ExtDBGDrivReadLF,
91         ExtDBGDrivGetStreamOffset,
92         ExtDBGDrivSetStreamOffset,
93         ExtDBGDrivIsLastCaptureFrame,
94         ExtDBGDrivWaitForEvent
95 };
96
97 void *ExtDBGDrivCreateStream(char *pszName,
98                                               u32 ui32CapMode,
99                                               u32 ui32OutMode,
100                                               u32 ui32Flags,
101                                               u32 ui32Size)
102 {
103         void *pvRet;
104
105         HostAquireMutex(g_pvAPIMutex);
106
107         pvRet =
108             DBGDrivCreateStream(pszName, ui32CapMode, ui32OutMode, ui32Flags,
109                                 ui32Size);
110
111         HostReleaseMutex(g_pvAPIMutex);
112
113         return pvRet;
114 }
115
116 void ExtDBGDrivDestroyStream(struct DBG_STREAM *psStream)
117 {
118
119         HostAquireMutex(g_pvAPIMutex);
120
121         DBGDrivDestroyStream(psStream);
122
123         HostReleaseMutex(g_pvAPIMutex);
124
125         return;
126 }
127
128 void *ExtDBGDrivFindStream(char *pszName,
129                                             IMG_BOOL bResetStream)
130 {
131         void *pvRet;
132
133         HostAquireMutex(g_pvAPIMutex);
134
135         pvRet = DBGDrivFindStream(pszName, bResetStream);
136
137         HostReleaseMutex(g_pvAPIMutex);
138
139         return pvRet;
140 }
141
142 u32 ExtDBGDrivWriteString(struct DBG_STREAM *psStream,
143                                               char *pszString,
144                                               u32 ui32Level)
145 {
146         u32 ui32Ret;
147
148         HostAquireMutex(g_pvAPIMutex);
149
150         ui32Ret = DBGDrivWriteString(psStream, pszString, ui32Level);
151
152         HostReleaseMutex(g_pvAPIMutex);
153
154         return ui32Ret;
155 }
156
157 u32 ExtDBGDrivReadString(struct DBG_STREAM *psStream,
158                                              char *pszString,
159                                              u32 ui32Limit)
160 {
161         u32 ui32Ret;
162
163         HostAquireMutex(g_pvAPIMutex);
164
165         ui32Ret = DBGDrivReadString(psStream, pszString, ui32Limit);
166
167         HostReleaseMutex(g_pvAPIMutex);
168
169         return ui32Ret;
170 }
171
172 u32 ExtDBGDrivWrite(struct DBG_STREAM *psStream,
173                                         u8 *pui8InBuf,
174                                         u32 ui32InBuffSize,
175                                         u32 ui32Level)
176 {
177         u32 ui32Ret;
178
179         HostAquireMutex(g_pvAPIMutex);
180
181         ui32Ret = DBGDrivWrite(psStream, pui8InBuf, ui32InBuffSize, ui32Level);
182
183         HostReleaseMutex(g_pvAPIMutex);
184
185         return ui32Ret;
186 }
187
188 u32 ExtDBGDrivRead(struct DBG_STREAM *psStream,
189                                        IMG_BOOL bReadInitBuffer,
190                                        u32 ui32OutBuffSize,
191                                        u8 *pui8OutBuf)
192 {
193         u32 ui32Ret;
194
195         HostAquireMutex(g_pvAPIMutex);
196
197         ui32Ret =
198             DBGDrivRead(psStream, bReadInitBuffer, ui32OutBuffSize, pui8OutBuf);
199
200         HostReleaseMutex(g_pvAPIMutex);
201
202         return ui32Ret;
203 }
204
205 void ExtDBGDrivSetCaptureMode(struct DBG_STREAM *psStream,
206                                            u32 ui32Mode,
207                                            u32 ui32Start,
208                                            u32 ui32End,
209                                            u32 ui32SampleRate)
210 {
211
212         HostAquireMutex(g_pvAPIMutex);
213
214         DBGDrivSetCaptureMode(psStream, ui32Mode, ui32Start, ui32End,
215                               ui32SampleRate);
216
217         HostReleaseMutex(g_pvAPIMutex);
218
219         return;
220 }
221
222 void ExtDBGDrivSetOutputMode(struct DBG_STREAM *psStream,
223                                           u32 ui32OutMode)
224 {
225
226         HostAquireMutex(g_pvAPIMutex);
227
228         DBGDrivSetOutputMode(psStream, ui32OutMode);
229
230         HostReleaseMutex(g_pvAPIMutex);
231
232         return;
233 }
234
235 void ExtDBGDrivSetDebugLevel(struct DBG_STREAM *psStream,
236                                           u32 ui32DebugLevel)
237 {
238
239         HostAquireMutex(g_pvAPIMutex);
240
241         DBGDrivSetDebugLevel(psStream, ui32DebugLevel);
242
243         HostReleaseMutex(g_pvAPIMutex);
244
245         return;
246 }
247
248 void ExtDBGDrivSetFrame(struct DBG_STREAM *psStream, u32 ui32Frame)
249 {
250
251         HostAquireMutex(g_pvAPIMutex);
252
253         DBGDrivSetFrame(psStream, ui32Frame);
254
255         HostReleaseMutex(g_pvAPIMutex);
256
257         return;
258 }
259
260 u32 ExtDBGDrivGetFrame(struct DBG_STREAM *psStream)
261 {
262         u32 ui32Ret;
263
264         HostAquireMutex(g_pvAPIMutex);
265
266         ui32Ret = DBGDrivGetFrame(psStream);
267
268         HostReleaseMutex(g_pvAPIMutex);
269
270         return ui32Ret;
271 }
272
273 u32 ExtDBGDrivIsLastCaptureFrame(struct DBG_STREAM *psStream)
274 {
275         u32 ui32Ret;
276
277         HostAquireMutex(g_pvAPIMutex);
278
279         ui32Ret = DBGDrivIsLastCaptureFrame(psStream);
280
281         HostReleaseMutex(g_pvAPIMutex);
282
283         return ui32Ret;
284 }
285
286 u32 ExtDBGDrivIsCaptureFrame(struct DBG_STREAM *psStream,
287                                                  IMG_BOOL bCheckPreviousFrame)
288 {
289         u32 ui32Ret;
290
291         HostAquireMutex(g_pvAPIMutex);
292
293         ui32Ret = DBGDrivIsCaptureFrame(psStream, bCheckPreviousFrame);
294
295         HostReleaseMutex(g_pvAPIMutex);
296
297         return ui32Ret;
298 }
299
300 void ExtDBGDrivOverrideMode(struct DBG_STREAM *psStream,
301                                          u32 ui32Mode)
302 {
303
304         HostAquireMutex(g_pvAPIMutex);
305
306         DBGDrivOverrideMode(psStream, ui32Mode);
307
308         HostReleaseMutex(g_pvAPIMutex);
309
310         return;
311 }
312
313 void ExtDBGDrivDefaultMode(struct DBG_STREAM *psStream)
314 {
315
316         HostAquireMutex(g_pvAPIMutex);
317
318         DBGDrivDefaultMode(psStream);
319
320         HostReleaseMutex(g_pvAPIMutex);
321
322         return;
323 }
324
325 u32 ExtDBGDrivWrite2(struct DBG_STREAM *psStream,
326                                          u8 *pui8InBuf,
327                                          u32 ui32InBuffSize,
328                                          u32 ui32Level)
329 {
330         u32 ui32Ret;
331
332         HostAquireMutex(g_pvAPIMutex);
333
334         ui32Ret = DBGDrivWrite2(psStream, pui8InBuf, ui32InBuffSize, ui32Level);
335
336         HostReleaseMutex(g_pvAPIMutex);
337
338         return ui32Ret;
339 }
340
341 u32 ExtDBGDrivWriteStringCM(struct DBG_STREAM *psStream,
342                                                 char *pszString,
343                                                 u32 ui32Level)
344 {
345         u32 ui32Ret;
346
347         HostAquireMutex(g_pvAPIMutex);
348
349         ui32Ret = DBGDrivWriteStringCM(psStream, pszString, ui32Level);
350
351         HostReleaseMutex(g_pvAPIMutex);
352
353         return ui32Ret;
354 }
355
356 u32 ExtDBGDrivWriteCM(struct DBG_STREAM *psStream,
357                                           u8 *pui8InBuf,
358                                           u32 ui32InBuffSize,
359                                           u32 ui32Level)
360 {
361         u32 ui32Ret;
362
363         HostAquireMutex(g_pvAPIMutex);
364
365         ui32Ret =
366             DBGDrivWriteCM(psStream, pui8InBuf, ui32InBuffSize, ui32Level);
367
368         HostReleaseMutex(g_pvAPIMutex);
369
370         return ui32Ret;
371 }
372
373 void ExtDBGDrivSetMarker(struct DBG_STREAM *psStream,
374                                       u32 ui32Marker)
375 {
376
377         HostAquireMutex(g_pvAPIMutex);
378
379         DBGDrivSetMarker(psStream, ui32Marker);
380
381         HostReleaseMutex(g_pvAPIMutex);
382
383         return;
384 }
385
386 u32 ExtDBGDrivGetMarker(struct DBG_STREAM *psStream)
387 {
388         u32 ui32Marker;
389
390         HostAquireMutex(g_pvAPIMutex);
391
392         ui32Marker = DBGDrivGetMarker(psStream);
393
394         HostReleaseMutex(g_pvAPIMutex);
395
396         return ui32Marker;
397 }
398
399 u32 ExtDBGDrivWriteLF(struct DBG_STREAM *psStream,
400                                           u8 *pui8InBuf,
401                                           u32 ui32InBuffSize,
402                                           u32 ui32Level,
403                                           u32 ui32Flags)
404 {
405         u32 ui32Ret;
406
407         HostAquireMutex(g_pvAPIMutex);
408
409         ui32Ret =
410             DBGDrivWriteLF(psStream, pui8InBuf, ui32InBuffSize, ui32Level,
411                            ui32Flags);
412
413         HostReleaseMutex(g_pvAPIMutex);
414
415         return ui32Ret;
416 }
417
418 u32 ExtDBGDrivReadLF(struct DBG_STREAM *psStream,
419                                          u32 ui32OutBuffSize,
420                                          u8 *pui8OutBuf)
421 {
422         u32 ui32Ret;
423
424         HostAquireMutex(g_pvAPIMutex);
425
426         ui32Ret = DBGDrivReadLF(psStream, ui32OutBuffSize, pui8OutBuf);
427
428         HostReleaseMutex(g_pvAPIMutex);
429
430         return ui32Ret;
431 }
432
433 void ExtDBGDrivStartInitPhase(struct DBG_STREAM *psStream)
434 {
435
436         HostAquireMutex(g_pvAPIMutex);
437
438         DBGDrivStartInitPhase(psStream);
439
440         HostReleaseMutex(g_pvAPIMutex);
441
442         return;
443 }
444
445 void ExtDBGDrivStopInitPhase(struct DBG_STREAM *psStream)
446 {
447
448         HostAquireMutex(g_pvAPIMutex);
449
450         DBGDrivStopInitPhase(psStream);
451
452         HostReleaseMutex(g_pvAPIMutex);
453
454         return;
455 }
456
457 u32 ExtDBGDrivGetStreamOffset(struct DBG_STREAM *psStream)
458 {
459         u32 ui32Ret;
460
461         HostAquireMutex(g_pvAPIMutex);
462
463         ui32Ret = DBGDrivGetStreamOffset(psStream);
464
465         HostReleaseMutex(g_pvAPIMutex);
466
467         return ui32Ret;
468 }
469
470 void ExtDBGDrivSetStreamOffset(struct DBG_STREAM *psStream,
471                                                 u32 ui32StreamOffset)
472 {
473
474         HostAquireMutex(g_pvAPIMutex);
475
476         DBGDrivSetStreamOffset(psStream, ui32StreamOffset);
477
478         HostReleaseMutex(g_pvAPIMutex);
479 }
480
481 void ExtDBGDrivWaitForEvent(enum DBG_EVENT eEvent)
482 {
483 #if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
484         DBGDrivWaitForEvent(eEvent);
485 #else
486         PVR_UNREFERENCED_PARAMETER(eEvent);
487 #endif
488 }
489
490 u32 AtoI(char *szIn)
491 {
492         u32 ui32Len = 0;
493         u32 ui32Value = 0;
494         u32 ui32Digit = 1;
495         u32 ui32Base = 10;
496         int iPos;
497         char bc;
498
499         while (szIn[ui32Len] > 0)
500                 ui32Len++;
501
502         if (ui32Len == 0)
503                 return 0;
504
505         iPos = 0;
506         while (szIn[iPos] == '0')
507                 iPos++;
508         if (szIn[iPos] == '\0')
509                 return 0;
510         if (szIn[iPos] == 'x' || szIn[iPos] == 'X') {
511                 ui32Base = 16;
512                 szIn[iPos] = '0';
513         }
514
515         for (iPos = ui32Len - 1; iPos >= 0; iPos--) {
516                 bc = szIn[iPos];
517
518                 if ((bc >= 'a') && (bc <= 'f') && ui32Base == 16)
519                         bc -= 'a' - 0xa;
520                 else if ((bc >= 'A') && (bc <= 'F') && ui32Base == 16)
521                         bc -= 'A' - 0xa;
522                 else if ((bc >= '0') && (bc <= '9'))
523                         bc -= '0';
524                 else
525                         return 0;
526
527                 ui32Value += bc * ui32Digit;
528
529                 ui32Digit = ui32Digit * ui32Base;
530         }
531         return ui32Value;
532 }
533
534 IMG_BOOL StreamValid(struct DBG_STREAM *psStream)
535 {
536         struct DBG_STREAM *psThis;
537
538         psThis = g_psStreamList;
539
540         while (psThis)
541                 if (psStream && (psThis == psStream))
542                         return IMG_TRUE;
543                 else
544                         psThis = psThis->psNext;
545
546         return IMG_FALSE;
547 }
548
549 void Write(struct DBG_STREAM *psStream, u8 *pui8Data,
550            u32 ui32InBuffSize)
551 {
552
553         if ((psStream->ui32WPtr + ui32InBuffSize) > psStream->ui32Size) {
554                 u32 ui32B1 = psStream->ui32Size - psStream->ui32WPtr;
555                 u32 ui32B2 = ui32InBuffSize - ui32B1;
556
557                 HostMemCopy((void *) (psStream->ui32Base +
558                                           psStream->ui32WPtr),
559                             (void *) pui8Data, ui32B1);
560
561                 HostMemCopy((void *) psStream->ui32Base,
562                             (void *) ((u32) pui8Data + ui32B1),
563                             ui32B2);
564
565                 psStream->ui32WPtr = ui32B2;
566         } else {
567                 HostMemCopy((void *) (psStream->ui32Base +
568                                           psStream->ui32WPtr),
569                             (void *) pui8Data, ui32InBuffSize);
570
571                 psStream->ui32WPtr += ui32InBuffSize;
572
573                 if (psStream->ui32WPtr == psStream->ui32Size)
574                         psStream->ui32WPtr = 0;
575         }
576         psStream->ui32DataWritten += ui32InBuffSize;
577 }
578
579 void MonoOut(char *pszString, IMG_BOOL bNewLine)
580 {
581         u32 i;
582         char *pScreen;
583
584         pScreen = (char *)DBGDRIV_MONOBASE;
585
586         pScreen += g_ui32Line * 160;
587
588         i = 0;
589         do {
590                 pScreen[g_ui32LOff + (i * 2)] = pszString[i];
591                 pScreen[g_ui32LOff + (i * 2) + 1] = 127;
592                 i++;
593         } while ((pszString[i] != 0) && (i < 4096));
594
595         g_ui32LOff += i * 2;
596
597         if (bNewLine) {
598                 g_ui32LOff = 0;
599                 g_ui32Line++;
600         }
601
602         if (g_ui32Line == g_ui32MonoLines) {
603                 g_ui32Line = g_ui32MonoLines - 1;
604
605                 HostMemCopy((void *) DBGDRIV_MONOBASE,
606                             (void *) (DBGDRIV_MONOBASE + 160),
607                             160 * (g_ui32MonoLines - 1));
608
609                 HostMemSet((void *) (DBGDRIV_MONOBASE +
610                                          (160 * (g_ui32MonoLines - 1))), 0,
611                            160);
612         }
613 }
614
615 void AppendName(char *pszOut, char *pszBase, char *pszName)
616 {
617         u32 i;
618         u32 ui32Off;
619
620         i = 0;
621
622         while (pszBase[i] != 0) {
623                 pszOut[i] = pszBase[i];
624                 i++;
625         }
626
627         ui32Off = i;
628         i = 0;
629
630         while (pszName[i] != 0) {
631                 pszOut[ui32Off + i] = pszName[i];
632                 i++;
633         }
634
635         pszOut[ui32Off + i] = pszName[i];
636 }
637
638 void *DBGDrivCreateStream(char *pszName,
639                                            u32 ui32CapMode,
640                                            u32 ui32OutMode,
641                                            u32 ui32Flags,
642                                            u32 ui32Size)
643 {
644         struct DBG_STREAM *psStream;
645         struct DBG_STREAM *psInitStream;
646         struct DBG_LASTFRAME_BUFFER *psLFBuffer;
647         u32 ui32Off;
648         void *pvBase;
649
650         psStream = (struct DBG_STREAM *)DBGDrivFindStream(pszName, IMG_FALSE);
651
652         if (psStream)
653                 return (void *)psStream;
654
655         psStream = HostNonPageablePageAlloc(1);
656         psInitStream = HostNonPageablePageAlloc(1);
657         psLFBuffer = HostNonPageablePageAlloc(1);
658         if ((!psStream) || (!psInitStream) || (!psLFBuffer)
659             ) {
660                 PVR_DPF(PVR_DBG_ERROR,
661                          "DBGDriv: Couldn't create buffer !!!!!\n\r");
662                 return NULL;
663         }
664
665         if ((ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
666                 pvBase = HostNonPageablePageAlloc(ui32Size);
667         else
668                 pvBase = HostPageablePageAlloc(ui32Size);
669
670         if (!pvBase) {
671                 PVR_DPF(PVR_DBG_ERROR,
672                          "DBGDriv: Couldn't create buffer !!!!!\n\r");
673                 HostNonPageablePageFree(psStream);
674                 return NULL;
675         }
676
677         psStream->psNext = 0;
678         psStream->ui32Flags = ui32Flags;
679         psStream->ui32Base = (u32) pvBase;
680         psStream->ui32Size = ui32Size * 4096;
681         psStream->ui32RPtr = 0;
682         psStream->ui32WPtr = 0;
683         psStream->ui32DataWritten = 0;
684         psStream->ui32CapMode = ui32CapMode;
685         psStream->ui32OutMode = ui32OutMode;
686         psStream->ui32DebugLevel = DEBUG_LEVEL_0;
687         psStream->ui32DefaultMode = ui32CapMode;
688         psStream->ui32Start = 0;
689         psStream->ui32End = 0;
690         psStream->ui32Current = 0;
691         psStream->ui32SampleRate = 1;
692         psStream->ui32Access = 0;
693         psStream->ui32Timeout = 0;
694         psStream->ui32Marker = 0;
695         psStream->bInitPhaseComplete = IMG_FALSE;
696
697         if ((ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
698                 pvBase = HostNonPageablePageAlloc(ui32Size);
699         else
700                 pvBase = HostPageablePageAlloc(ui32Size);
701
702         if (!pvBase) {
703                 PVR_DPF(PVR_DBG_ERROR,
704                          "DBGDriv: Couldn't create buffer !!!!!\n\r");
705
706                 if ((psStream->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
707                         HostNonPageablePageFree((void *) psStream->
708                                                 ui32Base);
709                 else
710                         HostPageablePageFree((void *) psStream->ui32Base);
711                 HostNonPageablePageFree(psStream);
712                 return NULL;
713         }
714
715         psInitStream->psNext = 0;
716         psInitStream->ui32Flags = ui32Flags;
717         psInitStream->ui32Base = (u32) pvBase;
718         psInitStream->ui32Size = ui32Size * 4096;
719         psInitStream->ui32RPtr = 0;
720         psInitStream->ui32WPtr = 0;
721         psInitStream->ui32DataWritten = 0;
722         psInitStream->ui32CapMode = ui32CapMode;
723         psInitStream->ui32OutMode = ui32OutMode;
724         psInitStream->ui32DebugLevel = DEBUG_LEVEL_0;
725         psInitStream->ui32DefaultMode = ui32CapMode;
726         psInitStream->ui32Start = 0;
727         psInitStream->ui32End = 0;
728         psInitStream->ui32Current = 0;
729         psInitStream->ui32SampleRate = 1;
730         psInitStream->ui32Access = 0;
731         psInitStream->ui32Timeout = 0;
732         psInitStream->ui32Marker = 0;
733         psInitStream->bInitPhaseComplete = IMG_FALSE;
734
735         psStream->psInitStream = psInitStream;
736
737         psLFBuffer->psStream = psStream;
738         psLFBuffer->ui32BufLen = 0;
739
740         g_bHotkeyMiddump = IMG_FALSE;
741         g_ui32HotkeyMiddumpStart = 0xffffffff;
742         g_ui32HotkeyMiddumpEnd = 0xffffffff;
743
744         ui32Off = 0;
745
746         do {
747                 psStream->szName[ui32Off] = pszName[ui32Off];
748
749                 ui32Off++;
750         } while ((pszName[ui32Off] != 0)
751                  && (ui32Off < (4096 - sizeof(struct DBG_STREAM))));
752
753         psStream->szName[ui32Off] = pszName[ui32Off];
754
755         psStream->psNext = g_psStreamList;
756         g_psStreamList = psStream;
757
758         psLFBuffer->psNext = g_psLFBufferList;
759         g_psLFBufferList = psLFBuffer;
760
761         return (void *)psStream;
762 }
763
764 void DBGDrivDestroyStream(struct DBG_STREAM *psStream)
765 {
766         struct DBG_STREAM *psStreamThis;
767         struct DBG_STREAM *psStreamPrev;
768         struct DBG_LASTFRAME_BUFFER *psLFBuffer;
769         struct DBG_LASTFRAME_BUFFER *psLFThis;
770         struct DBG_LASTFRAME_BUFFER *psLFPrev;
771
772         PVR_DPF(PVR_DBG_MESSAGE, "DBGDriv: Destroying stream %s\r\n",
773                  psStream->szName);
774
775         if (!StreamValid(psStream))
776                 return;
777
778         psLFBuffer = FindLFBuf(psStream);
779
780         psStreamThis = g_psStreamList;
781         psStreamPrev = 0;
782
783         while (psStreamThis)
784                 if (psStreamThis == psStream) {
785                         if (psStreamPrev)
786                                 psStreamPrev->psNext = psStreamThis->psNext;
787                         else
788                                 g_psStreamList = psStreamThis->psNext;
789
790                         psStreamThis = 0;
791                 } else {
792                         psStreamPrev = psStreamThis;
793                         psStreamThis = psStreamThis->psNext;
794                 }
795
796         psLFThis = g_psLFBufferList;
797         psLFPrev = 0;
798
799         while (psLFThis)
800                 if (psLFThis == psLFBuffer) {
801                         if (psLFPrev)
802                                 psLFPrev->psNext = psLFThis->psNext;
803                         else
804                                 g_psLFBufferList = psLFThis->psNext;
805
806                         psLFThis = 0;
807                 } else {
808                         psLFPrev = psLFThis;
809                         psLFThis = psLFThis->psNext;
810                 }
811
812         if (psStream->ui32CapMode & DEBUG_CAPMODE_HOTKEY)
813                 DeactivateHotKeys();
814
815         if ((psStream->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0) {
816                 HostNonPageablePageFree((void *) psStream->ui32Base);
817                 HostNonPageablePageFree((void *) psStream->psInitStream->
818                                         ui32Base);
819         } else {
820                 HostPageablePageFree((void *) psStream->ui32Base);
821                 HostPageablePageFree((void *) psStream->psInitStream->
822                                      ui32Base);
823         }
824
825         HostNonPageablePageFree(psStream->psInitStream);
826         HostNonPageablePageFree(psStream);
827         HostNonPageablePageFree(psLFBuffer);
828
829         if (g_psStreamList == 0)
830                 PVR_DPF(PVR_DBG_MESSAGE, "DBGDriv: Stream list now empty");
831
832         return;
833 }
834
835 void *DBGDrivFindStream(char *pszName,
836                                          IMG_BOOL bResetStream)
837 {
838         struct DBG_STREAM *psStream;
839         struct DBG_STREAM *psThis;
840         u32 ui32Off;
841         IMG_BOOL bAreSame;
842
843         psStream = 0;
844
845         for (psThis = g_psStreamList; psThis != NULL;
846              psThis = psThis->psNext) {
847                 bAreSame = IMG_TRUE;
848                 ui32Off = 0;
849
850                 if (strlen(psThis->szName) == strlen(pszName)) {
851                         while ((psThis->szName[ui32Off] != 0)
852                                && (pszName[ui32Off] != 0) && (ui32Off < 128)
853                                && bAreSame) {
854                                 if (psThis->szName[ui32Off] != pszName[ui32Off])
855                                         bAreSame = IMG_FALSE;
856
857                                 ui32Off++;
858                         }
859                 } else {
860                         bAreSame = IMG_FALSE;
861                 }
862
863                 if (bAreSame) {
864                         psStream = psThis;
865                         break;
866                 }
867         }
868
869         if (bResetStream && psStream) {
870                 static char szComment[] = "-- Init phase terminated\r\n";
871                 psStream->psInitStream->ui32RPtr = 0;
872                 psStream->ui32RPtr = 0;
873                 psStream->ui32WPtr = 0;
874                 psStream->ui32DataWritten =
875                     psStream->psInitStream->ui32DataWritten;
876                 if (psStream->bInitPhaseComplete == IMG_FALSE) {
877                         if (psStream->ui32Flags & DEBUG_FLAGS_TEXTSTREAM)
878                                 DBGDrivWrite2(psStream, (u8 *) szComment,
879                                               sizeof(szComment) - 1, 0x01);
880                         psStream->bInitPhaseComplete = IMG_TRUE;
881                 }
882         }
883
884         return (void *)psStream;
885 }
886
887 u32 DBGDrivWriteStringCM(struct DBG_STREAM *psStream,
888                                              char *pszString,
889                                              u32 ui32Level)
890 {
891
892         if (!StreamValid(psStream))
893                 return 0xFFFFFFFF;
894
895         if (psStream->ui32CapMode & DEBUG_CAPMODE_FRAMED) {
896                 if (!(psStream->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE))
897                         return 0;
898         } else {
899                 if (psStream->ui32CapMode == DEBUG_CAPMODE_HOTKEY)
900                         if ((psStream->ui32Current != g_ui32HotKeyFrame)
901                             || (g_bHotKeyPressed == IMG_FALSE))
902                                 return 0;
903         }
904
905         return DBGDrivWriteString(psStream, pszString, ui32Level);
906
907 }
908
909 u32 DBGDrivWriteString(struct DBG_STREAM *psStream,
910                                            char *pszString,
911                                            u32 ui32Level)
912 {
913         u32 ui32Len;
914         u32 ui32Space;
915         u32 ui32WPtr;
916         u8 *pui8Buffer;
917
918         if (!StreamValid(psStream))
919                 return 0xFFFFFFFF;
920
921         if (!(psStream->ui32DebugLevel & ui32Level))
922                 return 0xFFFFFFFF;
923
924         if (!(psStream->ui32OutMode & DEBUG_OUTMODE_ASYNC)) {
925                 if (psStream->ui32OutMode & DEBUG_OUTMODE_STANDARDDBG)
926                         PVR_DPF(PVR_DBG_MESSAGE, "%s: %s\r\n",
927                                  psStream->szName, pszString);
928
929                 if (psStream->ui32OutMode & DEBUG_OUTMODE_MONO) {
930                         MonoOut(psStream->szName, IMG_FALSE);
931                         MonoOut(": ", IMG_FALSE);
932                         MonoOut(pszString, IMG_TRUE);
933                 }
934         }
935
936         if (!((psStream->ui32OutMode & DEBUG_OUTMODE_STREAMENABLE) ||
937               (psStream->ui32OutMode & DEBUG_OUTMODE_ASYNC)
938             )
939             )
940                 return 0xFFFFFFFF;
941
942         ui32Space = SpaceInStream(psStream);
943
944         if (ui32Space > 0)
945                 ui32Space--;
946
947         ui32Len = 0;
948         ui32WPtr = psStream->ui32WPtr;
949         pui8Buffer = (u8 *) psStream->ui32Base;
950
951         while ((pszString[ui32Len] != 0) && (ui32Len < ui32Space)) {
952                 pui8Buffer[ui32WPtr] = pszString[ui32Len];
953                 ui32Len++;
954                 ui32WPtr++;
955                 if (ui32WPtr == psStream->ui32Size)
956                         ui32WPtr = 0;
957         }
958
959         if (ui32Len < ui32Space) {
960
961                 pui8Buffer[ui32WPtr] = pszString[ui32Len];
962                 ui32Len++;
963                 ui32WPtr++;
964                 if (ui32WPtr == psStream->ui32Size)
965                         ui32WPtr = 0;
966
967                 psStream->ui32WPtr = ui32WPtr;
968                 psStream->ui32DataWritten += ui32Len;
969         } else {
970                 ui32Len = 0;
971         }
972
973 #if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
974         if (ui32Len)
975                 HostSignalEvent(DBG_EVENT_STREAM_DATA);
976 #endif
977
978         return ui32Len;
979 }
980
981 u32 DBGDrivReadString(struct DBG_STREAM *psStream,
982                                           char *pszString,
983                                           u32 ui32Limit)
984 {
985         u32 ui32OutLen;
986         u32 ui32Len;
987         u32 ui32Offset;
988         u8 *pui8Buff;
989
990         if (!StreamValid(psStream))
991                 return 0;
992
993         pui8Buff = (u8 *) psStream->ui32Base;
994         ui32Offset = psStream->ui32RPtr;
995
996         if (psStream->ui32RPtr == psStream->ui32WPtr)
997                 return 0;
998
999         ui32Len = 0;
1000         while ((pui8Buff[ui32Offset] != 0)
1001                && (ui32Offset != psStream->ui32WPtr)) {
1002                 ui32Offset++;
1003                 ui32Len++;
1004
1005                 if (ui32Offset == psStream->ui32Size)
1006                         ui32Offset = 0;
1007         }
1008
1009         ui32OutLen = ui32Len + 1;
1010
1011         if (ui32Len > ui32Limit)
1012                 return 0;
1013
1014         ui32Offset = psStream->ui32RPtr;
1015         ui32Len = 0;
1016
1017         while ((pui8Buff[ui32Offset] != 0) && (ui32Len < ui32Limit)) {
1018                 pszString[ui32Len] = pui8Buff[ui32Offset];
1019                 ui32Offset++;
1020                 ui32Len++;
1021
1022                 if (ui32Offset == psStream->ui32Size)
1023                         ui32Offset = 0;
1024         }
1025
1026         pszString[ui32Len] = pui8Buff[ui32Offset];
1027
1028         psStream->ui32RPtr = ui32Offset + 1;
1029
1030         if (psStream->ui32RPtr == psStream->ui32Size)
1031                 psStream->ui32RPtr = 0;
1032
1033         return ui32OutLen;
1034 }
1035
1036 u32 DBGDrivWrite(struct DBG_STREAM *psMainStream,
1037                                      u8 *pui8InBuf,
1038                                      u32 ui32InBuffSize,
1039                                      u32 ui32Level)
1040 {
1041         u32 ui32Space;
1042         struct DBG_STREAM *psStream;
1043
1044         if (!StreamValid(psMainStream))
1045                 return 0xFFFFFFFF;
1046
1047         if (!(psMainStream->ui32DebugLevel & ui32Level))
1048                 return 0xFFFFFFFF;
1049
1050         if (psMainStream->ui32CapMode & DEBUG_CAPMODE_FRAMED) {
1051                 if (!(psMainStream->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE))
1052                         return 0xFFFFFFFF;
1053         } else {
1054         if (psMainStream->ui32CapMode == DEBUG_CAPMODE_HOTKEY)
1055                 if ((psMainStream->ui32Current != g_ui32HotKeyFrame)
1056                     || (g_bHotKeyPressed == IMG_FALSE))
1057                         return 0xFFFFFFFF;
1058
1059         }
1060
1061         if (psMainStream->bInitPhaseComplete)
1062                 psStream = psMainStream;
1063         else
1064                 psStream = psMainStream->psInitStream;
1065
1066         ui32Space = SpaceInStream(psStream);
1067
1068         if (!(psStream->ui32OutMode & DEBUG_OUTMODE_STREAMENABLE))
1069                 return 0;
1070
1071         if (ui32Space < 8)
1072                 return 0;
1073
1074         if (ui32Space <= (ui32InBuffSize + 4))
1075                 ui32InBuffSize = ui32Space - 8;
1076
1077         Write(psStream, (u8 *) &ui32InBuffSize, 4);
1078         Write(psStream, pui8InBuf, ui32InBuffSize);
1079
1080 #if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
1081         if (ui32InBuffSize)
1082                 HostSignalEvent(DBG_EVENT_STREAM_DATA);
1083 #endif
1084         return ui32InBuffSize;
1085 }
1086
1087 u32 DBGDrivWriteCM(struct DBG_STREAM *psStream,
1088                                        u8 *pui8InBuf,
1089                                        u32 ui32InBuffSize,
1090                                        u32 ui32Level)
1091 {
1092
1093         if (!StreamValid(psStream))
1094                 return 0xFFFFFFFF;
1095
1096         if (psStream->ui32CapMode & DEBUG_CAPMODE_FRAMED) {
1097                 if (!(psStream->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE))
1098                         return 0xFFFFFFFF;
1099         } else {
1100                 if (psStream->ui32CapMode == DEBUG_CAPMODE_HOTKEY)
1101                         if ((psStream->ui32Current != g_ui32HotKeyFrame)
1102                             || (g_bHotKeyPressed == IMG_FALSE))
1103                                 return 0xFFFFFFFF;
1104         }
1105
1106         return DBGDrivWrite2(psStream, pui8InBuf, ui32InBuffSize, ui32Level);
1107 }
1108
1109 u32 DBGDrivWrite2(struct DBG_STREAM *psMainStream,
1110                                       u8 *pui8InBuf,
1111                                       u32 ui32InBuffSize,
1112                                       u32 ui32Level)
1113 {
1114         u32 ui32Space;
1115         struct DBG_STREAM *psStream;
1116
1117         if (!StreamValid(psMainStream))
1118                 return 0xFFFFFFFF;
1119
1120         if (!(psMainStream->ui32DebugLevel & ui32Level))
1121                 return 0xFFFFFFFF;
1122
1123         if (psMainStream->bInitPhaseComplete)
1124                 psStream = psMainStream;
1125         else
1126                 psStream = psMainStream->psInitStream;
1127
1128         ui32Space = SpaceInStream(psStream);
1129
1130         if (!(psStream->ui32OutMode & DEBUG_OUTMODE_STREAMENABLE))
1131                 return 0;
1132
1133         if (psStream->ui32Flags & DEBUG_FLAGS_NO_BUF_EXPANDSION) {
1134
1135                 if (ui32Space < 32)
1136                         return 0;
1137         } else {
1138                 if ((ui32Space < 32) || (ui32Space <= (ui32InBuffSize + 4))) {
1139                         u32 ui32NewBufSize;
1140
1141                         ui32NewBufSize = 2 * psStream->ui32Size;
1142
1143                         if (ui32InBuffSize > psStream->ui32Size)
1144                                 ui32NewBufSize += ui32InBuffSize;
1145
1146                         if (!ExpandStreamBuffer(psStream, ui32NewBufSize))
1147                                 if (ui32Space < 32)
1148                                         return 0;
1149
1150                         ui32Space = SpaceInStream(psStream);
1151                 }
1152         }
1153
1154         if (ui32Space <= (ui32InBuffSize + 4))
1155                 ui32InBuffSize = ui32Space - 4;
1156
1157         Write(psStream, pui8InBuf, ui32InBuffSize);
1158
1159 #if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
1160         if (ui32InBuffSize)
1161                 HostSignalEvent(DBG_EVENT_STREAM_DATA);
1162 #endif
1163         return ui32InBuffSize;
1164 }
1165
1166 u32 DBGDrivRead(struct DBG_STREAM *psMainStream,
1167                                     IMG_BOOL bReadInitBuffer,
1168                                     u32 ui32OutBuffSize,
1169                                     u8 *pui8OutBuf)
1170 {
1171         u32 ui32Data;
1172         struct DBG_STREAM *psStream;
1173
1174         if (!StreamValid(psMainStream))
1175                 return 0;
1176
1177         if (bReadInitBuffer)
1178                 psStream = psMainStream->psInitStream;
1179         else
1180                 psStream = psMainStream;
1181
1182         if (psStream->ui32RPtr == psStream->ui32WPtr)
1183                 return 0;
1184
1185         if (psStream->ui32RPtr <= psStream->ui32WPtr) {
1186                 ui32Data = psStream->ui32WPtr - psStream->ui32RPtr;
1187         } else {
1188                 ui32Data =
1189                     psStream->ui32WPtr + (psStream->ui32Size -
1190                                           psStream->ui32RPtr);
1191         }
1192
1193         if (ui32Data > ui32OutBuffSize)
1194                 ui32Data = ui32OutBuffSize;
1195
1196         if ((psStream->ui32RPtr + ui32Data) > psStream->ui32Size) {
1197                 u32 ui32B1 = psStream->ui32Size - psStream->ui32RPtr;
1198                 u32 ui32B2 = ui32Data - ui32B1;
1199
1200                 HostMemCopy((void *) pui8OutBuf,
1201                             (void *) (psStream->ui32Base +
1202                                           psStream->ui32RPtr), ui32B1);
1203
1204                 HostMemCopy((void *) ((u32) pui8OutBuf + ui32B1),
1205                             (void *) psStream->ui32Base, ui32B2);
1206
1207                 psStream->ui32RPtr = ui32B2;
1208         } else {
1209                 HostMemCopy((void *) pui8OutBuf,
1210                             (void *) (psStream->ui32Base +
1211                                           psStream->ui32RPtr), ui32Data);
1212
1213                 psStream->ui32RPtr += ui32Data;
1214
1215                 if (psStream->ui32RPtr == psStream->ui32Size)
1216                         psStream->ui32RPtr = 0;
1217         }
1218
1219         return ui32Data;
1220 }
1221
1222 void DBGDrivSetCaptureMode(struct DBG_STREAM *psStream,
1223                                         u32 ui32Mode,
1224                                         u32 ui32Start,
1225                                         u32 ui32End,
1226                                         u32 ui32SampleRate)
1227 {
1228
1229         if (!StreamValid(psStream))
1230                 return;
1231
1232         psStream->ui32CapMode = ui32Mode;
1233         psStream->ui32DefaultMode = ui32Mode;
1234         psStream->ui32Start = ui32Start;
1235         psStream->ui32End = ui32End;
1236         psStream->ui32SampleRate = ui32SampleRate;
1237
1238         if (psStream->ui32CapMode & DEBUG_CAPMODE_HOTKEY)
1239                 ActivateHotKeys(psStream);
1240 }
1241
1242 void DBGDrivSetOutputMode(struct DBG_STREAM *psStream,
1243                                        u32 ui32OutMode)
1244 {
1245
1246         if (!StreamValid(psStream))
1247                 return;
1248
1249         psStream->ui32OutMode = ui32OutMode;
1250 }
1251
1252 void DBGDrivSetDebugLevel(struct DBG_STREAM *psStream,
1253                                        u32 ui32DebugLevel)
1254 {
1255
1256         if (!StreamValid(psStream))
1257                 return;
1258
1259         psStream->ui32DebugLevel = ui32DebugLevel;
1260 }
1261
1262 void DBGDrivSetFrame(struct DBG_STREAM *psStream, u32 ui32Frame)
1263 {
1264
1265         if (!StreamValid(psStream))
1266                 return;
1267
1268         psStream->ui32Current = ui32Frame;
1269
1270         if ((ui32Frame >= psStream->ui32Start) &&
1271             (ui32Frame <= psStream->ui32End) &&
1272             (((ui32Frame - psStream->ui32Start) % psStream->ui32SampleRate) ==
1273              0))
1274                 psStream->ui32Flags |= DEBUG_FLAGS_ENABLESAMPLE;
1275         else
1276                 psStream->ui32Flags &= ~DEBUG_FLAGS_ENABLESAMPLE;
1277
1278         if (g_bHotkeyMiddump) {
1279                 if ((ui32Frame >= g_ui32HotkeyMiddumpStart) &&
1280                     (ui32Frame <= g_ui32HotkeyMiddumpEnd) &&
1281                     (((ui32Frame -
1282                        g_ui32HotkeyMiddumpStart) % psStream->ui32SampleRate) ==
1283                      0)) {
1284                         psStream->ui32Flags |= DEBUG_FLAGS_ENABLESAMPLE;
1285                 } else {
1286                         psStream->ui32Flags &= ~DEBUG_FLAGS_ENABLESAMPLE;
1287                         if (psStream->ui32Current > g_ui32HotkeyMiddumpEnd)
1288                                 g_bHotkeyMiddump = IMG_FALSE;
1289                 }
1290         }
1291
1292         if (g_bHotKeyRegistered) {
1293                 g_bHotKeyRegistered = IMG_FALSE;
1294
1295                 PVR_DPF(PVR_DBG_MESSAGE, "Hotkey pressed (%08x)!\n",
1296                          psStream);
1297
1298                 if (!g_bHotKeyPressed) {
1299
1300                         g_ui32HotKeyFrame = psStream->ui32Current + 2;
1301
1302                         g_bHotKeyPressed = IMG_TRUE;
1303                 }
1304
1305                 if ((psStream->ui32CapMode & DEBUG_CAPMODE_FRAMED)
1306                     && (psStream->ui32CapMode & DEBUG_CAPMODE_HOTKEY)) {
1307                         if (!g_bHotkeyMiddump) {
1308
1309                                 g_ui32HotkeyMiddumpStart =
1310                                     g_ui32HotKeyFrame + 1;
1311                                 g_ui32HotkeyMiddumpEnd = 0xffffffff;
1312                                 g_bHotkeyMiddump = IMG_TRUE;
1313                                 PVR_DPF(PVR_DBG_MESSAGE,
1314                                          "Sampling every %d frame(s)\n",
1315                                          psStream->ui32SampleRate);
1316                         } else {
1317
1318                                 g_ui32HotkeyMiddumpEnd = g_ui32HotKeyFrame;
1319                                 PVR_DPF(PVR_DBG_MESSAGE,
1320                                          "Turning off sampling\n");
1321                         }
1322                 }
1323
1324         }
1325
1326         if (psStream->ui32Current > g_ui32HotKeyFrame)
1327                 g_bHotKeyPressed = IMG_FALSE;
1328 }
1329
1330 u32 DBGDrivGetFrame(struct DBG_STREAM *psStream)
1331 {
1332
1333         if (!StreamValid(psStream))
1334                 return 0;
1335
1336         return psStream->ui32Current;
1337 }
1338
1339 u32 DBGDrivIsLastCaptureFrame(struct DBG_STREAM *psStream)
1340 {
1341         u32 ui32NextFrame;
1342
1343         if (!StreamValid(psStream))
1344                 return IMG_FALSE;
1345
1346         if (psStream->ui32CapMode & DEBUG_CAPMODE_FRAMED) {
1347                 ui32NextFrame =
1348                     psStream->ui32Current + psStream->ui32SampleRate;
1349                 if (ui32NextFrame > psStream->ui32End)
1350                         return IMG_TRUE;
1351         }
1352         return IMG_FALSE;
1353 }
1354
1355 u32 DBGDrivIsCaptureFrame(struct DBG_STREAM *psStream,
1356                                               IMG_BOOL bCheckPreviousFrame)
1357 {
1358         u32 ui32FrameShift = bCheckPreviousFrame ? 1 : 0;
1359
1360         if (!StreamValid(psStream))
1361                 return IMG_FALSE;
1362
1363         if (psStream->ui32CapMode & DEBUG_CAPMODE_FRAMED) {
1364
1365                 if (g_bHotkeyMiddump) {
1366                         if ((psStream->ui32Current >=
1367                              (g_ui32HotkeyMiddumpStart - ui32FrameShift))
1368                             && (psStream->ui32Current <=
1369                                 (g_ui32HotkeyMiddumpEnd - ui32FrameShift))
1370                             &&
1371                             ((((psStream->ui32Current + ui32FrameShift) -
1372                                g_ui32HotkeyMiddumpStart) %
1373                               psStream->ui32SampleRate) == 0))
1374                                 return IMG_TRUE;
1375                 } else {
1376                         if ((psStream->ui32Current >=
1377                              (psStream->ui32Start - ui32FrameShift))
1378                             && (psStream->ui32Current <=
1379                                 (psStream->ui32End - ui32FrameShift))
1380                             &&
1381                             ((((psStream->ui32Current + ui32FrameShift) -
1382                                psStream->ui32Start) %
1383                               psStream->ui32SampleRate) == 0))
1384                                 return IMG_TRUE;
1385                 }
1386         } else if (psStream->ui32CapMode == DEBUG_CAPMODE_HOTKEY) {
1387                 if ((psStream->ui32Current ==
1388                      (g_ui32HotKeyFrame - ui32FrameShift))
1389                     && (g_bHotKeyPressed))
1390                         return IMG_TRUE;
1391         }
1392
1393
1394         return IMG_FALSE;
1395 }
1396
1397 void DBGDrivOverrideMode(struct DBG_STREAM *psStream, u32 ui32Mode)
1398 {
1399
1400         if (!StreamValid(psStream))
1401                 return;
1402
1403         psStream->ui32CapMode = ui32Mode;
1404 }
1405
1406 void DBGDrivDefaultMode(struct DBG_STREAM *psStream)
1407 {
1408
1409         if (!StreamValid(psStream))
1410                 return;
1411
1412         psStream->ui32CapMode = psStream->ui32DefaultMode;
1413 }
1414
1415 void DBGDrivSetMarker(struct DBG_STREAM *psStream, u32 ui32Marker)
1416 {
1417
1418         if (!StreamValid(psStream))
1419                 return;
1420
1421         psStream->ui32Marker = ui32Marker;
1422 }
1423
1424 u32 DBGDrivGetMarker(struct DBG_STREAM *psStream)
1425 {
1426
1427         if (!StreamValid(psStream))
1428                 return 0;
1429
1430         return psStream->ui32Marker;
1431 }
1432
1433 u32 DBGDrivGetStreamOffset(struct DBG_STREAM *psMainStream)
1434 {
1435         struct DBG_STREAM *psStream;
1436
1437         if (!StreamValid(psMainStream))
1438                 return 0;
1439
1440         if (psMainStream->bInitPhaseComplete)
1441                 psStream = psMainStream;
1442         else
1443                 psStream = psMainStream->psInitStream;
1444
1445         return psStream->ui32DataWritten;
1446 }
1447
1448 void DBGDrivSetStreamOffset(struct DBG_STREAM *psMainStream,
1449                                              u32 ui32StreamOffset)
1450 {
1451         struct DBG_STREAM *psStream;
1452
1453         if (!StreamValid(psMainStream))
1454                 return;
1455
1456         if (psMainStream->bInitPhaseComplete)
1457                 psStream = psMainStream;
1458         else
1459                 psStream = psMainStream->psInitStream;
1460
1461         psStream->ui32DataWritten = ui32StreamOffset;
1462 }
1463
1464 u32 DBGDrivGetServiceTable(void)
1465 {
1466         return (u32)&g_sDBGKMServices;
1467 }
1468
1469 u32 DBGDrivWriteLF(struct DBG_STREAM *psStream,
1470                                        u8 *pui8InBuf,
1471                                        u32 ui32InBuffSize,
1472                                        u32 ui32Level,
1473                                        u32 ui32Flags)
1474 {
1475         struct DBG_LASTFRAME_BUFFER *psLFBuffer;
1476
1477         if (!StreamValid(psStream))
1478                 return 0xFFFFFFFF;
1479
1480         if (!(psStream->ui32DebugLevel & ui32Level))
1481                 return 0xFFFFFFFF;
1482
1483         if (psStream->ui32CapMode & DEBUG_CAPMODE_FRAMED) {
1484                 if (!(psStream->ui32Flags & DEBUG_FLAGS_ENABLESAMPLE))
1485                         return 0xFFFFFFFF;
1486         } else if (psStream->ui32CapMode == DEBUG_CAPMODE_HOTKEY) {
1487                 if ((psStream->ui32Current != g_ui32HotKeyFrame)
1488                     || (g_bHotKeyPressed == IMG_FALSE))
1489                         return 0xFFFFFFFF;
1490         }
1491
1492         psLFBuffer = FindLFBuf(psStream);
1493
1494         if (ui32Flags & WRITELF_FLAGS_RESETBUF) {
1495
1496                 ui32InBuffSize =
1497                     (ui32InBuffSize >
1498                      LAST_FRAME_BUF_SIZE) ? LAST_FRAME_BUF_SIZE :
1499                     ui32InBuffSize;
1500                 HostMemCopy((void *) psLFBuffer->ui8Buffer,
1501                             (void *) pui8InBuf, ui32InBuffSize);
1502                 psLFBuffer->ui32BufLen = ui32InBuffSize;
1503         } else {
1504
1505                 ui32InBuffSize =
1506                     ((psLFBuffer->ui32BufLen + ui32InBuffSize) >
1507                      LAST_FRAME_BUF_SIZE) ? (LAST_FRAME_BUF_SIZE -
1508                                              psLFBuffer->
1509                                              ui32BufLen) : ui32InBuffSize;
1510                 HostMemCopy((void *) (&psLFBuffer->
1511                                           ui8Buffer[psLFBuffer->ui32BufLen]),
1512                             (void *) pui8InBuf, ui32InBuffSize);
1513                 psLFBuffer->ui32BufLen += ui32InBuffSize;
1514         }
1515
1516         return ui32InBuffSize;
1517 }
1518
1519 u32 DBGDrivReadLF(struct DBG_STREAM *psStream,
1520                                       u32 ui32OutBuffSize,
1521                                       u8 *pui8OutBuf)
1522 {
1523         struct DBG_LASTFRAME_BUFFER *psLFBuffer;
1524         u32 ui32Data;
1525
1526         if (!StreamValid(psStream))
1527                 return 0;
1528
1529         psLFBuffer = FindLFBuf(psStream);
1530
1531         ui32Data =
1532             (ui32OutBuffSize <
1533              psLFBuffer->ui32BufLen) ? ui32OutBuffSize : psLFBuffer->ui32BufLen;
1534
1535         HostMemCopy((void *) pui8OutBuf, (void *) psLFBuffer->ui8Buffer,
1536                     ui32Data);
1537
1538         return ui32Data;
1539 }
1540
1541 void DBGDrivStartInitPhase(struct DBG_STREAM *psStream)
1542 {
1543         psStream->bInitPhaseComplete = IMG_FALSE;
1544 }
1545
1546 void DBGDrivStopInitPhase(struct DBG_STREAM *psStream)
1547 {
1548         psStream->bInitPhaseComplete = IMG_TRUE;
1549 }
1550
1551 #if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
1552 void DBGDrivWaitForEvent(enum DBG_EVENT eEvent)
1553 {
1554         HostWaitForEvent(eEvent);
1555 }
1556 #endif
1557
1558 static IMG_BOOL ExpandStreamBuffer(struct DBG_STREAM *psStream, u32 ui32NewSize)
1559 {
1560         void *pvNewBuf;
1561         u32 ui32NewSizeInPages;
1562         u32 ui32NewWOffset;
1563         u32 ui32SpaceInOldBuf;
1564
1565         if (psStream->ui32Size >= ui32NewSize)
1566                 return IMG_FALSE;
1567
1568         ui32SpaceInOldBuf = SpaceInStream(psStream);
1569
1570         ui32NewSizeInPages = ((ui32NewSize + 0xfff) & ~0xfff) / 4096;
1571
1572         if ((psStream->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
1573                 pvNewBuf = HostNonPageablePageAlloc(ui32NewSizeInPages);
1574         else
1575                 pvNewBuf = HostPageablePageAlloc(ui32NewSizeInPages);
1576
1577         if (pvNewBuf == NULL)
1578                 return IMG_FALSE;
1579
1580         if (psStream->ui32RPtr <= psStream->ui32WPtr) {
1581
1582                 HostMemCopy((void *) pvNewBuf,
1583                             (void *) (psStream->ui32Base +
1584                                           psStream->ui32RPtr),
1585                             psStream->ui32WPtr - psStream->ui32RPtr);
1586         } else {
1587                 u32 ui32FirstCopySize;
1588
1589                 ui32FirstCopySize = psStream->ui32Size - psStream->ui32RPtr;
1590
1591                 HostMemCopy((void *) pvNewBuf,
1592                             (void *) (psStream->ui32Base +
1593                                           psStream->ui32RPtr),
1594                             ui32FirstCopySize);
1595
1596                 HostMemCopy((void *) ((u32) pvNewBuf +
1597                                           ui32FirstCopySize),
1598                             (void *) psStream->ui32Base,
1599                             psStream->ui32WPtr);
1600         }
1601
1602         ui32NewWOffset = psStream->ui32Size - ui32SpaceInOldBuf;
1603
1604         if ((psStream->ui32Flags & DEBUG_FLAGS_USE_NONPAGED_MEM) != 0)
1605                 HostNonPageablePageFree((void *) psStream->ui32Base);
1606         else
1607                 HostPageablePageFree((void *) psStream->ui32Base);
1608
1609         psStream->ui32Base = (u32) pvNewBuf;
1610         psStream->ui32RPtr = 0;
1611         psStream->ui32WPtr = ui32NewWOffset;
1612         psStream->ui32Size = ui32NewSizeInPages * 4096;
1613
1614         return IMG_TRUE;
1615 }
1616
1617 static u32 SpaceInStream(struct DBG_STREAM *psStream)
1618 {
1619         u32 ui32Space;
1620
1621         if (psStream->ui32RPtr > psStream->ui32WPtr)
1622                 ui32Space = psStream->ui32RPtr - psStream->ui32WPtr;
1623         else
1624                 ui32Space =
1625                     psStream->ui32RPtr + (psStream->ui32Size -
1626                                           psStream->ui32WPtr);
1627
1628         return ui32Space;
1629 }
1630
1631 void DestroyAllStreams(void)
1632 {
1633         while (g_psStreamList != NULL)
1634                 DBGDrivDestroyStream(g_psStreamList);
1635         return;
1636 }
1637
1638 struct DBG_LASTFRAME_BUFFER *FindLFBuf(struct DBG_STREAM *psStream)
1639 {
1640         struct DBG_LASTFRAME_BUFFER *psLFBuffer;
1641
1642         psLFBuffer = g_psLFBufferList;
1643
1644         while (psLFBuffer) {
1645                 if (psLFBuffer->psStream == psStream)
1646                         break;
1647
1648                 psLFBuffer = psLFBuffer->psNext;
1649         }
1650
1651         return psLFBuffer;
1652 }