ENGR00156850 gpu-viv: add gpu-viv driver source
[wandboard.git] / drivers / mxc / gpu-viv / hal / kernel / gc_hal_kernel_debug.c
blob0836e0d62f89d00d9ce10835f3dec97a5226683e
1 /****************************************************************************
3 * Copyright (C) 2005 - 2011 by Vivante Corp.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the license, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *****************************************************************************/
24 #include "gc_hal_kernel_precomp.h"
25 #include <gc_hal_kernel_debug.h>
27 /******************************************************************************\
28 ******************************** Debug Variables *******************************
29 \******************************************************************************/
31 static gceSTATUS _lastError = gcvSTATUS_OK;
32 static gctUINT32 _debugLevel = gcvLEVEL_ERROR;
33 static gctUINT32 _debugZones = gcvZONE_ALL;
35 /******************************************************************************\
36 ********************************* Debug Switches *******************************
37 \******************************************************************************/
40 gcdBUFFERED_OUTPUT
42 When set to non-zero, all output is collected into a buffer with the
43 specified size. Once the buffer gets full, the debug buffer will be
44 printed to the console. gcdBUFFERED_SIZE determines the size of the buffer.
46 #define gcdBUFFERED_OUTPUT 0
49 gcdBUFFERED_SIZE
51 When set to non-zero, all output is collected into a buffer with the
52 specified size. Once the buffer gets full, the debug buffer will be
53 printed to the console.
55 #define gcdBUFFERED_SIZE (1024 * 1024 * 2)
58 gcdDMA_BUFFER_COUNT
60 If greater then zero, the debugger will attempt to find the command buffer
61 where DMA is currently executing and then print this buffer and
62 (gcdDMA_BUFFER_COUNT - 1) buffers before the current one. If set to zero
63 or the current buffer is not found, all buffers are printed.
65 #define gcdDMA_BUFFER_COUNT 0
68 gcdTHREAD_BUFFERS
70 When greater then one, will accumulate messages from the specified number
71 of threads in separate output buffers.
73 #define gcdTHREAD_BUFFERS 1
76 gcdENABLE_OVERFLOW
78 When set to non-zero, and the output buffer gets full, instead of being
79 printed, it will be allowed to overflow removing the oldest messages.
81 #define gcdENABLE_OVERFLOW 1
84 gcdSHOW_LINE_NUMBER
86 When enabledm each print statement will be preceeded with the current
87 line number.
89 #define gcdSHOW_LINE_NUMBER 0
92 gcdSHOW_PROCESS_ID
94 When enabledm each print statement will be preceeded with the current
95 process ID.
97 #define gcdSHOW_PROCESS_ID 0
100 gcdSHOW_THREAD_ID
102 When enabledm each print statement will be preceeded with the current
103 thread ID.
105 #define gcdSHOW_THREAD_ID 0
108 gcdSHOW_TIME
110 When enabled each print statement will be preceeded with the current
111 high-resolution time.
113 #define gcdSHOW_TIME 0
116 /******************************************************************************\
117 ****************************** Miscellaneous Macros ****************************
118 \******************************************************************************/
120 #if gcmIS_DEBUG(gcdDEBUG_TRACE)
121 # define gcmDBGASSERT(Expression, Format, Value) \
122 if (!(Expression)) \
124 _DirectPrint( \
125 "*** gcmDBGASSERT ***************************\n" \
126 " function : %s\n" \
127 " line : %d\n" \
128 " expression : " #Expression "\n" \
129 " actual value : " Format "\n", \
130 __FUNCTION__, __LINE__, Value \
131 ); \
133 #else
134 # define gcmDBGASSERT(Expression, Format, Value)
135 #endif
137 #define gcmPTRALIGNMENT(Pointer, Alignemnt) \
139 gcmALIGN(gcmPTR2INT(Pointer), Alignemnt) - gcmPTR2INT(Pointer) \
142 #if gcdALIGNBYSIZE
143 # define gcmISALIGNED(Offset, Alignment) \
144 (((Offset) & ((Alignment) - 1)) == 0)
146 # define gcmkALIGNPTR(Type, Pointer, Alignment) \
147 Pointer = (Type) gcmINT2PTR(gcmALIGN(gcmPTR2INT(Pointer), Alignment))
148 #else
149 # define gcmISALIGNED(Offset, Alignment) \
150 gcvTRUE
152 # define gcmkALIGNPTR(Type, Pointer, Alignment)
153 #endif
155 #define gcmALIGNSIZE(Offset, Size) \
156 ((Size - Offset) + Size)
158 #define gcdHAVEPREFIX \
160 gcdSHOW_TIME \
161 || gcdSHOW_LINE_NUMBER \
162 || gcdSHOW_PROCESS_ID \
163 || gcdSHOW_THREAD_ID \
166 #if gcdHAVEPREFIX
168 # define gcdOFFSET 0
170 #if gcdSHOW_TIME
171 #if gcmISALIGNED(gcdOFFSET, 8)
172 # define gcdTIMESIZE gcmSIZEOF(gctUINT64)
173 # elif gcdOFFSET == 4
174 # define gcdTIMESIZE gcmALIGNSIZE(4, gcmSIZEOF(gctUINT64))
175 # else
176 # error "Unexpected offset value."
177 # endif
178 # undef gcdOFFSET
179 # define gcdOFFSET 8
180 #if !defined(gcdPREFIX_LEADER)
181 # define gcdPREFIX_LEADER gcmSIZEOF(gctUINT64)
182 # define gcdTIMEFORMAT "0x%016llX"
183 # else
184 # define gcdTIMEFORMAT ", 0x%016llX"
185 # endif
186 # else
187 # define gcdTIMESIZE 0
188 # define gcdTIMEFORMAT
189 # endif
191 #if gcdSHOW_LINE_NUMBER
192 #if gcmISALIGNED(gcdOFFSET, 8)
193 # define gcdNUMSIZE gcmSIZEOF(gctUINT64)
194 # elif gcdOFFSET == 4
195 # define gcdNUMSIZE gcmALIGNSIZE(4, gcmSIZEOF(gctUINT64))
196 # else
197 # error "Unexpected offset value."
198 # endif
199 # undef gcdOFFSET
200 # define gcdOFFSET 8
201 #if !defined(gcdPREFIX_LEADER)
202 # define gcdPREFIX_LEADER gcmSIZEOF(gctUINT64)
203 # define gcdNUMFORMAT "%8llu"
204 # else
205 # define gcdNUMFORMAT ", %8llu"
206 # endif
207 # else
208 # define gcdNUMSIZE 0
209 # define gcdNUMFORMAT
210 # endif
212 #if gcdSHOW_PROCESS_ID
213 #if gcmISALIGNED(gcdOFFSET, 4)
214 # define gcdPIDSIZE gcmSIZEOF(gctUINT32)
215 # else
216 # error "Unexpected offset value."
217 # endif
218 # undef gcdOFFSET
219 # define gcdOFFSET 4
220 #if !defined(gcdPREFIX_LEADER)
221 # define gcdPREFIX_LEADER gcmSIZEOF(gctUINT32)
222 # define gcdPIDFORMAT "pid=0x%04X"
223 # else
224 # define gcdPIDFORMAT ", pid=0x%04X"
225 # endif
226 # else
227 # define gcdPIDSIZE 0
228 # define gcdPIDFORMAT
229 # endif
231 #if gcdSHOW_THREAD_ID
232 #if gcmISALIGNED(gcdOFFSET, 4)
233 # define gcdTIDSIZE gcmSIZEOF(gctUINT32)
234 # else
235 # error "Unexpected offset value."
236 # endif
237 # undef gcdOFFSET
238 # define gcdOFFSET 4
239 #if !defined(gcdPREFIX_LEADER)
240 # define gcdPREFIX_LEADER gcmSIZEOF(gctUINT32)
241 # define gcdTIDFORMAT "tid=0x%04X"
242 # else
243 # define gcdTIDFORMAT ", tid=0x%04X"
244 # endif
245 # else
246 # define gcdTIDSIZE 0
247 # define gcdTIDFORMAT
248 # endif
250 # define gcdPREFIX_SIZE \
252 gcdTIMESIZE \
253 + gcdNUMSIZE \
254 + gcdPIDSIZE \
255 + gcdTIDSIZE \
258 static const char * _prefixFormat =
260 gcdTIMEFORMAT
261 gcdNUMFORMAT
262 gcdPIDFORMAT
263 gcdTIDFORMAT
264 "] ";
266 #else
268 # define gcdPREFIX_LEADER gcmSIZEOF(gctUINT32)
269 # define gcdPREFIX_SIZE 0
271 #endif
273 /* Assumed largest variable argument leader size. */
274 #define gcdVARARG_LEADER gcmSIZEOF(gctUINT64)
276 /* Alignnments. */
277 #if gcdALIGNBYSIZE
278 # define gcdPREFIX_ALIGNMENT gcdPREFIX_LEADER
279 # define gcdVARARG_ALIGNMENT gcdVARARG_LEADER
280 #else
281 # define gcdPREFIX_ALIGNMENT 0
282 # define gcdVARARG_ALIGNMENT 0
283 #endif
285 #if gcdBUFFERED_OUTPUT
286 # define gcdOUTPUTPREFIX _AppendPrefix
287 # define gcdOUTPUTSTRING _AppendString
288 # define gcdOUTPUTCOPY _AppendCopy
289 # define gcdOUTPUTBUFFER _AppendBuffer
290 #else
291 # define gcdOUTPUTPREFIX _PrintPrefix
292 # define gcdOUTPUTSTRING _PrintString
293 # define gcdOUTPUTCOPY _PrintString
294 # define gcdOUTPUTBUFFER _PrintBuffer
295 #endif
297 /******************************************************************************\
298 ****************************** Private Structures ******************************
299 \******************************************************************************/
301 typedef enum _gceBUFITEM
303 gceBUFITEM_NONE,
304 gcvBUFITEM_PREFIX,
305 gcvBUFITEM_STRING,
306 gcvBUFITEM_COPY,
307 gcvBUFITEM_BUFFER
309 gceBUFITEM;
311 /* Common item head/buffer terminator. */
312 typedef struct _gcsBUFITEM_HEAD * gcsBUFITEM_HEAD_PTR;
313 typedef struct _gcsBUFITEM_HEAD
315 gceBUFITEM type;
317 gcsBUFITEM_HEAD;
319 /* String prefix (for ex. [ 1,tid=0x019A]) */
320 typedef struct _gcsBUFITEM_PREFIX * gcsBUFITEM_PREFIX_PTR;
321 typedef struct _gcsBUFITEM_PREFIX
323 gceBUFITEM type;
324 #if gcdHAVEPREFIX
325 gctPOINTER prefixData;
326 #endif
328 gcsBUFITEM_PREFIX;
330 /* Buffered string. */
331 typedef struct _gcsBUFITEM_STRING * gcsBUFITEM_STRING_PTR;
332 typedef struct _gcsBUFITEM_STRING
334 gceBUFITEM type;
335 gctINT indent;
336 gctCONST_STRING message;
337 gctPOINTER messageData;
338 gctUINT messageDataSize;
340 gcsBUFITEM_STRING;
342 /* Buffered string (copy of the string is included with the record). */
343 typedef struct _gcsBUFITEM_COPY * gcsBUFITEM_COPY_PTR;
344 typedef struct _gcsBUFITEM_COPY
346 gceBUFITEM type;
347 gctINT indent;
348 gctPOINTER messageData;
349 gctUINT messageDataSize;
351 gcsBUFITEM_COPY;
353 /* Memory buffer. */
354 typedef struct _gcsBUFITEM_BUFFER * gcsBUFITEM_BUFFER_PTR;
355 typedef struct _gcsBUFITEM_BUFFER
357 gceBUFITEM type;
358 gctINT indent;
359 gceDUMP_BUFFER bufferType;
361 #if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
362 gctUINT32 dmaAddress;
363 #endif
365 gctUINT dataSize;
366 gctUINT32 address;
367 #if gcdHAVEPREFIX
368 gctPOINTER prefixData;
369 #endif
371 gcsBUFITEM_BUFFER;
373 typedef struct _gcsBUFFERED_OUTPUT * gcsBUFFERED_OUTPUT_PTR;
374 typedef struct _gcsBUFFERED_OUTPUT
376 #if gcdTHREAD_BUFFERS > 1
377 gctUINT32 threadID;
378 #endif
380 #if gcdSHOW_LINE_NUMBER
381 gctUINT64 lineNumber;
382 #endif
384 gctINT indent;
386 #if gcdBUFFERED_OUTPUT
387 gctINT start;
388 gctINT index;
389 gctINT count;
390 gctUINT8 buffer[gcdBUFFERED_SIZE];
391 #endif
393 gcsBUFFERED_OUTPUT_PTR prev;
394 gcsBUFFERED_OUTPUT_PTR next;
396 gcsBUFFERED_OUTPUT;
398 typedef gctUINT (* gcfPRINTSTRING) (
399 IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
400 IN gcsBUFITEM_HEAD_PTR Item
403 typedef gctINT (* gcfGETITEMSIZE) (
404 IN gcsBUFITEM_HEAD_PTR Item
407 /******************************************************************************\
408 ******************************* Private Variables ******************************
409 \******************************************************************************/
411 static gcsBUFFERED_OUTPUT _outputBuffer[gcdTHREAD_BUFFERS];
412 static gcsBUFFERED_OUTPUT_PTR _outputBufferHead = gcvNULL;
413 static gcsBUFFERED_OUTPUT_PTR _outputBufferTail = gcvNULL;
415 /******************************************************************************\
416 ****************************** Item Size Functions *****************************
417 \******************************************************************************/
419 #if gcdBUFFERED_OUTPUT
420 static gctINT
421 _GetTerminatorItemSize(
422 IN gcsBUFITEM_HEAD_PTR Item
425 return gcmSIZEOF(gcsBUFITEM_HEAD);
428 static gctINT
429 _GetPrefixItemSize(
430 IN gcsBUFITEM_HEAD_PTR Item
433 #if gcdHAVEPREFIX
434 gcsBUFITEM_PREFIX_PTR item = (gcsBUFITEM_PREFIX_PTR) Item;
435 gctUINT vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
436 return vlen + gcdPREFIX_SIZE;
437 #else
438 return gcmSIZEOF(gcsBUFITEM_PREFIX);
439 #endif
442 static gctINT
443 _GetStringItemSize(
444 IN gcsBUFITEM_HEAD_PTR Item
447 gcsBUFITEM_STRING_PTR item = (gcsBUFITEM_STRING_PTR) Item;
448 gctUINT vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
449 return vlen + item->messageDataSize;
452 static gctINT
453 _GetCopyItemSize(
454 IN gcsBUFITEM_HEAD_PTR Item
457 gcsBUFITEM_COPY_PTR item = (gcsBUFITEM_COPY_PTR) Item;
458 gctUINT vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
459 return vlen + item->messageDataSize;
462 static gctINT
463 _GetBufferItemSize(
464 IN gcsBUFITEM_HEAD_PTR Item
467 #if gcdHAVEPREFIX
468 gcsBUFITEM_BUFFER_PTR item = (gcsBUFITEM_BUFFER_PTR) Item;
469 gctUINT vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
470 return vlen + gcdPREFIX_SIZE + item->dataSize;
471 #else
472 gcsBUFITEM_BUFFER_PTR item = (gcsBUFITEM_BUFFER_PTR) Item;
473 return gcmSIZEOF(gcsBUFITEM_BUFFER) + item->dataSize;
474 #endif
477 static gcfGETITEMSIZE _itemSize[] =
479 _GetTerminatorItemSize,
480 _GetPrefixItemSize,
481 _GetStringItemSize,
482 _GetCopyItemSize,
483 _GetBufferItemSize
485 #endif
487 /******************************************************************************\
488 ******************************* Printing Functions *****************************
489 \******************************************************************************/
491 #if gcdDEBUG || gcdBUFFERED_OUTPUT
492 static void
493 _DirectPrint(
494 gctCONST_STRING Message,
498 gctINT len;
499 char buffer[768];
500 gctARGUMENTS arguments;
502 gcmkARGUMENTS_START(arguments, Message);
503 len = gcmkVSPRINTF(buffer, gcmSIZEOF(buffer), Message, arguments);
504 gcmkARGUMENTS_END(arguments);
506 buffer[len] = '\0';
507 gcmkOUTPUT_STRING(buffer);
509 #endif
511 static int
512 _AppendIndent(
513 IN gctINT Indent,
514 IN char * Buffer,
515 IN int BufferSize
518 gctINT i;
520 gctINT len = 0;
521 gctINT indent = Indent % 40;
523 for (i = 0; i < indent; i += 1)
525 Buffer[len++] = ' ';
528 if (indent != Indent)
530 len += gcmkSPRINTF(
531 Buffer + len, BufferSize - len, " <%d> ", Indent
534 Buffer[len] = '\0';
537 return len;
540 #if gcdHAVEPREFIX
541 static void
542 _PrintPrefix(
543 IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
544 IN gctPOINTER Data
547 char buffer[768];
548 gctINT len;
550 /* Format the string. */
551 len = gcmkVSPRINTF(buffer, gcmSIZEOF(buffer), _prefixFormat, Data);
552 buffer[len] = '\0';
554 /* Print the string. */
555 gcmkOUTPUT_STRING(buffer);
557 #endif
559 static void
560 _PrintString(
561 IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
562 IN gctINT Indent,
563 IN gctCONST_STRING Message,
564 IN gctUINT ArgumentSize,
565 IN gctPOINTER Data
568 char buffer[768];
569 gctINT len;
571 /* Append the indent string. */
572 len = _AppendIndent(Indent, buffer, gcmSIZEOF(buffer));
574 /* Format the string. */
575 len += gcmkVSPRINTF(buffer + len, gcmSIZEOF(buffer) - len, Message, Data);
576 buffer[len] = '\0';
578 /* Add end-of-line if missing. */
579 if (buffer[len - 1] != '\n')
581 buffer[len++] = '\n';
582 buffer[len] = '\0';
585 /* Print the string. */
586 gcmkOUTPUT_STRING(buffer);
589 static void
590 _PrintBuffer(
591 IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
592 IN gctINT Indent,
593 IN gctPOINTER PrefixData,
594 IN gctPOINTER Data,
595 IN gctUINT Address,
596 IN gctUINT DataSize,
597 IN gceDUMP_BUFFER Type,
598 IN gctUINT32 DmaAddress
601 static gctCONST_STRING _titleString[] =
603 "CONTEXT BUFFER",
604 "USER COMMAND BUFFER",
605 "KERNEL COMMAND BUFFER",
606 "LINK BUFFER",
607 "WAIT LINK BUFFER",
611 static const gctINT COLUMN_COUNT = 8;
613 gctUINT i, count, column, address;
614 gctUINT32_PTR data;
615 gctCHAR buffer[768];
616 gctUINT indent, len;
617 gctBOOL command;
619 /* Append space for the prefix. */
620 #if gcdHAVEPREFIX
621 indent = gcmkVSPRINTF(buffer, gcmSIZEOF(buffer), _prefixFormat, PrefixData);
622 buffer[indent] = '\0';
623 #else
624 indent = 0;
625 #endif
627 /* Append the indent string. */
628 indent += _AppendIndent(
629 Indent, buffer + indent, gcmSIZEOF(buffer) - indent
632 switch (Type)
634 case gceDUMP_BUFFER_CONTEXT:
635 case gceDUMP_BUFFER_USER:
636 case gceDUMP_BUFFER_KERNEL:
637 case gceDUMP_BUFFER_LINK:
638 case gceDUMP_BUFFER_WAITLINK:
639 /* Form and print the title string. */
640 gcmkSPRINTF2(
641 buffer + indent, gcmSIZEOF(buffer) - indent,
642 "%s%s\n", _titleString[Type],
643 ((DmaAddress >= Address) && (DmaAddress < Address + DataSize))
644 ? " (CURRENT)" : ""
647 gcmkOUTPUT_STRING(buffer);
649 /* Terminate the string. */
650 buffer[indent] = '\0';
652 /* This is a command buffer. */
653 command = gcvTRUE;
654 break;
656 case gceDUMP_BUFFER_FROM_USER:
657 /* This is not a command buffer. */
658 command = gcvFALSE;
660 /* No title. */
661 break;
663 default:
664 gcmDBGASSERT(gcvFALSE, "%s", "invalid buffer type");
666 /* This is not a command buffer. */
667 command = gcvFALSE;
670 /* Overwrite the prefix with spaces. */
671 for (i = 0; i < indent; i += 1)
673 buffer[i] = ' ';
676 /* Form and print the opening string. */
677 if (command)
679 gcmkSPRINTF2(
680 buffer + indent, gcmSIZEOF(buffer) - indent,
681 "@[kernel.command %08X %08X\n", Address, DataSize
684 gcmkOUTPUT_STRING(buffer);
686 /* Terminate the string. */
687 buffer[indent] = '\0';
690 /* Get initial address. */
691 address = Address;
693 /* Cast the data pointer. */
694 data = (gctUINT32_PTR) Data;
696 /* Compute the number of double words. */
697 count = DataSize / gcmSIZEOF(gctUINT32);
699 /* Print the buffer. */
700 for (i = 0, len = indent, column = 0; i < count; i += 1)
702 /* Append the address. */
703 if (column == 0)
705 len += gcmkSPRINTF(
706 buffer + len, gcmSIZEOF(buffer) - len, "0x%08X:", address
710 /* Append the data value. */
711 len += gcmkSPRINTF2(
712 buffer + len, gcmSIZEOF(buffer) - len, "%c%08X",
713 (address == DmaAddress)? '>' : ' ', data[i]
716 buffer[len] = '\0';
718 /* Update the address. */
719 address += gcmSIZEOF(gctUINT32);
721 /* Advance column count. */
722 column += 1;
724 /* End of line? */
725 if ((column % COLUMN_COUNT) == 0)
727 /* Append EOL. */
728 gcmkSTRCAT(buffer + len, gcmSIZEOF(buffer) - len, "\n");
730 /* Print the string. */
731 gcmkOUTPUT_STRING(buffer);
733 /* Reset. */
734 len = indent;
735 column = 0;
739 /* Print the last partial string. */
740 if (column != 0)
742 /* Append EOL. */
743 gcmkSTRCAT(buffer + len, gcmSIZEOF(buffer) - len, "\n");
745 /* Print the string. */
746 gcmkOUTPUT_STRING(buffer);
749 /* Form and print the opening string. */
750 if (command)
752 buffer[indent] = '\0';
753 gcmkSTRCAT(buffer, gcmSIZEOF(buffer), "] -- command\n");
754 gcmkOUTPUT_STRING(buffer);
758 #if gcdBUFFERED_OUTPUT
759 static gctUINT
760 _PrintNone(
761 IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
762 IN gcsBUFITEM_HEAD_PTR Item
765 /* Return the size of the node. */
766 return gcmSIZEOF(gcsBUFITEM_HEAD);
769 static gctUINT
770 _PrintPrefixWrapper(
771 IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
772 IN gcsBUFITEM_HEAD_PTR Item
775 #if gcdHAVEPREFIX
776 gcsBUFITEM_PREFIX_PTR item;
777 gctUINT vlen;
779 /* Get access to the data. */
780 item = (gcsBUFITEM_PREFIX_PTR) Item;
782 /* Print the message. */
783 _PrintPrefix(OutputBuffer, item->prefixData);
785 /* Compute the size of the variable portion of the structure. */
786 vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
788 /* Return the size of the node. */
789 return vlen + gcdPREFIX_SIZE;
790 #else
791 return gcmSIZEOF(gcsBUFITEM_PREFIX);
792 #endif
795 static gctUINT
796 _PrintStringWrapper(
797 IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
798 IN gcsBUFITEM_HEAD_PTR Item
801 gcsBUFITEM_STRING_PTR item;
802 gctUINT vlen;
804 /* Get access to the data. */
805 item = (gcsBUFITEM_STRING_PTR) Item;
807 /* Print the message. */
808 _PrintString(
809 OutputBuffer,
810 item->indent, item->message, item->messageDataSize, item->messageData
813 /* Compute the size of the variable portion of the structure. */
814 vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
816 /* Return the size of the node. */
817 return vlen + item->messageDataSize;
820 static gctUINT
821 _PrintCopyWrapper(
822 IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
823 IN gcsBUFITEM_HEAD_PTR Item
826 gcsBUFITEM_COPY_PTR item;
827 gctCONST_STRING message;
828 gctUINT vlen;
830 /* Get access to the data. */
831 item = (gcsBUFITEM_COPY_PTR) Item;
833 /* Determine the string pointer. */
834 message = (gctCONST_STRING) (item + 1);
836 /* Print the message. */
837 _PrintString(
838 OutputBuffer,
839 item->indent, message, item->messageDataSize, item->messageData
842 /* Compute the size of the variable portion of the structure. */
843 vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
845 /* Return the size of the node. */
846 return vlen + item->messageDataSize;
849 static gctUINT
850 _PrintBufferWrapper(
851 IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
852 IN gcsBUFITEM_HEAD_PTR Item
855 #if gcdHAVEPREFIX
856 gctUINT32 dmaAddress;
857 gcsBUFITEM_BUFFER_PTR item;
858 gctPOINTER data;
859 gctUINT vlen;
861 /* Get access to the data. */
862 item = (gcsBUFITEM_BUFFER_PTR) Item;
864 #if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
865 dmaAddress = item->dmaAddress;
866 #else
867 dmaAddress = 0xFFFFFFFF;
868 #endif
870 if (dmaAddress != 0)
872 /* Compute the data address. */
873 data = ((gctUINT8_PTR) item->prefixData) + gcdPREFIX_SIZE;
875 /* Print buffer. */
876 _PrintBuffer(
877 OutputBuffer,
878 item->indent, item->prefixData,
879 data, item->address, item->dataSize,
880 item->bufferType, dmaAddress
884 /* Compute the size of the variable portion of the structure. */
885 vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
887 /* Return the size of the node. */
888 return vlen + gcdPREFIX_SIZE + item->dataSize;
889 #else
890 gctUINT32 dmaAddress;
891 gcsBUFITEM_BUFFER_PTR item;
893 /* Get access to the data. */
894 item = (gcsBUFITEM_BUFFER_PTR) Item;
896 #if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
897 dmaAddress = item->dmaAddress;
898 #else
899 dmaAddress = 0xFFFFFFFF;
900 #endif
902 if (dmaAddress != 0)
904 /* Print buffer. */
905 _PrintBuffer(
906 OutputBuffer,
907 item->indent, gcvNULL,
908 item + 1, item->address, item->dataSize,
909 item->bufferType, dmaAddress
913 /* Return the size of the node. */
914 return gcmSIZEOF(gcsBUFITEM_BUFFER) + item->dataSize;
915 #endif
918 static gcfPRINTSTRING _printArray[] =
920 _PrintNone,
921 _PrintPrefixWrapper,
922 _PrintStringWrapper,
923 _PrintCopyWrapper,
924 _PrintBufferWrapper
926 #endif
928 /******************************************************************************\
929 ******************************* Private Functions ******************************
930 \******************************************************************************/
932 #if gcdBUFFERED_OUTPUT
934 #if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
935 static gcsBUFITEM_BUFFER_PTR
936 _FindCurrentDMABuffer(
937 gctUINT32 DmaAddress
940 gctINT i, skip;
941 gcsBUFITEM_HEAD_PTR item;
942 gcsBUFITEM_BUFFER_PTR dmaCurrent;
944 /* Reset the current buffer. */
945 dmaCurrent = gcvNULL;
947 /* Get the first stored item. */
948 item = (gcsBUFITEM_HEAD_PTR) &_outputBufferHead->buffer[_outputBufferHead->start];
950 /* Run through all items. */
951 for (i = 0; i < _outputBufferHead->count; i += 1)
953 /* Buffer item? */
954 if (item->type == gcvBUFITEM_BUFFER)
956 gcsBUFITEM_BUFFER_PTR buffer = (gcsBUFITEM_BUFFER_PTR) item;
958 if ((DmaAddress >= buffer->address) &&
959 (DmaAddress < buffer->address + buffer->dataSize))
961 dmaCurrent = buffer;
965 /* Get the item size and skip it. */
966 skip = (* _itemSize[item->type]) (item);
967 item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
969 /* End of the buffer? Wrap around. */
970 if (item->type == gceBUFITEM_NONE)
972 item = (gcsBUFITEM_HEAD_PTR) _outputBufferHead->buffer;
976 /* Return result. */
977 return dmaCurrent;
980 static void
981 _EnableAllDMABuffers(
982 void
985 gctINT i, skip;
986 gcsBUFITEM_HEAD_PTR item;
988 /* Get the first stored item. */
989 item = (gcsBUFITEM_HEAD_PTR) &_outputBufferHead->buffer[_outputBufferHead->start];
991 /* Run through all items. */
992 for (i = 0; i < _outputBufferHead->count; i += 1)
994 /* Buffer item? */
995 if (item->type == gcvBUFITEM_BUFFER)
997 gcsBUFITEM_BUFFER_PTR buffer = (gcsBUFITEM_BUFFER_PTR) item;
999 /* Enable the buffer. */
1000 buffer->dmaAddress = ~0U;
1003 /* Get the item size and skip it. */
1004 skip = (* _itemSize[item->type]) (item);
1005 item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
1007 /* End of the buffer? Wrap around. */
1008 if (item->type == gceBUFITEM_NONE)
1010 item = (gcsBUFITEM_HEAD_PTR) _outputBufferHead->buffer;
1015 static void
1016 _EnableDMABuffers(
1017 gctUINT32 DmaAddress,
1018 gcsBUFITEM_BUFFER_PTR CurrentDMABuffer
1021 gctINT i, skip, index;
1022 gcsBUFITEM_HEAD_PTR item;
1023 gcsBUFITEM_BUFFER_PTR buffers[gcdDMA_BUFFER_COUNT];
1025 /* Reset buffer pointers. */
1026 gckOS_ZeroMemory(buffers, gcmSIZEOF(buffers));
1028 /* Set the current buffer index. */
1029 index = -1;
1031 /* Get the first stored item. */
1032 item = (gcsBUFITEM_HEAD_PTR) &_outputBufferHead->buffer[_outputBufferHead->start];
1034 /* Run through all items until the current DMA buffer is found. */
1035 for (i = 0; i < _outputBufferHead->count; i += 1)
1037 /* Buffer item? */
1038 if (item->type == gcvBUFITEM_BUFFER)
1040 /* Advance the index. */
1041 index = (index + 1) % gcdDMA_BUFFER_COUNT;
1043 /* Add to the buffer array. */
1044 buffers[index] = (gcsBUFITEM_BUFFER_PTR) item;
1046 /* Stop if this is the current DMA buffer. */
1047 if ((gcsBUFITEM_BUFFER_PTR) item == CurrentDMABuffer)
1049 break;
1053 /* Get the item size and skip it. */
1054 skip = (* _itemSize[item->type]) (item);
1055 item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
1057 /* End of the buffer? Wrap around. */
1058 if (item->type == gceBUFITEM_NONE)
1060 item = (gcsBUFITEM_HEAD_PTR) _outputBufferHead->buffer;
1064 /* Enable the found buffers. */
1065 gcmDBGASSERT(index != -1, "%d", index);
1067 for (i = 0; i < gcdDMA_BUFFER_COUNT; i += 1)
1069 if (buffers[index] == gcvNULL)
1071 break;
1074 buffers[index]->dmaAddress = DmaAddress;
1076 index -= 1;
1078 if (index == -1)
1080 index = gcdDMA_BUFFER_COUNT - 1;
1084 #endif
1086 static void
1087 _Flush(
1088 gctUINT32 DmaAddress
1091 gctINT i, skip;
1092 gcsBUFITEM_HEAD_PTR item;
1094 gcsBUFFERED_OUTPUT_PTR outputBuffer = _outputBufferHead;
1096 #if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
1097 if ((outputBuffer != gcvNULL) && (outputBuffer->count != 0))
1099 /* Find the current DMA buffer. */
1100 gcsBUFITEM_BUFFER_PTR dmaCurrent = _FindCurrentDMABuffer(DmaAddress);
1102 /* Was the current buffer found? */
1103 if (dmaCurrent == gcvNULL)
1105 /* No, print all buffers. */
1106 _EnableAllDMABuffers();
1108 else
1110 /* Yes, enable only specified number of buffers. */
1111 _EnableDMABuffers(DmaAddress, dmaCurrent);
1114 #endif
1116 while (outputBuffer != gcvNULL)
1118 if (outputBuffer->count != 0)
1120 _DirectPrint("********************************************************************************\n");
1121 _DirectPrint("FLUSHING DEBUG OUTPUT BUFFER (%d elements).\n", outputBuffer->count);
1122 _DirectPrint("********************************************************************************\n");
1124 item = (gcsBUFITEM_HEAD_PTR) &outputBuffer->buffer[outputBuffer->start];
1126 for (i = 0; i < outputBuffer->count; i += 1)
1128 skip = (* _printArray[item->type]) (outputBuffer, item);
1130 item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
1132 if (item->type == gceBUFITEM_NONE)
1134 item = (gcsBUFITEM_HEAD_PTR) outputBuffer->buffer;
1138 outputBuffer->start = 0;
1139 outputBuffer->index = 0;
1140 outputBuffer->count = 0;
1143 outputBuffer = outputBuffer->next;
1147 static gcsBUFITEM_HEAD_PTR
1148 _AllocateItem(
1149 IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
1150 IN gctINT Size
1153 gctINT skip;
1154 gcsBUFITEM_HEAD_PTR item, next;
1156 #if gcdENABLE_OVERFLOW
1157 if (
1158 (OutputBuffer->index + Size >= gcdBUFFERED_SIZE - gcmSIZEOF(gcsBUFITEM_HEAD))
1161 (OutputBuffer->index < OutputBuffer->start) &&
1162 (OutputBuffer->index + Size >= OutputBuffer->start)
1166 if (OutputBuffer->index + Size >= gcdBUFFERED_SIZE - gcmSIZEOF(gcsBUFITEM_HEAD))
1168 if (OutputBuffer->index < OutputBuffer->start)
1170 item = (gcsBUFITEM_HEAD_PTR) &OutputBuffer->buffer[OutputBuffer->start];
1172 while (item->type != gceBUFITEM_NONE)
1174 skip = (* _itemSize[item->type]) (item);
1176 OutputBuffer->start += skip;
1177 OutputBuffer->count -= 1;
1179 item->type = gceBUFITEM_NONE;
1180 item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
1183 OutputBuffer->start = 0;
1186 OutputBuffer->index = 0;
1189 item = (gcsBUFITEM_HEAD_PTR) &OutputBuffer->buffer[OutputBuffer->start];
1191 while (OutputBuffer->start - OutputBuffer->index <= Size)
1193 skip = (* _itemSize[item->type]) (item);
1195 OutputBuffer->start += skip;
1196 OutputBuffer->count -= 1;
1198 item->type = gceBUFITEM_NONE;
1199 item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
1201 if (item->type == gceBUFITEM_NONE)
1203 OutputBuffer->start = 0;
1204 break;
1208 #else
1209 if (OutputBuffer->index + Size > gcdBUFFERED_SIZE - gcmSIZEOF(gcsBUFITEM_HEAD))
1211 _DirectPrint("\nMessage buffer full; forcing message flush.\n\n");
1212 _Flush(~0U);
1214 #endif
1216 item = (gcsBUFITEM_HEAD_PTR) &OutputBuffer->buffer[OutputBuffer->index];
1218 OutputBuffer->index += Size;
1219 OutputBuffer->count += 1;
1221 next = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + Size);
1222 next->type = gceBUFITEM_NONE;
1224 return item;
1227 #if gcdALIGNBYSIZE
1228 static void
1229 _FreeExtraSpace(
1230 IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
1231 IN gctPOINTER Item,
1232 IN gctINT ItemSize,
1233 IN gctINT FreeSize
1236 gcsBUFITEM_HEAD_PTR next;
1238 OutputBuffer->index -= FreeSize;
1240 next = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) Item + ItemSize);
1241 next->type = gceBUFITEM_NONE;
1243 #endif
1245 #if gcdHAVEPREFIX
1246 static void
1247 _AppendPrefix(
1248 IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
1249 IN gctPOINTER Data
1252 gctUINT8_PTR prefixData;
1253 gcsBUFITEM_PREFIX_PTR item;
1254 gctINT allocSize;
1256 #if gcdALIGNBYSIZE
1257 gctUINT alignment;
1258 gctINT size, freeSize;
1259 #endif
1261 gcmDBGASSERT(Data != gcvNULL, "%p", Data);
1263 /* Determine the maximum item size. */
1264 allocSize
1265 = gcmSIZEOF(gcsBUFITEM_PREFIX)
1266 + gcdPREFIX_SIZE
1267 + gcdPREFIX_ALIGNMENT;
1269 /* Allocate prefix item. */
1270 item = (gcsBUFITEM_PREFIX_PTR) _AllocateItem(OutputBuffer, allocSize);
1272 /* Compute the initial prefix data pointer. */
1273 prefixData = (gctUINT8_PTR) (item + 1);
1275 /* Align the data pointer as necessary. */
1276 #if gcdALIGNBYSIZE
1277 alignment = gcmPTRALIGNMENT(prefixData, gcdPREFIX_ALIGNMENT);
1278 prefixData += alignment;
1279 #endif
1281 /* Set item data. */
1282 item->type = gcvBUFITEM_PREFIX;
1283 item->prefixData = prefixData;
1285 /* Copy argument value. */
1286 memcpy(prefixData, Data, gcdPREFIX_SIZE);
1288 #if gcdALIGNBYSIZE
1289 /* Compute the actual node size. */
1290 size = gcmSIZEOF(gcsBUFITEM_PREFIX) + gcdPREFIX_SIZE + alignment;
1292 /* Free extra memory if any. */
1293 freeSize = allocSize - size;
1294 if (freeSize != 0)
1296 _FreeExtraSpace(OutputBuffer, item, size, freeSize);
1298 #endif
1300 #endif
1302 static void
1303 _AppendString(
1304 IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
1305 IN gctINT Indent,
1306 IN gctCONST_STRING Message,
1307 IN gctUINT ArgumentSize,
1308 IN gctPOINTER Data
1311 gctUINT8_PTR messageData;
1312 gcsBUFITEM_STRING_PTR item;
1313 gctINT allocSize;
1315 #if gcdALIGNBYSIZE
1316 gctUINT alignment;
1317 gctINT size, freeSize;
1318 #endif
1320 /* Determine the maximum item size. */
1321 allocSize
1322 = gcmSIZEOF(gcsBUFITEM_STRING)
1323 + ArgumentSize
1324 + gcdVARARG_ALIGNMENT;
1326 /* Allocate prefix item. */
1327 item = (gcsBUFITEM_STRING_PTR) _AllocateItem(OutputBuffer, allocSize);
1329 /* Compute the initial message data pointer. */
1330 messageData = (gctUINT8_PTR) (item + 1);
1332 /* Align the data pointer as necessary. */
1333 #if gcdALIGNBYSIZE
1334 alignment = gcmPTRALIGNMENT(messageData, gcdVARARG_ALIGNMENT);
1335 messageData += alignment;
1336 #endif
1338 /* Set item data. */
1339 item->type = gcvBUFITEM_STRING;
1340 item->indent = Indent;
1341 item->message = Message;
1342 item->messageData = messageData;
1343 item->messageDataSize = ArgumentSize;
1345 /* Copy argument value. */
1346 if (ArgumentSize != 0)
1348 memcpy(messageData, Data, ArgumentSize);
1351 #if gcdALIGNBYSIZE
1352 /* Compute the actual node size. */
1353 size = gcmSIZEOF(gcsBUFITEM_STRING) + ArgumentSize + alignment;
1355 /* Free extra memory if any. */
1356 freeSize = allocSize - size;
1357 if (freeSize != 0)
1359 _FreeExtraSpace(OutputBuffer, item, size, freeSize);
1361 #endif
1364 static void
1365 _AppendCopy(
1366 IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
1367 IN gctINT Indent,
1368 IN gctCONST_STRING Message,
1369 IN gctUINT ArgumentSize,
1370 IN gctPOINTER Data
1373 gctUINT8_PTR messageData;
1374 gcsBUFITEM_COPY_PTR item;
1375 gctINT allocSize;
1376 gctINT messageLength;
1377 gctCONST_STRING message;
1379 #if gcdALIGNBYSIZE
1380 gctUINT alignment;
1381 gctINT size, freeSize;
1382 #endif
1384 /* Get the length of the string. */
1385 messageLength = strlen(Message) + 1;
1387 /* Determine the maximum item size. */
1388 allocSize
1389 = gcmSIZEOF(gcsBUFITEM_COPY)
1390 + messageLength
1391 + ArgumentSize
1392 + gcdVARARG_ALIGNMENT;
1394 /* Allocate prefix item. */
1395 item = (gcsBUFITEM_COPY_PTR) _AllocateItem(OutputBuffer, allocSize);
1397 /* Determine the message placement. */
1398 message = (gctCONST_STRING) (item + 1);
1400 /* Compute the initial message data pointer. */
1401 messageData = (gctUINT8_PTR) message + messageLength;
1403 /* Align the data pointer as necessary. */
1404 #if gcdALIGNBYSIZE
1405 if (ArgumentSize == 0)
1407 alignment = 0;
1409 else
1411 alignment = gcmPTRALIGNMENT(messageData, gcdVARARG_ALIGNMENT);
1412 messageData += alignment;
1414 #endif
1416 /* Set item data. */
1417 item->type = gcvBUFITEM_COPY;
1418 item->indent = Indent;
1419 item->messageData = messageData;
1420 item->messageDataSize = ArgumentSize;
1422 /* Copy the message. */
1423 memcpy((gctPOINTER) message, Message, messageLength);
1425 /* Copy argument value. */
1426 if (ArgumentSize != 0)
1428 memcpy(messageData, Data, ArgumentSize);
1431 #if gcdALIGNBYSIZE
1432 /* Compute the actual node size. */
1433 size
1434 = gcmSIZEOF(gcsBUFITEM_COPY)
1435 + messageLength
1436 + ArgumentSize
1437 + alignment;
1439 /* Free extra memory if any. */
1440 freeSize = allocSize - size;
1441 if (freeSize != 0)
1443 _FreeExtraSpace(OutputBuffer, item, size, freeSize);
1445 #endif
1448 static void
1449 _AppendBuffer(
1450 IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
1451 IN gctINT Indent,
1452 IN gctPOINTER PrefixData,
1453 IN gctPOINTER Data,
1454 IN gctUINT Address,
1455 IN gctUINT DataSize,
1456 IN gceDUMP_BUFFER Type,
1457 IN gctUINT32 DmaAddress
1460 #if gcdHAVEPREFIX
1461 gctUINT8_PTR prefixData;
1462 gcsBUFITEM_BUFFER_PTR item;
1463 gctINT allocSize;
1464 gctPOINTER data;
1466 #if gcdALIGNBYSIZE
1467 gctUINT alignment;
1468 gctINT size, freeSize;
1469 #endif
1471 gcmDBGASSERT(DataSize != 0, "%d", DataSize);
1472 gcmDBGASSERT(Data != gcvNULL, "%p", Data);
1474 /* Determine the maximum item size. */
1475 allocSize
1476 = gcmSIZEOF(gcsBUFITEM_BUFFER)
1477 + gcdPREFIX_SIZE
1478 + gcdPREFIX_ALIGNMENT
1479 + DataSize;
1481 /* Allocate prefix item. */
1482 item = (gcsBUFITEM_BUFFER_PTR) _AllocateItem(OutputBuffer, allocSize);
1484 /* Compute the initial prefix data pointer. */
1485 prefixData = (gctUINT8_PTR) (item + 1);
1487 #if gcdALIGNBYSIZE
1488 /* Align the data pointer as necessary. */
1489 alignment = gcmPTRALIGNMENT(prefixData, gcdPREFIX_ALIGNMENT);
1490 prefixData += alignment;
1491 #endif
1493 /* Set item data. */
1494 item->type = gcvBUFITEM_BUFFER;
1495 item->indent = Indent;
1496 item->bufferType = Type;
1497 item->dataSize = DataSize;
1498 item->address = Address;
1499 item->prefixData = prefixData;
1501 #if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
1502 item->dmaAddress = DmaAddress;
1503 #endif
1505 /* Copy prefix data. */
1506 memcpy(prefixData, PrefixData, gcdPREFIX_SIZE);
1508 /* Compute the data pointer. */
1509 data = prefixData + gcdPREFIX_SIZE;
1511 /* Copy argument value. */
1512 memcpy(data, Data, DataSize);
1514 #if gcdALIGNBYSIZE
1515 /* Compute the actual node size. */
1516 size
1517 = gcmSIZEOF(gcsBUFITEM_BUFFER)
1518 + gcdPREFIX_SIZE
1519 + alignment
1520 + DataSize;
1522 /* Free extra memory if any. */
1523 freeSize = allocSize - size;
1524 if (freeSize != 0)
1526 _FreeExtraSpace(OutputBuffer, item, size, freeSize);
1528 #endif
1529 #else
1530 gcsBUFITEM_BUFFER_PTR item;
1531 gctINT size;
1533 gcmDBGASSERT(DataSize != 0, "%d", DataSize);
1534 gcmDBGASSERT(Data != gcvNULL, "%p", Data);
1536 /* Determine the maximum item size. */
1537 size = gcmSIZEOF(gcsBUFITEM_BUFFER) + DataSize;
1539 /* Allocate prefix item. */
1540 item = (gcsBUFITEM_BUFFER_PTR) _AllocateItem(OutputBuffer, size);
1542 /* Set item data. */
1543 item->type = gcvBUFITEM_BUFFER;
1544 item->indent = Indent;
1545 item->dataSize = DataSize;
1546 item->address = Address;
1548 /* Copy argument value. */
1549 memcpy(item + 1, Data, DataSize);
1550 #endif
1552 #endif
1554 static gcmINLINE void
1555 _InitBuffers(
1556 void
1559 int i;
1561 if (_outputBufferHead == gcvNULL)
1563 for (i = 0; i < gcdTHREAD_BUFFERS; i += 1)
1565 if (_outputBufferTail == gcvNULL)
1567 _outputBufferHead = &_outputBuffer[i];
1569 else
1571 _outputBufferTail->next = &_outputBuffer[i];
1574 #if gcdTHREAD_BUFFERS > 1
1575 _outputBuffer[i].threadID = ~0U;
1576 #endif
1578 _outputBuffer[i].prev = _outputBufferTail;
1579 _outputBuffer[i].next = gcvNULL;
1581 _outputBufferTail = &_outputBuffer[i];
1586 static gcmINLINE gcsBUFFERED_OUTPUT_PTR
1587 _GetOutputBuffer(
1588 void
1591 gcsBUFFERED_OUTPUT_PTR outputBuffer;
1593 #if gcdTHREAD_BUFFERS > 1
1594 /* Get the current thread ID. */
1595 gctUINT32 threadID = gcmkGETTHREADID();
1597 /* Locate the output buffer for the thread. */
1598 outputBuffer = _outputBufferHead;
1600 while (outputBuffer != gcvNULL)
1602 if (outputBuffer->threadID == ThreadID)
1604 break;
1607 outputBuffer = outputBuffer->next;
1610 /* No matching buffer found? */
1611 if (outputBuffer == gcvNULL)
1613 /* Get the tail for the buffer. */
1614 outputBuffer = _outputBufferTail;
1616 /* Move it to the head. */
1617 _outputBufferTail = _outputBufferTail->prev;
1618 _outputBufferTail->next = gcvNULL;
1620 outputBuffer->prev = gcvNULL;
1621 outputBuffer->next = _outputBufferHead;
1623 _outputBufferHead->prev = outputBuffer;
1624 _outputBufferHead = outputBuffer;
1626 /* Reset the buffer. */
1627 outputBuffer->threadID = ThreadID;
1628 outputBuffer->start = 0;
1629 outputBuffer->index = 0;
1630 outputBuffer->count = 0;
1631 outputBuffer->lineNumber = 0;
1633 #else
1634 outputBuffer = _outputBufferHead;
1635 #endif
1637 return outputBuffer;
1640 static gcmINLINE int _GetArgumentSize(
1641 IN gctCONST_STRING Message
1644 int i, count;
1646 gcmDBGASSERT(Message != gcvNULL, "%p", Message);
1648 for (i = 0, count = 0; Message[i]; i += 1)
1650 if (Message[i] == '%')
1652 count += 1;
1656 return count * gcmSIZEOF(gctUINT32);
1659 #if gcdHAVEPREFIX
1660 static void
1661 _InitPrefixData(
1662 IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
1663 IN gctPOINTER Data
1666 gctUINT8_PTR data = (gctUINT8_PTR) Data;
1668 #if gcdSHOW_TIME
1670 gctUINT64 time;
1671 gckOS_GetProfileTick(&time);
1672 gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT64));
1673 * ((gctUINT64_PTR) data) = time;
1674 data += gcmSIZEOF(gctUINT64);
1676 #endif
1678 #if gcdSHOW_LINE_NUMBER
1680 gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT64));
1681 * ((gctUINT64_PTR) data) = OutputBuffer->lineNumber;
1682 data += gcmSIZEOF(gctUINT64);
1684 #endif
1686 #if gcdSHOW_PROCESS_ID
1688 gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT32));
1689 * ((gctUINT32_PTR) data) = gcmkGETPROCESSID();
1690 data += gcmSIZEOF(gctUINT32);
1692 #endif
1694 #if gcdSHOW_THREAD_ID
1696 gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT32));
1697 * ((gctUINT32_PTR) data) = gcmkGETTHREADID();
1699 #endif
1701 #endif
1703 static void
1704 _Print(
1705 IN gctUINT ArgumentSize,
1706 IN gctBOOL CopyMessage,
1707 IN gctCONST_STRING Message,
1708 IN gctARGUMENTS Arguments
1711 gcsBUFFERED_OUTPUT_PTR outputBuffer;
1712 gcmkDECLARE_LOCK(lockHandle);
1714 gcmkLOCKSECTION(lockHandle);
1716 /* Initialize output buffer list. */
1717 _InitBuffers();
1719 /* Locate the proper output buffer. */
1720 outputBuffer = _GetOutputBuffer();
1722 /* Update the line number. */
1723 #if gcdSHOW_LINE_NUMBER
1724 outputBuffer->lineNumber += 1;
1725 #endif
1727 /* Print prefix. */
1728 #if gcdHAVEPREFIX
1730 gctUINT8_PTR alignedPrefixData;
1731 gctUINT8 prefixData[gcdPREFIX_SIZE + gcdPREFIX_ALIGNMENT];
1733 /* Compute aligned pointer. */
1734 alignedPrefixData = prefixData;
1735 gcmkALIGNPTR(gctUINT8_PTR, alignedPrefixData, gcdPREFIX_ALIGNMENT);
1737 /* Initialize the prefix data. */
1738 _InitPrefixData(outputBuffer, alignedPrefixData);
1740 /* Print the prefix. */
1741 gcdOUTPUTPREFIX(outputBuffer, alignedPrefixData);
1743 #endif
1745 /* Form the indent string. */
1746 if (strncmp(Message, "--", 2) == 0)
1748 outputBuffer->indent -= 2;
1751 /* Print the message. */
1752 if (CopyMessage)
1754 gcdOUTPUTCOPY(
1755 outputBuffer, outputBuffer->indent,
1756 Message, ArgumentSize, * (gctPOINTER *) &Arguments
1759 else
1761 gcdOUTPUTSTRING(
1762 outputBuffer, outputBuffer->indent,
1763 Message, ArgumentSize, * (gctPOINTER *) &Arguments
1767 /* Check increasing indent. */
1768 if (strncmp(Message, "++", 2) == 0)
1770 outputBuffer->indent += 2;
1773 gcmkUNLOCKSECTION(lockHandle);
1777 /******************************************************************************\
1778 ********************************* Debug Macros *********************************
1779 \******************************************************************************/
1781 #define gcmDEBUGPRINT(ArgumentSize, CopyMessage, Message) \
1783 gctARGUMENTS __arguments__; \
1784 gcmkARGUMENTS_START(__arguments__, Message); \
1785 _Print(ArgumentSize, CopyMessage, Message, __arguments__); \
1786 gcmkARGUMENTS_END(__arguments__); \
1790 /******************************************************************************\
1791 ********************************** Debug Code **********************************
1792 \******************************************************************************/
1794 /*******************************************************************************
1796 ** gckOS_Print
1798 ** Send a message to the debugger.
1800 ** INPUT:
1802 ** gctCONST_STRING Message
1803 ** Pointer to message.
1805 ** ...
1806 ** Optional arguments.
1808 ** OUTPUT:
1810 ** Nothing.
1813 void
1814 gckOS_Print(
1815 IN gctCONST_STRING Message,
1819 gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
1822 /*******************************************************************************
1824 ** gckOS_PrintN
1826 ** Send a message to the debugger.
1828 ** INPUT:
1830 ** gctUINT ArgumentSize
1831 ** The size of the optional arguments in bytes.
1833 ** gctCONST_STRING Message
1834 ** Pointer to message.
1836 ** ...
1837 ** Optional arguments.
1839 ** OUTPUT:
1841 ** Nothing.
1844 void
1845 gckOS_PrintN(
1846 IN gctUINT ArgumentSize,
1847 IN gctCONST_STRING Message,
1851 gcmDEBUGPRINT(ArgumentSize, gcvFALSE, Message);
1854 /*******************************************************************************
1856 ** gckOS_CopyPrint
1858 ** Send a message to the debugger. If in buffered output mode, the entire
1859 ** message will be copied into the buffer instead of using the pointer to
1860 ** the string.
1862 ** INPUT:
1864 ** gctCONST_STRING Message
1865 ** Pointer to message.
1867 ** ...
1868 ** Optional arguments.
1870 ** OUTPUT:
1872 ** Nothing.
1875 void
1876 gckOS_CopyPrint(
1877 IN gctCONST_STRING Message,
1881 gcmDEBUGPRINT(_GetArgumentSize(Message), gcvTRUE, Message);
1884 /*******************************************************************************
1886 ** gckOS_DumpBuffer
1888 ** Print the contents of the specified buffer.
1890 ** INPUT:
1892 ** gckOS Os
1893 ** Pointer to gckOS object.
1895 ** gctPOINTER Buffer
1896 ** Pointer to the buffer to print.
1898 ** gctUINT Size
1899 ** Size of the buffer.
1901 ** gceDUMP_BUFFER Type
1902 ** Buffer type.
1904 ** OUTPUT:
1906 ** Nothing.
1909 void
1910 gckOS_DumpBuffer(
1911 IN gckOS Os,
1912 IN gctPOINTER Buffer,
1913 IN gctUINT Size,
1914 IN gceDUMP_BUFFER Type,
1915 IN gctBOOL CopyMessage
1918 gctUINT32 address;
1919 gcsBUFFERED_OUTPUT_PTR outputBuffer;
1920 static gctBOOL userLocked;
1921 gctCHAR *buffer = (gctCHAR*)Buffer;
1923 gcmkDECLARE_LOCK(lockHandle);
1925 /* Request lock when not coming from user,
1926 or coming from user and not yet locked
1927 and message is starting with @[. */
1928 if (Type == gceDUMP_BUFFER_FROM_USER)
1930 if ((Size > 2)
1931 && (buffer[0] == '@')
1932 && (buffer[1] == '['))
1934 /* Beginning of a user dump. */
1935 gcmkLOCKSECTION(lockHandle);
1936 userLocked = gcvTRUE;
1938 /* Else, let it pass through. */
1940 else
1942 gcmkLOCKSECTION(lockHandle);
1943 userLocked = gcvFALSE;
1946 if (Buffer != gcvNULL)
1948 /* Initialize output buffer list. */
1949 _InitBuffers();
1951 /* Locate the proper output buffer. */
1952 outputBuffer = _GetOutputBuffer();
1954 /* Update the line number. */
1955 #if gcdSHOW_LINE_NUMBER
1956 outputBuffer->lineNumber += 1;
1957 #endif
1959 /* Get the physical address of the buffer. */
1960 if (Type != gceDUMP_BUFFER_FROM_USER)
1962 gcmkVERIFY_OK(gckOS_GetPhysicalAddress(Os, Buffer, &address));
1964 else
1966 address = 0;
1969 #if gcdHAVEPREFIX
1971 gctUINT8_PTR alignedPrefixData;
1972 gctUINT8 prefixData[gcdPREFIX_SIZE + gcdPREFIX_ALIGNMENT];
1974 /* Compute aligned pointer. */
1975 alignedPrefixData = prefixData;
1976 gcmkALIGNPTR(gctUINT8_PTR, alignedPrefixData, gcdPREFIX_ALIGNMENT);
1978 /* Initialize the prefix data. */
1979 _InitPrefixData(outputBuffer, alignedPrefixData);
1981 /* Print/schedule the buffer. */
1982 gcdOUTPUTBUFFER(
1983 outputBuffer, outputBuffer->indent,
1984 alignedPrefixData, Buffer, address, Size, Type, 0
1987 #else
1988 /* Print/schedule the buffer. */
1989 if (Type == gceDUMP_BUFFER_FROM_USER)
1991 gcdOUTPUTSTRING(
1992 outputBuffer, outputBuffer->indent,
1993 Buffer, 0, gcvNULL
1996 else
1998 gcdOUTPUTBUFFER(
1999 outputBuffer, outputBuffer->indent,
2000 gcvNULL, Buffer, address, Size, Type, 0
2003 #endif
2006 /* Unlock when not coming from user,
2007 or coming from user and not yet locked. */
2008 if (userLocked)
2010 if ((Size > 4)
2011 && (buffer[0] == ']')
2012 && (buffer[1] == ' ')
2013 && (buffer[2] == '-')
2014 && (buffer[3] == '-'))
2016 /* End of a user dump. */
2017 gcmkUNLOCKSECTION(lockHandle);
2018 userLocked = gcvFALSE;
2020 /* Else, let it pass through, don't unlock. */
2022 else
2024 gcmkUNLOCKSECTION(lockHandle);
2028 /*******************************************************************************
2030 ** gckOS_DebugTrace
2032 ** Send a leveled message to the debugger.
2034 ** INPUT:
2036 ** gctUINT32 Level
2037 ** Debug level of message.
2039 ** gctCONST_STRING Message
2040 ** Pointer to message.
2042 ** ...
2043 ** Optional arguments.
2045 ** OUTPUT:
2047 ** Nothing.
2050 void
2051 gckOS_DebugTrace(
2052 IN gctUINT32 Level,
2053 IN gctCONST_STRING Message,
2057 if (Level > _debugLevel)
2059 return;
2062 gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
2065 /*******************************************************************************
2067 ** gckOS_DebugTraceN
2069 ** Send a leveled message to the debugger.
2071 ** INPUT:
2073 ** gctUINT32 Level
2074 ** Debug level of message.
2076 ** gctUINT ArgumentSize
2077 ** The size of the optional arguments in bytes.
2079 ** gctCONST_STRING Message
2080 ** Pointer to message.
2082 ** ...
2083 ** Optional arguments.
2085 ** OUTPUT:
2087 ** Nothing.
2090 void
2091 gckOS_DebugTraceN(
2092 IN gctUINT32 Level,
2093 IN gctUINT ArgumentSize,
2094 IN gctCONST_STRING Message,
2098 if (Level > _debugLevel)
2100 return;
2103 gcmDEBUGPRINT(ArgumentSize, gcvFALSE, Message);
2106 /*******************************************************************************
2108 ** gckOS_DebugTraceZone
2110 ** Send a leveled and zoned message to the debugger.
2112 ** INPUT:
2114 ** gctUINT32 Level
2115 ** Debug level for message.
2117 ** gctUINT32 Zone
2118 ** Debug zone for message.
2120 ** gctCONST_STRING Message
2121 ** Pointer to message.
2123 ** ...
2124 ** Optional arguments.
2126 ** OUTPUT:
2128 ** Nothing.
2131 void
2132 gckOS_DebugTraceZone(
2133 IN gctUINT32 Level,
2134 IN gctUINT32 Zone,
2135 IN gctCONST_STRING Message,
2139 if ((Level > _debugLevel) || !(Zone & _debugZones))
2141 return;
2144 gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
2147 /*******************************************************************************
2149 ** gckOS_DebugTraceZoneN
2151 ** Send a leveled and zoned message to the debugger.
2153 ** INPUT:
2155 ** gctUINT32 Level
2156 ** Debug level for message.
2158 ** gctUINT32 Zone
2159 ** Debug zone for message.
2161 ** gctUINT ArgumentSize
2162 ** The size of the optional arguments in bytes.
2164 ** gctCONST_STRING Message
2165 ** Pointer to message.
2167 ** ...
2168 ** Optional arguments.
2170 ** OUTPUT:
2172 ** Nothing.
2175 void
2176 gckOS_DebugTraceZoneN(
2177 IN gctUINT32 Level,
2178 IN gctUINT32 Zone,
2179 IN gctUINT ArgumentSize,
2180 IN gctCONST_STRING Message,
2184 if ((Level > _debugLevel) || !(Zone & _debugZones))
2186 return;
2189 gcmDEBUGPRINT(ArgumentSize, gcvFALSE, Message);
2192 /*******************************************************************************
2194 ** gckOS_DebugBreak
2196 ** Break into the debugger.
2198 ** INPUT:
2200 ** Nothing.
2202 ** OUTPUT:
2204 ** Nothing.
2206 void
2207 gckOS_DebugBreak(
2208 void
2211 gckOS_DebugTrace(gcvLEVEL_ERROR, "%s(%d)", __FUNCTION__, __LINE__);
2214 /*******************************************************************************
2216 ** gckOS_DebugFatal
2218 ** Send a message to the debugger and break into the debugger.
2220 ** INPUT:
2222 ** gctCONST_STRING Message
2223 ** Pointer to message.
2225 ** ...
2226 ** Optional arguments.
2228 ** OUTPUT:
2230 ** Nothing.
2232 void
2233 gckOS_DebugFatal(
2234 IN gctCONST_STRING Message,
2238 gcmkPRINT_VERSION();
2239 gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
2241 /* Break into the debugger. */
2242 gckOS_DebugBreak();
2245 /*******************************************************************************
2247 ** gckOS_SetDebugLevel
2249 ** Set the debug level.
2251 ** INPUT:
2253 ** gctUINT32 Level
2254 ** New debug level.
2256 ** OUTPUT:
2258 ** Nothing.
2261 void
2262 gckOS_SetDebugLevel(
2263 IN gctUINT32 Level
2266 _debugLevel = Level;
2269 /*******************************************************************************
2271 ** gckOS_SetDebugZone
2273 ** Set the debug zone.
2275 ** INPUT:
2277 ** gctUINT32 Zone
2278 ** New debug zone.
2280 ** OUTPUT:
2282 ** Nothing.
2284 void
2285 gckOS_SetDebugZone(
2286 IN gctUINT32 Zone
2289 _debugZones = Zone;
2292 /*******************************************************************************
2294 ** gckOS_SetDebugLevelZone
2296 ** Set the debug level and zone.
2298 ** INPUT:
2300 ** gctUINT32 Level
2301 ** New debug level.
2303 ** gctUINT32 Zone
2304 ** New debug zone.
2306 ** OUTPUT:
2308 ** Nothing.
2311 void
2312 gckOS_SetDebugLevelZone(
2313 IN gctUINT32 Level,
2314 IN gctUINT32 Zone
2317 _debugLevel = Level;
2318 _debugZones = Zone;
2321 /*******************************************************************************
2323 ** gckOS_SetDebugZones
2325 ** Enable or disable debug zones.
2327 ** INPUT:
2329 ** gctUINT32 Zones
2330 ** Debug zones to enable or disable.
2332 ** gctBOOL Enable
2333 ** Set to gcvTRUE to enable the zones (or the Zones with the current
2334 ** zones) or gcvFALSE to disable the specified Zones.
2336 ** OUTPUT:
2338 ** Nothing.
2341 void
2342 gckOS_SetDebugZones(
2343 IN gctUINT32 Zones,
2344 IN gctBOOL Enable
2347 if (Enable)
2349 /* Enable the zones. */
2350 _debugZones |= Zones;
2352 else
2354 /* Disable the zones. */
2355 _debugZones &= ~Zones;
2359 /*******************************************************************************
2361 ** gckOS_Verify
2363 ** Called to verify the result of a function call.
2365 ** INPUT:
2367 ** gceSTATUS Status
2368 ** Function call result.
2370 ** OUTPUT:
2372 ** Nothing.
2375 void
2376 gckOS_Verify(
2377 IN gceSTATUS Status
2380 _lastError = Status;
2383 /*******************************************************************************
2385 ** gckOS_DebugFlush
2387 ** Force messages to be flushed out.
2389 ** INPUT:
2391 ** gctCONST_STRING CallerName
2392 ** Name of the caller function.
2394 ** gctUINT LineNumber
2395 ** Line number of the caller.
2397 ** gctUINT32 DmaAddress
2398 ** The current DMA address or ~0U to ignore.
2400 ** OUTPUT:
2402 ** Nothing.
2405 void
2406 gckOS_DebugFlush(
2407 gctCONST_STRING CallerName,
2408 gctUINT LineNumber,
2409 gctUINT32 DmaAddress
2412 #if gcdBUFFERED_OUTPUT
2413 _DirectPrint("\nFlush requested by %s(%d).\n\n", CallerName, LineNumber);
2414 _Flush(DmaAddress);
2415 #endif
2417 gctCONST_STRING
2418 gckOS_DebugStatus2Name(
2419 gceSTATUS status
2422 switch (status)
2424 case gcvSTATUS_OK:
2425 return "gcvSTATUS_OK";
2426 case gcvSTATUS_TRUE:
2427 return "gcvSTATUS_TRUE";
2428 case gcvSTATUS_NO_MORE_DATA:
2429 return "gcvSTATUS_NO_MORE_DATA";
2430 case gcvSTATUS_CACHED:
2431 return "gcvSTATUS_CACHED";
2432 case gcvSTATUS_MIPMAP_TOO_LARGE:
2433 return "gcvSTATUS_MIPMAP_TOO_LARGE";
2434 case gcvSTATUS_NAME_NOT_FOUND:
2435 return "gcvSTATUS_NAME_NOT_FOUND";
2436 case gcvSTATUS_NOT_OUR_INTERRUPT:
2437 return "gcvSTATUS_NOT_OUR_INTERRUPT";
2438 case gcvSTATUS_MISMATCH:
2439 return "gcvSTATUS_MISMATCH";
2440 case gcvSTATUS_MIPMAP_TOO_SMALL:
2441 return "gcvSTATUS_MIPMAP_TOO_SMALL";
2442 case gcvSTATUS_LARGER:
2443 return "gcvSTATUS_LARGER";
2444 case gcvSTATUS_SMALLER:
2445 return "gcvSTATUS_SMALLER";
2446 case gcvSTATUS_CHIP_NOT_READY:
2447 return "gcvSTATUS_CHIP_NOT_READY";
2448 case gcvSTATUS_NEED_CONVERSION:
2449 return "gcvSTATUS_NEED_CONVERSION";
2450 case gcvSTATUS_SKIP:
2451 return "gcvSTATUS_SKIP";
2452 case gcvSTATUS_DATA_TOO_LARGE:
2453 return "gcvSTATUS_DATA_TOO_LARGE";
2454 case gcvSTATUS_INVALID_CONFIG:
2455 return "gcvSTATUS_INVALID_CONFIG";
2456 case gcvSTATUS_CHANGED:
2457 return "gcvSTATUS_CHANGED";
2458 case gcvSTATUS_NOT_SUPPORT_DITHER:
2459 return "gcvSTATUS_NOT_SUPPORT_DITHER";
2461 case gcvSTATUS_INVALID_ARGUMENT:
2462 return "gcvSTATUS_INVALID_ARGUMENT";
2463 case gcvSTATUS_INVALID_OBJECT:
2464 return "gcvSTATUS_INVALID_OBJECT";
2465 case gcvSTATUS_OUT_OF_MEMORY:
2466 return "gcvSTATUS_OUT_OF_MEMORY";
2467 case gcvSTATUS_MEMORY_LOCKED:
2468 return "gcvSTATUS_MEMORY_LOCKED";
2469 case gcvSTATUS_MEMORY_UNLOCKED:
2470 return "gcvSTATUS_MEMORY_UNLOCKED";
2471 case gcvSTATUS_HEAP_CORRUPTED:
2472 return "gcvSTATUS_HEAP_CORRUPTED";
2473 case gcvSTATUS_GENERIC_IO:
2474 return "gcvSTATUS_GENERIC_IO";
2475 case gcvSTATUS_INVALID_ADDRESS:
2476 return "gcvSTATUS_INVALID_ADDRESS";
2477 case gcvSTATUS_CONTEXT_LOSSED:
2478 return "gcvSTATUS_CONTEXT_LOSSED";
2479 case gcvSTATUS_TOO_COMPLEX:
2480 return "gcvSTATUS_TOO_COMPLEX";
2481 case gcvSTATUS_BUFFER_TOO_SMALL:
2482 return "gcvSTATUS_BUFFER_TOO_SMALL";
2483 case gcvSTATUS_INTERFACE_ERROR:
2484 return "gcvSTATUS_INTERFACE_ERROR";
2485 case gcvSTATUS_NOT_SUPPORTED:
2486 return "gcvSTATUS_NOT_SUPPORTED";
2487 case gcvSTATUS_MORE_DATA:
2488 return "gcvSTATUS_MORE_DATA";
2489 case gcvSTATUS_TIMEOUT:
2490 return "gcvSTATUS_TIMEOUT";
2491 case gcvSTATUS_OUT_OF_RESOURCES:
2492 return "gcvSTATUS_OUT_OF_RESOURCES";
2493 case gcvSTATUS_INVALID_DATA:
2494 return "gcvSTATUS_INVALID_DATA";
2495 case gcvSTATUS_INVALID_MIPMAP:
2496 return "gcvSTATUS_INVALID_MIPMAP";
2497 case gcvSTATUS_NOT_FOUND:
2498 return "gcvSTATUS_NOT_FOUND";
2499 case gcvSTATUS_NOT_ALIGNED:
2500 return "gcvSTATUS_NOT_ALIGNED";
2501 case gcvSTATUS_INVALID_REQUEST:
2502 return "gcvSTATUS_INVALID_REQUEST";
2503 case gcvSTATUS_GPU_NOT_RESPONDING:
2504 return "gcvSTATUS_GPU_NOT_RESPONDING";
2505 case gcvSTATUS_TIMER_OVERFLOW:
2506 return "gcvSTATUS_TIMER_OVERFLOW";
2507 case gcvSTATUS_VERSION_MISMATCH:
2508 return "gcvSTATUS_VERSION_MISMATCH";
2509 case gcvSTATUS_LOCKED:
2510 return "gcvSTATUS_LOCKED";
2512 /* Linker errors. */
2513 case gcvSTATUS_GLOBAL_TYPE_MISMATCH:
2514 return "gcvSTATUS_GLOBAL_TYPE_MISMATCH";
2515 case gcvSTATUS_TOO_MANY_ATTRIBUTES:
2516 return "gcvSTATUS_TOO_MANY_ATTRIBUTES";
2517 case gcvSTATUS_TOO_MANY_UNIFORMS:
2518 return "gcvSTATUS_TOO_MANY_UNIFORMS";
2519 case gcvSTATUS_TOO_MANY_VARYINGS:
2520 return "gcvSTATUS_TOO_MANY_VARYINGS";
2521 case gcvSTATUS_UNDECLARED_VARYING:
2522 return "gcvSTATUS_UNDECLARED_VARYING";
2523 case gcvSTATUS_VARYING_TYPE_MISMATCH:
2524 return "gcvSTATUS_VARYING_TYPE_MISMATCH";
2525 case gcvSTATUS_MISSING_MAIN:
2526 return "gcvSTATUS_MISSING_MAIN";
2527 case gcvSTATUS_NAME_MISMATCH:
2528 return "gcvSTATUS_NAME_MISMATCH";
2529 case gcvSTATUS_INVALID_INDEX:
2530 return "gcvSTATUS_INVALID_INDEX";
2531 default:
2532 return "nil";