Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Trace Funnel Coresight component #1592

Merged
merged 2 commits into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions pyocd/coresight/component_ids.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from .tpiu import TPIU
from .gpr import GPR
from .sdc600 import SDC600
from .funnel import TraceFunnel

if TYPE_CHECKING:
from .component import CoreSightComponent
Expand Down Expand Up @@ -120,7 +121,7 @@ class CmpInfo(NamedTuple):
(ARM_ID, CORESIGHT_CLASS, 0x193, 0x00, 0x0a57) : CmpInfo('TSGEN', 'CS-600', None ),
(ARM_ID, CORESIGHT_CLASS, 0x906, 0x14, 0) : CmpInfo('CTI', 'CS-400', None ),
(ARM_ID, CORESIGHT_CLASS, 0x907, 0x21, 0) : CmpInfo('ETB', 'CS-400', None ),
(ARM_ID, CORESIGHT_CLASS, 0x908, 0x12, 0) : CmpInfo('Trace Funnel', 'CS-400', None ),
(ARM_ID, CORESIGHT_CLASS, 0x908, 0x12, 0) : CmpInfo('Trace Funnel', 'CS-400', TraceFunnel.factory ),
(ARM_ID, CORESIGHT_CLASS, 0x909, 0x22, 0) : CmpInfo('Trace Replicator',None, None ),
(ARM_ID, CORESIGHT_CLASS, 0x912, 0x11, 0) : CmpInfo('TPIU', 'CS-400', TPIU.factory ),
(ARM_ID, CORESIGHT_CLASS, 0x913, 0x43, 0) : CmpInfo('ITM', 'CS-400', None ),
Expand Down Expand Up @@ -159,7 +160,7 @@ class CmpInfo(NamedTuple):
(ARM_ID, CORESIGHT_CLASS, 0x9e8, 0x21, 0) : CmpInfo('ETR', 'CS-600', None ),
(ARM_ID, CORESIGHT_CLASS, 0x9e9, 0x21, 0) : CmpInfo('ETB', 'CS-600', None ),
(ARM_ID, CORESIGHT_CLASS, 0x9ea, 0x32, 0) : CmpInfo('ETF', 'CS-600', None ),
(ARM_ID, CORESIGHT_CLASS, 0x9eb, 0x12, 0) : CmpInfo('ATB Funnel', 'CS-600', None ),
(ARM_ID, CORESIGHT_CLASS, 0x9eb, 0x12, 0) : CmpInfo('ATB Funnel', 'CS-600', TraceFunnel.factory ),
(ARM_ID, CORESIGHT_CLASS, 0x9ec, 0x22, 0) : CmpInfo('ATB Replicator', 'CS-600', None ),
(ARM_ID, CORESIGHT_CLASS, 0x9ed, 0x14, 0x1a14) : CmpInfo('CTI', 'CS-600', None ),
(ARM_ID, CORESIGHT_CLASS, 0x9ee, 0x00, 0) : CmpInfo('CATU', 'CS-600', None ),
Expand Down
75 changes: 75 additions & 0 deletions pyocd/coresight/funnel.py
rapgenic marked this conversation as resolved.
Show resolved Hide resolved
rapgenic marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# pyOCD debugger
# Copyright (c) 2023 Protech Engineering
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import logging

from .component import CoreSightComponent

LOG = logging.getLogger(__name__)

class TraceFunnel(CoreSightComponent):
"""@brief CoreSight Trace Funnel"""

# Register definitions.
#
# The addresses are offsets from the base address.
CSTF = 0x00000000
CSTF_ENSX_MASK = 0xFF

DEVID = 0x00000FC8
DEVID_PORTCOUNT_MASK = 0xF

def __init__(self, ap, cmpid=None, addr=None):
"""@brief Standard CoreSight component constructor."""
super().__init__(ap, cmpid, addr)
self._available_channels = 2

@property
def available_channels(self) -> int:
"""@brief Number of input ports connected to the funnel"""
return self._available_channels

def init(self) -> None:
"""@brief Reads Funnel connected channels and enables them all by default."""
devid = self.ap.read32(self.address + TraceFunnel.DEVID)
self._available_channels = devid & TraceFunnel.DEVID_PORTCOUNT_MASK
self.enable()

def set_enabled_channels(self, channels: int) -> bool:
"""@brief Sets the enabled Trace Funnel channels.

@param channels Word describing the desired state for the funnel channels.
Setting the n-th bit of this word high enables the corresponding n-th channel, setting it low disables it.
"""
valid_channels_mask = 2**self.available_channels-1
if channels & ~valid_channels_mask:
LOG.warning(f"Trace Funnel: Trying to enable too many channels. Only {self.available_channels} channels are present")
return False

cstf = self.ap.read32(self.address + TraceFunnel.CSTF)
cstf = cstf & ~TraceFunnel.CSTF_ENSX_MASK
cstf = cstf | channels
self.ap.write32(self.address + TraceFunnel.CSTF, cstf)

return True

def enable(self) -> None:
"""@brief Enables all channels"""
self.set_enabled_channels(2**self.available_channels-1)

def disable(self) -> None:
"""@brief Disables all channels"""
self.set_enabled_channels(0x00)
Loading