Преглед на файлове

f7: Fix firmware update: The mode-switch flag must be flushed from DCache.

Keir Fraser преди 4 години
родител
ревизия
296567a7cf
променени са 5 файла, в които са добавени 31 реда и са изтрити 3 реда
  1. 2 0
      inc/stm32/f7.h
  2. 5 1
      scripts/greaseweazle/tools/util.py
  3. 3 0
      src/floppy.c
  4. 2 0
      src/fw_update.c
  5. 19 2
      src/stm32f7.c

+ 2 - 0
inc/stm32/f7.h

@@ -84,6 +84,8 @@ void peripheral_clock_delay(void);
 
 void gpio_set_af(GPIO gpio, unsigned int pin, unsigned int af);
 
+void dcache_disable(void);
+
 #define section_ext_ram __attribute__((section(".ext_ram")))
 
 /*

+ 5 - 1
scripts/greaseweazle/tools/util.py

@@ -149,7 +149,11 @@ def usb_open(devicename, is_update=False):
 
     if is_update and not usb.update_mode:
         if usb.hw_type == 7:
-            return usb_reopen(usb, is_update)
+            usb = usb_reopen(usb, is_update)
+            error.check(usb.update_mode, """\
+Greaseweazle F7 did not change to Firmware Update Mode as requested.
+If the problem persists, install the Update Jumper (across RX/TX).""")
+            return usb
         print("Greaseweazle is in Normal Mode:")
         print(" To \"update\" you must install the Update Jumper")
         sys.exit(1)

+ 3 - 0
src/floppy.c

@@ -1022,6 +1022,7 @@ static void process_command(void)
         sink_source_prep(&ssb);
         break;
     }
+#if STM32F == 7
     case CMD_SWITCH_FW_MODE: {
         uint8_t mode = u_buf[2];
         if ((len != 3) || (mode & ~1))
@@ -1031,10 +1032,12 @@ static void process_command(void)
             delay_ms(500);
             /* Poke a flag in SRAM1, picked up by the bootloader. */
             *(volatile uint32_t *)0x20010000 = 0xdeadbeef;
+            dcache_disable();
             system_reset();
         }
         break;
     }
+#endif
     default:
         goto bad_command;
     }

+ 2 - 0
src/fw_update.c

@@ -158,6 +158,7 @@ static void process_command(void)
         update_prep(u_len);
         break;
     }
+#if STM32F == 7
     case CMD_SWITCH_FW_MODE: {
         uint8_t mode = u_buf[2];
         if ((len != 3) || (mode & ~1))
@@ -169,6 +170,7 @@ static void process_command(void)
         }
         break;
     }
+#endif
     default:
         goto bad_command;
     }

+ 19 - 2
src/stm32f7.c

@@ -66,7 +66,7 @@ static void icache_enable(void)
     cpu_sync(); 
 }
 
-static void dcache_invalidate_all(void)
+static void _dcache_op_all(volatile uint32_t *opreg)
 {
     uint32_t ccsidr;
     unsigned int sets, ways;
@@ -78,12 +78,22 @@ static void dcache_invalidate_all(void)
     do {
         ways = CCSIDR_WAYS(ccsidr);
         do {
-            cache->dcisw = DCISW_SET(sets) | DCISW_WAY(ways);
+            *opreg = DCISW_SET(sets) | DCISW_WAY(ways);
         } while (ways--);
     } while (sets--);
     cpu_sync();
 }
 
+static void dcache_invalidate_all(void)
+{
+    _dcache_op_all(&cache->dcisw);
+}
+
+static void dcache_clear_and_invalidate_all(void)
+{
+    _dcache_op_all(&cache->dccisw);
+}
+
 static void dcache_enable(void)
 {
     dcache_invalidate_all();
@@ -91,6 +101,13 @@ static void dcache_enable(void)
     cpu_sync();
 }
 
+void dcache_disable(void)
+{
+    scb->ccr &= ~SCB_CCR_DC;
+    cpu_sync();
+    dcache_clear_and_invalidate_all();
+}
+
 void peripheral_clock_delay(void)
 {
     delay_ticks(2);