Advertisement
Guest User

isp_v3.py

a guest
Jul 16th, 2023
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 25.33 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. # SPDX-License-Identifier: MIT
  3. import sys, pathlib, time
  4. sys.path.append(str(pathlib.Path(__file__).resolve().parents[1]))
  5.  
  6. from m1n1.setup import *
  7. from m1n1.hw.dart import DART
  8. from m1n1.shell import run_shell
  9. #from m1n1.hw.isp import *
  10. from m1n1.fw.common import *
  11.  
  12. import atexit
  13. import struct
  14. from construct import *
  15.  
  16. PAGE_SIZE = 0x4000
  17. MAX_TRIES = 5
  18. DO_POLL = False
  19.  
  20. p.pmgr_adt_clocks_enable("/arm-io/isp")
  21. p.pmgr_adt_clocks_enable("/arm-io/dart-isp")
  22. dart = DART.from_adt(u, "/arm-io/dart-isp")
  23. dart.initialize()
  24.  
  25. isp_base = u.adt["/arm-io/isp"].get_reg(0)[0] # 0x22a000000
  26. pwr_base = u.adt["/arm-io/isp"].get_reg(1)[0] # 0x23b700000
  27.  
  28. # ane & isp have a 2nd & 3rd dart "domain"
  29. # they're not real darts, but it's also 0x4000 and their offsets resemble one
  30. # tldr they need these synced to the main domain
  31. # 1) ttbr (copy one-time after init). dma doesn't work without this.
  32. # 2) invalidation (sequence). it will panic & require hard reset.
  33. isp_dart0_base = u.adt["/arm-io/dart-isp"].get_reg(0)[0] # 0x22c0e8000
  34. isp_dart1_base = u.adt["/arm-io/dart-isp"].get_reg(1)[0] # 0x22c0f4000
  35. isp_dart2_base = u.adt["/arm-io/dart-isp"].get_reg(2)[0] # 0x22c0fc000
  36.  
  37. # gpios are +0x2100000
  38. ISP_GPIO0 = isp_base + 0x2104170
  39. ISP_GPIO1 = isp_base + 0x2104174
  40. ISP_GPIO2 = isp_base + 0x2104178
  41. ISP_GPIO3 = isp_base + 0x210417c
  42. ISP_GPIO4 = isp_base + 0x2104180
  43. ISP_GPIO5 = isp_base + 0x2104184
  44. ISP_GPIO6 = isp_base + 0x2104188
  45. ISP_GPIO7 = isp_base + 0x210418c
  46. ISP_GPIO8 = isp_base + 0x2104190
  47.  
  48. ISP_IRQ_INTERRUPT = isp_base + 0x2104000
  49. ISP_IRQ_ENABLE = isp_base + 0x2104004
  50. ISP_IRQ_DOORBELL = isp_base + 0x21043f0
  51. ISP_IRQ_ACK = isp_base + 0x21043fc
  52.  
  53. # asc controls are +0x100000 & +0x140000
  54. # gathered from ane panic logs (which happened to be the same for isp)
  55. ISP_ASC_RVBAR = isp_base + 0x1050000 # ANE_H11_CHINOOK_IO_RVBAR
  56. ISP_ASC_EDPRCR = isp_base + 0x1010310 # ANE_H11_ASC_CPU_EDPRCR
  57. ISP_ASC_CONTROL = isp_base + 0x1400044
  58. ISP_ASC_STATUS = isp_base + 0x1400048 # ANE_H11_ASCWRAP_IDLE_STATUS
  59.  
  60. # =============================================================================
  61.  
  62. # utils
  63. def ioread32(iova):
  64. return struct.unpack("<l", dart.ioread(0, iova, 0x4))[0]
  65.  
  66. def iowrite32(iova, val):
  67. dart.iowrite(0, iova, struct.pack("<l", val))
  68.  
  69. def ioalloc(iova, size):
  70. phys = u.heap.memalign(PAGE_SIZE, size)
  71. p.memset32(phys, 0, size)
  72. dart.iomap_at(0, iova, phys, size)
  73.  
  74. def wfile(fname, data):
  75. open(fname, "wb").write(data)
  76.  
  77. def rfile(fname):
  78. return open(fname, "rb").read()
  79.  
  80. mon = RegMonitor(u)
  81.  
  82. iomon = RegMonitor(u)
  83. def readmem_iova(iova, size, readfn):
  84. try:
  85. return dart.ioread(0, iova, size)
  86. except Exception as e:
  87. print(e)
  88. return None
  89. iomon.readmem = readmem_iova
  90.  
  91. # =============================================================================
  92.  
  93. def w_tun_a():
  94. # fabric tunables
  95. p.mask32(0x22a000000, 0x10, 0x10)
  96. p.mask32(0x22a000040, 0xffff, 0x50030)
  97. p.mask32(0x22a000044, 0xffff, 0xa0040)
  98. p.mask32(0x22a000400, 0x4, 0x40000001)
  99. p.mask32(0x22a000600, 0x0, 0x1ffffff)
  100. p.mask32(0x22a000738, 0x1ff01ff, 0x2) # these 4 are used in power reset
  101. p.mask32(0x22a000798, 0x1ff01ff, 0x300008)
  102. p.mask32(0x22a0007f8, 0x1ff01ff, 0x880020)
  103. p.mask32(0x22a000858, 0x1ff01ff, 0x200080)
  104. p.mask32(0x22a000900, 0x1, 0x101)
  105. p.mask32(0x22a000410, 0x100, 0x1100)
  106. p.mask32(0x22a000420, 0x100, 0x1100)
  107. p.mask32(0x22a000430, 0x100, 0x1100)
  108. p.mask32(0x22a008000, 0x0, 0x9)
  109. p.mask32(0x22a008000, 0x0, 0x9)
  110. p.mask32(0x22a000920, 0x0, 0x80)
  111.  
  112. p.write32(0x22a008008, 0x7)
  113. p.write32(0x22a008014, 0x1)
  114. p.mask32(0x22a008018, 0x0, 0x1)
  115. p.mask32(0x22a0007a8, 0x0, 0x1)
  116. p.write32(0x22a008208, 0x5)
  117. p.write32(0x22a008280, 0x20)
  118. p.write32(0x22a008288, 0x3)
  119. p.write32(0x22a00828c, 0xc)
  120. p.write32(0x22a008290, 0x18)
  121. p.write32(0x22a008294, 0x30)
  122. p.write32(0x22a008298, 0x78)
  123. p.write32(0x22a00829c, 0xff)
  124. p.mask32(0x22a0082b8, 0x0, 0x1)
  125. p.write32(0x22a0082bc, 0x1)
  126. p.mask32(0x22a0082c0, 0x0, 0x1)
  127. p.mask32(0x22a000748, 0x0, 0x1)
  128. p.write32(0x22a00820c, 0x3)
  129. p.write32(0x22a008284, 0x20)
  130. p.write32(0x22a0082a0, 0x3)
  131. p.write32(0x22a0082a4, 0xc)
  132. p.write32(0x22a0082a8, 0x18)
  133. p.write32(0x22a0082ac, 0x30)
  134. p.write32(0x22a0082b0, 0x78)
  135. p.write32(0x22a0082b4, 0xff)
  136. p.mask32(0x22a0082b8, 0x1, 0x3)
  137. p.write32(0x22a0082bc, 0x2)
  138. p.mask32(0x22a0082c0, 0x1, 0x3)
  139. p.write32(0x22a008210, 0x0)
  140. p.write32(0x22a008408, 0x3)
  141. p.write32(0x22a008418, 0x3)
  142. p.write32(0x22a00841c, 0x0)
  143. p.write32(0x22a008420, 0xffffffff)
  144. p.write32(0x22a008424, 0x0)
  145. p.write32(0x22a008428, 0xfff)
  146. p.mask32(0x22a0082b8, 0x3, 0x7)
  147. p.write32(0x22a0082bc, 0x4)
  148. p.mask32(0x22a0082c0, 0x3, 0x7)
  149.  
  150. def w_tun_b():
  151. p.write32(0x22c0e0080, 0x1)
  152. p.mask32(0x22c0f0020, 0x0, 0x80000000)
  153. p.mask32(0x22c0f8020, 0x0, 0x80000000)
  154.  
  155. def w_tun_c():
  156. dapf_cfg = getattr(u.adt['/arm-io/dart-isp'], 'filter-data-instance-0')
  157. dapf_base = u.adt['/arm-io/dart-isp'].reg[5].addr | 0x200000000
  158. offset = 0
  159. while offset < len(dapf_cfg):
  160. (start, end, _, r0h, r0l, _, r4) = struct.unpack_from('QQBBBBI', buffer=dapf_cfg, offset=offset)
  161. offset += 24
  162. p.write32(dapf_base + 0x4, r4)
  163. p.write32(dapf_base + 0x8, start & 0xFFFFFFFF)
  164. p.write32(dapf_base + 0xc, start >> 32) # macos does 32 bit writes, can we do 64?
  165. p.write32(dapf_base + 0x10, end & 0xFFFFFFFF)
  166. p.write32(dapf_base + 0x14, end >> 32)
  167. p.write32(dapf_base, (r0h << 4) | r0l)
  168. dapf_base += 0x40
  169.  
  170. def w_tun_d():
  171. p.write32(0x22c0e8100, 0x80) # TCR[0] = 0x80
  172. p.write32(0x22c0e813c, 0x100)
  173.  
  174. p.write32(isp_dart1_base + 0xfc, 0x1) # 0x22c0f40fc
  175. p.write32(isp_dart1_base + 0x200, dart.dart.regs.TTBR[0, 0].val) # 0x22c0f4200
  176. p.write32(isp_dart1_base + 0x2f0, 0x0) # 0x22c0f42f0
  177. p.write32(isp_dart1_base + 0x34, 0xffffffff) # 0x22c0f4034
  178. p.write32(isp_dart1_base + 0x20, 0x100000) # 0x22c0f4020
  179. p.mask32(isp_dart1_base + 0x60, 0x10000, 0x80016100) # 0x22c0f4060
  180. p.mask32(isp_dart1_base + 0x68, 0x20202, 0xf0f0f) # 0x22c0f4068
  181. p.mask32(isp_dart1_base + 0x6c, 0x0, 0x80808) # 0x22c0f406c
  182. p.write32(isp_dart1_base + 100, 0x80) # 0x22c0f4100
  183. p.write32(isp_dart1_base + 0x13c, 0x20000) # 0x22c0f413c
  184.  
  185. p.write32(isp_dart2_base + 0xfc, 0x1) # 0x22c0fc0fc
  186. p.write32(isp_dart2_base + 0x200, dart.dart.regs.TTBR[0, 0].val) # 0x22c0fc200
  187. p.write32(isp_dart2_base + 0x2f0, 0x0) # 0x22c0fc2f0
  188. p.write32(isp_dart2_base + 0x34, 0xffffffff) # 0x22c0fc034
  189. p.write32(isp_dart2_base + 0x20, 0x100000) # 0x22c0fc020
  190. p.mask32(isp_dart2_base + 0x60, 0x10000, 0x80016100) # 0x22c0fc060
  191. p.mask32(isp_dart2_base + 0x68, 0x20202, 0xf0f0f) # 0x22c0fc068
  192. p.mask32(isp_dart2_base + 0x6c, 0x0, 0x80808) # 0x22c0fc06c
  193. p.write32(isp_dart2_base + 100, 0x80) # 0x22c0fc100
  194. p.write32(isp_dart2_base + 0x13c, 0x20000) # 0x22c0fc13c
  195.  
  196. def w_tun():
  197. w_tun_a()
  198. w_tun_b()
  199. w_tun_c()
  200. w_tun_d()
  201.  
  202. # =============================================================================
  203.  
  204. def power_on():
  205. p.pmgr_adt_clocks_enable("/arm-io/isp")
  206. p.pmgr_adt_clocks_enable("/arm-io/dart-isp")
  207.  
  208. p.write32(pwr_base + 0x4000, 0xf) # power domains, low -> high
  209. p.write32(pwr_base + 0x4008, 0xf)
  210. p.write32(pwr_base + 0x4010, 0xf)
  211. p.write32(pwr_base + 0x4018, 0xf)
  212. p.write32(pwr_base + 0x4020, 0xf)
  213. p.write32(pwr_base + 0x4028, 0xf)
  214. p.write32(pwr_base + 0x4030, 0xf)
  215. p.write32(pwr_base + 0x4038, 0xf)
  216. p.write32(pwr_base + 0x4040, 0xf)
  217. p.write32(pwr_base + 0x4048, 0xf)
  218. p.write32(pwr_base + 0x4050, 0xf)
  219. p.write32(pwr_base + 0x4058, 0xf)
  220. p.write32(pwr_base + 0x4060, 0xf)
  221.  
  222. def power_off():
  223. p.write32(pwr_base + 0x4060, 0x0) # power domains, high -> low
  224. p.write32(pwr_base + 0x4058, 0x0)
  225. p.write32(pwr_base + 0x4050, 0x0)
  226. p.write32(pwr_base + 0x4048, 0x0)
  227. p.write32(pwr_base + 0x4040, 0x0)
  228. p.write32(pwr_base + 0x4038, 0x0)
  229. p.write32(pwr_base + 0x4030, 0x0)
  230. p.write32(pwr_base + 0x4028, 0x0)
  231. p.write32(pwr_base + 0x4020, 0x0)
  232. p.write32(pwr_base + 0x4018, 0x0)
  233.  
  234. # some intermediate state for the first 3 power domains
  235. p.write32(pwr_base + 0x4010, 0xf0017ff)
  236. p.write32(pwr_base + 0x4008, 0xf0017ff)
  237. p.write32(pwr_base + 0x4000, 0x7ff)
  238. p.write32(pwr_base + 0x4010, 0x0) # now turn them off
  239. p.write32(pwr_base + 0x4008, 0x0)
  240. p.write32(pwr_base + 0x4000, 0x0)
  241.  
  242. p.write32(0x22c508000, 0x103) # performance counters i think
  243. p.mask32(0x22c504000, 0xc01, 0xc03)
  244.  
  245. p.write32(0x22a008014, 0x1) # something w/ voltages
  246. p.write32(0x22a0082bc, 0x1)
  247. p.write32(0x22a0082bc, 0x2)
  248. p.write32(0x22a0082bc, 0x4)
  249.  
  250. power_on()
  251. atexit.register(power_off)
  252. w_tun()
  253.  
  254. if DO_POLL:
  255. mon.add(ISP_IRQ_INTERRUPT, 0x4)
  256. mon.add(ISP_IRQ_ENABLE, 0x4)
  257. mon.add(ISP_IRQ_DOORBELL, 0x4)
  258. mon.add(ISP_IRQ_ACK, 0x4)
  259. mon.poll()
  260.  
  261. # =============================================================================
  262.  
  263. """
  264. (shared) iova memory map
  265.  
  266. 0x0000000 - 0x09b4000; 0x09b4000: fw __TEXT
  267. 0x09b4000 - 0x0dd0000; 0x041c000: fw __DATA
  268. 0x0dd0000 - 0x1800000; 0x0a30000: internal heap fw uses for (fw) code execution
  269. 0x1800000 - 0x1804000; 0x0004000: not mapped
  270. 0x1804000 - 0x1820000; 0x001c000: ipc channels; see stage3()
  271. 0x1820000 - 0x1824000; 0x0004000: not mapped
  272. 0x1824000 - 0x3a24000; 0x2200000: extra heap requested by fw; for buffers & stuff
  273. """
  274.  
  275. def load_fw():
  276. # text_phys = 0x8009e8000; text_iova = 0x000000; text_size = 0x9b4000;
  277. # data_phys = 0x8019b8000; data_iova = 0x9b4000; data_size = 0x41c000;
  278. (text_phys, text_iova, _, text_size, data_phys, data_iova, _, data_size) = struct.unpack('<QQQI4xQQQI4x', getattr(u.adt['/arm-io/isp'], 'segment-ranges'))
  279. dart.iomap_at(0, text_iova, text_phys, text_size)
  280. dart.iomap_at(0, data_iova, data_phys, data_size)
  281.  
  282. heap_iova = data_iova + data_size # 0xdd0000
  283. heap_size = 0xa30000 # heap spans (0xdd0000 - 0x1800000)
  284. heap_phys = u.heap.memalign(PAGE_SIZE, heap_size)
  285. p.memset32(heap_phys, 0, heap_size)
  286. dart.iomap_at(0, heap_iova, heap_phys, heap_size)
  287.  
  288. # base ttbr is initialized after iomap_at(), so copy it now
  289. p.write32(isp_dart1_base + 0x200, dart.dart.regs.TTBR[0, 0].val) # 0x22c0f4200
  290. p.write32(isp_dart2_base + 0x200, dart.dart.regs.TTBR[0, 0].val) # 0x22c0fc200
  291.  
  292. load_fw()
  293.  
  294. def do_power_reset():
  295. p.write32(ISP_ASC_EDPRCR, 0x2) # External Debug Power/Reset Control Register
  296.  
  297. p.write32(isp_base + 0x738, 0xff00ff)
  298. p.write32(isp_base + 0x798, 0xff00ff)
  299. p.write32(isp_base + 0x7f8, 0xff00ff)
  300. p.write32(isp_base + 0x858, 0xff00ff) # needed?
  301.  
  302. p.write32(isp_base + 0x1400a00, 0xffffffff) # power cycle asc
  303. p.write32(isp_base + 0x1400a04, 0xffffffff)
  304. p.write32(isp_base + 0x1400a08, 0xffffffff)
  305. p.write32(isp_base + 0x1400a0c, 0xffffffff)
  306. p.write32(isp_base + 0x1400a10, 0xffffffff)
  307. p.write32(isp_base + 0x1400a14, 0xffffffff)
  308.  
  309. do_power_reset()
  310.  
  311. def get_asc_status():
  312. status = p.read32(ISP_ASC_STATUS)
  313. if (status & 0x3) == 0:
  314. # can't be 0x28, 0x2c
  315. print("ASC not in WFI; status: 0x%x" % status)
  316. return 0
  317. # normally 0x2a on first boot, 0x22 after
  318. print("ASC in WFI; status: 0x%x" % status)
  319. return 1
  320.  
  321. assert(get_asc_status()) # asc needs to be in wfi before booting
  322.  
  323. def stage1():
  324. # p.read32(0x22c0fc2f0)
  325.  
  326. p.write32(ISP_GPIO0, 0x0) # zero out gpios
  327. p.write32(ISP_GPIO1, 0x0)
  328. p.write32(ISP_GPIO2, 0x0)
  329. p.write32(ISP_GPIO3, 0x0)
  330. p.write32(ISP_GPIO4, 0x0)
  331. p.write32(ISP_GPIO5, 0x0)
  332. p.write32(ISP_GPIO6, 0x0)
  333. p.write32(ISP_GPIO7, 0x0)
  334. # p.write32(ISP_GPIO8, 0x1)
  335.  
  336. p.write32(ISP_ASC_CONTROL, 0x0) # turn on asc
  337. p.write32(ISP_ASC_CONTROL, 0x10)
  338.  
  339. # await ISP_GPIO7 to 0x0 -> 0x8042006
  340. p.write32(ISP_GPIO7, 0x0) # init signal to fw
  341. for n in range(MAX_TRIES):
  342. val = p.read32(ISP_GPIO7)
  343. print('ISP_GPIO7: 0x%x' % val)
  344. if (val == 0x8042006):
  345. print('got first magic number from firmware')
  346. break
  347. time.sleep(0.1)
  348. assert((p.read32(ISP_GPIO7) == 0x8042006))
  349.  
  350. stage1()
  351.  
  352. ipc_chan_count = p.read32(ISP_GPIO0) # 0x7; < 0x21
  353. ipc_args_offset = p.read32(ISP_GPIO1) # 0xef40
  354. unk_2 = p.read32(ISP_GPIO2) # 0x1
  355. extra_heap_size = p.read32(ISP_GPIO3) # 0x2200000
  356. unk_4 = p.read32(ISP_GPIO4) # 0x0
  357. print('ipc_chan_count: %d' % ipc_chan_count) # ISP_GPIO0
  358. print('ipc_args_offset: 0x%x' % ipc_args_offset) # ISP_GPIO1
  359. print('fw requested extra heap size: 0x%x' % extra_heap_size) # ISP_GPIO3
  360.  
  361. # terminal, io, debug, buf_h2t, buf_t2h, sharedmalloc, io_t2h
  362. assert((ipc_chan_count == 0x7))
  363.  
  364. # =============================================================================
  365.  
  366. IPCBootArgs = Struct(
  367. "pad" / Default(Int32ul, 0),
  368. "pad" / Default(Int32ul, 0),
  369. "ipc_iova" / Int32ul, # 0x1804000
  370. "pad" / Default(Int32ul, 0),
  371.  
  372. "unk0" / Int32ul, # 0x1800000
  373. "pad" / Default(Int32ul, 0),
  374. "unk1" / Int32ul, # 0xe800000
  375. "pad" / Default(Int32ul, 0),
  376.  
  377. "heap_iova" / Int32ul, # 0x1824000
  378. "pad" / Default(Int32ul, 0),
  379. "heap_size" / Int32ul, # 0x2200000
  380. "pad" / Default(Int32ul, 0),
  381.  
  382. "unk4" / Int32ul, # 0x1
  383. "pad" / Default(Int32ul, 0),
  384. "pad" / Default(Int32ul, 0),
  385. "pad" / Default(Int32ul, 0),
  386.  
  387. "pad" / Padding(0x10),
  388.  
  389. "ipc_size" / Int32ul, # 0x1c000
  390. "pad" / Default(Int32ul, 0),
  391. "pad" / Default(Int32ul, 0),
  392. "pad" / Default(Int32ul, 0),
  393.  
  394. "pad" / Default(Int32ul, 0),
  395. "pad" / Default(Int32ul, 0),
  396. "unk5" / Int32ul, # 0x40
  397. "pad" / Default(Int32ul, 0),
  398.  
  399. "pad" / Default(Int32ul, 0),
  400. "pad" / Default(Int32ul, 0),
  401. "unk6" / Int32ul, # 0x0 or 0x4b4c000
  402. "pad" / Default(Int32ul, 0),
  403.  
  404. "pad" / Padding(0x20),
  405.  
  406. "pad" / Default(Int32ul, 0),
  407. "unk7" / Int32ul, # 0x1
  408. "pad" / Default(Int32ul, 0),
  409. "pad" / Default(Int32ul, 0),
  410.  
  411. "pad" / Default(Int32ul, 0),
  412. "pad" / Default(Int32ul, 0),
  413. "pad" / Default(Int32ul, 0),
  414. "unk8" / Int32ul, # 0x18130f4
  415.  
  416. "pad" / Padding(0xb0),
  417.  
  418. "pad" / Default(Int32ul, 0),
  419. "pad" / Default(Int32ul, 0),
  420. "pad" / Default(Int32ul, 0),
  421. "unk9" / Int32ul, # 0x3
  422.  
  423. "pad" / Padding(0x10),
  424. )
  425. assert((IPCBootArgs.sizeof() == 0x190))
  426.  
  427. def prep_ipc():
  428. # prep shared ipc buf
  429. ipc_iova = 0x1804000
  430. ipc_size = 0x1c000
  431. ipc_phys = u.heap.memalign(PAGE_SIZE, ipc_size)
  432. p.memset32(ipc_phys, 0, ipc_size)
  433. dart.iomap_at(0, ipc_iova, ipc_phys, ipc_size)
  434.  
  435. """
  436. 00000000: 00000000 00000000 01804000 00000000 .........@......
  437. 00000010: 01800000 00000000 0e800000 00000000 ................
  438. 00000020: 01824000 00000000 02200000 00000000 .@........ .....
  439. 00000030: 00000001 00000000 00000000 00000000 ................
  440. 00000050: 0001c000 00000000 00000000 00000000 ................
  441. 00000060: 00000000 00000000 00000040 00000000 ........@.......
  442. 000000a0: 00000000 00000001 00000000 00000000 ................
  443. 000000b0: 00000000 00000000 00000000 018130f4 .............0..
  444. 00000170: 00000000 00000000 00000000 00000003 ................
  445. """
  446. bootargs = IPCBootArgs.build(dict(
  447. ipc_iova=ipc_iova,
  448. unk0=0x1800000,
  449. unk1=0xe800000,
  450. heap_iova=0x1824000,
  451. heap_size=0x2200000,
  452. unk4=0x1,
  453. ipc_size=0x1c000,
  454. unk5=0x40,
  455. unk6=0x0,
  456. unk7=0x1,
  457. unk8=0x18130f4,
  458. unk9=0x3,
  459. ))
  460. dart.iowrite(0, 0x1812f80, bootargs)
  461.  
  462. # TODO this io patch works but idk why
  463. """
  464. +0000c740: 00000001 00000000 00000000 00000000 ................
  465. +0000c780: 00000001 00000000 00000000 00000000 ................
  466. +0000c7c0: 00000001 00000000 00000000 00000000 ................
  467. """
  468. patch = struct.pack("<l", 0x1) + (struct.pack("<l", 0x0)*0xf)
  469. patch = patch * 79 # (0xdb00 - 0xc740) // 0x40
  470. dart.iowrite(0, 0x1810700 + 0x40, patch)
  471.  
  472. prep_ipc()
  473. if DO_POLL:
  474. iomon.add(0x1804000, 0x1c000)
  475. iomon.poll()
  476.  
  477. def stage2():
  478. # alloc extra heap requested by fw
  479. extra_heap_iova = 0x1824000 # (0x1804000 + 0x1c000) + 0x4000
  480. extra_heap_phys = u.heap.memalign(PAGE_SIZE, extra_heap_size)
  481. p.memset32(extra_heap_phys, 0, extra_heap_size)
  482. dart.iomap_at(0, extra_heap_iova, extra_heap_phys, extra_heap_size)
  483.  
  484.  
  485. p.write32(ISP_GPIO0, 0x1812f80) # ipc_iova + 0xef80;
  486. p.write32(ISP_GPIO1, 0x0) # unk
  487.  
  488. # await ISP_GPIO7 to 0xf7fbdff9 -> 0x8042006
  489. p.write32(ISP_GPIO7, 0xf7fbdff9) # signal to fw
  490. for n in range(MAX_TRIES):
  491. val = p.read32(ISP_GPIO7)
  492. print('ISP_GPIO7: 0x%x' % val)
  493. if (val == 0x8042006):
  494. print('got second magic number from firmware')
  495. break
  496. time.sleep(0.1)
  497. assert((p.read32(ISP_GPIO7) == 0x8042006))
  498.  
  499. stage2()
  500.  
  501. mon.poll()
  502. iomon.poll()
  503.  
  504. # =============================================================================
  505.  
  506. """
  507. TERMINAL - (type = 2, src = 0, size = 768, iova = 0x1804700)
  508. IO - (type = 0, src = 1, size = 8, iova = 0x1810700)
  509. DEBUG - (type = 0, src = 1, size = 8, iova = 0x1810900)
  510. BUF_H2T - (type = 0, src = 2, size = 64, iova = 0x1810b00)
  511. BUF_T2H - (type = 1, src = 3, size = 64, iova = 0x1811b00)
  512. SHAREDMALLOC - (type = 1, src = 3, size = 8, iova = 0x1812b00)
  513. IO_T2H - (type = 1, src = 3, size = 8, iova = 0x1812d00)
  514.  
  515. 0x1804000 - 0x1804700; 0x0000 - 0x0700; 0x700; Table
  516. 0x1804700 - 0x1810700; 0x0700 - 0xc700; 0xc000; TERMINAL
  517. 0x1810700 - 0x1810900; 0xc700 - 0xc900; 0x200; IO
  518. 0x1810900 - 0x1810b00; 0xc900 - 0xcb00; 0x200; DEBUG
  519. 0x1810b00 - 0x1811b00; 0xcb00 - 0xdb00; 0x1000; BUF_H2T
  520. 0x1811b00 - 0x1812b00; 0xdb00 - 0xeb00; 0x1000; BUF_T2H
  521. 0x1812b00 - 0x1812d00; 0xeb00 - 0xed00; 0x200; SHAREDMALLOC
  522. 0x1812d00 - 0x1812f00; 0xed00 - 0xef00; 0x200; IO_T2H
  523. """
  524.  
  525. IPCChanTableEntry = Struct(
  526. "name" / PaddedString(0x40, "utf8"),
  527. "type" / Int32ul, # +0x44
  528. "src" / Int32ul, # +0x48
  529. "num" / Int32ul, # +0x4c
  530. "pad" / Int32ul,
  531. "iova" / Hex(Int32ul), # +0x50
  532. "pad" / Default(Int32ul, 0),
  533. "pad" / Default(Int32ul, 0),
  534. "pad" / Default(Int32ul, 0),
  535. "pad" / Padding(0xa0),
  536. )
  537. assert((IPCChanTableEntry.sizeof() == 0x100))
  538.  
  539.  
  540. class ISPChannelMessage:
  541. COUNT = 8
  542. def __init__(self, **kwargs):
  543. self.__dict__.update(kwargs)
  544.  
  545. # am I stupid? is there not a better way?
  546. @classmethod
  547. def build(cls, arg0=0x0, arg1=0x0, arg2=0x0, arg3=0x0, arg4=0x0, arg5=0x0, arg6=0x0, arg7=0x0):
  548. return cls(arg0=arg0, arg1=arg1, arg2=arg2, arg3=arg3,
  549. arg4=arg4, arg5=arg5, arg6=arg6, arg7=arg7)
  550.  
  551. @classmethod
  552. def parse(cls, buf):
  553. arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 = struct.unpack("<8q", buf)
  554. return cls(arg0=arg0, arg1=arg1, arg2=arg2, arg3=arg3,
  555. arg4=arg4, arg5=arg5, arg6=arg6, arg7=arg7)
  556.  
  557. def encode(self):
  558. return struct.pack("<8q", *(self.arg0, self.arg1, self.arg2, self.arg3,
  559. self.arg4, self.arg5, self.arg6, self.arg7))
  560.  
  561. def __str__(self):
  562. s = "ISPMSG: ("
  563. for n in range(self.COUNT):
  564. g = getattr(self, f"arg{n}")
  565. s += "arg%d=0x%x" % (n, g)
  566. if (n < self.COUNT-1):
  567. s += ", "
  568. s += ")"
  569. return s
  570.  
  571.  
  572. class ISPChannel:
  573. WIDTH = 64
  574. def __init__(self, name, type_, src, num, iova):
  575. self.name = name
  576. self.type = type_
  577. self.src = src
  578. self.num = num
  579. self.size = self.num * self.WIDTH
  580. self.iova = iova
  581.  
  582. def dump(self, name=""):
  583. data = dart.ioread(0, self.iova, self.size)
  584. name = self.name.lower() if not name else name
  585. open("%s.bin" % name, "wb").write(data)
  586.  
  587. def get_iova(self, index):
  588. assert((index < self.num))
  589. return self.iova + (index * self.WIDTH)
  590.  
  591. def read_entry(self, index):
  592. assert((index < self.num))
  593. return dart.ioread(0, self.get_iova(index), self.WIDTH)
  594.  
  595. def read_msg(self, index):
  596. assert((index < self.num))
  597. return ISPChannelMessage.parse(self.read_entry(index))
  598.  
  599. def send_msg(self, index, msg):
  600. assert((index < self.num))
  601. dart.iowrite(0, self.get_iova(index), msg.encode())
  602.  
  603.  
  604. class ISPChannelTable:
  605. def __init__(self, terminal, io, debug, buf_h2t, buf_t2h, sharedmalloc, io_t2h):
  606. self.terminal = terminal
  607. self.io = io
  608. self.debug = debug
  609. self.buf_h2t = buf_h2t
  610. self.buf_t2h = buf_t2h
  611. self.sharedmalloc = sharedmalloc
  612. self.io_t2h = io_t2h
  613.  
  614.  
  615. def stage3():
  616. chan_table_iova = p.read32(ISP_GPIO0) # 0x1804000
  617. unk_1 = p.read32(ISP_GPIO1) # 0x0
  618. print("channel description table at iova 0x%x" % chan_table_iova)
  619.  
  620. ipc_width = IPCChanTableEntry.sizeof() # 0x100
  621. chan_table_data = dart.ioread(0, chan_table_iova, ipc_chan_count*ipc_width)
  622. channels = []
  623. for n in range(ipc_chan_count):
  624. chan_data = chan_table_data[n*ipc_width:(n+1)*ipc_width]
  625. parsed = IPCChanTableEntry.parse(chan_data)
  626. #print(parsed)
  627. chan = ISPChannel(parsed.name, parsed.type, parsed.src, parsed.num, parsed.iova)
  628. channels.append(chan)
  629. table = ISPChannelTable(*channels)
  630.  
  631. # await ISP_GPIO3 to 0x8042006 -> 0x0
  632. p.write32(ISP_GPIO3, 0x8042006)
  633. for n in range(MAX_TRIES):
  634. val = p.read32(ISP_GPIO3)
  635. print('ISP_GPIO3: 0x%x' % val)
  636. if (val == 0x0):
  637. print('got third magic number from firmware')
  638. break
  639. time.sleep(0.1)
  640. assert((p.read32(ISP_GPIO3) == 0x0))
  641.  
  642. return table
  643.  
  644.  
  645. table = stage3()
  646.  
  647. p.write32(ISP_IRQ_ENABLE, 0x0)
  648. p.write32(ISP_IRQ_ENABLE, 0xf) # enable interrupts
  649.  
  650. mon.poll()
  651. iomon.poll()
  652.  
  653. # =============================================================================
  654.  
  655. # doorbell from fw requesting malloc
  656. print("ISP_IRQ_INTERRUPT: 0x%x" % p.read32(ISP_IRQ_INTERRUPT))
  657. p.write32(ISP_IRQ_ACK, 0x8) # ack the request
  658.  
  659. # TODO all this should go under SHAREDMALLOC handler
  660. # REQ: {Arg0: 0x0, Arg1: 0x18000, Arg2: 0x4c4f47, Arg3: 0x0, Arg4: 0x0, Arg5: 0x0, Arg6: 0x0, Arg7: 0x0, }
  661. # RSP: {Arg0: 0x3a28001, Arg1: 0x0, Arg2: 0x8, Arg3: 0x0, Arg4: 0x0, Arg5: 0x0, Arg6: 0x0, Arg7: 0x0, }
  662.  
  663. # read request
  664. req = table.sharedmalloc.read_msg(0)
  665. print(req)
  666. # on malloc request arg0 (iova) is zeroed
  667. # ioread32(table.sharedmalloc.iova + 0x8) # 0x18000
  668. # chr(ioread32(table.sharedmalloc.iova + 0xc)) # 0x4c4f47 # 'LOG'
  669. size = req.arg1 # 0x18000
  670. name = struct.pack(">q", req.arg2).decode() # 0x4c4f47 # 'LOG'
  671. print("got SHAREDMALLOC request: size: 0x%x name: %s" % (size, name))
  672.  
  673. iova = 0x3a28000 # next +0x4000 after fw requested heap
  674. ioalloc(iova, size)
  675.  
  676. # prepare response
  677. # iowrite32(table.sharedmalloc.iova + 0x0, iova | 0x1)
  678. # iowrite32(table.sharedmalloc.iova + 0x8, 0x0)
  679. # iowrite32(table.sharedmalloc.iova + 0xc, 0x8)
  680. rsp = ISPChannelMessage.build(
  681. arg0 = iova | 0x1, # fill with new iova
  682. arg1 = 0x0, # zero out size
  683. arg2 = 0x8, # unk
  684. )
  685. print(rsp)
  686. table.sharedmalloc.send_msg(0, rsp)
  687.  
  688. p.write32(ISP_IRQ_DOORBELL, 0x8)
  689. time.sleep(1)
  690.  
  691. mon.poll()
  692. iomon.poll()
  693.  
  694. print(dart.ioread(0, iova, size).decode())
  695.  
  696.  
  697. #run_shell(globals(), msg="Have fun!")
  698.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement