s32 sceKernelGetEventFlagInfo(s32 evfId, vm::ptr<SceKernelEventFlagInfo> pInfo) { sceLibKernel.Error("sceKernelGetEventFlagInfo(evfId=0x%x, pInfo=*0x%x)", evfId, pInfo); const auto evf = idm::get<psv_event_flag_t>(evfId); if (!evf) { return SCE_KERNEL_ERROR_INVALID_UID; } std::lock_guard<std::mutex> lock(evf->mutex); pInfo->size = sizeof32(SceKernelEventFlagInfo); pInfo->evfId = evfId; strcpy_trunc(pInfo->name, evf->name); pInfo->attr = evf->attr; pInfo->initPattern = evf->init; pInfo->currentPattern = evf->pattern; pInfo->numWaitThreads = static_cast<u32>(evf->sq.size()); return SCE_OK; }
void ElementaryStream::push_au(u32 size, u64 dts, u64 pts, u64 userdata, bool rap, u32 specific) { u32 addr; { std::lock_guard<std::mutex> lock(m_mutex); assert(!is_full(size)); if (put + size + 128 > memAddr + memSize) { put = memAddr; } memcpy(vm::get_ptr<void>(put + 128), raw_data.data(), size); raw_data.erase(raw_data.begin(), raw_data.begin() + size); auto info = vm::ptr<CellDmuxAuInfoEx>::make(put); info->auAddr = put + 128; info->auSize = size; info->dts.lower = (u32)(dts); info->dts.upper = (u32)(dts >> 32); info->pts.lower = (u32)(pts); info->pts.upper = (u32)(pts >> 32); info->isRap = rap; info->reserved = 0; info->userData = userdata; auto spec = vm::ptr<u32>::make(put + sizeof32(CellDmuxAuInfoEx)); *spec = specific; auto inf = vm::ptr<CellDmuxAuInfo>::make(put + 64); inf->auAddr = put + 128; inf->auSize = size; inf->dtsLower = (u32)(dts); inf->dtsUpper = (u32)(dts >> 32); inf->ptsLower = (u32)(pts); inf->ptsUpper = (u32)(pts >> 32); inf->auMaxSize = 0; // ????? inf->userData = userdata; addr = put; put = align(put + 128 + size, 128); put_count++; } if (!entries.push(addr, &dmux->is_closed)) { assert(!"es::push_au() error: entries.Push() failed"); } }
cpu_thread& ppu_thread::args(std::initializer_list<std::string> values) { if (!values.size()) return *this; assert(argc == 0); envp.set(vm::alloc(align(sizeof32(*envp), stack_align), vm::main)); *envp = 0; argv.set(vm::alloc(sizeof32(*argv) * (u32)values.size(), vm::main)); for (auto &arg : values) { const u32 arg_size = align(u32(arg.size() + 1), stack_align); const u32 arg_addr = vm::alloc(arg_size, vm::main); std::memcpy(vm::get_ptr(arg_addr), arg.c_str(), arg.size() + 1); argv[argc++] = arg_addr; } return *this; }
std::string FragmentProgramDecompiler::AddConst() { std::string name = std::string("fc") + std::to_string(m_size + 4 * 4); if (m_parr.HasParam(PF_PARAM_UNIFORM, getFloatTypeName(4), name)) { return name; } auto data = vm::ps3::ptr<u32>::make(m_addr + m_size + 4 * sizeof32(u32)); m_offset = 2 * 4 * sizeof(u32); u32 x = GetData(data[0]); u32 y = GetData(data[1]); u32 z = GetData(data[2]); u32 w = GetData(data[3]); return m_parr.AddParam(PF_PARAM_UNIFORM, getFloatTypeName(4), name, std::string(getFloatTypeName(4) + "(") + std::to_string((float&)x) + ", " + std::to_string((float&)y) + ", " + std::to_string((float&)z) + ", " + std::to_string((float&)w) + ")"); }
int nmppsFFT1024FwdInitAllocCustom( NmppsFFTSpec** specFFT, Malloc32Func* allocate, Free32Func* free, int settings) { NmppsFFTSpec* spec=(NmppsFFTSpec*)allocate(sizeof32(NmppsFFTSpec)); if (spec==0) { (*specFFT)=0; return -1; } nmppsFFTResetSpec(spec); spec->buffer[0]=(nm32sc*)allocate(1024*2*3); spec->buffer[1]=(nm32sc*)allocate(1024*2*3); //spec->buffer[2]=0; //spec->buffer[3]=0; spec->shift [0]=-1; spec->free=free; if (spec->buffer[0]==0) {free(spec); *specFFT=0 ;return -1; } if (spec->buffer[1]==0) {free(spec->buffer[0]);free(spec); *specFFT=0 ;return -1; } *specFFT = spec; FFT_Fwd1024Set7bit(); return 0; }
s32 cellVdecGetPicItem(u32 handle, vm::pptr<CellVdecPicItem> picItem) { cellVdec.Log("cellVdecGetPicItem(handle=0x%x, picItem=**0x%x)", handle, picItem); const auto vdec = Emu.GetIdManager().get<VideoDecoder>(handle); if (!vdec) { return CELL_VDEC_ERROR_ARG; } VdecFrame vf; if (!vdec->frames.try_peek(vf)) { //std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack return CELL_VDEC_ERROR_EMPTY; } AVFrame& frame = *vf.data; const auto info = vm::ptr<CellVdecPicItem>::make(vdec->memAddr + vdec->memBias); vdec->memBias += 512; if (vdec->memBias + 512 > vdec->memSize) { vdec->memBias = 0; } info->codecType = vdec->type; info->startAddr = 0x00000123; // invalid value (no address for picture) info->size = align(av_image_get_buffer_size(vdec->ctx->pix_fmt, vdec->ctx->width, vdec->ctx->height, 1), 128); info->auNum = 1; info->auPts[0].lower = (u32)(vf.pts); info->auPts[0].upper = (u32)(vf.pts >> 32); info->auPts[1].lower = (u32)CODEC_TS_INVALID; info->auPts[1].upper = (u32)CODEC_TS_INVALID; info->auDts[0].lower = (u32)(vf.dts); info->auDts[0].upper = (u32)(vf.dts >> 32); info->auDts[1].lower = (u32)CODEC_TS_INVALID; info->auDts[1].upper = (u32)CODEC_TS_INVALID; info->auUserData[0] = vf.userdata; info->auUserData[1] = 0; info->status = CELL_OK; info->attr = CELL_VDEC_PICITEM_ATTR_NORMAL; info->picInfo_addr = info.addr() + sizeof32(CellVdecPicItem); if (vdec->type == CELL_VDEC_CODEC_TYPE_AVC) { auto avc = vm::ptr<CellVdecAvcInfo>::make(info.addr() + sizeof32(CellVdecPicItem)); avc->horizontalSize = frame.width; avc->verticalSize = frame.height; switch (frame.pict_type) { case AV_PICTURE_TYPE_I: avc->pictureType[0] = CELL_VDEC_AVC_PCT_I; break; case AV_PICTURE_TYPE_P: avc->pictureType[0] = CELL_VDEC_AVC_PCT_P; break; case AV_PICTURE_TYPE_B: avc->pictureType[0] = CELL_VDEC_AVC_PCT_B; break; default: cellVdec.Error("cellVdecGetPicItem(AVC): unknown pict_type value (0x%x)", frame.pict_type); } avc->pictureType[1] = CELL_VDEC_AVC_PCT_UNKNOWN; // ??? avc->idrPictureFlag = false; // ??? avc->aspect_ratio_idc = CELL_VDEC_AVC_ARI_SAR_UNSPECIFIED; // ??? avc->sar_height = 0; avc->sar_width = 0; avc->pic_struct = CELL_VDEC_AVC_PSTR_FRAME; // ??? avc->picOrderCount[0] = 0; // ??? avc->picOrderCount[1] = 0; avc->vui_parameters_present_flag = true; // ??? avc->frame_mbs_only_flag = true; // ??? progressive avc->video_signal_type_present_flag = true; // ??? avc->video_format = CELL_VDEC_AVC_VF_COMPONENT; // ??? avc->video_full_range_flag = false; // ??? avc->colour_description_present_flag = true; avc->colour_primaries = CELL_VDEC_AVC_CP_ITU_R_BT_709_5; // ??? avc->transfer_characteristics = CELL_VDEC_AVC_TC_ITU_R_BT_709_5; avc->matrix_coefficients = CELL_VDEC_AVC_MXC_ITU_R_BT_709_5; // important avc->timing_info_present_flag = true; switch (vf.frc) { case CELL_VDEC_FRC_24000DIV1001: avc->frameRateCode = CELL_VDEC_AVC_FRC_24000DIV1001; break; case CELL_VDEC_FRC_24: avc->frameRateCode = CELL_VDEC_AVC_FRC_24; break; case CELL_VDEC_FRC_25: avc->frameRateCode = CELL_VDEC_AVC_FRC_25; break; case CELL_VDEC_FRC_30000DIV1001: avc->frameRateCode = CELL_VDEC_AVC_FRC_30000DIV1001; break; case CELL_VDEC_FRC_30: avc->frameRateCode = CELL_VDEC_AVC_FRC_30; break; case CELL_VDEC_FRC_50: avc->frameRateCode = CELL_VDEC_AVC_FRC_50; break; case CELL_VDEC_FRC_60000DIV1001: avc->frameRateCode = CELL_VDEC_AVC_FRC_60000DIV1001; break; case CELL_VDEC_FRC_60: avc->frameRateCode = CELL_VDEC_AVC_FRC_60; break; default: cellVdec.Error("cellVdecGetPicItem(AVC): unknown frc value (0x%x)", vf.frc); } avc->fixed_frame_rate_flag = true; avc->low_delay_hrd_flag = true; // ??? avc->entropy_coding_mode_flag = true; // ??? avc->nalUnitPresentFlags = 0; // ??? avc->ccDataLength[0] = 0; avc->ccDataLength[1] = 0; avc->reserved[0] = 0; avc->reserved[1] = 0; } else if (vdec->type == CELL_VDEC_CODEC_TYPE_DIVX) { auto dvx = vm::ptr<CellVdecDivxInfo>::make(info.addr() + sizeof32(CellVdecPicItem)); switch (frame.pict_type) { case AV_PICTURE_TYPE_I: dvx->pictureType = CELL_VDEC_DIVX_VCT_I; break; case AV_PICTURE_TYPE_P: dvx->pictureType = CELL_VDEC_DIVX_VCT_P; break; case AV_PICTURE_TYPE_B: dvx->pictureType = CELL_VDEC_DIVX_VCT_B; break; default: cellVdec.Error("cellVdecGetPicItem(DivX): unknown pict_type value (0x%x)", frame.pict_type); } dvx->horizontalSize = frame.width; dvx->verticalSize = frame.height; dvx->pixelAspectRatio = CELL_VDEC_DIVX_ARI_PAR_1_1; // ??? dvx->parHeight = 0; dvx->parWidth = 0; dvx->colourDescription = false; // ??? dvx->colourPrimaries = CELL_VDEC_DIVX_CP_ITU_R_BT_709; // ??? dvx->transferCharacteristics = CELL_VDEC_DIVX_TC_ITU_R_BT_709; // ??? dvx->matrixCoefficients = CELL_VDEC_DIVX_MXC_ITU_R_BT_709; // ??? dvx->pictureStruct = CELL_VDEC_DIVX_PSTR_FRAME; // ??? switch (vf.frc) { case CELL_VDEC_FRC_24000DIV1001: dvx->frameRateCode = CELL_VDEC_DIVX_FRC_24000DIV1001; break; case CELL_VDEC_FRC_24: dvx->frameRateCode = CELL_VDEC_DIVX_FRC_24; break; case CELL_VDEC_FRC_25: dvx->frameRateCode = CELL_VDEC_DIVX_FRC_25; break; case CELL_VDEC_FRC_30000DIV1001: dvx->frameRateCode = CELL_VDEC_DIVX_FRC_30000DIV1001; break; case CELL_VDEC_FRC_30: dvx->frameRateCode = CELL_VDEC_DIVX_FRC_30; break; case CELL_VDEC_FRC_50: dvx->frameRateCode = CELL_VDEC_DIVX_FRC_50; break; case CELL_VDEC_FRC_60000DIV1001: dvx->frameRateCode = CELL_VDEC_DIVX_FRC_60000DIV1001; break; case CELL_VDEC_FRC_60: dvx->frameRateCode = CELL_VDEC_DIVX_FRC_60; break; default: cellVdec.Error("cellVdecGetPicItem(DivX): unknown frc value (0x%x)", vf.frc); } } else if (vdec->type == CELL_VDEC_CODEC_TYPE_MPEG2) { auto mp2 = vm::ptr<CellVdecMpeg2Info>::make(info.addr() + sizeof32(CellVdecPicItem)); throw EXCEPTION("MPEG2"); } *picItem = info; return CELL_OK; }
//#define NMPP_OPTIMIZE_ALLOC 1 //#define NMPP_CUSTOM_ALLOC 2 //#define SKIP_SINCOS 4 int nmppsFFT2048FwdInitAlloc4888( NmppsFFTSpec** specFFT, const void* src, const void* dst, int settings) { if (settings&NMPP_OPTIMIZE_ALLOC){ nmppsMallocResetRoute(); do { NmppsFFTSpec* spec; if (nmppsFFT2048FwdInitAlloc4888(&spec, src,dst, NMPP_CUSTOM_ALLOC|SKIP_SINCOS)==NMPP_OK){ nmppsMallocTimerStart(); nmppsFFT2048Fwd4888((nm32sc*)src, (nm32sc*)dst, spec); nmppsMallocTimerStop(); nmppsMallocBetterRoute(); nmppsFFTFree(spec); } } while (nmppsMallocIncrementRoute()==0); nmppsMallocSetBestRoute(1); } //if (settings==NMPP_CUSTOM_ALLOC){ NmppsFFTSpec* spec=(NmppsFFTSpec*)nmppsMalloc_32s(sizeof32(NmppsFFTSpec)); *specFFT=spec; if (spec==0) { return -1; } nmppsFFTResetSpec(spec); spec->buffer[0] =nmppsMalloc_32sc(2048); spec->buffer[1] =nmppsMalloc_32sc(2048); spec->fftTable[0]=nmppsMalloc_8s(4*4*2+4*8*8+32*8*8+256*8*8); // Bytes spec->fftTable[1]=nmppsMalloc_8s(4*4*2+4*8*8+32*8*8+256*8*8); // Bytes //spec->fftTable[2]=0; //spec->fftTable[3]=0; spec->shift[0]=0; spec->shift[1]=7; spec->shift[2]=7; spec->shift[3]=7; spec->amp[0]=1; spec->amp[1]=128; spec->amp[2]=128; spec->amp[3]=128; spec->free=free; if ((spec->fftTable[0]==0)||(spec->fftTable[1]==0)||(spec->buffer[0]==0)||(spec->buffer[1]==0)){ nmppsFFTFree(spec); spec=0; return -1; } //if (settings==-1) // return 0; if (!(settings&SKIP_SINCOS)){ nmppsFFT2048FwdInitSinCos4888(spec); } return NMPP_OK; }
bool SELFDecrypter::LoadMetadata() { aes_context aes; u32 metadata_info_size = sizeof32(meta_info); u8 *metadata_info = (u8 *)malloc(metadata_info_size); u32 metadata_headers_size = sce_hdr.se_hsize - (sizeof32(sce_hdr) + sce_hdr.se_meta + sizeof32(meta_info)); u8 *metadata_headers = (u8 *)malloc(metadata_headers_size); // Locate and read the encrypted metadata info. CHECK_ASSERTION(self_f.Seek(sce_hdr.se_meta + sizeof(sce_hdr)) != -1); self_f.Read(metadata_info, metadata_info_size); // Locate and read the encrypted metadata header and section header. CHECK_ASSERTION(self_f.Seek(sce_hdr.se_meta + sizeof(sce_hdr) + metadata_info_size) != -1); self_f.Read(metadata_headers, metadata_headers_size); // Find the right keyset from the key vault. SELF_KEY keyset = key_v.FindSelfKey(app_info.self_type, sce_hdr.se_flags, app_info.version); // Copy the necessary parameters. u8 metadata_key[0x20]; u8 metadata_iv[0x10]; memcpy(metadata_key, keyset.erk, 0x20); memcpy(metadata_iv, keyset.riv, 0x10); // Check DEBUG flag. if ((sce_hdr.se_flags & 0x8000) != 0x8000) { // Decrypt the NPDRM layer. if (!DecryptNPDRM(metadata_info, metadata_info_size)) return false; // Decrypt the metadata info. aes_setkey_dec(&aes, metadata_key, 256); // AES-256 aes_crypt_cbc(&aes, AES_DECRYPT, metadata_info_size, metadata_iv, metadata_info, metadata_info); } // Load the metadata info. meta_info.Load(metadata_info); // If the padding is not NULL for the key or iv fields, the metadata info // is not properly decrypted. if ((meta_info.key_pad[0] != 0x00) || (meta_info.iv_pad[0] != 0x00)) { LOG_ERROR(LOADER, "SELF: Failed to decrypt metadata info!"); return false; } // Perform AES-CTR encryption on the metadata headers. size_t ctr_nc_off = 0; u8 ctr_stream_block[0x10]; aes_setkey_enc(&aes, meta_info.key, 128); aes_crypt_ctr(&aes, metadata_headers_size, &ctr_nc_off, meta_info.iv, ctr_stream_block, metadata_headers, metadata_headers); // Load the metadata header. meta_hdr.Load(metadata_headers); // Load the metadata section headers. meta_shdr.clear(); for (unsigned int i = 0; i < meta_hdr.section_count; i++) { meta_shdr.emplace_back(); meta_shdr.back().Load(metadata_headers + sizeof(meta_hdr) + sizeof(MetadataSectionHeader) * i); } // Copy the decrypted data keys. data_keys_length = meta_hdr.key_count * 0x10; data_keys = (u8 *) malloc (data_keys_length); memcpy(data_keys, metadata_headers + sizeof(meta_hdr) + meta_hdr.section_count * sizeof(MetadataSectionHeader), data_keys_length); return true; }