def cmd_test(self, width, ui, args): """test memory with a write and readback""" x = util.mem_args(ui, args, self.cpu.device) if x is None: return (adr, n) = x if n == 0: return if n is None: n = 0x40 # round down address to 32-bit byte boundary adr &= ~3 # round up n to an integral multiple of 4 bytes n = (n + 3) & ~3 # convert to n 32/16/8-bit units nx = n / (width / 8) maxval = (1 << width) - 1 # we will typically be testing ram, so halt the cpu. self.cpu.halt() # build a random write buffer wrbuf = iobuf.data_buffer(width) [wrbuf.write(random.randint(0, maxval)) for i in xrange(nx)] # write it to memory t_start = time.time() self.cpu.wrmem(adr, nx, wrbuf) t_end = time.time() ui.put('write %.2f KiB/sec\n' % (float(n)/((t_end - t_start) * 1024.0))) # read it from memory rdbuf = iobuf.data_buffer(width) t_start = time.time() self.cpu.rdmem(adr, nx, rdbuf) t_end = time.time() ui.put('read %.2f KiB/sec\n' % (float(n)/((t_end - t_start) * 1024.0))) ui.put('read %s write\n' % ('!=', '==')[wrbuf.compare(rdbuf)])
def loadlib(self, lib, run = False): """load a library routine to ram""" # the cpu must be halted code = iobuf.data_buffer(32, lib['code']) self.wrmem(lib['load'], len(code), code) if run: return self.runlib(lib) return 0
def cmd_pic(self, ui, args): """display a pictorial summary of memory""" x = util.mem_args(ui, args, self.cpu.device) if x is None: return (adr, n) = x if n == 0: return if n is None: n = 0x40 # round down address to 32-bit byte boundary adr &= ~3 # round up n to an integral multiple of 4 bytes n = (n + 3) & ~3 # work out how many rows, columns and bytes per symbol we should display cols_max = 70 cols = cols_max + 1 bps = 1 # we try to display a matrix that is roughly square while cols > cols_max: bps *= 2 cols = int(math.sqrt(float(n) / float(bps))) rows = int(math.ceil(n / (float(cols) * float(bps)))) # bytes per row bpr = cols * bps # work out the none padding nwords = n / 4 nwords_displayed = (((cols * rows * bps) + 3) & ~3) / 4 none_pad = [ None, ] * ((nwords_displayed - nwords) * 4) # read the memory if n > (16 << 10): ui.put('reading memory ...\n') data = iobuf.data_buffer(32) self.cpu.rdmem32(adr, nwords, data) data.convert8(mode='le') # add the none padding data.buf.extend(none_pad) # display the summary ui.put("'.' all ones, '-' all zeroes, '$' various\n") ui.put('%d (0x%x) bytes per symbol\n' % (bps, bps)) ui.put('%d (0x%x) bytes per row\n' % (bpr, bpr)) ui.put('%d cols x %d rows\n' % (cols, rows)) # display the matrix ofs = 0 for y in range(rows): s = [] adr_str = '0x%08x: ' % (adr + ofs) for x in range(cols): s.append(self.__analyze(data.buf, ofs, bps)) ofs += bps ui.put('%s%s\n' % (adr_str, ''.join(s)))
def cmd_pic(self, ui, args): """display a pictorial summary of memory""" x = util.mem_args(ui, args, self.cpu.device) if x is None: return (adr, n) = x if n == 0: return if n is None: n = 0x40 # round down address to 32-bit byte boundary adr &= ~3 # round up n to an integral multiple of 4 bytes n = (n + 3) & ~3 # work out how many rows, columns and bytes per symbol we should display cols_max = 70 cols = cols_max + 1 bps = 1 # we try to display a matrix that is roughly square while cols > cols_max: bps *= 2 cols = int(math.sqrt(float(n)/float(bps))) rows = int(math.ceil(n / (float(cols) * float(bps)))) # bytes per row bpr = cols * bps # work out the none padding nwords = n / 4 nwords_displayed = (((cols * rows * bps) + 3) & ~3) / 4 none_pad = [None,] * ((nwords_displayed - nwords) * 4) # read the memory if n > (16 << 10): ui.put('reading memory ...\n') data = iobuf.data_buffer(32) self.cpu.rdmem32(adr, nwords, data) data.convert8(mode = 'le') # add the none padding data.buf.extend(none_pad) # display the summary ui.put("'.' all ones, '-' all zeroes, '$' various\n") ui.put('%d (0x%x) bytes per symbol\n' % (bps, bps)) ui.put('%d (0x%x) bytes per row\n' % (bpr, bpr)) ui.put('%d cols x %d rows\n' % (cols, rows)) # display the matrix ofs = 0 for y in range(rows): s = [] adr_str = '0x%08x: ' % (adr + ofs) for x in range(cols): s.append(self.__analyze(data.buf, ofs, bps)) ofs += bps ui.put('%s%s\n' % (adr_str, ''.join(s)))
def wr_mem32(self, adr, buf): """write 32-bit buffer to memory address""" assert adr & 3 == 0 # convert the 32-bit buffer to a array of bytes buf = iobuf.data_buffer(32, buf) buf.convert(8, 'le') buf = Array('B', buf.buf) # build the command cmd = Array('B', (STLINK_DEBUG_COMMAND, STLINK_DEBUG_WRITEMEM_32BIT)) append_u32(cmd, adr) append_u16(cmd, len(buf)) # send the command and buffer self.send_recv(cmd, 0) self.send_recv(buf, 0)
def cmd_test(self, width, ui, args): """test memory with a write and readback""" x = util.mem_args(ui, args, self.cpu.device) if x is None: return (adr, n) = x if n == 0: return if n is None: n = 0x40 # round down address to 32-bit byte boundary adr &= ~3 # round up n to an integral multiple of 4 bytes n = (n + 3) & ~3 # convert to n 32/16/8-bit units nx = n / (width / 8) maxval = (1 << width) - 1 # we will typically be testing ram, so halt the cpu. self.cpu.halt() # build a random write buffer wrbuf = iobuf.data_buffer(width) [wrbuf.write(random.randint(0, maxval)) for i in xrange(nx)] # write it to memory t_start = time.time() self.cpu.wrmem(adr, nx, wrbuf) t_end = time.time() ui.put('write %.2f KiB/sec\n' % (float(n) / ((t_end - t_start) * 1024.0))) # read it from memory rdbuf = iobuf.data_buffer(width) t_start = time.time() self.cpu.rdmem(adr, nx, rdbuf) t_end = time.time() ui.put('read %.2f KiB/sec\n' % (float(n) / ((t_end - t_start) * 1024.0))) ui.put('read %s write\n' % ('!=', '==')[wrbuf.compare(rdbuf)])
def cmd_md5(self, ui, args): """calculate an md5 hash of memory""" x = util.mem_args(ui, args, self.cpu.device) if x is None: return (adr, n) = x if n == 0: return if n is None: n = 0x40 # round down address to 32-bit byte boundary adr &= ~3 # round up n to an integral multiple of 4 bytes n = (n + 3) & ~3 # read the memory if n > (16 << 10): ui.put('reading memory ...\n') data = iobuf.data_buffer(32) t_start = time.time() self.cpu.rdmem(adr, n/4, data) t_end = time.time() ui.put('%s\n' % data.md5('le')) ui.put('%.2f KiB/sec\n' % (float(n)/((t_end - t_start) * 1024.0)))
def read(self): """read the buffer""" wr_ofs = self.cpu.rd(self.wr_ofs_adr, 32) rd_ofs = self.cpu.rd(self.rd_ofs_adr, 32) # do we have data? if wr_ofs != rd_ofs: # we have data - read it # TODO: possible performance improvement with 32 bit reads buf = iobuf.data_buffer(8) if rd_ofs < wr_ofs: # non-wrapped buffer: read to write offset self.cpu.rdmem(self.buf_adr + rd_ofs, wr_ofs - rd_ofs, buf) else: # wrapped buffer: read to end of buffer self.cpu.rdmem(self.buf_adr + rd_ofs, self.buf_size - rd_ofs, buf) # read to write offset self.cpu.rdmem(self.buf_adr, wr_ofs, buf) # we are caught up: read offset == write offset self.cpu.wr(self.rd_ofs_adr, wr_ofs, 32) return buf else: # no data return None
def cmd_md5(self, ui, args): """calculate an md5 hash of memory""" x = util.mem_args(ui, args, self.cpu.device) if x is None: return (adr, n) = x if n == 0: return if n is None: n = 0x40 # round down address to 32-bit byte boundary adr &= ~3 # round up n to an integral multiple of 4 bytes n = (n + 3) & ~3 # read the memory if n > (16 << 10): ui.put('reading memory ...\n') data = iobuf.data_buffer(32) t_start = time.time() self.cpu.rdmem(adr, n / 4, data) t_end = time.time() ui.put('%s\n' % data.md5('le')) ui.put('%.2f KiB/sec\n' % (float(n) / ((t_end - t_start) * 1024.0)))
def poll(self, ui): """poll this buffer""" wr_ofs = self.cpu.rd(self.wr_ofs_adr, 32) rd_ofs = self.cpu.rd(self.rd_ofs_adr, 32) ui.put('wr ofs 0x%x\n' % wr_ofs) ui.put('rd ofs 0x%x\n' % rd_ofs) if wr_ofs != rd_ofs: buf = iobuf.data_buffer(8) if rd_ofs < wr_ofs: # read to write offset self.cpu.rdmem(self.buf_adr + rd_ofs, wr_ofs - rd_ofs, buf) else: # read to end of buffer self.cpu.rdmem(self.buf_adr + rd_ofs, self.buf_size - rd_ofs, buf) # read to write offset self.cpu.rdmem(self.buf_adr, wr_ofs, buf) self.cpu.wr(self.rd_ofs_adr, wr_ofs, 32) ui.put('%d bytes read\n' % len(buf)) ui.put('%s\n' % buf.ascii_str()) else: ui.put('0 bytes read\n')
def __display(self, ui, args, width): """display memory: as width bits""" x = util.mem_args(ui, args, self.cpu.device) if x is None: return (adr, n) = x if n == 0: return if n is None: n = 0x40 # round down address to 16 byte boundary adr &= ~15 # round up n to an integral multiple of 16 bytes n = (n + 15) & ~15 # print the header if width == 8: ui.put( 'address 0 1 2 3 4 5 6 7 8 9 A B C D E F\n') elif width == 16: ui.put('address 0 2 4 6 8 A C E\n') elif width == 32: ui.put('address 0 4 8 C\n') else: assert False, 'bad width' # read and print the data for i in xrange(n / 16): # read 4, 32-bit words (16 bytes per line) io = iobuf.data_buffer(32) self.cpu.rdmem(adr, 4, io) # work out the data string io.convert(width, 'le') data_str = str(io) # work out the ascii string io.convert(8, 'le') ascii_str = io.ascii_str() ui.put('%08x: %s %s\n' % (adr, data_str, ascii_str)) adr += 16
def __display(self, ui, args, width): """display memory: as width bits""" x = util.mem_args(ui, args, self.cpu.device) if x is None: return (adr, n) = x if n == 0: return if n is None: n = 0x40 # round down address to 16 byte boundary adr &= ~15 # round up n to an integral multiple of 16 bytes n = (n + 15) & ~15 # print the header if width == 8: ui.put('address 0 1 2 3 4 5 6 7 8 9 A B C D E F\n') elif width == 16: ui.put('address 0 2 4 6 8 A C E\n') elif width == 32: ui.put('address 0 4 8 C\n') else: assert False, 'bad width' # read and print the data for i in xrange(n/16): # read 4, 32-bit words (16 bytes per line) io = iobuf.data_buffer(32) self.cpu.rdmem(adr, 4, io) # work out the data string io.convert(width, 'le') data_str = str(io) # work out the ascii string io.convert(8, 'le') ascii_str = io.ascii_str() ui.put('%08x: %s %s\n' % (adr, data_str, ascii_str)) adr += 16
def rd16(self, adr): """read 16 bit value from adr""" io = iobuf.data_buffer(16) self.rdmem16(adr, 1, io) return io.read()
def wr16(self, adr, val): """write 16 bit value to adr""" io = iobuf.data_buffer(16, (val,)) self.wrmem16(adr, 1, io)
def wr16(self, adr, val): """write 16 bit value to adr""" io = iobuf.data_buffer(16, (val, )) self.wrmem16(adr, 1, io)