forked from auracaster/openocd
arm_adi_v5: fix wrong addressing after change of CSW_ADDRINC
Problem: If the same memory location is accessed alternatively
by MEM-AP banked data registers without autoincrement and by standard
autoincremented read/write, TAR register is not updated correctly.
How to replicate: On a Cortex-M issue
mdw 0xe000edf0
multiple times. When poll is on (poll reads the same memory location)
only the first read is correct.
0xe000edf0: 01000000
0xe000edf0: 00000000
0xe000edf0: 20002640
0xe000edf0: 01000000
0xe000edf0: 00000000
0xe000edf0: 00000000
No problems with poll off.
0xe000edf0: 01000000
0xe000edf0: 01000000
0xe000edf0: 01000000
mem_ap_setup_tar() writes to MEM_AP_REG_TAR if requested TAR value
changed or CSW_ADDRINC_... is currently active.
However if an autoincremented access has been issued and autoinc
switched off in CSW afterwards, TAR does not get updated.
The change introduces mem_ap_update_tar_cache() which is called
after queuing of any access to MEM_AP_REG_DRW. It simulates
TAR increment to keep tar_value in sync with MEM_AP.
Crossing tar autoincrement block boundary invalidates cached value.
mem_ap_write() and mem_ap_read() do not check tar autoincrement
block boundary, mem_ap_setup_tar() is called before each transfer instead.
dap_invalidate_cache() is introduced to ensure invalidation
of all cached values during dap_dp_init() and swd_connect()
Change-Id: I815c2283d2989cffd6ea9a4100ce2f29dc3fb7b4
Signed-off-by: Tomas Vanek <vanekt@fbl.cz>
Reviewed-on: http://openocd.zylin.com/4162
Tested-by: jenkins
Reviewed-by: Christopher Head <chead@zaber.com>
Reviewed-by: Andreas Fritiofson <andreas.fritiofson@gmail.com>
This commit is contained in:
committed by
Andreas Fritiofson
parent
ada631cc5f
commit
4553abf906
@@ -102,6 +102,7 @@
|
||||
#define AP_REG_IDR 0xFC /* RO: Identification Register */
|
||||
|
||||
/* Fields of the MEM-AP's CSW register */
|
||||
#define CSW_SIZE_MASK 7
|
||||
#define CSW_8BIT 0
|
||||
#define CSW_16BIT 1
|
||||
#define CSW_32BIT 2
|
||||
@@ -180,6 +181,9 @@ struct adiv5_ap {
|
||||
|
||||
/* true if unaligned memory access is not supported by the MEM-AP */
|
||||
bool unaligned_access_bad;
|
||||
|
||||
/* true if tar_value is in sync with TAR register */
|
||||
bool tar_valid;
|
||||
};
|
||||
|
||||
|
||||
@@ -476,6 +480,9 @@ struct adiv5_dap *dap_init(void);
|
||||
int dap_dp_init(struct adiv5_dap *dap);
|
||||
int mem_ap_init(struct adiv5_ap *ap);
|
||||
|
||||
/* Invalidate cached DP select and cached TAR and CSW of all APs */
|
||||
void dap_invalidate_cache(struct adiv5_dap *dap);
|
||||
|
||||
/* Probe the AP for ROM Table location */
|
||||
int dap_get_debugbase(struct adiv5_ap *ap,
|
||||
uint32_t *dbgbase, uint32_t *apid);
|
||||
|
||||
Reference in New Issue
Block a user