Skip to content

Commit a17c589

Browse files
committed
MEM_AP: check supported address size and mask addresses.
- _init_cfg() is called for all AP versions now. - Check whether the Large Address extension is enabled. - Addresses passed into read/write routines are masked based on the supported address size. - Fixed invalid initial value for _transfer_sizes attribute.
1 parent ec3d941 commit a17c589

File tree

1 file changed

+32
-22
lines changed

1 file changed

+32
-22
lines changed

pyocd/coresight/ap.py

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ def __init__(self, dp, ap_address, idr=None, name="", flags=0, cmpid=None):
485485
self._cached_csw = -1
486486

487487
## Supported transfer sizes.
488-
self._transfer_sizes = (32)
488+
self._transfer_sizes = (32,)
489489

490490
## Auto-increment wrap modulus.
491491
#
@@ -497,6 +497,9 @@ def __init__(self, dp, ap_address, idr=None, name="", flags=0, cmpid=None):
497497
## Number of DAR registers.
498498
self._dar_count = 0
499499

500+
## Mask of addresses. This indicates whether 32-bit or 64-bit addresses are supported.
501+
self._address_mask = 0xffffffff
502+
500503
# Ask the probe for an accelerated memory interface for this AP. If it provides one,
501504
# then bind our memory interface APIs to its methods. Otherwise use our standard
502505
# memory interface based on AP register accesses.
@@ -525,10 +528,7 @@ def init(self):
525528
self._init_transfer_sizes()
526529
self._init_hprot()
527530
self._init_rom_table_base()
528-
529-
# For v2 MEM-APs, read the CFG register.
530-
if self.ap_version == APVersion.APv2:
531-
self._init_cfg()
531+
self._init_cfg()
532532

533533
def _init_transfer_sizes(self):
534534
"""! @brief Determine supported transfer sizes.
@@ -609,28 +609,34 @@ def _init_rom_table_base(self):
609609
raise exceptions.TargetError("invalid AP BASE value 0x%08x" % base)
610610

611611
def _init_cfg(self):
612-
"""! @brief Read MEM-APv2 CFG register."""
612+
"""! @brief Read MEM-AP CFG register."""
613613
cfg = self.read_reg(self._reg_offset + MEM_AP_CFG)
614614

615-
# Set autoinc page size if TARINC is non-zero. Otherwise we've already set the
616-
# default of 1 kB in the ctor.
617-
tarinc = (cfg & MEM_AP_CFG_TARINC_MASK) >> MEM_AP_CFG_TARINC_SHIFT
618-
if tarinc != 0:
619-
self.auto_increment_page_size = 1 << (9 + tarinc)
615+
# Check for 64-bit address support.
616+
if cfg & MEM_AP_CFG_LA_MASK:
617+
self._address_mask = 0xffffffffffffffff
618+
619+
# Check v2 MEM-AP CFG fields.
620+
if self.ap_version == APVersion.APv2:
621+
# Set autoinc page size if TARINC is non-zero. Otherwise we've already set the
622+
# default of 1 kB in the ctor.
623+
tarinc = (cfg & MEM_AP_CFG_TARINC_MASK) >> MEM_AP_CFG_TARINC_SHIFT
624+
if tarinc != 0:
625+
self.auto_increment_page_size = 1 << (9 + tarinc)
620626

621-
# Determine supported err mode.
622-
err = (cfg & MEM_AP_CFG_ERR_MASK) >> MEM_AP_CFG_ERR_SHIFT
623-
if err == MEM_AP_CFG_ERR_V1:
624-
# Configure the error mode such that errors are passed upstream, but they don't
625-
# prevent future transactions.
626-
self._csw &= ~(CSW_ERRSTOP | CSW_ERRNPASS)
627+
# Determine supported err mode.
628+
err = (cfg & MEM_AP_CFG_ERR_MASK) >> MEM_AP_CFG_ERR_SHIFT
629+
if err == MEM_AP_CFG_ERR_V1:
630+
# Configure the error mode such that errors are passed upstream, but they don't
631+
# prevent future transactions.
632+
self._csw &= ~(CSW_ERRSTOP | CSW_ERRNPASS)
627633

628-
# Clear TRR in case we attach to a device with a sticky error already set.
629-
self.write_reg(self._reg_offset + MEM_AP_TRR, MEM_AP_TRR_ERR_MASK)
634+
# Clear TRR in case we attach to a device with a sticky error already set.
635+
self.write_reg(self._reg_offset + MEM_AP_TRR, MEM_AP_TRR_ERR_MASK)
630636

631-
# Init size of DAR register window.
632-
darsize = (cfg & MEM_AP_CFG_DARSIZE_MASK) >> MEM_AP_CFG_DARSIZE_SHIFT
633-
self._dar_count = (1 << darsize) // 4
637+
# Init size of DAR register window.
638+
darsize = (cfg & MEM_AP_CFG_DARSIZE_MASK) >> MEM_AP_CFG_DARSIZE_SHIFT
639+
self._dar_count = (1 << darsize) // 4
634640

635641
@locked
636642
def find_components(self):
@@ -796,6 +802,7 @@ def _write_memory(self, addr, data, transfer_size=32):
796802
@exception TransferError Raised if the requested transfer size is not supported by the AP.
797803
"""
798804
assert (addr & (transfer_size // 8 - 1)) == 0
805+
addr &= self._address_mask
799806
if transfer_size not in self._transfer_sizes:
800807
raise exceptions.TransferError("%d-bit transfers are not supported by %s"
801808
% (transfer_size, self.short_description))
@@ -831,6 +838,7 @@ def _read_memory(self, addr, transfer_size=32, now=True):
831838
@exception TransferError Raised if the requested transfer size is not supported by the AP.
832839
"""
833840
assert (addr & (transfer_size // 8 - 1)) == 0
841+
addr &= self._address_mask
834842
if transfer_size not in self._transfer_sizes:
835843
raise exceptions.TransferError("%d-bit transfers are not supported by %s"
836844
% (transfer_size, self.short_description))
@@ -937,6 +945,7 @@ def _read_block32_page(self, addr, size):
937945
def _write_memory_block32(self, addr, data):
938946
"""! @brief Write a block of aligned words in memory."""
939947
assert (addr & 0x3) == 0
948+
addr &= self._address_mask
940949
size = len(data)
941950
while size > 0:
942951
n = self.auto_increment_page_size - (addr & (self.auto_increment_page_size - 1))
@@ -955,6 +964,7 @@ def _read_memory_block32(self, addr, size):
955964
@return A list of word values.
956965
"""
957966
assert (addr & 0x3) == 0
967+
addr &= self._address_mask
958968
resp = []
959969
while size > 0:
960970
n = self.auto_increment_page_size - (addr & (self.auto_increment_page_size - 1))

0 commit comments

Comments
 (0)