Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

pastie.org/pastes/2101977

By: a guest on Apr 29th, 2012  |  syntax: C  |  size: 6.96 KB  |  views: 647  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4.  
  5. #include "types.h"
  6. #include "netrpc.h"
  7. #include "lv1.h"
  8. #include "spu.h"
  9. #include "mm.h"
  10. #include "util.h"
  11.  
  12. #define PS3HOST "192.168.1.2"
  13.  
  14. u8 *_read_file(const char *name, u32 *size)
  15. {
  16.   u8 *buf;
  17.   u32 len;
  18.   FILE *fp;
  19.  
  20.   if((fp = fopen(name, "rb")) == NULL)
  21.   {
  22.     printf("could not open %s\n", name);
  23.     return NULL;
  24.   }
  25.  
  26.   //Read into buffer.
  27.   fseek(fp, 0, SEEK_END);
  28.   len = ftell(fp);
  29.   fseek(fp, 0, SEEK_SET);
  30.   buf = (u8 *)malloc(sizeof(u8) * len);
  31.   fread(buf, sizeof(u8), len, fp);
  32.  
  33.   fclose(fp);
  34.  
  35.   //Set buffer size.
  36.   if(size != NULL)
  37.     *size = len;
  38.  
  39.   return buf;
  40. }
  41.  
  42. u64 _vas_get_id(netrpc_ctxt_t *ctxt)
  43. {
  44.   u64 id;
  45.   netrpc_hvcall(ctxt, _N_lv1_get_logical_ppe_id, NULL, 0, &id, 1);
  46.   netrpc_hvcall(ctxt, _N_lv1_get_virtual_address_space_id_of_ppe, &id, 1, &id, 1);
  47.   return id;
  48. }
  49.  
  50. s64 _get_spe_intr_status(netrpc_ctxt_t *ctxt, u64 spe_id, u64 cls, u64 *stat)
  51. {
  52.   u64 args[] = {spe_id, cls};
  53.   return netrpc_hvcall(ctxt, _N_lv1_get_spe_interrupt_status, args, 2, stat, 1);
  54. }
  55.  
  56. s64 _clr_spe_intr_status(netrpc_ctxt_t *ctxt, u64 spe_id, u64 cls, u64 stat)
  57. {
  58.   u64 args[] = {spe_id, cls, stat, 0};
  59.   return netrpc_hvcall(ctxt, _N_lv1_clear_spe_interrupt_status, args, 4, NULL, 0);
  60. }
  61.  
  62. #define LDR_BASE 0x100000
  63. #define LDR_SIZE 0x2300000
  64. #define METLDR_SIZE 0x100000
  65. #define ISOLDR_SIZE 0x100000
  66.  
  67. #define SPU_SHADOW_SIZE 0x1000
  68. #define SPU_PROBLEM_SIZE 0x20000
  69. #define SPU_PRIV2_SIZE 0x20000
  70. #define SPU_LS_SIZE 0x40000
  71.  
  72. //static volatile u64 ldr_lpar_addr = 0x700020000000ULL + 0xE900000ULL - LDR_SIZE;
  73.  
  74. static u64 esid = 0x8000000018000000;
  75. static u64 vsid = 0x0000000000001400;
  76.  
  77. int main(int argc, char **argv)
  78. {
  79.   netrpc_ctxt_t ctxt;
  80.   s64 res;
  81.  
  82.   //Ohai.
  83.   printf("connecting...");
  84.   if(netrpc_connect(&ctxt, inet_addr(PS3HOST), NETRPC_PORT) < 0)
  85.   {
  86.     printf("error\n");
  87.     return 1;
  88.   }
  89.   printf("ok\n");
  90.  
  91.   printf("ping...");
  92.   if(netrpc_ping(&ctxt) < 0)
  93.   {
  94.     printf("error\n");
  95.     return 1;
  96.   }
  97.   printf("ok\n");
  98.  
  99.   //Get vas id.
  100.   u64 vas_id = _vas_get_id(&ctxt);
  101.  
  102.   //File adresses.
  103.   u64 metldr_addr, isoldr_addr;
  104.   metldr_addr = LDR_BASE;
  105.   isoldr_addr = metldr_addr + METLDR_SIZE;
  106.  
  107.   //Map region.
  108.   //res = mm_map_lpar_memory_region(&ctxt, vas_id, MM_EA2VA(metldr_addr), LDR_BASE /*ldr_lpar_addr*/, LDR_SIZE, 0xC, 0, 0);
  109.   //printf("map_lpar_memory_region : %lld\n", res);
  110.  
  111.   netrpc_addmmio(&ctxt, LDR_BASE, LDR_SIZE);
  112.  
  113.   printf("copy files out...");
  114.  
  115.   //Read files.
  116.   u32 metldr_size;
  117.   u8 *metldr = _read_file("./data/metldr", &metldr_size);
  118.   u32 isoldr_size;
  119.   u8 *isoldr = _read_file("./data/isoldr", &isoldr_size);
  120.   //u8 *isoldr = _read_file("./data/isoldr_patched", &isoldr_size);
  121.  
  122.   //Copy files out.
  123.   netrpc_memcpy_out(&ctxt, metldr_addr, metldr, metldr_size);
  124.   netrpc_memcpy_out(&ctxt, isoldr_addr, isoldr, isoldr_size);
  125.  
  126.   //Cleanup.
  127.   free(metldr);
  128.   free(isoldr);
  129.  
  130.   printf("done\n");
  131.  
  132.   printf("construct spe...");
  133.  
  134.   //Construct SPE.
  135.   u64 cspe_args[] = {0xc, 0xc, 0xc, 0xc, 0xc, vas_id, 0};
  136.   u64 cspe_res[] = {0, 0, 0, 0, 0, 0};
  137.   netrpc_hvcall(&ctxt, _N_lv1_construct_logical_spe, cspe_args, 7, cspe_res, 6);
  138.  
  139.   //SPE info.
  140.   u64 priv2_addr, problem_addr, ls_addr, shadow_addr, spe_id;
  141.   priv2_addr = cspe_res[0];
  142.   problem_addr = cspe_res[1];
  143.   ls_addr = cspe_res[2];
  144.   shadow_addr = cspe_res[4];
  145.   spe_id = cspe_res[5];
  146.  
  147.   netrpc_addmmio(&ctxt, priv2_addr, SPU_PRIV2_SIZE);
  148.   netrpc_addmmio(&ctxt, problem_addr, SPU_PROBLEM_SIZE);
  149.   netrpc_addmmio(&ctxt, shadow_addr, SPU_SHADOW_SIZE);
  150.   netrpc_addmmio(&ctxt, ls_addr, SPU_LS_SIZE);
  151.  
  152.   printf("done\n  priv2 @ 0x%016llx\n  problem @ 0x%016llx\n  ls @ 0x%016llx\n  shadow @ 0x%016llx\n  id : 0x%016llx\n",
  153.     priv2_addr, problem_addr, ls_addr, shadow_addr, spe_id);
  154.  
  155.   printf("setup spe...");
  156.  
  157.   //Setup SPE.
  158.   u64 setup_spe_args[] = {spe_id, 0, 0};
  159.  
  160.   setup_spe_args[1] = 6;
  161.   netrpc_hvcall(&ctxt, _N_lv1_enable_logical_spe, setup_spe_args, 2, NULL, 0);
  162.  
  163.   setup_spe_args[1] = 0;
  164.   setup_spe_args[2] = 0x7;
  165.   netrpc_hvcall(&ctxt, _N_lv1_set_spe_interrupt_mask, setup_spe_args, 3, NULL, 0);
  166.  
  167.   setup_spe_args[1] = 1;
  168.   setup_spe_args[2] = 0xf;
  169.   netrpc_hvcall(&ctxt, _N_lv1_set_spe_interrupt_mask, setup_spe_args, 3, NULL, 0);
  170.  
  171.   setup_spe_args[1] = 2;
  172.   setup_spe_args[2] = 0xf;
  173.   netrpc_hvcall(&ctxt, _N_lv1_set_spe_interrupt_mask, setup_spe_args, 3, NULL, 0);
  174.  
  175.   printf("done\n");
  176.  
  177.   u64 set_reg_args[] = {spe_id, _OFFSET_MFC_SR1, 0x10};
  178.   res = netrpc_hvcall(&ctxt, _N_lv1_set_spe_privilege_state_area_1_register, set_reg_args, 3, NULL, 0);
  179.   printf("set_spe_privilege_state_area_1_register : %lld\n", res);
  180.  
  181.   printf("start spe in isolation mode...");
  182.  
  183.   spu_slb_invalidate_all(&ctxt, priv2_addr);
  184.   spu_slb_set_entry(&ctxt, priv2_addr, 0, esid, vsid);
  185.   write_u64(&ctxt, SPU_RADDR(priv2_addr, _OFFSET_SPU_Cfg), 0);
  186.   netrpc_eieio(&ctxt);
  187.   spu_in_mbox_write_64(&ctxt, problem_addr, isoldr_addr);
  188.   spu_sig_notify_1_2_write_64(&ctxt, problem_addr, metldr_addr);
  189.   spu_isolation_req_enable(&ctxt, priv2_addr);
  190.   spu_isolation_req(&ctxt, problem_addr);
  191.  
  192.   printf("done\n");
  193.  
  194.   FILE *fp = fopen("ls.bin", "wb");
  195.  
  196.   u32 spu_status, size = 0;
  197.   u64 intr_status;
  198.   while(1)
  199.   {
  200.     res = _get_spe_intr_status(&ctxt, spe_id, 0, &intr_status);
  201.     if(intr_status)
  202.     {
  203.       printf("intr_status (0) : %016llx\n", intr_status);
  204.       printf("clear_intr_status : %lld\n", _clr_spe_intr_status(&ctxt, spe_id, 0, intr_status));
  205.     }
  206.    
  207.     res = _get_spe_intr_status(&ctxt, spe_id, 1, &intr_status);
  208.     if(intr_status)
  209.     {
  210.       printf("intr_status (1) : %016llx\n", intr_status);
  211.       printf("clear_intr_status : %lld\n", _clr_spe_intr_status(&ctxt, spe_id, 1, intr_status));
  212.     }
  213.    
  214.     res = _get_spe_intr_status(&ctxt, spe_id, 2, &intr_status);
  215.     if(intr_status & 0x1)
  216.     {
  217.       printf("mailbox interrupt\n");
  218.       printf("intr_status (2) : %016llx\n", intr_status);
  219.       printf("clear_intr_status : %lld\n", _clr_spe_intr_status(&ctxt, spe_id, 2, intr_status));
  220.     }
  221.    
  222.     /*
  223.     while(size <= 0x40000)
  224.     {
  225.       netrpc_eieio(&ctxt);
  226.      
  227.       //Wait for mbox value to be written.
  228.       while(spu_mbox_stat_out_mbox_count(&ctxt, problem_addr) == 0);
  229.      
  230.       //Read mbox value.
  231.       u32 mbox_value;
  232.       read_u32(&ctxt, SPU_RADDR(problem_addr, _OFFSET_SPU_Out_Mbox), &mbox_value);
  233.      
  234.       netrpc_eieio(&ctxt);
  235.      
  236.       //Write to file.
  237.       fwrite(&mbox_value, sizeof(u32), 1, fp);
  238.       size += 4;
  239.      
  240.       printf("\rdumped 0x%08x of 0x40000", size);
  241.      
  242.       usleep(10);
  243.     }
  244.     */
  245.    
  246.     read_u32(&ctxt, SPU_RADDR(problem_addr, _OFFSET_SPU_Status), &spu_status);
  247.     if((spu_status & 0x1) == 0)
  248.       break;
  249.    
  250.     usleep(1000);
  251.   }
  252.  
  253.   fclose(fp);
  254.  
  255.   printf("\ndone\n");
  256.   printf("spu_status: 0x%08x\n", spu_status);
  257.    
  258.   //Bye.
  259.   netrpc_close(&ctxt);
  260.  
  261.   return 0;
  262. }