Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: f6f8aa64057e46c2d2bcff789eb251bbd77049fc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
# *****************************************************************************
# * Copyright (c) 2011, 2013 Wind River Systems, Inc. and others.
# * All rights reserved. This program and the accompanying materials
# * are made available under the terms of the Eclipse Public License v1.0
# * which accompanies this distribution, and is available at
# * http://www.eclipse.org/legal/epl-v10.html
# *
# * Contributors:
# *     Wind River Systems - initial API and implementation
# *****************************************************************************

"""
Memory service provides basic operations to read/write memory on a target.
"""

from .. import services

NAME = "Memory"

# Context property names.
# String, ID of the context, same as getContext command argument
PROP_ID = "ID"

# String, ID of a parent context
PROP_PARENT_ID = "ParentID"

# String, process ID, see Processes service
PROP_PROCESS_ID = "ProcessID"

# Boolean, True if memory is big-endian
PROP_BIG_ENDIAN = "BigEndian"

# Number, size of memory address in bytes
PROP_ADDRESS_SIZE = "AddressSize"

# String, name of the context, can be used for UI purposes
PROP_NAME = "Name"

# Number, lowest address (inclusive) which is valid for the context
PROP_START_BOUND = "StartBound"

# Number, highest address (inclusive) which is valid for the context
PROP_END_BOUND = "EndBound"

# Array of String, the access types allowed for this context
PROP_ACCESS_TYPES = "AccessTypes"

# Values of "AccessTypes".
# Target system can support multiple different memory access types, like
# instruction and data access. Different access types can use different logic
# for address translation and memory mapping, so they can end up accessing
# different data bits, even if address is the same.
# Each distinct access type should be represented by separate memory context.
# A memory context can represent multiple access types if they are
# equivalent - all access same memory bits.
# Same data bits can be exposed through multiple memory contexts.

# Context represent instructions fetch access
ACCESS_INSTRUCTION = "instruction"

# Context represents data access
ACCESS_DATA = "data"

# Context represents IO peripherals
ACCESS_IO = "io"

# Context represents a user (e.g. application running in Linux) view to memory
ACCESS_USER = "user"

# Context represents a supervisor (e.g. Linux kernel) view to memory
ACCESS_SUPERVISOR = "supervisor"

# Context represents a hypervisor view to memory
ACCESS_HYPERVISOR = "hypervisor"

# Context uses virtual addresses
ACCESS_VIRTUAL = "virtual"

# Context uses physical addresses
ACCESS_PHYSICAL = "physical"

# Context is a cache
ACCESS_CACHE = "cache"

# Context is a TLB memory
ACCESS_TLB = "tlb"

# Memory access mode:
# Carry on when some of the memory cannot be accessed and
# return MemoryError at the end if any of the bytes
# were not processed correctly.
MODE_CONTINUEONERROR = 0x1

# Memory access mode:
# Verify result of memory operations (by reading and comparing).
MODE_VERIFY = 0x2


class MemoryContext(object):

    def __init__(self, props):
        self._props = props or {}

    def __str__(self):
        return "[Memory Context %s]" % self._props

    def getProperties(self):
        """
        Get context properties. See PROP_* definitions for property names.
        Context properties are read only, clients should not try to modify
        them.
        @return Map of context properties.
        """
        return self._props

    def getID(self):
        """
        Retrieve context ID.
        Same as getProperties().get('ID')
        """
        return self._props.get(PROP_ID)

    def getParentID(self):
        """
        Retrieve parent context ID.
        Same as getProperties().get('ParentID')
        """
        return self._props.get(PROP_PARENT_ID)

    def getProcessID(self):
        """
        Retrieve context process ID.
        Same as getProperties().get('ProcessID')
        """
        return self._props.get(PROP_PROCESS_ID)

    def isBigEndian(self):
        """
        Get memory endianness.
        @return True if memory is big-endian.
        """
        return self._props.get(PROP_BIG_ENDIAN, False)

    def getAddressSize(self):
        """
        Get memory address size.
        @return number of bytes used to store memory address value.
        """
        return self._props.get(PROP_ADDRESS_SIZE, 0)

    def getName(self):
        """
        Get memory context name.
        The name can be used for UI purposes.
        @return context name.
        """
        return self._props.get(PROP_NAME)

    def getStartBound(self):
        """
        Get lowest address (inclusive) which is valid for the context.
        @return lowest address.
        """
        return self._props.get(PROP_START_BOUND)

    def getEndBound(self):
        """
        Get highest address (inclusive) which is valid for the context.
        @return highest address.
        """
        return self._props.get(PROP_END_BOUND)

    def getAccessTypes(self):
        """
        Get the access types allowed for this context.
        @return collection of access type names.
        """
        return self._props.get(PROP_ACCESS_TYPES)

    def set(self, addr, ws, buf, offs, sz, mode, done):  # @ReservedAssignment
        """
        Set target memory.
        If 'ws' is 0 it means client does not care about word size.
        """
        raise NotImplementedError("Abstract method")

    def get(self, addr, word_size, buf, offs, size, mode, done):
        """
        Read target memory.
        """
        raise NotImplementedError("Abstract method")

    def fill(self, addr, word_size, value, size, mode, done):
        """
        Fill target memory with given pattern.
        'size' is number of bytes to fill.
        """
        raise NotImplementedError("Abstract method")


class DoneMemory(object):
    """
    Client call back interface for set(), get() and fill() commands.
    """
    def doneMemory(self, token, error):
        pass


class MemoryError(Exception):  # @ReservedAssignment
    pass


class ErrorOffset(object):
    """
    ErrorOffset may be implemented by MemoryError object,
    which is returned by get, set and fill commands.

    get/set/fill () returns this exception when reading failed
    for some but not all bytes, and MODE_CONTINUEONERROR
    has been set in mode. (For example, when only part of the request
    translates to valid memory addresses.)
    Exception.getMessage can be used for generalized message of the
    possible reasons of partial memory operation.
    """
    # Error may have per byte information
    BYTE_VALID = 0x00
    BYTE_UNKNOWN = 0x01  # e.g. out of range
    BYTE_INVALID = 0x02
    BYTE_CANNOT_READ = 0x04
    BYTE_CANNOT_WRITE = 0x08

    RANGE_KEY_ADDR = "addr"
    RANGE_KEY_SIZE = "size"
    RANGE_KEY_STAT = "stat"
    RANGE_KEY_MSG = "msg"

    def getStatus(self, offset):
        raise NotImplementedError("Abstract method")

    def getMessage(self, offset):
        raise NotImplementedError("Abstract method")


class MemoryService(services.Service):

    def getName(self):
        return NAME

    def getContext(self, contextID, done):
        """
        Retrieve context info for given context ID.

        @param contextID - context ID.
        @param done - call back interface called when operation is completed.
        @return - pending command handle.
        """
        raise NotImplementedError("Abstract method")

    def getChildren(self, parent_context_id, done):
        """
        Retrieve contexts available for memory commands.
        A context corresponds to an execution thread, process, address space,
        etc.
        A context can belong to a parent context. Contexts hierarchy can be
        simple plain list or it can form a tree. It is up to target agent
        developers to choose layout that is most descriptive for a given
        target. Context IDs are valid across all services. In other words, all
        services access same hierarchy of contexts, with same IDs, however,
        each service accesses its own subset of context's attributes and
        functionality, which is relevant to that service.

        @param parent_context_id - parent context ID. Can be None - to retrieve
                                   top level of the hierarchy, or one of
                                   context IDs retrieved by previous
                                   getChildren commands.
        @param done - call back interface called when operation is completed.
        @return - pending command handle.
        """
        raise NotImplementedError("Abstract method")

    def addListener(self, listener):
        """
        Add memory service event listener.
        @param listener - event listener implementation.
        """
        raise NotImplementedError("Abstract method")

    def removeListener(self, listener):
        """
        Remove memory service event listener.
        @param listener - event listener implementation.
        """
        raise NotImplementedError("Abstract method")


class MemoryListener(object):
    """
    Memory event listener is notified when memory context hierarchy
    changes, and when memory is modified by memory service commands.
    """

    def contextAdded(self, contexts):
        """
        Called when a new memory access context(s) is created.
        """
        pass

    def contextChanged(self, contexts):
        """
        Called when a memory access context(s) properties changed.
        """
        pass

    def contextRemoved(self, context_ids):
        """
        Called when memory access context(s) is removed.
        """
        pass

    def memoryChanged(self, context_id, addr, size):
        """
        Called when target memory content was changed and clients
        need to update themselves. Clients, at least, should invalidate
        corresponding cached memory data.
        Not every change is notified - it is not possible,
        only those, which are not caused by normal execution of the debuggee.
        'addr' and 'size' can be None if unknown.
        """
        pass


class DoneGetContext(object):
    """
    Client call back interface for getContext().
    """
    def doneGetContext(self, token, error, context):
        """
        Called when context data retrieval is done.
        @param error - error description if operation failed, None if
                       succeeded.
        @param context - context data.
        """
        pass


class DoneGetChildren(object):
    """
    Client call back interface for getChildren().
    """
    def doneGetChildren(self, token, error, context_ids):
        """
        Called when context list retrieval is done.
        @param error - error description if operation failed, None if
                       succeeded.
        @param context_ids - array of available context IDs.
        """
        pass

Back to the top