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>
This commit is contained in:
Hector Martin 2021-11-08 20:55:15 +09:00
parent 407663b73d
commit b9ddd74c02
2 changed files with 120 additions and 27 deletions

View file

@ -0,0 +1,88 @@
# 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()

View file

@ -10,29 +10,37 @@ SMC_READ_KEY = 0x10
SMC_WRITE_KEY = 0x11
SMC_GET_KEY_BY_INDEX = 0x12
SMC_GET_KEY_INFO = 0x13
SMC_GET_SRAM_ADDR = 0x17
SMC_INITIALIZE = 0x17
SMC_NOTIFICATION = 0x18
SMC_READ_KEY_PAYLOAD = 0x20
class SMCGetSRAMAddr(Register64):
TYPE = 8, 0, Constant(0x17)
ID = 16, 12
class SMCWriteKey(Register64):
TYPE = 8, 0, Constant(0x11)
ID = 16, 12
SIZE = 32, 16
KEY = 64, 32
class SMCMessage(Register64):
TYPE = 0, 0
VALUE = 64, 0
TYPE = 7, 0
UNK = 11, 8, Constant(0)
ID = 15, 12
class SMCMessage(Register64):
TYPE = 8, 0
ID = 16, 12
HPARAM = 32, 16
WPARAM = 64, 32
class SMCInitialize(SMCMessage):
TYPE = 7, 0, Constant(SMC_INITIALIZE)
class SMCGetKeyInfo(SMCMessage):
TYPE = 7, 0, Constant(SMC_GET_KEY_INFO)
KEY = 63, 32
class SMCWriteKey(SMCMessage):
TYPE = 7, 0, Constant(SMC_WRITE_KEY)
SIZE = 31, 16
KEY = 63, 32
class SMCReadKey(SMCMessage):
TYPE = 7, 0, Constant(SMC_READ_KEY)
SIZE = 31, 16
KEY = 63, 32
class SMCResult(Register64):
RESULT = 7, 0
ID = 15, 12
SIZE = 31, 16
VALUE = 63, 32
class SMCEndpoint(ASCBaseEndpoint):
BASE_MESSAGE = SMCMessage
@ -45,7 +53,7 @@ class SMCEndpoint(ASCBaseEndpoint):
self.outstanding = set()
def start(self):
self.send(SMCGetSRAMAddr(ID = self.new_msgid()))
self.send(SMCInitialize(ID = 0))
while self.shmem is None:
self.asc.work()
@ -56,7 +64,6 @@ class SMCEndpoint(ASCBaseEndpoint):
self.outstanding.add(mid)
return mid
def write_key(self, key, data):
print(self.shmem, key, data, len(data))
self.asc.iface.writemem(self.shmem, data)
@ -66,16 +73,14 @@ class SMCEndpoint(ASCBaseEndpoint):
self.asc.work()
return True
@msg_handler(0x00, SMCMessage)
def Startup(self, msg):
self.log(hex(msg.value))
def handle_msg(self, msg0, msg1):
if self.shmem is None:
self.log("Starting up")
self.shmem = msg.value
self.shmem = msg0
else:
ret = msg.value & 0xFF
mid = (msg.value >> 12) & 0xF
msg = SMCResult(msg0)
ret = msg.TYPE
mid = msg.ID
print(f"msg {mid} return value {ret}")
self.outstanding.discard(mid)