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

/*
*
* PRU Debug Program - disassembly routines
* (c) Copyright 2011 by Arctica Technologies
* Written by Steven Anderson
*
*/
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include "prudbg.h"
// util function to decode BurstLen in Format 6 instructions
void GetBurstLen(char *tempstr, unsigned int BurstLen)
{
if (BurstLen < 124) {
sprintf(tempstr, "%u", BurstLen+1);
} else if (BurstLen == 124) {
sprintf(tempstr, "b0");
} else if (BurstLen == 125) {
sprintf(tempstr, "b1");
} else if (BurstLen == 126) {
sprintf(tempstr, "b2");
} else if (BurstLen == 127) {
sprintf(tempstr, "b3");
} else {
sprintf(tempstr, "XX");
}
}
// disassemble the inst instruction and place string in str
void disassemble(char *str, unsigned int inst)
{
unsigned short Imm;
unsigned char OP, ALUOP, Rs2Sel, Rs2, Rs1Sel, Rs1, RdSel, Rd, IO, Imm2, SUBOP, Test;
unsigned char LoadStore, BurstLen, RxByteAddr, Rx, Ro, RoSel, Rb;
short BrOff;
char tempstr[50];
char *f1_inst[] = {"ADD", "ADC", "SUB", "SUC", "LSL", "LSR", "RSB", "RSC", "AND", "OR", "XOR", "NOT", "MIN", "MAX", "CLR", "SET"};
char *f2_inst[] = {
"JMP", "JAL", "LDI", "LMBD", "SCAN", "HALT",
"RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED",
"SLP"
};
char *f4_inst[] = {"xx", "LT", "EQ", "LE", "GT", "NE", "GE", "A"};
char *f5_inst[] = {"xx", "BC", "BS", "xx"};
char *f6_7_inst[] = {"SBBO", "LBBO"};
char *f6_4_inst[] = {"SBCO", "LBCO"};
char *sis[] = {".b0", ".b1", ".b2", ".b3", ".w0", ".w1", ".w2", ""};
char *bytenum[] = {"", ".b1", ".b2", ".b3"};
OP = (inst & 0xE0000000) >> 29;
switch (OP) {
case 0: // format 1
ALUOP = (inst & 0x1E000000) >> 25;
IO = (inst & 0x01000000) >> 24;
Rs1Sel = (inst & 0x0000E000) >> 13;
Rs1 = (inst & 0x00001F00) >> 8;
RdSel = (inst & 0x000000E0) >> 5;
Rd = (inst & 0x0000001F);
if (IO) {
Imm2 = (inst & 0x00FF0000) >> 16;
sprintf(str, "%s R%u%s, R%u%s, 0x%02x", f1_inst[ALUOP], Rd, sis[RdSel], Rs1, sis[Rs1Sel], Imm2);
} else {
Rs2Sel = (inst & 0x00E00000) >> 21;
Rs2 = (inst & 0x001F0000) >> 16;
sprintf(str, "%s R%u%s, R%u%s, R%u%s", f1_inst[ALUOP], Rd, sis[RdSel], Rs1, sis[Rs1Sel], Rs2, sis[Rs2Sel]);
}
break;
case 1: // format 2
SUBOP = (inst & 0x1E000000) >> 25;
switch (SUBOP) {
case 0: // JMP & JAL
case 1:
IO = (inst & 0x01000000) >> 24;
RdSel = (inst & 0x000000E0) >> 5;
Rd = (inst & 0x0000001F);
if (IO) {
Imm = (inst & 0x00FFFF00) >> 8;
if (SUBOP == 0)
sprintf(str, "%s 0x%04x", f2_inst[SUBOP], Imm);
else
sprintf(str, "%s R%u%s, 0x%04x", f2_inst[SUBOP], Rd, sis[RdSel], Imm);
} else {
Rs2Sel = (inst & 0x00E00000) >> 21;
Rs2 = (inst & 0x001F0000) >> 16;
if (SUBOP == 0)
sprintf(str, "%s R%u%s", f2_inst[SUBOP], Rs2, sis[Rs2Sel]);
else
sprintf(str, "%s R%u%s, R%u%s", f2_inst[SUBOP], Rd, sis[RdSel], Rs2, sis[Rs2Sel]);
}
break;
case 2: // LDI
Imm = (inst & 0x00FFFF00) >> 8;
RdSel = (inst & 0x000000E0) >> 5;
Rd = (inst & 0x0000001F);
sprintf(str, "%s R%u%s, 0x%04x", f2_inst[SUBOP], Rd, sis[RdSel], Imm);
break;
case 3: // LMBD
IO = (inst & 0x01000000) >> 24;
Rs1Sel = (inst & 0x0000E000) >> 13;
Rs1 = (inst & 0x00001F00) >> 8;
RdSel = (inst & 0x000000E0) >> 5;
Rd = (inst & 0x0000001F);
Rs2Sel = (inst & 0x00E00000) >> 21;
Rs2 = (inst & 0x001F0000) >> 16;
Imm2 = (inst & 0x00FF0000) >> 16;
if (IO) {
sprintf(str, "%s R%u%s, R%u%s, 0x%04x", f2_inst[SUBOP], Rd, sis[RdSel], Rs1, sis[Rs1Sel], Imm2);
} else {
sprintf(str, "%s R%u%s, R%u%s, R%u%s", f2_inst[SUBOP], Rd, sis[RdSel], Rs1, sis[Rs1Sel], Rs2, sis[Rs2Sel]);
}
break;
case 4: // SCAN
IO = (inst & 0x01000000) >> 24;
RdSel = (inst & 0x000000E0) >> 5;
Rd = (inst & 0x0000001F);
Rs2Sel = (inst & 0x00E00000) >> 21;
Rs2 = (inst & 0x001F0000) >> 16;
Imm2 = (inst & 0x00FF0000) >> 16;
if (IO) {
sprintf(str, "%s R%u%s, 0x%04x", f2_inst[SUBOP], Rd, sis[RdSel], Rs1, sis[Rs1Sel], Imm2);
} else {
sprintf(str, "%s R%u%s, R%u%s", f2_inst[SUBOP], Rd, sis[RdSel], Rs2, sis[Rs2Sel]);
}
break;
case 5: // HALT
sprintf(str, "%s", f2_inst[SUBOP]);
break;
case 15: // SLP
Imm = (inst & 0x00800000) >> 23;
sprintf(str, "%s %u", f2_inst[SUBOP], Imm);
break;
default:
sprintf(str, "UNKNOWN-F2");
break;
}
break;
case 2: // Format 4a & 4b - Quick Arithmetic Test and Branch
case 3:
Test = (inst & 0x38000000) >> 27;
IO = (inst & 0x01000000) >> 24;
Rs2Sel = (inst & 0x00E00000) >> 21;
Rs2 = (inst & 0x001F0000) >> 16;
Rs1Sel = (inst & 0x0000E000) >> 13;
Rs1 = (inst & 0x00001F00) >> 8;
Imm = (inst & 0x00FF0000) >> 16;
BrOff = ((inst & 0x06000000) >> 17) | (inst & 0x000000FF);
if (BrOff & 0x0200) BrOff |= 0xFC00;
if (Test == 7) {
sprintf(str, "QBA %d", BrOff);
} else {
if (IO) {
sprintf(str, "QB%s %d, R%u%s, %u", f4_inst[Test], BrOff, Rs1, sis[Rs1Sel], Imm);
} else {
sprintf(str, "QB%s %d, R%u%s, R%u%s", f4_inst[Test], BrOff, Rs1, sis[Rs1Sel], Rs2, sis[Rs2Sel]);
}
}
break;
case 6: // Format 5 - Quick bit test and banch instructions
Test = (inst & 0x18000000) >> 27;
IO = (inst & 0x01000000) >> 24;
Rs2Sel = (inst & 0x00E00000) >> 21;
Rs2 = (inst & 0x001F0000) >> 16;
Rs1Sel = (inst & 0x0000E000) >> 13;
Rs1 = (inst & 0x00001F00) >> 8;
Imm = (inst & 0x001F0000) >> 16;
BrOff = ((inst & 0x06000000) >> 17) | (inst & 0x000000FF);
if (BrOff & 0x0200) BrOff |= 0xFC00;
if (IO) {
sprintf(str, "QB%s %d, R%u%s, %u", f5_inst[Test], BrOff, Rs1, sis[Rs1Sel], Imm);
} else {
sprintf(str, "QB%s %d, R%u%s, R%u%s", f5_inst[Test], BrOff, Rs1, sis[Rs1Sel], Rs2, sis[Rs2Sel]);
}
break;
case 4:
case 7: // Format 6 - LBBO/SBBO/LBCO/SBCO instructions
LoadStore = (inst & 0x10000000) >> 28;
BurstLen = ((inst & 0x0E000000) >> 21) | ((inst & 0x0000E000) >> 12) | ((inst & 0x00000080) >> 7);
IO = (inst & 0x01000000) >> 24;
RxByteAddr = (inst & 0x00000060) >> 5;
Rx = (inst & 0x0000001F);
RoSel = (inst & 0x00E00000) >> 21;
Ro = (inst & 0x001F0000) >> 16;
Rb = (inst & 0x00001F00) >> 8;
Imm = (inst & 0x00FF0000) >> 16;
GetBurstLen(tempstr, BurstLen);
if (OP == 7) {
if (IO) {
sprintf(str, "%s R%u%s, R%u, %u, %s", f6_7_inst[LoadStore], Rx, bytenum[RxByteAddr], Rb, Imm, tempstr);
} else {
sprintf(str, "%s R%u%s, R%u, R%u%s, %s", f6_7_inst[LoadStore], Rx, bytenum[RxByteAddr], Rb, Ro, sis[RoSel], tempstr);
}
} else { // OP==4
if (IO) {
sprintf(str, "%s R%u%s, C%u, %u, %s", f6_4_inst[LoadStore], Rx, bytenum[RxByteAddr], Rb, Imm, tempstr);
} else {
sprintf(str, "%s R%u%s, C%u, R%u%s, %s", f6_4_inst[LoadStore], Rx, bytenum[RxByteAddr], Rb, Ro, sis[RoSel], tempstr);
}
}
break;
default:
sprintf(str, "UNKNOWN");
break;
}
}