bios/tools: allow disabling CRC check on serialboot (to speedup debug/loading large...
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 26 Aug 2019 15:15:01 +0000 (17:15 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Mon, 26 Aug 2019 15:15:01 +0000 (17:15 +0200)
litex/soc/software/bios/boot.c
litex/soc/software/bios/sfl.h
litex/tools/litex_term.py

index 2801202a881ac393cf777d2a1dabd97fa2e12b6b..41e179f49c37f22bfc5e881c574b4a73db438f51 100644 (file)
@@ -122,7 +122,7 @@ int serialboot(void)
                int actualcrc;
                int goodcrc;
 
-               /* Grab one frame */
+               /* Get one Frame */
                frame.length = uart_read();
                frame.crc[0] = uart_read();
                frame.crc[1] = uart_read();
@@ -130,26 +130,29 @@ int serialboot(void)
                for(i=0;i<frame.length;i++)
                        frame.payload[i] = uart_read();
 
-               /* Check CRC */
-               actualcrc = ((int)frame.crc[0] << 8)|(int)frame.crc[1];
-               goodcrc = crc16(&frame.cmd, frame.length+1);
-               if(actualcrc != goodcrc) {
-                       failed++;
-                       if(failed == MAX_FAILED) {
-                               printf("Too many consecutive errors, aborting");
-                               return 1;
+               /* Check Frame CRC (if CMD has a CRC) */
+               if (frame.cmd != SFL_CMD_LOAD_NO_CRC) {
+                       actualcrc = ((int)frame.crc[0] << 8)|(int)frame.crc[1];
+                       goodcrc = crc16(&frame.cmd, frame.length+1);
+                       if(actualcrc != goodcrc) {
+                               failed++;
+                               if(failed == MAX_FAILED) {
+                                       printf("Too many consecutive errors, aborting");
+                                       return 1;
+                               }
+                               uart_write(SFL_ACK_CRCERROR);
+                               continue;
                        }
-                       uart_write(SFL_ACK_CRCERROR);
-                       continue;
                }
 
-               /* CRC OK */
+               /* Execute Frame CMD */
                switch(frame.cmd) {
                        case SFL_CMD_ABORT:
                                failed = 0;
                                uart_write(SFL_ACK_SUCCESS);
                                return 1;
-                       case SFL_CMD_LOAD: {
+                       case SFL_CMD_LOAD:
+                       case SFL_CMD_LOAD_NO_CRC: {
                                char *writepointer;
 
                                failed = 0;
@@ -160,7 +163,8 @@ int serialboot(void)
                                        |((unsigned long)frame.payload[3] <<  0));
                                for(i=4;i<frame.length;i++)
                                        *(writepointer++) = frame.payload[i];
-                               uart_write(SFL_ACK_SUCCESS);
+                               if (frame.cmd == SFL_CMD_LOAD)
+                                       uart_write(SFL_ACK_SUCCESS);
                                break;
                        }
                        case SFL_CMD_JUMP: {
index d1338732e903b557b41f11ff07182ae3fc28cfaa..32041bd5bbb4ed26920831b1409703ad5ca65f87 100644 (file)
@@ -19,6 +19,7 @@ struct sfl_frame {
 #define SFL_CMD_ABORT          0x00
 #define SFL_CMD_LOAD           0x01
 #define SFL_CMD_JUMP           0x02
+#define SFL_CMD_LOAD_NO_CRC    0x03
 
 /* Replies */
 #define SFL_ACK_SUCCESS                'K'
index 8e68a7bbfb29f56e5a85ff6083a06a2cc5b71015..e96e3e0f77a70c495945725261767c49330a64de 100755 (executable)
@@ -55,9 +55,10 @@ sfl_magic_ack = b"z6IHG7cYDID6o\n"
 sfl_payload_length = 251
 
 # General commands
-sfl_cmd_abort = b"\x00"
-sfl_cmd_load  = b"\x01"
-sfl_cmd_jump  = b"\x02"
+sfl_cmd_abort       = b"\x00"
+sfl_cmd_load        = b"\x01"
+sfl_cmd_load_no_crc = b"\x03"
+sfl_cmd_jump        = b"\x02"
 
 # Replies
 sfl_ack_success  = b"K"
@@ -126,7 +127,7 @@ class SFLFrame:
 
 
 class LiteXTerm:
-    def __init__(self, serial_boot, kernel_image, kernel_address, json_images):
+    def __init__(self, serial_boot, kernel_image, kernel_address, json_images, no_crc):
         self.serial_boot = serial_boot
         assert not (kernel_image is not None and json_images is not None)
         self.mem_regions = {}
@@ -138,6 +139,7 @@ class LiteXTerm:
             self.mem_regions.update(json.load(f))
             self.boot_address = self.mem_regions[list(self.mem_regions.keys())[-1]]
             f.close()
+        self.no_crc = no_crc
 
         self.reader_alive = False
         self.writer_alive = False
@@ -176,15 +178,18 @@ class LiteXTerm:
         retry = 1
         while retry:
             self.port.write(frame.encode())
-            # Get the reply from the device
-            reply = self.port.read()
-            if reply == sfl_ack_success:
-                retry = 0
-            elif reply == sfl_ack_crcerror:
-                retry = 1
+            if not self.no_crc:
+                # Get the reply from the device
+                reply = self.port.read()
+                if reply == sfl_ack_success:
+                    retry = 0
+                elif reply == sfl_ack_crcerror:
+                    retry = 1
+                else:
+                    print("[LXTERM] Got unknown reply '{}' from the device, aborting.".format(reply))
+                    return 0
             else:
-                print("[LXTERM] Got unknown reply '{}' from the device, aborting.".format(reply))
-                return 0
+                retry = 0
         return 1
 
     def upload(self, filename, address):
@@ -202,7 +207,7 @@ class LiteXTerm:
             sys.stdout.flush()
             frame = SFLFrame()
             frame_data = data[:sfl_payload_length]
-            frame.cmd = sfl_cmd_load
+            frame.cmd = sfl_cmd_load if not self.no_crc else sfl_cmd_load_no_crc
             frame.payload = current_address.to_bytes(4, "big")
             frame.payload += frame_data
             if self.send_frame(frame) == 0:
@@ -332,12 +337,13 @@ def _get_args():
     parser.add_argument("--kernel", default=None, help="kernel image")
     parser.add_argument("--kernel-adr", default="0x40000000", help="kernel address")
     parser.add_argument("--images", default=None, help="json description of the images to load to memory")
+    parser.add_argument("--no-crc", default=False, action='store_true', help="disable CRC check (speedup serialboot)")
     return parser.parse_args()
 
 
 def main():
     args = _get_args()
-    term = LiteXTerm(args.serial_boot, args.kernel, args.kernel_adr, args.images)
+    term = LiteXTerm(args.serial_boot, args.kernel, args.kernel_adr, args.images, args.no_crc)
     term.open(args.port, int(float(args.speed)))
     term.console.configure()
     term.start()