@@ -209,7 +209,6 @@ int libswd_memap_read_char(libswd_ctx_t *libswdctx, libswd_operation_t operation
209209 return LIBSWD_ERROR_BADOPCODE ;
210210
211211 int i , loc , res = 0 , accsize = 0 , * memapdrw ;
212- int chunk , chunks , chunksize = 1024 ;
213212 float tdeltam ;
214213 struct timeval tstart , tstop ;
215214
@@ -285,41 +284,54 @@ int libswd_memap_read_char(libswd_ctx_t *libswdctx, libswd_operation_t operation
285284 else
286285 {
287286 // Use TAR Auto Increment (faster).
288- // 2^10 chunks are used due to TAR Auto Increment limitations.
287+ // TAR auto increment is only guaranteed to work on the bottom 10 bits
288+ // of the TAR register. Above that it is implementation defined.
289+ // We use 1024 byte chunks as it will work on every platform
290+ // and one TAR write every 1024 bytes is not adding too much overhead.
291+ const unsigned int BOUNDARY = 1024 ;
292+ unsigned int i ;
293+
289294 // Check if packed transfer, if so use word access.
290295 if (libswdctx -> log .memap .csw & LIBSWD_MEMAP_CSW_ADDRINC_PACKED ) accsize = 4 ;
291- chunks = count / chunksize ;
292- for (chunk = 0 ; chunk * chunksize < count ; chunk ++ )
296+
297+ for (loc = addr , i = 0 ; loc < ( addr + count ); loc += accsize , i += accsize )
293298 {
294299 int tmp ;
295300 int drw_shift ;
296- loc = addr + chunk * chunksize ;
301+
297302 // Calculate the offset in DRW where the data should be
298303 // see Data byte-laning in the ARM debug interface v5 documentation
299304 // note: this only works for little endian systems.
300305 drw_shift = 8 * (loc %4 );
301- // Pass address to TAR register.
302- res = libswd_ap_write (libswdctx , LIBSWD_OPERATION_EXECUTE , LIBSWD_MEMAP_TAR_ADDR , & loc );
303- if (res < 0 ) goto libswd_memap_read_char_error ;
304- libswdctx -> log .memap .tar = loc ;
305- for (i = 0 ;i < chunksize ;i += accsize )
306+
307+ // only write the TAR register, if this is the first time through the loop.
308+ // or if we've passed over the boundary where TAR auto inc isn't guaranteed
309+ // to work anymore.
310+ if (loc == addr ||
311+ (loc % BOUNDARY ) == 0 )
306312 {
307- if ((chunk * chunksize )+ i >=count ) break ;
308- // Measure transfer speed.
309- gettimeofday (& tstop , NULL );
310- tdeltam = fabsf ((tstop .tv_sec - tstart .tv_sec )* 1000 + (tstop .tv_usec - tstart .tv_usec )/1000 );
311- libswd_log (libswdctx , LIBSWD_LOGLEVEL_INFO ,
312- "LIBSWD_I: libswd_memap_read_char() reading address 0x%08X (chunk 0x%X/0x%X, speed %fKB/s)\r" ,
313- loc + i , chunk , chunks , count /tdeltam );
314- fflush (0 );
315- // Implode and Write data to DRW register.
316- res = libswd_ap_read (libswdctx , LIBSWD_OPERATION_EXECUTE , LIBSWD_MEMAP_DRW_ADDR , & memapdrw );
313+ // Pass address to TAR register.
314+ res = libswd_ap_write (libswdctx , LIBSWD_OPERATION_EXECUTE , LIBSWD_MEMAP_TAR_ADDR , & loc );
317315 if (res < 0 ) goto libswd_memap_read_char_error ;
318- libswdctx -> log .memap .drw = * memapdrw ;
319- // apply the data byte-laning shift
320- tmp = * memapdrw >>= drw_shift ;
321- memcpy ((void * )data + (chunk * chunksize )+ i , & tmp , accsize );
316+ libswdctx -> log .memap .tar = loc ;
322317 }
318+
319+ // Measure transfer speed.
320+ gettimeofday (& tstop , NULL );
321+ tdeltam = fabsf ((tstop .tv_sec - tstart .tv_sec )* 1000 + (tstop .tv_usec - tstart .tv_usec )/1000 );
322+ libswd_log (libswdctx , LIBSWD_LOGLEVEL_INFO ,
323+ "LIBSWD_I: libswd_memap_read_char() reading address 0x%08X (speed %fKB/s)\r" ,
324+ loc , count /tdeltam );
325+ fflush (0 );
326+
327+ // Read data from the DRW register.
328+ res = libswd_ap_read (libswdctx , LIBSWD_OPERATION_EXECUTE , LIBSWD_MEMAP_DRW_ADDR , & memapdrw );
329+ if (res < 0 ) goto libswd_memap_read_char_error ;
330+ libswdctx -> log .memap .drw = * memapdrw ;
331+
332+ // apply the data byte-laning shift
333+ tmp = * memapdrw >>= drw_shift ;
334+ memcpy ((void * )data + i , & tmp , accsize );
323335 }
324336 libswd_log (libswdctx , LIBSWD_LOGLEVEL_INFO , "\n" );
325337 }
@@ -440,7 +452,6 @@ int libswd_memap_read_int(libswd_ctx_t *libswdctx, libswd_operation_t operation,
440452 return LIBSWD_ERROR_BADOPCODE ;
441453
442454 int i , loc , res , * memapdrw ;
443- int chunk , chunks , chunksize = 1024 ;
444455 float tdeltam ;
445456 struct timeval tstart , tstop ;
446457
@@ -483,32 +494,40 @@ int libswd_memap_read_int(libswd_ctx_t *libswdctx, libswd_operation_t operation,
483494 else
484495 {
485496 // Use TAR Auto Increment (faster).
486- // 2^10 chunks are used due to TAR Auto Increment limitations.
487- // Check if packed transfer, if so use word access.
488- chunks = count /chunksize ;
489- for (chunk = 0 ;chunk * chunksize < count ;chunk ++ )
497+ // TAR auto increment is only guaranteed to work on the bottom 10 bits
498+ // of the TAR register. Above that it is implementation defined.
499+ // We use 1024 byte chunks as it will work on every platform
500+ // and one TAR write every 1024 bytes is not adding too much overhead.
501+ const unsigned int BOUNDARY = 1024 ;
502+ unsigned int i ;
503+
504+ for (loc = addr , i = 0 ; loc < (addr + (count * 4 )); loc += 4 , i ++ )
490505 {
491- loc = addr + chunk * chunksize ;
492- // Pass address to TAR register.
493- res = libswd_ap_write (libswdctx , LIBSWD_OPERATION_EXECUTE , LIBSWD_MEMAP_TAR_ADDR , & loc );
494- if (res < 0 ) goto libswd_memap_read_int_error ;
495- libswdctx -> log .memap .tar = loc ;
496- for (i = 0 ;i < chunksize ;i ++ )
506+ // only write the TAR register, if this is the first time through the loop.
507+ // or if we've passed over the boundary where TAR auto inc isn't guaranteed
508+ // to work anymore.
509+ if (loc == addr ||
510+ (loc % BOUNDARY ) == 0 )
497511 {
498- if ((chunk * chunksize )+ (i * 4 )>=count ) break ;
499- // Measure transfer speed.
500- gettimeofday (& tstop , NULL );
501- tdeltam = fabsf ((tstop .tv_sec - tstart .tv_sec )* 1000 + (tstop .tv_usec - tstart .tv_usec )/1000 );
502- libswd_log (libswdctx , LIBSWD_LOGLEVEL_INFO ,
503- "LIBSWD_I: libswd_memap_read_int() reading address 0x%08X (chunk 0x%X/0x%X, speed %fKB/s)\r" ,
504- loc + (i * 4 ), chunk , chunks , count * 4 /tdeltam );
505- fflush (0 );
506- // Write data to DRW register.
507- res = libswd_ap_read (libswdctx , LIBSWD_OPERATION_EXECUTE , LIBSWD_MEMAP_DRW_ADDR , & memapdrw );
512+ // Pass address to TAR register.
513+ res = libswd_ap_write (libswdctx , LIBSWD_OPERATION_EXECUTE , LIBSWD_MEMAP_TAR_ADDR , & loc );
508514 if (res < 0 ) goto libswd_memap_read_int_error ;
509- libswdctx -> log .memap .drw = * memapdrw ;
510- data [chunk * chunksize + i ]= * memapdrw ;
515+ libswdctx -> log .memap .tar = loc ;
511516 }
517+
518+ // Measure transfer speed.
519+ gettimeofday (& tstop , NULL );
520+ tdeltam = fabsf ((tstop .tv_sec - tstart .tv_sec )* 1000 + (tstop .tv_usec - tstart .tv_usec )/1000 );
521+ libswd_log (libswdctx , LIBSWD_LOGLEVEL_INFO ,
522+ "LIBSWD_I: libswd_memap_read_int() reading address 0x%08X (speed %fKB/s)\r" ,
523+ loc , count * 4 /tdeltam );
524+ fflush (0 );
525+
526+ // Read data from the DRW register.
527+ res = libswd_ap_read (libswdctx , LIBSWD_OPERATION_EXECUTE , LIBSWD_MEMAP_DRW_ADDR , & memapdrw );
528+ if (res < 0 ) goto libswd_memap_read_int_error ;
529+ libswdctx -> log .memap .drw = * memapdrw ;
530+ data [i ]= * memapdrw ;
512531 }
513532 libswd_log (libswdctx , LIBSWD_LOGLEVEL_INFO , "\n" );
514533 }
@@ -622,7 +641,6 @@ int libswd_memap_write_char(libswd_ctx_t *libswdctx, libswd_operation_t operatio
622641 return LIBSWD_ERROR_BADOPCODE ;
623642
624643 int i , loc , res = 0 , accsize = 0 ;
625- int chunk , chunks , chunksize = 1024 ;
626644 float tdeltam ;
627645 struct timeval tstart , tstop ;
628646
@@ -696,39 +714,50 @@ int libswd_memap_write_char(libswd_ctx_t *libswdctx, libswd_operation_t operatio
696714 else
697715 {
698716 // Use TAR Auto Increment (faster).
699- // 2^10 chunks are used due to TAR Auto Increment limitations.
717+ // TAR auto increment is only guaranteed to work on the bottom 10 bits
718+ // of the TAR register. Above that it is implementation defined.
719+ // We use 1024 byte chunks as it will work on every platform
720+ // and one TAR write every 1024 bytes is not adding too much overhead.
721+ const unsigned int BOUNDARY = 1024 ;
722+ unsigned int i ;
723+
700724 // Check if packed transfer, if so use word access.
701725 if (libswdctx -> log .memap .csw & LIBSWD_MEMAP_CSW_ADDRINC_PACKED ) accsize = 4 ;
702- chunks = count / chunksize ;
703- for (chunk = 0 ; chunk * chunksize < count ; chunk ++ )
726+
727+ for (loc = addr , i = 0 ; loc < ( addr + count ); loc += accsize , i += accsize )
704728 {
705729 int drw_shift ;
706- loc = addr + chunk * chunksize ;
730+
707731 // Calculate the offset in DRW where the data should go
708732 // see Data byte-laning in the ARM debug interface v5 documentation
709733 // note: this only works for little endian systems.
710734 drw_shift = 8 * (loc %4 );
711- // Pass address to TAR register.
712- res = libswd_ap_write (libswdctx , LIBSWD_OPERATION_EXECUTE , LIBSWD_MEMAP_TAR_ADDR , & loc );
713- if (res < 0 ) goto libswd_memap_write_char_error ;
714- libswdctx -> log .memap .tar = loc ;
715- for (i = 0 ;i < chunksize ;i += accsize )
735+
736+ // only write the TAR register, if this is the first time through the loop.
737+ // or if we've passed over the boundary where TAR auto inc isn't guaranteed
738+ // to work anymore.
739+ if (loc == addr ||
740+ (loc % BOUNDARY ) == 0 )
716741 {
717- if ((chunk * chunksize )+ i >=count ) break ;
718- // Measure transfer speed.
719- gettimeofday (& tstop , NULL );
720- tdeltam = fabsf ((tstop .tv_sec - tstart .tv_sec )* 1000 + (tstop .tv_usec - tstart .tv_usec )/1000 );
721- libswd_log (libswdctx , LIBSWD_LOGLEVEL_INFO ,
722- "LIBSWD_I: libswd_memap_write_char() writing address 0x%08X (chunk 0x%X/0x%X, speed %fKB/s)\r" ,
723- loc + i , chunk , chunks , count /tdeltam );
724- fflush (0 );
725- // Implode and Write data to DRW register.
726- memcpy ((void * )& libswdctx -> log .memap .drw , data + (chunk * chunksize )+ i , accsize );
727- // apply the data byte-laning shift
728- libswdctx -> log .memap .drw <<= drw_shift ;
729- res = libswd_ap_write (libswdctx , LIBSWD_OPERATION_EXECUTE , LIBSWD_MEMAP_DRW_ADDR , & libswdctx -> log .memap .drw );
742+ // Pass address to TAR register.
743+ res = libswd_ap_write (libswdctx , LIBSWD_OPERATION_EXECUTE , LIBSWD_MEMAP_TAR_ADDR , & loc );
730744 if (res < 0 ) goto libswd_memap_write_char_error ;
745+ libswdctx -> log .memap .tar = loc ;
731746 }
747+
748+ // Measure transfer speed.
749+ gettimeofday (& tstop , NULL );
750+ tdeltam = fabsf ((tstop .tv_sec - tstart .tv_sec )* 1000 + (tstop .tv_usec - tstart .tv_usec )/1000 );
751+ libswd_log (libswdctx , LIBSWD_LOGLEVEL_INFO ,
752+ "LIBSWD_I: libswd_memap_write_char() writing address 0x%08X (speed %fKB/s)\r" ,
753+ loc , count /tdeltam );
754+ fflush (0 );
755+
756+ // apply the data byte-laning shift and write to the DRW register
757+ memcpy ((void * )& libswdctx -> log .memap .drw , data + i , accsize );
758+ libswdctx -> log .memap .drw <<= drw_shift ;
759+ res = libswd_ap_write (libswdctx , LIBSWD_OPERATION_EXECUTE , LIBSWD_MEMAP_DRW_ADDR , & libswdctx -> log .memap .drw );
760+ if (res < 0 ) goto libswd_memap_write_char_error ;
732761 }
733762 libswd_log (libswdctx , LIBSWD_LOGLEVEL_INFO , "\n" );
734763 }
@@ -845,7 +874,6 @@ int libswd_memap_write_int(libswd_ctx_t *libswdctx, libswd_operation_t operation
845874 return LIBSWD_ERROR_BADOPCODE ;
846875
847876 int i , loc , res = 0 ;
848- int chunk , chunks , chunksize = 1024 ;
849877 float tdeltam ;
850878 struct timeval tstart , tstop ;
851879
@@ -887,31 +915,39 @@ int libswd_memap_write_int(libswd_ctx_t *libswdctx, libswd_operation_t operation
887915 else
888916 {
889917 // Use TAR Auto Increment (faster).
890- // 2^10 chunks are used due to TAR Auto Increment limitations.
891- // Check if packed transfer, if so use word access.
892- chunks = count /chunksize ;
893- for (chunk = 0 ;chunk * chunksize < count ;chunk ++ )
918+ // TAR auto increment is only guaranteed to work on the bottom 10 bits
919+ // of the TAR register. Above that it is implementation defined.
920+ // We use 1024 byte chunks as it will work on every platform
921+ // and one TAR write every 1024 bytes is not adding too much overhead.
922+ const unsigned int BOUNDARY = 1024 ;
923+ unsigned int i ;
924+
925+ for (loc = addr , i = 0 ; loc < (addr + (count * 4 )); loc += 4 , i ++ )
894926 {
895- loc = addr + chunk * chunksize ;
896- // Pass address to TAR register.
897- res = libswd_ap_write (libswdctx , LIBSWD_OPERATION_EXECUTE , LIBSWD_MEMAP_TAR_ADDR , & loc );
898- if (res < 0 ) goto libswd_memap_write_int_error ;
899- libswdctx -> log .memap .tar = loc ;
900- for (i = 0 ;i < chunksize ;i ++ )
927+ // only write the TAR register, if this is the first time through the loop.
928+ // or if we've passed over the boundary where TAR auto inc isn't guaranteed
929+ // to work anymore.
930+ if (loc == addr ||
931+ (loc % BOUNDARY ) == 0 )
901932 {
902- if ((chunk * chunksize )+ (i * 4 )>=count ) break ;
903- // Measure transfer speed.
904- gettimeofday (& tstop , NULL );
905- tdeltam = fabsf ((tstop .tv_sec - tstart .tv_sec )* 1000 + (tstop .tv_usec - tstart .tv_usec )/1000 );
906- libswd_log (libswdctx , LIBSWD_LOGLEVEL_INFO ,
907- "LIBSWD_I: libswd_memap_write_int() writing address 0x%08X (chunk 0x%X/0x%X speed %fKB/s)\r" ,
908- loc + (i * 4 ), chunk , chunks , count * 4 /tdeltam );
909- fflush (0 );
910- // Implode and Write data to DRW register.
911- libswdctx -> log .memap .drw = data [chunk * chunksize + i ];
912- res = libswd_ap_write (libswdctx , LIBSWD_OPERATION_EXECUTE , LIBSWD_MEMAP_DRW_ADDR , & libswdctx -> log .memap .drw );
933+ // Pass address to TAR register.
934+ res = libswd_ap_write (libswdctx , LIBSWD_OPERATION_EXECUTE , LIBSWD_MEMAP_TAR_ADDR , & loc );
913935 if (res < 0 ) goto libswd_memap_write_int_error ;
936+ libswdctx -> log .memap .tar = loc ;
914937 }
938+
939+ // Measure transfer speed.
940+ gettimeofday (& tstop , NULL );
941+ tdeltam = fabsf ((tstop .tv_sec - tstart .tv_sec )* 1000 + (tstop .tv_usec - tstart .tv_usec )/1000 );
942+ libswd_log (libswdctx , LIBSWD_LOGLEVEL_INFO ,
943+ "LIBSWD_I: libswd_memap_write_int() writing address 0x%08X (speed %fKB/s)\r" ,
944+ loc , count * 4 /tdeltam );
945+ fflush (0 );
946+
947+ // Write data to DRW register.
948+ libswdctx -> log .memap .drw = data [i ];
949+ res = libswd_ap_write (libswdctx , LIBSWD_OPERATION_EXECUTE , LIBSWD_MEMAP_DRW_ADDR , & libswdctx -> log .memap .drw );
950+ if (res < 0 ) goto libswd_memap_write_int_error ;
915951 }
916952 libswd_log (libswdctx , LIBSWD_LOGLEVEL_INFO , "\n" );
917953 }
0 commit comments