Guest User

Untitled

a guest
Jan 23rd, 2018
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.72 KB | None | 0 0
  1. /*
  2. * This program is free software; you can redistribute it and/or modify
  3. * it under the terms of the GNU General Public License as published by
  4. * the Free Software Foundation; version 2 of the License.
  5. *
  6. * This program is distributed in the hope that it will be useful,
  7. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. * GNU General Public License for more details.
  10. *
  11. * You should have received a copy of the GNU General Public License
  12. * along with this program; if not, write to the Free Software
  13. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  14. */
  15.  
  16. #include <lv1call.h>
  17. #include <mm.h>
  18. #include <gelic.h>
  19. #include <vas.h>
  20. #include <if_ether.h>
  21. #include <memcpy.h>
  22. #include <system.h>
  23. #include <time.h>
  24. #include <eid.h>
  25. #include <spu.h>
  26. #include <beep.h>
  27. #include <sb_iso.h>
  28. #include <sb_iso_get_rnd.h>
  29.  
  30. #define LDR_BASE 0x8000000014000000ULL
  31. #define LDR_OFFSET 0x14000000ULL
  32. #define LDR_PAGE_SIZE 16
  33. #define LDR_SIZE 0x2300000
  34. #define LDR_SIZE 0x2300000
  35. #define METLDR_SIZE 0x100000
  36. #define ISOLDR_SIZE 0x100000
  37. #define RVKPRG_SIZE 0x100000
  38. #define SPU_MODULE_SIZE 0x1000000
  39.  
  40. #define SPU_SHADOW_BASE 0x80000000133D0000ULL
  41. #define SPU_SHADOW_OFFSET 0x133D0000ULL
  42. #define SPU_SHADOW_SIZE 0x1000
  43.  
  44. #define SPU_PROBLEM_BASE 0x8000000013400000ULL
  45. #define SPU_PROBLEM_OFFSET 0x13400000ULL
  46. #define SPU_PROBLEM_SIZE 0x20000
  47.  
  48. #define SPU_PRIV2_BASE 0x8000000013420000ULL
  49. #define SPU_PRIV2_OFFSET 0x13420000ULL
  50. #define SPU_PRIV2_SIZE 0x20000
  51.  
  52. #define SPU_LS_BASE 0x8000000013440000ULL
  53. #define SPU_LS_OFFSET 0x13440000ULL
  54. #define SPU_LS_SIZE 0x40000
  55.  
  56. #define EID0_LS_ADDR 0x3E400
  57. #define LDR_ARGS_LS_ADDR 0x3E800
  58. #define RVK_PRG_LS_ADDR 0x3F000
  59.  
  60. struct ldr_args
  61. {
  62. u64 prog_auth_id;
  63. u64 lpar_auth_id;
  64. void *spu_module;
  65. void *spu_module_arg1;
  66. u64 spu_module_arg1_size;
  67. void *spu_module_arg2;
  68. u64 spu_module_arg2_size;
  69. u8 res1[16];
  70. u64 field48;
  71. u8 res2[16];
  72. };
  73.  
  74. static volatile u64 ldr_lpar_addr = 0x700020000000ULL + 0xE900000ULL - LDR_SIZE;
  75.  
  76. static volatile u64 lpar_auth_id = 0x1070000002000001;
  77. static volatile u64 prog_auth_id = 0x1050000003000001;
  78.  
  79. static volatile u64 esid = 0x8000000018000000;
  80. static volatile u64 vsid = 0x0000000000001400;
  81.  
  82. static struct ldr_args __attribute__ ((aligned ((128)))) ldr_args;
  83.  
  84. static volatile u64 __attribute__ ((aligned ((128)))) spu_ls_0x3EC00_value[12] = { -1 };
  85.  
  86. static volatile u64 __attribute__ ((aligned ((128)))) spu_ls_0x3E000_value[] =
  87. { 0xFF00000000ULL, 0 };
  88.  
  89. static volatile u8 __attribute__ ((aligned ((128)))) debug_buffer[4096];
  90.  
  91. static volatile u8 __attribute__ ((aligned ((128)))) spu_args[0x80];
  92.  
  93. int sb_iso_get_rnd(void)
  94. {
  95. u64 priv2_addr, problem_phys, local_store_phys, unused, shadow_addr, spe_id, intr_status;
  96. u8 *metldr, *isoldr, *rvkprg, *spu_module;
  97. struct spu_shadow volatile *spu_shadow;
  98. struct spu_problem volatile *spu_problem;
  99. struct spu_priv2 volatile *spu_priv2;
  100. u8 volatile *spu_ls;
  101. u64 ticks;
  102. u32 spu_out_intr_mbox_value;
  103. u32 spu_out_mbox_value;
  104. u8 mfc_cmd_tag;
  105. struct sb_iso_debug_buffer *sb_iso_debug_buffer;
  106. struct sb_iso_header *sb_iso_header;
  107. struct sb_iso_get_rnd *sb_iso_get_rnd;
  108. int metldr_size, isoldr_size, rvkprg_size, spu_module_size, i, result;
  109.  
  110. MM_LOAD_BASE(metldr, LDR_OFFSET);
  111.  
  112. result = mm_map_lpar_memory_region(0, MM_EA2VA((u64) metldr), ldr_lpar_addr,
  113. LDR_SIZE, 0xC, 0, 0);
  114. if (result != 0)
  115. return result;
  116.  
  117. metldr_size = gelic_recv_data(metldr, METLDR_SIZE);
  118. if (metldr_size <= 0)
  119. return metldr_size;
  120.  
  121. isoldr = metldr + METLDR_SIZE;
  122.  
  123. isoldr_size = gelic_recv_data(isoldr, ISOLDR_SIZE);
  124. if (isoldr_size <= 0)
  125. return isoldr_size;
  126.  
  127. rvkprg = isoldr + ISOLDR_SIZE;
  128.  
  129. rvkprg_size = gelic_recv_data(rvkprg, RVKPRG_SIZE);
  130. if (rvkprg_size <= 0)
  131. return rvkprg_size;
  132.  
  133. spu_module = rvkprg + RVKPRG_SIZE;
  134.  
  135. spu_module_size = gelic_recv_data(spu_module, SPU_MODULE_SIZE);
  136. if (spu_module_size <= 0)
  137. return spu_module_size;
  138.  
  139. result = lv1_construct_logical_spe(0xC, 0xC, 0xC, 0xC, 0xC, vas_get_id(), 0,
  140. &priv2_addr, &problem_phys, &local_store_phys, &unused, &shadow_addr, &spe_id);
  141. if (result != 0)
  142. return result;
  143.  
  144. result = lv1_enable_logical_spe(spe_id, 6);
  145. if (result != 0)
  146. return result;
  147.  
  148. result = lv1_set_spe_interrupt_mask(spe_id, 0, 0x7);
  149. if (result != 0)
  150. return result;
  151.  
  152. result = lv1_set_spe_interrupt_mask(spe_id, 1, 0xF);
  153. if (result != 0)
  154. return result;
  155.  
  156. result = lv1_set_spe_interrupt_mask(spe_id, 2, 0xF);
  157. if (result != 0)
  158. return result;
  159.  
  160. MM_LOAD_BASE(spu_shadow, SPU_SHADOW_OFFSET);
  161.  
  162. result = mm_map_lpar_memory_region(0, MM_EA2VA((u64) spu_shadow), shadow_addr,
  163. SPU_SHADOW_SIZE, 0xC, 0, 0x3);
  164. if (result != 0)
  165. return result;
  166.  
  167. MM_LOAD_BASE(spu_problem, SPU_PROBLEM_OFFSET);
  168.  
  169. result = mm_map_lpar_memory_region(0, MM_EA2VA((u64) spu_problem), problem_phys,
  170. SPU_PROBLEM_SIZE, 0xC, 0, 0);
  171. if (result != 0)
  172. return result;
  173.  
  174. MM_LOAD_BASE(spu_priv2, SPU_PRIV2_OFFSET);
  175.  
  176. result = mm_map_lpar_memory_region(0, MM_EA2VA((u64) spu_priv2), priv2_addr,
  177. SPU_PRIV2_SIZE, 0xC, 0, 0);
  178. if (result != 0)
  179. return result;
  180.  
  181. MM_LOAD_BASE(spu_ls, SPU_LS_OFFSET);
  182.  
  183. result = mm_map_lpar_memory_region(0, MM_EA2VA((u64) spu_ls), local_store_phys,
  184. SPU_LS_SIZE, 0xC, 0, 0);
  185. if (result != 0)
  186. return result;
  187.  
  188. result = lv1_set_spe_privilege_state_area_1_register(spe_id, MFC_SR1, 0x10);
  189. if (result != 0)
  190. return result;
  191.  
  192. spu_slb_invalidate_all(spu_priv2);
  193.  
  194. spu_slb_set_entry(spu_priv2, 0, esid, vsid);
  195.  
  196. spu_priv2->spu_cfg = 0;
  197.  
  198. eieio();
  199.  
  200. spu_in_mbox_write_64(spu_problem, (u64) isoldr);
  201.  
  202. spu_sig_notify_1_2_write_64(spu_problem, (u64) metldr);
  203.  
  204. spu_iso_load_req_enable(spu_priv2);
  205.  
  206. spu_iso_load_req(spu_problem);
  207.  
  208. while (1)
  209. {
  210. result = lv1_get_spe_interrupt_status(spe_id, 0, &intr_status);
  211. if (result != 0)
  212. return result;
  213.  
  214. if (intr_status)
  215. {
  216. result = gelic_xmit_data(gelic_bcast_mac_addr, 0xCAFE, &intr_status, 8);
  217. if (result != 0)
  218. return result;
  219.  
  220. result = lv1_clear_spe_interrupt_status(spe_id, 0, intr_status, 0);
  221. if (result != 0)
  222. return result;
  223. }
  224.  
  225. result = lv1_get_spe_interrupt_status(spe_id, 1, &intr_status);
  226. if (result != 0)
  227. return result;
  228.  
  229. if (intr_status)
  230. {
  231. result = gelic_xmit_data(gelic_bcast_mac_addr, 0xCAFE, &intr_status, 8);
  232. if (result != 0)
  233. return result;
  234.  
  235. result = lv1_clear_spe_interrupt_status(spe_id, 1, intr_status, 0);
  236. if (result != 0)
  237. return result;
  238. }
  239.  
  240. result = lv1_get_spe_interrupt_status(spe_id, 2, &intr_status);
  241. if (result != 0)
  242. return result;
  243.  
  244. if (intr_status & 0x1)
  245. {
  246. /* mailbox interrupt */
  247.  
  248. result = gelic_xmit_data(gelic_bcast_mac_addr, 0xCAFE, &intr_status, 8);
  249. if (result != 0)
  250. return result;
  251.  
  252. if (spu_mbox_stat_intr_out_mbox_count(spu_problem) != 0)
  253. {
  254. spu_out_intr_mbox_value = spu_priv2->spu_out_intr_mbox;
  255.  
  256. result = lv1_clear_spe_interrupt_status(spe_id, 2, intr_status, 0);
  257. if (result != 0)
  258. return result;
  259.  
  260. result = gelic_xmit_data(gelic_bcast_mac_addr, 0xCAFE, &spu_out_intr_mbox_value, 4);
  261. if (result != 0)
  262. return result;
  263.  
  264. if (spu_out_intr_mbox_value == 1)
  265. {
  266. /* transfer EID0, ldr args and revoke list for programs into SPU LS */
  267.  
  268. memset(spu_args, 0, sizeof(spu_args));
  269. sb_iso_debug_buffer = (struct sb_iso_debug_buffer *) spu_args;
  270. sb_iso_debug_buffer->buf = debug_buffer;
  271. sb_iso_debug_buffer->buf_size = sizeof(debug_buffer);
  272.  
  273. memset(&ldr_args, 0, sizeof(ldr_args));
  274. ldr_args.prog_auth_id = prog_auth_id;
  275. ldr_args.lpar_auth_id = lpar_auth_id;
  276. ldr_args.spu_module = spu_module;
  277. ldr_args.spu_module_arg1 = spu_args;
  278. ldr_args.spu_module_arg1_size = sizeof(spu_args);
  279. ldr_args.spu_module_arg2 = eid4;
  280. ldr_args.spu_module_arg2_size = sizeof(eid4);
  281. ldr_args.field48 = 3;
  282.  
  283. mfc_cmd_tag = 1;
  284.  
  285. if (spu_mfc_cmd_exec(spu_problem, EID0_LS_ADDR,
  286. (u64) eid0, 0x400, mfc_cmd_tag, 0, MFC_CMD_GET) != 0)
  287. break;
  288.  
  289. if (spu_mfc_cmd_exec(spu_problem, 0x3EC00,
  290. (u64) spu_ls_0x3EC00_value, sizeof(spu_ls_0x3EC00_value),
  291. mfc_cmd_tag, 0, MFC_CMD_GET) != 0)
  292. break;
  293.  
  294. if (spu_mfc_cmd_exec(spu_problem, LDR_ARGS_LS_ADDR,
  295. (u64) &ldr_args, sizeof(ldr_args), mfc_cmd_tag, 0, MFC_CMD_GET) != 0)
  296. break;
  297.  
  298. if (spu_mfc_cmd_exec(spu_problem, RVK_PRG_LS_ADDR,
  299. (u64) rvkprg, *(u64 *) (rvkprg + 0x10) + *(u64 *) (rvkprg + 0x18),
  300. mfc_cmd_tag, 0, MFC_CMD_GET) != 0)
  301. break;
  302.  
  303. if (spu_mfc_cmd_exec(spu_problem, 0x3E000,
  304. (u64) spu_ls_0x3E000_value, sizeof(spu_ls_0x3E000_value),
  305. mfc_cmd_tag, 0, MFC_CMD_GET) != 0)
  306. break;
  307.  
  308. /* wait until MFC transfers are finished */
  309.  
  310. while (spu_mfc_cmd_tag_status(spu_problem, mfc_cmd_tag) == 0)
  311. ;
  312.  
  313. eieio();
  314.  
  315. if (spu_mbox_stat_out_mbox_count(spu_problem) == 0)
  316. break;
  317.  
  318. spu_out_mbox_value = spu_problem->spu_out_mbox;
  319.  
  320. result = gelic_xmit_data(gelic_bcast_mac_addr, 0xCAFE, &spu_out_mbox_value, 4);
  321. if (result != 0)
  322. return result;
  323.  
  324. if (spu_out_mbox_value != 1)
  325. break;
  326. }
  327. else if (spu_out_intr_mbox_value == 2)
  328. {
  329. spu_out_mbox_value = spu_problem->spu_out_mbox;
  330.  
  331. result = gelic_xmit_data(gelic_bcast_mac_addr, 0xCAFE, &spu_out_mbox_value, 4);
  332. if (result != 0)
  333. return result;
  334.  
  335. if (spu_out_mbox_value != 2)
  336. break;
  337. }
  338. else if (spu_out_intr_mbox_value == 0x80)
  339. {
  340. sb_iso_header = (struct sb_iso_header *) spu_args;
  341. memset(sb_iso_header, 0, sizeof(struct sb_iso_header));
  342. sb_iso_header->seqno = 1;
  343. sb_iso_header->mbmsg = 1;
  344. sb_iso_header->cmd = 0x2005UL;
  345. sb_iso_header->cmd_size = sizeof(struct sb_iso_get_rnd);
  346.  
  347. sb_iso_get_rnd = (struct sb_iso_get_rnd *) (sb_iso_header + 1);
  348. memset(sb_iso_get_rnd, 0, sizeof(struct sb_iso_get_rnd));
  349. sb_iso_get_rnd->field0 = SB_ISO_REPO_NODE_BUS_1_ID_V2;
  350.  
  351. spu_in_mbox_write(spu_problem, 1);
  352. }
  353. else if (spu_out_intr_mbox_value == 0x81)
  354. {
  355. break;
  356. }
  357. }
  358. }
  359.  
  360. if ((spu_problem->spu_status & 0x1) == 0)
  361. break;
  362.  
  363. ticks = 1 * TB_TICKS_PER_SEC;
  364.  
  365. sleep(ticks);
  366. }
  367.  
  368. result = gelic_xmit_data(gelic_bcast_mac_addr, 0xCAFE, debug_buffer, sizeof(debug_buffer));
  369. if (result != 0)
  370. return result;
  371.  
  372. result = gelic_xmit_data(gelic_bcast_mac_addr, 0xCAFE, &spu_problem->spu_status, 4);
  373. if (result != 0)
  374. return result;
  375.  
  376. result = gelic_xmit_data(gelic_bcast_mac_addr, 0xBEEF, spu_args, sizeof(spu_args));
  377. if (result != 0)
  378. return result;
  379.  
  380. beep(BEEP_DOUBLE);
  381.  
  382. lv1_panic(1);
  383.  
  384. return 0;
  385. }
Add Comment
Please, Sign In to add comment