Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include "types.h"
- #include "netrpc.h"
- #include "lv1.h"
- #include "spu.h"
- #include "mm.h"
- #include "util.h"
- #define PS3HOST "192.168.1.2"
- u8 *_read_file(const char *name, u32 *size)
- {
- u8 *buf;
- u32 len;
- FILE *fp;
- if((fp = fopen(name, "rb")) == NULL)
- {
- printf("could not open %s\n", name);
- return NULL;
- }
- //Read into buffer.
- fseek(fp, 0, SEEK_END);
- len = ftell(fp);
- fseek(fp, 0, SEEK_SET);
- buf = (u8 *)malloc(sizeof(u8) * len);
- fread(buf, sizeof(u8), len, fp);
- fclose(fp);
- //Set buffer size.
- if(size != NULL)
- *size = len;
- return buf;
- }
- u64 _vas_get_id(netrpc_ctxt_t *ctxt)
- {
- u64 id;
- netrpc_hvcall(ctxt, _N_lv1_get_logical_ppe_id, NULL, 0, &id, 1);
- netrpc_hvcall(ctxt, _N_lv1_get_virtual_address_space_id_of_ppe, &id, 1, &id, 1);
- return id;
- }
- s64 _get_spe_intr_status(netrpc_ctxt_t *ctxt, u64 spe_id, u64 cls, u64 *stat)
- {
- u64 args[] = {spe_id, cls};
- return netrpc_hvcall(ctxt, _N_lv1_get_spe_interrupt_status, args, 2, stat, 1);
- }
- s64 _clr_spe_intr_status(netrpc_ctxt_t *ctxt, u64 spe_id, u64 cls, u64 stat)
- {
- u64 args[] = {spe_id, cls, stat, 0};
- return netrpc_hvcall(ctxt, _N_lv1_clear_spe_interrupt_status, args, 4, NULL, 0);
- }
- #define LDR_BASE 0x100000
- #define LDR_SIZE 0x2300000
- #define METLDR_SIZE 0x100000
- #define ISOLDR_SIZE 0x100000
- #define SPU_SHADOW_SIZE 0x1000
- #define SPU_PROBLEM_SIZE 0x20000
- #define SPU_PRIV2_SIZE 0x20000
- #define SPU_LS_SIZE 0x40000
- //static volatile u64 ldr_lpar_addr = 0x700020000000ULL + 0xE900000ULL - LDR_SIZE;
- static u64 esid = 0x8000000018000000;
- static u64 vsid = 0x0000000000001400;
- int main(int argc, char **argv)
- {
- netrpc_ctxt_t ctxt;
- s64 res;
- //Ohai.
- printf("connecting...");
- if(netrpc_connect(&ctxt, inet_addr(PS3HOST), NETRPC_PORT) < 0)
- {
- printf("error\n");
- return 1;
- }
- printf("ok\n");
- printf("ping...");
- if(netrpc_ping(&ctxt) < 0)
- {
- printf("error\n");
- return 1;
- }
- printf("ok\n");
- //Get vas id.
- u64 vas_id = _vas_get_id(&ctxt);
- //File adresses.
- u64 metldr_addr, isoldr_addr;
- metldr_addr = LDR_BASE;
- isoldr_addr = metldr_addr + METLDR_SIZE;
- //Map region.
- //res = mm_map_lpar_memory_region(&ctxt, vas_id, MM_EA2VA(metldr_addr), LDR_BASE /*ldr_lpar_addr*/, LDR_SIZE, 0xC, 0, 0);
- //printf("map_lpar_memory_region : %lld\n", res);
- netrpc_addmmio(&ctxt, LDR_BASE, LDR_SIZE);
- printf("copy files out...");
- //Read files.
- u32 metldr_size;
- u8 *metldr = _read_file("./data/metldr", &metldr_size);
- u32 isoldr_size;
- u8 *isoldr = _read_file("./data/isoldr", &isoldr_size);
- //u8 *isoldr = _read_file("./data/isoldr_patched", &isoldr_size);
- //Copy files out.
- netrpc_memcpy_out(&ctxt, metldr_addr, metldr, metldr_size);
- netrpc_memcpy_out(&ctxt, isoldr_addr, isoldr, isoldr_size);
- //Cleanup.
- free(metldr);
- free(isoldr);
- printf("done\n");
- printf("construct spe...");
- //Construct SPE.
- u64 cspe_args[] = {0xc, 0xc, 0xc, 0xc, 0xc, vas_id, 0};
- u64 cspe_res[] = {0, 0, 0, 0, 0, 0};
- netrpc_hvcall(&ctxt, _N_lv1_construct_logical_spe, cspe_args, 7, cspe_res, 6);
- //SPE info.
- u64 priv2_addr, problem_addr, ls_addr, shadow_addr, spe_id;
- priv2_addr = cspe_res[0];
- problem_addr = cspe_res[1];
- ls_addr = cspe_res[2];
- shadow_addr = cspe_res[4];
- spe_id = cspe_res[5];
- netrpc_addmmio(&ctxt, priv2_addr, SPU_PRIV2_SIZE);
- netrpc_addmmio(&ctxt, problem_addr, SPU_PROBLEM_SIZE);
- netrpc_addmmio(&ctxt, shadow_addr, SPU_SHADOW_SIZE);
- netrpc_addmmio(&ctxt, ls_addr, SPU_LS_SIZE);
- printf("done\n priv2 @ 0x%016llx\n problem @ 0x%016llx\n ls @ 0x%016llx\n shadow @ 0x%016llx\n id : 0x%016llx\n",
- priv2_addr, problem_addr, ls_addr, shadow_addr, spe_id);
- printf("setup spe...");
- //Setup SPE.
- u64 setup_spe_args[] = {spe_id, 0, 0};
- setup_spe_args[1] = 6;
- netrpc_hvcall(&ctxt, _N_lv1_enable_logical_spe, setup_spe_args, 2, NULL, 0);
- setup_spe_args[1] = 0;
- setup_spe_args[2] = 0x7;
- netrpc_hvcall(&ctxt, _N_lv1_set_spe_interrupt_mask, setup_spe_args, 3, NULL, 0);
- setup_spe_args[1] = 1;
- setup_spe_args[2] = 0xf;
- netrpc_hvcall(&ctxt, _N_lv1_set_spe_interrupt_mask, setup_spe_args, 3, NULL, 0);
- setup_spe_args[1] = 2;
- setup_spe_args[2] = 0xf;
- netrpc_hvcall(&ctxt, _N_lv1_set_spe_interrupt_mask, setup_spe_args, 3, NULL, 0);
- printf("done\n");
- u64 set_reg_args[] = {spe_id, _OFFSET_MFC_SR1, 0x10};
- res = netrpc_hvcall(&ctxt, _N_lv1_set_spe_privilege_state_area_1_register, set_reg_args, 3, NULL, 0);
- printf("set_spe_privilege_state_area_1_register : %lld\n", res);
- printf("start spe in isolation mode...");
- spu_slb_invalidate_all(&ctxt, priv2_addr);
- spu_slb_set_entry(&ctxt, priv2_addr, 0, esid, vsid);
- write_u64(&ctxt, SPU_RADDR(priv2_addr, _OFFSET_SPU_Cfg), 0);
- netrpc_eieio(&ctxt);
- spu_in_mbox_write_64(&ctxt, problem_addr, isoldr_addr);
- spu_sig_notify_1_2_write_64(&ctxt, problem_addr, metldr_addr);
- spu_isolation_req_enable(&ctxt, priv2_addr);
- spu_isolation_req(&ctxt, problem_addr);
- printf("done\n");
- FILE *fp = fopen("ls.bin", "wb");
- u32 spu_status, size = 0;
- u64 intr_status;
- while(1)
- {
- res = _get_spe_intr_status(&ctxt, spe_id, 0, &intr_status);
- if(intr_status)
- {
- printf("intr_status (0) : %016llx\n", intr_status);
- printf("clear_intr_status : %lld\n", _clr_spe_intr_status(&ctxt, spe_id, 0, intr_status));
- }
- res = _get_spe_intr_status(&ctxt, spe_id, 1, &intr_status);
- if(intr_status)
- {
- printf("intr_status (1) : %016llx\n", intr_status);
- printf("clear_intr_status : %lld\n", _clr_spe_intr_status(&ctxt, spe_id, 1, intr_status));
- }
- res = _get_spe_intr_status(&ctxt, spe_id, 2, &intr_status);
- if(intr_status & 0x1)
- {
- printf("mailbox interrupt\n");
- printf("intr_status (2) : %016llx\n", intr_status);
- printf("clear_intr_status : %lld\n", _clr_spe_intr_status(&ctxt, spe_id, 2, intr_status));
- }
- /*
- while(size <= 0x40000)
- {
- netrpc_eieio(&ctxt);
- //Wait for mbox value to be written.
- while(spu_mbox_stat_out_mbox_count(&ctxt, problem_addr) == 0);
- //Read mbox value.
- u32 mbox_value;
- read_u32(&ctxt, SPU_RADDR(problem_addr, _OFFSET_SPU_Out_Mbox), &mbox_value);
- netrpc_eieio(&ctxt);
- //Write to file.
- fwrite(&mbox_value, sizeof(u32), 1, fp);
- size += 4;
- printf("\rdumped 0x%08x of 0x40000", size);
- usleep(10);
- }
- */
- read_u32(&ctxt, SPU_RADDR(problem_addr, _OFFSET_SPU_Status), &spu_status);
- if((spu_status & 0x1) == 0)
- break;
- usleep(1000);
- }
- fclose(fp);
- printf("\ndone\n");
- printf("spu_status: 0x%08x\n", spu_status);
- //Bye.
- netrpc_close(&ctxt);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement