assembler: Add support for raw output format
authorMichael Buesch <mb@bu3sch.de>
Sun, 19 Sep 2010 15:42:39 +0000 (17:42 +0200)
committerMichael Buesch <mb@bu3sch.de>
Sun, 19 Sep 2010 15:42:39 +0000 (17:42 +0200)
Signed-off-by: Michael Buesch <mb@bu3sch.de>
assembler/args.c
assembler/args.h
assembler/main.c
assembler/main.h
disassembler/args.c

index b2a8ddf1dd7df94eca42c86921eeee8123c687c9..42d9c1809fca8b3658aed31264e34771174eaed7 100644 (file)
@@ -26,6 +26,7 @@ int _debug;
 bool arg_print_sizes;
 const char *initvals_fn_extension = ".initvals";
 static const char *real_infile_name;
+enum fwformat output_format = FMT_B43;
 
 
 #define ARG_MATCH              0
@@ -97,17 +98,20 @@ static int cmp_arg(char **argv, int *pos,
 static void usage(int argc, char **argv)
 {
        printf("Usage: %s INPUT_FILE OUTPUT_FILE [OPTIONS]\n", argv[0]);
-       printf("  -h|--help           Print this help\n");
+       printf("  -f|--format FMT     Output file format. FMT must be one of:\n");
+       printf("                      raw-le32, raw-be32, b43\n");
        printf("  -d|--debug          Print verbose debugging info\n");
        printf("                      Repeat for more verbose debugging\n");
        printf("  -s|--psize          Print the size of the code after assembling\n");
        printf("  -e|--ivalext EXT    Filename extension for the initvals\n");
+       printf("  -h|--help           Print this help\n");
 }
 
 int parse_args(int argc, char **argv)
 {
        int i;
        int res;
+       const char *param;
 
        if (argc < 3)
                goto out_usage;
@@ -118,6 +122,17 @@ int parse_args(int argc, char **argv)
                if ((res = cmp_arg(argv, &i, "--help", "-h", NULL)) == ARG_MATCH) {
                        usage(argc, argv);
                        return 1;
+               } else if ((res = cmp_arg(argv, &i, "--format", "-f", &param)) == ARG_MATCH) {
+                       if (strcasecmp(param, "raw-le32") == 0)
+                               output_format = FMT_RAW_LE32;
+                       else if (strcasecmp(param, "raw-be32") == 0)
+                               output_format = FMT_RAW_BE32;
+                       else if (strcasecmp(param, "b43") == 0)
+                               output_format = FMT_B43;
+                       else {
+                               fprintf(stderr, "Invalid -f|--format\n\n");
+                               goto out_usage;
+                       }
                } else if ((res = cmp_arg(argv, &i, "--debug", "-d", NULL)) == ARG_MATCH) {
                        _debug++;
                } else if ((res = cmp_arg(argv, &i, "--psize", "-s", NULL)) == ARG_MATCH) {
index 06f8ca3171a3be75f43f2417cd4c4e6a64001100..fc3abc1b46947174dede81da0928166e1271c3d6 100644 (file)
@@ -4,6 +4,12 @@
 #include "util.h"
 
 
+enum fwformat {
+       FMT_RAW_LE32,   /* Raw microcode. No headers. 32bit little endian chunks. */
+       FMT_RAW_BE32,   /* Raw microcode. No headers. 32bit big endian chunks. */
+       FMT_B43,        /* b43/b43legacy headers. */
+};
+
 int parse_args(int argc, char **argv);
 int open_input_file(void);
 void close_input_file(void);
@@ -11,6 +17,7 @@ void close_input_file(void);
 extern int _debug;
 extern bool arg_print_sizes;
 extern const char *initvals_fn_extension;
+extern enum fwformat output_format;
 
 #define IS_DEBUG               (_debug > 0)
 #define IS_VERBOSE_DEBUG       (_debug > 1)
index 309d7c5fed1f95536345efe4f26354d70b97eeb0..6b294a4c46d5ddf825a9924fadbe815d04dea500 100644 (file)
@@ -1048,7 +1048,7 @@ static void emit_code(struct assembler_context *ctx)
        struct code_output *c;
        uint64_t code;
        unsigned char outbuf[8];
-       unsigned int insn_count = 0;
+       unsigned int insn_count = 0, insn_count_limit;
        struct fw_header hdr;
 
        fn = outfile_name;
@@ -1070,19 +1070,37 @@ static void emit_code(struct assembler_context *ctx)
                }
        }
 
-       memset(&hdr, 0, sizeof(hdr));
-       hdr.type = FW_TYPE_UCODE;
-       hdr.ver = FW_HDR_VER;
-       hdr.size = cpu_to_be32(8 * insn_count);
-       if (fwrite(&hdr, sizeof(hdr), 1, fd) != 1) {
-               fprintf(stderr, "Could not write microcode outfile\n");
-               exit(1);
+       switch (output_format) {
+       case FMT_RAW_LE32:
+       case FMT_RAW_BE32:
+               /* Nothing */
+               break;
+       case FMT_B43:
+               memset(&hdr, 0, sizeof(hdr));
+               hdr.type = FW_TYPE_UCODE;
+               hdr.ver = FW_HDR_VER;
+               hdr.size = cpu_to_be32(8 * insn_count);
+               if (fwrite(&hdr, sizeof(hdr), 1, fd) != 1) {
+                       fprintf(stderr, "Could not write microcode outfile\n");
+                       exit(1);
+               }
+               break;
        }
 
-       if (insn_count > NUM_INSN_LIMIT)
-               asm_warn(ctx, "Generating more than %d instructions. This "
+       switch (ctx->arch) {
+       case 5:
+               insn_count_limit = NUM_INSN_LIMIT_R5;
+               break;
+       case 15:
+               insn_count_limit = ~0; //FIXME limit currently unknown.
+               break;
+       default:
+               asm_error(ctx, "Internal error: emit_code unknown arch\n");
+       }
+       if (insn_count > insn_count_limit)
+               asm_warn(ctx, "Generating more than %u instructions. This "
                              "will overflow the device microcode memory.",
-                        NUM_INSN_LIMIT);
+                        insn_count_limit);
 
        list_for_each_entry(c, &ctx->output, list) {
                switch (c->type) {
@@ -1094,41 +1112,52 @@ static void emit_code(struct assembler_context *ctx)
                                        c->operands[1].u.operand,
                                        c->operands[2].u.operand);
                        }
-                       code = 0;
-
-                       if (ctx->arch == 5) {
-                               /* Instruction binary format is: xxyyyzzz0000oooX
-                                *                        byte-0-^       byte-7-^
-                                * ooo is the opcode
-                                * Xxx is the first operand
-                                * yyy is the second operand
-                                * zzz is the third operand
-                                */
+
+                       switch (ctx->arch) {
+                       case 5:
+                               code = 0;
                                code |= ((uint64_t)c->operands[2].u.operand);
                                code |= ((uint64_t)c->operands[1].u.operand) << 12;
                                code |= ((uint64_t)c->operands[0].u.operand) << 24;
                                code |= ((uint64_t)c->opcode) << 36;
-                               code = ((code & (uint64_t)0xFFFFFFFF00000000ULL) >> 32) |
-                                      ((code & (uint64_t)0x00000000FFFFFFFFULL) << 32);
-                       } else if (ctx->arch == 15) {
+                               break;
+                       case 15:
+                               code = 0;
                                code |= ((uint64_t)c->operands[2].u.operand);
                                code |= ((uint64_t)c->operands[1].u.operand) << 13;
                                code |= ((uint64_t)c->operands[0].u.operand) << 26;
                                code |= ((uint64_t)c->opcode) << 39;
-                               code = ((code & (uint64_t)0xFFFFFFFF00000000ULL) >> 32) |
-                                      ((code & (uint64_t)0x00000000FFFFFFFFULL) << 32);
-                       } else {
+                               break;
+                       default:
                                asm_error(ctx, "No emit format for arch %u",
                                          ctx->arch);
                        }
-                       outbuf[0] = (code & (uint64_t)0xFF00000000000000ULL) >> 56;
-                       outbuf[1] = (code & (uint64_t)0x00FF000000000000ULL) >> 48;
-                       outbuf[2] = (code & (uint64_t)0x0000FF0000000000ULL) >> 40;
-                       outbuf[3] = (code & (uint64_t)0x000000FF00000000ULL) >> 32;
-                       outbuf[4] = (code & (uint64_t)0x00000000FF000000ULL) >> 24;
-                       outbuf[5] = (code & (uint64_t)0x0000000000FF0000ULL) >> 16;
-                       outbuf[6] = (code & (uint64_t)0x000000000000FF00ULL) >> 8;
-                       outbuf[7] = (code & (uint64_t)0x00000000000000FFULL) >> 0;
+
+                       switch (output_format) {
+                       case FMT_B43:
+                       case FMT_RAW_BE32:
+                               code = ((code & (uint64_t)0xFFFFFFFF00000000ULL) >> 32) |
+                                      ((code & (uint64_t)0x00000000FFFFFFFFULL) << 32);
+                               outbuf[0] = (code & (uint64_t)0xFF00000000000000ULL) >> 56;
+                               outbuf[1] = (code & (uint64_t)0x00FF000000000000ULL) >> 48;
+                               outbuf[2] = (code & (uint64_t)0x0000FF0000000000ULL) >> 40;
+                               outbuf[3] = (code & (uint64_t)0x000000FF00000000ULL) >> 32;
+                               outbuf[4] = (code & (uint64_t)0x00000000FF000000ULL) >> 24;
+                               outbuf[5] = (code & (uint64_t)0x0000000000FF0000ULL) >> 16;
+                               outbuf[6] = (code & (uint64_t)0x000000000000FF00ULL) >> 8;
+                               outbuf[7] = (code & (uint64_t)0x00000000000000FFULL) >> 0;
+                               break;
+                       case FMT_RAW_LE32:
+                               outbuf[7] = (code & (uint64_t)0xFF00000000000000ULL) >> 56;
+                               outbuf[6] = (code & (uint64_t)0x00FF000000000000ULL) >> 48;
+                               outbuf[5] = (code & (uint64_t)0x0000FF0000000000ULL) >> 40;
+                               outbuf[4] = (code & (uint64_t)0x000000FF00000000ULL) >> 32;
+                               outbuf[3] = (code & (uint64_t)0x00000000FF000000ULL) >> 24;
+                               outbuf[2] = (code & (uint64_t)0x0000000000FF0000ULL) >> 16;
+                               outbuf[1] = (code & (uint64_t)0x000000000000FF00ULL) >> 8;
+                               outbuf[0] = (code & (uint64_t)0x00000000000000FFULL) >> 0;
+                               break;
+                       }
 
                        if (fwrite(&outbuf, ARRAY_SIZE(outbuf), 1, fd) != 1) {
                                fprintf(stderr, "Could not write microcode outfile\n");
index e325f032276e82b91a91d8bfd68823433ac5bf3b..f5c22342c4dba1d71404f7750e9d2ac3dc49064e 100644 (file)
@@ -30,7 +30,7 @@ struct fw_header {
 /* Maximum number of allowed instructions in the code output.
  * This is what device memory can hold at maximum.
  */
-#define NUM_INSN_LIMIT 4096
+#define NUM_INSN_LIMIT_R5      4096
 
 
 struct lineinfo {
index 3663c59f1aabb183bfed7cadb2baa0802ea69999..7fc2978296cf7ff1f9d6c6303c7c73ea694eee63 100644 (file)
@@ -100,7 +100,7 @@ static void usage(FILE *fd, int argc, char **argv)
 {
        fprintf(fd, "Usage: %s INPUT_FILE OUTPUT_FILE [OPTIONS]\n", argv[0]);
        fprintf(fd, "  -a|--arch ARCH      The architecture type of the input file (5 or 15)\n");
-       fprintf(fd, "  -f|--format FMT     Input file format. FMT may be one of:\n");
+       fprintf(fd, "  -f|--format FMT     Input file format. FMT must be one of:\n");
        fprintf(fd, "                      raw-le32, raw-be32, b43\n");
        fprintf(fd, "  --paddr             Print the code addresses\n");
        fprintf(fd, "  -d|--debug          Print verbose debugging info\n");