]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/tumbl.git/commitdiff
Add scripts and programs for firmware
authorMartin Meloun <meloumar@cmp.felk.cvut.cz>
Wed, 18 Sep 2013 14:17:52 +0000 (16:17 +0200)
committerMartin Meloun <meloumar@cmp.felk.cvut.cz>
Wed, 18 Sep 2013 14:17:52 +0000 (16:17 +0200)
utils/bin2mem.c [new file with mode: 0644]
utils/mb-dasm.cpp [new file with mode: 0644]
utils/tumbl.ld-script [new file with mode: 0644]

diff --git a/utils/bin2mem.c b/utils/bin2mem.c
new file mode 100644 (file)
index 0000000..5233ef8
--- /dev/null
@@ -0,0 +1,61 @@
+/* Converts bin file to mem file */
+
+#include <stdio.h>
+#include <string.h>
+
+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 (file)
index 0000000..d582a3e
--- /dev/null
@@ -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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+
+
+// 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 (file)
index 0000000..bbac023
--- /dev/null
@@ -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 = . ;
+}