m1n1/proxyclient/hv/trace_smc.py
Hector Martin b9ddd74c02 hv/trace_smc.py: Add SMC tracer
Also fix up a bunch of stuff in m1n1.fw.smc, but it's untested as a
client.

Signed-off-by: Hector Martin <marcan@marcan.st>
2021-11-10 20:43:51 +09:00

88 lines
2.8 KiB
Python

# SPDX-License-Identifier: MIT
import struct
from enum import IntEnum
from m1n1.proxyutils import RegMonitor
from m1n1.utils import *
from m1n1.trace.dart import DARTTracer
from m1n1.trace.asc import ASCTracer, EP, EPState, msg, msg_log, DIR
from m1n1.fw.smc import *
ASCTracer = ASCTracer._reloadcls()
class SMCEpTracer(EP):
BASE_MESSAGE = SMCMessage
def __init__(self, tracer, epid):
super().__init__(tracer, epid)
self.state.sram_addr = None
self.state.verbose = 1
self.state.rb = {}
Initialize = msg_log(SMC_INITIALIZE, DIR.TX, SMCInitialize)
Notification = msg_log(SMC_NOTIFICATION, DIR.RX)
@msg(SMC_WRITE_KEY, DIR.TX, SMCWriteKey)
def WriteKey(self, msg):
key = msg.KEY.to_bytes(4, byteorder="big").decode("ascii")
data = self.hv.iface.readmem(self.state.sram_addr, msg.SIZE)
self.log(f"[{msg.ID:x}] >W: <{key}> = {data.hex()}")
return True
@msg(SMC_READ_KEY, DIR.TX, SMCReadKey)
def ReadKey(self, msg):
key = msg.KEY.to_bytes(4, byteorder="big").decode("ascii")
self.state.rb[msg.ID] = msg.TYPE, key, msg.SIZE
self.log(f"[{msg.ID:x}] >R: <{key}> = ...")
return True
@msg(SMC_GET_KEY_INFO, DIR.TX, SMCGetKeyInfo)
def GetInfo(self, msg):
key = msg.KEY.to_bytes(4, byteorder="big").decode("ascii")
self.state.rb[msg.ID] = msg.TYPE, key, None
self.log(f"[{msg.ID:x}] >Get Info: <{key}>")
return True
@msg(None, DIR.RX, Register64)
def RXMsg(self, msg):
if self.state.sram_addr is None:
self.log(f"SRAM address: {msg.value:#x}")
self.state.sram_addr = msg.value
return True
msg = SMCResult(msg.value)
if msg.RESULT != 0:
self.log(f"[{msg.ID:x}] <Err: 0x{msg.RESULT:02x}")
return True
if msg.ID in self.state.rb:
msgtype, key, size = self.state.rb.pop(msg.ID)
if msgtype == SMC_READ_KEY:
if size <= 4:
data = hex(msg.VALUE)
else:
data = self.hv.iface.readmem(self.state.sram_addr, msg.SIZE).hex()
self.log(f"[{msg.ID:x}] <R: <{key}> = {data}")
return True
elif msgtype == SMC_GET_KEY_INFO:
data = self.hv.iface.readmem(self.state.sram_addr, 6)
size, type, flags = struct.unpack("B4sB", data)
self.log(f"[{msg.ID:x}] <Info: <{key}>: size={size} type={type.decode('ascii')} flags={flags:#x}")
return True
self.log(f"[{msg.ID:x}] <OK {msg!r}")
return True
class SMCTracer(ASCTracer):
ENDPOINTS = {
0x20: SMCEpTracer
}
def handle_msg(self, direction, r0, r1):
super().handle_msg(direction, r0, r1)
smc_tracer = SMCTracer(hv, "/arm-io/smc", verbose=1)
smc_tracer.start()