commands-file.c (2672B)
1 // Copyright 2023, Brian Swetland <swetland@frotz.net> 2 // Licensed under the Apache License, Version 2.0. 3 4 #include <errno.h> 5 #include <string.h> 6 #include <stdlib.h> 7 #include <fcntl.h> 8 #include <unistd.h> 9 #include <sys/time.h> 10 11 #include "xdebug.h" 12 #include "transport.h" 13 #include "arm-v7-debug.h" 14 #include "arm-v7-system-control.h" 15 16 void *load_file(const char *fn, size_t *_sz) { 17 int fd; 18 off_t sz; 19 void *data = NULL; 20 fd = open(fn, O_RDONLY); 21 if (fd < 0) goto fail; 22 sz = lseek(fd, 0, SEEK_END); 23 if (sz < 0) goto fail; 24 if (lseek(fd, 0, SEEK_SET)) goto fail; 25 if ((data = malloc(sz + 4)) == NULL) goto fail; 26 if (read(fd, data, sz) != sz) goto fail; 27 *_sz = sz; 28 return data; 29 fail: 30 if (data) free(data); 31 if (fd >= 0) close(fd); 32 return NULL; 33 } 34 35 static long long now() { 36 struct timeval tv; 37 gettimeofday(&tv, 0); 38 return ((long long) tv.tv_usec) + ((long long) tv.tv_sec) * 1000000LL; 39 } 40 41 int do_upload(DC* dc, CC* cc) { 42 int status = DBG_ERR; 43 const char* fn; 44 uint32_t addr; 45 uint32_t len; 46 uint32_t sz; 47 long long t0, t1; 48 int fd, r; 49 void *data; 50 51 if (cmd_arg_str(cc, 1, &fn)) return DBG_ERR; 52 if (cmd_arg_u32(cc, 2, &addr)) return DBG_ERR; 53 if (cmd_arg_u32(cc, 3, &len)) return DBG_ERR; 54 if (addr & 3) { 55 ERROR("address not word aligned\n"); 56 return DBG_ERR; 57 } 58 if ((fd = open(fn, O_CREAT | O_TRUNC | O_WRONLY, 0644)) < 0) { 59 ERROR("cannot open '%s'\n", fn); 60 return DBG_ERR; 61 } 62 sz = (len + 3) & ~3; 63 64 if ((data = malloc(sz)) == NULL) { 65 ERROR("out of memory\n"); 66 goto done; 67 } 68 69 INFO("upload: reading %d bytes...\n", sz); 70 t0 = now(); 71 if (dc_mem_rd_words(dc, addr, sz / 4, data) < 0) { 72 ERROR("failed to read data\n"); 73 goto done; 74 } 75 t1 = now(); 76 INFO("upload: %lld uS -> %lld B/s\n", (t1 - t0), 77 (((long long)sz) * 1000000LL) / (t1 - t0)); 78 79 char *x = data; 80 while (len > 0) { 81 r = write(fd, x, sz); 82 if (r < 0) { 83 if (errno == EINTR) continue; 84 ERROR("write error\n"); 85 goto done; 86 } 87 x += r; 88 len -= r; 89 } 90 status = 0; 91 done: 92 close(fd); 93 if (data) free(data); 94 return status; 95 } 96 97 int do_download(DC* dc, CC* cc) { 98 const char* fn; 99 uint32_t addr; 100 void *data; 101 size_t sz; 102 long long t0, t1; 103 104 if (cmd_arg_str(cc, 1, &fn)) return DBG_ERR; 105 if (cmd_arg_u32(cc, 2, &addr)) return DBG_ERR; 106 107 if ((data = load_file(fn, &sz)) == NULL) { 108 ERROR("cannot read '%s'\n", fn); 109 return DBG_ERR; 110 } 111 sz = (sz + 3) & ~3; 112 113 INFO("download: sending %ld bytes...\n", sz); 114 t0 = now(); 115 if (dc_mem_wr_words(dc, addr, sz / 4, data) < 0) { 116 ERROR("failed to write data\n"); 117 free(data); 118 return DBG_ERR; 119 } 120 t1 = now(); 121 INFO("download: %lld uS -> %lld B/s\n", (t1 - t0), 122 (((long long)sz) * 1000000LL) / (t1 - t0)); 123 free(data); 124 return 0; 125 } 126 127