diff options
Diffstat (limited to 'tools/proxyclient/m1n1/fw/pmp.py')
| -rw-r--r-- | tools/proxyclient/m1n1/fw/pmp.py | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/tools/proxyclient/m1n1/fw/pmp.py b/tools/proxyclient/m1n1/fw/pmp.py new file mode 100644 index 0000000..fbfef45 --- /dev/null +++ b/tools/proxyclient/m1n1/fw/pmp.py @@ -0,0 +1,168 @@ +# SPDX-License-Identifier: MIT +import struct + +from ..utils import * + +from .asc import StandardASC +from .asc.base import * + +class PMPMessage(Register64): + TYPE = 56, 44 + +class PMP_Startup(PMPMessage): + TYPE = 56, 44, Constant(0x00) + +class PMP_Configure(PMPMessage): + TYPE = 56, 44, Constant(0x10) + DVA = 47, 0 + +class PMP_Configure_Ack(PMPMessage): + TYPE = 56, 44, Constant(0x20) + UNK = 47, 0 + +class PMP_Init1(PMPMessage): + TYPE = 56, 44, Constant(0x200) + UNK1 = 43, 16 + UNK2 = 15, 0 + +class PMP_Init1_Ack(PMPMessage): + TYPE = 56, 44, Constant(0x201) + UNK1 = 43, 16 + UNK2 = 15, 0 + +class PMP_Init2(PMPMessage): + TYPE = 56, 44, Constant(0x202) + UNK1 = 43, 16 + UNK2 = 15, 0 + +class PMP_Init2_Ack(PMPMessage): + TYPE = 56, 44, Constant(0x203) + UNK1 = 43, 16 + UNK2 = 15, 0 + +class PMP_Unk(PMPMessage): + TYPE = 56, 44, Constant(0x100) + UNK1 = 43, 16 + UNK2 = 15, 0 + +class PMP_Unk_Ack(PMPMessage): + TYPE = 56, 44, Constant(0x110) + UNK1 = 43, 16 + UNK2 = 15, 0 + +class PMP_DevPwr(PMPMessage): + TYPE = 56, 44, Constant(0x20e) + DEV = 31, 16 + STATE = 15, 0 + +class PMP_DevPwr_Sync(PMPMessage): + TYPE = 56, 44, Constant(0x208) + DEV = 31, 16 + STATE = 15, 0 + +class PMP_DevPwr_Ack(PMPMessage): + TYPE = 56, 44, Constant(0x209) + DEV = 31, 16 + STATE = 15, 0 + +class PMPEndpoint(ASCBaseEndpoint): + BASE_MESSAGE = PMPMessage + SHORT = "pmpep" + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.shmem = self.shmem_dva = None + self.init_complete = False + self.init1_acked = False + self.init2_acked = False + self.unk_acked = False + + @msg_handler(0x00, PMP_Startup) + def Startup(self, msg): + self.log("Starting up") + + self.shmem, self.shmem_dva = self.asc.ioalloc(0x10000) + + self.send_init_config() + return True + + def send_init_config(self): + self.asc.p.memset32(self.shmem, 0, 0x10000) + dram_config = self.asc.u.adt["arm-io/pmp/iop-pmp-nub"].energy_model_dram_configs + self.asc.iface.writemem(self.shmem + 0x2000, dram_config) + + node = self.asc.u.adt["arm-io/pmp"] + + maps = [] + dva = 0xc0000000 + for i in range(3, len(node.reg)): + addr, size = node.get_reg(i) + if size == 0: + maps.append(struct.pack("<QQ", 0, 0)) + continue + + self.asc.dart.iomap_at(0, dva, addr, size) + self.log(f"map {addr:#x} -> {dva:#x} [{size:#x}]") + maps.append(struct.pack("<QQ", dva, size)) + dva += align(size, 0x4000) + + chexdump(b"".join(maps)) + + self.asc.iface.writemem(self.shmem + 0xe000, b"".join(maps)) + self.send(PMP_Configure(DVA=self.shmem_dva)) + + while not self.init_complete: + self.asc.work() + return True + + @msg_handler(0x20, PMP_Configure_Ack) + def Configure_Ack(self, msg): + self.init_complete = True + + props = self.asc.iface.readmem(self.shmem, 0x2000) + devinfo = self.asc.iface.readmem(self.shmem + 0x4000, 0x1000) + status = self.asc.iface.readmem(self.shmem + 0xc000, 0x100) + + print("PMP Props:") + chexdump(props) + print("PMP Device Info:") + chexdump(devinfo) + print("PMP Status:") + chexdump(status) + + self.send(PMP_Init1(UNK1=1, UNK2=3)) + while not self.init1_acked: + self.asc.work() + + self.send(PMP_Init2(UNK1=1, UNK2=0)) + while not self.init2_acked: + self.asc.work() + + self.send(PMP_Unk(UNK1=0x3bc, UNK2=2)) + while not self.unk_acked: + self.asc.work() + + return True + + @msg_handler(0x201, PMP_Init1_Ack) + def Init1_Ack(self, msg): + self.init1_acked = True + return True + + @msg_handler(0x203, PMP_Init2_Ack) + def Init2_Ack(self, msg): + self.init2_acked = True + return True + + @msg_handler(0x110, PMP_Unk_Ack) + def Unk_Ack(self, msg): + self.unk_acked = True + return True + + +class PMPClient(StandardASC): + pass + + ENDPOINTS = { + 0x20: PMPEndpoint, + } |
