Skip to content

Commit

Permalink
v8M: define extra v8-M and v8.1-M core registers.
Browse files Browse the repository at this point in the history
- Added some core registers like MSPLIM and related.
- Added extension enums for v8.1 security additions and MVE FP support.
- Detecting the MVE extension.
- Added VPR register for MVE.
  • Loading branch information
flit committed Aug 16, 2020
1 parent 822308c commit 460fc54
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 2 deletions.
4 changes: 3 additions & 1 deletion pyocd/coresight/core_ids.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ class CortexMExtension(Enum):
FPU_DP = "FPU_DP" # Double-Precision floating point
FPU_HP = "FPU_HP" # Half-Precision floating point
SEC = "SEC" # Security Extension
MVE = "MVE" # M-profile Vector Extension
SEC_V81 = "SEC_V81" # v8.1-M additions to the Security Extension
MVE = "MVE" # M-profile Vector Extension, with integer support
MVE_FP = "MVE_FP" # M-profile Vector Extension single- and half-precision floating-point
UDE = "UDE" # Unprivileged Debug Extension
RAS = "RAS" # Reliability, Serviceability, and Availability
PMU = "PMU" # Performance Monitoring Unit
Expand Down
29 changes: 29 additions & 0 deletions pyocd/coresight/cortex_m_core_registers.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,32 @@ class CoreRegisterGroups:
_I('faultmask', -3, 32, 'int', 'system', 39, "org.gnu.gdb.arm.m-profile"),
]

## @brief Extra registers available with only with the Security extension.
V8M_SEC_ONLY = [
# Name index bits type group gdbnum feature
_I('msp_ns', 24, 32, 'data_ptr', 'stack', 40, "v8-m.sp"),
_I('psp_ns', 25, 32, 'data_ptr', 'stack', 41, "v8-m.sp"),
_I('msp_s', 26, 32, 'data_ptr', 'stack', 42, "v8-m.sp"),
_I('psp_s', 27, 32, 'data_ptr', 'stack', 43, "v8-m.sp"),
_I('msplim_s', 28, 32, 'int', 'stack', 46, "v8-m.sp"),
_I('psplim_s', 29, 32, 'int', 'stack', 47, "v8-m.sp"),
_I('cfbp_s', 34, 32, 'int', 'system'),
_I('cfbp_ns', 35, 32, 'int', 'system'),
]

## @brief The NS stack limits are only available when both Main and Security extensions are present.
V8M_ML_SEC_ONLY = [
# Name index bits type group gdbnum feature
_I('msplim_ns', 30, 32, 'int', 'stack', 44, "v8-m.sp"),
_I('psplim_ns', 31, 32, 'int', 'stack', 45, "v8-m.sp"),
]

## @brief Registers only available with the MVE extension.
V81M_MVE_ONLY = [
# Name index bits type group gdbnum feature
_I('vpr', 36, 32, 'int', 'mve', 44, "v8-m.mve"),
]

## @brief VFPv5 floating point registers.
#
# GDB understands the double/single separation so we don't need to separately pass the single regs,
Expand Down Expand Up @@ -223,6 +249,9 @@ class CoreRegisterGroups:
# Build info map.
CortexMCoreRegisterInfo.add_to_map(CoreRegisterGroups.M_PROFILE_COMMON
+ CoreRegisterGroups.V7M_v8M_ML_ONLY
+ CoreRegisterGroups.V8M_SEC_ONLY
+ CoreRegisterGroups.V8M_ML_SEC_ONLY
+ CoreRegisterGroups.V81M_MVE_ONLY
+ CoreRegisterGroups.VFP_V5)

def index_for_reg(name):
Expand Down
38 changes: 37 additions & 1 deletion pyocd/coresight/cortex_m_v8m.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ class CortexM_v8M(CortexM):
PFR1_SECURITY_EXT_V8_0 = 0x1 # Base security extension.
PFR1_SECURITY_EXT_V8_1 = 0x3 # v8.1-M adds several instructions.

# Media and FP Feature Register 1
MVFR1 = 0xE000EF44
MVFR1_MVE_MASK = 0x00000f00
MVFR1_MVE_SHIFT = 8
MVFR1_MVE__INTEGER = 0x1
MVFR1_MVE__FLOAT = 0x2

def __init__(self, rootTarget, ap, memoryMap=None, core_num=0, cmpid=None, address=None):
super(CortexM_v8M, self).__init__(rootTarget, ap, memoryMap, core_num, cmpid, address)

Expand Down Expand Up @@ -85,6 +92,8 @@ def _read_core_type(self):
self.has_security_extension = pfr1_sec in (self.PFR1_SECURITY_EXT_V8_0, self.PFR1_SECURITY_EXT_V8_1)
if self.has_security_extension:
self._extensions.append(CortexMExtension.SEC)
if pfr1_sec == self.PFR1_SECURITY_EXT_V8_1:
self._extensions.append(CortexMExtension.SEC_V81)

if arch == self.ARMv8M_BASE:
self._architecture = CoreArchitecture.ARMv8M_BASE
Expand All @@ -99,13 +108,40 @@ def _read_core_type(self):
else:
LOG.warning("CPU core #%d type is unrecognized", self.core_number)

def _check_for_fpu(self):
"""! @brief Determine if a core has an FPU.
In addition to the tests performed by CortexM, this method tests for the MVE extension.
"""
super(CortexM_v8M, self)._check_for_fpu()

# Check for MVE.
mvfr1 = self.read32(self.MVFR1)
mve = (mvfr1 & self.MVFR1_MVE_MASK) >> self.MVFR1_MVE_SHIFT
if mve == self.MVFR1_MVE__INTEGER:
self.extensions.append(CortexMExtension.MVE)
elif mve == self.MVFR1_MVE__FLOAT:
self.extensions += [CortexMExtension.MVE, CortexMExtension.MVE_FP]

def _build_registers(self):
super(CortexM_v8M, self)._build_registers()

# Registers available with Security extension, either Baseline or Mainline.
if self.has_security_extension:
self._core_registers.add_group(CoreRegisterGroups.V8M_SEC_ONLY)

# Mainline-only registers.
if self.architecture == CoreArchitecture.ARMv8M_MAIN:
self._core_registers.add_group(CoreRegisterGroups.V7M_v8M_ML_ONLY)


# Registers available when both Mainline and Security extensions are implemented.
if self.has_security_extension:
self._core_registers.add_group(CoreRegisterGroups.V8M_ML_SEC_ONLY)

# MVE registers.
if CortexMExtension.MVE in self.extensions:
self._core_registers.add_group(CoreRegisterGroups.V81M_MVE_ONLY)

def get_security_state(self):
"""! @brief Returns the current security state of the processor.
Expand Down

0 comments on commit 460fc54

Please sign in to comment.