Venezia

From Vita Development Wiki
Revision as of 06:10, 2 February 2017 by Yifan Lu (talk | contribs)
Jump to navigation Jump to search

There are 8 MeP cores that serve as the media co-processor (called Venezia or VIP). The CPU ID register for them are

0x00300500 0x00310500 0x00320500 0x00330500 0x00340500 0x00350500 0x00360500 0x00370500

This means they are MeP c5 cores and are uniquely numbered 48-55.

Running Code

It is easy to run your own MeP code. It appears that the code is DMA copied to MeP's private memory before resetting and executing it.

MeP payload:

.text

_start:
jmp 0x800018
jmp 0x800018
jmp 0x800018
jmp 0x800018
jmp 0x800018
jmp 0x800018

_init:
movh $0,0xf184
add3 $0,$0,0
mov $1,0x8
sw $1,0($0)

_writecpuid:
ldc $2,17
srl $2,14
ldc $1,17
add3 $2,$2,$0
add3 $2,$2,4
sw $1,0($2)

.wait:
bra .wait

On ARM:

// the following code has hard coded offsets in 1.69
int restart_vnz()
{
  volatile unsigned int *regs, *spram; // r4@1
  int v1; // r6@1
  unsigned int img_paddr; // r3@2
  int dram_base; // r0@2
  int size;
  unsigned int v4; // r0@3
  unsigned int v5; // r3@3
  int v7; // r1@6
  int v8; // r2@6

  spram = *(volatile unsigned int **)0x0190F67C;
  regs = *(volatile unsigned int **)0x0190F670;
  printf("ScePervasive2Reg: 0x%08X, spram: 0x%08X\n", regs, spram);
  ScePervasiveForDriver_0xFB01A2DD();
  img_paddr = 0x40800000; // paddr of region
  dram_base = 0x40300000;
  size = 0x400000;
  regs[192] = 0x1D001000;
  if ( dram_base < img_paddr )
  {
    v7 = img_paddr + size;
    v8 = dram_base + 0x2500000;
    if ( img_paddr + size < v8 )
    {
      regs[193] = dram_base;
      regs[194] = img_paddr;
      regs[195] = v7;
      regs[196] = v8;
    }
  }
  v4 = img_paddr >> 23 << 23;
  regs[224] = v4;
  regs[228] = 0x1E000000;
  regs[229] = 0x20000000;
  regs[230] = 0x22000000;
  regs[231] = img_paddr & 0xFE000000;
  regs[232] = 0x18000000;
  regs[233] = 0x20000000;
  regs[234] = img_paddr & 0xF8000000;
  regs[235] = (img_paddr + 0x8000000) & 0xF8000000;
  regs[236] = 0x1E000000;
  regs[237] = 0x20000000;
  regs[238] = 0x22000000;
  regs[239] = img_paddr & 0xFE000000;
  regs[256] = v4;
  regs[898] = 0xFFFF0000;
  spram[0] = 1;
  SceCpuForDriver_0xE813EBB2_clean_l2();
  regs[898];
  __asm__("dsb sy" ::: "memory");
  ScePervasiveForDriver_0xA7E64C6F_reset_vnz();
  v1 = 0;
  while (spram[0] != 8)
  {
    printf("waiting...");
    sceKernelDelayThread(100);
    if (v1++ > 20)
      break;
  }
  return 0;
}

int vnz_hack()
{
  volatile unsigned int *spram_vaddr;
  unsigned int *img_vaddr;
  int i;
  int ret;

  spram_vaddr = *(volatile unsigned int **)0x0190F67C;
  img_vaddr = *(unsigned int **)0x0190F664;
  printf("Vaddr: %08X\n", img_vaddr);
  ret = make_smc_call(1, 1, 0, 0, 0x110);
  printf("Reset VNZ: 0x%08X\n", ret);

  memset(spram_vaddr, 0, 256);
  memcpy(img_vaddr, YOUR_MEP_CODE, YOUR_MEP_CODE_LEN);
  ret = restart_vnz();
  printf("Restart VNZ: 0x%08X\n", ret);

  return 0;
}