Source code for microprobe.target.isa.dat

# Copyright 2011-2021 IBM Corporation
#
# 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.
""":mod:`microprobe.target.isa.dat` module

"""

# Futures
from __future__ import absolute_import, print_function

# Built-in modules
import abc
import warnings

# Third party modules

# Own modules
from microprobe.exceptions import MicroprobeAddressTranslationError, \
    MicroprobeDuplicatedValueError
from microprobe.utils.logger import get_logger
from microprobe.utils.misc import RejectingDict
from microprobe.utils.typeguard_decorator import typeguard_testsuite

# Constants

LOG = get_logger(__name__)
__all__ = ["DynamicAddressTranslation", "GenericDynamicAddressTranslation"]

# Functions


# Classes
[docs] @typeguard_testsuite class DynamicAddressTranslation(abc.ABC): """ """
[docs] @abc.abstractmethod def __init__(self, target, **kwargs): pass
[docs] @abc.abstractmethod def add_mapping(self, source, target, mask): raise NotImplementedError
@property @abc.abstractmethod def maps(self): raise NotImplementedError @property @abc.abstractmethod def control(self): raise NotImplementedError
[docs] @abc.abstractmethod def copy(self, **kwargs): raise NotImplementedError
[docs] @abc.abstractmethod def translate(self, address): raise NotImplementedError
[docs] @abc.abstractmethod def raw_parse(self, raw_str): raise NotImplementedError
[docs] @abc.abstractmethod def raw_decorate(self, raw_str): raise NotImplementedError
[docs] @abc.abstractmethod def required_register_values(self): raise NotImplementedError
[docs] @abc.abstractmethod def required_memory_values(self): raise NotImplementedError
[docs] @abc.abstractmethod def update_dat(self, **kwargs): raise NotImplementedError
[docs] @typeguard_testsuite class GenericDynamicAddressTranslation(DynamicAddressTranslation): """ """ _control_keys = {'DAT': False}
[docs] def __init__(self, target, **kwargs): super(GenericDynamicAddressTranslation, self).__init__(target, **kwargs) self._map = RejectingDict() self._target = target self._control = self._control_keys.copy() self._control.update(kwargs) tmaps = kwargs.pop('dat_map', False) if tmaps: for tmap in tmaps: self.add_mapping(tmap[0], tmap[1], tmap[2])
@property def control(self): return self._control @property def maps(self): return self._map
[docs] def add_mapping(self, source, target, mask): try: self._map[source & mask] = DATmap(source, target, mask) except MicroprobeDuplicatedValueError: raise MicroprobeAddressTranslationError( "Map in '%s' already exists" % hex(source & mask))
[docs] def copy(self, **kwargs): newargs = self.control.copy() newargs.update(kwargs) new_dat = GenericDynamicAddressTranslation(self._target, **newargs) for datmap in self.maps.values(): new_dat.add_mapping(datmap.source, datmap.target, datmap.mask) return new_dat
[docs] def translate(self, address, rev=False): if not self.control['DAT']: return address tmap = [ tmap for tmap in self.maps.values() if tmap.address_in_map(address, rev=rev) ] if len(tmap) > 1: raise MicroprobeAddressTranslationError( "Multiple translation maps found for address '%s'" % hex(address)) elif len(tmap) < 1: raise MicroprobeAddressTranslationError( "No translation maps found for address '%s'" % hex(address)) else: return tmap[0].address_translate(address, rev=rev)
[docs] def raw_parse(self, raw_str): raise NotImplementedError( "DAT mechanisms and parameters are target dependent. Target: '%s'" " does not implement them. " % self._target)
[docs] def raw_decorate(self, raw_str): raise NotImplementedError( "DAT mechanisms and parameters are target dependent. Target: '%s'" " does not implement them. " % self._target)
[docs] def required_register_values(self): return []
[docs] def required_memory_values(self): return []
[docs] def update_dat(self, **kwargs): for key, value in kwargs.items(): if key not in self._control_keys: warnings.warn( "DAT Control key '%s' specified but not supported. " "Ignoring it." % key) continue self._control[key] = value['value']
[docs] @typeguard_testsuite class DATmap: """ """
[docs] def __init__(self, source, target, mask): self._source = source self._target = target self._mask = mask
@property def mask(self): return self._mask @property def source(self): return self._source @property def target(self): return self._target
[docs] def address_in_map(self, address, rev=False): if rev: return self.target & self.mask == address & self.mask return self.source & self.mask == address & self.mask
[docs] def address_translate(self, address, rev=False): if not self.address_in_map(address, rev=rev): raise MicroprobeAddressTranslationError( "Unable to translate address '%s' in map: %s" % (hex(address), str(self))) address &= (~self.mask) if rev: address |= (self.source & self.mask) else: address |= (self.target & self.mask) return address