z180_postmortem.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. */
  13. #include "kgsl.h"
  14. #include "kgsl_device.h"
  15. #include "z180.h"
  16. #include "z180_reg.h"
  17. #define Z180_STREAM_PACKET_CALL 0x7C000275
  18. /* Postmortem Dump formatted Output parameters */
  19. /* Number of Words per dump data line */
  20. #define WORDS_PER_LINE 8
  21. /* Number of spaces per dump data line */
  22. #define NUM_SPACES (WORDS_PER_LINE - 1)
  23. /*
  24. * Output dump data is formatted as string, hence number of chars
  25. * per line for line string allocation
  26. */
  27. #define CHARS_PER_LINE \
  28. ((WORDS_PER_LINE * (2*sizeof(unsigned int))) + NUM_SPACES + 1)
  29. /* Z180 registers (byte offsets) to be dumped */
  30. static const unsigned int regs_to_dump[] = {
  31. ADDR_VGC_VERSION,
  32. ADDR_VGC_SYSSTATUS,
  33. ADDR_VGC_IRQSTATUS,
  34. ADDR_VGC_IRQENABLE,
  35. ADDR_VGC_IRQ_ACTIVE_CNT,
  36. ADDR_VGC_CLOCKEN,
  37. ADDR_VGC_MH_DATA_ADDR,
  38. ADDR_VGC_GPR0,
  39. ADDR_VGC_GPR1,
  40. ADDR_VGC_BUSYCNT,
  41. ADDR_VGC_FIFOFREE,
  42. };
  43. /**
  44. * z180_dump_regs - Dumps all of Z180 external registers. Prints the word offset
  45. * of the register in each output line.
  46. * @device: kgsl_device pointer to the Z180 core
  47. */
  48. static void z180_dump_regs(struct kgsl_device *device)
  49. {
  50. unsigned int i;
  51. unsigned int reg_val;
  52. z180_idle(device);
  53. KGSL_LOG_DUMP(device, "Z180 Register Dump\n");
  54. for (i = 0; i < ARRAY_SIZE(regs_to_dump); i++) {
  55. kgsl_regread(device,
  56. regs_to_dump[i]/sizeof(unsigned int), &reg_val);
  57. KGSL_LOG_DUMP(device, "REG: %04X: %08X\n",
  58. regs_to_dump[i]/sizeof(unsigned int), reg_val);
  59. }
  60. }
  61. /**
  62. * z180_dump_ringbuffer - Dumps the Z180 core's ringbuffer contents
  63. * @device: kgsl_device pointer to the z180 core
  64. */
  65. static void z180_dump_ringbuffer(struct kgsl_device *device)
  66. {
  67. unsigned int rb_size;
  68. unsigned int *rb_hostptr;
  69. unsigned int rb_words;
  70. unsigned int rb_gpuaddr;
  71. struct z180_device *z180_dev = Z180_DEVICE(device);
  72. unsigned int i;
  73. char linebuf[CHARS_PER_LINE];
  74. KGSL_LOG_DUMP(device, "Z180 ringbuffer dump\n");
  75. rb_hostptr = (unsigned int *) z180_dev->ringbuffer.cmdbufdesc.hostptr;
  76. rb_size = Z180_RB_SIZE;
  77. rb_gpuaddr = z180_dev->ringbuffer.cmdbufdesc.gpuaddr;
  78. rb_words = rb_size/sizeof(unsigned int);
  79. KGSL_LOG_DUMP(device, "ringbuffer size: %u\n", rb_size);
  80. KGSL_LOG_DUMP(device, "rb_words: %d\n", rb_words);
  81. for (i = 0; i < rb_words; i += WORDS_PER_LINE) {
  82. hex_dump_to_buffer(rb_hostptr+i,
  83. rb_size - i*sizeof(unsigned int),
  84. WORDS_PER_LINE*sizeof(unsigned int),
  85. sizeof(unsigned int), linebuf,
  86. sizeof(linebuf), false);
  87. KGSL_LOG_DUMP(device, "RB: %04X: %s\n",
  88. rb_gpuaddr + i*sizeof(unsigned int), linebuf);
  89. }
  90. }
  91. static void z180_dump_ib(struct kgsl_device *device)
  92. {
  93. unsigned int rb_size;
  94. unsigned int *rb_hostptr;
  95. unsigned int rb_words;
  96. unsigned int rb_gpuaddr;
  97. unsigned int ib_gpuptr = 0;
  98. unsigned int ib_size = 0;
  99. void *ib_hostptr = NULL;
  100. int rb_slot_num = -1;
  101. struct z180_device *z180_dev = Z180_DEVICE(device);
  102. struct kgsl_mem_entry *entry = NULL;
  103. phys_addr_t pt_base;
  104. unsigned int i;
  105. unsigned int j;
  106. char linebuf[CHARS_PER_LINE];
  107. unsigned int current_ib_slot;
  108. unsigned int len;
  109. unsigned int rowsize;
  110. KGSL_LOG_DUMP(device, "Z180 IB dump\n");
  111. rb_hostptr = (unsigned int *) z180_dev->ringbuffer.cmdbufdesc.hostptr;
  112. rb_size = Z180_RB_SIZE;
  113. rb_gpuaddr = z180_dev->ringbuffer.cmdbufdesc.gpuaddr;
  114. rb_words = rb_size/sizeof(unsigned int);
  115. KGSL_LOG_DUMP(device, "Ringbuffer size (bytes): %u\n", rb_size);
  116. KGSL_LOG_DUMP(device, "rb_words: %d\n", rb_words);
  117. pt_base = kgsl_mmu_get_current_ptbase(&device->mmu);
  118. /* Dump the current IB */
  119. for (i = 0; i < rb_words; i++) {
  120. if (rb_hostptr[i] == Z180_STREAM_PACKET_CALL) {
  121. rb_slot_num++;
  122. current_ib_slot =
  123. z180_dev->current_timestamp % Z180_PACKET_COUNT;
  124. if (rb_slot_num != current_ib_slot)
  125. continue;
  126. ib_gpuptr = rb_hostptr[i+1];
  127. entry = kgsl_get_mem_entry(device, pt_base, ib_gpuptr,
  128. 1);
  129. if (entry == NULL) {
  130. KGSL_LOG_DUMP(device,
  131. "IB mem entry not found for ringbuffer slot#: %d\n",
  132. rb_slot_num);
  133. continue;
  134. }
  135. ib_hostptr = kgsl_memdesc_map(&entry->memdesc);
  136. if (ib_hostptr == NULL) {
  137. KGSL_LOG_DUMP(device,
  138. "Could not map IB to kernel memory, Ringbuffer Slot: %d\n",
  139. rb_slot_num);
  140. kgsl_mem_entry_put(entry);
  141. continue;
  142. }
  143. ib_size = entry->memdesc.size;
  144. KGSL_LOG_DUMP(device,
  145. "IB size: %dbytes, IB size in words: %d\n",
  146. ib_size,
  147. ib_size/sizeof(unsigned int));
  148. for (j = 0; j < ib_size; j += WORDS_PER_LINE) {
  149. len = ib_size - j*sizeof(unsigned int);
  150. rowsize = WORDS_PER_LINE*sizeof(unsigned int);
  151. hex_dump_to_buffer(ib_hostptr+j, len, rowsize,
  152. sizeof(unsigned int), linebuf,
  153. sizeof(linebuf), false);
  154. KGSL_LOG_DUMP(device, "IB%d: %04X: %s\n",
  155. rb_slot_num,
  156. (rb_gpuaddr +
  157. j*sizeof(unsigned int)),
  158. linebuf);
  159. }
  160. KGSL_LOG_DUMP(device, "IB Dump Finished\n");
  161. kgsl_mem_entry_put(entry);
  162. }
  163. }
  164. }
  165. /**
  166. * z180_dump - Dumps the Z180 ringbuffer and registers (and IBs if asked for)
  167. * for postmortem
  168. * analysis.
  169. * @device: kgsl_device pointer to the Z180 core
  170. */
  171. int z180_dump(struct kgsl_device *device, int manual)
  172. {
  173. struct z180_device *z180_dev = Z180_DEVICE(device);
  174. mb();
  175. KGSL_LOG_DUMP(device, "Retired Timestamp: %d\n", z180_dev->timestamp);
  176. KGSL_LOG_DUMP(device,
  177. "Current Timestamp: %d\n", z180_dev->current_timestamp);
  178. /* Dump ringbuffer */
  179. z180_dump_ringbuffer(device);
  180. /* Dump registers */
  181. z180_dump_regs(device);
  182. /* Dump IBs, if asked for */
  183. if (device->pm_ib_enabled)
  184. z180_dump_ib(device);
  185. /* Get the stack trace if the dump was automatic */
  186. if (!manual)
  187. BUG_ON(1);
  188. return 0;
  189. }