/** * Y2R_U::SetConversionParams service function */ static void SetConversionParams(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); auto params = reinterpret_cast<const ConversionParameters*>(&cmd_buff[1]); LOG_DEBUG(Service_Y2R, "called input_format=%hhu output_format=%hhu rotation=%hhu block_alignment=%hhu " "input_line_width=%hu input_lines=%hu standard_coefficient=%hhu " "reserved=%hhu alpha=%hX", params->input_format, params->output_format, params->rotation, params->block_alignment, params->input_line_width, params->input_lines, params->standard_coefficient, params->reserved, params->alpha); ResultCode result = RESULT_SUCCESS; conversion.input_format = params->input_format; conversion.output_format = params->output_format; conversion.rotation = params->rotation; conversion.block_alignment = params->block_alignment; result = conversion.SetInputLineWidth(params->input_line_width); if (result.IsError()) goto cleanup; result = conversion.SetInputLines(params->input_lines); if (result.IsError()) goto cleanup; result = conversion.SetStandardCoefficient(params->standard_coefficient); if (result.IsError()) goto cleanup; conversion.alpha = params->alpha; cleanup: cmd_buff[0] = 0x00290040; // TODO verify cmd_buff[1] = result.raw; }
ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, VAddr icon_buffer, u32 icon_size, const FileSys::ArchiveFormatInfo& format_info) { // Construct the binary path to the archive first FileSys::Path path = FileSys::ConstructExtDataBinaryPath(static_cast<u32>(media_type), high, low); auto archive = id_code_map.find(media_type == MediaType::NAND ? ArchiveIdCode::SharedExtSaveData : ArchiveIdCode::ExtSaveData); if (archive == id_code_map.end()) { return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error } auto ext_savedata = static_cast<FileSys::ArchiveFactory_ExtSaveData*>(archive->second.get()); ResultCode result = ext_savedata->Format(path, format_info); if (result.IsError()) return result; if (!Memory::IsValidVirtualAddress(icon_buffer)) return ResultCode(-1); // TODO(Subv): Find the right error code std::vector<u8> smdh_icon(icon_size); Memory::ReadBlock(icon_buffer, smdh_icon.data(), smdh_icon.size()); ext_savedata->WriteIcon(path, smdh_icon.data(), smdh_icon.size()); return RESULT_SUCCESS; }
ResultCode Applet::Start(const Service::APT::AppletStartupParameter& parameter) { ResultCode result = StartImpl(parameter); if (result.IsError()) return result; // Schedule the update event CoreTiming::ScheduleEvent(usToCycles(applet_update_interval_us), applet_update_event, static_cast<u64>(id)); return result; }
ResultCode FormatConfig() { ResultCode res = DeleteConfigNANDSaveFile(); if (!res.IsSuccess()) return res; // Delete the old data cfg_config_file_buffer.fill(0); // Create the header SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data()); // This value is hardcoded, taken from 3dbrew, verified by hardware, it's always the same value config->data_entries_offset = 0x455C; // Insert the default blocks res = CreateConfigInfoBlk(0x00050005, sizeof(STEREO_CAMERA_SETTINGS), 0xE, reinterpret_cast<const u8*>(STEREO_CAMERA_SETTINGS.data())); if (!res.IsSuccess()) return res; res = CreateConfigInfoBlk(0x00090001, sizeof(CONSOLE_UNIQUE_ID), 0xE, reinterpret_cast<const u8*>(&CONSOLE_UNIQUE_ID)); if (!res.IsSuccess()) return res; res = CreateConfigInfoBlk(0x000F0004, sizeof(CONSOLE_MODEL), 0x8, reinterpret_cast<const u8*>(&CONSOLE_MODEL)); if (!res.IsSuccess()) return res; res = CreateConfigInfoBlk(0x000A0002, sizeof(CONSOLE_LANGUAGE), 0xA, &CONSOLE_LANGUAGE); if (!res.IsSuccess()) return res; res = CreateConfigInfoBlk(0x00070001, sizeof(SOUND_OUTPUT_MODE), 0xE, &SOUND_OUTPUT_MODE); if (!res.IsSuccess()) return res; res = CreateConfigInfoBlk(0x000B0000, sizeof(COUNTRY_INFO), 0xE, reinterpret_cast<const u8*>(&COUNTRY_INFO)); if (!res.IsSuccess()) return res; res = CreateConfigInfoBlk(0x000A0000, sizeof(CONSOLE_USERNAME_BLOCK), 0xE, reinterpret_cast<const u8*>(&CONSOLE_USERNAME_BLOCK)); if (!res.IsSuccess()) return res; // Save the buffer to the file res = UpdateConfigNANDSavegame(); if (!res.IsSuccess()) return res; return RESULT_SUCCESS; }
ResultVal<ArchiveHandle> OpenArchive(ArchiveIdCode id_code, FileSys::Path& archive_path) { LOG_TRACE(Service_FS, "Opening archive with id code 0x%08X", id_code); auto itr = id_code_map.find(id_code); if (itr == id_code_map.end()) { // TODO: Verify error against hardware return ResultCode(ErrorDescription::NotFound, ErrorModule::FS, ErrorSummary::NotFound, ErrorLevel::Permanent); } ResultCode res = itr->second->backend->Open(archive_path); if (!res.IsSuccess()) return res; // This should never even happen in the first place with 64-bit handles, while (handle_map.count(next_handle) != 0) { ++next_handle; } handle_map.emplace(next_handle, itr->second.get()); return MakeResult<ArchiveHandle>(next_handle++); }
/** * Y2R_U::SetPackageParameter service function */ static void SetPackageParameter(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); auto params = reinterpret_cast<const ConversionParameters*>(&cmd_buff[1]); conversion.input_format = params->input_format; conversion.output_format = params->output_format; conversion.rotation = params->rotation; conversion.block_alignment = params->block_alignment; ResultCode result = conversion.SetInputLineWidth(params->input_line_width); if (result.IsError()) goto cleanup; result = conversion.SetInputLines(params->input_lines); if (result.IsError()) goto cleanup; result = conversion.SetStandardCoefficient(params->standard_coefficient); if (result.IsError()) goto cleanup; conversion.padding = params->padding; conversion.alpha = params->alpha; cleanup: cmd_buff[0] = IPC::MakeHeader(0x29, 1, 0); cmd_buff[1] = result.raw; LOG_DEBUG( Service_Y2R, "called input_format=%hhu output_format=%hhu rotation=%hhu block_alignment=%hhu " "input_line_width=%hu input_lines=%hu standard_coefficient=%hhu reserved=%hhu alpha=%hX", params->input_format, params->output_format, params->rotation, params->block_alignment, params->input_line_width, params->input_lines, params->standard_coefficient, params->padding, params->alpha); }
ResultCode ArchiveManager::CreateExtSaveData(MediaType media_type, u32 high, u32 low, const std::vector<u8>& smdh_icon, const FileSys::ArchiveFormatInfo& format_info, u64 program_id) { // Construct the binary path to the archive first FileSys::Path path = FileSys::ConstructExtDataBinaryPath(static_cast<u32>(media_type), high, low); auto archive = id_code_map.find(media_type == MediaType::NAND ? ArchiveIdCode::SharedExtSaveData : ArchiveIdCode::ExtSaveData); if (archive == id_code_map.end()) { return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error } auto ext_savedata = static_cast<FileSys::ArchiveFactory_ExtSaveData*>(archive->second.get()); ResultCode result = ext_savedata->Format(path, format_info, program_id); if (result.IsError()) return result; ext_savedata->WriteIcon(path, smdh_icon.data(), smdh_icon.size()); return RESULT_SUCCESS; }
void ConfigureSystem::setConfiguration() { enabled = !System::IsPoweredOn(); if (!enabled) { ReadSystemSettings(); ui->group_system_settings->setEnabled(false); } else { // This tab is enabled only when game is not running (i.e. all service are not initialized). // Temporarily register archive types and load the config savegame file to memory. Service::FS::RegisterArchiveTypes(); ResultCode result = Service::CFG::LoadConfigNANDSaveFile(); Service::FS::UnregisterArchiveTypes(); if (result.IsError()) { ui->label_disable_info->setText(tr("Failed to load system settings data.")); ui->group_system_settings->setEnabled(false); enabled = false; return; } ReadSystemSettings(); ui->label_disable_info->hide(); } }
/// Map application or GSP heap memory static ResultCode ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 addr1, u32 size, u32 permissions) { using namespace Kernel; LOG_DEBUG(Kernel_SVC,"called operation=0x%08X, addr0=0x%08X, addr1=0x%08X, size=0x%X, permissions=0x%08X", operation, addr0, addr1, size, permissions); if ((addr0 & Memory::PAGE_MASK) != 0 || (addr1 & Memory::PAGE_MASK) != 0) { return ERR_MISALIGNED_ADDRESS; } if ((size & Memory::PAGE_MASK) != 0) { return ERR_MISALIGNED_SIZE; } u32 region = operation & MEMOP_REGION_MASK; operation &= ~MEMOP_REGION_MASK; if (region != 0) { LOG_WARNING(Kernel_SVC, "ControlMemory with specified region not supported, region=%X", region); } if ((permissions & (u32)MemoryPermission::ReadWrite) != permissions) { return ERR_INVALID_COMBINATION; } VMAPermission vma_permissions = (VMAPermission)permissions; auto& process = *g_current_process; switch (operation & MEMOP_OPERATION_MASK) { case MEMOP_FREE: { if (addr0 >= Memory::HEAP_VADDR && addr0 < Memory::HEAP_VADDR_END) { ResultCode result = process.HeapFree(addr0, size); if (result.IsError()) return result; } else if (addr0 >= process.GetLinearHeapBase() && addr0 < process.GetLinearHeapLimit()) { ResultCode result = process.LinearFree(addr0, size); if (result.IsError()) return result; } else { return ERR_INVALID_ADDRESS; } *out_addr = addr0; break; } case MEMOP_COMMIT: { if (operation & MEMOP_LINEAR) { CASCADE_RESULT(*out_addr, process.LinearAllocate(addr0, size, vma_permissions)); } else { CASCADE_RESULT(*out_addr, process.HeapAllocate(addr0, size, vma_permissions)); } break; } case MEMOP_MAP: // TODO: This is just a hack to avoid regressions until memory aliasing is implemented { CASCADE_RESULT(*out_addr, process.HeapAllocate(addr0, size, vma_permissions)); break; } case MEMOP_UNMAP: // TODO: This is just a hack to avoid regressions until memory aliasing is implemented { ResultCode result = process.HeapFree(addr0, size); if (result.IsError()) return result; break; } case MEMOP_PROTECT: { ResultCode result = process.vm_manager.ReprotectRange(addr0, size, vma_permissions); if (result.IsError()) return result; break; } default: LOG_ERROR(Kernel_SVC, "unknown operation=0x%08X", operation); return ERR_INVALID_COMBINATION; } process.vm_manager.LogLayout(Log::Level::Trace); return RESULT_SUCCESS; }