KISS Data Aquisition and Control System
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

238 lines
7.1 KiB

  1. /*
  2. *
  3. * PRU Debug Program - disassembly routines
  4. * (c) Copyright 2011 by Arctica Technologies
  5. * Written by Steven Anderson
  6. *
  7. */
  8. #include <stdio.h>
  9. #include <unistd.h>
  10. #include <fcntl.h>
  11. #include <sys/mman.h>
  12. #include <sys/types.h>
  13. #include <sys/stat.h>
  14. #include <errno.h>
  15. #include <termios.h>
  16. #include <sys/ioctl.h>
  17. #include <sys/select.h>
  18. #include "prudbg.h"
  19. // util function to decode BurstLen in Format 6 instructions
  20. void GetBurstLen(char *tempstr, unsigned int BurstLen)
  21. {
  22. if (BurstLen < 124) {
  23. sprintf(tempstr, "%u", BurstLen+1);
  24. } else if (BurstLen == 124) {
  25. sprintf(tempstr, "b0");
  26. } else if (BurstLen == 125) {
  27. sprintf(tempstr, "b1");
  28. } else if (BurstLen == 126) {
  29. sprintf(tempstr, "b2");
  30. } else if (BurstLen == 127) {
  31. sprintf(tempstr, "b3");
  32. } else {
  33. sprintf(tempstr, "XX");
  34. }
  35. }
  36. // disassemble the inst instruction and place string in str
  37. void disassemble(char *str, unsigned int inst)
  38. {
  39. unsigned short Imm;
  40. unsigned char OP, ALUOP, Rs2Sel, Rs2, Rs1Sel, Rs1, RdSel, Rd, IO, Imm2, SUBOP, Test;
  41. unsigned char LoadStore, BurstLen, RxByteAddr, Rx, Ro, RoSel, Rb;
  42. short BrOff;
  43. char tempstr[50];
  44. char *f1_inst[] = {"ADD", "ADC", "SUB", "SUC", "LSL", "LSR", "RSB", "RSC", "AND", "OR", "XOR", "NOT", "MIN", "MAX", "CLR", "SET"};
  45. char *f2_inst[] = {
  46. "JMP", "JAL", "LDI", "LMBD", "SCAN", "HALT",
  47. "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED",
  48. "SLP"
  49. };
  50. char *f4_inst[] = {"xx", "LT", "EQ", "LE", "GT", "NE", "GE", "A"};
  51. char *f5_inst[] = {"xx", "BC", "BS", "xx"};
  52. char *f6_7_inst[] = {"SBBO", "LBBO"};
  53. char *f6_4_inst[] = {"SBCO", "LBCO"};
  54. char *sis[] = {".b0", ".b1", ".b2", ".b3", ".w0", ".w1", ".w2", ""};
  55. char *bytenum[] = {"", ".b1", ".b2", ".b3"};
  56. OP = (inst & 0xE0000000) >> 29;
  57. switch (OP) {
  58. case 0: // format 1
  59. ALUOP = (inst & 0x1E000000) >> 25;
  60. IO = (inst & 0x01000000) >> 24;
  61. Rs1Sel = (inst & 0x0000E000) >> 13;
  62. Rs1 = (inst & 0x00001F00) >> 8;
  63. RdSel = (inst & 0x000000E0) >> 5;
  64. Rd = (inst & 0x0000001F);
  65. if (IO) {
  66. Imm2 = (inst & 0x00FF0000) >> 16;
  67. sprintf(str, "%s R%u%s, R%u%s, 0x%02x", f1_inst[ALUOP], Rd, sis[RdSel], Rs1, sis[Rs1Sel], Imm2);
  68. } else {
  69. Rs2Sel = (inst & 0x00E00000) >> 21;
  70. Rs2 = (inst & 0x001F0000) >> 16;
  71. sprintf(str, "%s R%u%s, R%u%s, R%u%s", f1_inst[ALUOP], Rd, sis[RdSel], Rs1, sis[Rs1Sel], Rs2, sis[Rs2Sel]);
  72. }
  73. break;
  74. case 1: // format 2
  75. SUBOP = (inst & 0x1E000000) >> 25;
  76. switch (SUBOP) {
  77. case 0: // JMP & JAL
  78. case 1:
  79. IO = (inst & 0x01000000) >> 24;
  80. RdSel = (inst & 0x000000E0) >> 5;
  81. Rd = (inst & 0x0000001F);
  82. if (IO) {
  83. Imm = (inst & 0x00FFFF00) >> 8;
  84. if (SUBOP == 0)
  85. sprintf(str, "%s 0x%04x", f2_inst[SUBOP], Imm);
  86. else
  87. sprintf(str, "%s R%u%s, 0x%04x", f2_inst[SUBOP], Rd, sis[RdSel], Imm);
  88. } else {
  89. Rs2Sel = (inst & 0x00E00000) >> 21;
  90. Rs2 = (inst & 0x001F0000) >> 16;
  91. if (SUBOP == 0)
  92. sprintf(str, "%s R%u%s", f2_inst[SUBOP], Rs2, sis[Rs2Sel]);
  93. else
  94. sprintf(str, "%s R%u%s, R%u%s", f2_inst[SUBOP], Rd, sis[RdSel], Rs2, sis[Rs2Sel]);
  95. }
  96. break;
  97. case 2: // LDI
  98. Imm = (inst & 0x00FFFF00) >> 8;
  99. RdSel = (inst & 0x000000E0) >> 5;
  100. Rd = (inst & 0x0000001F);
  101. sprintf(str, "%s R%u%s, 0x%04x", f2_inst[SUBOP], Rd, sis[RdSel], Imm);
  102. break;
  103. case 3: // LMBD
  104. IO = (inst & 0x01000000) >> 24;
  105. Rs1Sel = (inst & 0x0000E000) >> 13;
  106. Rs1 = (inst & 0x00001F00) >> 8;
  107. RdSel = (inst & 0x000000E0) >> 5;
  108. Rd = (inst & 0x0000001F);
  109. Rs2Sel = (inst & 0x00E00000) >> 21;
  110. Rs2 = (inst & 0x001F0000) >> 16;
  111. Imm2 = (inst & 0x00FF0000) >> 16;
  112. if (IO) {
  113. sprintf(str, "%s R%u%s, R%u%s, 0x%04x", f2_inst[SUBOP], Rd, sis[RdSel], Rs1, sis[Rs1Sel], Imm2);
  114. } else {
  115. sprintf(str, "%s R%u%s, R%u%s, R%u%s", f2_inst[SUBOP], Rd, sis[RdSel], Rs1, sis[Rs1Sel], Rs2, sis[Rs2Sel]);
  116. }
  117. break;
  118. case 4: // SCAN
  119. IO = (inst & 0x01000000) >> 24;
  120. RdSel = (inst & 0x000000E0) >> 5;
  121. Rd = (inst & 0x0000001F);
  122. Rs2Sel = (inst & 0x00E00000) >> 21;
  123. Rs2 = (inst & 0x001F0000) >> 16;
  124. Imm2 = (inst & 0x00FF0000) >> 16;
  125. if (IO) {
  126. sprintf(str, "%s R%u%s, 0x%04x", f2_inst[SUBOP], Rd, sis[RdSel], Rs1, sis[Rs1Sel], Imm2);
  127. } else {
  128. sprintf(str, "%s R%u%s, R%u%s", f2_inst[SUBOP], Rd, sis[RdSel], Rs2, sis[Rs2Sel]);
  129. }
  130. break;
  131. case 5: // HALT
  132. sprintf(str, "%s", f2_inst[SUBOP]);
  133. break;
  134. case 15: // SLP
  135. Imm = (inst & 0x00800000) >> 23;
  136. sprintf(str, "%s %u", f2_inst[SUBOP], Imm);
  137. break;
  138. default:
  139. sprintf(str, "UNKNOWN-F2");
  140. break;
  141. }
  142. break;
  143. case 2: // Format 4a & 4b - Quick Arithmetic Test and Branch
  144. case 3:
  145. Test = (inst & 0x38000000) >> 27;
  146. IO = (inst & 0x01000000) >> 24;
  147. Rs2Sel = (inst & 0x00E00000) >> 21;
  148. Rs2 = (inst & 0x001F0000) >> 16;
  149. Rs1Sel = (inst & 0x0000E000) >> 13;
  150. Rs1 = (inst & 0x00001F00) >> 8;
  151. Imm = (inst & 0x00FF0000) >> 16;
  152. BrOff = ((inst & 0x06000000) >> 17) | (inst & 0x000000FF);
  153. if (BrOff & 0x0200) BrOff |= 0xFC00;
  154. if (Test == 7) {
  155. sprintf(str, "QBA %d", BrOff);
  156. } else {
  157. if (IO) {
  158. sprintf(str, "QB%s %d, R%u%s, %u", f4_inst[Test], BrOff, Rs1, sis[Rs1Sel], Imm);
  159. } else {
  160. sprintf(str, "QB%s %d, R%u%s, R%u%s", f4_inst[Test], BrOff, Rs1, sis[Rs1Sel], Rs2, sis[Rs2Sel]);
  161. }
  162. }
  163. break;
  164. case 6: // Format 5 - Quick bit test and banch instructions
  165. Test = (inst & 0x18000000) >> 27;
  166. IO = (inst & 0x01000000) >> 24;
  167. Rs2Sel = (inst & 0x00E00000) >> 21;
  168. Rs2 = (inst & 0x001F0000) >> 16;
  169. Rs1Sel = (inst & 0x0000E000) >> 13;
  170. Rs1 = (inst & 0x00001F00) >> 8;
  171. Imm = (inst & 0x001F0000) >> 16;
  172. BrOff = ((inst & 0x06000000) >> 17) | (inst & 0x000000FF);
  173. if (BrOff & 0x0200) BrOff |= 0xFC00;
  174. if (IO) {
  175. sprintf(str, "QB%s %d, R%u%s, %u", f5_inst[Test], BrOff, Rs1, sis[Rs1Sel], Imm);
  176. } else {
  177. sprintf(str, "QB%s %d, R%u%s, R%u%s", f5_inst[Test], BrOff, Rs1, sis[Rs1Sel], Rs2, sis[Rs2Sel]);
  178. }
  179. break;
  180. case 4:
  181. case 7: // Format 6 - LBBO/SBBO/LBCO/SBCO instructions
  182. LoadStore = (inst & 0x10000000) >> 28;
  183. BurstLen = ((inst & 0x0E000000) >> 21) | ((inst & 0x0000E000) >> 12) | ((inst & 0x00000080) >> 7);
  184. IO = (inst & 0x01000000) >> 24;
  185. RxByteAddr = (inst & 0x00000060) >> 5;
  186. Rx = (inst & 0x0000001F);
  187. RoSel = (inst & 0x00E00000) >> 21;
  188. Ro = (inst & 0x001F0000) >> 16;
  189. Rb = (inst & 0x00001F00) >> 8;
  190. Imm = (inst & 0x00FF0000) >> 16;
  191. GetBurstLen(tempstr, BurstLen);
  192. if (OP == 7) {
  193. if (IO) {
  194. sprintf(str, "%s R%u%s, R%u, %u, %s", f6_7_inst[LoadStore], Rx, bytenum[RxByteAddr], Rb, Imm, tempstr);
  195. } else {
  196. sprintf(str, "%s R%u%s, R%u, R%u%s, %s", f6_7_inst[LoadStore], Rx, bytenum[RxByteAddr], Rb, Ro, sis[RoSel], tempstr);
  197. }
  198. } else { // OP==4
  199. if (IO) {
  200. sprintf(str, "%s R%u%s, C%u, %u, %s", f6_4_inst[LoadStore], Rx, bytenum[RxByteAddr], Rb, Imm, tempstr);
  201. } else {
  202. sprintf(str, "%s R%u%s, C%u, R%u%s, %s", f6_4_inst[LoadStore], Rx, bytenum[RxByteAddr], Rb, Ro, sis[RoSel], tempstr);
  203. }
  204. }
  205. break;
  206. default:
  207. sprintf(str, "UNKNOWN");
  208. break;
  209. }
  210. }