<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/simtrace2/+/26463">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  laforge: Looks good to me, approved
  osmith: Looks good to me, but someone else must approve
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">firmware: add crc stub to all dfu apps to ensure reliable loading<br><br>DFU flashing of apps sometimes aborts, and although rare this leads to<br>broken devices if no boot button or serial/jtag access exists, because<br>the bootloader will keep trying to start a half-flashed app that then<br>crashes at some point.<br><br>The easiest fix that works with existing bootloaders is to prepend a<br>small 512 byte stub that calculcates the crc and compares it with the<br>crc calculated at build time, and then either starts the actual app, or<br>sets the dfu flag and resets. This ensures we either have a working,<br>running app, or end up in the bootloader, ready to flash again.<br><br>For obvious reasons this only applies to dfu apps, and not to flash<br>targets like the actual bootloader itself.<br><br>Change-Id: Id6df0486c8b779889d21800dc2441b3aa9af8a5f<br>---<br>M contrib/prepare_upload.sh<br>M firmware/Makefile<br>M firmware/apps/blupdate/main.c<br>M firmware/libboard/common/resources/sam3s4/dfu.ld<br>M firmware/libboard/common/resources/sam3s4/flash.ld<br>A firmware/libcommon/source/crcstub.c<br>A firmware/misc/crctool.c<br>7 files changed, 246 insertions(+), 28 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/contrib/prepare_upload.sh b/contrib/prepare_upload.sh</span><br><span>index 90b3278..f134d2a 100755</span><br><span>--- a/contrib/prepare_upload.sh</span><br><span>+++ b/contrib/prepare_upload.sh</span><br><span>@@ -1,4 +1,4 @@</span><br><span style="color: hsl(0, 100%, 40%);">-#!/bin/sh -e</span><br><span style="color: hsl(120, 100%, 40%);">+#!/bin/bash -e</span><br><span> # Create copies of binaries with -latest, -$GIT_VERSION (OS#4413, OS#3452)</span><br><span> cd "$(dirname "$0")/.."</span><br><span> </span><br><span>@@ -9,8 +9,10 @@</span><br><span> cd firmware/bin</span><br><span> for ext in bin elf; do</span><br><span>       for file in *."$ext"; do</span><br><span style="color: hsl(0, 100%, 40%);">-              without_ext="${file%.*}"</span><br><span style="color: hsl(0, 100%, 40%);">-              cp -v "$file" "$without_ext-latest.$ext"</span><br><span style="color: hsl(0, 100%, 40%);">-            cp -v "$file" "$without_ext-$GIT_VERSION.$ext"</span><br><span style="color: hsl(120, 100%, 40%);">+            if ! [[ "$file" =~ ^(.*padded.*|.*nocrcstub.*)$ ]];then</span><br><span style="color: hsl(120, 100%, 40%);">+                     without_ext="${file%.*}"</span><br><span style="color: hsl(120, 100%, 40%);">+                    cp -v "$file" "$without_ext-latest.$ext"</span><br><span style="color: hsl(120, 100%, 40%);">+                  cp -v "$file" "$without_ext-$GIT_VERSION.$ext"</span><br><span style="color: hsl(120, 100%, 40%);">+            fi</span><br><span>   done</span><br><span> done</span><br><span>diff --git a/firmware/Makefile b/firmware/Makefile</span><br><span>index c30dc9a..9a2d347 100644</span><br><span>--- a/firmware/Makefile</span><br><span>+++ b/firmware/Makefile</span><br><span>@@ -117,7 +117,7 @@</span><br><span> C_LIBUSB_RT  = dfu.c dfu_runtime.c</span><br><span> C_LIBUSB_DFU = dfu.c dfu_desc.c dfu_driver.c</span><br><span> C_LIBCOMMON  = string.c stdio.c fputs.c usb_buf.c ringbuffer.c pseudo_talloc.c host_communication.c \</span><br><span style="color: hsl(0, 100%, 40%);">-             main_common.c stack_check.c</span><br><span style="color: hsl(120, 100%, 40%);">+           main_common.c stack_check.c crcstub.c</span><br><span> </span><br><span> C_BOARD      = $(notdir $(wildcard libboard/common/source/*.c))</span><br><span> C_BOARD     += $(notdir $(wildcard libboard/$(BOARD)/source/*.c))</span><br><span>@@ -229,12 +229,15 @@</span><br><span> $(OUTPUT)-combined.bin: $(BIN)/$(BOARD)-dfu-flash-padded.bin $(OUTPUT)-dfu.bin</span><br><span>   cat $^ > $@</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-$(BIN) $(OBJ): apps/$(APP)/usb_strings_generated.h</span><br><span style="color: hsl(120, 100%, 40%);">+$(BIN) $(OBJ): apps/$(APP)/usb_strings_generated.h misc/crctool</span><br><span>        mkdir -p $@</span><br><span> </span><br><span> usbstring/usbstring: usbstring/usbstring.c</span><br><span>        gcc $^ -o $@</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+misc/crctool: misc/crctool.c</span><br><span style="color: hsl(120, 100%, 40%);">+        gcc $^ -o $@</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> .PHONY: apps/$(APP)/usb_strings.txt.patched</span><br><span> apps/$(APP)/usb_strings.txt.patched: apps/$(APP)/usb_strings.txt</span><br><span>    sed "s/PRODUCT_STRING/$(shell cat libboard/$(BOARD)/product_string.txt)/" $< > $@</span><br><span>@@ -251,7 +254,6 @@</span><br><span>      $(SILENT)$(CC) $(CFLAGS) $(LDFLAGS) $(LD_OPTIONAL) -T"libboard/common/resources/$(CHIP)/$(1).ld" -Wl,-Map,$(OUTPUT)-$(1).map -o $(OUTPUT)-$(1).elf $$^ $(LIBS)</span><br><span>     $(SILENT)$(NM) $(OUTPUT)-$(1).elf >$(OUTPUT)-$(1).elf.txt</span><br><span>         $(SILENT)$(OBJCOPY) -O binary $(OUTPUT)-$(1).elf $(OUTPUT)-$(1).bin</span><br><span style="color: hsl(0, 100%, 40%);">-     $(SILENT)$(SIZE) $$^ $(OUTPUT)-$(1).elf</span><br><span> </span><br><span> $$(C_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.c Makefile $(OBJ) $(BIN)</span><br><span>       @echo [COMPILING $$<]</span><br><span>@@ -261,26 +263,17 @@</span><br><span>     @echo [ASSEMBLING $$@]</span><br><span>       $(SILENT)$(CC) $(ASFLAGS) -DENVIRONMENT_$(1) -DENVIRONMENT=\"$(1)\" -c -o $$@ $$<</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-debug_$(1): $(1)</span><br><span style="color: hsl(0, 100%, 40%);">-      $(GDB) -x "$(BOARD_LIB)/resources/gcc/$(BOARD)_$(1).gdb" -ex "reset" -readnow -se $(OUTPUT)-$(1).elf</span><br><span> endef</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-ALL_MEMORIES = dfu flash ram</span><br><span style="color: hsl(120, 100%, 40%);">+ALL_MEMORIES = flash ram</span><br><span> $(foreach MEMORY, $(ALL_MEMORIES), $(eval $(call RULES,$(MEMORY))))</span><br><span> </span><br><span> # files with those names do exist..</span><br><span style="color: hsl(0, 100%, 40%);">-.PHONY: ram</span><br><span> .PHONY: dfu</span><br><span style="color: hsl(0, 100%, 40%);">-.PHONY: flash</span><br><span style="color: hsl(120, 100%, 40%);">+dfu: $(OUTPUT)-dfu.bin</span><br><span style="color: hsl(120, 100%, 40%);">+.PHONY: ram</span><br><span> ram: build_ram</span><br><span style="color: hsl(0, 100%, 40%);">-dfu: build_dfu</span><br><span style="color: hsl(0, 100%, 40%);">-ifeq ($(APP), blupdate)</span><br><span style="color: hsl(0, 100%, 40%);">-        $(info updating updater section with padded bootloader file..)</span><br><span style="color: hsl(0, 100%, 40%);">-  $(SILENT)dd if=/dev/zero bs=16384 count=1 of=$(BIN)/$(BOARD)-dfu-flash-padded.bin</span><br><span style="color: hsl(0, 100%, 40%);">-       $(SILENT)dd if=$(BIN)/$(BOARD)-dfu-flash.bin conv=notrunc of=$(BIN)/$(BOARD)-dfu-flash-padded.bin</span><br><span style="color: hsl(0, 100%, 40%);">-       $(SILENT)$(OBJCOPY) --update-section .blupdate=bin/$(BOARD)-dfu-flash-padded.bin bin/$(BOARD)-blupdate-dfu.elf</span><br><span style="color: hsl(0, 100%, 40%);">-  $(SILENT)$(OBJCOPY) -O binary bin/$(BOARD)-blupdate-dfu.elf bin/$(BOARD)-blupdate-dfu.bin</span><br><span style="color: hsl(0, 100%, 40%);">-endif</span><br><span style="color: hsl(120, 100%, 40%);">+.PHONY: flash</span><br><span> flash: build_flash</span><br><span> #alternate way of embedding: obj file</span><br><span> #ifeq ($(APP), dfu)</span><br><span>@@ -288,8 +281,37 @@</span><br><span> # $(SILENT)$(OBJCOPY) --rename-section .data=.fwupdate -I binary -O elf32-littlearm bin/$(BOARD)-dfu-flash.bin $(OBJ)/flash_fwupdate.o</span><br><span> #endif</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-program:</span><br><span style="color: hsl(0, 100%, 40%);">-      openocd -f openocd/openocd.cfg -c "init" -c "halt" -c "flash write_bank 0 ./bin/project-flash.bin 0" -c "reset" -c "shutdown"</span><br><span style="color: hsl(120, 100%, 40%);">+C_OBJECTS_dfu = $(addprefix $(OBJ)/dfu_, $(C_OBJECTS))</span><br><span style="color: hsl(120, 100%, 40%);">+ASM_OBJECTS_dfu = $(addprefix $(OBJ)/dfu_, $(ASM_OBJECTS))</span><br><span style="color: hsl(120, 100%, 40%);">+EXTRA_OBJECTS_dfu = $(addprefix $(OBJ)/dfu_, $(EXTRA_OBJECTS))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+$(OUTPUT)-dfu.bin: $(OUTPUT)-dfu_nocrcstub.bin</span><br><span style="color: hsl(120, 100%, 40%);">+ $(info updating app with crc..)</span><br><span style="color: hsl(120, 100%, 40%);">+       $(SILENT)cp $< $@.temp</span><br><span style="color: hsl(120, 100%, 40%);">+     $(SILENT)misc/crctool 512 $@.temp</span><br><span style="color: hsl(120, 100%, 40%);">+     $(SILENT)mv $@.temp $@</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+$(OUTPUT)-dfu_nocrcstub.bin: $(OUTPUT)-dfu_nocrcstub.elf</span><br><span style="color: hsl(120, 100%, 40%);">+ifeq ($(APP), blupdate)</span><br><span style="color: hsl(120, 100%, 40%);">+   $(info updating updater section with padded bootloader file..)</span><br><span style="color: hsl(120, 100%, 40%);">+        $(SILENT)dd status=none if=/dev/zero bs=16384 count=1 of=$(BIN)/$(BOARD)-dfu-flash-padded.bin</span><br><span style="color: hsl(120, 100%, 40%);">+ $(SILENT)dd status=none if=$(BIN)/$(BOARD)-dfu-flash.bin conv=notrunc of=$(BIN)/$(BOARD)-dfu-flash-padded.bin</span><br><span style="color: hsl(120, 100%, 40%);">+ $(SILENT)$(OBJCOPY) --update-section .blupdate=bin/$(BOARD)-dfu-flash-padded.bin $<</span><br><span style="color: hsl(120, 100%, 40%);">+endif</span><br><span style="color: hsl(120, 100%, 40%);">+ $(SILENT)$(OBJCOPY) -O binary $< $@</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+$(OUTPUT)-dfu_nocrcstub.elf: $(ASM_OBJECTS_dfu) $(C_OBJECTS_dfu) $(EXTRA_OBJECTS_dfu)</span><br><span style="color: hsl(120, 100%, 40%);">+       $(SILENT)$(CC) $(CFLAGS) $(LDFLAGS) $(LD_OPTIONAL) -T"libboard/common/resources/$(CHIP)/dfu.ld" -Wl,-Map,$(OUTPUT)-dfu_nocrcstub.map -o $@ $^ $(LIBS)</span><br><span style="color: hsl(120, 100%, 40%);">+       $(SILENT)$(NM) $@ >$@.txt</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+$(C_OBJECTS_dfu): $(OBJ)/dfu_%.o: %.c Makefile $(OBJ) $(BIN)</span><br><span style="color: hsl(120, 100%, 40%);">+  @echo [COMPILING $<]</span><br><span style="color: hsl(120, 100%, 40%);">+       $(SILENT)$(CC) $(CFLAGS) -DENVIRONMENT_dfu -DENVIRONMENT=\"dfu\" -c -o $@ $<</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+$(ASM_OBJECTS_dfu): $(OBJ)/dfu_%.o: %.S Makefile $(OBJ) $(BIN)</span><br><span style="color: hsl(120, 100%, 40%);">+   @echo [ASSEMBLING $@]</span><br><span style="color: hsl(120, 100%, 40%);">+ $(SILENT)$(CC) $(ASFLAGS) -DENVIRONMENT_dfu -DENVIRONMENT=\"dfu\" -c -o$@ $<</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> </span><br><span> SERIAL ?= /dev/ttyUSB0</span><br><span> log:</span><br><span>diff --git a/firmware/apps/blupdate/main.c b/firmware/apps/blupdate/main.c</span><br><span>index e9ffe22..8c48e37 100644</span><br><span>--- a/firmware/apps/blupdate/main.c</span><br><span>+++ b/firmware/apps/blupdate/main.c</span><br><span>@@ -89,8 +89,14 @@</span><br><span>      flash_cmd(EFC_FCMD_EA, 0);</span><br><span> #endif</span><br><span>         flash_wait_ready();</span><br><span style="color: hsl(0, 100%, 40%);">-     for (;;)</span><br><span style="color: hsl(0, 100%, 40%);">-                NVIC_SystemReset();</span><br><span style="color: hsl(120, 100%, 40%);">+   for (;;) {</span><br><span style="color: hsl(120, 100%, 40%);">+            /* no functon call, since NVIC_SystemReset() might not be inlined! */</span><br><span style="color: hsl(120, 100%, 40%);">+         SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |</span><br><span style="color: hsl(120, 100%, 40%);">+                            SCB_AIRCR_SYSRESETREQ_Msk);</span><br><span style="color: hsl(120, 100%, 40%);">+             __DSB();</span><br><span style="color: hsl(120, 100%, 40%);">+              while (1)</span><br><span style="color: hsl(120, 100%, 40%);">+                     ;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span> }</span><br><span> </span><br><span> #define MAX_USB_ITER BOARD_MCK / 72 // This should be around a second</span><br><span>diff --git a/firmware/libboard/common/resources/sam3s4/dfu.ld b/firmware/libboard/common/resources/sam3s4/dfu.ld</span><br><span>index 7d896c6..86e6622 100644</span><br><span>--- a/firmware/libboard/common/resources/sam3s4/dfu.ld</span><br><span>+++ b/firmware/libboard/common/resources/sam3s4/dfu.ld</span><br><span>@@ -39,7 +39,8 @@</span><br><span> MEMORY</span><br><span> {</span><br><span>  /* reserve the first 16k (= 0x4000) for the DFU bootloader */</span><br><span style="color: hsl(0, 100%, 40%);">-   rom (rx)  : ORIGIN = 0x00400000 + 16K, LENGTH = 256K - 16K /* flash, 256K */</span><br><span style="color: hsl(120, 100%, 40%);">+  crcstub (rx)  : ORIGIN = 0x00400000 + 16K, LENGTH = 512 /* crcstub part */</span><br><span style="color: hsl(120, 100%, 40%);">+    rom (rx)  : ORIGIN = 0x00400000 + 16K + 512, LENGTH = 256K - 16K - 512 /* flash, 256K */</span><br><span>     /* note: dfudata will be at the start */</span><br><span>     ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K /* SRAM, 48K */</span><br><span> }</span><br><span>@@ -47,9 +48,17 @@</span><br><span> /* Section Definitions */ </span><br><span> SECTIONS </span><br><span> { </span><br><span style="color: hsl(0, 100%, 40%);">-    .text : </span><br><span style="color: hsl(0, 100%, 40%);">-    { </span><br><span style="color: hsl(120, 100%, 40%);">+    .crcstub :</span><br><span style="color: hsl(120, 100%, 40%);">+    {</span><br><span>         . = ALIGN(4);</span><br><span style="color: hsl(120, 100%, 40%);">+        KEEP(*(.crcstub_table))</span><br><span style="color: hsl(120, 100%, 40%);">+        KEEP(*(.crcstub_code))</span><br><span style="color: hsl(120, 100%, 40%);">+    } > crcstub = 0xff</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    .text :</span><br><span style="color: hsl(120, 100%, 40%);">+    {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        . = ALIGN(512);</span><br><span>         _sfixed = .;</span><br><span>         KEEP(*(.vectors .vectors.*))</span><br><span>         *(.text .text.* .gnu.linkonce.t.*)         </span><br><span>@@ -94,7 +103,7 @@</span><br><span> </span><br><span>         . = ALIGN(4);</span><br><span>         _efixed = .;            /* End of text section */</span><br><span style="color: hsl(0, 100%, 40%);">-    } > rom</span><br><span style="color: hsl(120, 100%, 40%);">+    } > rom = 0xff</span><br><span> </span><br><span>     /DISCARD/ :</span><br><span>     {</span><br><span>diff --git a/firmware/libboard/common/resources/sam3s4/flash.ld b/firmware/libboard/common/resources/sam3s4/flash.ld</span><br><span>index 50631c6..b1de154 100644</span><br><span>--- a/firmware/libboard/common/resources/sam3s4/flash.ld</span><br><span>+++ b/firmware/libboard/common/resources/sam3s4/flash.ld</span><br><span>@@ -97,6 +97,8 @@</span><br><span>     /DISCARD/ :</span><br><span>     {</span><br><span>         *(.ARM.exidx)</span><br><span style="color: hsl(120, 100%, 40%);">+        *(.crcstub_table)</span><br><span style="color: hsl(120, 100%, 40%);">+        *(.crcstub_code)</span><br><span>     }</span><br><span> </span><br><span>     . = ALIGN(4); </span><br><span>diff --git a/firmware/libcommon/source/crcstub.c b/firmware/libcommon/source/crcstub.c</span><br><span>new file mode 100644</span><br><span>index 0000000..ef52521</span><br><span>--- /dev/null</span><br><span>+++ b/firmware/libcommon/source/crcstub.c</span><br><span>@@ -0,0 +1,86 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* SIMtrace 2 firmware crc stub</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2021 by sysmocom -s.f.m.c. GmbH, Author: Eric Wild <ewild@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or</span><br><span style="color: hsl(120, 100%, 40%);">+ * modify it under the terms of the GNU General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * as published by the Free Software Foundation; either version 2</span><br><span style="color: hsl(120, 100%, 40%);">+ * of the License, or (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include "board.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "core_cm3.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "usb/device/dfu/dfu.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+* This file is a bit special, everything has to go to specific sections, and no globals are available.</span><br><span style="color: hsl(120, 100%, 40%);">+* No external functions may be called, unless inlining is enforced!</span><br><span style="color: hsl(120, 100%, 40%);">+*/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void crc_check_stub();</span><br><span style="color: hsl(120, 100%, 40%);">+__attribute__((section(".crcstub_table"))) volatile uint32_t crcstub_dummy_table[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+    (uint32_t)0xdeadc0de, /* deliberately choose invalid value so unpatched image will not be started */</span><br><span style="color: hsl(120, 100%, 40%);">+  (uint32_t)crc_check_stub, /* must be valid flash addr */</span><br><span style="color: hsl(120, 100%, 40%);">+      (uint32_t)0xf1, /* crc value calculated by the host */</span><br><span style="color: hsl(120, 100%, 40%);">+        (uint32_t)0xf2, /* crc calc start address */</span><br><span style="color: hsl(120, 100%, 40%);">+  (uint32_t)0xf3 /* crc calc length (byte) */</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+__attribute__((section(".crcstub_code"))) static void do_crc32(int8_t c, uint32_t *crc_reg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   int32_t i, mask;</span><br><span style="color: hsl(120, 100%, 40%);">+      *crc_reg ^= c;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      for (unsigned int j = 0; j < 8; j++)</span><br><span style="color: hsl(120, 100%, 40%);">+               if (*crc_reg & 1)</span><br><span style="color: hsl(120, 100%, 40%);">+                 *crc_reg = (*crc_reg >> 1) ^ 0xEDB88320;</span><br><span style="color: hsl(120, 100%, 40%);">+                else</span><br><span style="color: hsl(120, 100%, 40%);">+                  *crc_reg = *crc_reg >> 1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+__attribute__((section(".crcstub_code"), noinline)) static void crc_check_stub()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   uint32_t crc_reg = 0xffffffff;</span><br><span style="color: hsl(120, 100%, 40%);">+        uint32_t expected_crc_val = crcstub_dummy_table[2];</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t *crc_calc_startaddr = (uint8_t *)crcstub_dummy_table[3];</span><br><span style="color: hsl(120, 100%, 40%);">+      volatile uint32_t *actual_exc_tbl = (volatile uint32_t *)crc_calc_startaddr;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint32_t crc_len = crcstub_dummy_table[4];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* 4000ms wdt tickling */</span><br><span style="color: hsl(120, 100%, 40%);">+     WDT->WDT_MR = WDT_MR_WDRSTEN | WDT_MR_WDDBGHLT | WDT_MR_WDIDLEHLT | (((4000UL << 8) / 1000) << 16) |</span><br><span style="color: hsl(120, 100%, 40%);">+                 ((4000UL << 8) / 1000);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (uint8_t *i = crc_calc_startaddr; i < crc_calc_startaddr + crc_len; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+               do_crc32(*i, &crc_reg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ crc_reg = ~crc_reg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (crc_reg == expected_crc_val) {</span><br><span style="color: hsl(120, 100%, 40%);">+            /* this looks a bit awkward because we have to ensure the bx does not require a sp-relative load */</span><br><span style="color: hsl(120, 100%, 40%);">+           __asm__ volatile("\</span><br><span style="color: hsl(120, 100%, 40%);">+              mov r0, %0;\n\</span><br><span style="color: hsl(120, 100%, 40%);">+                mov r1, %1;\n\</span><br><span style="color: hsl(120, 100%, 40%);">+                MSR msp,r0;\n\</span><br><span style="color: hsl(120, 100%, 40%);">+                bx r1;"</span><br><span style="color: hsl(120, 100%, 40%);">+                           :</span><br><span style="color: hsl(120, 100%, 40%);">+                             : "r"(actual_exc_tbl[0]), "r"(actual_exc_tbl[1]));</span><br><span style="color: hsl(120, 100%, 40%);">+       } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              /* no globals ! */</span><br><span style="color: hsl(120, 100%, 40%);">+            ((struct dfudata *)0x20000000)->magic = USB_DFU_MAGIC;</span><br><span style="color: hsl(120, 100%, 40%);">+             __DSB();</span><br><span style="color: hsl(120, 100%, 40%);">+              for (;;) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    /* no functon call, since NVIC_SystemReset() might not be inlined! */</span><br><span style="color: hsl(120, 100%, 40%);">+                 SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |</span><br><span style="color: hsl(120, 100%, 40%);">+                                    SCB_AIRCR_SYSRESETREQ_Msk);</span><br><span style="color: hsl(120, 100%, 40%);">+                     __DSB();</span><br><span style="color: hsl(120, 100%, 40%);">+                      while (1)</span><br><span style="color: hsl(120, 100%, 40%);">+                             ;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/firmware/misc/crctool.c b/firmware/misc/crctool.c</span><br><span>new file mode 100644</span><br><span>index 0000000..2602753</span><br><span>--- /dev/null</span><br><span>+++ b/firmware/misc/crctool.c</span><br><span>@@ -0,0 +1,91 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* SIMtrace 2 firmware crc tool</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2021 by sysmocom -s.f.m.c. GmbH, Author: Eric Wild <ewild@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or</span><br><span style="color: hsl(120, 100%, 40%);">+ * modify it under the terms of the GNU General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * as published by the Free Software Foundation; either version 2</span><br><span style="color: hsl(120, 100%, 40%);">+ * of the License, or (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdio.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdlib.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void do_crc32(int8_t c, uint32_t *crc_reg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   int32_t i, mask;</span><br><span style="color: hsl(120, 100%, 40%);">+      *crc_reg ^= c;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      for (unsigned int j = 0; j < 8; j++)</span><br><span style="color: hsl(120, 100%, 40%);">+               if (*crc_reg & 1)</span><br><span style="color: hsl(120, 100%, 40%);">+                 *crc_reg = (*crc_reg >> 1) ^ 0xEDB88320;</span><br><span style="color: hsl(120, 100%, 40%);">+                else</span><br><span style="color: hsl(120, 100%, 40%);">+                  *crc_reg = *crc_reg >> 1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int main(int argc, char *argv[])</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     uint32_t crc_reg = 0xffffffff;</span><br><span style="color: hsl(120, 100%, 40%);">+        long fsize;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t *buffer;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint32_t crc_start_offset;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (argc < 3) {</span><br><span style="color: hsl(120, 100%, 40%);">+            perror("usage: crctool startoffset blupdate.bin");</span><br><span style="color: hsl(120, 100%, 40%);">+          return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   crc_start_offset = strtoull(argv[1], 0, 10);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        FILE *blfile = fopen(argv[2], "rb+");</span><br><span style="color: hsl(120, 100%, 40%);">+       if (blfile == NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+         perror("error opening file!");</span><br><span style="color: hsl(120, 100%, 40%);">+              return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   fseek(blfile, 0, SEEK_END);</span><br><span style="color: hsl(120, 100%, 40%);">+   fsize = ftell(blfile);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (fsize <= crc_start_offset) {</span><br><span style="color: hsl(120, 100%, 40%);">+           perror("file size?!");</span><br><span style="color: hsl(120, 100%, 40%);">+              return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   fseek(blfile, 0, SEEK_SET);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ buffer = malloc(fsize);</span><br><span style="color: hsl(120, 100%, 40%);">+       fread(buffer, 1, fsize, blfile);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (*(uint32_t *)buffer != 0xdeadc0de) {</span><br><span style="color: hsl(120, 100%, 40%);">+              perror("weird magic, not a valid blupdate file?");</span><br><span style="color: hsl(120, 100%, 40%);">+          free(buffer);</span><br><span style="color: hsl(120, 100%, 40%);">+         return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t *startaddr = buffer + crc_start_offset;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t *endaddr = buffer + fsize;</span><br><span style="color: hsl(120, 100%, 40%);">+    for (uint8_t *i = startaddr; i < endaddr; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+           do_crc32(*i, &crc_reg);</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     crc_reg = ~crc_reg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ fprintf(stderr, "len: %ld crc: %.8x\n", fsize - crc_start_offset, crc_reg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       ((uint32_t *)buffer)[0] = 0x2000baa0; /* fix magic to valid stack address, checked by BL */</span><br><span style="color: hsl(120, 100%, 40%);">+   ((uint32_t *)buffer)[2] = crc_reg;</span><br><span style="color: hsl(120, 100%, 40%);">+    ((uint32_t *)buffer)[3] = 0x00400000 + 0x4000 + crc_start_offset;</span><br><span style="color: hsl(120, 100%, 40%);">+     ((uint32_t *)buffer)[4] = fsize - crc_start_offset;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ fseek(blfile, 0, SEEK_SET);</span><br><span style="color: hsl(120, 100%, 40%);">+   fwrite(buffer, 4, 5, blfile);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       fclose(blfile);</span><br><span style="color: hsl(120, 100%, 40%);">+       free(buffer);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/simtrace2/+/26463">change 26463</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/simtrace2/+/26463"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: simtrace2 </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Id6df0486c8b779889d21800dc2441b3aa9af8a5f </div>
<div style="display:none"> Gerrit-Change-Number: 26463 </div>
<div style="display:none"> Gerrit-PatchSet: 9 </div>
<div style="display:none"> Gerrit-Owner: Hoernchen <ewild@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: osmith <osmith@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: tsaitgaist <kredon@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>