Guest User

isp_v2.py

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