Kristofer Jonsson | e56b6e4 | 2022-09-29 11:52:22 +0200 | [diff] [blame] | 1 | # |
| 2 | # SPDX-FileCopyrightText: Copyright 2022 Arm Limited and/or its affiliates <open-source-office@arm.com> |
| 3 | # |
| 4 | # SPDX-License-Identifier: Apache-2.0 |
| 5 | # |
| 6 | # Licensed under the Apache License, Version 2.0 (the License); you may |
| 7 | # not use this file except in compliance with the License. |
| 8 | # You may obtain a copy of the License at |
| 9 | # |
| 10 | # www.apache.org/licenses/LICENSE-2.0 |
| 11 | # |
| 12 | # Unless required by applicable law or agreed to in writing, software |
| 13 | # distributed under the License is distributed on an AS IS BASIS, WITHOUT |
| 14 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 15 | # See the License for the specific language governing permissions and |
| 16 | # limitations under the License. |
| 17 | # |
| 18 | |
| 19 | import struct |
| 20 | |
| 21 | class EventRecord_t: |
| 22 | SIZE = 16 |
| 23 | |
| 24 | INFO_ID_MASK = 0x0000FFFF |
| 25 | INFO_MESSAGE_MASK = 0x000000FF |
| 26 | INFO_COMPONENT_MASK = 0x0000FF00 |
| 27 | INFO_COMPONENT_POS = 8 |
| 28 | INFO_FIRST = 0x01000000 |
| 29 | INFO_LAST = 0x02000000 |
| 30 | INFO_LOCKED = 0x04000000 |
| 31 | INFO_VALID = 0x08000000 |
| 32 | INFO_MSB_TS = 0x10000000 |
| 33 | INFO_MSB_VAL1 = 0x20000000 |
| 34 | INFO_MSB_VAL2 = 0x40000000 |
| 35 | INFO_TBIT = 0x80000000 |
| 36 | |
| 37 | # Component identifiers |
| 38 | EVENT_CID = 0xFF |
| 39 | ETHOSU_CID = 0x00 |
| 40 | |
| 41 | # Message identifiers |
| 42 | EVENT_MID_INIT = 0x00 |
| 43 | EVENT_MID_START = 0x01 |
| 44 | EVENT_MID_STOP = 0x02 |
| 45 | EVENT_MID_CLOCK = 0x03 |
| 46 | |
| 47 | EVENT_ID_INIT = (EVENT_CID << 8) | EVENT_MID_INIT |
| 48 | EVENT_ID_START = (EVENT_CID << 8) | EVENT_MID_START |
| 49 | EVENT_ID_STOP = (EVENT_CID << 8) | EVENT_MID_STOP |
| 50 | EVENT_ID_CLOCK = (EVENT_CID << 8) | EVENT_MID_CLOCK |
| 51 | |
| 52 | def __init__(self, data): |
| 53 | self.data = data |
| 54 | |
| 55 | # Unpack the struct and restore the MSB from info to timestamp, val1 and val2 |
| 56 | t = struct.unpack('IIII', data) |
| 57 | self.timestamp = t[0] & ~EventRecord_t.INFO_TBIT | (t[3] & EventRecord_t.INFO_MSB_TS) << 3 |
| 58 | self.val1 = t[1] & ~EventRecord_t.INFO_TBIT | (t[3] & EventRecord_t.INFO_MSB_VAL1) << 2 |
| 59 | self.val2 = t[2] & ~EventRecord_t.INFO_TBIT | (t[3] & EventRecord_t.INFO_MSB_VAL2) << 1 |
| 60 | self.info = t[3] |
| 61 | |
| 62 | def first(self): |
| 63 | return self.info & EventRecord_t.INFO_FIRST != 0 |
| 64 | |
| 65 | def last(self): |
| 66 | return self.info & EventRecord_t.INFO_LAST != 0 |
| 67 | |
| 68 | def component(self): |
| 69 | return (self.info & EventRecord_t.INFO_COMPONENT_MASK) >> EventRecord_t.INFO_COMPONENT_POS |
| 70 | |
| 71 | def message(self): |
| 72 | return self.info & EventRecord_t.INFO_MESSAGE_MASK |
| 73 | |
| 74 | def id(self): |
| 75 | return self.info & EventRecord_t.INFO_ID_MASK |
| 76 | |
| 77 | def locked(self): |
| 78 | return self.info & EventRecord_t.INFO_LOCKED != 0 |
| 79 | |
| 80 | def valid(self): |
| 81 | return self.info & EventRecord_t.INFO_VALID != 0 |
| 82 | |
| 83 | def __str__(self): |
| 84 | return f'{{ "timestamp": {hex(self.timestamp)}, "val1": {hex(self.val1)}, "val2": {hex(self.val2)}, "info": "{hex(self.info)}" }}' |
| 85 | |
| 86 | class EventStatus_t: |
| 87 | SIZE = 36 |
| 88 | |
| 89 | def __init__(self, data): |
| 90 | t = struct.unpack('BBHIIIIIIII', data) |
| 91 | |
| 92 | self.state = t[0] |
| 93 | self.context = t[1] |
| 94 | self.infoCrc = t[2] |
| 95 | self.recordIndex = t[3] |
| 96 | self.recordsWritten = t[4] |
| 97 | self.recordsDumped = t[5] |
| 98 | self.tsOverflow = t[6] |
| 99 | self.tsFreq = t[7] |
| 100 | self.tsLast = t[8] |
| 101 | self.initCount = t[9] |
| 102 | self.signature = t[10] |
| 103 | |
| 104 | def __str__(self): |
| 105 | return f'{{ state={self.state}, context={self.context}, info_crc={self.infoCrc}, ' \ |
| 106 | f'record_index={self.recordIndex}, records_written={self.recordsWritten}, records_dumped={self.recordsDumped}, ' \ |
| 107 | f'ts_overflow={self.tsOverflow}, ts_freq={self.tsFreq}, ts_last={self.tsLast}, ' \ |
| 108 | f'init_count={self.initCount}, signature={self.signature} }}' |
| 109 | |
| 110 | class EventRecorderInfo_t: |
| 111 | SIZE = 24 |
| 112 | |
| 113 | def __init__(self, data): |
| 114 | t = struct.unpack('BBHIIIIBBBB', data) |
| 115 | |
| 116 | self.protocolType = t[0] |
| 117 | # self._reserved = t[1] |
| 118 | self.protocolVersion = t[2] |
| 119 | self.recordCount = t[3] |
| 120 | self.eventBuffer = t[4] |
| 121 | self.eventFilter = t[5] |
| 122 | self.eventStatus = t[6] |
| 123 | self.tsSource = t[7] |
| 124 | # self._reserved1 = t[8] |
| 125 | # self._reserved2 = t[9] |
| 126 | # self._reserved3 = t[10] |
| 127 | |
| 128 | def __str__(self): |
| 129 | return f'{{ protocolType={hex(self.protocolType)}, protocolVersion={hex(self.protocolVersion)}, recordCount={self.recordCount}, eventBuffer={hex(self.eventBuffer)}, eventFilter={hex(self.eventFilter)}, eventStatus={hex(self.eventStatus)}, tsSource={self.tsSource} }}' |