From 761cbc9ffeb490a87e9e8fc49d7468c2a9c46c23 Mon Sep 17 00:00:00 2001 From: Martin Meloun Date: Wed, 18 Sep 2013 16:17:52 +0200 Subject: [PATCH] Add scripts and programs for firmware --- utils/bin2mem.c | 61 +++++++++ utils/mb-dasm.cpp | 299 ++++++++++++++++++++++++++++++++++++++++++ utils/tumbl.ld-script | 25 ++++ 3 files changed, 385 insertions(+) create mode 100644 utils/bin2mem.c create mode 100644 utils/mb-dasm.cpp create mode 100644 utils/tumbl.ld-script diff --git a/utils/bin2mem.c b/utils/bin2mem.c new file mode 100644 index 0000000..5233ef8 --- /dev/null +++ b/utils/bin2mem.c @@ -0,0 +1,61 @@ +/* Converts bin file to mem file */ + +#include +#include + +void print_help(char * name) +{ + fprintf(stderr, "%s converts a binary file into a mem-file\n", name); + fprintf(stderr, "Usage: %s INFILE OUTFILE\n", name); +} + +int main(int argc, char *argv[]) +{ + FILE *infile, *outfile; + int whi, wlo, bhi, blo; + unsigned int addr; + + if (argc != 3) + { + print_help(argv[0]); + return(1); + } + + infile = fopen(argv[1], "rb"); + if (!infile) + { + printf("Cannot open file %s\n", argv[1]); + return(1); + } + + outfile = fopen(argv[2], "w"); + if (!outfile) + { + printf("Cannot open file %s\n", argv[2]); + return(1); + } + + fprintf(outfile,"// memory data file (do not edit the following line - required for mem load use)\n" + "// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1\n"); + + addr = 0; + while ((whi = fgetc(infile)) != EOF) + { + fprintf(outfile,"@%x ", addr); + + if ((wlo = fgetc(infile)) == EOF) + break; + if ((bhi = fgetc(infile)) == EOF) + break; + if ((blo = fgetc(infile)) == EOF) + break; + + fprintf(outfile, "%.2x%.2x%.2x%.2x\n", whi,wlo,bhi,blo); + addr++; + } + + fclose(infile); + fclose(outfile); + + return 0; +} diff --git a/utils/mb-dasm.cpp b/utils/mb-dasm.cpp new file mode 100644 index 0000000..d582a3e --- /dev/null +++ b/utils/mb-dasm.cpp @@ -0,0 +1,299 @@ +/******************************************************************************* +* +* File: dasm.c +* Description: Disassembler for TUMBL binary code. +* Syntax: mb-dasm [binFilename] +* if no binFilename specified, defaults to imem.bin in local +* directory. +* +* Author: Huib Lincklaen Arriens +* Date: August 2010 +* +* Note: No checks, e.g. on inputfile being a multiple of 4 bytes +* +********************************************************************************/ + + +#include +#include +#include +#include +#include +#include + + +// TUMBL Opcodes to be handled explicitely +#define OP_CMP 0x05 + +#define OP_MUL 0x10 +#define OP_BS 0x11 +#define OP_IDIV 0x12 +#define OP_FSL 0x13 +#define OP_FP 0x16 +#define OP_MULI 0x18 +#define OP_BSI 0x19 +#define OP_FSLD 0x1B + +#define OP_SEXT 0x24 +#define OP_SPR 0x25 +#define OP_BR 0x26 // for br brd brld bra brad brald brk +#define OP_BRC 0x27 // for beq bne blt ble bgt bge +#define OP_IMM 0x2C +#define OP_RTBD 0x2D +#define OP_BRI 0x2E // for bri brid brlid brai braid +#define OP_BRCI 0x2F // for beqi bnei blti blei bgti bgei + + +using namespace std; + +static const int MAXMEM = 65536; + +static const char *opc_Tbl[] = + { "add ", "rsub ", "addc ", "rsubc ", "addk ", "x_cmp ", "addkc ", "rsubkc ", + "addi ", "rsubi ", "addic ", "rsubic ", "addik ", "rsubik ", "addikc ", "rsubikc ", + "mul ", "bs ", "idiv ", "FSLd ", "-- ", "-- ", "FPI ", "-- ", + "muli ", "bsi ", "-- ", "FSL ", "-- ", "-- ", "-- ", "-- ", + "or ", "and ", "xor ", "andn ", "sext ", "SPR ", "br ", "brc ", + "ori ", "andi ", "xori ", "andni ", "imm ", "rtbd ", "bri ", "brci ", + "lbu ", "lhu ", "lw ", "-- ", "sb ", "sh ", "sw ", "-- ", + "lbui ", "lhui ", "lwi ", "-- ", "sbi ", "shi ", "swi ", "-- " }; + +static const char *brc_Tbl[] = + { "beq", "bne", "blt", "ble", "bgt", "bge" }; + + +char s1str[80] = ""; +char s2str[25] = ""; +const char spc_str[17] = " "; +unsigned int imem[MAXMEM]; +unsigned int mem_size; + + +void print_Usage (char *cmd_name) +{ + fprintf( stderr, "Usage: %s [binFilename]\n", cmd_name); + fprintf( stderr, "where the optional binFilename references a binary (Little Endian) code file.\n"); + fprintf( stderr, "If not specified binFilename tries to read imem.bin in the local directory.\n"); +} + +void read_bin (char *binFilename, unsigned int *imem, unsigned int *mem_size) +{ + ifstream binFile( binFilename, ios::in | ios::binary ); + // the next type should be "char" because the iostream needs it like that .... + char bin_bytes[MAXMEM]; // 4 Bytes in a Word + int isize; + int i, j; + + cout << "Reading " << binFilename << " ..." << endl << endl; + if ( binFile.fail() ) {cout << "Cannot open " << binFilename << " ..." << endl; exit (1);} + // get length of file: + binFile.seekg (0, ios::end); + isize = binFile.tellg(); + if (isize > sizeof(bin_bytes)) { + cout << binFilename << " larger than " << MAXMEM/1024 << " kBytes (" + << MAXMEM/4096 << " kWords) ..." << endl << endl; + exit (1); + } + *mem_size = isize/4; + binFile.seekg (0, ios::beg); + // read data as a block: + binFile.read (bin_bytes, isize); + if ( binFile.fail() ) {cout << "Read error ..." << endl; exit (2);} + binFile.close(); + for (i = 0, j = 0; i < isize; i += 4, j++ ) { + // remember iostream only read signed chars ... + imem[j] = ((unsigned char)bin_bytes[i] << 24) + + ((unsigned char)bin_bytes[i+1] << 16) + + ((unsigned char)bin_bytes[i+2] << 8) + + (unsigned char)bin_bytes[i+3]; + } +} + +void disasm (unsigned int pci) +{ + unsigned int pcb, ins; + unsigned int opc; + unsigned int rd, ra, rb, imm; + int s_imm; + unsigned int s1len; + bool a, l, d, b; + bool xpand, valid_code; + + pcb = 4*pci; + ins = imem[pci]; + // decode the current instruction + opc = (ins >> 26) & 0x3F; + ra = (ins >> 16) & 0x1F; + rd = (ins >> 21) & 0x1F; + if (!(opc & 0x08)) { + rb = (ins >> 11) & 0x1F; + imm = ins & 0x07FF; // not really imm!! + sprintf (s2str, "r%d, r%d, r%d", rd, ra, rb); + } + else { + imm = ins & 0xFFFF; + // 32 bit extension of a 16 bit or an 8 bit number + s_imm = imm & 0x8000 ? 0xffff0000 | imm : imm; + sprintf (s2str, "r%d, r%d, 0x%0x", rd, ra, imm); + } + + if (ins == 0) + sprintf (s1str, "nop"); + else { + xpand = 1; + switch (opc) + { + case OP_BR: // BR / BRA / BRD / BRAD / BRLD / BRALD + if ((ra & 0x1F) == 0x0C) // BRK + { + printf ("BRK"); //// ?????? + } + l = ra & 0x04; + a = ra & 0x08; + d = ra & 0x10; + b = (ra & 0x1F) == 0x0C; + if (b) sprintf (s1str, "brk r%d, r%d", rd, rb); + else + if (!l) { + s1len = sprintf (s1str, "br%s%s", a ? "a" : "", d ? "d" : ""); + sprintf (s1str, "%s r%d", strncat(s1str," ",6-s1len), rb); + } else { + s1len = sprintf (s1str, "br%sl%s", a ? "a" : "", d ? "d" : ""); + sprintf (s1str, "%s r%d, r%d", strncat(s1str," ",6-s1len), rd, rb); + } + break; + case OP_BRC: + if ((rd & 0xf) <= 0x5) + sprintf (s1str, "%s%s r%d, 0x%x", brc_Tbl[rd & 0xf], rd & 0x10 ? "d" : " ", ra, rb); + else + sprintf (s1str, "brc (opcode 0x27) has some errors, please check\n"); + break; + case OP_BRI: // BRI / BRAI / BRID / BRAID / BRLID / BRAILD + if ((ra & 0x1F) == 0x0C) // BRK + printf ("BRK"); //// ?????? + l = ra & 0x04; + a = ra & 0x08; + d = ra & 0x10; + b = (ra & 0x1F) == 0x0C; + if (b) sprintf (s1str, "brki r%d, 0x%x", rd, imm); + else { + if (!l) { + s1len = sprintf (s1str, "bri%s%s", a ? "a" : "", d ? "d" : "" ); + s1len = sprintf (s1str, "%s %d", strncat(s1str," ",6-s1len), s_imm); + } else { + s1len = sprintf (s1str, "bri%sl%s", a ? "a" : "", d ? "d" : ""); + s1len = sprintf (s1str, "%s r%d, %d", strncat(s1str," ",6-s1len), rd, s_imm); + } + if (a) + sprintf (s1str, "%s// 0x%x", strncat(s1str,spc_str,25-s1len), imm); + else + sprintf (s1str, "%s// 0x%x", strncat(s1str,spc_str,25-s1len), pcb + s_imm); + } + break; + case OP_BRCI: + if ((rd & 0xf) <= 0x5) { + s1len = sprintf (s1str, "%si%s r%d, %d", brc_Tbl[rd & 0xf], rd & 0x10 ? "d" : " ", ra, s_imm); + sprintf (s1str, "%s// 0x%x", strncat(s1str,spc_str,25-s1len), pcb + s_imm); + } else + sprintf (s1str, "brci (opcode 0x2f) has some errors, please check\n"); + break; + case OP_BSI: + sprintf (s2str, "r%d, r%d, 0x%0x", rd, ra, imm & 0x1F); + // !! no break + case OP_BS: + if (imm & 0x400) // left shift + s1len = sprintf (s1str, "bsll%s %s", opc & 0x08 ? "i" : " ", s2str); + else + s1len = sprintf (s1str, "bsr%s%s %s", + imm & 0x200 ? "a" : "l", opc & 0x08 ? "i" : " ", s2str); + break; + case OP_CMP: // or RSUBK + if (imm & 1) + sprintf (s1str, "cmp%s %s", imm & 2 ? "u" : " ", s2str); + else + sprintf (s1str, "rsubk %s", s2str); + break; + case OP_FP: + sprintf (s1str, "Floating Point Instruction NOT IMPLEMENTED IN TUMBL"); + break; + case OP_FSL: + case OP_FSLD: + sprintf (s1str, "FSL Instruction NOT IMPLEMENTED IN TUMBL"); + break; + case OP_IDIV: + s1len = sprintf (s1str, "idiv%s %s", imm & 0x02 ? "u" : " ", s2str); + sprintf (s1str, "%s NOT IMPLEMENTED IN TUMBL", strncat(s1str,spc_str,25-s1len)); + break; + case OP_IMM: + sprintf (s1str, "imm 0x%04x // %d", imm, s_imm); + break; + case OP_MUL: + case OP_MULI: + s1len = sprintf (s1str, "%s%s", opc_Tbl[opc], s2str); + break; + case OP_RTBD: + valid_code = 1; + switch(rd) { + case 0x12: sprintf (s2str, "rtbd"); break; // RTBD + case 0x11: sprintf (s2str, "rtid"); break; // RTID + case 0x14: sprintf (s2str, "rted"); break; // RTED + case 0x10: sprintf (s2str, "rtsd"); break; // RTSD + default: + sprintf (s1str, "Illegal subopcode in OP_RTBD"); + valid_code = 0; + } + if (valid_code) + sprintf (s1str, "%s r%d, 0x%x", s2str, ra, imm); + break; + case OP_SEXT: + valid_code = 1; + switch (imm) { + case 0x61: sprintf (s2str, "sext16"); break; // SEXT16 + case 0x60: sprintf (s2str, "sext8 "); break; // SEXT8 + case 0x01: sprintf (s2str, "sra "); break; // SRA + case 0x21: sprintf (s2str, "src "); break; // SRC + case 0x41: sprintf (s2str, "srl "); break; // SRL + default : + sprintf (s1str, "OP_SEXT has some errors, please check" ); + valid_code = 0; + } + if (valid_code) + sprintf (s1str, "%s r%d, r%d", s2str, rd, ra); + break; + case OP_SPR: + sprintf (s1str, "SP-Reg Instruction NOT IMPLEMENTED IN TUMBL"); + break; + default: + xpand = 0; + } // switch (opc) + + if (!xpand) { + if (strncmp(opc_Tbl[opc],"--",2)) + sprintf (s1str, "%s%s", opc_Tbl[opc], s2str); + else + sprintf (s1str, "Unknown instruction / possibly data ?"); + } + } + printf ("%6x: %08x %s\n", pcb, ins, s1str); +} + + +int main(int argc, char *argv[]) +{ + char binFilename[132]; + + // note: strncmp == 0 if the parts of the strings are equal + if ((argc > 2) || ((argc == 2) && !strncmp(argv[1],"-",1))) { + print_Usage( argv[0]); + return (1); + } + + if (argc == 2) + sprintf( binFilename, argv[1]); + else + sprintf( binFilename, "imem.bin"); + read_bin (binFilename, imem, &mem_size); + for (int pci = 0; pci < mem_size; pci++) + disasm (pci); +} + diff --git a/utils/tumbl.ld-script b/utils/tumbl.ld-script new file mode 100644 index 0000000..bbac023 --- /dev/null +++ b/utils/tumbl.ld-script @@ -0,0 +1,25 @@ +/* LD script for Tumbl coprocessor */ + +ENTRY(_main) + +MEMORY +{ + imem (x) : ORIGIN = 0x00000050, LENGTH = 2k + dmem (ar!x) : ORIGIN = 0x00000000, LENGTH = 4k +} + +SECTIONS +{ + . = 0x00000000; + . = ALIGN(4); + .text : { *(.text) *(.text.*) } > imem + + . = 0x00000000; + . = ALIGN(4); + _sdata = . ; + .data : { *(.data) *(.data.*) } > dmem + + . = ALIGN(4); + .bss : { *(.bss) *(.bss.*) } > dmem + _edata = . ; +} -- 2.39.2