Пример #1
0
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")
        self.state.rb[msg.ID] = msg.TYPE, key, msg.SIZE
        data = self.hv.iface.readmem(self.state.sram_addr, msg.SIZE)
        self.log(f"[{msg.ID:x}] >W: <{key}> = {data.hex()} ({msg.SIZE})")
        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}> = ... ({msg.SIZE})")
        return True

    @msg(SMC_RW_KEY, DIR.TX, SMCReadWriteKey)
    def ReadKeyPayload(self, msg):
        key = msg.KEY.to_bytes(4, byteorder="big").decode("ascii")
        self.state.rb[msg.ID] = msg.TYPE, key, msg.RSIZE
        data = self.hv.iface.readmem(self.state.sram_addr, msg.WSIZE)
        self.log(
            f"[{msg.ID:x}] >RP: <{key}> = {data.hex()} ({msg.WSIZE, msg.RSIZE})"
        )
        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 in (SMC_READ_KEY, SMC_RW_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
Пример #2
0
class AFKEp(EP):
    BASE_MESSAGE = AFKEPMessage

    def __init__(self, tracer, epid):
        super().__init__(tracer, epid)
        self.txbuf = None
        self.rxbuf = None
        self.state.txbuf = EPState()
        self.state.rxbuf = EPState()
        self.state.shmem_iova = None
        self.state.txbuf_info = None
        self.state.rxbuf_info = None
        self.state.verbose = 1

    def start(self):
        #self.add_mon()
        self.create_bufs()

    def create_bufs(self):
        if not self.state.shmem_iova:
            return
        if not self.txbuf and self.state.txbuf_info:
            off, size = self.state.txbuf_info
            self.txbuf = AFKRingBufSniffer(self, self.state.txbuf,
                                           self.state.shmem_iova + off, size)
        if not self.rxbuf and self.state.rxbuf_info:
            off, size = self.state.rxbuf_info
            self.rxbuf = AFKRingBufSniffer(self, self.state.rxbuf,
                                           self.state.shmem_iova + off, size)

    def add_mon(self):
        if self.state.shmem_iova:
            iomon.add(self.state.shmem_iova, 32768,
                      name=f"{self.name}.shmem@{self.state.shmem_iova:08x}", offset=0)

    Init =          msg_log(0x80, DIR.TX)
    Init_Ack =      msg_log(0xa0, DIR.RX)

    GetBuf =        msg_log(0x89, DIR.RX)

    Shutdown =      msg_log(0xc0, DIR.TX)
    Shutdown_Ack =  msg_log(0xc1, DIR.RX)

    @msg(0xa1, DIR.TX, AFKEP_GetBuf_Ack)
    def GetBuf_Ack(self, msg):
        self.state.shmem_iova = msg.DVA
        self.txbuf = None
        self.rxbuf = None
        self.state.txbuf = EPState()
        self.state.rxbuf = EPState()
        self.state.txbuf_info = None
        self.state.rxbuf_info = None
        #self.add_mon()

    @msg(0xa2, DIR.TX, AFKEP_Send)
    def Send(self, msg):
        for data in self.txbuf.read():
            if self.state.verbose >= 3:
                self.log(f">TX rptr={self.txbuf.state.rptr:#x}")
                chexdump(data)
            self.handle_ipc(data, dir=">")
        return True

    Hello =         msg_log(0xa3, DIR.TX)

    @msg(0x85, DIR.RX, AFKEPMessage)
    def Recv(self, msg):
        for data in self.rxbuf.read():
            if self.state.verbose >= 3:
                self.log(f"<RX rptr={self.rxbuf.state.rptr:#x}")
                chexdump(data)
            self.handle_ipc(data, dir="<")
        return True

    def handle_ipc(self, data, dir=None):
        pass

    @msg(0x8a, DIR.RX, AFKEP_InitRB)
    def InitTX(self, msg):
        off = msg.OFFSET * AFKRingBuf.BLOCK_SIZE
        size = msg.SIZE * AFKRingBuf.BLOCK_SIZE
        self.state.txbuf_info = (off, size)
        self.create_bufs()

    @msg(0x8b, DIR.RX, AFKEP_InitRB)
    def InitRX(self, msg):
        off = msg.OFFSET * AFKRingBuf.BLOCK_SIZE
        size = msg.SIZE * AFKRingBuf.BLOCK_SIZE
        self.state.rxbuf_info = (off, size)
        self.create_bufs()
Пример #3
0
class DCPEp(EP):
    BASE_MESSAGE = DCPMessage

    def __init__(self, tracer, epid):
        super().__init__(tracer, epid)
        self.state.shmem_iova = None
        self.state.show_globals = True
        self.state.show_acks = True
        self.state.max_len = 1024 * 1024
        self.state.verbosity = 3
        self.state.op_verb = {}
        self.state.ch = {}
        self.state.dumpfile = None

        self.ch_cb = DCPCallChannel(self, "CB", 0x60000, 0x8000)
        self.ch_cmd = DCPCallChannel(self, "CMD", 0, 0x8000)
        self.ch_async = DCPCallChannel(self, "ASYNC", 0x40000, 0x20000)
        self.ch_oobcb = DCPCallChannel(self, "OOBCB", 0x68000, 0x8000)
        self.ch_oobcmd = DCPCallChannel(self, "OOBCMD", 0x8000, 0x8000)

        self.cmd_ch = {
            CallContext.CB: self.ch_cmd,
            CallContext.CMD: self.ch_cmd,
            CallContext.ASYNC: None, # unknown
            CallContext.OOBCB: self.ch_oobcmd,
            CallContext.OOBCMD: self.ch_oobcmd,
        }

        self.cb_ch = {
            CallContext.CB: self.ch_cb,
            CallContext.CMD: None,
            CallContext.ASYNC: self.ch_async,
            CallContext.OOBCB: self.ch_oobcb,
            CallContext.OOBCMD: None,
        }

    def start(self):
        self.add_mon()

    def add_mon(self):
        if self.state.shmem_iova and self.state.show_globals:
            addr = self.state.shmem_iova + 0x80000
            iomon.add(addr, 128,
                      name=f"{self.name}.shmem@{addr:08x}", offset=addr)

            #addr = self.state.shmem_iova
            #iomon.add(addr, 0x80080,
                      #name=f"{self.name}.shmem@{addr:08x}", offset=addr)

    InitComplete = msg_log(1, DIR.RX)

    @msg(0, DIR.TX, DCPEp_SetShmem)
    def SetShmem(self, msg):
        self.log(f"Shared memory DVA: {msg.DVA:#x}")
        self.state.shmem_iova = msg.DVA & 0xffffffff
        self.add_mon()

    @msg(2, DIR.TX, DCPEp_Msg)
    def Tx(self, msg):
        if msg.ACK:
            self.cb_ch[msg.CTX].ack(msg, ">")
        else:
            self.cmd_ch[msg.CTX].call(msg, ">")

        if self.state.show_globals:
            iomon.poll()

        return True

    @msg(2, DIR.RX, DCPEp_Msg)
    def Rx(self, msg):
        self.log(msg)
        if msg.ACK:
            self.cmd_ch[msg.CTX].ack(msg, "<")
        else:
            self.cb_ch[msg.CTX].call(msg, "<")

        if self.state.show_globals:
            iomon.poll()

        return True

    def get_verbosity(self, tag):
        return self.state.op_verb.get(tag, self.state.verbosity)

    def set_verb_known(self, verb):
        for i in KNOWN_MSGS:
            if verb is None:
                self.state.op_verb.pop(i, None)
            else:
                self.state.op_verb[i] = verb
Пример #4
0
class IOEp(EP):
    BASE_MESSAGE = IOEp_Generic

    def __init__(self, tracer, epid):
        super().__init__(tracer, epid)
        self.state.txbuf = EPState()
        self.state.rxbuf = EPState()
        self.state.shmem_iova = None
        self.state.verbose = 1

    def start(self):
        #self.add_mon()
        self.create_bufs()

    def create_bufs(self):
        if not self.state.shmem_iova:
            return
        self.txbuf = IORingBuf(self, self.state.txbuf, self.state.shmem_iova)
        self.rxbuf = IORingBuf(self, self.state.rxbuf, self.state.shmem_iova + 0x4000)

    def add_mon(self):
        if self.state.shmem_iova:
            iomon.add(self.state.shmem_iova, 32768,
                      name=f"{self.name}.shmem@{self.state.shmem_iova:08x}", offset=0)

    Init =          msg_log(0x80, DIR.TX)
    Init_Ack =      msg_log(0xa0, DIR.RX)

    GetBuf =        msg_log(0x89, DIR.RX)

    Shutdown =      msg_log(0xc0, DIR.TX)
    Shutdown_Ack =  msg_log(0xc1, DIR.RX)

    @msg(0xa1, DIR.TX, IOEp_SetBuf_Ack)
    def GetBuf_Ack(self, msg):
        self.state.shmem_iova = msg.IOVA
        #self.add_mon()

    @msg(0xa2, DIR.TX, IOEp_Send)
    def Send(self, msg):
        for data in self.txbuf.read(wptr=msg.WPTR):
            if self.state.verbose >= 1:
                self.log(f">TX rptr={self.txbuf.state.rptr:#x}")
                chexdump(data)
        return True

    Hello =         msg_log(0xa3, DIR.TX)

    @msg(0x85, DIR.RX, IOEpMessage)
    def Recv(self, msg):
        for data in self.rxbuf.read():
            if self.state.verbose >= 1:
                self.log(f"<RX rptr={self.rxbuf.state.rptr:#x}")
                chexdump(data)
        return True

    @msg(0x8b, DIR.RX)
    def BufInitialized(self, msg):
        self.create_bufs()
        self.txbuf.init()
        self.rxbuf.init()