/* * disasm.c - disassembler for MPC5200 Bestcomm DMA Firmware * copy and paste task code into fw, compile a run * by Frank bennett, 3/29/2006 * * Based on Freescale pdf "SmartDMA Hand-Assembly Guides" * * TODO: * o add inc[0:7] array (maybe var) to deternmine proper term condition (upper 3 bits) * o need to review sheet 3 of the pdf * o simulator would be nice * */ // Task12 (TASK_GEN_TX_BD) : Start of TDT -> 0xf0008528 // linuxppc_2_4_devel/arch/ppc/5xxx_io/bestcomm/code_dma/image_rtos1/"dma_image.reloc.c // // 31,30,29,28|27,26,25,24|23,22,21,20|19,18,17,16|15,14,13,12|11,10, 9, 8| 7, 6, 5, 4| 3, 2, 1, 0 // 0 0 0 1 0 0| 0 0 0 0 0| 0 0| 0 0| 0| 0 0 0 1 0 0| 1| 1 0 0 0 0 1| 0 0 0 // 0x10001308, /* 000C DRD1A: var4 = idx1; FN=0 MORE init=0 WS=0 RS=2 */ // 1 0 0| 1 1 0 0 1 0| 0| 0| 1 1 0 0 1 0| 0 0| 0| 0 0 0 0 0 0| 1 1 0| 1 1 0 // 0x99190036, /* 002C LCD: idx2 = idx2; idx2 once var0; idx2 += inc6 */ // 31,30,29,28|27,26,25,24|23,22,21,20|19,18,17,16|15,14,13,12|11,10, 9, 8| 7, 6, 5, 4| 3, 2, 1, 0 // 1 0| 0 1 1 0, 0 1 0 1, 1 0 0, 0 0 1| 1 0| 1 0 0 1 0 0 0 0 1 0 0 0 0 // 0x9950d210 /* Task12(TASK_GEN_TX_BD): Start of TDT -> 0xf0008528 */ unsigned long fw[] = { 0x800220e3, /* 0000 LCD: idx0 = var0, idx1 = var4; idx1 <= var3; idx0 += inc4, idx1 += inc3 */ 0x13e01010, /* 0004 DRD1A: var4 = var2; FN=0 MORE init=24 WS=0 RS=0 */ 0xb8808264, /* 0008 LCD: idx2 = *idx1, idx3 = var1; idx2 < var9; idx2 += inc4, idx3 += inc4 */ 0x10001308, /* 000C DRD1A: var4 = idx1; FN=0 MORE init=0 WS=0 RS=2 */ 0x60140002, /* 0010 DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */ 0x0cccfcca, /* 0014 DRD2B1: *idx3 = EU3(); EU3(*idx3,var10) */ 0xd9190300, /* 0018 LCDEXT: idx2 = idx2; idx2 > var12; idx2 += inc0 */ 0xb8c5e009, /* 001C LCD: idx3 = *(idx1 + var00000015); ; idx3 += inc1 */ 0x03fec398, /* 0020 DRD1A: *idx0 = *idx3; FN=0 init=24 WS=3 RS=2 */ 0x9919826a, /* 0024 LCD: idx2 = idx2, idx3 = idx3; idx2 > var9; idx2 += inc5, idx3 += inc2 */ 0x0feac398, /* 0028 DRD1A: *idx0 = *idx3; FN=0 TFD INT init=24 WS=1 RS=2 */ 0x99190036, /* 002C LCD: idx2 = idx2; idx2 once var0; idx2 += inc6 */ 0x60000005, /* 0030 DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */ 0x0c4cf889, /* 0034 DRD2B1: *idx1 = EU3(); EU3(idx2,var9) */ 0x000001f8, /* 0038 NOP */ 0x9950d210, 0x2c4cf889, 0 }; union { unsigned long i; struct { unsigned sb:3; // [02:00] increment #2 unsigned sa:3; // [05:03] increment #1 unsigned tc:6; // [11:06] variable to which idx is compared unsigned drtc:1; // [12] dr ? *(tc) : (tc) unsigned tu:2; // [14:13] term usage 00-idx_a, 01-idx_b, 10- lit init 11-no cond unsigned ib:6; // [20:15] init_b unsigned drib:1; // [21] dr ? *(init_a) : (init_a) unsigned p:1; // [22] indx plus offset unsigned ia:6; // [28:23] init_a unsigned dria:1; // [29] dr ? *(init_a) : (init_a) unsigned ext:1; // [30] = 2 or 3 for LCD unsigned op:1; // [31] = 2 or 3 for LCD } lcd; struct { unsigned ll:13; // [12:00] literal init low unsigned tu:2; // [14:13] term usage == 2 unsigned lh:15; // [29:15] literal init hi unsigned bas:1; // [30] = 2 or 3 for LCD unsigned op:1; // [31] = 2 or 3 for LCD } lcdl; struct { unsigned fn:3; // [02:00] unsigned src:6; // [08:03] unsigned drs:1; // [09] deref src? unsigned dst:6; // [15:10] unsigned drd:1; // [16] deref dst? scal? unsigned ws:2; // [18:17] 0-32bit, 1-1 byte, 2-16 word, 3-dynamic/reserved?? unsigned rs:2; // [20:19] 0-32bit, 1-1 byte, 2-16 word, 3-dynamic/reserved?? unsigned init:5; // [25:21] unsigned intr:1; // [26] unsigned tfd:1; // [27] unsigned more:1; // [28] unsigned type:1; // [29] unsigned ext:1; // [30] unsigned op:1; // [31] = 0 for DRD } drd1a; struct { unsigned eu3:4; // [03:00] Execution Unit3 Function number unsigned eu2:4; // [07:04] Execution Unit3 Function number unsigned eu1:4; // [11:08] Execution Unit3 Function number unsigned eu0:4; // [15:12] Execution Unit3 Function number unsigned drd:1; // [16] deref dst? scal? unsigned ws:2; // [18:17] 0-32bit, 1-1 byte, 2-16 word, 3-dynamic/reserved?? unsigned rs:2; // [20:19] 0-32bit, 1-1 byte, 2-16 word, 3-dynamic/reserved?? unsigned init:5; // [25:21] unsigned int:1; // [26] unsigned tfd:1; // [27] unsigned more:1; // [28] unsigned type:1; // [29] unsigned ext:1; // [30] unsigned op:1; // [31] = 0 for DRD } drd2a; struct { unsigned od1:6; // [05:00] EU operand 1 unsigned od0:6; // [11:06] EU operand 0 unsigned eu:2; // [13:12] EU#, only #3 available on MPC5200 unsigned mems:6; // [19:14] memory write source unsigned drds:1; // [20] unsigned rsv2:1; // [21] unsigned memd:6; // [27:22] memory write destination unsigned rsv1:1; // [28] reserved? unsigned type:1; // [29] unsigned ext:1; // [30] unsigned op:1; // [31] = 0 for DRD } drd2b1; struct { unsigned odb1:6; // [05:00] EUb operand 1/3/5/7 unsigned odb0:6; // [11:06] EUb operand 0/2/4/6 unsigned eub:2; // [13:12] EUb#, only #3 available on MPC5200 unsigned oda1:6; // [19:14] EUa operand 1/3/5/7 unsigned oda0:6; // [25:20] EUa operand 0/2/4/6 unsigned eua:2; // [27:26] EUa#, only #3 available on MPC5200 unsigned rsv1:1; // [28] unsigned type:1; // [29] unsigned ext:1; // [30] unsigned op:1; // [31] = 0 for DRD } drd2b2; } x; // Condition codes (first 4 bits of the increments) // >= c // > 4 // once 0 // != 6 // <= a // < 2 char *ft[] = { "ld_acc", "unld_acc", "and", "or", "xor" "andn", "not", "add", "sub", "lsh", "rsh", "crc8", "crc16", "crc32", "endian32", "endian16" }; char s[8]; indvar (int i) { switch ((i & 0x3f) >> 4) { case 0: sprintf (s, "var%d", i & 0x1f); // varN break; case 1: sprintf (s, "inc%d", i & 0x07); // incN break; case 2: // extraN case 3: sprintf (s, "idx%d", i & 0x0f); // idxN break; } } #define L2 LLev*2 main () { int i, j, LLev = 0, drdt, ex = 0, ml; char in[12]; for (i = 0; fw[i]; i++) { x.i = fw[i]; if (x.i == 0x1f8) printf ("0x%08x, // NOP\n", x.i); else if (x.lcd.op) // LCD { if (LLev == 0) strcpy (in, ""); else strcpy (in, " "); if (x.lcd.ext) // LCDEXT { indvar (x.lcd.tc); printf ("0x%08x, // %sLCDEXT: idx%d=idx%d; idx%d >%s%s ; idx%d += inc%d\n", x.i, in, L2, L2, L2, x.lcd.drtc ? "*" : " ", s, L2, x.lcd.sb); } else if (x.lcd.tu == 2) // LCDLIT { printf ("0x%08x, // %sLCDLIT: idx%d = 0x%07x ??\n", x.i, in, L2, (x.lcdl.lh << 13) | x.lcdl.ll); } else // LCD { printf ("0x%08x, // %sLCD: ", x.i, in); if (x.lcd.p) // indexed p-plus { indvar (x.lcd.ia); printf ("idx%d = %s(%s + ", L2 + 1, x.lcd.dria ? "*" : " ", s); indvar (x.lcd.ib); printf ("%s%s); ; ", x.lcd.drib ? "*" : " ", s); } else { indvar (x.lcd.ia); printf ("idx%d=%s%s, ", L2, x.lcd.dria ? "*" : " ", s); indvar (x.lcd.ib); printf ("idx%d=%s%s, ", L2 + 1, x.lcd.drib ? "*" : " ", s); } if (x.lcd.tu < 2) { indvar (x.lcd.tc); printf ("idx%d <=%s%s, ", (x.lcd.tu == 0) ? L2 : L2 + 1, x.lcd.drtc ? "*" : " ", s); } if (x.lcd.tu != 3) printf ("idx%d += inc%01x, ", L2, x.lcd.sa); printf ("idx%d += inc%01x\n", L2 + 1, x.lcd.sb); ex = 0; } } else { // DRD if (LLev == 0) strcpy (in, " "); else strcpy (in, " "); drdt = (ex << 2) | (x.drd1a.ext << 1) | x.drd1a.type; switch (drdt) { case 0: // DRD1A printf ("0x%08x, // %sDRD1A: ", x.i, in); indvar (x.drd1a.dst); printf ("%s%s =", x.drd1a.drd ? "*" : " ", s); indvar (x.drd1a.src); printf ("%s%s; ", x.drd1a.drs ? "*" : " ", s); printf ("FN=%d (%s) ", x.drd1a.fn, ft[x.drd1a.fn]); if (x.drd1a.more) printf ("MORE "); if (x.drd1a.tfd) printf ("TFD "); if (x.drd1a.intr) printf ("INT "); printf ("init=%d ", x.drd1a.init); printf ("WS=%d RS=%d \n", x.drd1a.ws, x.drd1a.rs); break; case 3: // DRD2A ex = x.drd2a.ext; printf ("0x%08x, // %sDRD2A: ", x.i, in); printf ("EU0=0 EU1=0 EU2=0 EU3=%d (%s) EXT init=%d ", x.drd2a.eu3, ft[x.drd2a.eu3], x.drd2a.init); printf ("WS=%d RS=%d \n", x.drd2a.ws, x.drd2a.rs); break; case 4: // DRD2B1 printf ("0x%08x, // %sDRD2B1: ", x.i, in); indvar (x.drd2b1.memd); // mems ?? printf ("*%s=EU%d(); ", s, x.drd2b1.eu); indvar (x.drd2b1.od0); printf ("EU%d(%s, ", x.drd2b1.eu, s); indvar (x.drd2b1.od1); printf ("%s) \n", s); break; case 5: // DRD2B2 case 7: // DRD2B2? printf ("0x%08x, // %sDRD2B2: ", x.i, in); indvar (x.drd2b2.oda0); printf ("EU%d(%s, ", x.drd2b2.eub, s); indvar (x.drd2b2.oda1); printf ("%s) , ", s); indvar (x.drd2b2.odb0); printf ("EU%d(%s, ", x.drd2b2.eua, s); indvar (x.drd2b2.odb1); printf ("%s) ??\n", s); break; case 1: case 2: case 6: printf ("fix_me\n"); ex = x.drd1a.ext; break; } LLev |= 1; } } }