int loadmodulemem(char *buf,int len,int lenarg,char *arg) { unsigned iopmem=0; int ret=0; SifInitIopHeap(); iopmem=(unsigned int)SifAllocIopHeap(len+15); printf("iopmem=%d\n", iopmem); if(iopmem==0) { return -1; } if(iop_heap_dma_upload(buf, iopmem,len+15)<0) { SifFreeIopHeap((void*)iopmem); return -1; } if(SifLoadModuleBuffer((void *)iopmem, lenarg, arg) < 0) { SifFreeIopHeap((void*)iopmem); return -1; } return ret; }
int sndLoadSample(void *buf, u32 spuaddr, int size) { void *iopbuf; int id, iopfree; SifDmaTransfer_t sifdma; iopfree = sndQueryMaxFreeMemSize()/2; if (size>iopfree) { return(-1); } iopbuf = SifAllocIopHeap(size); if (iopbuf==0) return(-1); FlushCache(0); sifdma.src = buf; sifdma.dest = iopbuf; sifdma.size = size; sifdma.attr = 0; id = SifSetDma(&sifdma, 1); while(SifDmaStat(id) >= 0);; FlushCache(0); SdVoiceTrans(0, SD_TRANS_WRITE, iopbuf, (void*)spuaddr, size); SdVoiceTransStatus(0, 1); SifFreeIopHeap(iopbuf); return(size); }
int audsrv_load_adpcm(audsrv_adpcm_t *adpcm, void *buffer, int size) { void* iop_addr; SifDmaTransfer_t sifdma; int id, ret; iop_addr = SifAllocIopHeap(size); if (iop_addr == 0) { return -AUDSRV_ERR_OUT_OF_MEMORY; } sifdma.src = buffer; sifdma.dest = iop_addr; sifdma.size = size; sifdma.attr = 0; /* send by dma */ while((id = SifSetDma(&sifdma, 1)) == 0); while(SifDmaStat(id) >= 0); WaitSema(completion_sema); sbuff[0] = (int)iop_addr; sbuff[1] = size; sbuff[2] = (int)adpcm; /* use as id */ SifCallRpc(&cd0, AUDSRV_LOAD_ADPCM, 0, sbuff, 12, sbuff, 16, NULL, NULL); if(sbuff[0] != 0) { adpcm->buffer = 0; ret = sbuff[0]; } else { adpcm->buffer = buffer; adpcm->size = size; adpcm->pitch = sbuff[1]; adpcm->loop = sbuff[2]; adpcm->channels = sbuff[3]; ret = AUDSRV_ERR_NOERROR; } SignalSema(completion_sema); SifFreeIopHeap(iop_addr); return ret; }
int sbv_patch_enable_lmb() { u8 buf[256]; slib_exp_lib_t *modload_lib = (slib_exp_lib_t *)buf; smod_mod_info_t *loadfile_info = (smod_mod_info_t *)buf; void *pStartModule, *pLoadModuleBuffer, *lf_text_start, *patch_addr; u32 lf_rpc_dispatch, lf_jump_table, result; int nexps, id, i; memset(&_slib_cur_exp_lib_list, 0, sizeof(slib_exp_lib_list_t)); /* Locate the modload export library - it must have at least 16 exports. */ if ((nexps = slib_get_exp_lib("modload", modload_lib)) < 16) return -1; pStartModule = modload_lib->exports[8]; pLoadModuleBuffer = modload_lib->exports[10]; /* Now we need to find the loadfile module. */ memset(buf, 0, sizeof(smod_mod_info_t)); if (!(id = smod_get_mod_by_name("LoadModuleByEE", loadfile_info))) return -1; /* Locate the loadfile RPC dispatch code, where the first 4 instructions look like: 27bdffe8 addiu $sp, -24 2c820006 sltiu $v0, $a0, 6 14400003 bnez $v0, +12 afbf0010 sw $ra, 0x10($sp) */ lf_text_start = (void *)(loadfile_info->text_start + 0x400); smem_read(lf_text_start, buf, sizeof buf); for (i = 0; i < sizeof buf; i += 4) { if ((*(u32 *)(buf + i) == 0x27bdffe8) && (*(u32 *)(buf + i + 4) == 0x2c820006) && (*(u32 *)(buf + i + 8) == 0x14400003) && (*(u32 *)(buf + i + 12) == 0xafbf0010)) break; } /* This is a special case: if the IOP was reset with an image that contains a LOADFILE that supports LMB, we won't detect the dispatch routine. If we even got this far in the code then we can return success. */ if (i >= sizeof buf) return 0; /* We need to extract the address of the jump table, it's only 40 bytes in. */ lf_rpc_dispatch = (u32)lf_text_start + i; smem_read((void *)lf_rpc_dispatch, buf, 40); lf_jump_table = (*(u16 *)(buf + 0x1c) << 16) + *(s16 *)(buf + 0x24); /* Now we can patch our subversive LoadModuleBuffer RPC call. */ SifInitIopHeap(); if (!(patch_addr = SifAllocIopHeap(sizeof lmb_patch))) return -1; /* result is where the RPC return structure is stored. */ result = (u32)patch_addr + 96; lmb_patch[5] = JAL((u32)pLoadModuleBuffer); lmb_patch[7] = HI16(result); lmb_patch[9] = LO16(result); lmb_patch[15] = JAL((u32)pStartModule); SyncDCache(lmb_patch, (void *)(lmb_patch + 24)); smem_write(patch_addr, lmb_patch, sizeof lmb_patch); /* Finally. The last thing to do is to patch the loadfile RPC dispatch routine so that it will jump to entry #6 in it's jump table, and to patch the jump table itself. */ ee_kmode_enter(); *(u32 *)(SUB_VIRT_MEM + lf_rpc_dispatch + 4) = 0x2c820007; *(u32 *)(SUB_VIRT_MEM + lf_jump_table + 0x18) = (u32)patch_addr; ee_kmode_exit(); return 0; }