From 2cb9ee566f035acad146dc2c3c0b2de675469f02 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Thu, 26 Nov 2009 15:22:55 +0100 Subject: [PATCH 01/16] fwcutter: Add sparse support, Add quiet build, Add autodependencies Signed-off-by: Michael Buesch --- fwcutter/Makefile | 63 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 17 deletions(-) diff --git a/fwcutter/Makefile b/fwcutter/Makefile index 2eb2e84..197ddef 100644 --- a/fwcutter/Makefile +++ b/fwcutter/Makefile @@ -1,34 +1,63 @@ VERSION = 012 -CC ?= cc -PREFIX ?= /usr/local -CFLAGS ?= -Os -fomit-frame-pointer -CFLAGS += -std=c99 -Wall -pedantic -D_BSD_SOURCE -LDFLAGS ?= +# The toolchain definitions +CC = cc +SPARSE = sparse + +V = @ # Verbose build: make V=1 +C = 0 # Sparsechecker build: make C=1 +Q = $(V:1=) +QUIET_CC = $(Q:@=@echo ' CC '$@;)$(CC) +QUIET_DEPEND = $(Q:@=@echo ' DEPEND '$@;)$(CC) +ifeq ($(C),1) +QUIET_SPARSE = $(Q:@=@echo ' SPARSE '$@;)$(SPARSE) +else +QUIET_SPARSE = @/bin/true +endif +PREFIX ?= /usr/local +CFLAGS ?= -Os -fomit-frame-pointer +CFLAGS += -std=c99 -Wall -pedantic -D_BSD_SOURCE +LDFLAGS ?= -OBJECTS = fwcutter.o md5.o +SRCS = fwcutter.c md5.c BIN = b43-fwcutter CFLAGS += -DFWCUTTER_VERSION_=$(VERSION) -all: $(BIN) +.SUFFIXES: +.PHONY: all install clean distclean +.DEFAULT_GOAL := all + +DEPS = $(sort $(patsubst %.c,dep/%.d,$(1))) +OBJS = $(sort $(patsubst %.c,obj/%.o,$(1))) -fwcutter.o: fwcutter.h fwcutter_list.h md5.h +# Generate dependencies +$(call DEPS,$(SRCS)): dep/%.d: %.c + @mkdir -p $(dir $@) + $(QUIET_DEPEND) -o $@.tmp -MM -MG -MT "$@ $(patsubst dep/%.d,obj/%.o,$@)" $(CFLAGS) $< && mv -f $@.tmp $@ -md5.o: md5.h +-include $(call DEPS,$(SRCS)) + +# Generate object files +$(call OBJS,$(SRCS)): obj/%.o: + @mkdir -p $(dir $@) + $(QUIET_SPARSE) $(SPARSEFLAGS) $< + $(QUIET_CC) -o $@ -c $(CFLAGS) $< + +all: $(BIN) -$(BIN): $(OBJECTS) - $(CC) $(CFLAGS) -o $(BIN) $(OBJECTS) $(LDFLAGS) +$(BIN): $(call OBJS,$(SRCS)) + $(QUIET_CC) $(CFLAGS) -o $(BIN) $(call OBJS,$(SRCS)) $(LDFLAGS) install: all - -install -d -o 0 -g 0 -m 755 $(PREFIX)/bin/ - -install -o 0 -g 0 -m 755 $(BIN) $(PREFIX)/bin/ - -install -d -o 0 -g 0 -m 755 $(PREFIX)/man/man1/ - -install -o 0 -g 0 -m 644 $(BIN).1 $(PREFIX)/man/man1/ + install -d -o 0 -g 0 -m 755 $(PREFIX)/bin/ + install -o 0 -g 0 -m 755 $(BIN) $(PREFIX)/bin/ + install -d -o 0 -g 0 -m 755 $(PREFIX)/man/man1/ + install -o 0 -g 0 -m 644 $(BIN).1 $(PREFIX)/man/man1/ clean: - -rm -f *.o $(BIN) + -rm -Rf obj dep *.orig *.rej *~ distclean: clean - -rm -f *.fw *.orig *.rej *~ + -rm -f *.fw $(BIN) -- 2.31.1 From 883671d1a412bb7fb9d2b112f63a3fe10d02e726 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Thu, 26 Nov 2009 15:28:21 +0100 Subject: [PATCH 02/16] ssb_sprom: Add sparse support, Add quiet build, Add autodependencies Signed-off-by: Michael Buesch --- ssb_sprom/Makefile | 59 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 13 deletions(-) diff --git a/ssb_sprom/Makefile b/ssb_sprom/Makefile index eb0eac0..01efc0e 100644 --- a/ssb_sprom/Makefile +++ b/ssb_sprom/Makefile @@ -1,22 +1,55 @@ -CC = cc -PREFIX = /usr/local -CFLAGS = -std=c99 -O2 -fomit-frame-pointer -Wall -D_BSD_SOURCE -LDFLAGS = +# The toolchain definitions +CC = cc +SPARSE = sparse +V = @ # Verbose build: make V=1 +C = 0 # Sparsechecker build: make C=1 +Q = $(V:1=) +QUIET_CC = $(Q:@=@echo ' CC '$@;)$(CC) +QUIET_DEPEND = $(Q:@=@echo ' DEPEND '$@;)$(CC) +ifeq ($(C),1) +QUIET_SPARSE = $(Q:@=@echo ' SPARSE '$@;)$(SPARSE) +else +QUIET_SPARSE = @/bin/true +endif -OBJECTS = ssb_sprom.o utils.o +PREFIX ?= /usr/local +CFLAGS += -std=c99 -O2 -fomit-frame-pointer -Wall -D_BSD_SOURCE +LDFLAGS ?= -all: ssb_sprom +SRCS = ssb_sprom.c utils.c +BIN = ssb_sprom -ssb_sprom: $(OBJECTS) - $(CC) $(CFLAGS) -o ssb-sprom $(OBJECTS) $(LDFLAGS) +.SUFFIXES: +.PHONY: all install clean distclean +.DEFAULT_GOAL := all + +DEPS = $(sort $(patsubst %.c,dep/%.d,$(1))) +OBJS = $(sort $(patsubst %.c,obj/%.o,$(1))) + +# Generate dependencies +$(call DEPS,$(SRCS)): dep/%.d: %.c + @mkdir -p $(dir $@) + $(QUIET_DEPEND) -o $@.tmp -MM -MG -MT "$@ $(patsubst dep/%.d,obj/%.o,$@)" $(CFLAGS) $< && mv -f $@.tmp $@ + +-include $(call DEPS,$(SRCS)) + +# Generate object files +$(call OBJS,$(SRCS)): obj/%.o: + @mkdir -p $(dir $@) + $(QUIET_SPARSE) $(SPARSEFLAGS) $< + $(QUIET_CC) -o $@ -c $(CFLAGS) $< + +all: $(BIN) + +$(BIN): $(call OBJS,$(SRCS)) + $(QUIET_CC) $(CFLAGS) -o $(BIN) $(call OBJS,$(SRCS)) $(LDFLAGS) install: all - -install -o 0 -g 0 -m 755 ssb-sprom $(PREFIX)/bin/ + install -o 0 -g 0 -m 755 $(BIN) $(PREFIX)/bin/ clean: - -rm -f *~ *.o *.orig *.rej ssb-sprom + -rm -Rf obj dep *~ *.orig *.rej -# dependencies -ssb_sprom.o: ssb_sprom.h utils.h -utils.o: utils.h ssb_sprom.h +distclean: clean + -rm -f $(BIN) -- 2.31.1 From 006b58e7e80ec68d5b7720aaec5f127455c9f5fc Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Thu, 26 Nov 2009 15:30:36 +0100 Subject: [PATCH 03/16] ssb_sprom: Fix sparse warnings Signed-off-by: Michael Buesch --- ssb_sprom/ssb_sprom.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ssb_sprom/ssb_sprom.c b/ssb_sprom/ssb_sprom.c index 5c1585e..25236dc 100644 --- a/ssb_sprom/ssb_sprom.c +++ b/ssb_sprom/ssb_sprom.c @@ -33,8 +33,8 @@ struct cmdline_args cmdargs; -uint8_t sprom_rev; -uint16_t sprom_size; +static uint8_t sprom_rev; +static uint16_t sprom_size; /* SPROM layouts are described by the following table. The entries are as follows: * @@ -804,7 +804,7 @@ static int do_cmp_arg(char **argv, int *pos, } if (strcmp(arg, template) == 0) { if (param) { - if (*param == 0) { + if (*param == NULL) { prerror("%s needs a parameter\n", arg); return ARG_ERROR; } @@ -1081,20 +1081,20 @@ static int parse_args(int argc, char *argv[], int pass) return -1; } - if (arg_match(argv, &i, "--version", "-v", 0)) { + if (arg_match(argv, &i, "--version", "-v", NULL)) { print_banner(1); return 1; - } else if (arg_match(argv, &i, "--help", "-h", 0)) { + } else if (arg_match(argv, &i, "--help", "-h", NULL)) { goto out_usage; } else if (arg_match(argv, &i, "--input", "-i", ¶m)) { cmdargs.infile = param; } else if (arg_match(argv, &i, "--output", "-o", ¶m)) { cmdargs.outfile = param; - } else if (arg_match(argv, &i, "--verbose", "-V", 0)) { + } else if (arg_match(argv, &i, "--verbose", "-V", NULL)) { cmdargs.verbose = 1; - } else if (arg_match(argv, &i, "--force", "-n", 0)) { + } else if (arg_match(argv, &i, "--force", "-n", NULL)) { cmdargs.force = 1; - } else if (arg_match(argv, &i, "--binmode", "-b", 0)) { + } else if (arg_match(argv, &i, "--binmode", "-b", NULL)) { cmdargs.bin_mode = 1; } else if (pass == 2 && arg_match(argv, &i, "--rawset", "-s", ¶m)) { vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]); @@ -1107,7 +1107,7 @@ static int parse_args(int argc, char *argv[], int pass) if (err < 0) goto error; - } else if (pass == 2 && arg_match(argv, &i, "--print-all", "-P", 0)) { + } else if (pass == 2 && arg_match(argv, &i, "--print-all", "-P", NULL)) { err = generate_printall(); if (err) goto error; -- 2.31.1 From 5a082479780cc0ce68c1a1b8709b30a092461e4c Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Thu, 26 Nov 2009 15:38:38 +0100 Subject: [PATCH 04/16] ssb_sprom: Fix binary name Signed-off-by: Michael Buesch --- ssb_sprom/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ssb_sprom/Makefile b/ssb_sprom/Makefile index 01efc0e..21f70eb 100644 --- a/ssb_sprom/Makefile +++ b/ssb_sprom/Makefile @@ -18,7 +18,7 @@ CFLAGS += -std=c99 -O2 -fomit-frame-pointer -Wall -D_BSD_SOURCE LDFLAGS ?= SRCS = ssb_sprom.c utils.c -BIN = ssb_sprom +BIN = ssb-sprom .SUFFIXES: .PHONY: all install clean distclean -- 2.31.1 From 4f612e99fb89379b35bc831bfbe244398e4eead4 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Mon, 19 Apr 2010 17:39:27 +0200 Subject: [PATCH 05/16] Bump fwcutter version Signed-off-by: Michael Buesch --- fwcutter/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fwcutter/Makefile b/fwcutter/Makefile index 197ddef..bdf7302 100644 --- a/fwcutter/Makefile +++ b/fwcutter/Makefile @@ -1,4 +1,4 @@ -VERSION = 012 +VERSION = 013 # The toolchain definitions CC = cc -- 2.31.1 From 762043b61e46c1b4d61d18931c702b77bcc86067 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Mon, 19 Apr 2010 17:48:59 +0200 Subject: [PATCH 06/16] Update release script Signed-off-by: Michael Buesch --- fwcutter/makerelease.sh | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/fwcutter/makerelease.sh b/fwcutter/makerelease.sh index bcb74e0..5760708 100755 --- a/fwcutter/makerelease.sh +++ b/fwcutter/makerelease.sh @@ -3,42 +3,51 @@ set -e project="b43-fwcutter" +origin="$(dirname "$0")" +[ "${origin:0:1}" = "/" ] || origin="$PWD/$origin" + +do_git_tag=1 +[ "$1" = "--notag" ] && do_git_tag=0 -origin="$(pwd)" version="$(cat $origin/Makefile | grep -e VERSION | head -n1 | cut -d' ' -f3)" if [ -z "$version" ]; then echo "Could not determine version!" exit 1 fi +tmpdir="/tmp" release_name="$project-$version" tarball="$release_name.tar.bz2" export GIT_DIR="$origin/../.git" -cd /tmp/ -rm -Rf "$release_name" +rm -Rf "$tmpdir/$release_name" echo "Creating target directory" -mkdir "$release_name" -cd "$release_name" +mkdir -p "$tmpdir/$release_name" +cd "$tmpdir/$release_name" echo "git checkout" git checkout -f mv fwcutter $release_name -cd $release_name +targetdir="$tmpdir/$release_name/$release_name" -rm makerelease.sh +rm "$targetdir/makerelease.sh" echo "creating tarball" -cd .. +cd "$targetdir/.." tar cjf "$tarball" "$release_name" mv "$tarball" "$origin" echo "running testbuild" -cd "$release_name" +cd "$targetdir" make echo "removing testbuild" -cd ../.. -rm -R "$release_name" +rm -R "$tmpdir/$release_name" + +if [ "$do_git_tag" -ne 0 ]; then + echo "Tagging GIT" + cd "$origin" + git tag -m "$tagmsg" -a "$tagname" +fi echo echo "built release $version" -- 2.31.1 From dba264e4bc39ade0608c507fa0ca29f969986c3b Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Mon, 19 Apr 2010 17:50:59 +0200 Subject: [PATCH 07/16] fwcutter: Fix release script tagging Signed-off-by: Michael Buesch --- fwcutter/makerelease.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fwcutter/makerelease.sh b/fwcutter/makerelease.sh index 5760708..2c25a86 100755 --- a/fwcutter/makerelease.sh +++ b/fwcutter/makerelease.sh @@ -17,6 +17,8 @@ fi tmpdir="/tmp" release_name="$project-$version" tarball="$release_name.tar.bz2" +tagname="$project-$version-release" +tagmsg="$project-$version release" export GIT_DIR="$origin/../.git" -- 2.31.1 From a73ba526c3bd9f4e95cc95808d7487607c651cd0 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Mon, 19 Apr 2010 18:17:55 +0200 Subject: [PATCH 08/16] b43-fwcutter: Fix compiler warnings "Type punned pointer blah blah..." Just call the "from_..." functions from the "to_..." functions. They also work backwards. Signed-off-by: Michael Buesch --- fwcutter/fwcutter.c | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/fwcutter/fwcutter.c b/fwcutter/fwcutter.c index 0d82806..79e351f 100644 --- a/fwcutter/fwcutter.c +++ b/fwcutter/fwcutter.c @@ -65,18 +65,6 @@ static int file_ok(const struct file *f) return !(f->flags & FW_FLAG_UNSUPPORTED) || cmdargs.unsupported; } -/* Convert a CPU-endian 16bit integer to Big-Endian */ -static be16_t to_be16(uint16_t v) -{ - uint8_t ret[2]; - - ret[0] = (v & 0xFF00) >> 8; - ret[1] = (v & 0x00FF); - - return *((be16_t *)ret); -} - -#if 0 /* Convert a Big-Endian 16bit integer to CPU-endian */ static uint16_t from_be16(be16_t v) { @@ -87,19 +75,11 @@ static uint16_t from_be16(be16_t v) return ret; } -#endif -/* Convert a CPU-endian 32bit integer to Big-Endian */ -static be32_t to_be32(uint32_t v) +/* Convert a CPU-endian 16bit integer to Big-Endian */ +static be16_t to_be16(uint16_t v) { - uint8_t ret[4]; - - ret[0] = (v & 0xFF000000) >> 24; - ret[1] = (v & 0x00FF0000) >> 16; - ret[2] = (v & 0x0000FF00) >> 8; - ret[3] = (v & 0x000000FF); - - return *((be32_t *)ret); + return (be16_t)from_be16((be16_t)v); } /* Convert a Big-Endian 32bit integer to CPU-endian */ @@ -115,6 +95,12 @@ static uint32_t from_be32(be32_t v) return ret; } +/* Convert a CPU-endian 32bit integer to Big-Endian */ +static be32_t to_be32(uint32_t v) +{ + return (be32_t)from_be32((be32_t)v); +} + /* tiny disassembler */ static void print_ucode_version(struct insn *insn) { -- 2.31.1 From 6d2b4e5f11ac4194bdf4d53c47006b88060ebfb8 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Mon, 26 Jul 2010 20:15:25 +0200 Subject: [PATCH 09/16] b43-fwcutter: add COPYING file Signed-off-by: Michael Buesch --- fwcutter/COPYING | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 fwcutter/COPYING diff --git a/fwcutter/COPYING b/fwcutter/COPYING new file mode 100644 index 0000000..0085efb --- /dev/null +++ b/fwcutter/COPYING @@ -0,0 +1,26 @@ +Unless otherwise indicated, the following notice applies to all +files in the "b43-fwcutter" package: + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- 2.31.1 From 58f016da560c96ca5ef4b344952dc8cd73dece5c Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Sat, 7 Aug 2010 12:19:48 +0200 Subject: [PATCH 10/16] b43asm: Update README Signed-off-by: Michael Buesch --- assembler/README | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/assembler/README b/assembler/README index 6658803..c64ab01 100644 --- a/assembler/README +++ b/assembler/README @@ -18,7 +18,7 @@ subc | A,B,rD | Sub with Carry | rD=A-B-Carry subc. | A,B,rD | Sub with Carry, set Carry | rD=A-B-C SaveCarry Branch instructions: -jmp | l | Unconditional jump | PC=l +jmp | l | Uncond. jump (virtual instr.) | PC=l jand | A,B,l | Jump if binary AND | if(A&B) PC=l jnand | A,B,l | Jump if not binary AND | if(!(A&B)) PC=l js | A,B,l | Jump if all bits set | if((A&B)==A) PC=l @@ -41,7 +41,7 @@ jext | E,A,B,l | Jump if External Condition true | if(E) PC=l jnext | E,A,B,l | Jump if External Condition false| if(!E) PC=l Data transfer instructions: -mov | A,rD | Copy data | rD=A +mov | A,rD | Copy data (virtual instruction) | rD=A tkiph | A,rD | TKIP S-Box lookup high | rD=SBOX[hi8(A)] tkiphs | A,rD | TKIP S-Box lkup hi swap'd | rD=byteswap(tkiph) tkipl | A,rD | TKIP S-Box lookup low | rD=SBOX[lo8(A)] @@ -54,14 +54,14 @@ and | A,B,rD | Bitwise AND | rD=A&B xor | A,B,rD | Bitwise XOR | rD=A^B sr | A,B,rD | Rightshift | rD=A>>B sl | A,B,rD | Leftshift | rD=A< Date: Sun, 19 Sep 2010 16:56:34 +0200 Subject: [PATCH 11/16] Disassembler: Fixes for r15 architecture Signed-off-by: Michael Buesch --- disassembler/args.c | 38 ++++--- disassembler/args.h | 8 +- disassembler/main.c | 249 +++++++++++++++++++++++++++++++++----------- 3 files changed, 219 insertions(+), 76 deletions(-) diff --git a/disassembler/args.c b/disassembler/args.c index 67ba2fc..3663c59 100644 --- a/disassembler/args.c +++ b/disassembler/args.c @@ -26,7 +26,7 @@ int _debug; struct cmdline_args cmdargs = { .arch = 5, /* Default to v5 architecture. */ - .no_header = 0, /* Input file does not have a header. */ + .informat = FMT_B43, /* Input file format */ .print_addresses = 0, /* Print the code addresses in the output. */ }; @@ -96,15 +96,16 @@ static int cmp_arg(char **argv, int *pos, return err; } -static void usage(int argc, char **argv) +static void usage(FILE *fd, int argc, char **argv) { - fprintf(stderr, "Usage: %s INPUT_FILE OUTPUT_FILE [OPTIONS]\n", argv[0]); - fprintf(stderr, " -a|--arch ARCH The architecture type of the input file\n"); - fprintf(stderr, " -h|--help Print this help\n"); - fprintf(stderr, " --nohdr The input file does not have a header\n"); - fprintf(stderr, " --paddr Print the code addresses\n"); - fprintf(stderr, " -d|--debug Print verbose debugging info\n"); - fprintf(stderr, " Repeat for more verbose debugging\n"); + 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, " raw-le32, raw-be32, b43\n"); + fprintf(fd, " --paddr Print the code addresses\n"); + fprintf(fd, " -d|--debug Print verbose debugging info\n"); + fprintf(fd, " Repeat for more verbose debugging\n"); + fprintf(fd, " -h|--help Print this help\n"); } int parse_args(int argc, char **argv) @@ -118,10 +119,19 @@ int parse_args(int argc, char **argv) for (i = 1; i < argc; i++) { if ((res = cmp_arg(argv, &i, "--help", "-h", NULL)) == ARG_MATCH) { - usage(argc, argv); + usage(stdout, argc, argv); return 1; - } else if ((res = cmp_arg(argv, &i, "--nohdr", NULL, NULL)) == ARG_MATCH) { - cmdargs.no_header = 1; + } else if ((res = cmp_arg(argv, &i, "--format", "-f", ¶m)) == ARG_MATCH) { + if (strcasecmp(param, "raw-le32") == 0) + cmdargs.informat = FMT_RAW_LE32; + else if (strcasecmp(param, "raw-be32") == 0) + cmdargs.informat = FMT_RAW_BE32; + else if (strcasecmp(param, "b43") == 0) + cmdargs.informat = FMT_B43; + else { + fprintf(stderr, "Invalid -f|--format\n"); + return -1; + } } else if ((res = cmp_arg(argv, &i, "--paddr", NULL, NULL)) == ARG_MATCH) { cmdargs.print_addresses = 1; } else if ((res = cmp_arg(argv, &i, "--debug", "-d", NULL)) == ARG_MATCH) { @@ -131,7 +141,7 @@ int parse_args(int argc, char **argv) char *tail; arch = strtol(param, &tail, 0); - if (strlen(tail) || (arch != 5)) { + if (strlen(tail) || (arch != 5 && arch != 15)) { fprintf(stderr, "Unsupported architecture \"%s\"\n", param); return -1; @@ -155,7 +165,7 @@ int parse_args(int argc, char **argv) return 0; out_usage: - usage(argc, argv); + usage(stderr, argc, argv); return -1; } diff --git a/disassembler/args.h b/disassembler/args.h index 8dc69f2..0cb372c 100644 --- a/disassembler/args.h +++ b/disassembler/args.h @@ -1,9 +1,15 @@ #ifndef B43_DASM_ARGS_H_ #define B43_DASM_ARGS_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. */ +}; + struct cmdline_args { unsigned int arch; - int no_header; + enum fwformat informat; int print_addresses; }; diff --git a/disassembler/main.c b/disassembler/main.c index dbd2b5f..b3ba686 100644 --- a/disassembler/main.c +++ b/disassembler/main.c @@ -82,8 +82,8 @@ static const char * disasm_mem_operand(unsigned int operand) { char *ret; - ret = xmalloc(8); - snprintf(ret, 8, "[0x%03X]", operand); + ret = xmalloc(9); + snprintf(ret, 9, "[0x%X]", operand); return ret; } @@ -102,14 +102,29 @@ static const char * disasm_indirect_mem_operand(unsigned int operand) static const char * disasm_imm_operand(unsigned int operand) { char *ret; + unsigned int signmask; + unsigned int mask; + + switch (cmdargs.arch) { + case 5: + signmask = (1 << 9); + mask = 0x3FF; + break; + case 15: + signmask = (1 << 10); + mask = 0x7FF; + break; + default: + fprintf(stderr, "Internal error: disasm_imm_operand invalid arch\n"); + exit(1); + } - operand &= ~0xC00; + operand &= mask; ret = xmalloc(7); - if (operand & (1 << 9)) - snprintf(ret, 7, "0x%04X", (operand | 0xFC00)); - else - snprintf(ret, 7, "0x%03X", operand); + if (operand & signmask) + operand = (operand | (~mask & 0xFFFF)); + snprintf(ret, 7, "0x%X", operand); return ret; } @@ -117,9 +132,22 @@ static const char * disasm_imm_operand(unsigned int operand) static const char * disasm_spr_operand(unsigned int operand) { char *ret; + unsigned int mask; - ret = xmalloc(7); - snprintf(ret, 7, "spr%03X", (operand & 0x1FF)); + switch (cmdargs.arch) { + case 5: + mask = 0x1FF; + break; + case 15: + mask = 0x7FF; + break; + default: + fprintf(stderr, "Internal error: disasm_spr_operand invalid arch\n"); + exit(1); + } + + ret = xmalloc(8); + snprintf(ret, 8, "spr%X", (operand & mask)); return ret; } @@ -127,19 +155,22 @@ static const char * disasm_spr_operand(unsigned int operand) static const char * disasm_gpr_operand(unsigned int operand) { char *ret; + unsigned int mask; - ret = xmalloc(4); - snprintf(ret, 4, "r%u", (operand & 0x3F)); - - return ret; -} - -static const char * disasm_offr_operand(unsigned int operand) -{ - char *ret; + switch (cmdargs.arch) { + case 5: + mask = 0x3F; + break; + case 15: + mask = 0x7F; + break; + default: + fprintf(stderr, "Internal error: disasm_gpr_operand invalid arch\n"); + exit(1); + } ret = xmalloc(5); - snprintf(ret, 5, "off%u", (operand & 0x7)); + snprintf(ret, 5, "r%u", (operand & mask)); return ret; } @@ -154,24 +185,46 @@ static void disasm_std_operand(struct statement *stmt, if (forceraw) goto raw; - if (!(operand & 0x800)) { - stmt->u.insn.operands[out_idx] = disasm_mem_operand(operand); - return; - } else if ((operand & 0xC00) == 0xC00) { - stmt->u.insn.operands[out_idx] = disasm_imm_operand(operand); - return; - } else if ((operand & 0xFC0) == 0xBC0) { - stmt->u.insn.operands[out_idx] = disasm_gpr_operand(operand); - return; - } else if ((operand & 0xE00) == 0x800) { - stmt->u.insn.operands[out_idx] = disasm_spr_operand(operand); - return; - } else if ((operand & 0xFF8) == 0x860) { - stmt->u.insn.operands[out_idx] = disasm_offr_operand(operand); - return; - } else if ((operand & 0xE00) == 0xA00) { - stmt->u.insn.operands[out_idx] = disasm_indirect_mem_operand(operand); - return; + switch (cmdargs.arch) { + case 5: + if (!(operand & 0x800)) { + stmt->u.insn.operands[out_idx] = disasm_mem_operand(operand); + return; + } else if ((operand & 0xC00) == 0xC00) { + stmt->u.insn.operands[out_idx] = disasm_imm_operand(operand); + return; + } else if ((operand & 0xFC0) == 0xBC0) { + stmt->u.insn.operands[out_idx] = disasm_gpr_operand(operand); + return; + } else if ((operand & 0xE00) == 0x800) { + stmt->u.insn.operands[out_idx] = disasm_spr_operand(operand); + return; + } else if ((operand & 0xE00) == 0xA00) { + stmt->u.insn.operands[out_idx] = disasm_indirect_mem_operand(operand); + return; + } + break; + case 15: + if (!(operand & 0x1000)) { + stmt->u.insn.operands[out_idx] = disasm_mem_operand(operand); + return; + } else if ((operand & 0x1800) == 0x1800) { + stmt->u.insn.operands[out_idx] = disasm_imm_operand(operand); + return; + } else if ((operand & 0x1F80) == 0x1780) { + stmt->u.insn.operands[out_idx] = disasm_gpr_operand(operand); + return; + } else if ((operand & 0x1C00) == 0x1000) { + stmt->u.insn.operands[out_idx] = disasm_spr_operand(operand); + return; + } else if ((operand & 0x1C00) == 0x1400) { + stmt->u.insn.operands[out_idx] = disasm_indirect_mem_operand(operand); + return; + } + break; + default: + fprintf(stderr, "Internal error: disasm_std_operand invalid arch\n"); + exit(1); } raw: stmt->u.insn.operands[out_idx] = gen_raw_code(operand); @@ -386,8 +439,10 @@ static void disasm_constant_opcodes(struct disassembler_context *ctx, case 0x002: { char *str; + //FIXME: Broken for r15 stmt->u.insn.name = "call"; stmt->u.insn.is_labelref = 1; +//printf("CALL 0x%X 0x%X 0x%X\n", stmt->u.insn.bin->operands[0], stmt->u.insn.bin->operands[1], stmt->u.insn.bin->operands[2]); stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2]; str = xmalloc(4); snprintf(str, 4, "lr%u", stmt->u.insn.bin->operands[0]); @@ -407,10 +462,22 @@ static void disasm_constant_opcodes(struct disassembler_context *ctx, break; } case 0x1E0: { - unsigned int flags; + unsigned int flags, mask; + + switch (cmdargs.arch) { + case 5: + mask = 0x3FF; + break; + case 15: + mask = 0x7FF; + break; + default: + fprintf(stderr, "Internal error: TKIP invalid arch\n"); + exit(1); + } flags = stmt->u.insn.bin->operands[1]; - switch (flags & ~0xC00) { + switch (flags & mask) { case 0x1: stmt->u.insn.name = "tkiph"; break; @@ -433,17 +500,30 @@ static void disasm_constant_opcodes(struct disassembler_context *ctx, break; } case 0x001: { + unsigned int mask; + stmt->u.insn.name = "nap"; - if (stmt->u.insn.bin->operands[0] != 0xBC0) { - fprintf(stderr, "NAP: invalid first argument 0x%03X\n", + switch (cmdargs.arch) { + case 5: + mask = 0xBC0; + break; + case 15: + mask = 0x1780; + break; + default: + fprintf(stderr, "Internal error: NAP invalid arch\n"); + exit(1); + } + if (stmt->u.insn.bin->operands[0] != mask) { + fprintf(stderr, "NAP: invalid first argument 0x%04X\n", stmt->u.insn.bin->operands[0]); } - if (stmt->u.insn.bin->operands[1] != 0xBC0) { - fprintf(stderr, "NAP: invalid second argument 0x%03X\n", + if (stmt->u.insn.bin->operands[1] != mask) { + fprintf(stderr, "NAP: invalid second argument 0x%04X\n", stmt->u.insn.bin->operands[1]); } - if (stmt->u.insn.bin->operands[2] != 0x000) { - fprintf(stderr, "NAP: invalid third argument 0x%03X\n", + if (stmt->u.insn.bin->operands[2] != 0) { + fprintf(stderr, "NAP: invalid third argument 0x%04X\n", stmt->u.insn.bin->operands[2]); } break; @@ -693,7 +773,12 @@ static int read_input(struct disassembler_context *ctx) if (err) goto error; - if (!cmdargs.no_header) { + switch (cmdargs.informat) { + case FMT_RAW_LE32: + case FMT_RAW_BE32: + /* Nothing */ + break; + case FMT_B43: ret = fread(&hdr, 1, sizeof(hdr), infile); if (ret != sizeof(hdr)) { fprintf(stderr, "Corrupt input file (not fwcutter output)\n"); @@ -707,6 +792,7 @@ static int read_input(struct disassembler_context *ctx) fprintf(stderr, "Invalid input file header version.\n"); goto err_close; } + break; } while (1) { @@ -722,21 +808,62 @@ static int read_input(struct disassembler_context *ctx) goto err_free_code; } - codeword = 0; - codeword |= ((uint64_t)tmp[0]) << 56; - codeword |= ((uint64_t)tmp[1]) << 48; - codeword |= ((uint64_t)tmp[2]) << 40; - codeword |= ((uint64_t)tmp[3]) << 32; - codeword |= ((uint64_t)tmp[4]) << 24; - codeword |= ((uint64_t)tmp[5]) << 16; - codeword |= ((uint64_t)tmp[6]) << 8; - codeword |= ((uint64_t)tmp[7]); - - code[pos].opcode = (codeword >> 4) & 0xFFF; - code[pos].operands[0] = (codeword & 0xF) << 8; - code[pos].operands[0] |= (codeword >> 56) & 0xFF; - code[pos].operands[1] = (codeword >> 44) & 0xFFF; - code[pos].operands[2] = (codeword >> 32) & 0xFFF; + switch (cmdargs.informat) { + case FMT_B43: + case FMT_RAW_BE32: + codeword = 0; + codeword |= ((uint64_t)tmp[0]) << 56; + codeword |= ((uint64_t)tmp[1]) << 48; + codeword |= ((uint64_t)tmp[2]) << 40; + codeword |= ((uint64_t)tmp[3]) << 32; + codeword |= ((uint64_t)tmp[4]) << 24; + codeword |= ((uint64_t)tmp[5]) << 16; + codeword |= ((uint64_t)tmp[6]) << 8; + codeword |= ((uint64_t)tmp[7]); + codeword = ((codeword & (uint64_t)0xFFFFFFFF00000000ULL) >> 32) | + ((codeword & (uint64_t)0x00000000FFFFFFFFULL) << 32); + break; + case FMT_RAW_LE32: + codeword = 0; + codeword |= ((uint64_t)tmp[7]) << 56; + codeword |= ((uint64_t)tmp[6]) << 48; + codeword |= ((uint64_t)tmp[5]) << 40; + codeword |= ((uint64_t)tmp[4]) << 32; + codeword |= ((uint64_t)tmp[3]) << 24; + codeword |= ((uint64_t)tmp[2]) << 16; + codeword |= ((uint64_t)tmp[1]) << 8; + codeword |= ((uint64_t)tmp[0]); + break; + } + + switch (cmdargs.arch) { + case 5: + if (codeword >> 48) { + fprintf(stderr, "Instruction format error at 0x%X (upper not clear). " + "Wrong input format or architecture?\n", (unsigned int)pos); + goto err_free_code; + } + code[pos].opcode = (codeword >> 36) & 0xFFF; + code[pos].operands[2] = codeword & 0xFFF; + code[pos].operands[1] = (codeword >> 12) & 0xFFF; + code[pos].operands[0] = (codeword >> 24) & 0xFFF; + break; + case 15: + if (codeword >> 51) { + fprintf(stderr, "Instruction format error at 0x%X (upper not clear). " + "Wrong input format or architecture?\n", (unsigned int)pos); + goto err_free_code; + } + code[pos].opcode = (codeword >> 39) & 0xFFF; + code[pos].operands[2] = codeword & 0x1FFF; + code[pos].operands[1] = (codeword >> 13) & 0x1FFF; + code[pos].operands[0] = (codeword >> 26) & 0x1FFF; + break; + default: + fprintf(stderr, "Internal error: read_input unknown arch %u\n", + cmdargs.arch); + goto err_free_code; + } pos++; } -- 2.31.1 From cda7a69307d808c09e08806563d3fed050f2f4d4 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Sun, 19 Sep 2010 16:58:25 +0200 Subject: [PATCH 12/16] Add script for brcm80211 firmware conversion Signed-off-by: Michael Buesch --- disassembler/brcm80211conv | 194 +++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100755 disassembler/brcm80211conv diff --git a/disassembler/brcm80211conv b/disassembler/brcm80211conv new file mode 100755 index 0000000..0d2628b --- /dev/null +++ b/disassembler/brcm80211conv @@ -0,0 +1,194 @@ +#!/usr/bin/env python +""" +# Copyright (C) 2010 Michael Buesch +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 +# as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +""" + +import sys +import getopt + +def indexToName(index): + D11UCODE_NAMETAG_START = 0 + D11LCN0BSINITVALS24 = 1 + D11LCN0INITVALS24 = 2 + D11LCN1BSINITVALS24 = 3 + D11LCN1INITVALS24 = 4 + D11LCN2BSINITVALS24 = 5 + D11LCN2INITVALS24 = 6 + D11N0ABSINITVALS16 = 7 + D11N0BSINITVALS16 = 8 + D11N0INITVALS16 = 9 + D11UCODE_OVERSIGHT16_MIMO = 10 + D11UCODE_OVERSIGHT16_MIMOSZ = 11 + D11UCODE_OVERSIGHT24_LCN = 12 + D11UCODE_OVERSIGHT24_LCNSZ = 13 + D11UCODE_OVERSIGHT_BOMMAJOR = 14 + D11UCODE_OVERSIGHT_BOMMINOR = 15 + + namemap = { + D11UCODE_NAMETAG_START : "start", + D11LCN0BSINITVALS24 : "LCN0 bs initvals 24", + D11LCN0INITVALS24 : "LCN0 initvals 24", + D11LCN1BSINITVALS24 : "LCN1 bs initvals 24", + D11LCN1INITVALS24 : "LCN1 initvals 24", + D11LCN2BSINITVALS24 : "LCN2 bs initvals 24", + D11LCN2INITVALS24 : "LCN2 initvals 24", + D11N0ABSINITVALS16 : "N0A bs initvals 16", + D11N0BSINITVALS16 : "N0 bs initvals 16", + D11N0INITVALS16 : "N0 initvals 16", + D11UCODE_OVERSIGHT16_MIMO : "microcode 16 MIMO", + D11UCODE_OVERSIGHT16_MIMOSZ : "microcode 16 MIMO size", + D11UCODE_OVERSIGHT24_LCN : "microcode 24 LCN", + D11UCODE_OVERSIGHT24_LCNSZ : "microcode 24 LCN size", + D11UCODE_OVERSIGHT_BOMMAJOR : "bom major", + D11UCODE_OVERSIGHT_BOMMINOR : "bom minor", + } + try: + return namemap[index] + except KeyError: + return "Unknown" + +def parseHeader(hdr_data): + sections = [] + for i in range(0, len(hdr_data), 3 * 4): + offset = ord(hdr_data[i + 0]) | (ord(hdr_data[i + 1]) << 8) |\ + (ord(hdr_data[i + 2]) << 16) | (ord(hdr_data[i + 3]) << 24) + length = ord(hdr_data[i + 4]) | (ord(hdr_data[i + 5]) << 8) |\ + (ord(hdr_data[i + 6]) << 16) | (ord(hdr_data[i + 7]) << 24) + index = ord(hdr_data[i + 8]) | (ord(hdr_data[i + 9]) << 8) |\ + (ord(hdr_data[i + 10]) << 16) | (ord(hdr_data[i + 11]) << 24) + + sections.append( (offset, length, index) ) + sections.sort(key = lambda x: x[2]) # Sort by index + return sections + +def getSectionByIndex(sections, searchIndex): + for section in sections: + (offset, length, index) = section + if searchIndex == index: + return section + return None + +def parseHeaderFile(hdr_filepath): + try: + hdr_data = file(hdr_filepath, "rb").read() + except (IOError), e: + print "Failed to read header file: %s" % e.strerror + return None + if len(hdr_data) % (3 * 4) != 0: + print "Invalid header file format" + return None + return parseHeader(hdr_data) + +def dumpInfo(hdr_filepath): + sections = parseHeaderFile(hdr_filepath) + if not sections: + return 1 + for section in sections: + (offset, length, index) = section + print "Index %2d %24s ==> offset:0x%08X length:0x%08X" %\ + (index, indexToName(index), offset, length) + return 0 + +def extractSection(hdr_filepath, bin_filepath, extractIndex, outfile): + sections = parseHeaderFile(hdr_filepath) + if not sections: + return 1 + section = getSectionByIndex(sections, extractIndex) + if not section: + print "Did not find a section with index %d" % extractIndex + return 1 + (offset, length, index) = section + try: + bin_data = file(bin_filepath, "rb").read() + except (IOError), e: + print "Failed to read bin file: %s" % e.strerror + return 1 + try: + outfile.write(bin_data[offset : offset + length]) + except IndexError: + print "Binfile index error." + return 1 + return 0 + +def usage(): + print "BRCM80211 firmware converter tool" + print "" + print "Usage: %s [OPTIONS]" % sys.argv[0] + print "" + print " -H|--header FILE Use FILE as input header file" + print " -B|--bin FILE Use FILE as bin file" + print " -O|--outfile FILE Use FILE as output file. If not set, stdout is used." + print "" + print "Actions:" + print " -d|--dump Dump general information" + print " -x|--extract INDEX Extract the section with index INDEX" + print "" + print " -h|--help Print this help text" + +def main(): + opt_header = None + opt_bin = None + opt_action = None + opt_index = None + opt_outfile = sys.stdout + + try: + (opts, args) = getopt.getopt(sys.argv[1:], + "hH:B:O:dx:", + [ "help", "header=", "bin=", "outfile=", "dump", "extract=", ]) + except getopt.GetoptError: + usage() + return 1 + for (o, v) in opts: + if o in ("-h", "--help"): + usage() + return 0; + if o in ("-H", "--header"): + opt_header = v + if o in ("-B", "--bin"): + opt_bin = v + if o in ("-O", "--outfile"): + try: + opt_outfile = file(v, "wb") + except (IOError), e: + print "Failed to open output file: %s" % e.strerror + return 1 + if o in ("-d", "--dump"): + opt_action = "dump" + if o in ("-x", "--extract"): + opt_action = "extract" + try: + opt_index = int(v) + except ValueError: + print "Invalid -x|--extract index number\n" + usage() + return 1 + if not opt_action: + print "No action specified\n" + usage() + return 1 + if opt_action == "dump": + if not opt_header: + print "No header file specified\n" + usage() + return 1 + return dumpInfo(opt_header) + elif opt_action == "extract": + if not opt_header or not opt_bin: + print "No header or bin file specified\n" + usage() + return 1 + return extractSection(opt_header, opt_bin, opt_index, opt_outfile) + return 1 + +if __name__ == "__main__": + sys.exit(main()) -- 2.31.1 From 98eed13a9ea417aa2822c31dbcf277e0d6e0606d Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Sun, 19 Sep 2010 17:00:18 +0200 Subject: [PATCH 13/16] Install brcm80211fwconv Signed-off-by: Michael Buesch --- disassembler/Makefile | 5 +++-- disassembler/{brcm80211conv => brcm80211fwconv} | 0 2 files changed, 3 insertions(+), 2 deletions(-) rename disassembler/{brcm80211conv => brcm80211fwconv} (100%) diff --git a/disassembler/Makefile b/disassembler/Makefile index 8944a21..8c0554d 100644 --- a/disassembler/Makefile +++ b/disassembler/Makefile @@ -48,8 +48,9 @@ $(BIN): $(call OBJS,$(SRCS)) $(QUIET_CC) $(CFLAGS) -o $(BIN) $(call OBJS,$(SRCS)) $(LDFLAGS) install: all - install -o 0 -g 0 -m 755 $(BIN) $(PREFIX)/bin/ - install -o 0 -g 0 -m 755 b43-ivaldump $(PREFIX)/bin/ + install -m 755 $(BIN) $(PREFIX)/bin/ + install -m 755 b43-ivaldump $(PREFIX)/bin/ + install -m 755 brcm80211fwconv $(PREFIX)/bin/ clean: -rm -Rf obj dep *~ *.orig *.rej diff --git a/disassembler/brcm80211conv b/disassembler/brcm80211fwconv similarity index 100% rename from disassembler/brcm80211conv rename to disassembler/brcm80211fwconv -- 2.31.1 From 1c80842adfb1a722e33f3b8b9e0e13c65782d084 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Sun, 19 Sep 2010 17:08:12 +0200 Subject: [PATCH 14/16] Decode opcode 0x002 RAW on r15 for now. Signed-off-by: Michael Buesch --- disassembler/main.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/disassembler/main.c b/disassembler/main.c index b3ba686..e55a545 100644 --- a/disassembler/main.c +++ b/disassembler/main.c @@ -230,6 +230,15 @@ raw: stmt->u.insn.operands[out_idx] = gen_raw_code(operand); } +static void disasm_opcode_raw(struct disassembler_context *ctx, + struct statement *stmt) +{ + stmt->u.insn.name = gen_raw_code(stmt->u.insn.bin->opcode); + disasm_std_operand(stmt, 0, 0, 1); + disasm_std_operand(stmt, 1, 1, 1); + disasm_std_operand(stmt, 2, 2, 1); +} + static void disasm_constant_opcodes(struct disassembler_context *ctx, struct statement *stmt) { @@ -439,14 +448,20 @@ static void disasm_constant_opcodes(struct disassembler_context *ctx, case 0x002: { char *str; - //FIXME: Broken for r15 - stmt->u.insn.name = "call"; - stmt->u.insn.is_labelref = 1; -//printf("CALL 0x%X 0x%X 0x%X\n", stmt->u.insn.bin->operands[0], stmt->u.insn.bin->operands[1], stmt->u.insn.bin->operands[2]); - stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2]; - str = xmalloc(4); - snprintf(str, 4, "lr%u", stmt->u.insn.bin->operands[0]); - stmt->u.insn.operands[0] = str; + switch (cmdargs.arch) { + case 5: + stmt->u.insn.name = "call"; + stmt->u.insn.is_labelref = 1; + stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2]; + str = xmalloc(4); + snprintf(str, 4, "lr%u", stmt->u.insn.bin->operands[0]); + stmt->u.insn.operands[0] = str; + break; + case 15: + //FIXME: This opcode is different on r15. Decode raw for now. + disasm_opcode_raw(ctx, stmt); + break; + } break; } case 0x003: { @@ -529,10 +544,7 @@ static void disasm_constant_opcodes(struct disassembler_context *ctx, break; } default: - stmt->u.insn.name = gen_raw_code(bin->opcode); - disasm_std_operand(stmt, 0, 0, 1); - disasm_std_operand(stmt, 1, 1, 1); - disasm_std_operand(stmt, 2, 2, 1); + disasm_opcode_raw(ctx, stmt); break; } } -- 2.31.1 From 7ff7a760aa92b63ed4af8aabddb621cc9483e67f Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Sun, 19 Sep 2010 17:19:28 +0200 Subject: [PATCH 15/16] assembler: Some r15 fixes Signed-off-by: Michael Buesch --- assembler/main.c | 22 +++++++++++++++++----- assembler/scanner.l | 2 +- disassembler/main.c | 2 +- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/assembler/main.c b/assembler/main.c index 0d995a4..309d7c5 100644 --- a/assembler/main.c +++ b/assembler/main.c @@ -325,9 +325,21 @@ static unsigned int generate_mem_operand(struct assembler_context *ctx, case MEM_DIRECT: /* format: 0b0mmm mmmm mmmm */ off = mem->offset; - if (off & ~0x7FF) { //FIXME 4096 words for v15 arch possible? - asm_warn(ctx, "DIRECT memoffset 0x%X too long (> 11 bits)", off); - off &= 0x7FF; + switch (ctx->arch) { + case 5: + if (off & ~0x7FF) { + asm_warn(ctx, "DIRECT memoffset 0x%X too long (> 11 bits)", off); + off &= 0x7FF; + } + break; + case 15: + if (off & ~0xFFF) { + asm_warn(ctx, "DIRECT memoffset 0x%X too long (> 12 bits)", off); + off &= 0xFFF; + } + break; + default: + asm_error(ctx, "Internal error: generate_mem_operand invalid arch"); } val |= off; break; @@ -345,9 +357,9 @@ static unsigned int generate_mem_operand(struct assembler_context *ctx, /* Assembler bug. The parser shouldn't pass this value. */ asm_error(ctx, "OFFR-nr too big"); } - if (reg == 6) { + if (reg == 6 && ctx->arch == 5) { asm_warn(ctx, "Using offset register 6. This register is broken " - "on certain devices. Use off0 to off5 only."); + "on architecture 5 devices. Use off0 to off5 only."); } val |= off; val |= (reg << 6); diff --git a/assembler/scanner.l b/assembler/scanner.l index b135552..a9928da 100644 --- a/assembler/scanner.l +++ b/assembler/scanner.l @@ -56,7 +56,7 @@ NEWLINE ((\r)|(\n)|(\r\n)) ^{WS}*\.text{WS}*$ { update_lineinfo(); return SECTION_TEXT; } ^{WS}*\.initvals/\({IDENTIFIER}\) { update_lineinfo(); return SECTION_IVALS; } -spr[0-9a-fA-F]{3,3} { update_lineinfo(); return SPR; } +spr[0-9a-fA-F]{1,4} { update_lineinfo(); return SPR; } r/([0-9]|([1-5][0-9])|(6[0-3])) { update_lineinfo(); return GPR; } off/[0-6] { update_lineinfo(); return OFFR; } lr/[0-3] { update_lineinfo(); return LR; } diff --git a/disassembler/main.c b/disassembler/main.c index e55a545..43415a1 100644 --- a/disassembler/main.c +++ b/disassembler/main.c @@ -94,7 +94,7 @@ static const char * disasm_indirect_mem_operand(unsigned int operand) ret = xmalloc(12); snprintf(ret, 12, "[0x%02X,off%u]", - (operand & 0x3F), ((operand >> 6) & 0x7)); + (operand & 0x3F), ((operand >> 6) & 0x7)); //FIXME r15? return ret; } -- 2.31.1 From d1a8976facb28d18ef9d3a29de5bd1bd721f3394 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Sun, 19 Sep 2010 17:42:39 +0200 Subject: [PATCH 16/16] assembler: Add support for raw output format Signed-off-by: Michael Buesch --- assembler/args.c | 17 +++++++- assembler/args.h | 7 ++++ assembler/main.c | 99 +++++++++++++++++++++++++++++---------------- assembler/main.h | 2 +- disassembler/args.c | 2 +- 5 files changed, 89 insertions(+), 38 deletions(-) diff --git a/assembler/args.c b/assembler/args.c index b2a8ddf..42d9c18 100644 --- a/assembler/args.c +++ b/assembler/args.c @@ -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", ¶m)) == 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) { diff --git a/assembler/args.h b/assembler/args.h index 06f8ca3..fc3abc1 100644 --- a/assembler/args.h +++ b/assembler/args.h @@ -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) diff --git a/assembler/main.c b/assembler/main.c index 309d7c5..6b294a4 100644 --- a/assembler/main.c +++ b/assembler/main.c @@ -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"); diff --git a/assembler/main.h b/assembler/main.h index e325f03..f5c2234 100644 --- a/assembler/main.h +++ b/assembler/main.h @@ -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 { diff --git a/disassembler/args.c b/disassembler/args.c index 3663c59..7fc2978 100644 --- a/disassembler/args.c +++ b/disassembler/args.c @@ -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"); -- 2.31.1