Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- # SPDX-License-Identifier: MIT
- import sys, pathlib, time
- sys.path.append(str(pathlib.Path(__file__).resolve().parents[1]))
- from m1n1.setup import *
- from m1n1.hw.dart import DART
- from m1n1.shell import run_shell
- #from m1n1.hw.isp import *
- from m1n1.fw.common import *
- import atexit
- import struct
- from construct import *
- PAGE_SIZE = 0x4000
- MAX_TRIES = 5
- DO_POLL = False
- p.pmgr_adt_clocks_enable("/arm-io/isp")
- p.pmgr_adt_clocks_enable("/arm-io/dart-isp")
- dart = DART.from_adt(u, "/arm-io/dart-isp")
- dart.initialize()
- isp_base = u.adt["/arm-io/isp"].get_reg(0)[0] # 0x22a000000
- pwr_base = u.adt["/arm-io/isp"].get_reg(1)[0] # 0x23b700000
- # ane & isp have a 2nd & 3rd dart "domain"
- # they're not real darts, but it's also 0x4000 and their offsets resemble one
- # tldr they need these synced to the main domain
- # 1) ttbr (copy one-time after init). dma doesn't work without this.
- # 2) invalidation (sequence). it will panic & require hard reset.
- isp_dart0_base = u.adt["/arm-io/dart-isp"].get_reg(0)[0] # 0x22c0e8000
- isp_dart1_base = u.adt["/arm-io/dart-isp"].get_reg(1)[0] # 0x22c0f4000
- isp_dart2_base = u.adt["/arm-io/dart-isp"].get_reg(2)[0] # 0x22c0fc000
- # gpios are +0x2100000
- ISP_GPIO0 = isp_base + 0x2104170
- ISP_GPIO1 = isp_base + 0x2104174
- ISP_GPIO2 = isp_base + 0x2104178
- ISP_GPIO3 = isp_base + 0x210417c
- ISP_GPIO4 = isp_base + 0x2104180
- ISP_GPIO5 = isp_base + 0x2104184
- ISP_GPIO6 = isp_base + 0x2104188
- ISP_GPIO7 = isp_base + 0x210418c
- ISP_GPIO8 = isp_base + 0x2104190
- ISP_IRQ_INTERRUPT = isp_base + 0x2104000
- ISP_IRQ_ENABLE = isp_base + 0x2104004
- ISP_IRQ_DOORBELL = isp_base + 0x21043f0
- ISP_IRQ_ACK = isp_base + 0x21043fc
- # asc controls are +0x100000 & +0x140000
- # gathered from ane panic logs (which happened to be the same for isp)
- ISP_ASC_RVBAR = isp_base + 0x1050000 # ANE_H11_CHINOOK_IO_RVBAR
- ISP_ASC_EDPRCR = isp_base + 0x1010310 # ANE_H11_ASC_CPU_EDPRCR
- ISP_ASC_CONTROL = isp_base + 0x1400044
- ISP_ASC_STATUS = isp_base + 0x1400048 # ANE_H11_ASCWRAP_IDLE_STATUS
- # =============================================================================
- # utils
- def ioread32(iova):
- return struct.unpack("<l", dart.ioread(0, iova, 0x4))[0]
- def iowrite32(iova, val):
- dart.iowrite(0, iova, struct.pack("<l", val))
- def ioalloc(iova, size):
- phys = u.heap.memalign(PAGE_SIZE, size)
- p.memset32(phys, 0, size)
- dart.iomap_at(0, iova, phys, size)
- def wfile(fname, data):
- open(fname, "wb").write(data)
- def rfile(fname):
- return open(fname, "rb").read()
- mon = RegMonitor(u)
- iomon = RegMonitor(u)
- def readmem_iova(iova, size, readfn):
- try:
- return dart.ioread(0, iova, size)
- except Exception as e:
- print(e)
- return None
- iomon.readmem = readmem_iova
- # =============================================================================
- def w_tun_a():
- # fabric tunables
- p.mask32(0x22a000000, 0x10, 0x10)
- p.mask32(0x22a000040, 0xffff, 0x50030)
- p.mask32(0x22a000044, 0xffff, 0xa0040)
- p.mask32(0x22a000400, 0x4, 0x40000001)
- p.mask32(0x22a000600, 0x0, 0x1ffffff)
- p.mask32(0x22a000738, 0x1ff01ff, 0x2) # these 4 are used in power reset
- p.mask32(0x22a000798, 0x1ff01ff, 0x300008)
- p.mask32(0x22a0007f8, 0x1ff01ff, 0x880020)
- p.mask32(0x22a000858, 0x1ff01ff, 0x200080)
- p.mask32(0x22a000900, 0x1, 0x101)
- p.mask32(0x22a000410, 0x100, 0x1100)
- p.mask32(0x22a000420, 0x100, 0x1100)
- p.mask32(0x22a000430, 0x100, 0x1100)
- p.mask32(0x22a008000, 0x0, 0x9)
- p.mask32(0x22a008000, 0x0, 0x9)
- p.mask32(0x22a000920, 0x0, 0x80)
- p.write32(0x22a008008, 0x7)
- p.write32(0x22a008014, 0x1)
- p.mask32(0x22a008018, 0x0, 0x1)
- p.mask32(0x22a0007a8, 0x0, 0x1)
- p.write32(0x22a008208, 0x5)
- p.write32(0x22a008280, 0x20)
- p.write32(0x22a008288, 0x3)
- p.write32(0x22a00828c, 0xc)
- p.write32(0x22a008290, 0x18)
- p.write32(0x22a008294, 0x30)
- p.write32(0x22a008298, 0x78)
- p.write32(0x22a00829c, 0xff)
- p.mask32(0x22a0082b8, 0x0, 0x1)
- p.write32(0x22a0082bc, 0x1)
- p.mask32(0x22a0082c0, 0x0, 0x1)
- p.mask32(0x22a000748, 0x0, 0x1)
- p.write32(0x22a00820c, 0x3)
- p.write32(0x22a008284, 0x20)
- p.write32(0x22a0082a0, 0x3)
- p.write32(0x22a0082a4, 0xc)
- p.write32(0x22a0082a8, 0x18)
- p.write32(0x22a0082ac, 0x30)
- p.write32(0x22a0082b0, 0x78)
- p.write32(0x22a0082b4, 0xff)
- p.mask32(0x22a0082b8, 0x1, 0x3)
- p.write32(0x22a0082bc, 0x2)
- p.mask32(0x22a0082c0, 0x1, 0x3)
- p.write32(0x22a008210, 0x0)
- p.write32(0x22a008408, 0x3)
- p.write32(0x22a008418, 0x3)
- p.write32(0x22a00841c, 0x0)
- p.write32(0x22a008420, 0xffffffff)
- p.write32(0x22a008424, 0x0)
- p.write32(0x22a008428, 0xfff)
- p.mask32(0x22a0082b8, 0x3, 0x7)
- p.write32(0x22a0082bc, 0x4)
- p.mask32(0x22a0082c0, 0x3, 0x7)
- def w_tun_b():
- p.write32(0x22c0e0080, 0x1)
- p.mask32(0x22c0f0020, 0x0, 0x80000000)
- p.mask32(0x22c0f8020, 0x0, 0x80000000)
- def w_tun_c():
- dapf_cfg = getattr(u.adt['/arm-io/dart-isp'], 'filter-data-instance-0')
- dapf_base = u.adt['/arm-io/dart-isp'].reg[5].addr | 0x200000000
- offset = 0
- while offset < len(dapf_cfg):
- (start, end, _, r0h, r0l, _, r4) = struct.unpack_from('QQBBBBI', buffer=dapf_cfg, offset=offset)
- offset += 24
- p.write32(dapf_base + 0x4, r4)
- p.write32(dapf_base + 0x8, start & 0xFFFFFFFF)
- p.write32(dapf_base + 0xc, start >> 32) # macos does 32 bit writes, can we do 64?
- p.write32(dapf_base + 0x10, end & 0xFFFFFFFF)
- p.write32(dapf_base + 0x14, end >> 32)
- p.write32(dapf_base, (r0h << 4) | r0l)
- dapf_base += 0x40
- def w_tun_d():
- p.write32(0x22c0e8100, 0x80) # TCR[0] = 0x80
- p.write32(0x22c0e813c, 0x100)
- p.write32(isp_dart1_base + 0xfc, 0x1) # 0x22c0f40fc
- p.write32(isp_dart1_base + 0x200, dart.dart.regs.TTBR[0, 0].val) # 0x22c0f4200
- p.write32(isp_dart1_base + 0x2f0, 0x0) # 0x22c0f42f0
- p.write32(isp_dart1_base + 0x34, 0xffffffff) # 0x22c0f4034
- p.write32(isp_dart1_base + 0x20, 0x100000) # 0x22c0f4020
- p.mask32(isp_dart1_base + 0x60, 0x10000, 0x80016100) # 0x22c0f4060
- p.mask32(isp_dart1_base + 0x68, 0x20202, 0xf0f0f) # 0x22c0f4068
- p.mask32(isp_dart1_base + 0x6c, 0x0, 0x80808) # 0x22c0f406c
- p.write32(isp_dart1_base + 100, 0x80) # 0x22c0f4100
- p.write32(isp_dart1_base + 0x13c, 0x20000) # 0x22c0f413c
- p.write32(isp_dart2_base + 0xfc, 0x1) # 0x22c0fc0fc
- p.write32(isp_dart2_base + 0x200, dart.dart.regs.TTBR[0, 0].val) # 0x22c0fc200
- p.write32(isp_dart2_base + 0x2f0, 0x0) # 0x22c0fc2f0
- p.write32(isp_dart2_base + 0x34, 0xffffffff) # 0x22c0fc034
- p.write32(isp_dart2_base + 0x20, 0x100000) # 0x22c0fc020
- p.mask32(isp_dart2_base + 0x60, 0x10000, 0x80016100) # 0x22c0fc060
- p.mask32(isp_dart2_base + 0x68, 0x20202, 0xf0f0f) # 0x22c0fc068
- p.mask32(isp_dart2_base + 0x6c, 0x0, 0x80808) # 0x22c0fc06c
- p.write32(isp_dart2_base + 100, 0x80) # 0x22c0fc100
- p.write32(isp_dart2_base + 0x13c, 0x20000) # 0x22c0fc13c
- def w_tun():
- w_tun_a()
- w_tun_b()
- w_tun_c()
- w_tun_d()
- # =============================================================================
- def power_on():
- p.pmgr_adt_clocks_enable("/arm-io/isp")
- p.pmgr_adt_clocks_enable("/arm-io/dart-isp")
- p.write32(pwr_base + 0x4000, 0xf) # power domains, low -> high
- p.write32(pwr_base + 0x4008, 0xf)
- p.write32(pwr_base + 0x4010, 0xf)
- p.write32(pwr_base + 0x4018, 0xf)
- p.write32(pwr_base + 0x4020, 0xf)
- p.write32(pwr_base + 0x4028, 0xf)
- p.write32(pwr_base + 0x4030, 0xf)
- p.write32(pwr_base + 0x4038, 0xf)
- p.write32(pwr_base + 0x4040, 0xf)
- p.write32(pwr_base + 0x4048, 0xf)
- p.write32(pwr_base + 0x4050, 0xf)
- p.write32(pwr_base + 0x4058, 0xf)
- p.write32(pwr_base + 0x4060, 0xf)
- def power_off():
- p.write32(pwr_base + 0x4060, 0x0) # power domains, high -> low
- p.write32(pwr_base + 0x4058, 0x0)
- p.write32(pwr_base + 0x4050, 0x0)
- p.write32(pwr_base + 0x4048, 0x0)
- p.write32(pwr_base + 0x4040, 0x0)
- p.write32(pwr_base + 0x4038, 0x0)
- p.write32(pwr_base + 0x4030, 0x0)
- p.write32(pwr_base + 0x4028, 0x0)
- p.write32(pwr_base + 0x4020, 0x0)
- p.write32(pwr_base + 0x4018, 0x0)
- # some intermediate state for the first 3 power domains
- p.write32(pwr_base + 0x4010, 0xf0017ff)
- p.write32(pwr_base + 0x4008, 0xf0017ff)
- p.write32(pwr_base + 0x4000, 0x7ff)
- p.write32(pwr_base + 0x4010, 0x0) # now turn them off
- p.write32(pwr_base + 0x4008, 0x0)
- p.write32(pwr_base + 0x4000, 0x0)
- p.write32(0x22c508000, 0x103) # performance counters i think
- p.mask32(0x22c504000, 0xc01, 0xc03)
- p.write32(0x22a008014, 0x1) # something w/ voltages
- p.write32(0x22a0082bc, 0x1)
- p.write32(0x22a0082bc, 0x2)
- p.write32(0x22a0082bc, 0x4)
- power_on()
- atexit.register(power_off)
- w_tun()
- if DO_POLL:
- mon.add(ISP_IRQ_INTERRUPT, 0x4)
- mon.add(ISP_IRQ_ENABLE, 0x4)
- mon.add(ISP_IRQ_DOORBELL, 0x4)
- mon.add(ISP_IRQ_ACK, 0x4)
- mon.poll()
- # =============================================================================
- """
- (shared) iova memory map
- 0x0000000 - 0x09b4000; 0x09b4000: fw __TEXT
- 0x09b4000 - 0x0dd0000; 0x041c000: fw __DATA
- 0x0dd0000 - 0x1800000; 0x0a30000: internal heap fw uses for (fw) code execution
- 0x1800000 - 0x1804000; 0x0004000: not mapped
- 0x1804000 - 0x1820000; 0x001c000: ipc channels; see stage3()
- 0x1820000 - 0x1824000; 0x0004000: not mapped
- 0x1824000 - 0x3a24000; 0x2200000: extra heap requested by fw; for buffers & stuff
- """
- def load_fw():
- # text_phys = 0x8009e8000; text_iova = 0x000000; text_size = 0x9b4000;
- # data_phys = 0x8019b8000; data_iova = 0x9b4000; data_size = 0x41c000;
- (text_phys, text_iova, _, text_size, data_phys, data_iova, _, data_size) = struct.unpack('<QQQI4xQQQI4x', getattr(u.adt['/arm-io/isp'], 'segment-ranges'))
- dart.iomap_at(0, text_iova, text_phys, text_size)
- dart.iomap_at(0, data_iova, data_phys, data_size)
- heap_iova = data_iova + data_size # 0xdd0000
- heap_size = 0xa30000 # heap spans (0xdd0000 - 0x1800000)
- heap_phys = u.heap.memalign(PAGE_SIZE, heap_size)
- p.memset32(heap_phys, 0, heap_size)
- dart.iomap_at(0, heap_iova, heap_phys, heap_size)
- # base ttbr is initialized after iomap_at(), so copy it now
- p.write32(isp_dart1_base + 0x200, dart.dart.regs.TTBR[0, 0].val) # 0x22c0f4200
- p.write32(isp_dart2_base + 0x200, dart.dart.regs.TTBR[0, 0].val) # 0x22c0fc200
- load_fw()
- def do_power_reset():
- p.write32(ISP_ASC_EDPRCR, 0x2) # External Debug Power/Reset Control Register
- p.write32(isp_base + 0x738, 0xff00ff)
- p.write32(isp_base + 0x798, 0xff00ff)
- p.write32(isp_base + 0x7f8, 0xff00ff)
- p.write32(isp_base + 0x858, 0xff00ff) # needed?
- p.write32(isp_base + 0x1400a00, 0xffffffff) # power cycle asc
- p.write32(isp_base + 0x1400a04, 0xffffffff)
- p.write32(isp_base + 0x1400a08, 0xffffffff)
- p.write32(isp_base + 0x1400a0c, 0xffffffff)
- p.write32(isp_base + 0x1400a10, 0xffffffff)
- p.write32(isp_base + 0x1400a14, 0xffffffff)
- do_power_reset()
- def get_asc_status():
- status = p.read32(ISP_ASC_STATUS)
- if (status & 0x3) == 0:
- # can't be 0x28, 0x2c
- print("ASC not in WFI; status: 0x%x" % status)
- return 0
- # normally 0x2a on first boot, 0x22 after
- print("ASC in WFI; status: 0x%x" % status)
- return 1
- assert(get_asc_status()) # asc needs to be in wfi before booting
- def stage1():
- # p.read32(0x22c0fc2f0)
- p.write32(ISP_GPIO0, 0x0) # zero out gpios
- p.write32(ISP_GPIO1, 0x0)
- p.write32(ISP_GPIO2, 0x0)
- p.write32(ISP_GPIO3, 0x0)
- p.write32(ISP_GPIO4, 0x0)
- p.write32(ISP_GPIO5, 0x0)
- p.write32(ISP_GPIO6, 0x0)
- p.write32(ISP_GPIO7, 0x0)
- # p.write32(ISP_GPIO8, 0x1)
- p.write32(ISP_ASC_CONTROL, 0x0) # turn on asc
- p.write32(ISP_ASC_CONTROL, 0x10)
- # await ISP_GPIO7 to 0x0 -> 0x8042006
- p.write32(ISP_GPIO7, 0x0) # init signal to fw
- for n in range(MAX_TRIES):
- val = p.read32(ISP_GPIO7)
- print('ISP_GPIO7: 0x%x' % val)
- if (val == 0x8042006):
- print('got first magic number from firmware')
- break
- time.sleep(0.1)
- assert((p.read32(ISP_GPIO7) == 0x8042006))
- stage1()
- ipc_chan_count = p.read32(ISP_GPIO0) # 0x7; < 0x21
- ipc_args_offset = p.read32(ISP_GPIO1) # 0xef40
- unk_2 = p.read32(ISP_GPIO2) # 0x1
- extra_heap_size = p.read32(ISP_GPIO3) # 0x2200000
- unk_4 = p.read32(ISP_GPIO4) # 0x0
- print('ipc_chan_count: %d' % ipc_chan_count) # ISP_GPIO0
- print('ipc_args_offset: 0x%x' % ipc_args_offset) # ISP_GPIO1
- print('fw requested extra heap size: 0x%x' % extra_heap_size) # ISP_GPIO3
- # terminal, io, debug, buf_h2t, buf_t2h, sharedmalloc, io_t2h
- assert((ipc_chan_count == 0x7))
- # =============================================================================
- IPCBootArgs = Struct(
- "pad" / Default(Int32ul, 0),
- "pad" / Default(Int32ul, 0),
- "ipc_iova" / Int32ul, # 0x1804000
- "pad" / Default(Int32ul, 0),
- "unk0" / Int32ul, # 0x1800000
- "pad" / Default(Int32ul, 0),
- "unk1" / Int32ul, # 0xe800000
- "pad" / Default(Int32ul, 0),
- "heap_iova" / Int32ul, # 0x1824000
- "pad" / Default(Int32ul, 0),
- "heap_size" / Int32ul, # 0x2200000
- "pad" / Default(Int32ul, 0),
- "unk4" / Int32ul, # 0x1
- "pad" / Default(Int32ul, 0),
- "pad" / Default(Int32ul, 0),
- "pad" / Default(Int32ul, 0),
- "pad" / Padding(0x10),
- "ipc_size" / Int32ul, # 0x1c000
- "pad" / Default(Int32ul, 0),
- "pad" / Default(Int32ul, 0),
- "pad" / Default(Int32ul, 0),
- "pad" / Default(Int32ul, 0),
- "pad" / Default(Int32ul, 0),
- "unk5" / Int32ul, # 0x40
- "pad" / Default(Int32ul, 0),
- "pad" / Default(Int32ul, 0),
- "pad" / Default(Int32ul, 0),
- "unk6" / Int32ul, # 0x0 or 0x4b4c000
- "pad" / Default(Int32ul, 0),
- "pad" / Padding(0x20),
- "pad" / Default(Int32ul, 0),
- "unk7" / Int32ul, # 0x1
- "pad" / Default(Int32ul, 0),
- "pad" / Default(Int32ul, 0),
- "pad" / Default(Int32ul, 0),
- "pad" / Default(Int32ul, 0),
- "pad" / Default(Int32ul, 0),
- "unk8" / Int32ul, # 0x18130f4
- "pad" / Padding(0xb0),
- "pad" / Default(Int32ul, 0),
- "pad" / Default(Int32ul, 0),
- "pad" / Default(Int32ul, 0),
- "unk9" / Int32ul, # 0x3
- "pad" / Padding(0x10),
- )
- assert((IPCBootArgs.sizeof() == 0x190))
- def prep_ipc():
- # prep shared ipc buf
- ipc_iova = 0x1804000
- ipc_size = 0x1c000
- ipc_phys = u.heap.memalign(PAGE_SIZE, ipc_size)
- p.memset32(ipc_phys, 0, ipc_size)
- dart.iomap_at(0, ipc_iova, ipc_phys, ipc_size)
- """
- 00000000: 00000000 00000000 01804000 00000000 .........@......
- 00000010: 01800000 00000000 0e800000 00000000 ................
- 00000020: 01824000 00000000 02200000 00000000 .@........ .....
- 00000030: 00000001 00000000 00000000 00000000 ................
- 00000050: 0001c000 00000000 00000000 00000000 ................
- 00000060: 00000000 00000000 00000040 00000000 ........@.......
- 000000a0: 00000000 00000001 00000000 00000000 ................
- 000000b0: 00000000 00000000 00000000 018130f4 .............0..
- 00000170: 00000000 00000000 00000000 00000003 ................
- """
- bootargs = IPCBootArgs.build(dict(
- ipc_iova=ipc_iova,
- unk0=0x1800000,
- unk1=0xe800000,
- heap_iova=0x1824000,
- heap_size=0x2200000,
- unk4=0x1,
- ipc_size=0x1c000,
- unk5=0x40,
- unk6=0x0,
- unk7=0x1,
- unk8=0x18130f4,
- unk9=0x3,
- ))
- dart.iowrite(0, 0x1812f80, bootargs)
- # TODO this io patch works but idk why
- """
- +0000c740: 00000001 00000000 00000000 00000000 ................
- +0000c780: 00000001 00000000 00000000 00000000 ................
- +0000c7c0: 00000001 00000000 00000000 00000000 ................
- """
- patch = struct.pack("<l", 0x1) + (struct.pack("<l", 0x0)*0xf)
- patch = patch * 79 # (0xdb00 - 0xc740) // 0x40
- dart.iowrite(0, 0x1810700 + 0x40, patch)
- prep_ipc()
- if DO_POLL:
- iomon.add(0x1804000, 0x1c000)
- iomon.poll()
- def stage2():
- # alloc extra heap requested by fw
- extra_heap_iova = 0x1824000 # (0x1804000 + 0x1c000) + 0x4000
- extra_heap_phys = u.heap.memalign(PAGE_SIZE, extra_heap_size)
- p.memset32(extra_heap_phys, 0, extra_heap_size)
- dart.iomap_at(0, extra_heap_iova, extra_heap_phys, extra_heap_size)
- p.write32(ISP_GPIO0, 0x1812f80) # ipc_iova + 0xef80;
- p.write32(ISP_GPIO1, 0x0) # unk
- # await ISP_GPIO7 to 0xf7fbdff9 -> 0x8042006
- p.write32(ISP_GPIO7, 0xf7fbdff9) # signal to fw
- for n in range(MAX_TRIES):
- val = p.read32(ISP_GPIO7)
- print('ISP_GPIO7: 0x%x' % val)
- if (val == 0x8042006):
- print('got second magic number from firmware')
- break
- time.sleep(0.1)
- assert((p.read32(ISP_GPIO7) == 0x8042006))
- stage2()
- mon.poll()
- iomon.poll()
- # =============================================================================
- """
- TERMINAL - (type = 2, src = 0, size = 768, iova = 0x1804700)
- IO - (type = 0, src = 1, size = 8, iova = 0x1810700)
- DEBUG - (type = 0, src = 1, size = 8, iova = 0x1810900)
- BUF_H2T - (type = 0, src = 2, size = 64, iova = 0x1810b00)
- BUF_T2H - (type = 1, src = 3, size = 64, iova = 0x1811b00)
- SHAREDMALLOC - (type = 1, src = 3, size = 8, iova = 0x1812b00)
- IO_T2H - (type = 1, src = 3, size = 8, iova = 0x1812d00)
- 0x1804000 - 0x1804700; 0x0000 - 0x0700; 0x700; Table
- 0x1804700 - 0x1810700; 0x0700 - 0xc700; 0xc000; TERMINAL
- 0x1810700 - 0x1810900; 0xc700 - 0xc900; 0x200; IO
- 0x1810900 - 0x1810b00; 0xc900 - 0xcb00; 0x200; DEBUG
- 0x1810b00 - 0x1811b00; 0xcb00 - 0xdb00; 0x1000; BUF_H2T
- 0x1811b00 - 0x1812b00; 0xdb00 - 0xeb00; 0x1000; BUF_T2H
- 0x1812b00 - 0x1812d00; 0xeb00 - 0xed00; 0x200; SHAREDMALLOC
- 0x1812d00 - 0x1812f00; 0xed00 - 0xef00; 0x200; IO_T2H
- """
- IPCChanTableEntry = Struct(
- "name" / PaddedString(0x40, "utf8"),
- "type" / Int32ul, # +0x44
- "src" / Int32ul, # +0x48
- "num" / Int32ul, # +0x4c
- "pad" / Int32ul,
- "iova" / Hex(Int32ul), # +0x50
- "pad" / Default(Int32ul, 0),
- "pad" / Default(Int32ul, 0),
- "pad" / Default(Int32ul, 0),
- "pad" / Padding(0xa0),
- )
- assert((IPCChanTableEntry.sizeof() == 0x100))
- class ISPChannelMessage:
- COUNT = 8
- def __init__(self, **kwargs):
- self.__dict__.update(kwargs)
- # am I stupid? is there not a better way?
- @classmethod
- def build(cls, arg0=0x0, arg1=0x0, arg2=0x0, arg3=0x0, arg4=0x0, arg5=0x0, arg6=0x0, arg7=0x0):
- return cls(arg0=arg0, arg1=arg1, arg2=arg2, arg3=arg3,
- arg4=arg4, arg5=arg5, arg6=arg6, arg7=arg7)
- @classmethod
- def parse(cls, buf):
- arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 = struct.unpack("<8q", buf)
- return cls(arg0=arg0, arg1=arg1, arg2=arg2, arg3=arg3,
- arg4=arg4, arg5=arg5, arg6=arg6, arg7=arg7)
- def encode(self):
- return struct.pack("<8q", *(self.arg0, self.arg1, self.arg2, self.arg3,
- self.arg4, self.arg5, self.arg6, self.arg7))
- def __str__(self):
- s = "ISPMSG: ("
- for n in range(self.COUNT):
- g = getattr(self, f"arg{n}")
- s += "arg%d=0x%x" % (n, g)
- if (n < self.COUNT-1):
- s += ", "
- s += ")"
- return s
- class ISPChannel:
- WIDTH = 64
- def __init__(self, name, type_, src, num, iova):
- self.name = name
- self.type = type_
- self.src = src
- self.num = num
- self.size = self.num * self.WIDTH
- self.iova = iova
- def dump(self, name=""):
- data = dart.ioread(0, self.iova, self.size)
- name = self.name.lower() if not name else name
- open("%s.bin" % name, "wb").write(data)
- def get_iova(self, index):
- assert((index < self.num))
- return self.iova + (index * self.WIDTH)
- def read_entry(self, index):
- assert((index < self.num))
- return dart.ioread(0, self.get_iova(index), self.WIDTH)
- def read_msg(self, index):
- assert((index < self.num))
- return ISPChannelMessage.parse(self.read_entry(index))
- def send_msg(self, index, msg):
- assert((index < self.num))
- dart.iowrite(0, self.get_iova(index), msg.encode())
- class ISPChannelTable:
- def __init__(self, terminal, io, debug, buf_h2t, buf_t2h, sharedmalloc, io_t2h):
- self.terminal = terminal
- self.io = io
- self.debug = debug
- self.buf_h2t = buf_h2t
- self.buf_t2h = buf_t2h
- self.sharedmalloc = sharedmalloc
- self.io_t2h = io_t2h
- def stage3():
- chan_table_iova = p.read32(ISP_GPIO0) # 0x1804000
- unk_1 = p.read32(ISP_GPIO1) # 0x0
- print("channel description table at iova 0x%x" % chan_table_iova)
- ipc_width = IPCChanTableEntry.sizeof() # 0x100
- chan_table_data = dart.ioread(0, chan_table_iova, ipc_chan_count*ipc_width)
- channels = []
- for n in range(ipc_chan_count):
- chan_data = chan_table_data[n*ipc_width:(n+1)*ipc_width]
- parsed = IPCChanTableEntry.parse(chan_data)
- #print(parsed)
- chan = ISPChannel(parsed.name, parsed.type, parsed.src, parsed.num, parsed.iova)
- channels.append(chan)
- table = ISPChannelTable(*channels)
- # await ISP_GPIO3 to 0x8042006 -> 0x0
- p.write32(ISP_GPIO3, 0x8042006)
- for n in range(MAX_TRIES):
- val = p.read32(ISP_GPIO3)
- print('ISP_GPIO3: 0x%x' % val)
- if (val == 0x0):
- print('got third magic number from firmware')
- break
- time.sleep(0.1)
- assert((p.read32(ISP_GPIO3) == 0x0))
- return table
- table = stage3()
- p.write32(ISP_IRQ_ENABLE, 0x0)
- p.write32(ISP_IRQ_ENABLE, 0xf) # enable interrupts
- mon.poll()
- iomon.poll()
- # =============================================================================
- # doorbell from fw requesting malloc
- print("ISP_IRQ_INTERRUPT: 0x%x" % p.read32(ISP_IRQ_INTERRUPT))
- p.write32(ISP_IRQ_ACK, 0x8) # ack the request
- # TODO all this should go under SHAREDMALLOC handler
- # REQ: {Arg0: 0x0, Arg1: 0x18000, Arg2: 0x4c4f47, Arg3: 0x0, Arg4: 0x0, Arg5: 0x0, Arg6: 0x0, Arg7: 0x0, }
- # RSP: {Arg0: 0x3a28001, Arg1: 0x0, Arg2: 0x8, Arg3: 0x0, Arg4: 0x0, Arg5: 0x0, Arg6: 0x0, Arg7: 0x0, }
- # read request
- req = table.sharedmalloc.read_msg(0)
- print(req)
- # on malloc request arg0 (iova) is zeroed
- # ioread32(table.sharedmalloc.iova + 0x8) # 0x18000
- # chr(ioread32(table.sharedmalloc.iova + 0xc)) # 0x4c4f47 # 'LOG'
- size = req.arg1 # 0x18000
- name = struct.pack(">q", req.arg2).decode() # 0x4c4f47 # 'LOG'
- print("got SHAREDMALLOC request: size: 0x%x name: %s" % (size, name))
- iova = 0x3a28000 # next +0x4000 after fw requested heap
- ioalloc(iova, size)
- # prepare response
- # iowrite32(table.sharedmalloc.iova + 0x0, iova | 0x1)
- # iowrite32(table.sharedmalloc.iova + 0x8, 0x0)
- # iowrite32(table.sharedmalloc.iova + 0xc, 0x8)
- rsp = ISPChannelMessage.build(
- arg0 = iova | 0x1, # fill with new iova
- arg1 = 0x0, # zero out size
- arg2 = 0x8, # unk
- )
- print(rsp)
- table.sharedmalloc.send_msg(0, rsp)
- p.write32(ISP_IRQ_DOORBELL, 0x8)
- time.sleep(1)
- mon.poll()
- iomon.poll()
- print(dart.ioread(0, iova, size).decode())
- #run_shell(globals(), msg="Have fun!")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement